def test_contains_set_correctly(self): self.assertIsNotNone( ApiResource('url', 'netloc', { 'Links': { 'Contains': [] } }, None).contains) self.assertEqual( 1, len( ApiResource('url', 'netloc', { 'Links': { 'Contains': [{ "@odata.id": 1 }] } }, None).contains)) contains = ApiResource('url', 'netloc', { 'Links': { 'Contains': [{ "@odata.id": 'id_1' }, { "@odata.id": 'id_2' }] } }, None).contains self.assertEqual(2, len(contains)) self.assertIn('id_1', contains) self.assertIn('id_2', contains)
def test_contained_by_set_to_null_when_definition_is_invalid(self): self.assertIsNone( ApiResource('url', 'netloc', { 'Links': 1 }, None).contained_by) self.assertIsNone( ApiResource('url', 'netloc', { 'Links': { 'ContainedBy': 1 } }, None).contained_by) self.assertIsNone( ApiResource('url', 'netloc', { 'Links': { 'ContainedBy': [] } }, None).contained_by) self.assertIsNone( ApiResource('url', 'netloc', { 'Links': { 'ContainedBy': { "foo": "bar" } } }, None).contained_by)
def test_contains_set_to_null_when_definition_is_invalid(self): self.assertIsNone( ApiResource('url', 'netloc', { 'Links': 1 }, None).contains) self.assertIsNone( ApiResource('url', 'netloc', { 'Links': { 'Contains': 1 } }, None).contains) self.assertIsNone( ApiResource('url', 'netloc', { 'Links': { 'Contains': [1] } }, None).contains) self.assertIsNone( ApiResource('url', 'netloc', { 'Links': { 'Contains': [{ 1: 2 }] } }, None).contains)
def test_more_than_one_root_resource(self): container = DiscoveryContainer() container.add_resource( ApiResource( "id_1", 'netloc', { '@odata.id': '123', 'Oem': { 'Intel_RackScale': { 'Location': { 'Id': 1, 'ParentId': None } } } }, None)) container.add_resource( ApiResource( "id_2", 'netloc', { '@odata.id': '456', 'Oem': { 'Intel_RackScale': { 'Location': { 'Id': 3, 'ParentId': None } } } }, None)) root_ids = [r.odata_id for r in container.root_resources()] self.assertEqual(2, len(root_ids)) self.assertIn('123', root_ids) self.assertIn('456', root_ids)
def test_non_empty_root_resources(self): container = DiscoveryContainer() container.add_resource( ApiResource( "id_1", 'netloc', { '@odata.id': '123', 'Oem': { 'Intel_RackScale': { 'Location': { 'Id': 1, 'ParentId': None } } } }, None)) container.add_resource( ApiResource("id_2", 'netloc', { 'Oem': { 'Intel_RackScale': { 'Location': { 'Id': 3, 'ParentId': 4 } } } }, None)) root = container.root_resources() self.assertEqual(1, len(root)) self.assertEqual('123', root[0].odata_id)
def test_empty_root_resources_when_none_location_has_empty_parentid(self): container = DiscoveryContainer() container.add_resource( ApiResource("id_1", 'netloc', { 'Oem': { 'Intel_RackScale': { 'Location': { 'Id': 1, 'ParentId': 2 } } } }, None)) container.add_resource( ApiResource("id_2", 'netloc', { 'Oem': { 'Intel_RackScale': { 'Location': { 'Id': 3, 'ParentId': 4 } } } }, None)) self.assertFalse(container.root_resources())
def test_empty_root_resources_when_location_not_specified(self): container = DiscoveryContainer() container.add_resource(ApiResource("id_1", 'netloc', {}, None)) container.add_resource( ApiResource("id_1", 'netloc', {'some_property': 'some_value'}, None)) self.assertFalse(container.root_resources())
def test_iter_all(self): metadata_manager = MetadataManager(["qualifier"]) discovery_container = DiscoveryContainer( metadata_container=metadata_manager.read_metadata_from_strings( "Unknown", self.TEST_METADATA)) chassis1_2 = { "@odata.context": "/redfish/v1/$metadata#Chassis/Members/$entity", "@odata.id": "/redfish/v1/Chassis/Rack1", "@odata.type": "#Chassis.v1_2_0.Chassis", "ChassisType": "Rack", } discovery_container.add_resource( ApiResource("/redfish/v1/Chassis/Rack1", 'netloc', chassis1_2, "Chassis.v1_2_0.Chassis")) self.assertEqual( 1, len(list(discovery_container.iter_all("Chassis.v1_2_0.Chassis")))) self.assertEqual( 1, len(list(discovery_container.iter_all("Chassis.v1_0_0.Chassis")))) self.assertEqual( 1, len(list(discovery_container.iter_all("Chassis.Chassis")))) self.assertEqual( 1, len(list( discovery_container.iter_all("Resource.v1_0_0.Resource")))) self.assertEqual( 1, len(list(discovery_container.iter_all("Resource.Resource")))) chassis1_0 = { "@odata.context": "/redfish/v1/$metadata#Chassis/Members/$entity", "@odata.id": "/redfish/v1/Chassis/Module1", "@odata.type": "#Chassis.v1_0_0.Chassis", "ChassisType": "Module", } discovery_container.add_resource( ApiResource("/redfish/v1/Chassis/Module1", 'netloc', chassis1_0, "Chassis.v1_0_0.Chassis")) self.assertEqual( 1, len(list(discovery_container.iter_all("Chassis.v1_2_0.Chassis")))) self.assertEqual( 2, len(list(discovery_container.iter_all("Chassis.v1_0_0.Chassis")))) self.assertEqual( 2, len(list(discovery_container.iter_all("Chassis.Chassis")))) self.assertEqual( 2, len(list( discovery_container.iter_all("Resource.v1_0_0.Resource")))) self.assertEqual( 2, len(list(discovery_container.iter_all("Resource.Resource"))))
def test_should_pass_for_chassis_with_power(self): self.discovery_container.add_resource(ApiResource("/redfish/v1/Chassis/rack-with-power", 'netloc', RACK_WITH_POWER, "Chassis.v1_1_0.Chassis")) self.discovery_container.add_resource(ApiResource( "/redfish/v1/Chassis/rack-with-power/PowerZones", 'netloc', POWER_ZONES_EMPTY, "PowerZoneCollection.PowerZoneCollection")) self.discovery_container.add_resource(ApiResource( "/redfish/v1/Chassis/rack-with-power/Power", 'netloc', POWER_WITH_POWER_CONTROL, "Power.v1_1_0.Power")) self.discovery_container.add_resource(ApiResource( "/redfish/v1/Chassis/rack-with-power/Power/PowerControl/1", 'netloc', POWER_CONTROL_1, "Power.v1_1_0.PowerControl")) with StdoutCapture() as output: self.checklist.power_monitoring_support(self.discovery_container) self.assertEqual(ValidationStatus.PASSED, self.checklist.validation_status)
def setUp(self): metadata_manager = MetadataManager(["qualifier"], ) self.metadata_container = metadata_manager.read_metadata_from_strings("Unknown", METADATA) self.discovery_container = DiscoveryContainer() self.discovery_container.add_resource(ApiResource("/redfish/v1/Managers/RMC", 'netloc', RESOURCE, "#Manager.1.0.0.Manager"))
def test_parent_odata_id(self): child_parent_pairs = [ ("", None), (None, None), ("/", ""), ("/anything", "/"), ("/some/resource/path", "/some/resource"), ("/some/resource/path/", "/some/resource"), ("/redfish/v1/EthernetSwitches/1/Ports/1/VLANs/1", "/redfish/v1/EthernetSwitches/1/Ports/1/VLANs"), ("/redfish/v1/EthernetSwitches/1/Ports/1/VLANs/", "/redfish/v1/EthernetSwitches/1/Ports/1"), ("/redfish/v1/Chassis/cr1-1/Thermal#/Temperatures/1", "/redfish/v1/Chassis/cr1-1/Thermal#/Temperatures") ] with StdoutCapture() as output: # some warnings for Nones and empty strings expected for pair in child_parent_pairs: resource = ApiResource(pair[0], 'netloc', { '@odata.id' : pair[0] }, None) self.assertEqual(resource._get_parent_url(), pair[1])
def _test_case_get_created_logical_drive(self, logical_drive=None): print "TEST_CASE::Get the created logical drive" if not logical_drive: logical_drive = self.created_logical_drive status, status_code, response_body, _ = self.api_caller.get_resource(logical_drive) if not status: print "ERROR::Wrong status code of GET response: %s" % status_code print "ERROR::Response body:\n%s" % response_body self.set_status_failed() return ValidationStatus.FAILED else: api_resource = ApiResource(response_body, response_body["@odata.type"]) self.discovery_container.add_resource(logical_drive, api_resource) print "MESSAGE::Comparing newly created logical drive to given payload" ignored_fields = ["/Name", "/Image"] # Name setting not supported by PSME REST API, Image is optional print "MESSAGE::Comparing newly created logical drive to given payload" if not JsonComparator.compare_json_to_golden(response_body, self.expected_created_logical_drive_body, ignore = ignored_fields): print "ERROR::Newly created logical drive's body incorrect" self.set_status_failed() print "MESSAGE::Proceeding with deleting the resource" return ValidationStatus.FAILED print "MESSAGE::Newly created logical drive's body correct" self.set_status_passed() return ValidationStatus.PASSED
def get_resource(self, url, discovery_container, acceptable_return_codes=None, api_endpoint_override=None, check_resource_against_metadata=None): """ Sends http GET request to remote endpoint and retrieves resource odata_id. :type url: str :type discovery_container: DiscoveryContainer :type acceptable_return_codes: list(int) :rtype link :rtype status :rtype status_code :rtype response_body :rtype headers """ link, status, status_code, response_body, headers = \ self._perform_call(url, acceptable_return_codes=acceptable_return_codes, api_endpoint_override=api_endpoint_override) if not discovery_container: return link, status, status_code, response_body, headers if status == RequestStatus.SUCCESS: if response_body and status_code != ReturnCodes.NOT_FOUND: status = discovery_container.add_resource( ApiResource(link.link, link.netloc, response_body, discovery_container.get_expected_odata_type_for_url(link.link)), check_resource_against_metadata=check_resource_against_metadata) else: cts_error("{url:id} Get failed. Status code: {code}", url=url, code=status_code) return link, status, status_code, response_body, headers
def test_should_fail_when_processors_invalid_on_computer_system(self): system = { "@odata.context": "/redfish/v1/$metadata#Systems/Members/$entity", "@odata.id": "/redfish/v1/Systems/s1-2", "@odata.type": "#ComputerSystem.v1_0_0.ComputerSystem", "ProcessorSummary": { "Count": 0 }, "MemorySummary": { "TotalSystemMemoryGiB": 8 } } self.discovery_container.add_resource( ApiResource("/redfish/v1/ComputerSystem/1", 'netloc', system, "ComputerSystem.v1_1_0.ComputerSystem")) with StdoutCapture() as output: self.checklist.at_least_one_compute_module_in_pod( self.discovery_container) self.assertIn( 'ERROR::Computer System with memory and processors not found', output.raw) self.assertIn('STATUS::Failed', output)
def test_visited_endpoint(self): discovery_container = DiscoveryContainer() discovery_container.add_resource(ApiResource("http://ip:123/something", None, {}, None)) discovery_container.add_resource = MagicMock() returned_discovery_container, _ = self.api_explorer.discover("http://ip:123/something", None, discovery_container) discovery_container.add_resource.assert_not_called()
def test_location_set_to_null_when_definition_is_invalid(self): self.assertIsNone( ApiResource('url', 'netloc', { 'Oem': 1 }, None).location) self.assertIsNone( ApiResource('url', 'netloc', { 'Oem': {} }, None).location) self.assertIsNone( ApiResource('url', 'netloc', { 'Oem': { 'Intel_RackScale': 2 } }, None).location) self.assertIsNone( ApiResource('url', 'netloc', { 'Oem': { 'Intel_RackScale': {} } }, None).location) self.assertIsNone( ApiResource('url', 'netloc', { 'Oem': { 'Intel_RackScale': { 'Location': 2 } } }, None).location) self.assertIsNone( ApiResource('url', 'netloc', { 'Oem': { 'Intel_RackScale': { 'Location': {} } } }, None).location) self.assertIsNone( ApiResource('url', 'netloc', { 'Oem': { 'Intel_RackScale': { 'Location': { 'Id': 2 } } } }, None).location) self.assertIsNone( ApiResource('url', 'netloc', { 'Oem': { 'Intel_RackScale': { 'Location': { 'ParentId': 2 } } } }, None).location)
def setUp(self): metadata_manager = MetadataManager(["qualifier"]) self.metadata_container = metadata_manager.read_metadata_from_strings( METADATA) self.discovery_container = DiscoveryContainer() self.discovery_container.add_resource( ApiResource("/redfish/v1/Fabrics/1/Endpoints/8", 'netloc', RESOURCE, "#Endpoint.v1_0_0.Endpoint"))
def test_contained_by_set_correctly(self): self.assertEqual( "alamakota", ApiResource('url', 'netloc', { 'Links': { 'ContainedBy': { "@odata.id": "alamakota" } } }, None).contained_by)
def test_location_set_correctly(self): self.assertIsNotNone( ApiResource('url', 'netloc', { 'Oem': { 'Intel_RackScale': { 'Location': { 'Id': 1, 'ParentId': 2 } } } }, None).location)
def test_reference_is_recreated(self): container = DiscoveryContainer() container.add_resource( ApiResource( "id_1", 'netloc', { '@odata.id': 'id1', 'Oem': { 'Intel_RackScale': { 'Location': { 'Id': 1, 'ParentId': 2 } } } }, None)) container.add_resource( ApiResource( "id_2", 'netloc', { '@odata.id': 'id2', 'Oem': { 'Intel_RackScale': { 'Location': { 'Id': 3, 'ParentId': 4 } } } }, None)) res = container["id_2"] self.assertTrue(isinstance(res, ApiResourceProxy)) self.assertEquals(res.odata_id, "id2") container.delete_resource("id_2") with StdoutCapture() as output: with self.assertRaises(AttributeError): res.odata_id self.assertIn('ERROR::ApiResources id_2 is no longer valid', output.raw)
def test_allowable(self): resource = ApiResource( 'url', 'netloc', { 'a' : 'A', 'b' : 'B', '*****@*****.**' : [ 'B', 'C' ], 'c' : { 'ca' : 1, '*****@*****.**' : [ 1, 2 ] } } , None) self.assertEqual([], resource.get_allowable_from_path(['a'])) self.assertEqual(['B', 'C'], resource.get_allowable_from_path(['b'])) self.assertEqual([], resource.get_allowable_from_path(['c'])) self.assertEqual([1,2], resource.get_allowable_from_path(['c', 'ca']))
def _get_members(self, url, response_body, expected_odata_type, api_endpoint_override=None): status = ValidationStatus.BLOCKED link = None if "Members" in response_body: len_members_exists = len(response_body["Members"]) founded_members = [] for founded_member in range(0, len_members_exists): founded_members.append( response_body["Members"][founded_member]["@odata.id"]) for founded_member in list(set(founded_members)): link, status, response_body = self._get_resource( founded_member, api_endpoint_override=api_endpoint_override) if status == RequestStatus.SUCCESS and response_body: api_resource = ApiResource(link.link, link.netloc, response_body, expected_odata_type) self._discovery_container.add_resource(api_resource) self._process_resource(api_resource) if not response_body: cts_error("GET {id:id} Empty response body", id=url) self._status = ValidationStatus.FAILED return if status == RequestStatus.SUCCESS and response_body: api_resource = ApiResource(link.link, link.netloc, response_body, expected_odata_type) self._discovery_container.add_resource(api_resource) self._process_resource(api_resource)
def test_not_found_in_non_empty_discovery_container(self): discovery_container = DiscoveryContainer(metadata_container=self.metadata_container) discovery_container.add_resource(ApiResource("id_1", 'netloc', {'@odata.id': '123', 'Oem': {'Intel_RackScale': {'Location': {'Id': 1, 'ParentId': None} } } }, None)) requirements = [ Requirement("Chassis.Chassis", min=1, max=1) ] preconditions = Preconditions(self.metadata_container, requirements) self.assertEqual(ValidationStatus.FAILED, preconditions.validate(discovery_container))
def test_should_pass_if_entity_type_declared_on_ignore_list(self): metadata_manager = MetadataManager(["qualifier"], ignore_types=["N.R"]) self.metadata_container = metadata_manager.read_metadata_from_strings( "Unknown", METADATA) self.discovery_container = DiscoveryContainer() self.discovery_container.add_resource( ApiResource("/redfish/resource1", 'netloc', RESOURCE_WITH_INVALID_PROPERTY_VALUE, "#N.R")) requirements = [] validator = MetadataGetValidator(self.metadata_container, requirements) self.assertEqual(ValidationStatus.PASSED, validator.validate(self.discovery_container))
def test_should_pass_with_correct_resource(self): metadata_manager = MetadataManager(["qualifier"]) self.metadata_container = metadata_manager.read_metadata_from_strings( "Unknown", METADATA) self.discovery_container = DiscoveryContainer() self.discovery_container.add_resource( ApiResource("/redfish/resource1", 'netloc', RESOURCE_CORRECT, "#N.R")) requirements = [] validator = MetadataGetValidator(self.metadata_container, requirements) with StdoutCapture() as output: self.assertEqual(ValidationStatus.PASSED, validator.validate(self.discovery_container))
def test_fail_when_more_than_max(self): discovery_container = DiscoveryContainer(metadata_container=self.metadata_container) discovery_container.add_resource(ApiResource("id_1", 'netloc', {'@odata.id': '123', '@odata.type' : '#Chassis.v1_0_0.Chassis', 'Oem': {'Intel_RackScale': {'Location': {'Id': 1, 'ParentId': None} } } }, None)) requirements = [ Requirement("Chassis.Chassis", min=0, max=0) ] preconditions = Preconditions(self.metadata_container, requirements) self.assertEqual(ValidationStatus.FAILED, preconditions.validate(discovery_container))
def test_should_not_patch_if_property_annotation_is_non_trivial_and_alternative_implementation_not_known( self): """ when additional property of type 'ComplexType' does have annotation Term Nontriavial should not be patched """ metadata_manager = MetadataManager(["qualifier"]) metadata_container = metadata_manager.read_metadata_from_strings( AdditionalPropertiesPatchTest.METADATA) entity_json = { "@odata.type": "MyNamespace.v1_0_0.MyEntity", "Outer": { "@odata.type": "MyNamespace.v1_0_0.OuterComplexType", "Name": "OuterName", "InnerToValidate": { "@odata.type": "MyNamespace.v1_0_0.InnerComplexType", "Name": "This name property is required" } } } self.discovery_container.add_resource( ApiResource("/redfish/v1/Managers/RMC", "netloc", entity_json, "#MyNamespace.v1_0_0.MyEntity")) with mock.patch('cts_core.commons.api_caller.ApiCaller.__init__' ) as api_caller_init_mock: api_caller_init_mock.return_value = None validator = MetadataPatchValidator(metadata_container, None, PatchingStrategy2_2()) # this ValidationStatus.BLOCKED should be not affect final ValidationStatus validator._verify_property = MagicMock( return_value=(ValidationStatus.BLOCKED, None)) validator._restore_property = MagicMock( return_value=ValidationStatus.BLOCKED) validator._patch_property = MagicMock( return_value=(True, True, ValidationStatus.BLOCKED)) with StdoutCapture() as out: self.assertEqual(ValidationStatus.PASSED_WITH_WARNINGS, validator.validate(self.discovery_container)) self.assertIn('WARNING::Skipping non-trivial property Name;', out.raw)
def test_should_fail_bacause_of_unknown_entity_type(self): metadata_manager = MetadataManager(["qualifier"]) self.metadata_container = metadata_manager.read_metadata_from_strings( "Unknown", METADATA) self.discovery_container = DiscoveryContainer() self.discovery_container.add_resource( ApiResource("/redfish/resource1", 'netloc', RESOURCE_WITH_UNKNOWN_ENTITY_TYPE, "#N.R")) requirements = [] validator = MetadataGetValidator(self.metadata_container, requirements) with StdoutCapture() as output: self.assertEqual(ValidationStatus.FAILED, validator.validate(self.discovery_container)) self.assertIn("ERROR::Unknown entity type 'unknown.entity.type'", output.raw)
def test_should_pass_when_unknown_entity_type_mapped_to_known_one(self): metadata_manager = MetadataManager(["qualifier"], map_types={ "A": "B", "unknown.entity.type": "N.R" }) self.metadata_container = metadata_manager.read_metadata_from_strings( "Unknown", METADATA) self.discovery_container = DiscoveryContainer() self.discovery_container.add_resource( ApiResource("/redfish/resource1", 'netloc', RESOURCE_WITH_UNKNOWN_ENTITY_TYPE, "#N.R")) requirements = [] validator = MetadataGetValidator(self.metadata_container, requirements) self.assertEqual(ValidationStatus.PASSED, validator.validate(self.discovery_container))
def test_should_fail_bacause_of_unknown_complex_type(self): metadata_manager = MetadataManager(["qualifier"]) self.metadata_container = metadata_manager.read_metadata_from_strings( "Unknown", METADATA) self.discovery_container = DiscoveryContainer() self.discovery_container.add_resource( ApiResource("/redfish/resource1", 'netloc', RESOURCE_WITH_UNKNOWN_COMPLEX_TYPE, "#N.R")) requirements = [] validator = MetadataGetValidator(self.metadata_container, requirements) with StdoutCapture() as output: self.assertEqual(ValidationStatus.FAILED, validator.validate(self.discovery_container)) self.assertIn('Reference to unknown type unknown.complex.type', '\n'.join(output))
def test_should_validate_dynamic_properties_at_entity_level(self): metadata_manager = MetadataManager(["qualifier"]) self.metadata_container = metadata_manager.read_metadata_from_strings( "Unknown", METADATA) self.discovery_container = DiscoveryContainer() self.discovery_container.add_resource( ApiResource("/redfish/resource1", 'netloc', RESOURCE_WITH_INCOMPLETE_DYNAMIC_PROPERTY, "#N.R")) requirements = [] validator = MetadataGetValidator(self.metadata_container, requirements) with StdoutCapture() as output: self.assertEqual(ValidationStatus.FAILED, validator.validate(self.discovery_container)) self.assertIn( 'ERROR::Required property resource.id->aaaaaaaa->Obligatory not present in the resource', '\n'.join(output))