def execute(self, auth, tc, nodes, extra_args, pod_labels): if tc['duration'] > 0: repeat = time() + tc['duration'] count = time() else: count = 0 repeat = tc.get('repeat', self.repeat) test_count = 1 if 'data' not in tc: tc['data'] = "{}" current_module = importlib.import_module('main') klass = getattr(current_module, tc['service-mapping']) obj = klass(tc, auth, nodes=nodes, extra_args=extra_args, pod_labels=pod_labels) target_method = getattr(obj, tc['operation'].lower()) while count < repeat: tc_name = tc['name']+'-'+str(test_count) tc_status, message, tc = target_method() logger.info("Test Case: %-20s Status: %4s Message: %s " % (tc_name, tc_status, message)) if tc['duration'] > 0: count = time() else: count += 1 test_count += 1
def post(self): self.data['input']['import_from'] = self.extra_args['import_from'] response = self.gc.POST(self.url, self.headers, data=self.data) if response.status_code >= 200 and response.status_code < 400: task_id = response.json()['id'] image_id = None url = "{}/{}".format(self.url, task_id) logger.info('Waiting for task {} to be completed'.format(task_id)) result = self.gc.check_resource_status(url, self.headers) tc_status = 'PASS' while result.json()['status'] != "success": result = self.gc.check_resource_status(url, self.headers) image_result = result.json().get('result', None) if image_result: image_id = image_result.get('image_id', None) if result.json()['status'] == "killed": tc_status = 'FAIL' message = result.text break logger.info('Deleting the created image: {}'.format(image_id)) images_url = self.url.replace('tasks', 'images') delete_url = "{}/{}".format(images_url, image_id) result = self.gc.DELETE(delete_url, self.headers) if result.status_code >= 200 and result.status_code < 400: tc_status = 'PASS' message = 'stripped not printing' else: tc_status = 'FAIL' message = result.text return tc_status, message, self.tc
def create_floating_ip(self, headers, port_id, network): public_network_id = self.get_network_id(headers, network) url = self.get_endpoint(service='network', interface='public') network_url = url + 'v2.0/floatingips' data = { 'floatingip': { 'floating_network_id': public_network_id, 'port_id': port_id, } } try: response = requests.post(network_url, headers=headers, data=json.dumps(data)) except Exception as e: error_msg = "{}: {}".format(e.__class__.__name__, e) response = requests.Response() response.status_code = -1 response._content = str.encode(error_msg) return response response_json = self.load_json_data(response.text) floating_ip = response_json['floatingip']['floating_ip_address'] floating_ip_id = response_json['floatingip']['id'] logger.info( 'Waiting for floating IP {} to be associated'.format(floating_ip)) status = 'DOWN' while status != 'ACTIVE': response = requests.get(network_url, headers=headers) response_json = self.load_json_data(response.text) floating_ip_dicts = response_json['floatingips'] for floating_ip_dict in floating_ip_dicts: if floating_ip_dict['id'] == floating_ip_id: status = floating_ip_dict['status'] return (floating_ip_id, floating_ip)
def __init__(self, tc, auth, **kwargs): self.auth = auth self.gc = GenericClient(auth) self.tc = tc self.url = tc['url'] self.headers = tc['headers'] self.body = tc['body'] custom_req = kwargs.get("custom_req", None) logger.info('Executing test case: {}'.format(tc['name'])) logger.info('Executing test service endpoint: {}'.format(self.url))
def post(self): tc_status = "FAIL" message = "Failed to power off the node" for node in self.nodes: po = power_operation(node['ipmi_ip'], node['user'], node['password']) logger.info("Powering off node %s" % (node['node_name'])) po.set_power_state("off") tc_status = "PASS" message = "Powered off the node %s" % (node['node_name']) return tc_status, message, self.tc
def create_vm(self): random_string = ''.join( random.choice(string.ascii_lowercase + string.digits) for _ in range(6)) flavor_id = self.gc.get_flavor_id(self.url, self.headers, name=self.tc['flavor']) image_id = self.gc.get_image_id(self.headers) network = self.gc.get_network_id(self.headers, self.tc['private_network']) self.tc['data'] = { 'server': { "name": "resiliency_vm_{}".format(random_string), "imageRef": image_id, "flavorRef": flavor_id, "networks": [{ "uuid": network }] } } vm_id = "" hostname = "" response = self.gc.POST(self.url, self.headers, data=self.tc['data']) if response.status_code >= 200 and response.status_code < 400: tc_status = "PASS" message = "Stripped not printing" vm_id = response.json()['server']['id'] url = self.url + '/' + vm_id result = self.gc.check_resource_status(url, self.headers) ts = time() logger.info("Waiting for %s vm to come to active state" % (vm_id)) if result.status_code >= 200 and result.status_code < 400: while result.json()['server']['status'].lower() != 'active': if result.json()['server']['status'].lower() == 'error': tc_status = 'FAIL' message = 'stripped not printing' break if (time() - ts) == 600: tc_status = "FAIL" message = "Timed out waiting for the stack to complete" break result = self.gc.check_resource_status(url, self.headers) if result.status_code < 200 and result.status_code > 400: tc_status = 'FAIL' message = result.text break if tc_status == "PASS": hostname = result.json()['server']['OS-EXT-SRV-ATTR:host'] else: tc_status = "FAIL" message = result.text return tc_status, message, vm_id, hostname
def delete_vm(self, vm_id): logger.info('Deleting the created instance: {}'.format(vm_id)) delete_url = "{}/{}".format(self.url, vm_id) result = self.gc.DELETE(delete_url, self.headers) if result.status_code >= 200 and result.status_code < 400: tc_status = 'PASS' message = 'stripped not printing' else: tc_status = 'FAIL' message = result.text logger.info('Instance Deleted') return tc_status, message
def post(self, **kwargs): tc_status, message, tc = super().post() if tc_status != "FAIL": for node in self.nodes: po = power_operation(node['ipmi_ip'], node['user'], node['password']) logger.info("Powering off the node %s" % (node['node_name'])) po.set_power_state("off") while True: tc_status, message, tc = super().post() if tc_status == "PASS": break logger.info("Powering on the node %s" % (node['node_name'])) po.set_power_state("on") return tc_status, message, self.tc
def post(self): tc_status = "FAIL" message = "Failed to power off the node" for node in self.nodes: attempts = 0 while attempts <= 5: po = power_operation(node['ipmi_ip'], node['user'], node['password']) logger.info("Powering off node %s" % (node['node_name'])) response, status = po.set_power_state("off") if status: break attempts += 1 tc_status = "PASS" message = "Powered off the node %s" % (node['node_name']) return tc_status, message, self.tc
def get_endpoint(self, service='keystone', interface='public'): """ Get openstack endpoints """ logger.info('Get openstack endpoints started') if self.token is None: self.token = self.get_openstack_token() url = self.auth['auth_url'] + '/services' params = {'type': service} headers = { 'X-Auth-Token': self.token, 'Content-Type': 'application/json', 'Accept': 'application/json' } response = requests.get(url, headers=headers, params=params, verify=False) service_dict = self.load_json_data(response.text) services = service_dict.get('services', None) if services is None: return None service_id = services[0]['id'] url = self.auth['auth_url'] + '/endpoints' params = {'service_id': service_id, 'interface': interface} headers = { 'X-Auth-Token': self.token, 'Content-Type': 'application/json', 'Accept': 'application/json' } response = requests.get(url, headers=headers, params=params, verify=False) endpoint_dict = self.load_json_data(response.text) endpoints = endpoint_dict.get('endpoints', None) if endpoints is None: return None endpoint = endpoints[0]['url'] logger.info('Get openstack endpoints completed successfully') return endpoint
def get_openstack_token(self): """ Get openstack token """ logger.info('Get openstack token started') data_template = Template(OPENSTACK_TOKEN) data = data_template.substitute(self.auth) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' } url = self.auth['auth_url'] + '/auth/tokens' response = requests.post(url, headers=headers, data=data, verify=False) self.token = response.headers.get('X-Subject-Token', None) response_dict = self.load_json_data(response.text) # Handle error in case token fails if response.status_code == 201: self.tenant_id = response_dict['token']['project']['id'] logger.info('Get openstack token completed successfully') else: logger.error('Get openstack token failed') return self.token
def __init__(self, tc, auth, **kwargs): self.auth = auth self.gc = GenericClient(auth) token = self.gc.get_openstack_token() self.tc = tc self.nodes = kwargs.get("nodes", None) self.extra_args = kwargs.get("nodes", None) logger.info('Executing test case: {}'.format(tc['name'])) self.headers = { 'X-Auth-Token': token, # 'Content-Type': 'application/octet-stream', 'Content-Type': 'application/json', 'Accept': 'application/json' } url = self.gc.get_endpoint(service=tc['service_type'], interface='public') url += tc['url'] url = url.replace('%(tenant_id)s', self.gc.tenant_id) self.url = url.replace('%(project_id)s', self.gc.tenant_id) self.data = tc['data']
def post(self, **kwargs): tc_status, message, vm_id, hostname = self.create_vm() if tc_status is not 'FAIL': port_id = self.gc.get_vm_port_id(self.headers, vm_id) (floating_ip_id, floating_ip) = self.gc.create_floating_ip( self.headers, port_id) logger.info( 'Performing ping test on floating ip,' '{} of vm {}'.format( floating_ip, self.tc['data']['server']['name'])) pod_delete_cmd = ( "kubectl delete po -n openstack --field-selector" " spec.nodeName=%s -l %s|awk 'FNR == 2 {print $1}'" % ( hostname, self.pod_labels)) logger.info(subprocess.check_output(pod_delete_cmd, stderr=subprocess.STDOUT, shell=True).decode('utf-8').strip("\n")) cmd = "ping -w {} {}".format(self.tc['duration'], floating_ip) exit_code = subprocess.check_output( cmd, stderr=subprocess.STDOUT, shell=True).decode('utf-8').strip("\n") # count = time() logger.info(exit_code) cmd = ( "echo '" + exit_code + "'|grep 'transmitted' | awk -F" "',' '{print $3}' | awk -F '%' '{print $1}'") ping_result = subprocess.check_output( cmd, stderr=subprocess.STDOUT, shell=True).decode('utf-8').strip("\n") if ping_result == ' 0': tc_status = 'PASS' else: tc_status = 'FAIL' logger.info('Deleting the created floating ip {}'.format( floating_ip_id)) network_url = self.gc.get_endpoint(service='network', interface='public') delete_url = "{}/v2.0/floatingips/{}".format( network_url, floating_ip_id) result = self.gc.DELETE(delete_url, self.headers) if result.status_code >= 200 and result.status_code < 400: # tc_status = 'PASS' message = 'Deleted floating IP' else: tc_status = 'FAIL' message = result.text tc_status, message = self.delete_vm(vm_id) return tc_status, message, self.tc
def post(self, **kwargs): response = self.gc.POST(self.url, self.headers, data=self.data) if response.status_code >= 200 and response.status_code < 400: tc_status = "PASS" message = response.text volume_id = response.json()['volume']['id'] logger.info("Created volume %s" % (volume_id)) poll_url = "{}/{}".format(self.url, volume_id) result = self.gc.check_resource_status(poll_url, self.headers) logger.info("Waiting for the volume %s to be available" % (volume_id)) ts = time() while result.json()['volume']['status'] != "available": result = self.gc.check_resource_status(poll_url, self.headers) if result.status_code < 200 and result.status_code > 400: tc_status = 'FAIL' message = result.text break if (time() - ts) == 600: tc_status = "FAIL" message = "Timed out waiting for the stack to complete" break if result.json()['volume']['status'] == "error": tc_status = "FAIL" message = result.text logger.info("Deleting volume %s" % (volume_id)) response = self.gc.DELETE(poll_url, self.headers) if response.status_code >= 200 and response.status_code < 400: tc_status = "PASS" else: tc_status = "FAIL" message = response.text return tc_status, message, self.tc
def post(self): random_string = ''.join(random.choice( string.ascii_lowercase + string.digits) for _ in range(6)) self.tc['data']['stack_name'] = "resiliency_stack_" + random_string response = self.gc.POST(self.url, self.headers, data=self.data) if response.status_code >= 200 and response.status_code < 400: tc_status = "PASS" message = "Stripped not printing" stack_id = response.json()['stack']['id'] stack_name = self.tc['data']['stack_name'] url = "{}/{}/{}".format(self.url, stack_name, stack_id) result = self.gc.check_resource_status(url, self.headers) ts = time() logger.info("Waiting for %s stack to complete " % (stack_id)) while result.json()['stack']['stack_status'] != 'CREATE_COMPLETE': if result.json()['stack']['stack_status'] == "CREATE_FAILED": tc_status = 'FAIL' message = result.text break if (time() - ts) == 900: tc_status = "FAIL" message = "Timed out waiting for the stack to complete" break result = self.gc.check_resource_status(url, self.headers) logger.info('Deleting the created stack: {}'.format( stack_id)) result = self.gc.DELETE(url, self.headers) if result.status_code >= 200 and result.status_code < 400: tc_status = 'PASS' message = 'stripped not printing' else: tc_status = 'FAIL' message = result.text logger.info("Error message: {}".format(message)) logger.info('Stack Deleted') else: tc_status = "FAIL" message = response.text return tc_status, message, self.tc
def post(self): random_string = ''.join( random.choice(string.ascii_lowercase + string.digits) for _ in range(6)) self.data['router']['name'] = "test-resiliency-{}".format( random_string) response = self.gc.POST(self.url, self.headers, data=self.data) if response.status_code >= 200 and response.status_code < 400: router_id = response.json()['router']['id'] logger.info("Created router %s" % (router_id)) tc_status = 'PASS' logger.info('Deleting the created router: {}'.format(router_id)) delete_url = "{}/{}".format(self.url, router_id) result = self.gc.DELETE(delete_url, self.headers) if result.status_code >= 200 and result.status_code < 400: tc_status = 'PASS' message = 'stripped not printing' else: tc_status = 'FAIL' message = result.text logger.info("Error message: {}".format(message)) logger.info('Router Deleted') return tc_status, message, self.tc
if __name__ == "__main__": inputs = sys.argv auth = ast.literal_eval(inputs[1]) component = inputs[2] duration = int(inputs[3]) count = int(inputs[4]) if inputs[5]: nodes = ast.literal_eval(inputs[5]) else: nodes = [] if inputs[6]: extra_args = ast.literal_eval(inputs[6]) else: extra_args = [] if inputs[7]: pod_labels = ast.literal_eval(inputs[7]) else: pod_labels = [] run = Runner() logger.info('Starting with test case execution') testcases = json.loads(open("testcases.json", "r").read()) testcases[component]["duration"] = duration testcases[component]["repeat"] = count try: run.execute(auth, testcases[component], nodes, extra_args, pod_labels) except Exception as e: logger.error("%s: %s" % (e.__class__.__name__, e)) logger.error(traceback.print_exc())