def test_setup(): r""" Do test case setup tasks. """ gp.qprintn() gp.qprint_executing()
def enumerate(self, resource_path, return_json=1, include_dead_resources=False): r""" Perform a GET enumerate request and return available resource paths. Description of argument(s): resource_path URI resource absolute path (e.g. "/redfish/v1/SessionService/Sessions"). return_json Indicates whether the result should be returned as a json string or as a dictionary. include_dead_resources Check and return a list of dead/broken URI resources. """ gp.qprint_executing(style=gp.func_line_style_short) # Set quiet variable to keep subordinate get() calls quiet. quiet = 1 self.__result = {} # Variable to hold the pending list of resources for which enumeration is yet to be obtained. self.__pending_enumeration = set() self.__pending_enumeration.add(resource_path) # Variable having resources for which enumeration is completed. enumerated_resources = set() dead_resources = {} resources_to_be_enumerated = (resource_path,) while resources_to_be_enumerated: for resource in resources_to_be_enumerated: # JsonSchemas, SessionService or URLs containing # are not required in enumeration. # Example: '/redfish/v1/JsonSchemas/' and sub resources. # '/redfish/v1/SessionService' # '/redfish/v1/Managers/bmc#/Oem' if ('JsonSchemas' in resource) or ('SessionService' in resource) or ('#' in resource): continue self._rest_response_ = self.get(resource, valid_status_codes=[200, 404, 500]) # Enumeration is done for available resources ignoring the ones for which response is not # obtained. if self._rest_response_.status != 200: if include_dead_resources: try: dead_resources[self._rest_response_.status].append(resource) except KeyError: dead_resources[self._rest_response_.status] = [resource] continue self.walk_nested_dict(self._rest_response_.dict, url=resource) enumerated_resources.update(set(resources_to_be_enumerated)) resources_to_be_enumerated = tuple(self.__pending_enumeration - enumerated_resources) if return_json: if include_dead_resources: return json.dumps(self.__result, sort_keys=True, indent=4, separators=(',', ': ')), dead_resources else: return json.dumps(self.__result, sort_keys=True, indent=4, separators=(',', ': ')) else: if include_dead_resources: return self.__result, dead_resources else: return self.__result
def list_request(self, resource_path): r""" Perform a GET list request and return available resource paths. Description of argument(s): resource_path URI resource absolute path (e.g. "/redfish/v1/SessionService/Sessions"). """ gp.qprint_executing(style=gp.func_line_style_short) # Set quiet variable to keep subordinate get() calls quiet. quiet = 1 self.__pending_enumeration = set() self._rest_response_ = \ self._redfish_.get(resource_path, valid_status_codes=[200, 404, 500]) # Return empty list. if self._rest_response_.status != 200: return self.__pending_enumeration self.walk_nested_dict(self._rest_response_.dict) if not self.__pending_enumeration: return resource_path for resource in self.__pending_enumeration.copy(): self._rest_response_ = \ self._redfish_.get(resource, valid_status_codes=[200, 404, 500]) if self._rest_response_.status != 200: continue self.walk_nested_dict(self._rest_response_.dict) return list(sorted(self.__pending_enumeration))
def stop_boot_test(signal_number=0, frame=None): r""" Handle SIGUSR1 by aborting the boot test that is running. Description of argument(s): signal_number The signal number (should always be 10 for SIGUSR1). frame The frame data. """ gp.qprintn() gp.qprint_executing() gp.lprint_executing() # Restore original sigusr1 handler. set_default_siguser1() message = "The caller has asked that the boot test be stopped and marked" message += " as a failure." function_stack = gm.get_function_stack() if "wait_state" in function_stack: st.set_exit_wait_early_message(message) else: BuiltIn().fail(gp.sprint_error(message))
def enumerate_request(self, resource_path, return_json=1): r""" Perform a GET enumerate request and return available resource paths. Description of argument(s): resource_path URI resource absolute path (e.g. "/redfish/v1/SessionService/Sessions"). return_json Indicates whether the result should be returned as a json string or as a dictionary. """ gp.qprint_executing(style=gp.func_line_style_short) return_json = int(return_json) # Set quiet variable to keep subordinate get() calls quiet. quiet = 1 # Variable to hold enumerated data. self.__result = {} # Variable to hold the pending list of resources for which enumeration. # is yet to be obtained. self.__pending_enumeration = set() self.__pending_enumeration.add(resource_path) # Variable having resources for which enumeration is completed. enumerated_resources = set() resources_to_be_enumerated = (resource_path, ) while resources_to_be_enumerated: for resource in resources_to_be_enumerated: # JsonSchemas data are not required in enumeration. # Example: '/redfish/v1/JsonSchemas/' and sub resources. if 'JsonSchemas' in resource: continue self._rest_response_ = \ self._redfish_.get(resource, valid_status_codes=[200, 404, 500]) # Enumeration is done for available resources ignoring the # ones for which response is not obtained. if self._rest_response_.status != 200: continue self.walk_nested_dict(self._rest_response_.dict, url=resource) enumerated_resources.update(set(resources_to_be_enumerated)) resources_to_be_enumerated = \ tuple(self.__pending_enumeration - enumerated_resources) if return_json: return json.dumps(self.__result, sort_keys=True, indent=4, separators=(',', ': ')) else: return self.__result
def test_setup(): r""" Do test case setup tasks. """ gp.qprintn() gp.qprint_executing()
def rest_request(self, func, *args, **kwargs): r""" Perform redfish rest request and return response. This function provides the following additional functionality. - The calling function's call line is logged to standard out (provided that global variable "quiet" is not set). - The caller may include a valid_status_codes argument. - Callers may include inline python code strings to define arguments. This predominantly benefits robot callers. For example, instead of calling like this: ${data}= Create Dictionary HostName=${hostname} Redfish.patch ${REDFISH_NW_PROTOCOL_URI} body=&{data} Callers may do this: Redfish.patch ${REDFISH_NW_PROTOCOL_URI} ... body=[('HostName', '${hostname}')] Description of argument(s): func A reference to the parent class function which is to be called (e.g. get, put, etc.). args This is passed directly to the function referenced by the func argument (see the documentation for the corresponding redfish HttpClient method for details). kwargs This is passed directly to the function referenced by the func argument (see the documentation for the corresponding redfish HttpClient method for details) with the following exception: If kwargs contains a valid_status_codes key, it will be removed from kwargs and processed by this function. This allows the caller to indicate what rest status codes are acceptable. The default value is [200]. See the valid_http_status_code function above for details. Example uses: From a python program: response = bmc_redfish.get("/redfish/v1/Managers/bmc/EthernetInterfaces", [200, 201]) If this call to the get method generates a response.status equal to anything other than 200 or 201, an exception will be raised. From a robot program: BMC_Redfish.logout ${response}= BMC_Redfish.Get /redfish/v1/Managers/bmc/EthernetInterfaces valid_status_codes=[401] As part of a robot test, the programmer has logged out to verify that the get request will generate a status code of 401 (i.e. "Unauthorized"). """ gp.qprint_executing(stack_frame_ix=3, style=gp.func_line_style_short) # Convert python string object definitions to objects (mostly useful for robot callers). args = fa.args_to_objects(args) kwargs = fa.args_to_objects(kwargs) valid_status_codes = kwargs.pop('valid_status_codes', [200]) response = func(*args, **kwargs) valid_http_status_code(response.status, valid_status_codes) return response
def set_default_siguser1(): r""" Set the default_sigusr1 function to be the SIGUSR1 handler. """ gp.qprintn() gp.qprint_executing() gp.lprint_executing() signal.signal(signal.SIGUSR1, default_sigusr1)
def rest_request(self, func, *args, **kwargs): r""" Perform redfish rest request and return response. This function provides the following additional functionality. - The calling function's call line is logged to standard out (provided that global variable "quiet" is not set). - The caller may include a valid_status_codes argument. Description of argument(s): func A reference to the parent class function which is to be called (e.g. get, put, etc.). args This is passed directly to the function referenced by the func argument (see the documentation for the corresponding redfish HttpClient method for details). kwargs This is passed directly to the function referenced by the func argument (see the documentation for the corresponding redfish HttpClient method for details) with the following exception: If kwargs contains a valid_status_codes key, it will be removed from kwargs and processed by this function. This allows the caller to indicate what rest status codes are acceptable. The default value is [200]. See the valid_http_status_code function above for details. Example uses: From a python program: response = bmc_redfish.get("/redfish/v1/Managers/bmc/EthernetInterfaces", [200, 201]) If this call to the get method generates a response.status equal to anything other than 200 or 201, an exception will be raised. From a robot program: BMC_Redfish.logout ${response}= BMC_Redfish.Get /redfish/v1/Managers/bmc/EthernetInterfaces valid_status_codes=[401] As part of a robot test, the programmer has logged out to verify that the get request will generate a status code of 401 (i.e. "Unauthorized"). """ gp.qprint_executing(stack_frame_ix=3, style=gp.func_line_style_short) valid_status_codes = kwargs.pop('valid_status_codes', [200]) response = func(*args, **kwargs) #valid_http_status_code(response.status, valid_status_codes) return response
def gen_signal_handler(signal_number, frame): r""" Handle signals. Without a function to catch a SIGTERM or SIGINT, the program would terminate immediately with return code 143 and without calling the exit_function. """ # The convention is to set up exit_function with atexit.register() so there is no need to explicitly # call exit_function from here. gp.qprint_executing() # Calling exit prevents control from returning to the code that was running when the signal was received. exit(0)
def default_sigusr1(signal_number=0, frame=None): r""" Handle SIGUSR1 by doing nothing. This function assists in debugging SIGUSR1 processing by printing messages to stdout and to the log.html file. Description of argument(s): signal_number The signal number (should always be 10 for SIGUSR1). frame The frame data. """ gp.qprintn() gp.qprint_executing() gp.lprint_executing()
def test_teardown(): r""" Clean up after this test case. """ gp.qprintn() gp.qprint_executing() if ga.psutil_imported: ga.terminate_descendants() cmd_buf = ["Print Error", "A keyword timeout occurred ending this program.\n"] BuiltIn().run_keyword_if_timeout_occurred(*cmd_buf) gp.qprint_pgm_footer()
def obmc_boot_test_teardown(): r""" Clean up after the main keyword. """ gp.qprint_executing() if ga.psutil_imported: ga.terminate_descendants() if cp_setup_called: plug_in_setup() rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( call_point='cleanup', stop_on_plug_in_failure=0) if 'boot_results_file_path' in globals(): # Save boot_results and boot_history objects to a file in case they are # needed again. gp.qprint_timen("Saving boot_results to the following path.") gp.qprint_var(boot_results_file_path) pickle.dump((boot_results, boot_history), open(boot_results_file_path, 'wb'), pickle.HIGHEST_PROTOCOL) global save_stack # Restore any global values saved on the save_stack. for parm_name in main_func_parm_list: # Get the parm_value if it was saved on the stack. try: parm_value = save_stack.pop(parm_name) except BaseException: # If it was not saved, no further action is required. continue # Restore the saved value. cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\ "}\", parm_value)" gp.dpissuing(cmd_buf) exec(cmd_buf) gp.dprintn(save_stack.sprint_obj())