예제 #1
0
    def _suites_for_investigation(self,
                                  suite=None,
                                  configurations=None,
                                  recent=None,
                                  branch=None,
                                  begin=None,
                                  end=None,
                                  begin_query_time=None,
                                  end_query_time=None,
                                  unexpected=None,
                                  limit=None,
                                  **kwargs):
        AssertRequest.is_type(['GET'])
        AssertRequest.query_kwargs_empty(**kwargs)

        with self.upload_controller.upload_context:
            suites_by_configuration = self.upload_controller.upload_context.find_suites(
                configurations=configurations,
                recent=boolean_query(*recent)[0] if recent else True)
            candidate_suites = set()
            for suites_for_config in suites_by_configuration.values():
                for s in suites_for_config:
                    candidate_suites.add(s)
            return sorted(
                [s for s in candidate_suites if not suite or s in suite])
예제 #2
0
    def _find_uploads_for_query(self, configurations=None, suite=None, branch=None, begin=None, end=None, recent=None, limit=None, **kwargs):
        AssertRequest.query_kwargs_empty(**kwargs)
        recent = boolean_query(*recent)[0] if recent else True

        with self.upload_context:
            if not suite:
                suites = set()
                for config_suites in self.upload_context.find_suites(configurations=configurations, recent=recent).values():
                    [suites.add(suite) for suite in config_suites]
            else:
                suites = set(suite)

            current_uploads = 0
            result = defaultdict(dict)
            for suite in suites:
                if current_uploads >= limit:
                    break
                results_dict = self.upload_context.find_test_results(
                    configurations=configurations, suite=suite, branch=branch[0],
                    begin=begin, end=end, recent=recent, limit=(limit - current_uploads),
                )
                for config, results in results_dict.items():
                    current_uploads += len(results)
                    result[config][suite] = results
            return result
예제 #3
0
    def _suites_for_search(self,
                           suite=None,
                           configurations=None,
                           recent=None,
                           branch=None,
                           begin=None,
                           end=None,
                           begin_query_time=None,
                           end_query_time=None,
                           test=None,
                           limit=None,
                           **kwargs):
        AssertRequest.is_type(['GET'])
        AssertRequest.query_kwargs_empty(**kwargs)

        if test and (not suite or len(suite) != len(test)):
            abort(400, description='Each test must be paired with a suite')

        with self.upload_controller.upload_context:
            suites_by_configuration = self.upload_controller.upload_context.find_suites(
                configurations=configurations,
                recent=boolean_query(*recent)[0] if recent else True)
            candidate_suites = set()
            for suites_for_config in suites_by_configuration.values():
                for s in suites_for_config:
                    candidate_suites.add(s)
            return sorted([
                s for s in candidate_suites if test or not suite or s in suite
            ])
예제 #4
0
    def suites(self,
               configurations=None,
               recent=None,
               suite=None,
               branch=None,
               **kwargs):
        AssertRequest.is_type(['GET'])
        AssertRequest.query_kwargs_empty(**kwargs)

        with self.upload_context:
            suites_by_config = self.upload_context.find_suites(
                configurations=configurations,
                recent=boolean_query(*recent)[0] if recent else True,
                branch=branch[0] if branch else None,
            )
            result = []
            for config, candidate_suites in suites_by_config.items():
                suites_for_config = [
                    s for s in candidate_suites if not suite or s in suite
                ]
                if suites_for_config:
                    result.append([config, suites_for_config])
            if not result:
                abort(404,
                      description='No suites matching the specified criteria')
            return jsonify(Configuration.Encoder().default(result))
예제 #5
0
    def find_run_results(self,
                         suite=None,
                         configurations=None,
                         recent=None,
                         branch=None,
                         begin=None,
                         end=None,
                         begin_query_time=None,
                         end_query_time=None,
                         limit=None,
                         **kwargs):
        AssertRequest.is_type(['GET'])
        AssertRequest.query_kwargs_empty(**kwargs)

        recent = boolean_query(*recent)[0] if recent else True

        with self.suite_context:
            if not suite:
                abort(400, description='No suite specified')

            query_dict = dict(
                suite=suite,
                configurations=configurations,
                recent=recent,
                branch=branch[0],
                begin=begin,
                end=end,
                begin_query_time=begin_query_time,
                end_query_time=end_query_time,
                limit=limit,
            )
            specified_commits = sum(
                [1 if element else 0 for element in [begin, end]])
            specified_timestamps = sum([
                1 if element else 0
                for element in [begin_query_time, end_query_time]
            ])

            if specified_commits >= specified_timestamps:
                find_function = self.suite_context.find_by_commit

                def sort_function(result):
                    return result['uuid']

            else:
                find_function = self.suite_context.find_by_start_time

                def sort_function(result):
                    return result['start_time']

            response = []
            for config, results in find_function(**query_dict).items():
                response.append(
                    dict(
                        configuration=Configuration.Encoder().default(config),
                        results=sorted(results, key=sort_function),
                    ))
            return jsonify(response)
예제 #6
0
    def test_boolean_query(self):
        self.assertTrue(all(boolean_query('True', 'true')))
        self.assertTrue(all(boolean_query('Yes', 'yes')))
        self.assertTrue(all(boolean_query('1', '100')))

        self.assertFalse(any(boolean_query('False', 'false')))
        self.assertFalse(any(boolean_query('No', 'no')))
        self.assertFalse(any(boolean_query('0', 'any string')))
예제 #7
0
        def real_method(self=None,
                        platform=None,
                        version=None,
                        sdk=None,
                        version_name=None,
                        is_simulator=None,
                        architecture=None,
                        model=None,
                        style=None,
                        flavor=None,
                        **kwargs):
            args = dict(
                platform=platform or [],
                version=version or [],
                sdk=sdk or [],
                version_name=version_name or [],
                is_simulator=boolean_query(*(is_simulator or [])),
                architecture=architecture or [],
                model=model or [],
                style=style or [],
                flavor=flavor or [],
            )

            def recursive_callback(keys, **kwargs):
                if not keys:
                    return {Configuration(**kwargs)}

                if not args[keys[-1]]:
                    return recursive_callback(keys[:-1], **kwargs)
                result = set()
                for element in args[keys[-1]]:
                    forwarded_args = {
                        key: value
                        for key, value in kwargs.items()
                    }
                    forwarded_args[keys[-1]] = element
                    result = result.union(
                        recursive_callback(keys[:-1], **forwarded_args))
                return result

            if self is None:
                return method(
                    configurations=list(recursive_callback(list(args.keys())))
                    or [Configuration()],
                    **kwargs)
            return method(
                self,
                configurations=list(recursive_callback(list(args.keys())))
                or [Configuration()],
                **kwargs)
예제 #8
0
    def urls_for_queue(self,
                       suite=None,
                       branch=None,
                       configurations=None,
                       recent=None,
                       limit=None,
                       **kwargs):
        AssertRequest.is_type(['GET'])
        AssertRequest.query_kwargs_empty(**kwargs)

        is_recent = True
        if recent:
            is_recent = boolean_query(*recent)[0]

        with self.ci_context, self.upload_context:
            suites = self._suites_for_query_arguments(
                suite=suite,
                configurations=configurations,
                is_recent=is_recent)
            if not branch:
                branch = [None]

            results = []
            for suite in suites:
                for config, url in self.ci_context.find_urls_by_queue(
                        configurations=configurations,
                        recent=is_recent,
                        branch=branch[0],
                        suite=suite,
                        limit=limit,
                ).items():
                    configuration_dict = Configuration.Encoder().default(
                        config)
                    configuration_dict['suite'] = suite
                    results.append(
                        dict(configuration=configuration_dict, url=url))

            return results
예제 #9
0
    def download(
        self, suite=None, configurations=None, recent=None,
        branch=None, begin=None, end=None,
        begin_query_time=None, end_query_time=None, **kwargs
    ):
        AssertRequest.is_type(['GET'])
        AssertRequest.query_kwargs_empty(**kwargs)
        recent = boolean_query(*recent)[0] if recent else True

        if not suite:
            suites = set()
            for config_suites in self.upload_context.find_suites(configurations=configurations, recent=recent).values():
                [suites.add(suite) for suite in config_suites]
        else:
            suites = set(suite)

        result = None
        filename = None
        digest = None
        with self.archive_context, self.upload_context:
            for suite in suites:
                for configuration, archives in self.archive_context.find_archive(
                    configurations=configurations, suite=suite, branch=branch[0],
                    begin=begin, end=end, recent=recent, limit=2,
                    begin_query_time=begin_query_time, end_query_time=end_query_time,
                ).items():
                    for archive in archives:
                        if archive.get('archive') and archive.get('digest'):
                            if digest and digest != archive.get('digest'):
                                abort(400, description='Multiple archives matching the specified criteria')
                            result = archive.get('archive')
                            filename = f'{configuration}@{archive["uuid"]}'.replace(' ', '_').replace('.', '-')
                            digest = archive.get('digest')

        if not result:
            abort(404, description='No archives matching the specified criteria')
        return send_file(result, attachment_filename=f'{filename}.zip', as_attachment=True)
예제 #10
0
    def failures(self,
                 suite=None,
                 configurations=None,
                 recent=None,
                 branch=None,
                 begin=None,
                 end=None,
                 begin_query_time=None,
                 end_query_time=None,
                 unexpected=None,
                 collapsed=None,
                 limit=None,
                 **kwargs):
        AssertRequest.is_type(['GET'])
        AssertRequest.query_kwargs_empty(**kwargs)

        recent = boolean_query(*recent)[0] if recent else True
        unexpected = boolean_query(*unexpected)[0] if unexpected else True
        collapsed = boolean_query(*collapsed)[0] if collapsed else True

        if not suite:
            abort(400, description='No suite specified')

        with self.failure_context:
            query_dict = dict(
                suite=suite,
                configurations=configurations,
                recent=recent,
                branch=branch[0],
                begin=begin,
                end=end,
                begin_query_time=begin_query_time,
                end_query_time=end_query_time,
                limit=limit,
                unexpected=unexpected,
                collapsed=collapsed,
            )
            num_specified_commits = sum(
                [1 if element else 0 for element in [begin, end]])
            num_specified_timestamps = sum([
                1 if element else 0
                for element in [begin_query_time, end_query_time]
            ])

            if num_specified_commits >= num_specified_timestamps:
                find_function = self.failure_context.failures_by_commit

                def sort_function(result):
                    return result['uuid']

            else:
                find_function = self.failure_context.failures_by_start_time

                def sort_function(result):
                    return result['start_time']

            failures = find_function(**query_dict)
            if failures is None:
                abort(
                    404,
                    description='No test runs found with the specified criteria'
                )

            if collapsed:
                return jsonify(sorted(set(failures)))

            response = []
            for config, results in failures.items():
                response.append(
                    dict(
                        configuration=Configuration.Encoder().default(config),
                        results=sorted(results, key=sort_function),
                    ))
            return jsonify(response)
예제 #11
0
    def extract(
        self, path=None, format=None,
        suite=None, configurations=None, recent=None,
        branch=None, begin=None, end=None,
        begin_query_time=None, end_query_time=None,
        limit=None, **kwargs
    ):
        AssertRequest.is_type(['GET'])
        AssertRequest.query_kwargs_empty(**kwargs)
        recent = boolean_query(*recent)[0] if recent else True

        if not suite:
            suites = set()
            for config_suites in self.upload_context.find_suites(configurations=configurations, recent=recent).values():
                [suites.add(suite) for suite in config_suites]
        else:
            suites = set(suite)

        result = None
        with self.archive_context, self.upload_context:
            for suite in suites:
                for files in self.archive_context.file(
                    path=path,
                    configurations=configurations, suite=suite, branch=branch[0],
                    begin=begin, end=end, recent=recent, limit=2,
                    begin_query_time=begin_query_time, end_query_time=end_query_time,
                ).values():
                    for file in files:
                        candidate = file.get('file')
                        if not candidate:
                            continue
                        if not result:
                            if isinstance(candidate, list):
                                result = set(candidate)
                            else:
                                result = candidate
                            continue
                        if isinstance(candidate, list) and isinstance(result, set):
                            result |= set(candidate)
                            continue
                        if result == candidate:
                            continue
                        abort(403, 'Multiple archives match with different content')

        if not result:
            abort(404, f"No archive content{' at ' + path if path else ''}")

        if isinstance(result, set):
            return self.list(path=path, values=sorted(result))

        mimetype = self.FORMAT.get(format)
        if not mimetype and '.' in path:
            mimetype = self.FORMAT.get(path.split('.')[-1])
        mimetype = mimetype or 'text/plain'

        # A bit of a hack to add the right query arguments into results.html
        # Ideally, this should be done with changes to results.html, but we
        # have legacy results to handle.
        if mimetype == 'text/html':
            query = query_as_string()
            result = result.replace(
                "href=\"' + testPrefix + suffix + '\"".encode('utf-8'),
                f"href=\"' + testPrefix + suffix + '{query}' + '\"".encode('utf-8'),
            )

            for include_to_strip in ['js/status-bubble.js', 'code-review.js?version=48']:
                result = result.replace(f'<script src="{include_to_strip}"></script>'.encode('utf-8'), ''.encode('utf-8'))

            if (query):
                result = result.replace("src += '?format=txt'".encode('utf-8'), "src += '&format=txt'".encode('utf-8'))

        return Response(result, mimetype=mimetype or 'text/plain')
예제 #12
0
    def urls_for_builds(self,
                        suite=None,
                        configurations=None,
                        recent=None,
                        branch=None,
                        begin=None,
                        end=None,
                        begin_query_time=None,
                        end_query_time=None,
                        limit=None,
                        **kwargs):
        AssertRequest.is_type(['GET'])
        AssertRequest.query_kwargs_empty(**kwargs)

        is_recent = True
        if recent:
            is_recent = boolean_query(*recent)[0]

        with self.ci_context, self.upload_context:
            suites = self._suites_for_query_arguments(
                suite=suite,
                configurations=configurations,
                is_recent=is_recent)
            if not branch:
                branch = [None]

            query_dict = dict(
                configurations=configurations,
                recent=is_recent,
                branch=branch[0],
                begin=begin,
                end=end,
                begin_query_time=begin_query_time,
                end_query_time=end_query_time,
                limit=limit,
            )
            num_uuid_query_args = sum(
                [1 if element else 0 for element in [begin, end]])
            num_timestamp_query_args = sum([
                1 if element else 0
                for element in [begin_query_time, end_query_time]
            ])

            if num_uuid_query_args >= num_timestamp_query_args:
                find_function = self.ci_context.find_urls_by_commit

                def sort_function(result):
                    return result['uuid']
            else:
                find_function = self.ci_context.find_urls_by_start_time

                def sort_function(result):
                    return result['start_time']

            results = []
            for suite in suites:
                for config, urls in find_function(suite=suite,
                                                  **query_dict).items():
                    configuration_dict = Configuration.Encoder().default(
                        config)
                    configuration_dict['suite'] = suite
                    results.append(
                        dict(configuration=configuration_dict,
                             urls=sorted(urls, key=sort_function)))

            return results