def test_partition_facts(ansible_mod_cls, check_mode, hmc_session): # noqa: F811, E501 """ Test fact gathering on a partition. """ hd = hmc_session.hmc_definition # Determine one of the CPCs in the HMC definition file to test cpc_names = hd.cpcs.keys() assert len(cpc_names) >= 1 cpc_name = cpc_names[0] # Determine an existing partition to test. This also validates that # the CPC defined in the HMC definition file actually exists. client = zhmcclient.Client(hmc_session) cpc = client.cpcs.find_by_name(cpc_name) partitions = cpc.partitions.list() assert len(partitions) >= 1 partition = partitions[0] # Pick first partition in list # Prepare module input parameters params = { 'hmc_host': hd.hmc_host, 'hmc_auth': dict(userid=hd.hmc_userid, password=hd.hmc_password), 'cpc_name': cpc_name, 'name': partition.name, 'state': 'facts', 'log_file': None, 'faked_session': None, } # Prepare mocks for AnsibleModule object mod_obj = mock_ansible_module(ansible_mod_cls, params, check_mode) # Exercise the code to be tested with pytest.raises(SystemExit) as exc_info: zhmc_partition.main() exit_code = exc_info.value.args[0] # Assert module exit code assert exit_code == 0, \ "Module unexpectedly failed with this message:\n{0}". \ format(get_failure_msg(mod_obj)) # Assert module output changed, partition_props = get_module_output(mod_obj) assert changed is False assert_partition_props(partition_props)
def test_main_param_error(self, ansible_mod_cls, perform_task_func): """ Test main() with ParameterError being raised in perform_task(). """ # Module invocation params = { 'hmc_host': 'fake-host', 'hmc_auth': dict(userid='fake-userid', password='******'), 'cpc_name': 'fake-cpc-name', 'name': 'fake-name', 'state': 'absent', 'expand_storage_groups': False, 'expand_crypto_adapters': False, 'log_file': None, } check_mode = False # Exception raised by perform_task() perform_task_exc = module_utils.ParameterError("fake message") # Prepare mocks mod_obj = ansible_mod_cls.return_value mod_obj.params = params mod_obj.check_mode = check_mode mod_obj.fail_json.configure_mock(side_effect=SystemExit(1)) mod_obj.exit_json.configure_mock(side_effect=SystemExit(0)) perform_task_func.mock.configure_mock(side_effect=perform_task_exc) # Exercise code with self.assertRaises(SystemExit) as cm: zhmc_partition.main() exit_code = cm.exception.args[0] # Assert module exit code assert(exit_code == 1) # Assert call to perform_task() assert(perform_task_func.call_args == mock.call(params, check_mode)) # Assert call to fail_json() assert(mod_obj.fail_json.call_args == mock.call(msg="ParameterError: fake message")) # Assert no call to exit_json() assert(mod_obj.exit_json.called is False)
def test_main_success(self, ansible_mod_cls, perform_task_func): """ Test main() with all required module parameters. """ # Module invocation params = { 'hmc_host': 'fake-host', 'hmc_auth': dict(userid='fake-userid', password='******'), 'cpc_name': 'fake-cpc-name', 'name': 'fake-name', 'state': 'absent', 'expand_storage_groups': False, 'expand_crypto_adapters': False, 'log_file': None, } check_mode = False # Return values of perform_task() perform_task_changed = True perform_task_result = {} # Prepare mocks mod_obj = ansible_mod_cls.return_value mod_obj.params = params mod_obj.check_mode = check_mode mod_obj.fail_json.configure_mock(side_effect=SystemExit(1)) mod_obj.exit_json.configure_mock(side_effect=SystemExit(0)) perform_task_func.return_value = (perform_task_changed, perform_task_result) # Exercise code with self.assertRaises(SystemExit) as cm: zhmc_partition.main() exit_code = cm.exception.args[0] # Assert module exit code assert (exit_code == 0) # Assert call to AnsibleModule() expected_argument_spec = dict( hmc_host=dict(required=True, type='str'), hmc_auth=dict( required=True, type='dict', options=dict( userid=dict(required=True, type='str'), password=dict(required=True, type='str', no_log=True), ca_certs=dict(required=False, type='str', default=None), verify=dict(required=False, type='bool', default=True), ), ), cpc_name=dict(required=True, type='str'), name=dict(required=True, type='str'), state=dict(required=True, type='str', choices=['absent', 'stopped', 'active', 'facts']), properties=dict(required=False, type='dict', default={}), expand_storage_groups=dict(required=False, type='bool', default=False), expand_crypto_adapters=dict(required=False, type='bool', default=False), log_file=dict(required=False, type='str', default=None), _faked_session=dict(required=False, type='raw'), ) assert (ansible_mod_cls.call_args == mock.call( argument_spec=expected_argument_spec, supports_check_mode=True)) # Assert call to perform_task() assert (perform_task_func.call_args == mock.call(params, check_mode)) # Assert call to exit_json() assert (mod_obj.exit_json.call_args == mock.call( changed=perform_task_changed, partition=perform_task_result)) # Assert no call to fail_json() assert (mod_obj.fail_json.called is False)
def test_zhmc_partition_properties(ansible_mod_cls, type_state, check_mode, dpm_mode_cpcs): # noqa: F811, E501 """ Test the zhmc_partition module with updating properties. """ if not dpm_mode_cpcs: pytest.skip("HMC definition does not include any CPCs in DPM mode") partition_type, state = type_state for cpc in dpm_mode_cpcs: assert cpc.dpm_enabled session = cpc.manager.session hd = session.hmc_definition hmc_host = hd.host hmc_auth = dict(userid=hd.userid, password=hd.password, ca_certs=hd.ca_certs, verify=hd.verify) faked_session = session if hd.mock_file else None # Create a partition name that does not exist partition_name = unique_partition_name() # Create initial partition if partition_type == 'ssc': create_props = STD_SSC_PARTITION_HMC_INPUT_PROPS else: create_props = STD_LINUX_PARTITION_HMC_INPUT_PROPS create_props['type'] = partition_type partition = setup_partition(hd, cpc, partition_name, create_props, state) try: # The test is optimized for runtime - we use the same partition # for all updates. machine_type = cpc.get_property('machine-type') if machine_type in ('2964', '2965'): # z13 if partition_type == 'ssc': update_items = PARTITION_UPDATE_ITEMS_Z13_SSC else: update_items = PARTITION_UPDATE_ITEMS_Z13_LINUX elif machine_type in ('3906', '3907'): # z14 if partition_type == 'ssc': update_items = PARTITION_UPDATE_ITEMS_Z14_SSC else: update_items = PARTITION_UPDATE_ITEMS_Z14_LINUX elif machine_type in ('8561', '8562'): # z15 if partition_type == 'ssc': update_items = PARTITION_UPDATE_ITEMS_Z15_SSC else: update_items = PARTITION_UPDATE_ITEMS_Z15_LINUX elif machine_type in ('3931', '3932'): # z16 if partition_type == 'ssc': update_items = PARTITION_UPDATE_ITEMS_Z16_SSC else: update_items = PARTITION_UPDATE_ITEMS_Z16_LINUX else: raise AssertionError( "Unknown machine type: {m!r}".format(m=machine_type)) for update_item in update_items: if DEBUG: print("Debug: Testcase: update_item={i!r}".format( i=update_item)) where = "update_item {i!r}".format(i=update_item) partition.pull_full_properties() update_props = {} exp_props = {} exp_exit_code = 0 exp_changed = False for prop_name in update_item: prop_hmc_name = prop_name.replace('_', '-') if prop_name in NON_RETRIEVABLE_PROPS: current_hmc_value = '<non-retrievable>' else: current_hmc_value = partition.get_property( prop_hmc_name) value_item = update_item[prop_name] if isinstance(value_item, tuple): new_value = value_item[0] new_hmc_value = value_item[1] else: new_value = value_item new_hmc_value = value_item allowed, create, update, update_while_active, eq_func, \ type_cast = \ zhmc_partition.ZHMC_PARTITION_PROPERTIES[prop_name] # Note that update_while_active will be handled in the # Ansible module by stopping the partition, updating the # porperty and starting the partition. if not update: exp_exit_code = 1 else: if prop_name in NON_RETRIEVABLE_PROPS: exp_changed = True elif current_hmc_value != new_hmc_value: exp_changed = True if DEBUG: print("Debug: Property {p!r}: update={u}, " "update_while_active={ua}, " "current_hmc_value={cv!r}, " "new_value={nv!r}, new_hmc_value={nhv!r}".format( p=prop_hmc_name, u=update, ua=update_while_active, cv=current_hmc_value, nv=new_value, nhv=new_hmc_value)) update_props[prop_name] = new_value if prop_name not in NON_RETRIEVABLE_PROPS: exp_props[prop_hmc_name] = new_hmc_value if 'cp_processors' in update_props: cpc_cp_count = cpc.get_property( 'processor-count-general-purpose') if DEBUG: print("Debug: CPC has {n} CPs".format(n=cpc_cp_count)) if cpc_cp_count < 2: if DEBUG: print("Debug: CPC has not enough CPs; " "skipping update item: {i!r}".format( i=update_item)) continue if 'ifl_processors' in update_props: cpc_ifl_count = cpc.get_property('processor-count-ifl') if DEBUG: print( "Debug: CPC has {n} IFLs".format(n=cpc_ifl_count)) if cpc_ifl_count < 2: if DEBUG: print("Debug: CPC has not enough IFLs; " "skipping update item: {i!r}".format( i=update_item)) continue initial_props = copy.deepcopy(partition.properties) if DEBUG: print("Debug: Calling module with properties={p!r}".format( p=update_props)) # Prepare module input parms (must be all required + optional) params = { 'hmc_host': hmc_host, 'hmc_auth': hmc_auth, 'cpc_name': cpc.name, 'name': partition_name, 'state': state, # no state change 'properties': update_props, 'expand_storage_groups': False, 'expand_crypto_adapters': False, 'log_file': LOG_FILE, '_faked_session': faked_session, } mod_obj = mock_ansible_module(ansible_mod_cls, params, check_mode) # Exercise the code to be tested with pytest.raises(SystemExit) as exc_info: zhmc_partition.main() exit_code = exc_info.value.args[0] if exit_code != 0: msg = get_failure_msg(mod_obj) if msg.startswith('HTTPError: 403,1'): pytest.skip( "HMC user '{u}' is not permitted to create " "test partition".format(u=hd.userid)) msg_str = " and failed with message:\n{m}".format(m=msg) else: msg_str = '' if exit_code != exp_exit_code: raise AssertionError( "{w}: Module has unexpected exit code {e}{m}".format( w=where, e=exit_code, m=msg_str)) changed, output_props = get_module_output(mod_obj) if changed != exp_changed: initial_props_sorted = \ dict(sorted( initial_props.items(), key=lambda x: x[0])) \ if initial_props is not None else None update_props_sorted = \ dict(sorted(update_props.items(), key=lambda x: x[0])) \ if update_props is not None else None output_props_sorted = \ dict(sorted(output_props.items(), key=lambda x: x[0])) \ if output_props is not None else None raise AssertionError( "{w}: Unexpected change flag returned: actual: {a}, " "expected: {e}\n" "Initial partition properties:\n{ip}\n" "Module input properties:\n{up}\n" "Resulting partition properties:\n{op}".format( w=where, a=changed, e=exp_changed, ip=pformat(initial_props_sorted, indent=2), up=pformat(update_props_sorted, indent=2), op=pformat(output_props_sorted, indent=2))) assert_partition_props(output_props, exp_props, where) finally: teardown_partition(hd, cpc, partition_name)
def test_zhmc_partition_state(ansible_mod_cls, desc, initial_props, input_state, input_props, exp_props, exp_changed, check_mode, dpm_mode_cpcs): # noqa: F811, E501 """ Test the zhmc_partition module with different initial and target state. """ if not dpm_mode_cpcs: pytest.skip("HMC definition does not include any CPCs in DPM mode") for cpc in dpm_mode_cpcs: assert cpc.dpm_enabled session = cpc.manager.session hd = session.hmc_definition hmc_host = hd.host hmc_auth = dict(userid=hd.userid, password=hd.password, ca_certs=hd.ca_certs, verify=hd.verify) faked_session = session if hd.mock_file else None # Create a partition name that does not exist partition_name = unique_partition_name() where = "partition '{u}'".format(u=partition_name) if input_props is not None: input_props2 = input_props.copy() else: input_props2 = None # Create initial partition, if specified so if initial_props is not None: setup_partition(hd, cpc, partition_name, initial_props) try: # Prepare module input parameters (must be all required + optional) params = { 'hmc_host': hmc_host, 'hmc_auth': hmc_auth, 'cpc_name': cpc.name, 'name': partition_name, 'state': input_state, 'expand_storage_groups': False, 'expand_crypto_adapters': False, 'log_file': LOG_FILE, '_faked_session': faked_session, } if input_props2 is not None: params['properties'] = input_props2 mod_obj = mock_ansible_module(ansible_mod_cls, params, check_mode) # Exercise the code to be tested with pytest.raises(SystemExit) as exc_info: zhmc_partition.main() exit_code = exc_info.value.args[0] if exit_code != 0: msg = get_failure_msg(mod_obj) if msg.startswith('HTTPError: 403,1'): pytest.skip("HMC user '{u}' is not permitted to create " "test partition".format(u=hd.userid)) raise AssertionError( "{w}: Module failed with exit code {e} and message:\n{m}". format(w=where, e=exit_code, m=msg)) changed, output_props = get_module_output(mod_obj) if changed != exp_changed: initial_props_sorted = \ dict(sorted(initial_props.items(), key=lambda x: x[0])) \ if initial_props is not None else None input_props_sorted = \ dict(sorted(input_props2.items(), key=lambda x: x[0])) \ if input_props2 is not None else None output_props_sorted = \ dict(sorted(output_props.items(), key=lambda x: x[0])) \ if output_props is not None else None raise AssertionError( "Unexpected change flag returned: actual: {0}, " "expected: {1}\n" "Initial partition properties:\n{2}\n" "Module input properties:\n{3}\n" "Resulting partition properties:\n{4}".format( changed, exp_changed, pformat(initial_props_sorted, indent=2), pformat(input_props_sorted, indent=2), pformat(output_props_sorted, indent=2))) if input_state != 'absent': assert_partition_props(output_props, exp_props, where) finally: teardown_partition(hd, cpc, partition_name)
def test_zhmc_partition_facts(ansible_mod_cls, partition_type, check_mode, dpm_mode_cpcs): # noqa: F811, E501 """ Test the zhmc_partition module with state=facts on DPM mode CPCs. """ if not dpm_mode_cpcs: pytest.skip("HMC definition does not include any CPCs in DPM mode") for cpc in dpm_mode_cpcs: assert cpc.dpm_enabled session = cpc.manager.session hd = session.hmc_definition hmc_host = hd.host hmc_auth = dict(userid=hd.userid, password=hd.password, ca_certs=hd.ca_certs, verify=hd.verify) faked_session = session if hd.mock_file else None # Determine a random existing partition of the desired type to test. partitions = cpc.partitions.list() typed_partitions = [ p for p in partitions if p.get_property('type') == partition_type ] if len(typed_partitions) == 0: pytest.skip("CPC '{c}' has no partitions of type '{t}'".format( c=cpc.name, t=partition_type)) partition = random.choice(typed_partitions) where = "partition '{p}'".format(p=partition.name) # Prepare module input parameters (must be all required + optional) params = { 'hmc_host': hmc_host, 'hmc_auth': hmc_auth, 'cpc_name': cpc.name, 'name': partition.name, 'state': 'facts', 'properties': {}, 'expand_storage_groups': False, 'expand_crypto_adapters': False, 'log_file': None, '_faked_session': faked_session, } # Prepare mocks for AnsibleModule object mod_obj = mock_ansible_module(ansible_mod_cls, params, check_mode) # Exercise the code to be tested with pytest.raises(SystemExit) as exc_info: zhmc_partition.main() exit_code = exc_info.value.args[0] # Assert module exit code assert exit_code == 0, \ "{w}: Module failed with exit code {e} and message:\n{m}". \ format(w=where, e=exit_code, m=get_failure_msg(mod_obj)) # Assert module output changed, output_props = get_module_output(mod_obj) assert changed is False, \ "{w}: Module returned changed={c}". \ format(w=where, c=changed) assert_partition_props(output_props, partition.properties, where)