class SOSreport(EutesterTestCase): def __init__(self): self.setuptestcase() self.setup_parser() self.start_time = int(time.time()) self.parser.add_argument("--ticket-number", default=str(self.start_time)) self.parser.add_argument("--timeout", default=1200, type=int) self.parser.add_argument("--remote-dir", default="/root/") self.parser.add_argument("--local-dir", default=os.getcwd()) self.parser.add_argument("--package-url", default="http://downloads.eucalyptus.com/software/tools/centos/6/x86_64/eucalyptus-sos-plugins-0.1.5-0.el6.noarch.rpm") self.get_args() self.remote_dir = self.args.remote_dir + "/euca-sosreport-" + self.args.ticket_number + "/" # Setup basic nephoria object self.tester = Eucaops( config_file=self.args.config,password=self.args.password, download_creds=False) def clean_method(self): pass def Install(self): """ This is where the test description goes """ for machine in self.tester.get_component_machines(): assert isinstance(machine, Machine) if machine.distro.name is "vmware": continue machine.install("sos") machine.sys("yum install -y " + self.args.package_url) def Run(self): error_msg = "" for machine in self.tester.get_component_machines(): try: assert isinstance(machine, Machine) if machine.distro.name is "vmware": continue machine.sys("mkdir -p " + self.args.remote_dir) machine.sys("sosreport --batch --skip-plugins=emc --tmp-dir " + self.args.remote_dir + " --ticket-number " + str(self.args.ticket_number), code=0, timeout=self.args.timeout) except Exception, e: error_msg += 'Error running SOS report on:' + str(machine.hostname) + '. Error:' + str(e) if error_msg: raise Exception(error_msg)
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 nephoria_unit_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.ec2.add_group(group_name="group-" + str(time.time())) self.tester.ec2.authorize_group_by_name(group_name=self.group.name) self.tester.ec2.authorize_group_by_name(group_name=self.group.name, port=-1, protocol="icmp") ### Generate a keypair for the instance self.keypair = self.tester.ec2.create_keypair_and_localcert("keypair-" + str(time.time())) self.keypath = '%s/%s.pem' % (os.curdir, self.keypair.name) if emi: self.image = self.tester.ec2.get_emi(emi=self.args.emi) else: self.image = self.tester.ec2.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.connection.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 nephoria_unit_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 nephoria_unit_tests. The nephoria_unit_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 nephoria_unit_tests fail, the test case will error out, logging the results. """ reservation = self.tester.ec2.run_image(**self.run_instance_params) for instance in reservation.instances: self.assertTrue(self.tester.ec2.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 nephoria_unit_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 nephoria_unit_tests fail, the test case will error out, logging the results. """ if not self.reservation: reservation = self.tester.ec2.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 self.address = self.tester.ec2.allocate_address(domain=instance.vpc_id) self.assertTrue(self.address, 'Unable to allocate address') self.tester.ec2.associate_address(instance, self.address) instance.update() self.assertTrue(self.tester.ping(instance.ip_address), "Could not ping instance with new IP") self.tester.ec2.disassociate_address_from_instance(instance) self.tester.ec2.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 nephoria_unit_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.ec2.terminate_instances(self.reservation) self.set_reservation(None) reservation = self.tester.ec2.run_image(min=2, max=2, **self.run_instance_params) self.assertTrue(self.tester.ec2.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 nephoria_unit_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.ec2.terminate_instances(self.reservation) self.set_reservation(None) reservation = self.tester.ec2.run_image(type="c1.xlarge", **self.run_instance_params) self.assertTrue(self.tester.ec2.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 nephoria_unit_tests fail, the test case will error out; logging the results. """ if not self.reservation: reservation = self.tester.ec2.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 nephoria_unit_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 nephoria_unit_tests fail, the test case will error out; logging the results. """ if not self.reservation: reservation = self.tester.ec2.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.ec2.wait_for_result(validate_instance_dns, True, timeout=120) self.set_reservation(reservation) return reservation