Beispiel #1
0
    def post(self, request, sessions, *args, **kwargs):
        """Initialize the tests run data.

        Args:
            tests_tree (dict): contains the hierarchy of the tests in the run.
            run_data (dict): contains additional data about the run.
        """
        try:
            run_data = RunData.objects.create(**request.model.run_data)

        except TypeError:
            raise BadRequest("Invalid run data provided!")

        all_tests = {}
        tests_tree = request.model.tests
        try:
            main_test = self._create_test_data(tests_tree, run_data, all_tests)

        except KeyError:
            raise BadRequest("Invalid tests tree provided!")

        run_data.main_test = main_test
        run_data.user_name = request.get_host()
        run_data.save()

        session = sessions[request.model.token]
        session.all_tests = all_tests
        session.run_data = run_data
        session.main_test = main_test

        return Response({}, status=httplib.NO_CONTENT)
Beispiel #2
0
    def _get_available_resources(self, descriptor, username, groups):
        """Get the potential resources to be locked that fits the descriptor.

        Args:
            descriptor (ResourceDescriptor): a descriptor of the wanted
                resource.
            username (str): the user who wants to lock the resource.
            groups (list): list of the resource groups that the resource
                should be taken from.

        Raises:
            BadRequest. if the descriptor given is invalid or the are no
                resources to be locked.

        Returns:
            generator. generator of resources that can be locked and are
                available to the user who requested them.
        """
        # query for resources that are usable and match the user's
        # preference, which are either belong groups he's in or
        # don't belong to any group.
        query = (Q(is_usable=True, **descriptor.properties) &
                 (Q(group__isnull=True) | Q(group__in=groups)))
        try:
            matches = descriptor.type.objects.select_for_update() \
                .filter(query).order_by('-reserved')

        except FieldError as e:
            raise BadRequest(e.message)

        if matches.count() == 0:
            raise BadRequest(INVALID_RESOURCES.format(descriptor))

        return (resource for resource in matches
                if resource.is_available(username))
Beispiel #3
0
    def get(self, request, sessions, *args, **kwargs):
        """Initialize the tests run data."""
        parameters = {"test_name": request.model.test_name}
        if request.model.max_sample_size is not None:
            parameters["max_size"] = request.model.max_sample_size

        test_durations = collect_durations(**parameters)
        if len(test_durations) < 1:
            raise BadRequest("No test history found!")

        parameters = {"durations": test_durations}
        if request.model.min_duration_cut is not None:
            parameters["min_duration_cut"] = request.model.min_duration_cut
        if request.model.max_iterations is not None:
            parameters["max_iterations"] = request.model.max_iterations
        if request.model.acceptable_ratio is not None:
            parameters["acceptable_ratio"] = request.model.acceptable_ratio

        test_durations = clean_data(**parameters)
        if len(test_durations) < 1:
            raise BadRequest("Test history disparity too wide!")

        response = {
            "min": min(test_durations),
            "avg": sum(test_durations) / len(test_durations),
            "max": max(test_durations)
        }

        return Response(response, status=http_client.OK)
Beispiel #4
0
    def post(self, request, *args, **kwargs):
        """Find and return the resources that answer the client's query.

        Args:
            request (Request): QueryResources request.

        Returns:
            ResourcesReply. a reply containing matching resources.
        """
        try:
            descriptor = ResourceDescriptor.decode(request.model.obj)

        except ResourceTypeError as e:
            raise BadRequest(str(e))

        # query for resources that are usable and match the descriptors
        query = (Q(is_usable=True, **descriptor.properties))
        query_result = []
        with transaction.atomic():
            matches = descriptor.type.objects.select_for_update().filter(query)

            if matches.count() == 0:
                raise BadRequest("No existing resource meets "
                                 "the requirements: {!r}".format(descriptor))

            encoder = JSONParser()
            query_result = [
                encoder.recursive_encode(resource) for resource in matches
            ]

        return Response({"resource_descriptors": query_result},
                        status=http_client.OK)
Beispiel #5
0
    def get(self, request, sessions, *args, **kwargs):
        """Check if the test passed in the last run according to results DB.

        Args:
            test_id (number): the identifier of the test.
            token (str): token of the session.
        """
        session_token = request.model.token
        try:
            session_data = sessions[session_token]
            test_data = session_data.all_tests[request.model.test_id]

        except KeyError:
            raise BadRequest("Invalid token/test_id provided!")

        run_data = session_data.run_data

        test_should_skip = test_data.should_skip(test_name=test_data.name,
                                                 run_data=run_data,
                                                 exclude_pk=test_data.pk)
        reason = SKIP_DELTA_MESSAGE if test_should_skip else ""

        return Response({
            "should_skip": test_should_skip,
            "reason": reason
        }, status=httplib.OK)
Beispiel #6
0
    def post(self, request, sessions, *args, **kwargs):
        """Update the resources list for a test data.

        Args:
            test_id (number): the identifier of the test.
            descriptors (list): the resources the test used.
        """
        session_token = request.model.test_details.token
        try:
            session_data = sessions[session_token]
            test_data = \
                session_data.all_tests[request.model.test_details.test_id]

        except KeyError:
            raise BadRequest("Invalid token/test_id provided "
                             "(Test timed out?)")

        test_data.resources.clear()

        for resource_descriptor in request.model.descriptors:
            resource_dict = ResourceDescriptor.decode(resource_descriptor)
            test_data.resources.add(resource_dict.type.objects.get(
                **resource_dict.properties))

        test_data.save()

        return Response({}, status=http_client.NO_CONTENT)
Beispiel #7
0
    def post(self, request, sessions, *args, **kwargs):
        """Lock the given resources one by one.

        Note:
            If one of the resources fails to lock, all the resources that has
            been locked until that resource will be released.
        """
        username = get_username(request)
        session = sessions[request.model.token]
        descriptors = request.model.descriptors

        if not auth_models.User.objects.filter(username=username).exists():
            raise BadRequest(USER_NOT_EXIST.format(username))

        locked_resources = []
        user = auth_models.User.objects.get(username=username)
        groups = list(user.groups.all())
        with transaction.atomic():
            for descriptor_dict in descriptors:
                locked_resources.append(
                    self._try_to_lock_available_resource(
                        username, groups, descriptor_dict))

        for resource in locked_resources:
            session.resources.append(resource)

        encoder = JSONParser()
        response = [
            encoder.encode(_resource) for _resource in locked_resources
        ]
        return Response({"resource_descriptors": response}, status=httplib.OK)
Beispiel #8
0
    def _create_test_data(self, test_dict, run_data, all_tests):
        """Recursively create the test's datas and add them to 'all_tests'.

        Args:
            tests_tree (dict): contains the hierarchy of the tests in the run.

        Returns:
            GeneralData. the created test data object.
        """
        parser = JSONParser()
        data_type = parser.decode(test_dict[TEST_CLASS_CODE_KEY])
        try:
            test_data = data_type(name=test_dict[TEST_NAME_KEY])

        except TypeError:
            raise BadRequest("Invalid type provided: {}".format(data_type))

        test_data.run_data = run_data
        test_data.save()
        all_tests[test_dict[TEST_ID_KEY]] = test_data

        if TEST_SUBTESTS_KEY in test_dict:
            for sub_test_dict in test_dict[TEST_SUBTESTS_KEY]:
                sub_test = self._create_test_data(sub_test_dict,
                                                  run_data,
                                                  all_tests)
                test_data.add_sub_test_data(sub_test)
                sub_test.save()

        return test_data
Beispiel #9
0
    def post(self, request, sessions, *args, **kwargs):
        """Initialize the tests run data."""
        session_token = request.model.token
        try:
            session_data = sessions[session_token]

        except KeyError:
            raise BadRequest("Invalid token provided!")

        run_data = session_data.run_data
        RunData.objects.filter(pk=run_data.pk).update(**request.model.run_data)

        return Response({}, status=http_client.NO_CONTENT)
Beispiel #10
0
    def _try_to_lock_available_resource(self, username, groups,
                                        descriptor_dict):
        """Try to lock one of the given available resources.

        Args:
            descriptor_dict (dict): a descriptor dict of the wanted resource.
                Example:
                    {
                        "type": "resourceData",
                        "properties": {}
                    }
            username (str): the user who wants to lock the resource.
            groups (list): list of the resource groups that the resource
                should be taken from.

        Returns:
            ResourceData. the locked resource.

        Raises:
            BadRequest. If there are no available resources.
        """
        try:
            descriptor = ResourceDescriptor.decode(descriptor_dict)

        except ResourceTypeError as e:
            raise BadRequest(e.message)

        availables = self._get_available_resources(descriptor, username,
                                                   groups)

        try:
            resource = availables.next()
            self._lock_resource(resource, username)
            return resource

        except StopIteration:
            raise BadRequest(UNAVAILABLE_RESOURCES.format(descriptor))
Beispiel #11
0
    def post(self, request, sessions, *args, **kwargs):
        """Update the test data to 'in progress' state and set the start time.

        Args:
            test_id (number): the identifier of the test.
        """
        session_token = request.model.token
        try:
            session_data = sessions[session_token]
            test_data = session_data.all_tests[request.model.test_id]

        except KeyError:
            raise BadRequest("Invalid token/test_id provided!")

        test_data.start()
        test_data.save()

        return Response({}, status=httplib.NO_CONTENT)
Beispiel #12
0
    def post(self, request, sessions, *args, **kwargs):
        """End a test run.

        Args:
            request (Request): StopTest request.
        """
        session_token = request.model.token
        try:
            session_data = sessions[session_token]
            test_data = session_data.all_tests[request.model.test_id]

        except KeyError:
            raise BadRequest("Invalid token/test_id provided!")

        test_data.end()
        test_data.save()

        return Response({}, status=httplib.NO_CONTENT)
Beispiel #13
0
    def post(self, request, sessions, *args, **kwargs):
        """Save the composite test's data.

        Args:
            test_id (number): the identifier of the test.
        """
        session_token = request.model.token
        try:
            session_data = sessions[session_token]
            test_data = session_data.all_tests[request.model.test_id]

        except KeyError:
            raise BadRequest("Invalid token/test_id provided!")

        has_succeeded = all(sub_test.success for sub_test in test_data)
        test_data.success = has_succeeded
        test_data.end()
        test_data.save()

        return Response({}, status=httplib.NO_CONTENT)
Beispiel #14
0
    def post(self, request, sessions, *args, **kwargs):
        """Release the given resources one by one."""
        try:
            session = sessions[request.model.token]

        except KeyError:
            raise BadRequest("Invalid token provided!")

        errors = {}
        username = get_username(request)

        with transaction.atomic():
            for name in request.model.resources:
                try:
                    resource_data = ResourceData.objects.select_for_update() \
                        .get(name=name)

                except ObjectDoesNotExist:
                    errors[name] = (ResourceDoesNotExistError.ERROR_CODE,
                                    "Resource %r doesn't exist" % name)
                    continue

                resource = get_sub_model(resource_data)

                try:
                    self.release_resource(resource, username)
                    session.resources.remove(resource)

                except ServerError as ex:
                    errors[name] = (ex.ERROR_CODE, ex.get_error_content())

        if len(errors) > 0:
            return Response(
                {
                    "errors": errors,
                    "details": "errors occurred while releasing resource"
                },
                status=http_client.BAD_REQUEST)

        return Response({}, status=http_client.NO_CONTENT)
Beispiel #15
0
    def post(self, request, sessions, *args, **kwargs):
        """Add a result to the test.

        Args:
            test_id (number): the identifier of the test.
            result_code (number): code of the result as defined in TestOutcome.
            info (str): additional info (traceback / end reason etc).
        """
        session_token = request.model.test_details.token
        try:
            session_data = sessions[session_token]
            test_data = \
                session_data.all_tests[request.model.test_details.test_id]

        except KeyError:
            raise BadRequest("Invalid token/test_id provided!")

        test_data.update_result(request.model.result.result_code,
                                request.model.result.info)
        test_data.save()

        return Response({}, status=httplib.NO_CONTENT)