示例#1
0
class InstanceBasics(EutesterTestCase):
    def __init__(self,
                 name="InstanceBasics",
                 credpath=None,
                 region=None,
                 config_file=None,
                 password=None,
                 emi=None,
                 zone=None,
                 user_data=None,
                 instance_user=None,
                 **kwargs):
        """
        EC2 API tests focused on instance store instances

        :param credpath: Path to directory containing eucarc file
        :param region: EC2 Region to run testcase in
        :param config_file: Configuration file path
        :param password: SSH password for bare metal machines if config is passed and keys arent synced
        :param emi: Image id to use for test
        :param zone: Availability Zone to run test in
        :param user_data: User Data to pass to instance
        :param instance_user: User to login to instance as
        :param kwargs: Additional arguments
        """
        super(InstanceBasics, self).__init__(name=name)
        if region:
            self.tester = EC2ops(credpath=credpath, region=region)
        else:
            self.tester = Eucaops(config_file=config_file,
                                  password=password,
                                  credpath=credpath)
        self.instance_timeout = 600

        ### Add and authorize a group for the instance
        self.group = self.tester.add_group(group_name="group-" +
                                           str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name)
        self.tester.authorize_group_by_name(group_name=self.group.name,
                                            port=-1,
                                            protocol="icmp")
        ### Generate a keypair for the instance
        self.keypair = self.tester.add_keypair("keypair-" + str(time.time()))
        self.keypath = '%s/%s.pem' % (os.curdir, self.keypair.name)
        if emi:
            self.image = emi
        else:
            self.image = self.tester.get_emi(root_device_type="instance-store",
                                             not_platform="windows")
        self.address = None
        self.volume = None
        self.private_addressing = False
        if not zone:
            zones = self.tester.ec2.get_all_zones()
            self.zone = random.choice(zones).name
        else:
            self.zone = zone
        self.reservation = None
        self.reservation_lock = threading.Lock()
        self.run_instance_params = {
            'image': self.image,
            'user_data': user_data,
            'username': instance_user,
            'keypair': self.keypair.name,
            'group': self.group.name,
            'zone': self.zone,
            'timeout': self.instance_timeout
        }
        self.managed_network = True

        ### If I have access to the underlying infrastructure I can look
        ### at the network mode and only run certain tests where it makes sense
        if hasattr(self.tester, "service_manager"):
            cc = self.tester.get_component_machines("cc")[0]
            network_mode = cc.sys(
                "cat " + self.tester.eucapath +
                "/etc/eucalyptus/eucalyptus.conf | grep MODE")[0]
            if re.search("(SYSTEM|STATIC)", network_mode):
                self.managed_network = False

    def set_reservation(self, reservation):
        self.reservation_lock.acquire()
        self.reservation = reservation
        self.reservation_lock.release()

    def clean_method(self):
        self.tester.cleanup_artifacts()

    def BasicInstanceChecks(self):
        """
        This case was developed to run through a series of basic instance tests.
             The tests are as follows:
                   - execute run_instances command
                   - make sure that public DNS name and private IP aren't the same
                       (This is for Managed/Managed-NOVLAN networking modes)
                   - test to see if instance is ping-able
                   - test to make sure that instance is accessible via ssh
                       (ssh into instance and run basic ls command)
             If any of these tests fail, the test case will error out, logging the results.
        """
        reservation = self.tester.run_instance(**self.run_instance_params)
        for instance in reservation.instances:
            self.assertTrue(self.tester.wait_for_reservation(reservation),
                            'Instance did not go to running')
            self.assertTrue(self.tester.ping(instance.ip_address),
                            'Could not ping instance')
            if self.image.virtualization_type == "paravirtual":
                paravirtual_ephemeral = "/dev/" + instance.rootfs_device + "2"
                self.assertFalse(
                    instance.found("ls -1 " + paravirtual_ephemeral,
                                   "No such file or directory"),
                    "Did not find ephemeral storage at " +
                    paravirtual_ephemeral)
            elif self.image.virtualization_type == "hvm":
                hvm_ephemeral = "/dev/" + instance.block_device_prefix + "b"
                self.assertFalse(
                    instance.found("ls -1 " + hvm_ephemeral,
                                   "No such file or directory"),
                    "Did not find ephemeral storage at " + hvm_ephemeral)
        self.set_reservation(reservation)
        return reservation

    def ElasticIps(self):
        """
       This case was developed to test elastic IPs in Eucalyptus. This test case does
       not test instances that are launched using private-addressing option.
       The test case executes the following tests:
           - allocates an IP, associates the IP to the instance, then pings the instance.
           - disassociates the allocated IP, then pings the instance.
           - releases the allocated IP address
       If any of the tests fail, the test case will error out, logging the results.
        """
        if not self.reservation:
            reservation = self.tester.run_instance(**self.run_instance_params)
        else:
            reservation = self.reservation

        for instance in reservation.instances:
            if instance.ip_address == instance.private_ip_address:
                self.tester.debug(
                    "WARNING: System or Static mode detected, skipping ElasticIps"
                )
                return reservation
            self.address = self.tester.allocate_address()
            self.assertTrue(self.address, 'Unable to allocate address')
            self.tester.associate_address(instance, self.address)
            instance.update()
            self.assertTrue(self.tester.ping(instance.ip_address),
                            "Could not ping instance with new IP")
            self.tester.disassociate_address_from_instance(instance)
            self.tester.release_address(self.address)
            self.address = None
            assert isinstance(instance, EuInstance)
            self.tester.sleep(5)
            instance.update()
            self.assertTrue(self.tester.ping(instance.ip_address),
                            "Could not ping after dissassociate")
        self.set_reservation(reservation)
        return reservation

    def MultipleInstances(self):
        """
        This case was developed to test the maximum number of m1.small vm types a configured
        cloud can run.  The test runs the maximum number of m1.small vm types allowed, then
        tests to see if all the instances reached a running state.  If there is a failure,
        the test case errors out; logging the results.
        """
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
            self.set_reservation(None)

        reservation = self.tester.run_instance(min=2,
                                               max=2,
                                               **self.run_instance_params)
        self.assertTrue(self.tester.wait_for_reservation(reservation),
                        'Not all instances  went to running')
        self.set_reservation(reservation)
        return reservation

    def LargestInstance(self):
        """
        This case was developed to test the maximum number of c1.xlarge vm types a configured
        cloud can run.  The test runs the maximum number of c1.xlarge vm types allowed, then
        tests to see if all the instances reached a running state.  If there is a failure,
        the test case errors out; logging the results.
        """
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
            self.set_reservation(None)
        reservation = self.tester.run_instance(type="c1.xlarge",
                                               **self.run_instance_params)
        self.assertTrue(self.tester.wait_for_reservation(reservation),
                        'Not all instances  went to running')
        self.set_reservation(reservation)
        return reservation

    def MetaData(self):
        """
        This case was developed to test the metadata service of an instance for consistency.
        The following meta-data attributes are tested:
           - public-keys/0/openssh-key
           - security-groups
           - instance-id
           - local-ipv4
           - public-ipv4
           - ami-id
           - ami-launch-index
           - reservation-id
           - placement/availability-zone
           - kernel-id
           - public-hostname
           - local-hostname
           - hostname
           - ramdisk-id
           - instance-type
           - any bad metadata that shouldn't be present.
        Missing nodes
         ['block-device-mapping/',  'ami-manifest-path']
        If any of these tests fail, the test case will error out; logging the results.
        """
        if not self.reservation:
            reservation = self.tester.run_instance(**self.run_instance_params)
        else:
            reservation = self.reservation
        for instance in reservation.instances:
            ## Need to verify  the public key (could just be checking for a string of a certain length)
            self.assertTrue(
                re.match(
                    instance.get_metadata("public-keys/0/openssh-key")
                    [0].split('eucalyptus.')[-1], self.keypair.name),
                'Incorrect public key in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("security-groups")[0],
                    self.group.name), 'Incorrect security group in metadata')
            # Need to validate block device mapping
            #self.assertTrue(re.search(instance_ssh.get_metadata("block-device-mapping/")[0], ""))
            self.assertTrue(
                re.match(instance.get_metadata("instance-id")[0], instance.id),
                'Incorrect instance id in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("local-ipv4")[0],
                    instance.private_ip_address),
                'Incorrect private ip in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("public-ipv4")[0],
                    instance.ip_address), 'Incorrect public ip in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("ami-id")[0], instance.image_id),
                'Incorrect ami id in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("ami-launch-index")[0],
                    instance.ami_launch_index),
                'Incorrect launch index in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("reservation-id")[0],
                    reservation.id), 'Incorrect reservation in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("placement/availability-zone")[0],
                    instance.placement),
                'Incorrect availability-zone in metadata')
            if self.image.virtualization_type == "paravirtual":
                self.assertTrue(
                    re.match(
                        instance.get_metadata("kernel-id")[0],
                        instance.kernel), 'Incorrect kernel id in metadata')
                self.assertTrue(
                    re.match(
                        instance.get_metadata("ramdisk-id")[0],
                        instance.ramdisk), 'Incorrect ramdisk in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("public-hostname")[0],
                    instance.public_dns_name),
                'Incorrect public host name in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("local-hostname")[0],
                    instance.private_dns_name),
                'Incorrect private host name in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("hostname")[0],
                    instance.private_dns_name),
                'Incorrect host name in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("instance-type")[0],
                    instance.instance_type),
                'Incorrect instance type in metadata')
            bad_meta_data_keys = ['foobar']
            for key in bad_meta_data_keys:
                self.assertTrue(
                    re.search("Not Found",
                              "".join(instance.get_metadata(key))),
                    'No fail message on invalid meta-data node')
        self.set_reservation(reservation)
        return reservation

    def DNSResolveCheck(self):
        """
        This case was developed to test DNS resolution information for public/private DNS
        names and IP addresses.  The tested DNS resolution behavior is expected to follow

        AWS EC2.  The following tests are ran using the associated meta-data attributes:
           - check to see if Eucalyptus Dynamic DNS is configured
           - nslookup on hostname; checks to see if it matches local-ipv4
           - nslookup on local-hostname; check to see if it matches local-ipv4
           - nslookup on local-ipv4; check to see if it matches local-hostname
           - nslookup on public-hostname; check to see if it matches local-ipv4
           - nslookup on public-ipv4; check to see if it matches public-host
        If any of these tests fail, the test case will error out; logging the results.
        """
        if not self.reservation:
            reservation = self.tester.run_instance(**self.run_instance_params)
        else:
            reservation = self.reservation

        for instance in reservation.instances:
            if not re.search("internal", instance.private_dns_name):
                self.tester.debug(
                    "Did not find instance DNS enabled, skipping test")
                self.set_reservation(reservation)
                return reservation
            # Test to see if Dynamic DNS has been configured #
            # Per AWS standard, resolution should have private hostname or private IP as a valid response
            # Perform DNS resolution against public IP and public DNS name
            # Perform DNS resolution against private IP and private DNS name
            # Check to see if nslookup was able to resolve
            assert isinstance(instance, EuInstance)
            # Check nslookup to resolve public DNS Name to local-ipv4 address
            self.assertTrue(
                instance.found("nslookup " + instance.public_dns_name,
                               instance.private_ip_address),
                "Incorrect DNS resolution for hostname.")
            # Check nslookup to resolve public-ipv4 address to public DNS name
            if self.managed_network:
                self.assertTrue(
                    instance.found("nslookup " + instance.ip_address,
                                   instance.public_dns_name),
                    "Incorrect DNS resolution for public IP address")
            # Check nslookup to resolve private DNS Name to local-ipv4 address
            if self.managed_network:
                self.assertTrue(
                    instance.found("nslookup " + instance.private_dns_name,
                                   instance.private_ip_address),
                    "Incorrect DNS resolution for private hostname.")
            # Check nslookup to resolve local-ipv4 address to private DNS name
            self.assertTrue(
                instance.found("nslookup " + instance.private_ip_address,
                               instance.private_dns_name),
                "Incorrect DNS resolution for private IP address")
            self.assertTrue(self.tester.ping(instance.public_dns_name))
        self.set_reservation(reservation)
        return reservation

    def Reboot(self):
        """
        This case was developed to test IP connectivity and volume attachment after
        instance reboot.  The following tests are done for this test case:
                   - creates a 1 gig EBS volume, then attach volume
                   - reboot instance
                   - attempts to connect to instance via ssh
                   - checks to see if EBS volume is attached
                   - detaches volume
                   - deletes volume
        If any of these tests fail, the test case will error out; logging the results.
        """
        if not self.reservation:
            reservation = self.tester.run_instance(**self.run_instance_params)
        else:
            reservation = self.reservation
        for instance in reservation.instances:
            ### Create 1GB volume in first AZ
            volume = self.tester.create_volume(instance.placement,
                                               size=1,
                                               timepergig=180)
            instance.attach_volume(volume)
            ### Reboot instance
            instance.reboot_instance_and_verify(waitconnect=20)
            instance.detach_euvolume(volume)
            self.tester.delete_volume(volume)
        self.set_reservation(reservation)
        return reservation

    def Churn(self):
        """
        This case was developed to test robustness of Eucalyptus by starting instances,
        stopping them before they are running, and increase the time to terminate on each
        iteration.  This test case leverages the BasicInstanceChecks test case. The
        following steps are ran:
            - runs BasicInstanceChecks test case 5 times, 10 second apart.
            - While each test is running, run and terminate instances with a 10sec sleep in between.
            - When a test finishes, rerun BasicInstanceChecks test case.
        If any of these tests fail, the test case will error out; logging the results.
        """
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
            self.set_reservation(None)
        try:
            available_instances_before = self.tester.get_available_vms(
                zone=self.zone)
            if available_instances_before > 4:
                count = 4
            else:
                count = available_instances_before
        except IndexError, e:
            self.debug("Running as non-admin, defaulting to 4 VMs")
            available_instances_before = count = 4

        future_instances = []

        with ThreadPoolExecutor(max_workers=count) as executor:
            ## Start asynchronous activity
            ## Run 5 basic instance check instances 10s apart
            for i in xrange(count):
                future_instances.append(
                    executor.submit(self.BasicInstanceChecks))
                self.tester.sleep(10)

        with ThreadPoolExecutor(max_workers=count) as executor:
            ## Start asynchronous activity
            ## Terminate all instances
            for future in future_instances:
                executor.submit(self.tester.terminate_instances,
                                future.result())

        def available_after_greater():
            return self.tester.get_available_vms(
                zone=self.zone) >= available_instances_before

        self.tester.wait_for_result(available_after_greater,
                                    result=True,
                                    timeout=360)
示例#2
0
class InstanceBasics(EutesterTestCase):
    def __init__(self, extra_args=None):
        self.setuptestcase()
        self.setup_parser()
        if extra_args:
            for arg in extra_args:
                self.parser.add_argument(arg)
        self.get_args()
        # Setup basic eutester object
        self.tester = Eucaops(credpath=self.args.credpath)
        self.tester.poll_count = 120

        ### Add and authorize a group for the instance
        self.group = self.tester.add_group(group_name="group-" +
                                           str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name)
        self.tester.authorize_group_by_name(group_name=self.group.name,
                                            port=-1,
                                            protocol="icmp")
        ### Generate a keypair for the instance
        self.keypair = self.tester.add_keypair("keypair-" + str(time.time()))
        self.keypath = '%s/%s.pem' % (os.curdir, self.keypair.name)
        self.image = self.args.emi
        if not self.image:
            self.image = self.tester.get_emi(root_device_type="instance-store")
        self.address = None
        self.volume = None
        self.private_addressing = False
        zones = self.tester.ec2.get_all_zones()
        self.zone = random.choice(zones).name
        self.reservation = None

    def clean_method(self):
        if self.reservation:
            self.assertTrue(self.tester.terminate_instances(self.reservation),
                            "Unable to terminate instance(s)")
        if self.address:
            assert isinstance(self.address, Address)
            self.tester.release_address(self.address)
        if self.volume:
            self.tester.delete_volume(self.volume)
        self.tester.delete_group(self.group)
        self.tester.delete_keypair(self.keypair)
        os.remove(self.keypath)

    def BasicInstanceChecks(self, zone=None):
        """
        This case was developed to run through a series of basic instance tests.
             The tests are as follows:
                   - execute run_instances command
                   - make sure that public DNS name and private IP aren't the same
                       (This is for Managed/Managed-NOVLAN networking modes)
                   - test to see if instance is ping-able
                   - test to make sure that instance is accessible via ssh
                       (ssh into instance and run basic ls command)
             If any of these tests fail, the test case will error out, logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(
                self.image,
                keypair=self.keypair.name,
                group=self.group.name,
                zone=zone)
        for instance in self.reservation.instances:
            self.assertTrue(self.tester.wait_for_reservation(self.reservation),
                            'Instance did not go to running')
            self.assertNotEqual(instance.public_dns_name,
                                instance.private_ip_address,
                                'Public and private IP are the same')
            self.assertTrue(self.tester.ping(instance.public_dns_name),
                            'Could not ping instance')
            self.assertFalse(
                instance.found("ls -1 /dev/" + instance.rootfs_device + "2",
                               "No such file or directory"),
                'Did not find ephemeral storage at ' + instance.rootfs_device +
                "2")
        return self.reservation

    def ElasticIps(self, zone=None):
        """
       This case was developed to test elastic IPs in Eucalyptus. This test case does
       not test instances that are launched using private-addressing option.
       The test case executes the following tests:
           - allocates an IP, associates the IP to the instance, then pings the instance.
           - disassociates the allocated IP, then pings the instance.
           - releases the allocated IP address
       If any of the tests fail, the test case will error out, logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(
                keypair=self.keypair.name, group=self.group.name, zone=zone)
        for instance in self.reservation.instances:
            self.address = self.tester.allocate_address()
            self.assertTrue(self.address, 'Unable to allocate address')
            self.tester.associate_address(instance, self.address)
            instance.update()
            self.assertTrue(self.tester.ping(instance.public_dns_name),
                            "Could not ping instance with new IP")
            self.tester.disassociate_address_from_instance(instance)
            self.tester.release_address(self.address)
            self.address = None
            instance.update()
            self.assertTrue(self.tester.ping(instance.public_dns_name),
                            "Could not ping after dissassociate")
        return self.reservation

    def MaxSmallInstances(self, available_small=None, zone=None):
        """
        This case was developed to test the maximum number of m1.small vm types a configured
        cloud can run.  The test runs the maximum number of m1.small vm types allowed, then
        tests to see if all the instances reached a running state.  If there is a failure,
        the test case errors out; logging the results.
        """
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
        if available_small is None:
            available_small = self.tester.get_available_vms()
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,
                                                    keypair=self.keypair.name,
                                                    group=self.group.name,
                                                    min=available_small,
                                                    max=available_small,
                                                    zone=zone)
        self.assertTrue(self.tester.wait_for_reservation(self.reservation),
                        'Not all instances  went to running')
        return self.reservation

    def LargestInstance(self, zone=None):
        """
        This case was developed to test the maximum number of c1.xlarge vm types a configured
        cloud can run.  The test runs the maximum number of c1.xlarge vm types allowed, then
        tests to see if all the instances reached a running state.  If there is a failure,
        the test case errors out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
        self.reservation = self.tester.run_instance(self.image,
                                                    keypair=self.keypair.name,
                                                    group=self.group.name,
                                                    type="c1.xlarge",
                                                    zone=zone)
        self.assertTrue(self.tester.wait_for_reservation(self.reservation),
                        'Not all instances  went to running')
        return self.reservation

    def MetaData(self, zone=None):
        """
        This case was developed to test the metadata service of an instance for consistency.
        The following meta-data attributes are tested:
           - public-keys/0/openssh-key
           - security-groups
           - instance-id
           - local-ipv4
           - public-ipv4
           - ami-id
           - ami-launch-index
           - reservation-id
           - placement/availability-zone
           - kernel-id
           - public-hostname
           - local-hostname
           - hostname
           - ramdisk-id
           - instance-type
           - any bad metadata that shouldn't be present.
        Missing nodes
         ['block-device-mapping/',  'ami-manifest-path']
        If any of these tests fail, the test case will error out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(
                self.image,
                keypair=self.keypair.name,
                group=self.group.name,
                zone=zone)
        for instance in self.reservation.instances:
            ## Need to verify  the public key (could just be checking for a string of a certain length)
            self.assertTrue(
                re.match(
                    instance.get_metadata("public-keys/0/openssh-key")
                    [0].split('eucalyptus.')[-1], self.keypair.name),
                'Incorrect public key in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("security-groups")[0],
                    self.group.name), 'Incorrect security group in metadata')
            # Need to validate block device mapping
            #self.assertTrue(re.search(instance_ssh.get_metadata("block-device-mapping/")[0], ""))
            self.assertTrue(
                re.match(instance.get_metadata("instance-id")[0], instance.id),
                'Incorrect instance id in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("local-ipv4")[0],
                    instance.private_ip_address),
                'Incorrect private ip in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("public-ipv4")[0],
                    instance.ip_address), 'Incorrect public ip in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("ami-id")[0], instance.image_id),
                'Incorrect ami id in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("ami-launch-index")[0],
                    instance.ami_launch_index),
                'Incorrect launch index in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("reservation-id")[0],
                    self.reservation.id), 'Incorrect reservation in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("placement/availability-zone")[0],
                    instance.placement),
                'Incorrect availability-zone in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("kernel-id")[0], instance.kernel),
                'Incorrect kernel id in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("public-hostname")[0],
                    instance.public_dns_name),
                'Incorrect public host name in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("local-hostname")[0],
                    instance.private_dns_name),
                'Incorrect private host name in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("hostname")[0], instance.dns_name),
                'Incorrect host name in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("ramdisk-id")[0], instance.ramdisk),
                'Incorrect ramdisk in metadata')  #instance-type
            self.assertTrue(
                re.match(
                    instance.get_metadata("instance-type")[0],
                    instance.instance_type),
                'Incorrect instance type in metadata')
            BAD_META_DATA_KEYS = ['foobar']
            for key in BAD_META_DATA_KEYS:
                self.assertTrue(
                    re.search("Not Found",
                              "".join(instance.get_metadata(key))),
                    'No fail message on invalid meta-data node')
        return self.reservation

    def DNSResolveCheck(self, zone=None):
        """
        This case was developed to test DNS resolution information for public/private DNS
        names and IP addresses.  The tested DNS resolution behavior is expected to follow
        AWS EC2.  The following tests are ran using the associated meta-data attributes:
           - check to see if Eucalyptus Dynamic DNS is configured
           - nslookup on hostname; checks to see if it matches local-ipv4
           - nslookup on local-hostname; check to see if it matches local-ipv4
           - nslookup on local-ipv4; check to see if it matches local-hostname
           - nslookup on public-hostname; check to see if it matches local-ipv4
           - nslookup on public-ipv4; check to see if it matches public-host
        If any of these tests fail, the test case will error out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(
                self.image,
                keypair=self.keypair.name,
                group=self.group.name,
                zone=zone)
        for instance in self.reservation.instances:

            # Test to see if Dynamic DNS has been configured #
            if re.match("internal",
                        instance.private_dns_name.split('eucalyptus.')[-1]):
                # Per AWS standard, resolution should have private hostname or private IP as a valid response
                # Perform DNS resolution against private IP and private DNS name
                # Check to see if nslookup was able to resolve
                self.assertTrue(
                    re.search(
                        'answer\:',
                        instance.sys("nslookup " +
                                     instance.get_metadata("hostname")[0])[3]),
                    "DNS lookup failed for hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-hostname returns local-ipv4 address
                self.assertTrue(
                    re.search(
                        instance.get_metadata("local-ipv4")[0],
                        instance.sys("nslookup " +
                                     instance.get_metadata("hostname")[0])[5]),
                    "Incorrect DNS resolution for hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(
                    re.search(
                        'answer\:',
                        instance.sys(
                            "nslookup " +
                            instance.get_metadata("local-hostname")[0])[3]),
                    "DNS lookup failed for private hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-hostname returns local-ipv4 address
                self.assertTrue(
                    re.search(
                        instance.get_metadata("local-ipv4")[0],
                        instance.sys(
                            "nslookup " +
                            instance.get_metadata("local-hostname")[0])[5]),
                    "Incorrect DNS resolution for private hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(
                    re.search(
                        'answer\:',
                        instance.sys("nslookup " +
                                     instance.get_metadata("local-ipv4")[0])
                        [3]), "DNS lookup failed for private IP address.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-ipv4 address returns local-hostname
                self.assertTrue(
                    re.search(
                        instance.get_metadata("local-hostname")[0],
                        instance.sys("nslookup " +
                                     instance.get_metadata("local-ipv4")[0])
                        [4]),
                    "Incorrect DNS resolution for private IP address")
                # Perform DNS resolution against public IP and public DNS name
                # Check to see if nslookup was able to resolve
                self.assertTrue(
                    re.search(
                        'answer\:',
                        instance.sys(
                            "nslookup " +
                            instance.get_metadata("public-hostname")[0])[3]),
                    "DNS lookup failed for public-hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on public-hostname returns local-ipv4 address
                self.assertTrue(
                    re.search(
                        instance.get_metadata("local-ipv4")[0],
                        instance.sys(
                            "nslookup " +
                            instance.get_metadata("public-hostname")[0])[5]),
                    "Incorrect DNS resolution for public-hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(
                    re.search(
                        'answer\:',
                        instance.sys("nslookup " +
                                     instance.get_metadata("public-ipv4")[0])
                        [3]), "DNS lookup failed for public IP address.")
                # Since nslookup was able to resolve, now check to see if nslookup on public-ipv4 address returns public-hostname
                self.assertTrue(
                    re.search(
                        instance.get_metadata("public-hostname")[0],
                        instance.sys("nslookup " +
                                     instance.get_metadata("public-ipv4")[0])
                        [4]), "Incorrect DNS resolution for public IP address")

        return self.reservation

    def DNSCheck(self, zone=None):
        """
        This case was developed to test to make sure Eucalyptus Dynamic DNS reports correct
        information for public/private IP address and DNS names passed to meta-data service.
        The following tests are ran using the associated meta-data attributes:
           - check to see if Eucalyptus Dynamic DNS is configured
           - check to see if local-ipv4 and local-hostname are not the same
           - check to see if public-ipv4 and public-hostname are not the same
        If any of these tests fail, the test case will error out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(
                self.image,
                keypair=self.keypair.name,
                group=self.group.name,
                zone=zone)
        for instance in self.reservation.instances:

            # Test to see if Dynamic DNS has been configured #
            if re.match("internal",
                        instance.private_dns_name.split('eucalyptus.')[-1]):
                # Make sure that private_ip_address is not the same as local-hostname
                self.assertFalse(
                    re.match(instance.private_ip_address,
                             instance.private_dns_name),
                    'local-ipv4 and local-hostname are the same with DNS on')
                # Make sure that ip_address is not the same as public-hostname
                self.assertFalse(
                    re.match(instance.ip_address, instance.public_dns_name),
                    'public-ipv4 and public-hostname are the same with DNS on')

        return self.reservation

    def Reboot(self, zone=None):
        """
        This case was developed to test IP connectivity and volume attachment after
        instance reboot.  The following tests are done for this test case:
                   - creates a 1 gig EBS volume, then attach volume
                   - reboot instance
                   - attempts to connect to instance via ssh
                   - checks to see if EBS volume is attached
                   - detaches volume
                   - deletes volume
        If any of these tests fail, the test case will error out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(
                self.image,
                keypair=self.keypair.name,
                group=self.group.name,
                zone=zone)
        for instance in self.reservation.instances:
            ### Create 1GB volume in first AZ
            self.volume = self.tester.create_volume(instance.placement, 1)
            self.volume_device = instance.attach_volume(self.volume)
            ### Reboot instance
            instance.reboot_instance_and_verify(waitconnect=20)
            instance.detach_euvolume(self.volume)
            self.tester.delete_volume(self.volume)
            self.volume = None
        return self.reservation

    def run_terminate(self):
        reservation = None
        try:
            reservation = self.tester.run_instance(image=self.image,
                                                   zone=self.zone,
                                                   keypair=self.keypair.name,
                                                   group=self.group.name)
            self.tester.terminate_instances(reservation)
            return 0
        except Exception, e:
            if reservation:
                self.tester.terminate_instances(reservation)
            return 1
示例#3
0
class InstanceBasics(EutesterTestCase):
    def __init__(self, extra_args= None):
        self.setuptestcase()
        self.setup_parser()
        if extra_args:
            for arg in extra_args:
                self.parser.add_argument(arg)
        self.get_args()
        # Setup basic eutester object
        if self.args.region:
            self.tester = EC2ops( credpath=self.args.credpath, region=self.args.region)
        else:
            self.tester = Eucaops(config_file=self.args.config, password=self.args.password, credpath=self.args.credpath)
        self.tester.poll_count = 120

        ### Add and authorize a group for the instance
        self.group = self.tester.add_group(group_name="group-" + str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name )
        self.tester.authorize_group_by_name(group_name=self.group.name, port=-1, protocol="icmp" )
        ### Generate a keypair for the instance
        self.keypair = self.tester.add_keypair( "keypair-" + str(time.time()))
        self.keypath = '%s/%s.pem' % (os.curdir, self.keypair.name)
        self.image = self.args.emi
        if not self.image:
            self.image = self.tester.get_emi(root_device_type="instance-store")
        self.address = None
        self.volume = None
        self.private_addressing = False
        zones = self.tester.ec2.get_all_zones()
        self.zone = random.choice(zones).name
        self.reservation = None

    def clean_method(self):
        if self.reservation:
            self.assertTrue(self.tester.terminate_instances(self.reservation), "Unable to terminate instance(s)")
        if self.address:
            assert isinstance(self.address,Address)
            self.tester.release_address(self.address)
        if self.volume:
            self.tester.delete_volume(self.volume)
        self.tester.delete_group(self.group)
        self.tester.delete_keypair(self.keypair)
        os.remove(self.keypath)


    def BasicInstanceChecks(self, zone = None):
        """
        This case was developed to run through a series of basic instance tests.
             The tests are as follows:
                   - execute run_instances command
                   - make sure that public DNS name and private IP aren't the same
                       (This is for Managed/Managed-NOVLAN networking modes)
                   - test to see if instance is ping-able
                   - test to make sure that instance is accessible via ssh
                       (ssh into instance and run basic ls command)
             If any of these tests fail, the test case will error out, logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(self.image, keypair=self.keypair.name, group=self.group.name, zone=zone)
        for instance in self.reservation.instances:
            self.assertTrue( self.tester.wait_for_reservation(self.reservation) ,'Instance did not go to running')
            self.assertNotEqual( instance.public_dns_name, instance.private_ip_address, 'Public and private IP are the same')
            self.assertTrue( self.tester.ping(instance.public_dns_name), 'Could not ping instance')
            self.assertFalse( instance.found("ls -1 /dev/" + instance.rootfs_device + "2",  "No such file or directory"),  'Did not find ephemeral storage at ' + instance.rootfs_device + "2")
        return self.reservation

    def ElasticIps(self, zone = None):
        """
       This case was developed to test elastic IPs in Eucalyptus. This test case does
       not test instances that are launched using private-addressing option.
       The test case executes the following tests:
           - allocates an IP, associates the IP to the instance, then pings the instance.
           - disassociates the allocated IP, then pings the instance.
           - releases the allocated IP address
       If any of the tests fail, the test case will error out, logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(keypair=self.keypair.name, group=self.group.name,zone=zone)
        for instance in self.reservation.instances:
            self.address = self.tester.allocate_address()
            self.assertTrue(self.address,'Unable to allocate address')
            self.tester.associate_address(instance, self.address)
            instance.update()
            self.assertTrue( self.tester.ping(instance.public_dns_name), "Could not ping instance with new IP")
            self.tester.disassociate_address_from_instance(instance)
            self.tester.release_address(self.address)
            self.address = None
            instance.update()
            self.assertTrue( self.tester.ping(instance.public_dns_name), "Could not ping after dissassociate")
        return self.reservation

    def MaxSmallInstances(self, available_small=None,zone = None):
        """
        This case was developed to test the maximum number of m1.small vm types a configured
        cloud can run.  The test runs the maximum number of m1.small vm types allowed, then
        tests to see if all the instances reached a running state.  If there is a failure,
        the test case errors out; logging the results.
        """
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
        if available_small is None:
            available_small = self.tester.get_available_vms()
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,keypair=self.keypair.name, group=self.group.name,min=available_small, max=available_small, zone=zone)
        self.assertTrue( self.tester.wait_for_reservation(self.reservation) ,'Not all instances  went to running')
        return self.reservation

    def LargestInstance(self, zone = None):
        """
        This case was developed to test the maximum number of c1.xlarge vm types a configured
        cloud can run.  The test runs the maximum number of c1.xlarge vm types allowed, then
        tests to see if all the instances reached a running state.  If there is a failure,
        the test case errors out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
        self.reservation = self.tester.run_instance(self.image,keypair=self.keypair.name, group=self.group.name,type="c1.xlarge",zone=zone)
        self.assertTrue( self.tester.wait_for_reservation(self.reservation) ,'Not all instances  went to running')
        return self.reservation

    def MetaData(self, zone=None):
        """
        This case was developed to test the metadata service of an instance for consistency.
        The following meta-data attributes are tested:
           - public-keys/0/openssh-key
           - security-groups
           - instance-id
           - local-ipv4
           - public-ipv4
           - ami-id
           - ami-launch-index
           - reservation-id
           - placement/availability-zone
           - kernel-id
           - public-hostname
           - local-hostname
           - hostname
           - ramdisk-id
           - instance-type
           - any bad metadata that shouldn't be present.
        Missing nodes
         ['block-device-mapping/',  'ami-manifest-path']
        If any of these tests fail, the test case will error out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(self.image,keypair=self.keypair.name, group=self.group.name, zone=zone)
        for instance in self.reservation.instances:
            ## Need to verify  the public key (could just be checking for a string of a certain length)
            self.assertTrue(re.match(instance.get_metadata("public-keys/0/openssh-key")[0].split('eucalyptus.')[-1], self.keypair.name), 'Incorrect public key in metadata')
            self.assertTrue(re.match(instance.get_metadata("security-groups")[0], self.group.name), 'Incorrect security group in metadata')
            # Need to validate block device mapping
            #self.assertTrue(re.search(instance_ssh.get_metadata("block-device-mapping/")[0], "")) 
            self.assertTrue(re.match(instance.get_metadata("instance-id")[0], instance.id), 'Incorrect instance id in metadata')
            self.assertTrue(re.match(instance.get_metadata("local-ipv4")[0] , instance.private_ip_address), 'Incorrect private ip in metadata')
            self.assertTrue(re.match(instance.get_metadata("public-ipv4")[0] , instance.ip_address), 'Incorrect public ip in metadata')
            self.assertTrue(re.match(instance.get_metadata("ami-id")[0], instance.image_id), 'Incorrect ami id in metadata')
            self.assertTrue(re.match(instance.get_metadata("ami-launch-index")[0], instance.ami_launch_index), 'Incorrect launch index in metadata')
            self.assertTrue(re.match(instance.get_metadata("reservation-id")[0], self.reservation.id), 'Incorrect reservation in metadata')
            self.assertTrue(re.match(instance.get_metadata("placement/availability-zone")[0], instance.placement), 'Incorrect availability-zone in metadata')
            self.assertTrue(re.match(instance.get_metadata("kernel-id")[0], instance.kernel),  'Incorrect kernel id in metadata')
            self.assertTrue(re.match(instance.get_metadata("public-hostname")[0], instance.public_dns_name), 'Incorrect public host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("local-hostname")[0], instance.private_dns_name), 'Incorrect private host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("hostname")[0], instance.dns_name), 'Incorrect host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("ramdisk-id")[0], instance.ramdisk ), 'Incorrect ramdisk in metadata') #instance-type
            self.assertTrue(re.match(instance.get_metadata("instance-type")[0], instance.instance_type ), 'Incorrect instance type in metadata')
            BAD_META_DATA_KEYS = ['foobar']
            for key in BAD_META_DATA_KEYS:
                self.assertTrue(re.search("Not Found", "".join(instance.get_metadata(key))), 'No fail message on invalid meta-data node')
        return self.reservation

    def DNSResolveCheck(self, zone=None):
        """
        This case was developed to test DNS resolution information for public/private DNS
        names and IP addresses.  The tested DNS resolution behavior is expected to follow
        AWS EC2.  The following tests are ran using the associated meta-data attributes:
           - check to see if Eucalyptus Dynamic DNS is configured
           - nslookup on hostname; checks to see if it matches local-ipv4
           - nslookup on local-hostname; check to see if it matches local-ipv4
           - nslookup on local-ipv4; check to see if it matches local-hostname
           - nslookup on public-hostname; check to see if it matches local-ipv4
           - nslookup on public-ipv4; check to see if it matches public-host
        If any of these tests fail, the test case will error out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(self.image,keypair=self.keypair.name, group=self.group.name, zone=zone)
        for instance in self.reservation.instances:

            # Test to see if Dynamic DNS has been configured # 
            if re.match("internal", instance.private_dns_name.split('eucalyptus.')[-1]):
                # Per AWS standard, resolution should have private hostname or private IP as a valid response
                # Perform DNS resolution against private IP and private DNS name
                # Check to see if nslookup was able to resolve
                self.assertTrue(re.search('answer\:', instance.sys("nslookup " +  instance.get_metadata("hostname")[0])[3]), "DNS lookup failed for hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-hostname returns local-ipv4 address
                self.assertTrue(re.search(instance.get_metadata("local-ipv4")[0], instance.sys("nslookup " + instance.get_metadata("hostname")[0])[5]), "Incorrect DNS resolution for hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(re.search('answer\:', instance.sys("nslookup " +  instance.get_metadata("local-hostname")[0])[3]), "DNS lookup failed for private hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-hostname returns local-ipv4 address
                self.assertTrue(re.search(instance.get_metadata("local-ipv4")[0], instance.sys("nslookup " + instance.get_metadata("local-hostname")[0])[5]), "Incorrect DNS resolution for private hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(re.search('answer\:', instance.sys("nslookup " +  instance.get_metadata("local-ipv4")[0])[3]), "DNS lookup failed for private IP address.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-ipv4 address returns local-hostname
                self.assertTrue(re.search(instance.get_metadata("local-hostname")[0], instance.sys("nslookup " +  instance.get_metadata("local-ipv4")[0])[4]), "Incorrect DNS resolution for private IP address")
                # Perform DNS resolution against public IP and public DNS name
                # Check to see if nslookup was able to resolve
                self.assertTrue(re.search('answer\:', instance.sys("nslookup " +  instance.get_metadata("public-hostname")[0])[3]), "DNS lookup failed for public-hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on public-hostname returns local-ipv4 address
                self.assertTrue(re.search(instance.get_metadata("local-ipv4")[0], instance.sys("nslookup " + instance.get_metadata("public-hostname")[0])[5]), "Incorrect DNS resolution for public-hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(re.search('answer\:', instance.sys("nslookup " +  instance.get_metadata("public-ipv4")[0])[3]), "DNS lookup failed for public IP address.")
                # Since nslookup was able to resolve, now check to see if nslookup on public-ipv4 address returns public-hostname
                self.assertTrue(re.search(instance.get_metadata("public-hostname")[0], instance.sys("nslookup " +  instance.get_metadata("public-ipv4")[0])[4]), "Incorrect DNS resolution for public IP address")

        return self.reservation

    def DNSCheck(self, zone=None):
        """
        This case was developed to test to make sure Eucalyptus Dynamic DNS reports correct
        information for public/private IP address and DNS names passed to meta-data service.
        The following tests are ran using the associated meta-data attributes:
           - check to see if Eucalyptus Dynamic DNS is configured
           - check to see if local-ipv4 and local-hostname are not the same
           - check to see if public-ipv4 and public-hostname are not the same
        If any of these tests fail, the test case will error out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(self.image,keypair=self.keypair.name, group=self.group.name, zone=zone)
        for instance in self.reservation.instances:

            # Test to see if Dynamic DNS has been configured # 
            if re.match("internal", instance.private_dns_name.split('eucalyptus.')[-1]):
                # Make sure that private_ip_address is not the same as local-hostname
                self.assertFalse(re.match(instance.private_ip_address, instance.private_dns_name), 'local-ipv4 and local-hostname are the same with DNS on')
                # Make sure that ip_address is not the same as public-hostname
                self.assertFalse(re.match(instance.ip_address, instance.public_dns_name), 'public-ipv4 and public-hostname are the same with DNS on')

        return self.reservation

    def Reboot(self, zone=None):
        """
        This case was developed to test IP connectivity and volume attachment after
        instance reboot.  The following tests are done for this test case:
                   - creates a 1 gig EBS volume, then attach volume
                   - reboot instance
                   - attempts to connect to instance via ssh
                   - checks to see if EBS volume is attached
                   - detaches volume
                   - deletes volume
        If any of these tests fail, the test case will error out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            self.reservation = self.tester.run_instance(self.image, keypair=self.keypair.name, group=self.group.name, zone=zone)
        for instance in self.reservation.instances:
            ### Create 1GB volume in first AZ
            self.volume = self.tester.create_volume(instance.placement, 1)
            self.volume_device = instance.attach_volume(self.volume)
            ### Reboot instance
            instance.reboot_instance_and_verify(waitconnect=20)
            instance.detach_euvolume(self.volume)
            self.tester.delete_volume(self.volume)
            self.volume = None
        return self.reservation

    def run_terminate(self):
        reservation = None
        try:
            reservation = self.tester.run_instance(image=self.image,zone=self.zone, keypair=self.keypair.name, group=self.group.name)
            self.tester.terminate_instances(reservation)
            return 0
        except Exception, e:
            if reservation:
                self.tester.terminate_instances(reservation)
            return 1
示例#4
0
class Instances(unittest.TestCase):
    def setUp(self):
        # Setup basic eutester object
        
        self.tester = Eucaops( config_file="../input/2b_tested.lst", password="******", credpath="../credentials")
        self.tester.poll_count = 240
        self.tester.start_euca_logs()
        
        ### Determine whether virtio drivers are being used
        self.device_prefix = "sd"
        if self.tester.hypervisor == "kvm":
            self.device_prefix = "vd"
        self.ephemeral = "/dev/" + self.device_prefix + "a2"
        
        ### Adda and authorize a group for the instance
        self.group = self.tester.add_group(group_name="group-" + str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name )
        self.tester.authorize_group_by_name(group_name=self.group.name, port=-1, protocol="icmp" )
        
        ### Generate a keypair for the instance
        self.keypair = self.tester.add_keypair( "keypair-" + str(time.time()))
        self.keypath = os.curdir + "/" + self.keypair.name + ".pem"
        self.reservation = self.tester.run_instance(keypair=self.keypair.name, group=self.group.name)
        self.tester.sleep(10)
    
    def tearDown(self):
        """Stop Euca logs""" 
        self.assertTrue(self.tester.terminate_instances(self.reservation), "Unable to terminate instance(s)")
        self.tester.delete_group(self.group)
        self.tester.delete_keypair(self.keypair)
        os.remove(self.keypath)
        self.tester.stop_euca_logs()
        self.tester.save_euca_logs()
        self.reservation = None
        self.group = None
        self.keypair = None
        self.tester = None
        self.ephemeral = None
    
    def test1_Instance(self):
        """Instance checks including reachability and ephemeral storage"""
        for instance in self.reservation.instances:
            self.assertTrue( self.tester.wait_for_reservation(self.reservation) ,'Instance did not go to running')
            self.assertNotEqual( instance.public_dns_name, instance.private_ip_address, 'Public and private IP are the same')
            self.assertTrue( self.tester.ping(instance.public_dns_name), 'Could not ping instance')
            instance_ssh = Eucaops( hostname=instance.public_dns_name,  keypath= self.keypath)
            self.assertTrue( instance_ssh.found("ls -1 " + self.ephemeral,  self.ephemeral),  'Did not find ephemeral storage at ' + self.ephemeral)
            self.assertTrue( self.tester.terminate_instances(self.reservation), 'Failure when terminating instance')
    
    def test2_ElasticIps(self):
        """ Basic test for elastic IPs"""
        for instance in self.reservation.instances:
            address = self.tester.allocate_address()
            self.assertTrue(address,'Unable to allocate address')
            self.assertTrue(self.tester.associate_address(instance, address))
            self.tester.sleep(30)
            instance.update()
            self.assertTrue( self.tester.ping(instance.public_dns_name), "Could not ping instance with new IP")
            address.disassociate()
            self.tester.sleep(30)
            instance.update()
            self.assertTrue( self.tester.ping(instance.public_dns_name), "Could not ping instance with new IP")
            self.tester.release_address()
    
    def test3_MaxInstances(self):
        """Run the maximum m1.smalls available"""
        self.assertTrue(self.tester.terminate_instances(self.reservation), "Was not able to terminate original instance")
        available_small = self.tester.get_available_vms()
        self.reservation = self.tester.run_instance(keypair=self.keypair.name, group=self.group.name,min=available_small, max=available_small)
        self.assertTrue( self.tester.wait_for_reservation(self.reservation) ,'Not all instances  went to running')
    
    def test4_LargeInstance(self):
        """Run 1 of the largest instance c1.xlarge"""
        self.assertTrue(self.tester.terminate_instances(self.reservation), "Was not able to terminate original instance")
        self.reservation = self.tester.run_instance(keypair=self.keypair.name, group=self.group.name,type="c1.xlarge")
        self.assertTrue( self.tester.wait_for_reservation(self.reservation) ,'Not all instances  went to running')
    
    def test5_MetaData(self):
        """Check metadata for consistency"""
        # Missing nodes
        # ['block-device-mapping/',  'ami-manifest-path' , 'hostname',  'placement/']   
        for instance in self.reservation.instances:
            instance_ssh = Eucaops( hostname=instance.public_dns_name,  keypath= self.keypath)
            ### Check metadata service
            self.assertTrue(re.search(instance_ssh.get_metadata("public-keys/0/")[0], self.keypair.name))
            self.assertTrue(re.search(instance_ssh.get_metadata("security-groups")[0], self.group)) 
            #self.assertTrue(re.search(instance_ssh.get_metadata("block-device-mapping/")[0], "")) 
            self.assertTrue(re.search(instance_ssh.get_metadata("instance-id")[0], instance.id))  
            self.assertTrue(re.search(instance_ssh.get_metadata("local-ipv4")[0] , instance.private_ip_address))
            self.assertTrue(re.search(instance_ssh.get_metadata("public-ipv4")[0] , instance.ip_address))          
            self.assertTrue(re.search(instance_ssh.get_metadata("ami-id")[0], instance.image_id))
            self.assertTrue(re.search(instance_ssh.get_metadata("ami-launch-index")[0], instance.ami_launch_index))
            self.assertTrue(re.search(instance_ssh.get_metadata("reservation-id")[0], self.reservation.id))
            self.assertTrue(re.search(instance_ssh.get_metadata("kernel-id")[0], instance.kernel))
            self.assertTrue(re.search(instance_ssh.get_metadata("public-hostname")[0], instance.public_dns_name))
            self.assertTrue(re.search(instance_ssh.get_metadata("ramdisk-id")[0], instance.ramdisk )) #instance-type
            self.assertTrue(re.search(instance_ssh.get_metadata("instance-type")[0], instance.instance_type ))
           
    def test6_Reboot(self):
        """Reboot instance ensure IP connectivity and volumes stay attached"""
        for instance in self.reservation.instances:
            ### Create 1GB volume in first AZ
            volume = self.tester.create_volume(self.tester.ec2.get_all_zones()[0].name)
            
            ### Pass in check the devices on the instance before the attachment
            device_path = "/dev/" + self.device_prefix  +"j"
            instance_ssh = Eucaops( hostname=instance.public_dns_name,  keypath= self.keypath)
            before_attach = instance_ssh.sys("ls -1 /dev/ | grep " + self.device_prefix)
            
            ### Attach the volume to the instance
            self.assertTrue(self.tester.attach_volume(instance, volume, device_path), "Failure attaching volume")
            
            ### Check devices after attachment
            after_attach = instance_ssh.sys("ls -1 /dev/ | grep " + self.device_prefix)
            new_devices = self.tester.diff(after_attach, before_attach)
            
            ### Check for device in instance
            self.assertTrue(instance_ssh.check_device("/dev/" + new_devices[0]), "Did not find device on instance before reboot")
            
            ### Reboot instance
            instance.reboot()
            self.tester.sleep(30)
            
            ### Check for device in instance
            instance_ssh = Eucaops( hostname=instance.public_dns_name,  keypath= self.keypath)
            self.assertTrue(instance_ssh.check_device("/dev/" + new_devices[0]), "Did not find device on instance after reboot")
            self.assertTrue(self.tester.detach_volume(volume), "Unable to detach volume")
            self.assertTrue(self.tester.delete_volume(volume), "Unable to delete volume")
        
    def suite():
        tests = ['test1_Instance', 'test2_ElasticIps', 'test3_MaxInstances', 'test4_LargeInstance','test5_MetaData', 'test6_Reboot']
        return unittest.TestSuite(map(Instances, tests))
示例#5
0
class PopulateUpgrade(EutesterTestCase):
    def __init__(self, extra_args=None):
        self.setuptestcase()
        self.setup_parser()
        self.parser.add_argument("--region", default=None)
        if extra_args:
            for arg in extra_args:
                self.parser.add_argument(arg)
        self.get_args()
        # Setup basic eutester object
        if self.args.region:
            self.tester = EC2ops(credpath=self.args.credpath,
                                 region=self.args.region)
        else:
            self.tester = Eucaops(credpath=self.args.credpath,
                                  config_file=self.args.config,
                                  password=self.args.password)
        self.tester.poll_count = 120

        self.security_groups = []

        ### Generate a keypair for the instance
        self.keypair = self.tester.add_keypair("keypair-" + str(time.time()))
        self.keypath = '%s/%s.pem' % (os.curdir, self.keypair.name)
        self.image = self.args.emi
        if not self.image:
            self.image = self.tester.get_emi(root_device_type="instance-store")
        self.address = None
        self.volume = None
        self.snapshot = None
        self.private_addressing = False
        zones = self.tester.ec2.get_all_zones()
        self.zone = random.choice(zones).name
        self.reservation = None

    def clean_method(self):
        pass

    def Instances(self, type="instance-store"):
        """
        This case was developed to run through a series of basic instance tests.
             The tests are as follows:
                   - execute run_instances command
                   - make sure that public DNS name and private IP aren't the same
                       (This is for Managed/Managed-NOVLAN networking modes)
                   - test to see if instance is ping-able
                   - test to make sure that instance is accessible via ssh
                       (ssh into instance and run basic ls command)
             If any of these tests fail, the test case will error out, logging the results.
        """
        test_image = self.tester.get_emi(root_device_type=type)

        ### Add and authorize a group for the instance
        self.group = self.tester.add_group(group_name="group-" +
                                           str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name)
        self.tester.authorize_group_by_name(group_name=self.group.name,
                                            port=-1,
                                            protocol="icmp")

        self.security_groups.append(self.group)

        # Test: INSTANCESTORE VOLATTACH:no ADDR:user
        instance_1 = self.tester.run_instance(
            test_image, keypair=self.keypair.name,
            group=self.group.name).instances[0]
        instance_1_address = self.tester.allocate_address()
        self.tester.associate_address(instance=instance_1,
                                      address=instance_1_address)

        # Test: INSTANCESTORE VOLATTACH:no ADDR:system
        instance_2 = self.tester.run_instance(
            test_image, keypair=self.keypair.name,
            group=self.group.name).instances[0]

        # Test: INSTANCESTORE VOLATTACH:no ADDR:system
        instance_3 = self.tester.run_instance(test_image,
                                              group=self.group.name,
                                              private_addressing=True,
                                              is_reachable=False).instances[0]

        # Test: INSTANCESTORE VOLATTACH:yes ADDR:user
        instance_4 = self.tester.run_instance(
            test_image, keypair=self.keypair.name,
            group=self.group.name).instances[0]
        instance_4_address = self.tester.allocate_address()
        self.tester.associate_address(instance=instance_4,
                                      address=instance_4_address)
        volume = self.tester.create_volume(zone=self.zone)
        instance_4.attach_volume(volume=volume)

        # Test: INSTANCESTORE VOLATTACH:yes ADDR:system
        instance_5 = self.tester.run_instance(
            test_image, keypair=self.keypair.name,
            group=self.group.name).instances[0]
        volume = self.tester.create_volume(zone=self.zone)
        instance_5.attach_volume(volume=volume)

        self.group = self.tester.add_group(group_name="group-" +
                                           str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name)
        self.tester.authorize_group_by_name(group_name=self.group.name,
                                            port=-1,
                                            protocol="icmp")
        self.security_groups.append(self.group)
        # Test: INSTANCESTORE VOLATTACH:yes ADDR:system
        instance_6 = self.tester.run_instance(test_image,
                                              group=self.group.name,
                                              private_addressing=True,
                                              is_reachable=False).instances[0]

    def PopulateAll(self):
        self.Instances("instance-store")
        self.Instances("ebs")
示例#6
0
class InstanceBasics(EutesterTestCase):
    def __init__( self, name="InstanceBasics", credpath=None, region=None, config_file=None, password=None, emi=None, zone=None,
                  user_data=None, instance_user=None, **kwargs):
        """
        EC2 API tests focused on instance store instances

        :param credpath: Path to directory containing eucarc file
        :param region: EC2 Region to run testcase in
        :param config_file: Configuration file path
        :param password: SSH password for bare metal machines if config is passed and keys arent synced
        :param emi: Image id to use for test
        :param zone: Availability Zone to run test in
        :param user_data: User Data to pass to instance
        :param instance_user: User to login to instance as
        :param kwargs: Additional arguments
        """
        super(InstanceBasics, self).__init__(name=name)
        if region:
            self.tester = EC2ops(credpath=credpath, region=region)
        else:
            self.tester = Eucaops(config_file=config_file, password=password, credpath=credpath)
        self.instance_timeout = 480

        ### Add and authorize a group for the instance
        self.group = self.tester.add_group(group_name="group-" + str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name)
        self.tester.authorize_group_by_name(group_name=self.group.name, port=-1, protocol="icmp" )
        ### Generate a keypair for the instance
        self.keypair = self.tester.add_keypair( "keypair-" + str(time.time()))
        self.keypath = '%s/%s.pem' % (os.curdir, self.keypair.name)
        if emi:
            self.image = emi
        else:
            self.image = self.tester.get_emi(root_device_type="instance-store",not_location="loadbalancer")
        self.address = None
        self.volume = None
        self.private_addressing = False
        if not zone:
            zones = self.tester.ec2.get_all_zones()
            self.zone = random.choice(zones).name
        else:
            self.zone = zone
        self.reservation = None
        self.reservation_lock = threading.Lock()
        self.run_instance_params = {'image': self.image, 'user_data': user_data, 'username': instance_user,
                                'keypair': self.keypair.name, 'group': self.group.name,'zone': self.zone,
                                'timeout': self.instance_timeout}
        self.managed_network = True

        ### If I have access to the underlying infrastructure I can look
        ### at the network mode and only run certain tests where it makes sense
        if hasattr(self.tester,"service_manager"):
            cc = self.tester.get_component_machines("cc")[0]
            network_mode = cc.sys("cat " + self.tester.eucapath + "/etc/eucalyptus/eucalyptus.conf | grep MODE")[0]
            if re.search("(SYSTEM|STATIC)", network_mode):
                self.managed_network = False

    def set_reservation(self, reservation):
        self.reservation_lock.acquire()
        self.reservation = reservation
        self.reservation_lock.release()

    def clean_method(self):
        self.tester.cleanup_artifacts()

    def BasicInstanceChecks(self):
        """
        This case was developed to run through a series of basic instance tests.
             The tests are as follows:
                   - execute run_instances command
                   - make sure that public DNS name and private IP aren't the same
                       (This is for Managed/Managed-NOVLAN networking modes)
                   - test to see if instance is ping-able
                   - test to make sure that instance is accessible via ssh
                       (ssh into instance and run basic ls command)
             If any of these tests fail, the test case will error out, logging the results.
        """
        reservation = self.tester.run_instance(**self.run_instance_params)
        for instance in reservation.instances:
            self.assertTrue( self.tester.wait_for_reservation(reservation) ,'Instance did not go to running')
            self.assertTrue( self.tester.ping(instance.ip_address), 'Could not ping instance')
            self.assertFalse( instance.found("ls -1 /dev/" + instance.rootfs_device + "2",  "No such file or directory"),  'Did not find ephemeral storage at ' + instance.rootfs_device + "2")
        self.set_reservation(reservation)
        return reservation

    def ElasticIps(self):
        """
       This case was developed to test elastic IPs in Eucalyptus. This test case does
       not test instances that are launched using private-addressing option.
       The test case executes the following tests:
           - allocates an IP, associates the IP to the instance, then pings the instance.
           - disassociates the allocated IP, then pings the instance.
           - releases the allocated IP address
       If any of the tests fail, the test case will error out, logging the results.
        """
        if not self.reservation:
            reservation = self.tester.run_instance(**self.run_instance_params)
        else:
            reservation = self.reservation

        for instance in reservation.instances:
            if instance.ip_address == instance.private_ip_address:
                self.tester.debug("WARNING: System or Static mode detected, skipping ElasticIps")
                return reservation
            self.address = self.tester.allocate_address()
            self.assertTrue(self.address,'Unable to allocate address')
            self.tester.associate_address(instance, self.address)
            instance.update()
            self.assertTrue( self.tester.ping(instance.ip_address), "Could not ping instance with new IP")
            self.tester.disassociate_address_from_instance(instance)
            self.tester.release_address(self.address)
            self.address = None
            assert isinstance(instance, EuInstance)
            self.tester.sleep(5)
            instance.update()
            self.assertTrue( self.tester.ping(instance.ip_address), "Could not ping after dissassociate")
        self.set_reservation(reservation)
        return reservation

    def MultipleInstances(self):
        """
        This case was developed to test the maximum number of m1.small vm types a configured
        cloud can run.  The test runs the maximum number of m1.small vm types allowed, then
        tests to see if all the instances reached a running state.  If there is a failure,
        the test case errors out; logging the results.
        """
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
            self.set_reservation(None)

        reservation = self.tester.run_instance(min=2, max=2, **self.run_instance_params)
        self.assertTrue(self.tester.wait_for_reservation(reservation) ,'Not all instances  went to running')
        self.set_reservation(reservation)
        return reservation

    def LargestInstance(self):
        """
        This case was developed to test the maximum number of c1.xlarge vm types a configured
        cloud can run.  The test runs the maximum number of c1.xlarge vm types allowed, then
        tests to see if all the instances reached a running state.  If there is a failure,
        the test case errors out; logging the results.
        """
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
            self.set_reservation(None)
        reservation = self.tester.run_instance(type="c1.xlarge", **self.run_instance_params)
        self.assertTrue( self.tester.wait_for_reservation(reservation) ,'Not all instances  went to running')
        self.set_reservation(reservation)
        return reservation

    def MetaData(self):
        """
        This case was developed to test the metadata service of an instance for consistency.
        The following meta-data attributes are tested:
           - public-keys/0/openssh-key
           - security-groups
           - instance-id
           - local-ipv4
           - public-ipv4
           - ami-id
           - ami-launch-index
           - reservation-id
           - placement/availability-zone
           - kernel-id
           - public-hostname
           - local-hostname
           - hostname
           - ramdisk-id
           - instance-type
           - any bad metadata that shouldn't be present.
        Missing nodes
         ['block-device-mapping/',  'ami-manifest-path']
        If any of these tests fail, the test case will error out; logging the results.
        """
        if not self.reservation:
            reservation = self.tester.run_instance(**self.run_instance_params)
        else:
            reservation = self.reservation
        for instance in reservation.instances:
            ## Need to verify  the public key (could just be checking for a string of a certain length)
            self.assertTrue(re.match(instance.get_metadata("public-keys/0/openssh-key")[0].split('eucalyptus.')[-1], self.keypair.name), 'Incorrect public key in metadata')
            self.assertTrue(re.match(instance.get_metadata("security-groups")[0], self.group.name), 'Incorrect security group in metadata')
            # Need to validate block device mapping
            #self.assertTrue(re.search(instance_ssh.get_metadata("block-device-mapping/")[0], "")) 
            self.assertTrue(re.match(instance.get_metadata("instance-id")[0], instance.id), 'Incorrect instance id in metadata')
            self.assertTrue(re.match(instance.get_metadata("local-ipv4")[0] , instance.private_ip_address), 'Incorrect private ip in metadata')
            self.assertTrue(re.match(instance.get_metadata("public-ipv4")[0] , instance.ip_address), 'Incorrect public ip in metadata')
            self.assertTrue(re.match(instance.get_metadata("ami-id")[0], instance.image_id), 'Incorrect ami id in metadata')
            self.assertTrue(re.match(instance.get_metadata("ami-launch-index")[0], instance.ami_launch_index), 'Incorrect launch index in metadata')
            self.assertTrue(re.match(instance.get_metadata("reservation-id")[0], reservation.id), 'Incorrect reservation in metadata')
            self.assertTrue(re.match(instance.get_metadata("placement/availability-zone")[0], instance.placement), 'Incorrect availability-zone in metadata')
            self.assertTrue(re.match(instance.get_metadata("kernel-id")[0], instance.kernel),  'Incorrect kernel id in metadata')
            self.assertTrue(re.match(instance.get_metadata("public-hostname")[0], instance.public_dns_name), 'Incorrect public host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("local-hostname")[0], instance.private_dns_name), 'Incorrect private host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("hostname")[0], instance.private_dns_name), 'Incorrect host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("ramdisk-id")[0], instance.ramdisk ), 'Incorrect ramdisk in metadata') #instance-type
            self.assertTrue(re.match(instance.get_metadata("instance-type")[0], instance.instance_type ), 'Incorrect instance type in metadata')
            BAD_META_DATA_KEYS = ['foobar']
            for key in BAD_META_DATA_KEYS:
                self.assertTrue(re.search("Not Found", "".join(instance.get_metadata(key))), 'No fail message on invalid meta-data node')
        self.set_reservation(reservation)
        return reservation

    def DNSResolveCheck(self, zone=None):
        """
        This case was developed to test DNS resolution information for public/private DNS
        names and IP addresses.  The tested DNS resolution behavior is expected to follow
        AWS EC2.  The following tests are ran using the associated meta-data attributes:
           - check to see if Eucalyptus Dynamic DNS is configured
           - nslookup on hostname; checks to see if it matches local-ipv4
           - nslookup on local-hostname; check to see if it matches local-ipv4
           - nslookup on local-ipv4; check to see if it matches local-hostname
           - nslookup on public-hostname; check to see if it matches local-ipv4
           - nslookup on public-ipv4; check to see if it matches public-host
        If any of these tests fail, the test case will error out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            reservation = self.tester.run_instance(**self.run_instance_params)
        else:
            reservation = self.reservation

        for instance in reservation.instances:
            if not re.search("internal", instance.private_dns_name):
                self.tester.debug("Did not find instance DNS enabled, skipping test")
                self.set_reservation(reservation)
                return reservation
            # Test to see if Dynamic DNS has been configured #
            # Per AWS standard, resolution should have private hostname or private IP as a valid response
            # Perform DNS resolution against public IP and public DNS name
            # Perform DNS resolution against private IP and private DNS name
            # Check to see if nslookup was able to resolve
            assert isinstance(instance, EuInstance)
            # Check nslookup to resolve public DNS Name to local-ipv4 address
            self.assertTrue(instance.found("nslookup " + instance.public_dns_name + " " + self.tester.ec2.host, instance.private_ip_address), "Incorrect DNS resolution for hostname.")
            # Check nslookup to resolve public-ipv4 address to public DNS name
            if self.managed_network:
                self.assertTrue( instance.found("nslookup " +  instance.ip_address + " " + self.tester.ec2.host, instance.public_dns_name), "Incorrect DNS resolution for public IP address")
            # Check nslookup to resolve private DNS Name to local-ipv4 address
            if self.managed_network:
                self.assertTrue(instance.found("nslookup " + instance.private_dns_name + " " + self.tester.ec2.host, instance.private_ip_address), "Incorrect DNS resolution for private hostname.")
            # Check nslookup to resolve local-ipv4 address to private DNS name
            self.assertTrue(instance.found("nslookup " +  instance.private_ip_address + " " + self.tester.ec2.host, instance.private_dns_name), "Incorrect DNS resolution for private IP address")
        self.assertTrue(self.tester.ping(instance.public_dns_name))
        self.set_reservation(reservation)
        return reservation

    def Reboot(self, zone=None):
        """
        This case was developed to test IP connectivity and volume attachment after
        instance reboot.  The following tests are done for this test case:
                   - creates a 1 gig EBS volume, then attach volume
                   - reboot instance
                   - attempts to connect to instance via ssh
                   - checks to see if EBS volume is attached
                   - detaches volume
                   - deletes volume
        If any of these tests fail, the test case will error out; logging the results.
        """
        if zone is None:
            zone = self.zone
        if not self.reservation:
            reservation = self.tester.run_instance(**self.run_instance_params)
        else:
            reservation = self.reservation
        for instance in reservation.instances:
            ### Create 1GB volume in first AZ
            volume = self.tester.create_volume(instance.placement, 1)
            volume_device = instance.attach_volume(volume)
            ### Reboot instance
            instance.reboot_instance_and_verify(waitconnect=20)
            instance.detach_euvolume(volume)
            self.tester.delete_volume(volume)
        self.set_reservation(reservation)
        return reservation

    def Churn(self):
        """
        This case was developed to test robustness of Eucalyptus by starting instances,
        stopping them before they are running, and increase the time to terminate on each
        iteration.  This test case leverages the BasicInstanceChecks test case. The
        following steps are ran:
            - runs BasicInstanceChecks test case 5 times, 10 second apart.
            - While each test is running, run and terminate instances with a 10sec sleep in between.
            - When a test finishes, rerun BasicInstanceChecks test case.
        If any of these tests fail, the test case will error out; logging the results.
        """
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
            self.set_reservation(None)

        available_instances_before = self.tester.get_available_vms(zone=self.zone)

        ## Run through count iterations of test
        count = 4
        future_instances =[]

        with ThreadPoolExecutor(max_workers=count) as executor:
            ## Start asynchronous activity
            ## Run 5 basic instance check instances 10s apart
            for i in xrange(count):
                future_instances.append(executor.submit(self.BasicInstanceChecks))
                self.tester.sleep(10)

        with ThreadPoolExecutor(max_workers=count) as executor:
            ## Start asynchronous activity
            ## Terminate all instances
            for future in future_instances:
                executor.submit(self.tester.terminate_instances,future.result())

        def available_after_greater():
            return self.tester.get_available_vms(zone=self.zone) >= available_instances_before
        self.tester.wait_for_result(available_after_greater, result=True, timeout=360)

    def PrivateIPAddressing(self):
        """
        This case was developed to test instances that are launched with private-addressing
        set to True.  The tests executed are as follows:
            - run an instance with private-addressing set to True
            - allocate/associate/disassociate/release an Elastic IP to that instance
            - check to see if the instance went back to private addressing
        If any of these tests fail, the test case will error out; logging the results.
        """
        if self.reservation:
            for instance in self.reservation.instances:
                if instance.ip_address == instance.private_ip_address:
                    self.tester.debug("WARNING: System or Static mode detected, skipping PrivateIPAddressing")
                    return self.reservation
            self.tester.terminate_instances(self.reservation)
            self.set_reservation(None)
        reservation = self.tester.run_instance(private_addressing=True, **self.run_instance_params)
        for instance in reservation.instances:
            address = self.tester.allocate_address()
            self.assertTrue(address,'Unable to allocate address')
            self.tester.associate_address(instance, address)
            self.tester.sleep(30)
            instance.update()
            self.assertTrue( self.tester.ping(instance.ip_address), "Could not ping instance with new IP")
            address.disassociate()
            self.tester.sleep(30)
            instance.update()
            self.assertFalse(self.tester.ping(instance.ip_address), "Was able to ping instance that should have only had a private IP")
            address.release()
            if instance.ip_address != "0.0.0.0" and instance.ip_address != instance.private_ip_address:
                self.fail("Instance received a new public IP: " + instance.ip_address)
        self.tester.terminate_instances(self.reservation)
        self.set_reservation(None)
        return reservation

    def ReuseAddresses(self):
        """
        This case was developed to test when you run instances in a series, and make sure
        they get the same address.  The test launches an instance, checks the IP information,
        then terminates the instance. This test is launched 5 times in a row.  If there
        is an error, the test case will error out; logging the results.
        """
        prev_address = None
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
            self.set_reservation(None)
        for i in xrange(5):
            reservation = self.tester.run_instance(**self.run_instance_params)
            for instance in reservation.instances:
                if prev_address is not None:
                    self.assertTrue(re.search(str(prev_address) ,str(instance.ip_address)), str(prev_address) +" Address did not get reused but rather  " + str(instance.public_dns_name))
                prev_address = instance.ip_address
            self.tester.terminate_instances(reservation)
示例#7
0
class InstanceBasics(unittest.TestCase):
    def setUp(self, credpath=None):
        # Setup basic eutester object
        if credpath is None:
            credpath = arg_credpath
        self.tester = Eucaops( credpath=credpath)
        self.tester.poll_count = 120
        
        ### Add and authorize a group for the instance
        self.group = self.tester.add_group(group_name="group-" + str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name )
        self.tester.authorize_group_by_name(group_name=self.group.name, port=-1, protocol="icmp" )
        ### Generate a keypair for the instance
        self.keypair = self.tester.add_keypair( "keypair-" + str(time.time()))
        self.keypath = '%s/%s.pem' % (os.curdir, self.keypair.name)
        ### Use a random instance-store backed EMI if no cli option set 
        if arg_emi is False:
            self.image = self.tester.get_emi(root_device_type="instance-store")
        else: 
            self.image  = self.tester.get_emi(arg_emi)
        self.reservation = None
        self.private_addressing = False
        zones = self.tester.ec2.get_all_zones()
        self.zone = random.choice(zones).name

    
    def tearDown(self):
        if self.reservation is not None:
            self.assertTrue(self.tester.terminate_instances(self.reservation), "Unable to terminate instance(s)")
        self.tester.delete_group(self.group)
        self.tester.delete_keypair(self.keypair)
        os.remove(self.keypath)
        self.reservation = None
        self.group = None
        self.keypair = None
        self.tester = None
        self.ephemeral = None


    def BasicInstanceChecks(self, zone = None):
        """Instance checks including reachability and ephemeral storage"""
        if zone is None:
            zone = self.zone
        if self.reservation is None:
            self.reservation = self.tester.run_instance(self.image, keypair=self.keypair.name, group=self.group.name, zone=zone)
        for instance in self.reservation.instances:
            self.assertTrue( self.tester.wait_for_reservation(self.reservation) ,'Instance did not go to running')
            self.assertNotEqual( instance.public_dns_name, instance.private_ip_address, 'Public and private IP are the same')
            self.assertTrue( self.tester.ping(instance.public_dns_name), 'Could not ping instance')
            self.assertFalse( instance.found("ls -1 /dev/" + instance.rootfs_device + "2",  "No such file or directory"),  'Did not find ephemeral storage at ' + instance.rootfs_device + "2")
        return self.reservation
    
    def ElasticIps(self, zone = None):
        """ Basic test for elastic IPs
            Allocate an IP, associate it with an instance, ping the instance
            Disassociate the IP, ping the instance
            Release the address"""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(keypair=self.keypair.name, group=self.group.name,zone=zone)
        for instance in self.reservation.instances:
            address = self.tester.allocate_address()
            self.assertTrue(address,'Unable to allocate address')
            self.tester.associate_address(instance, address)
            instance.update()
            self.assertTrue( self.tester.ping(instance.public_dns_name), "Could not ping instance with new IP")
            self.tester.disassociate_address_from_instance(instance)
            self.tester.release_address(address)
            instance.update()
            self.assertTrue( self.tester.ping(instance.public_dns_name), "Could not ping after dissassociate")
        return self.reservation
    
    def MaxSmallInstances(self, available_small=None,zone = None):
        """Run the maximum m1.smalls available"""
        if available_small is None:
            available_small = self.tester.get_available_vms()
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,keypair=self.keypair.name, group=self.group.name,min=available_small, max=available_small, zone=zone)
        self.assertTrue( self.tester.wait_for_reservation(self.reservation) ,'Not all instances  went to running')
        return self.reservation
    
    def LargestInstance(self, zone = None): 
        """Run 1 of the largest instance c1.xlarge"""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,keypair=self.keypair.name, group=self.group.name,type="c1.xlarge",zone=zone)
        self.assertTrue( self.tester.wait_for_reservation(self.reservation) ,'Not all instances  went to running')
        return self.reservation
    
    def MetaData(self, zone=None):
        """Check metadata for consistency"""
        # Missing nodes
        # ['block-device-mapping/',  'ami-manifest-path']
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,keypair=self.keypair.name, group=self.group.name, zone=zone)
        for instance in self.reservation.instances:
            ## Need to verify  the public key (could just be checking for a string of a certain length)
            self.assertTrue(re.match(instance.get_metadata("public-keys/0/openssh-key")[0].split('eucalyptus.')[-1], self.keypair.name), 'Incorrect public key in metadata')
            self.assertTrue(re.match(instance.get_metadata("security-groups")[0], self.group.name), 'Incorrect security group in metadata') 
            # Need to validate block device mapping
            #self.assertTrue(re.search(instance_ssh.get_metadata("block-device-mapping/")[0], "")) 
            self.assertTrue(re.match(instance.get_metadata("instance-id")[0], instance.id), 'Incorrect instance id in metadata')  
            self.assertTrue(re.match(instance.get_metadata("local-ipv4")[0] , instance.private_ip_address), 'Incorrect private ip in metadata')
            self.assertTrue(re.match(instance.get_metadata("public-ipv4")[0] , instance.ip_address), 'Incorrect public ip in metadata')          
            self.assertTrue(re.match(instance.get_metadata("ami-id")[0], instance.image_id), 'Incorrect ami id in metadata')
            self.assertTrue(re.match(instance.get_metadata("ami-launch-index")[0], instance.ami_launch_index), 'Incorrect launch index in metadata')
            self.assertTrue(re.match(instance.get_metadata("reservation-id")[0], self.reservation.id), 'Incorrect reservation in metadata')
            self.assertTrue(re.match(instance.get_metadata("placement/availability-zone")[0], instance.placement), 'Incorrect availability-zone in metadata')
            self.assertTrue(re.match(instance.get_metadata("kernel-id")[0], instance.kernel),  'Incorrect kernel id in metadata')
            self.assertTrue(re.match(instance.get_metadata("public-hostname")[0], instance.public_dns_name), 'Incorrect public host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("local-hostname")[0], instance.private_dns_name), 'Incorrect private host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("hostname")[0], instance.dns_name), 'Incorrect host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("ramdisk-id")[0], instance.ramdisk ), 'Incorrect ramdisk in metadata') #instance-type
            self.assertTrue(re.match(instance.get_metadata("instance-type")[0], instance.instance_type ), 'Incorrect instance type in metadata')
            BAD_META_DATA_KEYS = ['foobar']
            for key in BAD_META_DATA_KEYS:
                self.assertTrue(re.search("Not Found", "".join(instance.get_metadata(key))), 'No fail message on invalid meta-data node')
        return self.reservation
           
    def DNSResolveCheck(self, zone=None):
        """Check DNS resolution information for public/private DNS names and IP addresses.  The DNS resolution behavior follows AWS EC2."""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,keypair=self.keypair.name, group=self.group.name, zone=zone)
        for instance in self.reservation.instances:
           
            # Test to see if Dynamic DNS has been configured # 
            if re.match("internal", instance.private_dns_name.split('eucalyptus.')[-1]):
                # Per AWS standard, resolution should have private hostname or private IP as a valid response
                # Perform DNS resolution against private IP and private DNS name
                # Check to see if nslookup was able to resolve
                self.assertTrue(re.search('answer\:', instance.sys("nslookup " +  instance.get_metadata("hostname")[0])[3]), "DNS lookup failed for hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-hostname returns local-ipv4 address
                self.assertTrue(re.search(instance.get_metadata("local-ipv4")[0], instance.sys("nslookup " + instance.get_metadata("hostname")[0])[5]), "Incorrect DNS resolution for hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(re.search('answer\:', instance.sys("nslookup " +  instance.get_metadata("local-hostname")[0])[3]), "DNS lookup failed for private hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-hostname returns local-ipv4 address
                self.assertTrue(re.search(instance.get_metadata("local-ipv4")[0], instance.sys("nslookup " + instance.get_metadata("local-hostname")[0])[5]), "Incorrect DNS resolution for private hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(re.search('answer\:', instance.sys("nslookup " +  instance.get_metadata("local-ipv4")[0])[3]), "DNS lookup failed for private IP address.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-ipv4 address returns local-hostname
                self.assertTrue(re.search(instance.get_metadata("local-hostname")[0], instance.sys("nslookup " +  instance.get_metadata("local-ipv4")[0])[4]), "Incorrect DNS resolution for private IP address")       
                # Perform DNS resolution against public IP and public DNS name
                # Check to see if nslookup was able to resolve
                self.assertTrue(re.search('answer\:', instance.sys("nslookup " +  instance.get_metadata("public-hostname")[0])[3]), "DNS lookup failed for public-hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on public-hostname returns local-ipv4 address
                self.assertTrue(re.search(instance.get_metadata("local-ipv4")[0], instance.sys("nslookup " + instance.get_metadata("public-hostname")[0])[5]), "Incorrect DNS resolution for public-hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(re.search('answer\:', instance.sys("nslookup " +  instance.get_metadata("public-ipv4")[0])[3]), "DNS lookup failed for public IP address.")
                # Since nslookup was able to resolve, now check to see if nslookup on public-ipv4 address returns public-hostname
                self.assertTrue(re.search(instance.get_metadata("public-hostname")[0], instance.sys("nslookup " +  instance.get_metadata("public-ipv4")[0])[4]), "Incorrect DNS resolution for public IP address")

        return self.reservation
           
    def DNSCheck(self, zone=None):
        """Check to make sure Dynamic DNS reports correct information for public/private IP address and DNS names"""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,keypair=self.keypair.name, group=self.group.name, zone=zone)
        for instance in self.reservation.instances:
           
            # Test to see if Dynamic DNS has been configured # 
            if re.match("internal", instance.private_dns_name.split('eucalyptus.')[-1]):
                # Make sure that private_ip_address is not the same as local-hostname
                self.assertFalse(re.match(instance.private_ip_address, instance.private_dns_name), 'local-ipv4 and local-hostname are the same with DNS on') 
                # Make sure that ip_address is not the same as public-hostname
                self.assertFalse(re.match(instance.ip_address, instance.public_dns_name), 'public-ipv4 and public-hostname are the same with DNS on')

        return self.reservation

    def Reboot(self, zone=None):
        """Reboot instance ensure IP connectivity and volumes stay attached"""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image, keypair=self.keypair.name, group=self.group.name, zone=zone)
        for instance in self.reservation.instances:
            ### Create 1GB volume in first AZ
            self.volume = self.tester.create_volume(instance.placement, 1)
            euvolume = EuVolume.make_euvol_from_vol(self.volume)
            self.volume_device = instance.attach_euvolume(euvolume)
            ### Reboot instance
            instance.reboot_instance_and_verify(waitconnect=20)
            instance.detach_euvolume(euvolume)
        return self.reservation
    
    def Churn(self, testcase="BasicInstanceChecks"):
        """Start instances and stop them before they are running, increase time to terminate on each iteration"""
        from multiprocessing import Process
        from multiprocessing import Queue
        ### Increase time to terminate by step seconds on each iteration
        step = 10
        
        ## Run through count iterations of test
        count = self.tester.get_available_vms("m1.small") / 2
        thread_pool = []
        queue_pool = []
        
        ## Start asynchronous activity
        ## Run 5 basic instance check instances 10s apart
        for i in xrange(count):
            q = Queue()
            queue_pool.append(q)
            p = Process(target=self.run_testcase_thread, args=(q, step * i,testcase))
            thread_pool.append(p)
            self.tester.debug("Starting Thread " + str(i) +" in " + str(step * i))
            p.start()

        ### While the other tests are running, run and terminate count instances with a 10s sleep in between
        for i in xrange(count):
            self.reservation = self.image.run()
            self.tester.debug("Sleeping for " + str(step) + " seconds before terminating instances")
            self.tester.sleep(step )
            for instance in self.reservation.instances:
                instance.terminate()
                self.assertTrue(self.tester.wait_for_instance(instance, "terminated"), "Instance did not go to terminated")
        
        ### Once the previous test is complete rerun the BasicInstanceChecks test case
        ### Wait for an instance to become available
        count = self.tester.get_available_vms("m1.small")
        poll_count = 30
        while poll_count > 0:
            self.tester.sleep(5)
            count = self.tester.get_available_vms("m1.small")
            if count > 0:
                self.tester.debug("There is an available VM to use for final test")
                break
            poll_count -= 1
        
        fail_count = 0
        ### Block until the script returns a result
        for queue in queue_pool:
            test_result = queue.get(True)
            self.tester.debug("Got Result: " + str(test_result) )
            fail_count += test_result

        for thread in thread_pool:
            thread.join()
        
        if fail_count > 0:
            raise Exception("Failure detected in one of the " + str(count)  + " Basic Instance tests")

        self.tester.debug("Successfully completed churn test")

    def PrivateIPAddressing(self, zone = None):
        """Basic test to run an instance with Private only IP
           and later allocate/associate/diassociate/release 
           an Elastic IP. In the process check after diassociate
           the instance has only got private IP or new Public IP
           gets associated to it"""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(keypair=self.keypair.name, group=self.group.name, private_addressing=True, zone=zone)
        for instance in self.reservation.instances:
            address = self.tester.allocate_address()
            self.assertTrue(address,'Unable to allocate address')
            self.assertTrue(self.tester.associate_address(instance, address))
            self.tester.sleep(30)
            instance.update()
            self.assertTrue( self.tester.ping(instance.public_dns_name), "Could not ping instance with new IP")
            address.disassociate()
            self.tester.sleep(30)
            instance.update()
            self.assertFalse( self.tester.ping(instance.public_dns_name), "Was able to ping instance that should have only had a private IP")
            address.release()
            if instance.public_dns_name != instance.private_dns_name:
                self.fail("Instance received a new public IP: " + instance.public_dns_name)
        return self.reservation
    
    def ReuseAddresses(self, zone = None):
        """ Run instances in series and ensure they get the same address"""
        prev_address = None
        if zone is None:
            zone = self.zone
        ### Run the test 5 times in a row
        for i in xrange(5):
            self.reservation = self.tester.run_instance(keypair=self.keypair.name, group=self.group.name, zone=zone)
            for instance in self.reservation.instances:
                if prev_address is not None:
                    self.assertTrue(re.search(str(prev_address) ,str(instance.public_dns_name)), str(prev_address) +" Address did not get reused but rather  " + str(instance.public_dns_name))
                prev_address = instance.public_dns_name
            self.tester.terminate_instances(self.reservation)
            
    def run_testcase_thread(self, queue,delay = 20, name="MetaData"):
        ### Thread that runs a testcase (function) and returns its pass or fail result
        self.tester.sleep(delay)
        try:
            result = unittest.TextTestRunner(verbosity=2).run(InstanceBasics(name))
        except Exception, e:
            queue.put(1)
            raise e
        if result.wasSuccessful():
            self.tester.debug("Passed test: " + name)
            queue.put(0)
            return False
        else:
            self.tester.debug("Failed test: " + name)
            queue.put(1)
            return True
示例#8
0
class PopulateUpgrade(EutesterTestCase):
    def __init__(self, extra_args= None):
        self.setuptestcase()
        self.setup_parser()
        if extra_args:
            for arg in extra_args:
                self.parser.add_argument(arg)
        self.get_args()
        # Setup basic eutester object
        self.tester = Eucaops( credpath=self.args.credpath, config_file=self.args.config,password=self.args.password)
        self.tester.poll_count = 120

        self.security_groups = []

        ### Generate a keypair for the instance
        self.keypair = self.tester.add_keypair( "keypair-" + str(time.time()))
        self.keypath = '%s/%s.pem' % (os.curdir, self.keypair.name)
        self.image = self.args.emi
        if not self.image:
            self.image = self.tester.get_emi(root_device_type="instance-store")
        self.address = None
        self.volume = None
        self.snapshot = None
        self.private_addressing = False
        zones = self.tester.ec2.get_all_zones()
        self.zone = random.choice(zones).name
        self.reservation = None

    def clean_method(self):
        pass

    def Instances(self, type="instance-store"):
        """
        This case was developed to run through a series of basic instance tests.
             The tests are as follows:
                   - execute run_instances command
                   - make sure that public DNS name and private IP aren't the same
                       (This is for Managed/Managed-NOVLAN networking modes)
                   - test to see if instance is ping-able
                   - test to make sure that instance is accessible via ssh
                       (ssh into instance and run basic ls command)
             If any of these tests fail, the test case will error out, logging the results.
        """
        test_image = self.tester.get_emi(root_device_type=type)

        ### Add and authorize a group for the instance
        self.group = self.tester.add_group(group_name="group-" + str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name )
        self.tester.authorize_group_by_name(group_name=self.group.name, port=-1, protocol="icmp" )

        self.security_groups.append(self.group)

        # Test: INSTANCESTORE VOLATTACH:no ADDR:user
        instance_1 = self.tester.run_instance(test_image, keypair=self.keypair.name, group=self.group.name).instances[0]
        instance_1_address = self.tester.allocate_address()
        self.tester.associate_address(instance=instance_1, address=instance_1_address)

        # Test: INSTANCESTORE VOLATTACH:no ADDR:system
        instance_2 = self.tester.run_instance(test_image, keypair=self.keypair.name, group=self.group.name).instances[0]

        # Test: INSTANCESTORE VOLATTACH:no ADDR:system
        instance_3 = self.tester.run_instance(test_image, group=self.group.name, private_addressing=True, is_reachable=False).instances[0]

        # Test: INSTANCESTORE VOLATTACH:yes ADDR:user
        instance_4 = self.tester.run_instance(test_image, keypair=self.keypair.name, group=self.group.name).instances[0]
        instance_4_address = self.tester.allocate_address()
        self.tester.associate_address(instance=instance_4, address=instance_4_address)
        volume = self.tester.create_volume(zone=self.zone)
        instance_4.attach_volume(volume=volume)

        # Test: INSTANCESTORE VOLATTACH:yes ADDR:system
        instance_5 = self.tester.run_instance(test_image, keypair=self.keypair.name, group=self.group.name).instances[0]
        volume = self.tester.create_volume(zone=self.zone)
        instance_5.attach_volume(volume=volume)

        self.group = self.tester.add_group(group_name="group-" + str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name )
        self.tester.authorize_group_by_name(group_name=self.group.name, port=-1, protocol="icmp" )
        self.security_groups.append(self.group)
        # Test: INSTANCESTORE VOLATTACH:yes ADDR:system
        instance_6 = self.tester.run_instance(test_image, group=self.group.name, private_addressing=True, is_reachable=False).instances[0]

    def PopulateAll(self):
        self.Instances("instance-store")
        self.Instances("ebs")
示例#9
0
class InstanceBasics(EutesterTestCase):
    def __init__( self, name="InstanceBasics", credpath=None, region=None, config_file=None, password=None, emi=None, zone=None,
                  user_data=None, instance_user=None, **kwargs):
        """
        EC2 API tests focused on instance store instances

        :param credpath: Path to directory containing eucarc file
        :param region: EC2 Region to run testcase in
        :param config_file: Configuration file path
        :param password: SSH password for bare metal machines if config is passed and keys arent synced
        :param emi: Image id to use for test
        :param zone: Availability Zone to run test in
        :param user_data: User Data to pass to instance
        :param instance_user: User to login to instance as
        :param kwargs: Additional arguments
        """
        super(InstanceBasics, self).__init__(name=name)
        self.get_args()
        self.show_args()
        for kw in kwargs:
            print 'Setting kwarg:'+str(kw)+" to "+str(kwargs[kw])
            self.set_arg(kw ,kwargs[kw])
        self.show_args()
        if self.args.region:
            self.tester = EC2ops(credpath=self.args.redpath, region=self.args.region)
        else:
            self.tester = Eucaops(config_file=self.args.config_file,
                                  password=self.args.password,
                                  credpath=self.args.credpath)
        self.instance_timeout = 600

        ### Add and authorize a group for the instance
        self.group = self.tester.add_group(group_name="group-" + str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name)
        self.tester.authorize_group_by_name(group_name=self.group.name, port=-1, protocol="icmp")
        ### Generate a keypair for the instance
        self.keypair = self.tester.add_keypair("keypair-" + str(time.time()))
        self.keypath = '%s/%s.pem' % (os.curdir, self.keypair.name)
        if emi:
            self.image = self.tester.get_emi(emi=self.args.emi)
        else:
            self.image = self.tester.get_emi(root_device_type="instance-store", basic_image=True)
        self.address = None
        self.volume = None
        self.private_addressing = False
        if not self.args.zone:
            zones = self.tester.ec2.get_all_zones()
            self.zone = random.choice(zones).name
        else:
            self.zone = self.args.zone
        self.reservation = None
        self.reservation_lock = threading.Lock()
        self.run_instance_params = {'image': self.image,
                                    'user_data': self.args.user_data,
                                    'username': self.args.instance_user,
                                    'keypair': self.keypair.name,
                                    'group': self.group.name,
                                    'zone': self.zone,
                                    'return_reservation': True,
                                    'timeout': self.instance_timeout}
        self.managed_network = True

        ### If I have access to the underlying infrastructure I can look
        ### at the network mode and only run certain tests where it makes sense
        if hasattr(self.tester, "service_manager"):
            cc = self.tester.get_component_machines("cc")[0]
            network_mode = cc.sys("cat " + self.tester.eucapath + "/etc/eucalyptus/eucalyptus.conf | grep MODE")[0]
            if re.search("(SYSTEM|STATIC)", network_mode):
                self.managed_network = False

    def set_reservation(self, reservation):
        self.reservation_lock.acquire()
        self.reservation = reservation
        self.reservation_lock.release()

    def clean_method(self):
        self.tester.cleanup_artifacts()

    def BasicInstanceChecks(self):
        """
        This case was developed to run through a series of basic instance tests.
             The tests are as follows:
                   - execute run_instances command
                   - make sure that public DNS name and private IP aren't the same
                       (This is for Managed/Managed-NOVLAN networking modes)
                   - test to see if instance is ping-able
                   - test to make sure that instance is accessible via ssh
                       (ssh into instance and run basic ls command)
             If any of these tests fail, the test case will error out, logging the results.
        """
        reservation = self.tester.run_image(**self.run_instance_params)
        for instance in reservation.instances:
            self.assertTrue(self.tester.wait_for_reservation(reservation), 'Instance did not go to running')
            self.assertTrue(self.tester.ping(instance.ip_address), 'Could not ping instance')
            if self.image.virtualization_type == "paravirtual":
                paravirtual_ephemeral = "/dev/" + instance.rootfs_device + "2"
                self.assertFalse(instance.found("ls -1 " + paravirtual_ephemeral,  "No such file or directory"),
                                 "Did not find ephemeral storage at " + paravirtual_ephemeral)
            elif self.image.virtualization_type == "hvm":
                hvm_ephemeral = "/dev/" + instance.block_device_prefix + "b"
                self.assertFalse(instance.found("ls -1 " + hvm_ephemeral,  "No such file or directory"),
                                 "Did not find ephemeral storage at " + hvm_ephemeral)
            self.debug("Pinging instance public IP from inside instance")
            instance.sys('ping -c 1 ' + instance.ip_address, code=0)
            self.debug("Pinging instance private IP from inside instance")
            instance.sys('ping -c 1 ' + instance.private_ip_address, code=0)
        self.set_reservation(reservation)
        return reservation

    def ElasticIps(self):
        """
       This case was developed to test elastic IPs in Eucalyptus. This test case does
       not test instances that are launched using private-addressing option.
       The test case executes the following tests:
           - allocates an IP, associates the IP to the instance, then pings the instance.
           - disassociates the allocated IP, then pings the instance.
           - releases the allocated IP address
       If any of the tests fail, the test case will error out, logging the results.
        """
        if not self.reservation:
            reservation = self.tester.run_image(**self.run_instance_params)
        else:
            reservation = self.reservation

        for instance in reservation.instances:
            if instance.ip_address == instance.private_ip_address:
                self.tester.debug("WARNING: System or Static mode detected, skipping ElasticIps")
                return reservation
            domain = None
            if instance.vpc_id:
                domain = 'vpc' # Set domain to 'vpc' for use with instance in a VPC
            self.address = self.tester.allocate_address(domain=domain)
            self.assertTrue(self.address, 'Unable to allocate address')
            self.tester.associate_address(instance, self.address)
            instance.update()
            self.assertTrue(self.tester.ping(instance.ip_address), "Could not ping instance with new IP")
            self.tester.disassociate_address_from_instance(instance)
            self.tester.release_address(self.address)
            self.address = None
            assert isinstance(instance, EuInstance)
            self.tester.sleep(5)
            instance.update()
            self.assertTrue(self.tester.ping(instance.ip_address), "Could not ping after dissassociate")
        self.set_reservation(reservation)
        return reservation

    def MultipleInstances(self):
        """
        This case was developed to test the maximum number of m1.small vm types a configured
        cloud can run.  The test runs the maximum number of m1.small vm types allowed, then
        tests to see if all the instances reached a running state.  If there is a failure,
        the test case errors out; logging the results.
        """
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
            self.set_reservation(None)

        reservation = self.tester.run_image(min=2, max=2, **self.run_instance_params)
        self.assertTrue(self.tester.wait_for_reservation(reservation), 'Not all instances  went to running')
        self.set_reservation(reservation)
        return reservation

    def LargestInstance(self):
        """
        This case was developed to test the maximum number of c1.xlarge vm types a configured
        cloud can run.  The test runs the maximum number of c1.xlarge vm types allowed, then
        tests to see if all the instances reached a running state.  If there is a failure,
        the test case errors out; logging the results.
        """
        if self.reservation:
            self.tester.terminate_instances(self.reservation)
            self.set_reservation(None)
        reservation = self.tester.run_image(type="c1.xlarge", **self.run_instance_params)
        self.assertTrue(self.tester.wait_for_reservation(reservation), 'Not all instances  went to running')
        self.set_reservation(reservation)
        return reservation

    def MetaData(self):
        """
        This case was developed to test the metadata service of an instance for consistency.
        The following meta-data attributes are tested:
           - public-keys/0/openssh-key
           - security-groups
           - instance-id
           - local-ipv4
           - public-ipv4
           - ami-id
           - ami-launch-index
           - reservation-id
           - placement/availability-zone
           - kernel-id
           - public-hostname
           - local-hostname
           - hostname
           - ramdisk-id
           - instance-type
           - any bad metadata that shouldn't be present.
        Missing nodes
         ['block-device-mapping/',  'ami-manifest-path']
        If any of these tests fail, the test case will error out; logging the results.
        """
        if not self.reservation:
            reservation = self.tester.run_image(**self.run_instance_params)
        else:
            reservation = self.reservation
        for instance in reservation.instances:
            ## Need to verify  the public key (could just be checking for a string of a certain length)
            self.assertTrue(re.match(instance.get_metadata("public-keys/0/openssh-key")[0].split('eucalyptus.')[-1],
                                     self.keypair.name), 'Incorrect public key in metadata')
            self.assertTrue(re.match(instance.get_metadata("security-groups")[0], self.group.name),
                            'Incorrect security group in metadata')
            # Need to validate block device mapping
            #self.assertTrue(re.search(instance_ssh.get_metadata("block-device-mapping/")[0], "")) 
            self.assertTrue(re.match(instance.get_metadata("instance-id")[0], instance.id),
                            'Incorrect instance id in metadata')
            self.assertTrue(re.match(instance.get_metadata("local-ipv4")[0], instance.private_ip_address),
                            'Incorrect private ip in metadata')
            self.assertTrue(re.match(instance.get_metadata("public-ipv4")[0], instance.ip_address),
                            'Incorrect public ip in metadata')
            self.assertTrue(re.match(instance.get_metadata("ami-id")[0], instance.image_id),
                            'Incorrect ami id in metadata')
            self.assertTrue(re.match(instance.get_metadata("ami-launch-index")[0], instance.ami_launch_index),
                            'Incorrect launch index in metadata')
            self.assertTrue(re.match(instance.get_metadata("reservation-id")[0], reservation.id),
                            'Incorrect reservation in metadata')
            self.assertTrue(re.match(instance.get_metadata("placement/availability-zone")[0], instance.placement),
                            'Incorrect availability-zone in metadata')
            if self.image.virtualization_type == "paravirtual":
                self.assertTrue(re.match(instance.get_metadata("kernel-id")[0], instance.kernel),
                                'Incorrect kernel id in metadata')
                self.assertTrue(re.match(instance.get_metadata("ramdisk-id")[0], instance.ramdisk),
                                'Incorrect ramdisk in metadata')
            self.assertTrue(re.match(instance.get_metadata("public-hostname")[0], instance.public_dns_name),
                            'Incorrect public host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("local-hostname")[0], instance.private_dns_name),
                            'Incorrect private host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("hostname")[0], instance.private_dns_name),
                            'Incorrect host name in metadata')
            self.assertTrue(re.match(instance.get_metadata("instance-type")[0], instance.instance_type),
                            'Incorrect instance type in metadata')
            bad_meta_data_keys = ['foobar']
            for key in bad_meta_data_keys:
                self.assertTrue(re.search("Not Found", "".join(instance.get_metadata(key))),
                                'No fail message on invalid meta-data node')
        self.set_reservation(reservation)
        return reservation

    def DNSResolveCheck(self):
        """
        This case was developed to test DNS resolution information for public/private DNS
        names and IP addresses.  The tested DNS resolution behavior is expected to follow

        AWS EC2.  The following tests are ran using the associated meta-data attributes:
           - check to see if Eucalyptus Dynamic DNS is configured
           - nslookup on hostname; checks to see if it matches local-ipv4
           - nslookup on local-hostname; check to see if it matches local-ipv4
           - nslookup on local-ipv4; check to see if it matches local-hostname
           - nslookup on public-hostname; check to see if it matches local-ipv4
           - nslookup on public-ipv4; check to see if it matches public-host
        If any of these tests fail, the test case will error out; logging the results.
        """
        if not self.reservation:
            reservation = self.tester.run_image(**self.run_instance_params)
        else:
            reservation = self.reservation

        def validate_instance_dns():
            try:
                for instance in reservation.instances:
                    if not re.search("internal", instance.private_dns_name):
                        self.tester.debug("Did not find instance DNS enabled, skipping test")
                        self.set_reservation(reservation)
                        return reservation
                    self.debug('\n'
                               '# Test to see if Dynamic DNS has been configured \n'
                               '# Per AWS standard, resolution should have private hostname or '
                               'private IP as a valid response\n'
                               '# Perform DNS resolution against public IP and public DNS name\n'
                               '# Perform DNS resolution against private IP and private DNS name\n'
                               '# Check to see if nslookup was able to resolve\n')
                    assert isinstance(instance, EuInstance)
                    self.debug('Check nslookup to resolve public DNS Name to local-ipv4 address')
                    self.assertTrue(instance.found("nslookup " + instance.public_dns_name,
                                                   instance.private_ip_address), "Incorrect DNS resolution for hostname.")
                    self.debug('Check nslookup to resolve public-ipv4 address to public DNS name')
                    if self.managed_network:
                        self.assertTrue(instance.found("nslookup " + instance.ip_address,
                                                       instance.public_dns_name),
                                        "Incorrect DNS resolution for public IP address")
                    self.debug('Check nslookup to resolve private DNS Name to local-ipv4 address')
                    if self.managed_network:
                        self.assertTrue(instance.found("nslookup " + instance.private_dns_name,
                                                       instance.private_ip_address),
                                        "Incorrect DNS resolution for private hostname.")
                    self.debug('Check nslookup to resolve local-ipv4 address to private DNS name')
                    self.assertTrue(instance.found("nslookup " + instance.private_ip_address,
                                                   instance.private_dns_name),
                                    "Incorrect DNS resolution for private IP address")
                    self.debug('Attempt to ping instance public_dns_name')
                    self.assertTrue(self.tester.ping(instance.public_dns_name))
                    return True
            except Exception, e:
                return False
        self.tester.wait_for_result(validate_instance_dns, True, timeout=120)
        self.set_reservation(reservation)
        return reservation
示例#10
0
class InstanceBasics(unittest.TestCase):
    def setUp(self, credpath=None):
        # Setup basic eutester object
        if credpath is None:
            credpath = arg_credpath
        self.tester = Eucaops(credpath=credpath)
        self.tester.poll_count = 120

        ### Add and authorize a group for the instance
        self.group = self.tester.add_group(group_name="group-" +
                                           str(time.time()))
        self.tester.authorize_group_by_name(group_name=self.group.name)
        self.tester.authorize_group_by_name(group_name=self.group.name,
                                            port=-1,
                                            protocol="icmp")
        ### Generate a keypair for the instance
        self.keypair = self.tester.add_keypair("keypair-" + str(time.time()))
        self.keypath = '%s/%s.pem' % (os.curdir, self.keypair.name)
        self.image = self.tester.get_emi(root_device_type="instance-store")
        self.reservation = None
        self.private_addressing = False
        zones = self.tester.ec2.get_all_zones()
        self.zone = random.choice(zones).name

    def tearDown(self):
        if self.reservation is not None:
            self.assertTrue(self.tester.terminate_instances(self.reservation),
                            "Unable to terminate instance(s)")
        self.tester.delete_group(self.group)
        self.tester.delete_keypair(self.keypair)
        os.remove(self.keypath)
        self.reservation = None
        self.group = None
        self.keypair = None
        self.tester = None
        self.ephemeral = None

    def BasicInstanceChecks(self, zone=None):
        """Instance checks including reachability and ephemeral storage"""
        if zone is None:
            zone = self.zone
        if self.reservation is None:
            self.reservation = self.tester.run_instance(
                self.image,
                keypair=self.keypair.name,
                group=self.group.name,
                zone=zone)
        for instance in self.reservation.instances:
            self.assertTrue(self.tester.wait_for_reservation(self.reservation),
                            'Instance did not go to running')
            self.assertNotEqual(instance.public_dns_name,
                                instance.private_ip_address,
                                'Public and private IP are the same')
            self.assertTrue(self.tester.ping(instance.public_dns_name),
                            'Could not ping instance')
            self.assertFalse(
                instance.found("ls -1 /dev/" + instance.rootfs_device + "2",
                               "No such file or directory"),
                'Did not find ephemeral storage at ' + instance.rootfs_device +
                "2")
        return self.reservation

    def ElasticIps(self, zone=None):
        """ Basic test for elastic IPs
            Allocate an IP, associate it with an instance, ping the instance
            Disassociate the IP, ping the instance
            Release the address"""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(keypair=self.keypair.name,
                                                    group=self.group.name,
                                                    zone=zone)
        for instance in self.reservation.instances:
            address = self.tester.allocate_address()
            self.assertTrue(address, 'Unable to allocate address')
            self.tester.associate_address(instance, address)
            instance.update()
            self.assertTrue(self.tester.ping(instance.public_dns_name),
                            "Could not ping instance with new IP")
            self.tester.disassociate_address_from_instance(instance)
            self.tester.release_address(address)
            instance.update()
            self.assertTrue(self.tester.ping(instance.public_dns_name),
                            "Could not ping after dissassociate")
        return self.reservation

    def MaxSmallInstances(self, available_small=None, zone=None):
        """Run the maximum m1.smalls available"""
        if available_small is None:
            available_small = self.tester.get_available_vms()
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,
                                                    keypair=self.keypair.name,
                                                    group=self.group.name,
                                                    min=available_small,
                                                    max=available_small,
                                                    zone=zone)
        self.assertTrue(self.tester.wait_for_reservation(self.reservation),
                        'Not all instances  went to running')
        return self.reservation

    def LargestInstance(self, zone=None):
        """Run 1 of the largest instance c1.xlarge"""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,
                                                    keypair=self.keypair.name,
                                                    group=self.group.name,
                                                    type="c1.xlarge",
                                                    zone=zone)
        self.assertTrue(self.tester.wait_for_reservation(self.reservation),
                        'Not all instances  went to running')
        return self.reservation

    def MetaData(self, zone=None):
        """Check metadata for consistency"""
        # Missing nodes
        # ['block-device-mapping/',  'ami-manifest-path']
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,
                                                    keypair=self.keypair.name,
                                                    group=self.group.name,
                                                    zone=zone)
        for instance in self.reservation.instances:
            ## Need to verify  the public key (could just be checking for a string of a certain length)
            self.assertTrue(
                re.match(
                    instance.get_metadata("public-keys/0/openssh-key")
                    [0].split('eucalyptus.')[-1], self.keypair.name),
                'Incorrect public key in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("security-groups")[0],
                    self.group.name), 'Incorrect security group in metadata')
            # Need to validate block device mapping
            #self.assertTrue(re.search(instance_ssh.get_metadata("block-device-mapping/")[0], ""))
            self.assertTrue(
                re.match(instance.get_metadata("instance-id")[0], instance.id),
                'Incorrect instance id in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("local-ipv4")[0],
                    instance.private_ip_address),
                'Incorrect private ip in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("public-ipv4")[0],
                    instance.ip_address), 'Incorrect public ip in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("ami-id")[0], instance.image_id),
                'Incorrect ami id in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("ami-launch-index")[0],
                    instance.ami_launch_index),
                'Incorrect launch index in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("reservation-id")[0],
                    self.reservation.id), 'Incorrect reservation in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("placement/availability-zone")[0],
                    instance.placement),
                'Incorrect availability-zone in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("kernel-id")[0], instance.kernel),
                'Incorrect kernel id in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("public-hostname")[0],
                    instance.public_dns_name),
                'Incorrect public host name in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("local-hostname")[0],
                    instance.private_dns_name),
                'Incorrect private host name in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("hostname")[0], instance.dns_name),
                'Incorrect host name in metadata')
            self.assertTrue(
                re.match(
                    instance.get_metadata("ramdisk-id")[0], instance.ramdisk),
                'Incorrect ramdisk in metadata')  #instance-type
            self.assertTrue(
                re.match(
                    instance.get_metadata("instance-type")[0],
                    instance.instance_type),
                'Incorrect instance type in metadata')
            BAD_META_DATA_KEYS = ['foobar']
            for key in BAD_META_DATA_KEYS:
                self.assertTrue(
                    re.search("Not Found",
                              "".join(instance.get_metadata(key))),
                    'No fail message on invalid meta-data node')
        return self.reservation

    def DNSResolveCheck(self, zone=None):
        """Check DNS resolution information for public/private DNS names and IP addresses.  The DNS resolution behavior follows AWS EC2."""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,
                                                    keypair=self.keypair.name,
                                                    group=self.group.name,
                                                    zone=zone)
        for instance in self.reservation.instances:

            # Test to see if Dynamic DNS has been configured #
            if re.match("internal",
                        instance.private_dns_name.split('eucalyptus.')[-1]):
                # Per AWS standard, resolution should have private hostname or private IP as a valid response
                # Perform DNS resolution against private IP and private DNS name
                # Check to see if nslookup was able to resolve
                self.assertTrue(
                    re.search(
                        'answer\:',
                        instance.sys("nslookup " +
                                     instance.get_metadata("hostname")[0])[3]),
                    "DNS lookup failed for hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-hostname returns local-ipv4 address
                self.assertTrue(
                    re.search(
                        instance.get_metadata("local-ipv4")[0],
                        instance.sys("nslookup " +
                                     instance.get_metadata("hostname")[0])[5]),
                    "Incorrect DNS resolution for hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(
                    re.search(
                        'answer\:',
                        instance.sys(
                            "nslookup " +
                            instance.get_metadata("local-hostname")[0])[3]),
                    "DNS lookup failed for private hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-hostname returns local-ipv4 address
                self.assertTrue(
                    re.search(
                        instance.get_metadata("local-ipv4")[0],
                        instance.sys(
                            "nslookup " +
                            instance.get_metadata("local-hostname")[0])[5]),
                    "Incorrect DNS resolution for private hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(
                    re.search(
                        'answer\:',
                        instance.sys("nslookup " +
                                     instance.get_metadata("local-ipv4")[0])
                        [3]), "DNS lookup failed for private IP address.")
                # Since nslookup was able to resolve, now check to see if nslookup on local-ipv4 address returns local-hostname
                self.assertTrue(
                    re.search(
                        instance.get_metadata("local-hostname")[0],
                        instance.sys("nslookup " +
                                     instance.get_metadata("local-ipv4")[0])
                        [4]),
                    "Incorrect DNS resolution for private IP address")
                # Perform DNS resolution against public IP and public DNS name
                # Check to see if nslookup was able to resolve
                self.assertTrue(
                    re.search(
                        'answer\:',
                        instance.sys(
                            "nslookup " +
                            instance.get_metadata("public-hostname")[0])[3]),
                    "DNS lookup failed for public-hostname.")
                # Since nslookup was able to resolve, now check to see if nslookup on public-hostname returns local-ipv4 address
                self.assertTrue(
                    re.search(
                        instance.get_metadata("local-ipv4")[0],
                        instance.sys(
                            "nslookup " +
                            instance.get_metadata("public-hostname")[0])[5]),
                    "Incorrect DNS resolution for public-hostname.")
                # Check to see if nslookup was able to resolve
                self.assertTrue(
                    re.search(
                        'answer\:',
                        instance.sys("nslookup " +
                                     instance.get_metadata("public-ipv4")[0])
                        [3]), "DNS lookup failed for public IP address.")
                # Since nslookup was able to resolve, now check to see if nslookup on public-ipv4 address returns public-hostname
                self.assertTrue(
                    re.search(
                        instance.get_metadata("public-hostname")[0],
                        instance.sys("nslookup " +
                                     instance.get_metadata("public-ipv4")[0])
                        [4]), "Incorrect DNS resolution for public IP address")

        return self.reservation

    def DNSCheck(self, zone=None):
        """Check to make sure Dynamic DNS reports correct information for public/private IP address and DNS names"""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,
                                                    keypair=self.keypair.name,
                                                    group=self.group.name,
                                                    zone=zone)
        for instance in self.reservation.instances:

            # Test to see if Dynamic DNS has been configured #
            if re.match("internal",
                        instance.private_dns_name.split('eucalyptus.')[-1]):
                # Make sure that private_ip_address is not the same as local-hostname
                self.assertFalse(
                    re.match(instance.private_ip_address,
                             instance.private_dns_name),
                    'local-ipv4 and local-hostname are the same with DNS on')
                # Make sure that ip_address is not the same as public-hostname
                self.assertFalse(
                    re.match(instance.ip_address, instance.public_dns_name),
                    'public-ipv4 and public-hostname are the same with DNS on')

        return self.reservation

    def Reboot(self, zone=None):
        """Reboot instance ensure IP connectivity and volumes stay attached"""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(self.image,
                                                    keypair=self.keypair.name,
                                                    group=self.group.name,
                                                    zone=zone)
        for instance in self.reservation.instances:
            ### Create 1GB volume in first AZ
            self.volume = self.tester.create_volume(instance.placement, 1)
            euvolume = EuVolume.make_euvol_from_vol(self.volume)
            self.volume_device = instance.attach_euvolume(euvolume)
            ### Reboot instance
            instance.reboot_instance_and_verify(waitconnect=20)
            instance.detach_euvolume(euvolume)
        return self.reservation

    def Churn(self, testcase="BasicInstanceChecks"):
        """Start instances and stop them before they are running, increase time to terminate on each iteration"""
        from multiprocessing import Process
        from multiprocessing import Queue
        ### Increase time to terminate by step seconds on each iteration
        step = 10

        ## Run through count iterations of test
        count = self.tester.get_available_vms("m1.small") / 2
        thread_pool = []
        queue_pool = []

        ## Start asynchronous activity
        ## Run 5 basic instance check instances 10s apart
        for i in xrange(count):
            q = Queue()
            queue_pool.append(q)
            p = Process(target=self.run_testcase_thread,
                        args=(q, step * i, testcase))
            thread_pool.append(p)
            self.tester.debug("Starting Thread " + str(i) + " in " +
                              str(step * i))
            p.start()

        ### While the other tests are running, run and terminate count instances with a 10s sleep in between
        for i in xrange(count):
            self.reservation = self.image.run()
            self.tester.debug("Sleeping for " + str(step) +
                              " seconds before terminating instances")
            self.tester.sleep(step)
            for instance in self.reservation.instances:
                instance.terminate()
                self.assertTrue(
                    self.tester.wait_for_instance(instance, "terminated"),
                    "Instance did not go to terminated")

        ### Once the previous test is complete rerun the BasicInstanceChecks test case
        ### Wait for an instance to become available
        count = self.tester.get_available_vms("m1.small")
        poll_count = 30
        while poll_count > 0:
            self.tester.sleep(5)
            count = self.tester.get_available_vms("m1.small")
            if count > 0:
                self.tester.debug(
                    "There is an available VM to use for final test")
                break
            poll_count -= 1

        fail_count = 0
        ### Block until the script returns a result
        for queue in queue_pool:
            test_result = queue.get(True)
            self.tester.debug("Got Result: " + str(test_result))
            fail_count += test_result

        for thread in thread_pool:
            thread.join()

        if fail_count > 0:
            raise Exception("Failure detected in one of the " + str(count) +
                            " Basic Instance tests")

        self.tester.debug("Successfully completed churn test")

    def PrivateIPAddressing(self, zone=None):
        """Basic test to run an instance with Private only IP
           and later allocate/associate/diassociate/release 
           an Elastic IP. In the process check after diassociate
           the instance has only got private IP or new Public IP
           gets associated to it"""
        if zone is None:
            zone = self.zone
        self.reservation = self.tester.run_instance(keypair=self.keypair.name,
                                                    group=self.group.name,
                                                    private_addressing=True,
                                                    zone=zone)
        for instance in self.reservation.instances:
            address = self.tester.allocate_address()
            self.assertTrue(address, 'Unable to allocate address')
            self.assertTrue(self.tester.associate_address(instance, address))
            self.tester.sleep(30)
            instance.update()
            self.assertTrue(self.tester.ping(instance.public_dns_name),
                            "Could not ping instance with new IP")
            address.disassociate()
            self.tester.sleep(30)
            instance.update()
            self.assertFalse(
                self.tester.ping(instance.public_dns_name),
                "Was able to ping instance that should have only had a private IP"
            )
            address.release()
            if instance.public_dns_name != instance.private_dns_name:
                self.fail("Instance received a new public IP: " +
                          instance.public_dns_name)
        return self.reservation

    def ReuseAddresses(self, zone=None):
        """ Run instances in series and ensure they get the same address"""
        prev_address = None
        if zone is None:
            zone = self.zone
        ### Run the test 5 times in a row
        for i in xrange(5):
            self.reservation = self.tester.run_instance(
                keypair=self.keypair.name, group=self.group.name, zone=zone)
            for instance in self.reservation.instances:
                if prev_address is not None:
                    self.assertTrue(
                        re.search(str(prev_address),
                                  str(instance.public_dns_name)),
                        str(prev_address) +
                        " Address did not get reused but rather  " +
                        str(instance.public_dns_name))
                prev_address = instance.public_dns_name
            self.tester.terminate_instances(self.reservation)

    def run_testcase_thread(self, queue, delay=20, name="MetaData"):
        ### Thread that runs a testcase (function) and returns its pass or fail result
        self.tester.sleep(delay)
        try:
            result = unittest.TextTestRunner(verbosity=2).run(
                InstanceBasics(name))
        except Exception, e:
            queue.put(1)
            raise e
        if result.wasSuccessful():
            self.tester.debug("Passed test: " + name)
            queue.put(0)
            return False
        else:
            self.tester.debug("Failed test: " + name)
            queue.put(1)
            return True