コード例 #1
0
    def run(self):
        api_explorer = ApiExplorer(self.metadata_container, self.configuration)
        discovery_container, status = api_explorer.discover(
            MetadataConstants.SERVICE_ROOT_URI, MetadataConstants.SERVICE_ROOT)
        status = ValidationStatus.PASSED

        catalog = expanduser(
            "~"
        ) + "/.cts/tests/Rack_Scale_2_5_Storage_Services/required/tests_archeo_ss/"
        for test in listdir(catalog):
            with open(catalog + test) as f:
                data = json.load(f)
                test_name = data["name"]
                print "TEST_CASE::Validating section " + ColorPrinter.format_text(test_name,
                                                                                  color=ColorPrinter.YELLOW_FORE) + \
                      " of architecture specification"
                status_of_test = ArchSpecTests().parse_json(
                    discovery_container, data)
                if _skip_pnc_tests_if_resource_is_not_available(test) and \
                        (status_of_test == ValidationStatus.FAILED):
                    status = ValidationStatus.join_statuses(
                        status, ValidationStatus.PASSED_WITH_WARNINGS)
                    print "MESSAGE:: CTS can not detect a PNC. Skipping this tests"
                else:
                    status = ValidationStatus.join_statuses(
                        status, status_of_test)
                print "STATUS::{status}".format(status=status_of_test)
        print "MESSAGE::All tests finished"
        print "STATUS::{status}".format(status=status)
コード例 #2
0
ファイル: validate_use_case.py プロジェクト: 01org/intelRSD
    def action_runner(self, specific_action):
        actions_status = ValidationStatus.RUNNING

        for action_step, action in enumerate(specific_action['actions'], 1):
            step_counter = "%d/%d" % (action_step, len(specific_action['actions']))
            action_type = action['type']
            if action_type == 'timeout':
                try:
                    self.perform_timeout(step_counter, action['value'])
                except IndexError:
                    self.perform_timeout(step_counter)
                continue

            retry_if_fail, retry_timeout = self.__get_retry_information(action)
            action_args = (specific_action['name'],
                           action['name'],
                           action['action'],
                           step_counter,
                           int(retry_if_fail),
                           int(retry_timeout))

            if action_type == 'external':
                actions_status = ValidationStatus.join_statuses(self.perform_external_command(*action_args))
                continue
            elif action_type == 'usecase':
                actions_status = ValidationStatus.join_statuses(self.perform_action(*action_args))
        return actions_status
コード例 #3
0
    def run(self):
        if self.metadata_container is None:
            return

        test_name = "Storage Services CRUD test"
        print "MESSAGE::%s starting" % test_name

        print "TEST_CASE::API crawling"
        api_explorer = ApiExplorer(self.metadata_container, self.configuration)
        self.discovery_container, status = api_explorer.discover(MetadataConstants.SERVICE_ROOT_URI,
                                                                 MetadataConstants.SERVICE_ROOT)
        print "STATUS::{status}".format(status=status)

        requirements = [
            Requirement(MetadataConstants.SERVICE_ROOT, min=1, max=1),
            Requirement(MetadataConstants.STORAGE_SERVICE, min=1),
            Requirement(MetadataConstants.LOGICAL_DRIVE_COLLECTION, min=1),
            Requirement(MetadataConstants.REMOTE_TARGET_COLLECTION, min=1),
            Requirement(MetadataConstants.LOGICAL_DRIVE, min=2)
        ]
        preconditions = Preconditions(self.metadata_container, requirements)
        status = preconditions.validate(self.discovery_container)

        if  status == ValidationStatus.FAILED:
            self.set_status_blocked()
            return

        self.api_caller = ApiCaller(self.configuration)

        status = ValidationStatus.join_statuses(status, self.crud_logical_drive())
        status = ValidationStatus.join_statuses(status, self.crud_remote_target())

        print "MESSAGE::%s overall status: %s" % (test_name, ColorPrinter.format_status(status))
コード例 #4
0
    def _patch_and_verify_property(self, context, variable_path, current_value, value_requested,
                                   verify_only_response=False, collection=None, property_description_type=None):
        """
        :type context: Context
        :type variable_path: list [str or int]
        :type current_value: *
        :type value_requested: *
        :type verify_only_response: bool
        """

        property = "%s[%s]" \
                   % (context.api_resource.odata_id, "->".join([str(path) for path in
                                                                variable_path]))

        patch_applied, status, validation_status = self._patch_property(context,
                                                                        property,
                                                                        current_value,
                                                                        value_requested,
                                                                        variable_path,
                                                                        collection=collection)
        # only _verify_property if the PATCH request succeeded and is not only writeable
        if status == RequestStatus.SUCCESS and patch_applied:
            if not verify_only_response:
                verify_status, current_value = self._verify_property(context,
                                                                     patch_applied,
                                                                     property,
                                                                     current_value,
                                                                     value_requested,
                                                                     variable_path,
                                                                     property_description_type=property_description_type)
                validation_status = ValidationStatus.join_statuses(validation_status, verify_status)
            else:
                validation_status = ValidationStatus.join_statuses(validation_status, ValidationStatus.PASSED)

        return validation_status, current_value
コード例 #5
0
    def action_runner(self, specific_action):
        actions_status = ValidationStatus.RUNNING

        for action_step, action in enumerate(specific_action['actions'], 1):
            step_counter = "%d/%d" % (action_step,
                                      len(specific_action['actions']))
            action_type = action['type']
            if action_type == 'timeout':
                try:
                    self.perform_timeout(step_counter, action['value'])
                except IndexError:
                    self.perform_timeout(step_counter)
                continue

            retry_if_fail, retry_timeout = self.__get_retry_information(action)
            action_args = (specific_action['name'], action['name'],
                           action['action'], step_counter, int(retry_if_fail),
                           int(retry_timeout))

            if action_type == 'external':
                actions_status = ValidationStatus.join_statuses(
                    self.perform_external_command(*action_args))
                continue
            elif action_type == 'usecase':
                actions_status = ValidationStatus.join_statuses(
                    self.perform_action(*action_args))
        return actions_status
コード例 #6
0
    def min_count_search(api, key):
        """
        Verify the minimal presents of the properties
        :param api:
        :param key:
        :return:
        """
        resource_tree = objectpath.Tree(json.loads(json.dumps(api)))

        phase_status = ValidationStatus.PASSED

        for element_key, element_count in key.iteritems():
            result_tuple = tuple(
                resource_tree.execute('$..{key}'.format(key=element_key)))

            if len(result_tuple) < 1:
                cts_color_message(
                    "\t{status} Minimal count of {element_key} not achieved. Minimum values <= {count}"
                    .format(status=get_fail(),
                            element_key=element_key,
                            count=element_count))
                phase_status = ValidationStatus.join_statuses(
                    ValidationStatus.FAILED)
            else:
                cts_color_message(
                    "\t{status} Minimal count of {element_key} was achieved".
                    format(status=get_ok(), element_key=element_key))
                phase_status = ValidationStatus.join_statuses(
                    ValidationStatus.PASSED)
        return phase_status
コード例 #7
0
    def _validate_patchable_property(self, context, variable_path, property_description):
        """
        :type context: Context
        :type variable_path: list [str or int]
        :type property_description: cts_core.metadata.model.property.Property
        :rtype: str
        """
        api_resource = context.api_resource
        verify_only_response = property_description.patch_status == PatchStatus.WRITE_ONLY

        new_values_list = property_description.generate_values(property_description.annotations)
        allowed_values = api_resource.get_allowable_from_path(variable_path)
        if allowed_values:
            new_values_list = [value for value in new_values_list if value in allowed_values]

        collection = None
        if property_description.is_collection and len(variable_path) > 1:
            collection = api_resource.get_value_from_path(variable_path[:-1])

        try:
            value_pre = current_value = api_resource.get_value_from_path(variable_path)
        except KeyError:
            return ValidationStatus.PASSED

        total_status = ValidationStatus.PASSED

        for new_value in new_values_list:
            if new_value != current_value:
                status, current_value = \
                    self._patch_and_verify_property(context,
                                                    variable_path,
                                                    current_value,
                                                    new_value,
                                                    verify_only_response,
                                                    collection=collection,
                                                    property_description_type=property_description.name)

                total_status = ValidationStatus.join_statuses(total_status, status)

                if current_value is None:
                    try:
                        value_pre = current_value = api_resource.get_value_from_path(variable_path)
                    except KeyError:
                        return total_status

        if not allowed_values or value_pre in allowed_values:
            total_status = ValidationStatus.join_statuses(total_status,
                                                          self._restore_property(context,
                                                                                 value_pre,
                                                                                 variable_path,
                                                                                 collection=collection))
        else:
            print "MESSAGE::Original value '{value_pre}' is illegal. Will not _restore_property" \
                .format(value_pre=dumps(value_pre))

        return total_status
コード例 #8
0
    def _validate_property_list(self, context, variable_path, property_list):
        """
        :type context: Context
        :type variable_path: list [str or int]
        :type property_list: list[cts_core.metadata.model.property.Property]
        :rtype: str
        """
        api_resource = context.api_resource

        status = ValidationStatus.PASSED
        # use local copy - api resource will be modified while test is executed
        local_property_list = list(property_list)
        for property_description in local_property_list:
            status = ValidationStatus.join_statuses(
                self._validate_property(context, variable_path,
                                        property_description), status)

        # validate additional properties
        try:
            body = api_resource.get_value_from_path(variable_path)
        except KeyError as key:
            cts_warning("Unable to access {odataid:id}->{path}. Key={key}",
                        odataid=api_resource.odata_id,
                        path="->".join(variable_path),
                        key=key)
            body = None

        if body is not None:
            all_properties = set(body.keys())
            known_properties = set(
                [property.name for property in local_property_list])
            additional_properties = all_properties - known_properties
            for additional_property_name in additional_properties:
                property_value = body[additional_property_name]
                if isinstance(property_value,
                              dict) and "@odata.type" in property_value:
                    raw_soup = """
                    <Property Name="{name}" Type="{type}">
                        <Annotation Term="OData.Permissions"
                                    EnumMember="OData.Permission/ReadWrite"/>
                    </Property>
                    """
                    soup = BeautifulSoup(
                        raw_soup.format(name=additional_property_name,
                                        type=get_odata_type(property_value)),
                        "lxml").find_all("property")[0]

                    adhoc_description = Property(self._metadata_container,
                                                 None, soup)
                    status = ValidationStatus.join_statuses(
                        self._validate_property(context, variable_path,
                                                adhoc_description), status)

        return status
コード例 #9
0
    def validate(self, discovery_container):
        """
        :type discovery_container: cts_core.discovery.discovery_container.DiscoveryContainer
        :rtype: cts_core.validation.validation_status.ValidationStatus
        """
        print "TEST_CASE::Checking for mandatory entities"
        status = self._preconditions.validate(discovery_container)
        print "STATUS::%s" % status

        resources = discovery_container.itervalues()
        count = len(discovery_container)
        for idx, api_resource in enumerate(resources):
            print "TEST_CASE::%s" % api_resource.odata_id
            print "MESSAGE::[%5d/%5d] Checking %s : %s" % (
                idx + 1, count, api_resource.odata_id, api_resource.odata_type)

            api_resource_status = self.validate_single_entity(api_resource)
            print "STATUS::%s" % api_resource_status

            redfish_uri_compliance = discovery_container.validate_redfish_uris_consistency(
                api_resource, self._metadata_container)
            status = ValidationStatus.join_statuses(status,
                                                    api_resource_status,
                                                    redfish_uri_compliance)

        print "SCREEN::Overall status: %s" % status
        return status
コード例 #10
0
 def set_validation_status(self, status):
     print "STATUS::%s" % status
     if hasattr(self, "validation_status"):
         self.validation_status = ValidationStatus.join_statuses(
             self.validation_status, status)
     else:
         self.validation_status = status
コード例 #11
0
ファイル: crud_operations.py プロジェクト: 01org/intelRSD
    def run(self):
        if self.metadata_container is None:
            return

        self.chosen_endpoint, self.chosen_zone, self.chosen_volume, self.chosen_volume_collection = (None,)*4
        self.initiator_endpoint, self.target_endpoint, self.zone_endpoint, self.created_volume = (None,)*4

        test_name = "Storage Services CRUD test"
        print "MESSAGE::%s starting" % test_name

        print "TEST_CASE::API crawling"
        api_explorer = ApiExplorer(self.metadata_container, self.configuration)
        self.discovery_container, status = api_explorer.discover(MetadataConstants.SERVICE_ROOT_URI,
                                                                 MetadataConstants.SERVICE_ROOT)
        print "STATUS::{status}".format(status=status)

        requirements = [
            Requirement(MetadataConstants.SERVICE_ROOT, min=1, max=1),
            Requirement(MetadataConstants.STORAGE_SERVICE, min=1),
            Requirement(MetadataConstants.VOLUME, min=1),
            Requirement(MetadataConstants.VOLUME_COLLECTION, min=1)
        ]
        preconditions = Preconditions(self.metadata_container, requirements)
        status = preconditions.validate(self.discovery_container)

        if status == ValidationStatus.FAILED:
            self.set_status_failed()
            return

        self.api_caller = ApiCaller(self.configuration)

        status = ValidationStatus.join_statuses(status, self.crud_fabrics_target())

        print "MESSAGE::%s overall status: %s" % (test_name, ColorPrinter.format_status(status))
コード例 #12
0
    def validate(self, resource, resource_path, annotations=None):
        """
        :type annotations: dict
        :type resource: dict
        :type resource_path: str
        :rtype: str
        """
        try:
            odata_type = self.metadata_container.map_type(get_odata_type(resource))
            mapped_odata_type = self.metadata_container.map_type(odata_type)
            if self.metadata_container.to_be_ignored(odata_type, mapped_odata_type):
                return ValidationStatus.PASSED
        except KeyError:
            pass #this is legal that complex type does not have odata.type specified

        types_consistency_validation_status, complex_type_name = self.validate_types_consistency(resource, resource_path)
        if self.metadata_container.to_be_ignored(complex_type_name):
            return ValidationStatus.PASSED

        if complex_type_name == self.name:
            resource_validation_status = self.validate_properties(resource, resource_path)
        else:
            try:
                resource_validation_status = self.metadata_container.types[complex_type_name].validate(resource, resource_path)
            except KeyError:
                resource_validation_status = ValidationStatus.FAILED
            except Exception as err:
                import traceback
                cts_error("{path} - exception {err:exceptions}: {stack:stacktrace}",
                          path=resource_path, err=err, stack=traceback.format_exc())
                resource_validation_status = ValidationStatus.FAILED

        return ValidationStatus.join_statuses(types_consistency_validation_status, resource_validation_status)
コード例 #13
0
    def handle_nontrivial_property(self):
        try:
            value_pre = self.get_property_value()
        except KeyError:
            return ValidationStatus.FAILED

        for payload in self.payload():
            property_str = "->".join(
                map(str,
                    self.variable_path + [self.property_description.name]))
            print "TEST_CASE:: Patch %s[%s]" % (self.api_resource.odata_id,
                                                property_str)
            patch_status = self.do_patch(payload)
            print "STATUS::%s" % patch_status

            if patch_status == ValidationStatus.FAILED:
                return ValidationStatus.FAILED

            print "TEST_CASE:: Verify %s[%s]" % (self.api_resource.odata_id,
                                                 property_str)
            verify_status = self.verify(self.api_resource, payload)
            print "STATUS::%s" % verify_status

        print "TEST_CASE:: Restore %s[%s]" % (self.api_resource.odata_id,
                                              property_str)
        restore_status = self.do_restore(value_pre)
        print "STATUS::%s" % restore_status

        return ValidationStatus.join_statuses(patch_status, verify_status,
                                              restore_status)
コード例 #14
0
    def validate_path_using_contains_property(self):
        res = ValidationStatus.PASSED
        remained_to_be_visited = [r.odata_id for r in self.discover_container.physical_location_aware_resources()]
        root_resources = self.discover_container.root_resources()
        if root_resources:
            if len(root_resources) > 1:
                fmt = ', '.join(["{resources[%d].odata_id:id}" % idx for idx, _ in enumerate(root_resources)])
                cts_error("More than one root resource (with NULL ParentId). " +
                          "Expected only one. Root resources found: %s" % fmt,
                          resources=root_resources)
                res = ValidationStatus.FAILED

            for root in root_resources:
                res = ValidationStatus.join_statuses(
                    self._validate_from(root, remained_to_be_visited, parent_location=None, parent_odata_id=None),
                    res)

        else:
            if self.discover_container.physical_location_aware_resources():
                cts_error("Resources with Location in Oem property has been found, but none has NULL ParentId")
                res = ValidationStatus.FAILED

        if remained_to_be_visited:
            fmt = ', '.join(['{remained_to_be_visited[%d]:id}' % i for i, _ in enumerate(remained_to_be_visited)])
            cts_error("Not all location-aware resources visited while traversing tree using 'Link->Contains'. " +
                      "Unreachable are: %s" % fmt,
                      remained_to_be_visited=remained_to_be_visited)
            res = ValidationStatus.FAILED

        return res
コード例 #15
0
 def _test_delete_all_created_endpoints_and_zones(self):
     status = ValidationStatus.PASSED
     for resource, link in OrderedDict([("volume", self.created_volume),
                                        ("zone", self.zone_endpoint),
                                        ("initiator endpoint", self.initiator_endpoint),
                                        ("target endpoint", self.target_endpoint)]).iteritems():
         print "TEST_CASE::Delete {resource}".format(resource=resource)
         if link:
             if not self.__delete_location(link):
                 self.set_status_failed()
                 status = ValidationStatus.join_statuses(status, ValidationStatus.FAILED)
             else:
                 self.set_status_passed()
                 status = ValidationStatus.join_statuses(status, ValidationStatus.PASSED)
         else:
             self.set_status_blocked()
             status = ValidationStatus.join_statuses(status, ValidationStatus.BLOCKED)
     return status
コード例 #16
0
ファイル: crud_operations.py プロジェクト: 01org/intelRSD
 def _test_delete_all_created_endpoints_and_zones(self):
     status = ValidationStatus.PASSED
     for resource, link in OrderedDict([("volume", self.created_volume),
                                        ("zone", self.zone_endpoint),
                                        ("initiator endpoint", self.initiator_endpoint),
                                        ("target endpoint", self.target_endpoint)]).iteritems():
         print "TEST_CASE::Delete {resource}".format(resource=resource)
         if link:
             if not self.__delete_location(link):
                 self.set_status_failed()
                 status = ValidationStatus.join_statuses(status, ValidationStatus.FAILED)
             else:
                 self.set_status_passed()
                 status = ValidationStatus.join_statuses(status, ValidationStatus.PASSED)
         else:
             self.set_status_blocked()
             status = ValidationStatus.join_statuses(status, ValidationStatus.BLOCKED)
     return status
コード例 #17
0
    def test_roulette(self, api, value_element):
        test_phases = {
            self.tree_deep_search: [
                "last_property",
                "Test phase: Verify that the \"PropertyRequirements\" fields exists"
            ],
            self.min_count_search: [
                "min_count",
                "Test phase: Verify the number of elements meets the minimum criterion "
                "(\"MinCount\")"
            ],
            self.read_requirement: [
                "read_requirement",
                "Test phase: Verify that the \"ReadRequirement\" fields exist and are readable"
            ],
            self.write_requirement: [
                "write_requirement",
                "Test phase: ONLY Verify that the \"WriteRequirement\" elements are exist"
            ]
        }
        test_case_status = ValidationStatus.PASSED
        for test_to_do, test_description in test_phases.iteritems():
            phase_status = ValidationStatus.PASSED
            each_value_element = value_element[test_description[0]]
            try:
                if len(each_value_element) > 0:
                    cts_message(test_description[1])
                    each_value_element = set(
                        value_element[test_description[0]])
                else:
                    continue
            except TypeError:
                pass

            for each in each_value_element:
                phase_status = ValidationStatus.join_statuses(
                    test_to_do(api.body, each))
            print("STATUS::{status}".format(status=phase_status))
            test_case_status = ValidationStatus.join_statuses(phase_status)
        cts_color_message("Tested element {odata_type} ({odata_id})".format(
            odata_type=api.odata_type, odata_id=api.odata_id),
                          font_color="LIGHT_BLUE")
        print("STATUS::{status}".format(status=test_case_status))
コード例 #18
0
    def read_requirement(api, key):
        """
        Verify that the resource exists in the list and that it can be read with GET
        :param api:
        :param key:
        :return:
        """
        resource_tree = objectpath.Tree(json.loads(json.dumps(api)))

        phase_status = ValidationStatus.PASSED

        for element_key, element_property in key.iteritems():
            result_tuple = tuple(
                resource_tree.execute('$..{key}'.format(key=element_key)))

            if not result_tuple:
                if element_property == "Mandatory":
                    cts_error(
                        "\t{status} Element {element_key} is {element_property}"
                        .format(status=get_fail(),
                                element_key=element_key,
                                element_property=element_property))
                    phase_status = ValidationStatus.join_statuses(
                        ValidationStatus.FAILED)
                elif element_property == "IfImplemented":
                    continue
                else:
                    cts_color_message(
                        "\t{status} Element {element_key} is {element_property}"
                        .format(status=get_info(),
                                element_key=element_key,
                                element_property=element_property))
                    phase_status = ValidationStatus.join_statuses(
                        ValidationStatus.PASSED_WITH_WARNINGS)
            else:
                cts_message(
                    "\t{status} Element {element_key} is {element_property}".
                    format(status=get_ok(),
                           element_key=element_key,
                           element_property=element_property))
                phase_status = ValidationStatus.join_statuses(
                    ValidationStatus.PASSED)
        return phase_status
コード例 #19
0
    def validate(self, discovery_container):
        self.discovery_container = discovery_container
        status = self._check_mandatory_entities()

        for api_resource in self._enumerate_resources(discovery_container):
            context = Context(api_resource)
            resource_status = self._validate_resource(context)
            self._print_resource_footer(api_resource, context, resource_status)
            status = ValidationStatus.join_statuses(status, resource_status)

        print "SCREEN::Overall status: %s" % status
        return status
コード例 #20
0
ファイル: crud_operations.py プロジェクト: 01org/intelRSD
    def crud_fabrics_target(self):
        status = ValidationStatus.PASSED

        cts_message("CRUD FABRICS TARGET")

        # test pre check
        self.__find_volumes_without_any_links(optional_pre_check=True)

        try:
            status = ValidationStatus.join_statuses(status, self._test_create_volume())
        except:
            self._test_delete_all_created_endpoints_and_zones()
            status = ValidationStatus.FAILED

        self.__find_and_choose_endpoint_collection()
        self.__find_and_choose_volume()

        if not (self.chosen_volume and self.chosen_endpoint and self.chosen_zone):
            self.set_status_blocked()
            return ValidationStatus.BLOCKED

        cts_message("Chosen Volume for test: {volume_url}".format(volume_url=self.chosen_volume))

        try:
            status = ValidationStatus.join_statuses(status, self._test_create_initiator_endpoint())
            status = ValidationStatus.join_statuses(status, self._test_create_target_endpoint())
            status = ValidationStatus.join_statuses(status, self._test_create_zone_with_only_one_endpoint())
            status = ValidationStatus.join_statuses(status, self._test_patch_zone_with_target_endpoint())
        except:
            status = ValidationStatus.FAILED
        finally:
            status = ValidationStatus.join_statuses(status, self._test_delete_all_created_endpoints_and_zones())

        return status
コード例 #21
0
    def crud_nvme(self):
        status = ValidationStatus.PASSED

        cts_message("CRUD NVME")

        # test pre check
        self.__find_volumes_without_any_links(optional_pre_check=True)

        try:
            status = ValidationStatus.join_statuses(status, self._test_create_volume())
        except:
            self._test_delete_all_created_endpoints_and_zones()
            status = ValidationStatus.FAILED

        self.__find_and_choose_endpoint_collection()
        self.__find_and_choose_volume()

        if not (self.chosen_volume and self.chosen_endpoint and self.chosen_zone):
            self.set_status_blocked()
            return ValidationStatus.BLOCKED

        cts_message("Chosen Volume for test: {volume_url}".format(volume_url=self.chosen_volume))

        try:
            status = ValidationStatus.join_statuses(status, self._test_create_initiator_endpoint())
            status = ValidationStatus.join_statuses(status, self._test_create_target_endpoint())
            status = ValidationStatus.join_statuses(status, self._test_create_zone_with_only_one_endpoint())
            status = ValidationStatus.join_statuses(status, self._test_patch_zone_with_target_endpoint())
        except:
            status = ValidationStatus.FAILED
        finally:
            status = ValidationStatus.join_statuses(status, self._test_delete_all_created_endpoints_and_zones())

        return status
コード例 #22
0
    def validate_properties(self, container, path):
        """
        :type container: dict
        :type path: str
        :rtype: str
        """
        additional_items_validation = self._validate_additional_properties(container, path)

        fields_validation = list()

        for resource_property in self.properties.itervalues():
            fields_validation.append(resource_property.validate(container, path))

        return ValidationStatus.join_statuses(additional_items_validation, *fields_validation)
コード例 #23
0
ファイル: entity.py プロジェクト: 01org/intelRSD
    def _validate_container(self, container, path):
        """
        :type container: dict
        :type path: str
        :rtype: str
        """
        additional_items_validation = self._validate_additional_properties(container, path)

        fields_validation = list()

        for resource_property in self.properties.itervalues():
            fields_validation.append(resource_property.validate(container, path))

        return ValidationStatus.join_statuses(additional_items_validation, *fields_validation)
コード例 #24
0
    def validate(self,
                 resource,
                 resource_path,
                 annotations=None,
                 odata_type=None):
        """
        :type annotations: dict
        :type resource: dict
        :type resource_path: str
        :type odata_type: str
        :rtype: str
        """
        if not odata_type:
            try:
                odata_type = get_odata_type(resource)
            except KeyError:
                odata_type = None

        if not odata_type:
            cts_warning(
                "Resource {odata_id} did not report odata.type property",
                odata_id=resource_path)
            return ValidationStatus.PASSED_WITH_WARNINGS
        else:
            mapped_odata_type = self.metadata_container.map_type(odata_type)
            if self.metadata_container.to_be_ignored(odata_type,
                                                     mapped_odata_type):
                return ValidationStatus.PASSED

        types_consistency_validation_status, entity_type = self._validate_types_consistency(
            resource, resource_path, odata_type)

        if entity_type == self.name:
            resource_validation_status = self._validate_container(
                resource, resource_path)
        else:
            try:
                resource_validation_status = self.metadata_container.entities[
                    entity_type]._validate_container(resource, resource_path)
            except KeyError:
                resource_validation_status = ValidationStatus.FAILED
            except Exception as error:
                cts_error("{id:id} Unexpected error: {error:exception}",
                          id == resource_path,
                          error=error)
                resource_validation_status = ValidationStatus.FAILED

        return ValidationStatus.join_statuses(
            types_consistency_validation_status, resource_validation_status)
コード例 #25
0
    def detect(self, profile_name, purpose, profile=None):
        cts_color_message(
            "Testing a profile: {name}".format(name=profile_name), "HEADER")
        cts_color_message("Purpose: {purpose}".format(purpose=purpose))

        status = ValidationStatus.PASSED

        self.main_resource_validation(profile)
        self.show_results(profile_name)

        if self.missing_main_elements:
            status = ValidationStatus.join_statuses(ValidationStatus.BLOCKED)
            cts_warning("Some elements are missing for all tests")
            print("STATUS::{status}".format(status=status))
        else:
            status = ValidationStatus.join_statuses(ValidationStatus.PASSED)
            cts_message("All main elements are available")
            print("STATUS::{status}".format(status=status))

        self.run(self.profile_container)

        cts_color_message("Deeper verification", font_color="HEADER")
        self.validate_profile_container()
        return status
コード例 #26
0
ファイル: entity.py プロジェクト: 01org/intelRSD
    def _validate_additional_properties(self, container, path):
        """
        :type container: dict
        :type path: str
        :rtype: str
        """
        status = ValidationStatus.PASSED
        expected_properties = self.properties.keys() + self.navigation_properties.keys()
        present_properties = container.keys()
        unused_properties = set(expected_properties) - set(present_properties)

        for property_name in container.keys():
            if property_name not in expected_properties and not is_special_property(property_name):
                status = ValidationStatus.join_statuses(status,
                                                        self._validate_additional_property(property_name,
                                                                                           container[property_name],
                                                                                           path,
                                                                                           unused_properties))
        return status
コード例 #27
0
    def run(self):
        api_explorer = ApiExplorer(self.metadata_container, self.configuration)
        discovery_container, status = api_explorer.discover(MetadataConstants.SERVICE_ROOT_URI,
                                                            MetadataConstants.SERVICE_ROOT)
        status = ValidationStatus.PASSED

        catalog = expanduser("~") + "/.cts/tests/Rack_Scale_2_5_PSME/required/tests_archeo_psme/"
        for test in listdir(catalog):
            with open(catalog + test) as f:
                data = json.load(f)
                test_name = data["name"]
                print "TEST_CASE::Validating section " + ColorPrinter.format_text(test_name,
                                                                                  color=ColorPrinter.YELLOW_FORE) + \
                      " of architecture specification"
                status_of_test = ArchSpecTests().parse_json(discovery_container, data)
                print "STATUS::{status}".format(status=status_of_test)
                status = ValidationStatus.join_statuses(status, status_of_test)
        print "MESSAGE::All tests finished"
        print "STATUS::{status}".format(status=status)
コード例 #28
0
    def run(self):
        if self.metadata_container is None:
            return

        self.chosen_endpoint, self.chosen_zone, self.chosen_volume, self.chosen_volume_collection = (
            None, ) * 4
        self.initiator_endpoint, self.target_endpoint, self.zone_endpoint, self.created_volume = (
            None, ) * 4

        self.initiator_unique_name = self.generate_unique_names() if self.configuration.UniqueInitiatorName \
            != "generate" else self.configuration.UniqueInitiatorName
        self.target_unique_name = self.generate_unique_names() if self.configuration.UniqueTargetName \
            != "generate" else self.configuration.UniqueTargetName

        test_name = "Storage Services CRUD test with NVM Express (NVMe) Support"
        print "MESSAGE::%s starting" % test_name

        print "TEST_CASE::API crawling"
        api_explorer = ApiExplorer(self.metadata_container, self.configuration)
        self.discovery_container, status = api_explorer.discover(
            MetadataConstants.SERVICE_ROOT_URI, MetadataConstants.SERVICE_ROOT)
        print "STATUS::{status}".format(status=status)

        requirements = [
            Requirement(MetadataConstants.SERVICE_ROOT, min=1, max=1),
            Requirement(MetadataConstants.STORAGE_SERVICE, min=1),
            Requirement(MetadataConstants.VOLUME, min=1),
            Requirement(MetadataConstants.VOLUME_COLLECTION, min=1)
        ]
        preconditions = Preconditions(self.metadata_container, requirements)
        status = preconditions.validate(self.discovery_container)

        if status == ValidationStatus.FAILED:
            self.set_status_failed()
            return

        self.api_caller = ApiCaller(self.configuration)

        status = ValidationStatus.join_statuses(status, self.crud_nvme())

        print "MESSAGE::%s overall status: %s" % (
            test_name, ColorPrinter.format_status(status))
コード例 #29
0
    def _validate_additional_properties(self, container, path):
        """
        :type container: dict
        :type path: str
        :rtype: str
        """
        status = ValidationStatus.PASSED
        expected_properties = self.properties.keys(
        ) + self.navigation_properties.keys()
        present_properties = container.keys()
        unused_properties = set(expected_properties) - set(present_properties)

        for property_name in container.keys():
            if property_name not in expected_properties and not is_special_property(
                    property_name):
                status = ValidationStatus.join_statuses(
                    status,
                    self._validate_additional_property(
                        property_name, container[property_name], path,
                        unused_properties))
        return status
コード例 #30
0
ファイル: entity.py プロジェクト: 01org/intelRSD
    def validate(self, resource, resource_path, annotations=None, odata_type=None):
        """
        :type annotations: dict
        :type resource: dict
        :type resource_path: str
        :type odata_type: str
        :rtype: str
        """
        if not odata_type:
            try:
                odata_type = get_odata_type(resource)
            except KeyError:
                odata_type = None

        if not odata_type:
            cts_warning("Resource {odata_id} did not report odata.type property", odata_id=resource_path)
            return ValidationStatus.PASSED_WITH_WARNINGS
        else:
            mapped_odata_type = self.metadata_container.map_type(odata_type)
            if self.metadata_container.to_be_ignored(odata_type, mapped_odata_type):
                return ValidationStatus.PASSED

        types_consistency_validation_status, entity_type = self._validate_types_consistency(resource,
                                                                                            resource_path,
                                                                                            odata_type)

        if entity_type == self.name:
            resource_validation_status = self._validate_container(resource, resource_path)
        else:
            try:
                resource_validation_status = self.metadata_container.entities[entity_type]._validate_container(resource,
                                                                                                               resource_path)
            except KeyError:
                resource_validation_status = ValidationStatus.FAILED
            except Exception as error:
                cts_error("{id:id} Unexpected error: {error:exception}", id==resource_path, error=error)
                resource_validation_status = ValidationStatus.FAILED

        return ValidationStatus.join_statuses(types_consistency_validation_status, resource_validation_status)
コード例 #31
0
ファイル: property.py プロジェクト: zhangrb/intelRSD
    def _validate_collection(self, property_value, resource_path):
        value_is_collection = True
        status = ValidationStatus.PASSED
        if isinstance(property_value, list):
            try:
                for path_element, resource_element in enumerate(
                        property_value):
                    status = ValidationStatus.join_statuses(
                        self.metadata_container.types[self.type].validate(
                            resource_element,
                            "%s->%s" % (resource_path, path_element),
                            self.annotations), status)
            except TypeError:
                value_is_collection = False
        else:
            value_is_collection = False

        if not value_is_collection:
            cts_error(
                "Property {resource_path} is expected to be collection, but it is not",
                resource_path=resource_path)
            status = ValidationStatus.FAILED

        return status
コード例 #32
0
    def handle_nontrivial_property(self):
        try:
            value_pre = self.get_property_value()
        except KeyError:
            return ValidationStatus.FAILED

        for payload in self.payload():
            property_str = "->".join(map(str, self.variable_path + [self.property_description.name]))
            print "TEST_CASE:: Patch %s[%s]" % (self.api_resource.odata_id, property_str)
            patch_status = self.do_patch(payload)
            print "STATUS::%s" % patch_status

            if patch_status == ValidationStatus.FAILED:
                return ValidationStatus.FAILED

            print "TEST_CASE:: Verify %s[%s]" % (self.api_resource.odata_id, property_str)
            verify_status = self.verify(self.api_resource, payload)
            print "STATUS::%s" % verify_status

        print "TEST_CASE:: Restore %s[%s]" % (self.api_resource.odata_id, property_str)
        restore_status = self.do_restore(value_pre)
        print "STATUS::%s" % restore_status

        return ValidationStatus.join_statuses(patch_status, verify_status, restore_status)
コード例 #33
0
    def crud_logical_drive(self, create_logical_drive_for_target_crud=None):
        """
        Test is trying to perform CRUD (create, read, update, delete) operations on a logical drive
        :type create_logical_drive_for_target_crud: Boolean
        """

        status = ValidationStatus.BLOCKED

        lvm_found = False

        chosen_logical_drive_type, chosen_logical_drive_mode = None, None
        chosen_logical_drive_collection, chosen_logical_drive, chosen_logical_drive_group = None, None, None
        inherited_bootable = None

        # to speed things up, always look for the lowest capacity logical drive
        LVM_LV_SPECIFIC_CONSTRAINTS = [equal("Mode", "LV"), greater("CapacityGiB", 0), not_equal("Snapshot", True),
                                       order_by("CapacityGiB")]
        CEPH_RBD_SPECIFIC_CONSTRAINTS = [equal("Mode", "RBD"), greater("CapacityGiB", 0), order_by("CapacityGiB")]

        logical_drive_collections = dict(self.discovery_container.get_resources(
                                         MetadataConstants.LOGICAL_DRIVE_COLLECTION,
                                         any_child_version=True))

        for collection in logical_drive_collections.keys():
            chosen_logical_drive_collection = collection
            logical_drive_groups = dict(self.discovery_container.get_resources(MetadataConstants.LOGICAL_DRIVE,
                                                                      any_child_version=True,
                                                                      constraints=[equal("Mode", "LVG"),
                                                                                   from_collection(collection)]))
            if logical_drive_groups:
                lvm_found = True
            else:
                logical_drive_groups = dict(self.discovery_container.get_resources(MetadataConstants.LOGICAL_DRIVE,
                                                                                    any_child_version=True,
                                                                                    constraints=[equal("Mode", "Pool"),
                                                                                                 from_collection(
                                                                                                     collection)]))
            if logical_drive_groups:
                specific_constraints = LVM_LV_SPECIFIC_CONSTRAINTS if lvm_found else CEPH_RBD_SPECIFIC_CONSTRAINTS

                for lvg_link, lvg in logical_drive_groups.iteritems():
                    chosen_logical_drive_group = lvg.odata_id
                    try:
                        child_lvs = [lv["@odata.id"] for lv in lvg.body["Links"]["LogicalDrives"]]
                        chosen_logical_drive, _ = self.discovery_container.get_resources(
                                                                                       MetadataConstants.LOGICAL_DRIVE,
                                                                                       any_child_version=True,
                                                                                       constraints=specific_constraints
                                                                                       + [odata_ids(child_lvs)])[0]
                        lv = self.discovery_container[chosen_logical_drive]
                        inherited_bootable = lv.body["Bootable"]
                        chosen_logical_drive_type = lv.body["Type"]
                        chosen_logical_drive_mode = lv.body["Mode"]
                    except (KeyError,IndexError) as error:
                        cts_error("Exception while parsing {id:id}: {error:exception}", id=chosen_logical_drive,
                                                                                        error=error)
                        chosen_logical_drive = None
                        pass
                    else:
                        break
            if not chosen_logical_drive_group:
                resource = "logical drive group" if lvm_found else "Pool"
                cts_warning("Could not find a {resource} resource in collection {collection}", **locals())
            if lvm_found and not chosen_logical_drive:
                cts_warning("Could not find a logical volume in collection {collection}", **locals())

        if lvm_found and not chosen_logical_drive:
            cts_error("Could not find any logical volume")
            return status

        if not chosen_logical_drive_group:
            cts_error("Could not find any logical drive group, aborting")
            return status

        self.post_logical_drive_payload = dict(
            Name="LVM Logical Drive created by CTS",
            Type=chosen_logical_drive_type,
            Mode=chosen_logical_drive_mode,
            Protected=False,
            CapacityGiB=self.discovery_container[chosen_logical_drive].body["CapacityGiB"],
            Image="CTS test image",
            Bootable=inherited_bootable if inherited_bootable else False,
            Snapshot=True,
            Links=dict(
                LogicalDrives=[{"@odata.id": chosen_logical_drive_group}],
                MasterDrive={"@odata.id": urlparse(chosen_logical_drive).path}
            )
        )

        # Creating the first RBD if no other was found
        if not chosen_logical_drive:
            if lvm_found:
                print "ERROR::Could not find a logical drive suitable for snapshot"
                return status
            cts_warning("Could not find any logical drive suitable for snapshot. Since CEPH was detected, CTS will "\
                        "try to create the first RBD")
            self.post_logical_drive_payload = dict(
                Name="CEPH Logical Drive created by CTS",
                Type="CEPH",
                Mode="RBD",
                Protected=False,
                CapacityGiB=self.discovery_container[chosen_logical_drive_group].body["CapacityGiB"]/2,
                Bootable=False,
                Snapshot=False,
                Links=dict(
                    LogicalDrives=[{"@odata.id": urlparse(chosen_logical_drive_group).path}],
                    MasterDrive=None
                )
            )

        print "MESSAGE::Logical drive CRUD test will be performed on logical drive collection %s, creating logical " \
              "drive based on %s on group %s" % (chosen_logical_drive_collection, chosen_logical_drive,
                                                 chosen_logical_drive_group)

        self.expected_created_logical_drive_body = deepcopy(self.post_logical_drive_payload)
        # The logical drive in LogicalDrives link is really the volume group and is going to be seen under
        # UsedBy on REST
        self.expected_created_logical_drive_body["Links"]["UsedBy"] = \
            self.expected_created_logical_drive_body["Links"]["LogicalDrives"]
        self.expected_created_logical_drive_body["Links"]["LogicalDrives"] = []

        status = self._test_case_create_logical_drive(chosen_logical_drive_collection)
        if status == ValidationStatus.PASSED: # only perform other tests if creation was successful
            ld = self.created_logical_drive
            status = ValidationStatus.join_statuses(status, self._test_case_get_created_logical_drive(ld))
            if create_logical_drive_for_target_crud:
                return status
            if status == ValidationStatus.PASSED:
                status = ValidationStatus.join_statuses(status, self._test_case_update_created_logical_drive())
            status = ValidationStatus.join_statuses(status, self._test_case_delete_created_logical_drive(ld))
            status = ValidationStatus.join_statuses(status, self._test_case_get_deleted_logical_drive(ld))

        return status
コード例 #34
0
    def _validate_from(self, resource, remained_to_be_visited, parent_location=None, parent_odata_id=None):
        """
        :type resource: ApiResourceProxy
        :rtype: str
        """
        res = ValidationStatus.PASSED

        if resource.odata_id in remained_to_be_visited:
            remained_to_be_visited.remove(resource.odata_id)

        location = resource.location

        if location and location.parent_id:
            if not parent_location:
                cts_error("Parent resource {parent_odata_id:id} has no location specified, " +
                          "but child resource {odata_id:id} has Location->ParentId={parent_id:ignore}",
                          parent_odata_id=parent_odata_id, odata_id=resource.odata_id, parent_id=location.parent_id)
                res = ValidationStatus.FAILED

        if parent_location:
            if location.parent_id != parent_location.id:
                cts_error("Parent resource {parent_odata_id:id} contains resource {odata_id:id}, " +
                          "but child resource has invalid Location->ParentId. " +
                          "Is: {id:ignore}. Expected: {expected:ignore}",
                          parent_odata_id=parent_odata_id,
                          odata_id=resource.odata_id,
                          id=location.parent_id,
                          expected=parent_location.id)
                res = ValidationStatus.FAILED
        if parent_odata_id and resource.contained_by:
            if parent_odata_id != resource.contained_by:
                cts_error("Resource {odata_id:id} has ContainedBy={contained_by:id}, " +
                          "but it's parent is {parent_odata_id:id}",
                          odata_id=resource.odata_id,
                          contained_by=resource.contained_by,
                          parent_odata_id=parent_odata_id)
                res = ValidationStatus.FAILED
        if res != ValidationStatus.FAILED and resource.contains:

            locations_within_scope = dict()

            for sub_resource_id in resource.contains:
                try:
                    sub_resource = self.discover_container.odataid_lookup(sub_resource_id)[0]
                    # validate that resources have unique location id within scope of their parent
                    if sub_resource.location.id in locations_within_scope:
                        fmt = ", ".join(['{locations[%d]:id}' % i for i, _
                                         in enumerate(locations_within_scope[sub_resource.location.id])])
                        cts_error("Resource {odata_id:id} has location id {location_id:ignore} " +
                                  "that conflicts with resources: %s" % fmt,
                                  odata_id=sub_resource.odata_id,
                                  location_id=sub_resource.location.id,
                                  locations=locations_within_scope[sub_resource.location.id])
                        res = ValidationStatus.FAILED
                    locations_within_scope.setdefault(sub_resource.location.id, []).append(sub_resource.odata_id)

                    res = ValidationStatus.join_statuses(res, self._validate_from(sub_resource, remained_to_be_visited,
                                                                                  location, resource.odata_id))
                except IndexError:
                    cts_error("Resource {odata_id:id} contains reference to nonexistent resource {subresource:id}",
                              odata_id=resource.odata_id, subresource=sub_resource_id)
                    res = ValidationStatus.FAILED

        return res
コード例 #35
0
ファイル: crud_operations.py プロジェクト: j143-zz/intelRSD
    def crud_logical_drive(self, called_from_crud_remote_target=None):
        """
        Test is trying to perform CRUD (create, read, update, delete) operations on a logical volume
        :type discovery_container: cts_core.discovery.discovery_container.DiscoveryContainer
        :type self.metadata_container: cts_core.metadata.self.metadata_container.MetadataContainer
        """

        status = ValidationStatus.BLOCKED

        lvm_found = False
        logical_volumes = dict()
        logical_volume_groups = dict()
        logical_drive_collections = dict()

        for resource_link, resource in self.discovery_container.iteritems():
            ok = True
            if self.metadata_container.entities[MetadataConstants.LOGICAL_DRIVE].compare_entities(resource.odata_type):
                print "DEBUG::found entity of type %s in %s" % (MetadataConstants.LOGICAL_DRIVE, resource_link)
                try:
                    if resource.body["Type"] == "LVM":
                        lvm_found = True
                        if resource.body["Mode"] == "LVG":
                            logical_volume_groups[resource_link] = resource
                        elif resource.body["Mode"] == "LV":
                            if "CapacityGiB" not in resource.body.keys():
                                print "DEBUG::%s drive does not have specified capacity" % resource_link
                                ok = False
                            if "Snapshot" in resource.body.keys() and resource.body["Snapshot"] == True:
                                print "DEBUG::%s cannot be used - drive is a snapshot volume" % resource_link
                                ok = False
                            if ok:
                                logical_volumes[resource_link] = resource
                    elif resource.body["Type"] == "CEPH":
                        if resource.body["Mode"] == "Pool":
                            logical_volume_groups[resource_link] = resource
                        elif resource.body["Mode"] == "RBD":
                            if "CapacityGiB" not in resource.body.keys():
                                print "DEBUG::%s drive does not have specified capacity" % resource_link
                                ok = False
                            if ok:
                                logical_volumes[resource_link] = resource
                except:
                    print "WARNING::Incorrect resource %s structure" % resource_link
            elif self.metadata_container.entities[MetadataConstants.LOGICAL_DRIVE_COLLECTION]\
                 .compare_entities(resource.odata_type):
                logical_drive_collections[resource_link] = resource

        if lvm_found and (not logical_volume_groups or not logical_volumes):
            print "ERROR::Insufficient resources available on API for test. Found %s logical volumes and %s logical " \
                  " volume groups" % (len(logical_volumes), len(logical_volume_groups))
            return ValidationStatus.BLOCKED

        # to speed things up, always look for the lowest capacity logical volume
        lowest_capacity = float('inf')
        chosen_logical_drive_collection, chosen_logical_volume, chosen_logical_volume_group = None, None, None
        inherited_bootable = None

        if not logical_volume_groups:
            if lvm_found:
                print "ERROR::No LVM volume group found, aborting"
            else:
                print "ERROR::No CEPH Pool device found, aborting"
            return ValidationStatus.BLOCKED

        for lvg_link, lvg in logical_volume_groups.iteritems():
            # finding a collection matching this volume group
            possible_collections = [collection for collection in logical_drive_collections.keys() if collection in lvg_link]
            if not possible_collections:
                continue
            try:
                for lv in lvg.body["Links"]["LogicalDrives"]: # iterating LVs that have this LVG as a parent
                    try:
                        lv_link = lv["@odata.id"]
                        lv_type = logical_volumes[lv_link].body["Type"]
                        lv_mode = logical_volumes[lv_link].body["Mode"]
                        lv_capacity = logical_volumes[lv_link].body["CapacityGiB"]
                        lv_bootable = logical_volumes[lv_link].body["Bootable"]
                        if lv_capacity < lowest_capacity:
                            lowest_capacity = lv_capacity
                            inherited_bootable = lv_bootable
                            chosen_logical_volume = lv_link
                            chosen_logical_volume_type = lv_type
                            chosen_logical_volume_mode = lv_mode
                            chosen_logical_volume_group = lvg_link
                            chosen_logical_drive_collection = possible_collections[0]
                    except KeyError:
                        pass
            except KeyError:
                pass

        self.post_logical_drive_payload = dict(
            Name="LVM Logical Drive created by CTS",
            Type=chosen_logical_volume_type,
            Mode=chosen_logical_volume_mode,
            Protected=False,
            CapacityGiB=self.discovery_container[chosen_logical_volume].body["CapacityGiB"],
            Bootable=inherited_bootable if inherited_bootable else False,
            Snapshot=True,
            Links=dict(
                LogicalDrives=[{"@odata.id": chosen_logical_volume_group}],
                MasterDrive={"@odata.id": chosen_logical_volume}
            )
        )

        # Creating the first RBD if no other was found
        if not chosen_logical_volume:
            if lvm_found:
                print "ERROR::Could not find a (logical volume, logical volume group) pair suitable for the test"
                return status
            else:
                self.post_logical_drive_payload = dict(
                    Name="CEPH Logical Drive created by CTS",
                    Type="CEPH",
                    Mode="RBD",
                    Protected=False,
                    CapacityGiB=self.discovery_container[chosen_logical_volume_group].body["CapacityGiB"]/2,
                    Bootable=False,
                    Snapshot=False,
                    Links=dict(
                        LogicalDrives=[{"@odata.id": chosen_logical_volume_group}],
                        MasterDrive=None
                    )
                )


        print "MESSAGE::Logical drive CRUD test will be performed on logical drive collection %s, creating logical volume " \
              "based on %s on group %s" % (chosen_logical_drive_collection, chosen_logical_volume, chosen_logical_volume_group)

        self.expected_created_logical_drive_body = deepcopy(self.post_logical_drive_payload)
        # The logical drive in LogicalDrives link is really the volume group and is going to be seen under
        # UsedBy on REST
        self.expected_created_logical_drive_body["Links"]["UsedBy"] = \
            self.expected_created_logical_drive_body["Links"]["LogicalDrives"]
        self.expected_created_logical_drive_body["Links"]["LogicalDrives"] = []

        status = self._test_case_create_logical_drive(chosen_logical_drive_collection)
        if status == ValidationStatus.PASSED: # only perform other tests if creation was successful
            status = ValidationStatus.join_statuses(status, self._test_case_get_created_logical_drive())
            if called_from_crud_remote_target:
                status = ValidationStatus.join_statuses(status,
                         self.crud_remote_target(called_from_crud_logical_drive=True))
            else:
                status = ValidationStatus.join_statuses(status, self._test_case_update_created_logical_drive())
            status = ValidationStatus.join_statuses(status, self._test_case_delete_created_logical_drive())
            status = ValidationStatus.join_statuses(status, self._test_case_get_deleted_logical_drive())

        return status
コード例 #36
0
    def _validate_property(self, context, variable_path, property_description,
                           skip_collection=False, ignore_list=[]):
        """
        :type context: Context
        :type variable_path: list [str or int]
        :type property_description: cts_core.metadata.model.property.Property
        :type skip_collection: bool
        :rtype: str
        """
        applicability = None
        if property_description.patch_status == PatchStatus.NONTRIVIAL:
            applicability, validation_result = self.handle_nontrivial(context, variable_path, property_description)
            if applicability == ApplicabilityTestResult.MATCHED:
                return validation_result
            if applicability in [ApplicabilityTestResult.NOT_MATCHED, ApplicabilityTestResult.SKIP_PROPERTY]:
                return validation_result

        api_resource = context.api_resource

        if not skip_collection:
            variable_path = variable_path + [property_description.name]

        try:
            property_body = api_resource.get_value_from_path(variable_path)
            if len(ignore_list) == 1 and ignore_list[0] in property_body:
                path_s = "->".join([str(segment) for segment in variable_path])
                cts_message("Patching %s->%s" % (api_resource.odata_id, path_s))
                cts_message("This property {ignore_element} is marked in IgnoredElement list as element to skip".format(
                    ignore_element=ignore_list[0]
                ))
        except KeyError as error:
            if property_description.is_required:
                path_s = "->".join([str(segment) for segment in variable_path])
                print "TEST_CASE::Patching %s->%s" % (api_resource.odata_id, path_s)
                cts_error("Unable to patch {error}", error=error)
                status = ValidationStatus.FAILED
                print "STATUS::%s" % status
            else:
                status = ValidationStatus.PASSED

            return status

        if property_description.is_collection and not skip_collection:
            status = ValidationStatus.PASSED

            for path_element, _ in enumerate(property_body):
                status = \
                    ValidationStatus.join_statuses(status,
                                                   self._validate_property(context,
                                                                           variable_path + [path_element],
                                                                           property_description,
                                                                           skip_collection=True,
                                                                           ignore_list=ignore_list))
            return status
        else:
            try:
                if self._metadata_container.types[property_description.type].type_category \
                        == MetadataTypeCategories.COMPLEX_TYPE:
                    return self._validate_property_list(context,
                                                        variable_path,
                                                        self._metadata_container.types[property_description.type].
                                                        properties.itervalues(),
                                                        ignore_list)
                else:
                    if str(property_description) in ignore_list:
                        return ValidationStatus.PASSED
                    return self._validate_leaf_property(context,
                                                        variable_path,
                                                        property_description)
            except KeyError as key:
                cts_error("Unable to find definition of type {type} referenced by {odata_id:id}",
                          type=key,
                          odata_id=api_resource.odata_id)
                return ValidationStatus.FAILED
コード例 #37
0
ファイル: crud_operations.py プロジェクト: j143-zz/intelRSD
    def crud_remote_target(self, called_from_crud_logical_drive=None):
        """
        Test is checking for rsa compute blade presence
        :type discovery_container: cts_core.discovery.discovery_container.DiscoveryContainer
        :type self.metadata_container: cts_core.metadata.self.metadata_container.MetadataContainer
        """
        target_iqn = "cts.target:cts_test_target"
        target_iqns = set()

        logical_volumes = dict()
        remote_target_collections = dict()

        for resource_link, resource in self.discovery_container.iteritems():
            if self.metadata_container.entities[MetadataConstants.LOGICAL_DRIVE].compare_entities(resource.odata_type):
                print "DEBUG::found entity of type %s in %s" % (MetadataConstants.LOGICAL_DRIVE, resource_link)
                try:
                    # looking for unprotected LVs with no targets associated with it
                    if ((resource.body["Mode"] == "LV" or resource.body["Mode"] == "RBD")
                        and not len(resource.body["Links"]["Targets"]) and not resource.body["Protected"]):
                        logical_volumes[resource_link] = resource
                except:
                    print "WARNING::Incorrect resource %s structure" % resource_link
            elif self.metadata_container.entities[MetadataConstants.REMOTE_TARGET_COLLECTION].compare_entities(resource.odata_type):
                remote_target_collections[resource_link] = resource
            elif self.metadata_container.entities[MetadataConstants.REMOTE_TARGET].compare_entities(
                    resource.odata_type):
                try:
                    for address in resource.body["Addresses"]:
                        target_iqns.add(address["iSCSI"]["TargetIQN"])
                except KeyError:
                    pass

        if target_iqn in target_iqns:
            iqn_number = 0
            while target_iqn + str(iqn_number) in target_iqns:
                iqn_number += 1
            target_iqn = target_iqn + str(iqn_number)

        if not logical_volumes:
            print "WARNING::Insufficient resources available on API for test. Could not find an unprotected logical volume with"\
                  " no targets attached"
            if called_from_crud_logical_drive:
                print "ERROR::Creating a new logical volume for the target failed, skipping remote target tests"
                return ValidationStatus.BLOCKED
            else:
                print "MESSAGE::Trying to create a new logical volume for the target, then proceeding with remote target CRUD test"
                return self.crud_logical_drive(called_from_crud_remote_target=True)

        chosen_logical_volume = logical_volumes.keys()[0]
        chosen_remote_target_collection = remote_target_collections.keys()[0]

        print "MESSAGE::Remote Target CRUD test will be performed on remote target collection %s, creating remote target " \
              "based on %s" % (chosen_remote_target_collection, chosen_logical_volume)

        self.post_remote_target_payload = dict(
            Addresses=[dict(
                iSCSI=dict(
                    TargetIQN=target_iqn,
                    TargetLUN=[dict(
                        LUN=1,
                        LogicalDrive={"@odata.id": chosen_logical_volume}
                    )],
                )
            )],
            Initiator=[dict(
                iSCSI=dict(
                    InitiatorIQN="cts.initiator:initiator_cts_test"
                )
            )]
        )

        status = self._test_case_create_remote_target(chosen_remote_target_collection)
        if status == ValidationStatus.PASSED: # only perform other tests if creation was successful
            status = ValidationStatus.join_statuses(status, self._test_case_get_created_remote_target())
            status = ValidationStatus.join_statuses(status, self._test_case_logical_volume_has_link_to_created_target(
                chosen_logical_volume))
            status = ValidationStatus.join_statuses(status, self._test_case_update_created_remote_target())
            status = ValidationStatus.join_statuses(status, self._test_case_delete_created_remote_target())
            status = ValidationStatus.join_statuses(status, self._test_case_get_deleted_remote_target())

        return status
コード例 #38
0
ファイル: hardware_check_list.py プロジェクト: 01org/intelRSD
 def set_validation_status(self, status):
     print "STATUS::%s" % status
     if hasattr(self, "validation_status"):
         self.validation_status = ValidationStatus.join_statuses(self.validation_status, status)
     else:
         self.validation_status = status
コード例 #39
0
    def crud_remote_target(self):
        """
        Test is checking for rsa compute blade presence
        """

        ld_created_for_crud = False
        target_iqn = "cts.target:cts_test_target"
        target_iqns = set()

        chosen_logical_drive, chosen_remote_target_collection = None, None

        if not self.discovery_container.count_resources(MetadataConstants.LOGICAL_DRIVE, any_child_version=True):
            cts_error("Insufficient resources for API test. No logical drives found.")
            return ValidationStatus.BLOCKED

        logical_drives = dict(self.discovery_container.get_resources(MetadataConstants.LOGICAL_DRIVE,
                                                                      any_child_version=True,
                                                                      constraints=[equal("Mode", "LV"),
                                                                                   equal("Protected", False)]))
        if not logical_drives:
            logical_drives = dict(self.discovery_container.get_resources(MetadataConstants.LOGICAL_DRIVE,
                                                                      any_child_version=True,
                                                                      constraints=[equal("Mode", "RBD"),
                                                                                   equal("Protected", False)]))
        try:
            chosen_remote_target_collection = self.discovery_container.get_resources(
                                              MetadataConstants.REMOTE_TARGET_COLLECTION,
                                              any_child_version=True)[0][0]
            chosen_logical_drive = [link for link, resource in logical_drives.iteritems() if not
                                     len(resource.body["Links"]["Targets"])][0]
        except (KeyError, IndexError):
            pass

        if not chosen_remote_target_collection:
            cts_error("Insufficient resources available on API for test. Could not find any remote target collection")
            return ValidationStatus.BLOCKED

        if not chosen_logical_drive:
            cts_warning("Insufficient resources available on API for test. Could not find an unprotected logical drive "
                        "with no targets attached")
            print "MESSAGE::Trying to create a new logical volume for the target, then proceeding with remote target "\
                  "CRUD test"
            if self.crud_logical_drive(create_logical_drive_for_target_crud=True) == ValidationStatus.PASSED:
                chosen_logical_drive = self.created_logical_drive
                ld_created_for_crud = True
            else:
                cts_error("Creating a new logical volume for the target failed, skipping remote target tests")
                return ValidationStatus.BLOCKED

        targets = [link for link, resource in
                   self.discovery_container.get_resources(MetadataConstants.REMOTE_TARGET,
                                                          any_child_version=True,
                                                          constraints=[
                                                              from_collection(chosen_remote_target_collection)
                                                          ])]
        for target in targets:
            addresses = self.discovery_container[target].body["Addresses"]
            for address in addresses:
                try:
                    target_iqns.add(address["iSCSI"]["TargetIQN"])
                except KeyError:
                    pass

        if target_iqn in target_iqns:
            iqn_number = 0
            while target_iqn + str(iqn_number) in target_iqns:
                iqn_number += 1
            target_iqn = target_iqn + str(iqn_number)

        print "MESSAGE::Remote Target CRUD test will be performed on remote target collection %s, creating remote "\
              "target based on %s with first lowest consecutive \'cts.target:cts_test_target<number>\' target IQN "\
              "available: %s" % (chosen_remote_target_collection, chosen_logical_drive, target_iqn)

        self.post_remote_target_payload = dict(
            Addresses=[dict(
                iSCSI=dict(
                    TargetIQN=target_iqn,
                    TargetLUN=[dict(
                        LUN=1,
                        LogicalDrive={"@odata.id": urlparse(chosen_logical_drive).path}
                    )],
                )
            )],
            Initiator=[dict(
                iSCSI=dict(
                    InitiatorIQN="cts.initiator:initiator_cts_test"
                )
            )]
        )

        status = self._test_case_create_remote_target(chosen_remote_target_collection)
        if status == ValidationStatus.PASSED: # only perform other tests if creation was successful
            status = ValidationStatus.join_statuses(status, self._test_case_get_created_remote_target())
            status = ValidationStatus.join_statuses(status, self._test_case_logical_drive_has_link_to_created_target(
                chosen_logical_drive))
            status = ValidationStatus.join_statuses(status, self._test_case_update_created_remote_target())
            status = ValidationStatus.join_statuses(status, self._test_case_delete_created_remote_target())
            status = ValidationStatus.join_statuses(status, self._test_case_get_deleted_remote_target())

        if ld_created_for_crud:
            ld = self.created_logical_drive
            del_status = self._test_case_delete_created_logical_drive(ld)
            del_status = ValidationStatus.join_statuses(del_status, self._test_case_get_deleted_logical_drive(ld))
            if status == ValidationStatus.PASSED and del_status != status:
                cts_error("Remote target CRUD test passed, but the logical drive it created failed to delete properly")
                status = ValidationStatus.PASSED_WITH_WARNINGS

        return status