Esempio n. 1
0
    def find_test_results(self,
                          configurations,
                          suite,
                          branch=None,
                          begin=None,
                          end=None,
                          recent=True,
                          limit=100):
        if not isinstance(suite, str):
            raise TypeError(f'Expected type {str}, got {type(suite)}')

        with self:
            result = {}
            for configuration in configurations:
                result.update({
                    config: [value.unpack() for value in values]
                    for config, values in self.configuration_context.
                    select_from_table_with_configurations(
                        self.UploadsByConfiguration.__table_name__,
                        configurations=[configuration],
                        recent=recent,
                        suite=suite,
                        sdk=configuration.sdk,
                        branch=branch
                        or self.commit_context.DEFAULT_BRANCH_KEY,
                        uuid__gte=CommitContext.convert_to_uuid(begin),
                        uuid__lte=CommitContext.convert_to_uuid(
                            end, CommitContext.timestamp_to_uuid()),
                        limit=limit,
                    ).items()
                })
            return result
Esempio n. 2
0
    def _find_results(
            self, table, configurations, suite, recent=True,
            branch=None, begin=None, end=None,
            begin_query_time=None, end_query_time=None,
            limit=DEFAULT_LIMIT,
    ):
        if not isinstance(suite, str):
            raise TypeError(f'Expected type {str}, got {type(suite)}')

        def get_time(time):
            if isinstance(time, datetime):
                return time
            elif time:
                return datetime.utcfromtimestamp(int(time))
            return None

        with self:
            result = {}
            for configuration in configurations:
                result.update({config: [value.unpack() for value in values] for config, values in self.configuration_context.select_from_table_with_configurations(
                    table.__table_name__, configurations=[configuration], recent=recent,
                    suite=suite, sdk=configuration.sdk, branch=branch or self.commit_context.DEFAULT_BRANCH_KEY,
                    uuid__gte=CommitContext.convert_to_uuid(begin),
                    uuid__lte=CommitContext.convert_to_uuid(end, CommitContext.timestamp_to_uuid()),
                    start_time__gte=get_time(begin_query_time), start_time__lte=get_time(end_query_time),
                    limit=limit,
                ).items()})
            return result
Esempio n. 3
0
    def __init__(self, redis, cassandra, repositories=[], default_ttl_seconds=TTL_YEAR * 5, archive_ttl_seconds=TTL_WEEK * 8, async_processing=False, s3_credentials=None):
        if default_ttl_seconds is not None and default_ttl_seconds < 4 * self.TTL_WEEK:
            raise ValueError('TTL must be at least 4 weeks')
        if archive_ttl_seconds is not None and archive_ttl_seconds < 2 * self.TTL_WEEK:
            raise ValueError('Archive TTL must be at least 2 weeks')
        self.default_ttl_seconds = default_ttl_seconds
        self.archive_ttl_seconds = archive_ttl_seconds or default_ttl_seconds
        self._async_processing = async_processing

        self.redis = redis
        self.cassandra = cassandra

        with self.cassandra:
            self.cassandra.create_table(self.HealthTable)

        self.commit_context = CommitContext(redis, cassandra)
        for repository in repositories:
            self.commit_context.register_repository(repository)
        self.configuration_context = ConfigurationContext(redis, cassandra)
        self.upload_context = UploadContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
            async_processing=async_processing,
        )

        self.suite_context = SuiteContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )
        self.test_context = TestContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )
        self.failure_context = FailureContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )
        self.ci_context = CIContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )

        for context in [self.ci_context, self.failure_context, self.suite_context, self.test_context]:
            self.upload_context.register_upload_callback(context.name, context.register)

        self.archive_context = ArchiveContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.archive_ttl_seconds,
            s3_credentials=s3_credentials,
        )
Esempio n. 4
0
    def find_archive(
            self, configurations=None, suite=None, recent=True,
            branch=None, begin=None, end=None,
            begin_query_time=None, end_query_time=None,
            limit=DEFAULT_LIMIT,
    ):
        if not configurations:
            configurations = []
        if not isinstance(suite, str):
            raise TypeError(f'Expected type {str}, got {type(suite)}')

        with self:
            metadata_by_config = {}
            for configuration in configurations:
                metadata_by_config.update({config: [value.unpack() for value in values] for config, values in self.configuration_context.select_from_table_with_configurations(
                    self.ArchiveMetaDataByCommit.__table_name__, configurations=[configuration], recent=recent,
                    suite=suite, sdk=configuration.sdk, branch=branch or self.commit_context.DEFAULT_BRANCH_KEY,
                    uuid__gte=CommitContext.convert_to_uuid(begin),
                    uuid__lte=CommitContext.convert_to_uuid(end, CommitContext.timestamp_to_uuid()),
                    start_time__gte=_get_time(begin_query_time), start_time__lte=_get_time(end_query_time),
                    limit=limit,
                ).items()})

            memory_used = 0
            for values in metadata_by_config.values():
                for value in values:
                    if not value.get('digest'):
                        continue

                    memory_used += value.get('size', 0)
                    if memory_used > self.MEMORY_LIMIT:
                        raise RuntimeError('Hit soft-memory cap when fetching archives, aborting')

            archive_by_digest = {}
            result = {}
            for config, values in metadata_by_config.items():
                for value in values:
                    if not value.get('digest'):
                        continue

                    if not archive_by_digest.get(value.get('digest')):
                        archive = self.archiver.retrieve(value.get('digest'), value.get('size', None))
                        if not archive:
                            continue
                        archive_by_digest[value.get('digest')] = archive

                    archive_by_digest.get(value.get('digest')).seek(0)
                    result.setdefault(config, [])
                    result[config].append(dict(
                        archive=archive_by_digest.get(value.get('digest')),
                        digest=value.get('digest'),
                        uuid=value['uuid'],
                        start_time=value['start_time'],
                    ))

            return result
Esempio n. 5
0
    def init_database(self, redis=StrictRedis, cassandra=CassandraContext):
        redis_instance = redis()

        self.stash_repository = MockStashRepository.safari(redis_instance)
        self.svn_repository = MockSVNRepository.webkit(redis_instance)

        cassandra.drop_keyspace(keyspace=self.KEYSPACE)
        self.database = CommitContext(
            redis=redis_instance,
            cassandra=cassandra(keyspace=self.KEYSPACE, create_keyspace=True),
        )
        self.database.register_repository(self.stash_repository)
        self.database.register_repository(self.svn_repository)
Esempio n. 6
0
    def __init__(self,
                 redis,
                 cassandra,
                 repositories=[],
                 default_ttl_seconds=TTL_YEAR * 5,
                 async_processing=False):
        if default_ttl_seconds is not None and default_ttl_seconds < 4 * self.TTL_WEEK:
            raise ValueError('TTL must be at least 4 weeks')
        self.default_ttl_seconds = default_ttl_seconds
        self._async_processing = async_processing

        self.redis = redis
        self.cassandra = cassandra
        self.commit_context = CommitContext(redis, cassandra)
        for repository in repositories:
            self.commit_context.register_repository(repository)
        self.configuration_context = ConfigurationContext(redis, cassandra)
        self.upload_context = UploadContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
            async_processing=async_processing,
        )

        self.suite_context = SuiteContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )
        self.test_context = TestContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )
        self.ci_context = CIContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )

        for context in [
                self.suite_context, self.test_context, self.ci_context
        ]:
            self.upload_context.register_upload_callback(
                context.name, context.register)

        self.archive_context = ArchiveContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )
Esempio n. 7
0
    def init_database(self, redis=StrictRedis, cassandra=CassandraContext):
        redis_instance = redis()

        self.stash_repository = StashRepository(
            'https://bitbucket.example.com/projects/SAFARI/repos/safari')
        self.svn_repository = WebKitRepository()

        cassandra.drop_keyspace(keyspace=self.KEYSPACE)
        self.database = CommitContext(
            redis=redis_instance,
            cassandra=cassandra(keyspace=self.KEYSPACE, create_keyspace=True),
        )
        self.database.register_repository(self.stash_repository)
        self.database.register_repository(self.svn_repository)
Esempio n. 8
0
 def test_uuid_for_commits(self,
                           redis=StrictRedis,
                           cassandra=CassandraContext):
     with MockModelFactory.safari(), MockModelFactory.webkit():
         self.init_database(redis=redis, cassandra=cassandra)
         uuid = CommitContext.uuid_for_commits([
             self.stash_repository.commit(ref='bae5d1e90999'),
             self.svn_repository.commit(ref=6),
         ])
         self.assertEqual(uuid, 160166800000)
Esempio n. 9
0
    def find_test_results(self,
                          configurations,
                          suite,
                          branch=None,
                          begin=None,
                          end=None,
                          recent=True,
                          limit=100):
        if not isinstance(suite, str):
            raise TypeError(f'Expected type {str}, got {type(suite)}')

        with self:
            result = {}
            for configuration in configurations:
                # FIXME: Remove the UploadsByConfigurationLegacy once results in it are sufficently old in Spring 2021
                # We don't need to ignore duplicates because we never reported to both databases
                result.update({
                    config: [value.unpack() for value in values]
                    for config, values in self.configuration_context.
                    select_from_table_with_configurations(
                        self.UploadsByConfigurationLegacy.__table_name__,
                        configurations=[configuration],
                        recent=recent,
                        suite=suite,
                        sdk=configuration.sdk,
                        branch=branch
                        or self.commit_context.DEFAULT_BRANCH_KEY,
                        uuid__gte=CommitContext.convert_to_uuid(begin),
                        uuid__lte=CommitContext.convert_to_uuid(
                            end, CommitContext.timestamp_to_uuid()),
                        limit=limit,
                    ).items()
                })

                result.update({
                    config: [value.unpack() for value in values]
                    for config, values in self.configuration_context.
                    select_from_table_with_configurations(
                        self.UploadsByConfiguration.__table_name__,
                        configurations=[configuration],
                        recent=recent,
                        suite=suite,
                        sdk=configuration.sdk,
                        branch=branch
                        or self.commit_context.DEFAULT_BRANCH_KEY,
                        uuid__gte=CommitContext.convert_to_uuid(begin),
                        uuid__lte=CommitContext.convert_to_uuid(
                            end, CommitContext.timestamp_to_uuid()),
                        limit=limit,
                    ).items()
                })
            return result
Esempio n. 10
0
 def test_verify_table(self, redis=StrictRedis, cassandra=CassandraContext):
     with MockModelFactory.safari(), MockModelFactory.webkit():
         self.init_database(redis=redis, cassandra=cassandra)
         CommitContext(redis=redis(),
                       cassandra=cassandra(keyspace=self.KEYSPACE))
Esempio n. 11
0
class CommitContextTest(WaitForDockerTestCase):
    KEYSPACE = 'commit_mapping_test_keyspace'

    def init_database(self, redis=StrictRedis, cassandra=CassandraContext):
        redis_instance = redis()

        self.stash_repository = StashRepository(
            'https://bitbucket.example.com/projects/SAFARI/repos/safari')
        self.svn_repository = WebKitRepository()

        cassandra.drop_keyspace(keyspace=self.KEYSPACE)
        self.database = CommitContext(
            redis=redis_instance,
            cassandra=cassandra(keyspace=self.KEYSPACE, create_keyspace=True),
        )
        self.database.register_repository(self.stash_repository)
        self.database.register_repository(self.svn_repository)

    def add_all_commits_to_database(self):
        with MockModelFactory.safari() as safari, MockModelFactory.webkit(
        ) as webkit:
            with self.database, self.database.cassandra.batch_query_context():
                for key, repository in dict(safari=safari,
                                            webkit=webkit).items():
                    for branch, commits in repository.commits.items():
                        for commit in commits:
                            self.database.register_partial_commit(
                                key,
                                hash=commit.hash,
                                revision=commit.revision,
                                fast=False,
                            )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_verify_table(self, redis=StrictRedis, cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            CommitContext(redis=redis(),
                          cassandra=cassandra(keyspace=self.KEYSPACE))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_by_id(self, redis=StrictRedis, cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()

            self.assertEqual(
                [self.stash_repository.commit(ref='d8bce26fa65c')],
                self.database.find_commits_by_ref(repository_id='safari',
                                                  ref='d8bce26fa65c'),
            )

            self.assertEqual(
                [self.svn_repository.commit(ref=6)],
                self.database.find_commits_by_ref(repository_id='webkit',
                                                  ref=6),
            )
            self.assertEqual(
                0,
                len(
                    self.database.find_commits_by_ref(repository_id='webkit',
                                                      ref='1234')))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_by_uuid(self,
                            redis=StrictRedis,
                            cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()

            self.assertEqual(
                [self.stash_repository.commit(ref='1abe25b443e9')],
                self.database.find_commits_by_uuid(repository_id='safari',
                                                   branch='main',
                                                   uuid=160166300000),
            )
            self.assertEqual(
                [self.svn_repository.commit(ref=6)],
                self.database.find_commits_by_uuid(repository_id='webkit',
                                                   branch='main',
                                                   uuid=160163990000),
            )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_by_timestamp(self,
                                 redis=StrictRedis,
                                 cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()

            self.assertEqual(
                [self.stash_repository.commit(ref='1abe25b443e9')],
                self.database.find_commits_by_timestamp(repository_id='safari',
                                                        branch='main',
                                                        timestamp=1601663000),
            )
            self.assertEqual(
                [self.svn_repository.commit(ref=6)],
                self.database.find_commits_by_timestamp(repository_id='webkit',
                                                        branch='main',
                                                        timestamp=1601639900),
            )
            self.assertEqual(
                2,
                len(
                    self.database.find_commits_by_timestamp(
                        repository_id='safari',
                        branch='main',
                        timestamp=1601668000)))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_all_commits_stash(self,
                               redis=StrictRedis,
                               cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()
            self.assertEqual(
                5,
                len(
                    self.database.find_commits_in_range(repository_id='safari',
                                                        branch='main')))
            self.assertEqual(
                [
                    self.stash_repository.commit(ref='d8bce26fa65c'),
                    self.stash_repository.commit(ref='bae5d1e90999')
                ],
                self.database.find_commits_in_range(repository_id='safari',
                                                    branch='main',
                                                    limit=2),
            )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_all_commits_svn(self,
                             redis=StrictRedis,
                             cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()
            self.assertEqual(
                4,
                len(
                    self.database.find_commits_in_range(repository_id='webkit',
                                                        branch='main')))
            self.assertEqual(
                [
                    self.svn_repository.commit(ref=6),
                    self.svn_repository.commit(ref=4)
                ],
                self.database.find_commits_in_range(repository_id='webkit',
                                                    branch='main',
                                                    limit=2),
            )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_stash_commits_in_range(self,
                                    redis=StrictRedis,
                                    cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()
            self.assertEqual(
                [
                    self.stash_repository.commit(ref='bae5d1e90999'),
                    self.stash_repository.commit(ref='1abe25b443e9')
                ],
                self.database.find_commits_in_range(repository_id='safari',
                                                    branch='main',
                                                    begin=1601663000,
                                                    end=1601668000),
            )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_svn_commits_in_range(self,
                                  redis=StrictRedis,
                                  cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()
            self.assertEqual(
                [
                    self.svn_repository.commit(ref=6),
                    self.svn_repository.commit(ref=4)
                ],
                self.database.find_commits_in_range(repository_id='webkit',
                                                    branch='main',
                                                    begin=1601637900,
                                                    end=1601639900),
            )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_stash_commits_between(self,
                                   redis=StrictRedis,
                                   cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()

            commits = [
                self.stash_repository.commit(ref='1abe25b443e9'),
                self.stash_repository.commit(ref='fff83bb2d917'),
                self.stash_repository.commit(ref='9b8311f25a77'),
            ]
            self.assertEqual(
                commits,
                self.database.find_commits_in_range(repository_id='safari',
                                                    branch='main',
                                                    begin=commits[-1],
                                                    end=commits[0]))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_svn_commits_between(self,
                                 redis=StrictRedis,
                                 cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()

            commits = [
                self.svn_repository.commit(ref=6),
                self.svn_repository.commit(ref=4),
                self.svn_repository.commit(ref=2),
            ]
            self.assertEqual(
                commits,
                self.database.find_commits_in_range(repository_id='webkit',
                                                    branch='main',
                                                    begin=commits[-1],
                                                    end=commits[0]))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_from_stash_repo(self,
                                    redis=StrictRedis,
                                    cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.database.register_partial_commit('safari',
                                                  hash='d8bce26fa65c',
                                                  fast=False)
            self.assertEqual(
                [self.stash_repository.commit(ref='d8bce26fa65c')],
                self.database.find_commits_by_ref(repository_id='safari',
                                                  ref='d8bce26fa65c'),
            )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_from_svn_repo(self,
                                  redis=StrictRedis,
                                  cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.database.register_partial_commit('webkit',
                                                  revision=6,
                                                  fast=False)
            self.assertEqual(
                [self.svn_repository.commit(ref=6)],
                self.database.find_commits_by_ref(repository_id='webkit',
                                                  ref=6),
            )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_branches(self, redis=StrictRedis, cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()
            self.assertEqual(['branch-a', 'branch-b', 'main'],
                             self.database.branches(repository_id='safari'))
            self.assertEqual(
                ['branch-a', 'branch-b', 'main'],
                self.database.branches(repository_id='webkit'),
            )
            self.assertEqual(['branch-a', 'branch-b'],
                             self.database.branches(repository_id='safari',
                                                    branch='branch'))
            self.assertEqual(['branch-a'],
                             self.database.branches(repository_id='webkit',
                                                    branch='branch-a'))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_next_commit(self, redis=StrictRedis, cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()

            self.assertEqual(
                self.database.next_commit(self.svn_repository.commit(ref=4)),
                self.svn_repository.commit(ref=6),
            )
            self.assertEqual(
                self.database.next_commit(
                    self.stash_repository.commit(ref='bae5d1e90999')),
                self.stash_repository.commit(ref='d8bce26fa65c'),
            )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_previous_commit(self,
                             redis=StrictRedis,
                             cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()

            self.assertEqual(
                self.svn_repository.commit(ref=4),
                self.database.previous_commit(
                    self.svn_repository.commit(ref=6)),
            )
            self.assertEqual(
                self.stash_repository.commit(ref='bae5d1e90999'),
                self.database.previous_commit(
                    self.stash_repository.commit(ref='d8bce26fa65c')),
            )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_sibling_commits(self,
                             redis=StrictRedis,
                             cassandra=CassandraContext):
        self.maxDiff = None
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.add_all_commits_to_database()

            self.assertEqual(
                self.database.sibling_commits(
                    self.svn_repository.commit(ref=6), ['safari']),
                {
                    'safari': [
                        self.stash_repository.commit(ref='d8bce26fa65c'),
                        self.stash_repository.commit(ref='bae5d1e90999'),
                        self.stash_repository.commit(ref='1abe25b443e9'),
                        self.stash_repository.commit(ref='fff83bb2d917'),
                        self.stash_repository.commit(ref='9b8311f25a77'),
                    ]
                },
            )
            self.assertEqual(
                self.database.sibling_commits(
                    self.stash_repository.commit(ref='d8bce26fa65c'),
                    ['webkit']),
                {'webkit': [self.svn_repository.commit(ref=6)]},
            )
            self.assertEqual(
                self.database.sibling_commits(
                    self.svn_repository.commit(ref=1), ['safari']),
                {'safari': []},
            )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_uuid_for_commits(self,
                              redis=StrictRedis,
                              cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            uuid = CommitContext.uuid_for_commits([
                self.stash_repository.commit(ref='bae5d1e90999'),
                self.svn_repository.commit(ref=6),
            ])
            self.assertEqual(uuid, 160166800000)

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_branch_keys_for_commits(self,
                                     redis=StrictRedis,
                                     cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            branches = self.database.branch_keys_for_commits([
                self.stash_repository.commit(ref='d8bce26fa65c'),
                self.svn_repository.commit(ref=6),
            ])
            self.assertEqual(branches, ['default'])

            branches = self.database.branch_keys_for_commits([
                self.stash_repository.commit(ref='621652add7fc'),
                self.svn_repository.commit(ref=7),
            ])
            self.assertEqual(branches, ['branch-a'])

            branches = self.database.branch_keys_for_commits([
                self.stash_repository.commit(ref='790725a6d79e'),
                self.svn_repository.commit(ref=8),
            ])
            self.assertEqual(branches, ['branch-b'])

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_url(self, redis=StrictRedis, cassandra=CassandraContext):
        with MockModelFactory.safari(), MockModelFactory.webkit():
            self.init_database(redis=redis, cassandra=cassandra)
            self.assertEqual(
                'https://bitbucket.example.com/projects/SAFARI/repos/safari/commits/d8bce26fa65c6fc8f39c17927abb77f69fab82fc',
                self.database.url(
                    self.stash_repository.commit(ref='d8bce26fa65c')),
            )
            self.assertEqual(
                'https://commits.webkit.org/4@main',
                self.database.url(self.svn_repository.commit(ref=6)),
            )
Esempio n. 12
0
class Model(object):
    TTL_DAY = 60 * 60 * 24
    TTL_WEEK = 7 * TTL_DAY
    TTL_YEAR = 365 * TTL_DAY

    def __init__(self,
                 redis,
                 cassandra,
                 repositories=[],
                 default_ttl_seconds=TTL_YEAR * 5,
                 async_processing=False):
        if default_ttl_seconds is not None and default_ttl_seconds < 4 * self.TTL_WEEK:
            raise ValueError('TTL must be at least 4 weeks')
        self.default_ttl_seconds = default_ttl_seconds
        self._async_processing = async_processing

        self.redis = redis
        self.cassandra = cassandra
        self.commit_context = CommitContext(redis, cassandra)
        for repository in repositories:
            self.commit_context.register_repository(repository)
        self.configuration_context = ConfigurationContext(redis, cassandra)
        self.upload_context = UploadContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
            async_processing=async_processing,
        )

        self.suite_context = SuiteContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )
        self.test_context = TestContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )
        self.ci_context = CIContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )

        for context in [
                self.suite_context, self.test_context, self.ci_context
        ]:
            self.upload_context.register_upload_callback(
                context.name, context.register)

        self.archive_context = ArchiveContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )

    def do_work(self):
        if not self._async_processing:
            raise RuntimeError(
                'No work to be done, asynchronous processing disabled')

        try:
            self.upload_context.do_processing_work()
        except Exception as e:
            sys.stderr.write(f'{traceback.format_exc()}\n')
            sys.stderr.write(f'{e}\n')
Esempio n. 13
0
 def test_verify_table(self, redis=StrictRedis, cassandra=CassandraContext):
     self.init_database(redis=redis, cassandra=cassandra)
     CommitContext(redis=redis(),
                   cassandra=cassandra(keyspace=self.KEYSPACE))
Esempio n. 14
0
 def test_uuid_for_commits(self):
     uuid = CommitContext.uuid_for_commits([
         MockStashRepository.safari().commit_for_id(id='bb6bda5f'),
         MockSVNRepository.webkit().commit_for_id(id=236544)
     ])
     self.assertEqual(uuid, 153805240800)
Esempio n. 15
0
class CommitContextTest(WaitForDockerTestCase):
    KEYSPACE = 'commit_mapping_test_keyspace'

    def init_database(self, redis=StrictRedis, cassandra=CassandraContext):
        redis_instance = redis()

        self.stash_repository = MockStashRepository.safari(redis_instance)
        self.svn_repository = MockSVNRepository.webkit(redis_instance)

        cassandra.drop_keyspace(keyspace=self.KEYSPACE)
        self.database = CommitContext(
            redis=redis_instance,
            cassandra=cassandra(keyspace=self.KEYSPACE, create_keyspace=True),
        )
        self.database.register_repository(self.stash_repository)
        self.database.register_repository(self.svn_repository)

    def add_all_commits_to_database(self):
        for mock_repository in [self.stash_repository, self.svn_repository]:
            for commit_list in mock_repository.commits.values():
                for commit in commit_list:
                    self.database.register_commit(commit)

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_verify_table(self, redis=StrictRedis, cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        CommitContext(redis=redis(),
                      cassandra=cassandra(keyspace=self.KEYSPACE))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_by_id(self, redis=StrictRedis, cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()

        self.assertEqual(
            [
                self.stash_repository.commit_for_id(id='bb6bda5f44',
                                                    branch='master')
            ],
            self.database.find_commits_by_id(repository_id='safari',
                                             branch='master',
                                             commit_id='bb6bda5f44'),
        )
        self.assertEqual(
            2,
            len(
                self.database.find_commits_by_id(repository_id='safari',
                                                 branch='master',
                                                 commit_id='336610a')))

        self.assertEqual(
            [self.svn_repository.commit_for_id(id=236544, branch='trunk')],
            self.database.find_commits_by_id(repository_id='webkit',
                                             branch='trunk',
                                             commit_id=236544),
        )
        self.assertEqual(
            0,
            len(
                self.database.find_commits_by_id(repository_id='webkit',
                                                 branch='trunk',
                                                 commit_id='23654')))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_by_uuid(self,
                            redis=StrictRedis,
                            cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()

        self.assertEqual(
            [
                self.stash_repository.commit_for_id(id='7be4084258',
                                                    branch='master')
            ],
            self.database.find_commits_by_uuid(repository_id='safari',
                                               branch='master',
                                               uuid=153755068501),
        )
        self.assertEqual(
            [self.svn_repository.commit_for_id(id=236540, branch='trunk')],
            self.database.find_commits_by_uuid(repository_id='webkit',
                                               branch='trunk',
                                               uuid=153802947900),
        )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_by_timestamp(self,
                                 redis=StrictRedis,
                                 cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()

        self.assertEqual(
            [
                self.stash_repository.commit_for_id(id='336610a84f',
                                                    branch='master')
            ],
            self.database.find_commits_by_timestamp(repository_id='safari',
                                                    branch='master',
                                                    timestamp=1537809818),
        )
        self.assertEqual(
            [self.svn_repository.commit_for_id(id=236540, branch='trunk')],
            self.database.find_commits_by_timestamp(repository_id='webkit',
                                                    branch='trunk',
                                                    timestamp=1538029479),
        )
        self.assertEqual(
            2,
            len(
                self.database.find_commits_by_timestamp(repository_id='safari',
                                                        branch='master',
                                                        timestamp=1537550685)))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_all_commits_stash(self,
                               redis=StrictRedis,
                               cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()
        self.assertEqual(
            5,
            len(
                self.database.find_commits_in_range(repository_id='safari',
                                                    branch='master')))
        self.assertEqual(
            [
                self.stash_repository.commit_for_id(id='bb6bda5f44',
                                                    branch='master'),
                self.stash_repository.commit_for_id(id='336610a84f',
                                                    branch='master')
            ],
            self.database.find_commits_in_range(repository_id='safari',
                                                branch='master',
                                                limit=2),
        )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_all_commits_svn(self,
                             redis=StrictRedis,
                             cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()
        self.assertEqual(
            5,
            len(
                self.database.find_commits_in_range(repository_id='webkit',
                                                    branch='trunk')))
        self.assertEqual(
            [
                self.svn_repository.commit_for_id(id=236544, branch='trunk'),
                self.svn_repository.commit_for_id(id=236543, branch='trunk')
            ],
            self.database.find_commits_in_range(repository_id='webkit',
                                                branch='trunk',
                                                limit=2),
        )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_stash_commits_in_range(self,
                                    redis=StrictRedis,
                                    cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()
        self.assertEqual(
            [
                self.stash_repository.commit_for_id(id='bb6bda5f44',
                                                    branch='master'),
                self.stash_repository.commit_for_id(id='336610a84f',
                                                    branch='master')
            ],
            self.database.find_commits_in_range(repository_id='safari',
                                                branch='master',
                                                begin=1537809818,
                                                end=1537810281),
        )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_svn_commits_in_range(self,
                                  redis=StrictRedis,
                                  cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()
        self.assertEqual(
            [
                self.svn_repository.commit_for_id(id=236544, branch='trunk'),
                self.svn_repository.commit_for_id(id=236543, branch='trunk')
            ],
            self.database.find_commits_in_range(repository_id='webkit',
                                                branch='trunk',
                                                begin=1538050458,
                                                end=1538052408),
        )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_stash_commits_between(self,
                                   redis=StrictRedis,
                                   cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()

        commits = [
            self.stash_repository.commit_for_id(id='bb6bda5f',
                                                branch='master'),
            self.stash_repository.commit_for_id(id='336610a8',
                                                branch='master'),
            self.stash_repository.commit_for_id(id='336610a4',
                                                branch='master'),
        ]
        self.assertEqual(
            commits,
            self.database.find_commits_in_range(repository_id='safari',
                                                branch='master',
                                                begin=commits[-1],
                                                end=commits[0]))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_svn_commits_between(self,
                                 redis=StrictRedis,
                                 cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()

        commits = [
            self.svn_repository.commit_for_id(id=236544, branch='trunk'),
            self.svn_repository.commit_for_id(id=236543, branch='trunk'),
            self.svn_repository.commit_for_id(id=236542, branch='trunk'),
        ]
        self.assertEqual(
            commits,
            self.database.find_commits_in_range(repository_id='webkit',
                                                branch='trunk',
                                                begin=commits[-1],
                                                end=commits[0]))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_from_stash_repo(self,
                                    redis=StrictRedis,
                                    cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.database.register_commit_with_repo_and_id('safari', 'master',
                                                       'bb6bda5f44')
        self.assertEqual(
            [
                self.stash_repository.commit_for_id(id='bb6bda5f44',
                                                    branch='master')
            ],
            self.database.find_commits_by_id(repository_id='safari',
                                             branch='master',
                                             commit_id='bb6bda5f44'),
        )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_from_svn_repo(self,
                                  redis=StrictRedis,
                                  cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.database.register_commit_with_repo_and_id('webkit', 'trunk',
                                                       236544)
        self.assertEqual(
            [self.svn_repository.commit_for_id(id=236544, branch='trunk')],
            self.database.find_commits_by_id(repository_id='webkit',
                                             branch='trunk',
                                             commit_id=236544),
        )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_branches(self, redis=StrictRedis, cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()
        self.assertEqual(['master', 'safari-606-branch'],
                         self.database.branches(repository_id='safari'))
        self.assertEqual(['safari-606-branch', 'trunk'],
                         self.database.branches(repository_id='webkit'))
        self.assertEqual(['safari-606-branch'],
                         self.database.branches(repository_id='safari',
                                                branch='safari'))
        self.assertEqual(['safari-606-branch'],
                         self.database.branches(repository_id='webkit',
                                                branch='safari-606-branch'))

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_next_commit(self, redis=StrictRedis, cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()

        self.assertEqual(
            self.database.next_commit(
                self.svn_repository.commit_for_id(id=236542)),
            self.svn_repository.commit_for_id(id=236543),
        )
        self.assertEqual(
            self.database.next_commit(
                self.stash_repository.commit_for_id(
                    id='336610a40c3fecb728871e12ca31482ca715b383')),
            self.stash_repository.commit_for_id(
                id='336610a84fdcf14ddcf1db65075af95480516fda'),
        )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_previous_commit(self,
                             redis=StrictRedis,
                             cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()

        self.assertEqual(
            self.svn_repository.commit_for_id(id=236542),
            self.database.previous_commit(
                self.svn_repository.commit_for_id(id=236543)),
        )
        self.assertEqual(
            self.stash_repository.commit_for_id(
                id='336610a40c3fecb728871e12ca31482ca715b383'),
            self.database.previous_commit(
                self.stash_repository.commit_for_id(
                    id='336610a84fdcf14ddcf1db65075af95480516fda')),
        )

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_sibling_commits(self,
                             redis=StrictRedis,
                             cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.add_all_commits_to_database()

        self.assertEqual(
            self.database.sibling_commits(
                self.svn_repository.commit_for_id(id=236542), ['safari']),
            {
                'safari': [
                    self.stash_repository.commit_for_id(
                        id='bb6bda5f44dd24d0b54539b8ff6e8c17f519249a')
                ]
            },
        )
        self.assertEqual(
            self.database.sibling_commits(
                self.stash_repository.commit_for_id(
                    id='bb6bda5f44dd24d0b54539b8ff6e8c17f519249a'),
                ['webkit']),
            {
                'webkit': [
                    self.svn_repository.commit_for_id(id=236544),
                    self.svn_repository.commit_for_id(id=236543),
                    self.svn_repository.commit_for_id(id=236542),
                    self.svn_repository.commit_for_id(id=236541),
                    self.svn_repository.commit_for_id(id=236540),
                ]
            },
        )
        self.assertEqual(
            self.database.sibling_commits(
                self.stash_repository.commit_for_id(
                    id='336610a84fdcf14ddcf1db65075af95480516fda'),
                ['webkit']),
            {'webkit': []},
        )

    def test_uuid_for_commits(self):
        uuid = CommitContext.uuid_for_commits([
            MockStashRepository.safari().commit_for_id(id='bb6bda5f'),
            MockSVNRepository.webkit().commit_for_id(id=236544)
        ])
        self.assertEqual(uuid, 153805240800)

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_branch_keys_for_commits(self,
                                     redis=StrictRedis,
                                     cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        branches = self.database.branch_keys_for_commits([
            MockStashRepository.safari().commit_for_id(id='bb6bda5f'),
            MockSVNRepository.webkit().commit_for_id(id=236544),
        ])
        self.assertEqual(branches, ['default'])

        branches = self.database.branch_keys_for_commits([
            MockStashRepository.safari().commit_for_id(
                id='79256c32', branch='safari-606-branch'),
            MockSVNRepository.webkit().commit_for_id(id=236544),
        ])
        self.assertEqual(branches, ['safari-606-branch'])

        branches = self.database.branch_keys_for_commits([
            MockStashRepository.safari().commit_for_id(
                id='79256c32', branch='safari-606-branch'),
            MockSVNRepository.webkit().commit_for_id(
                id=236335, branch='safari-606-branch'),
        ])
        self.assertEqual(branches, ['safari-606-branch'])

    @WaitForDockerTestCase.mock_if_no_docker(
        mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
    def test_commit_url(self, redis=StrictRedis, cassandra=CassandraContext):
        self.init_database(redis=redis, cassandra=cassandra)
        self.assertEqual(
            'https://fake-stash-instance.apple.com/projects/BROWSER/repos/safari/commits/bb6bda5f44dd24d0b54539b8ff6e8c17f519249a',
            self.database.url(
                MockStashRepository.safari().commit_for_id(id='bb6bda5f')),
        )
        self.assertEqual(
            'https://trac.webkit.org/changeset/236544/webkit',
            self.database.url(
                MockSVNRepository.webkit().commit_for_id(id=236544)),
        )
Esempio n. 16
0
    def _failures(
        self,
        all_table,
        unexpected_table,
        configurations,
        suite,
        recent=True,
        branch=None,
        begin=None,
        end=None,
        begin_query_time=None,
        end_query_time=None,
        unexpected=True,
        collapsed=True,
        limit=DEFAULT_LIMIT,
    ):
        table = unexpected_table if unexpected else all_table
        if not isinstance(suite, str):
            raise TypeError(
                f'Expected type {str} for suite, got {type(suite)}')

        def get_time(time):
            if isinstance(time, datetime):
                return time
            elif time:
                return datetime.utcfromtimestamp(int(time))
            return None

        with self:
            has_test_runs = False
            if collapsed:
                result = set()
            else:
                result = {}

            for configuration in configurations:
                for config, values in self.configuration_context.select_from_table_with_configurations(
                        table.__table_name__,
                        configurations=[configuration],
                        recent=recent,
                        suite=suite,
                        sdk=configuration.sdk,
                        branch=branch
                        or self.commit_context.DEFAULT_BRANCH_KEY,
                        uuid__gte=CommitContext.convert_to_uuid(begin),
                        uuid__lte=CommitContext.convert_to_uuid(
                            end, CommitContext.timestamp_to_uuid()),
                        start_time__gte=get_time(begin_query_time),
                        start_time__lte=get_time(end_query_time),
                        limit=limit,
                ).items():
                    if collapsed:
                        for value in values:
                            has_test_runs = True
                            for test in value.unpack():
                                if test not in ['uuid', 'start_time']:
                                    result.add(test)
                    else:
                        runs = []
                        for value in values:
                            has_test_runs = True

                            # uuid and start_time are not in the unpacked values
                            unpacked = value.unpack()
                            if len(unpacked) > 2:
                                runs.append(unpacked)
                        if runs:
                            result.update({config: runs})

            return result if has_test_runs else None
Esempio n. 17
0
class Model(object):
    TTL_DAY = 60 * 60 * 24
    TTL_WEEK = 7 * TTL_DAY
    TTL_YEAR = 365 * TTL_DAY

    class HealthTable(CassandraModel):
        __table_name__ = 'health'
        key = columns.Text(partition_key=True, required=True)
        value = columns.Text(required=True)

    def __init__(self,
                 redis,
                 cassandra,
                 repositories=[],
                 default_ttl_seconds=TTL_YEAR * 5,
                 archive_ttl_seconds=TTL_WEEK * 8,
                 async_processing=False,
                 s3_credentials=None):
        if default_ttl_seconds is not None and default_ttl_seconds < 4 * self.TTL_WEEK:
            raise ValueError('TTL must be at least 4 weeks')
        if archive_ttl_seconds is not None and archive_ttl_seconds < 2 * self.TTL_WEEK:
            raise ValueError('Archive TTL must be at least 2 weeks')
        self.default_ttl_seconds = default_ttl_seconds
        self.archive_ttl_seconds = archive_ttl_seconds or default_ttl_seconds
        self._async_processing = async_processing

        self.redis = redis
        self.cassandra = cassandra

        with self.cassandra:
            self.cassandra.create_table(self.HealthTable)

        self.commit_context = CommitContext(redis, cassandra)
        for repository in repositories:
            self.commit_context.register_repository(repository)
        self.configuration_context = ConfigurationContext(redis, cassandra)
        self.upload_context = UploadContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
            async_processing=async_processing,
        )

        self.suite_context = SuiteContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )
        self.test_context = TestContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )
        self.failure_context = FailureContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )
        self.ci_context = CIContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.default_ttl_seconds,
        )

        for context in [
                self.ci_context, self.failure_context, self.suite_context,
                self.test_context, self.commit_context
        ]:
            self.upload_context.register_upload_callback(
                context.name, context.register)

        self.archive_context = ArchiveContext(
            configuration_context=self.configuration_context,
            commit_context=self.commit_context,
            ttl_seconds=self.archive_ttl_seconds,
            s3_credentials=s3_credentials,
        )

    def healthy(self, writable=True):
        if writable:
            self.redis.set('health-check', b'healthy', ex=5 * 60)
        value = self.redis.get('health-check')
        if value is not None and value != b'healthy':
            return False

        with self.cassandra:
            if writable:
                self.cassandra.insert_row(
                    self.HealthTable.__table_name__,
                    key='health-check',
                    value='healthy',
                    ttl=5 * 60,
                )
            values = [
                element.value for element in self.cassandra.select_from_table(
                    self.HealthTable.__table_name__,
                    limit=100,
                    key='health-check',
                )
            ]
            if values and values != ['healthy']:
                return False

        return True

    def do_work(self):
        if not self._async_processing:
            raise RuntimeError(
                'No work to be done, asynchronous processing disabled')

        try:
            return self.upload_context.do_processing_work()
        except Exception as e:
            sys.stderr.write(f'{traceback.format_exc()}\n')
            sys.stderr.write(f'{e}\n')

        return False
Esempio n. 18
0
    def find_archive(
            self, configurations=None, suite=None, recent=True,
            branch=None, begin=None, end=None,
            begin_query_time=None, end_query_time=None,
            limit=DEFAULT_LIMIT,
    ):
        if not configurations:
            configurations = []
        if not isinstance(suite, str):
            raise TypeError(f'Expected type {str}, got {type(suite)}')

        with self:
            metadata_by_config = {}
            for configuration in configurations:
                metadata_by_config.update({config: [value.unpack() for value in values] for config, values in self.configuration_context.select_from_table_with_configurations(
                    self.ArchiveMetaDataByCommit.__table_name__, configurations=[configuration], recent=recent,
                    suite=suite, sdk=configuration.sdk, branch=branch or self.commit_context.DEFAULT_BRANCH_KEY,
                    uuid__gte=CommitContext.convert_to_uuid(begin),
                    uuid__lte=CommitContext.convert_to_uuid(end, CommitContext.timestamp_to_uuid()),
                    start_time__gte=_get_time(begin_query_time), start_time__lte=_get_time(end_query_time),
                    limit=limit,
                ).items()})

            memory_used = 0
            for values in metadata_by_config.values():
                for value in values:
                    if not value.get('digest'):
                        continue

                    memory_used += value.get('size', 0)
                    if memory_used > self.MEMORY_LIMIT:
                        raise RuntimeError('Hit soft-memory cap when fetching archives, aborting')

            result = {}
            for config, values in metadata_by_config.items():
                for value in values:
                    if not value.get('digest'):
                        continue

                    rows = self.cassandra.select_from_table(
                        self.ArchiveChunks.__table_name__,
                        digest=value.get('digest'),
                        limit=1 + int(value.get('size', 0) / self.CHUNK_SIZE),
                    )
                    if len(rows) == 0:
                        continue

                    digest = hashlib.md5()
                    archive = io.BytesIO()
                    archive_size = 0
                    for row in rows:
                        archive_size += len(row.chunk)
                        digest.update(row.chunk)
                        archive.write(row.chunk)

                    if archive_size != value.get('size', 0) or value.get('digest', '') != digest.hexdigest():
                        raise RuntimeError('Failed to reconstruct archive from chunks')

                    archive.seek(0)
                    result.setdefault(config, [])
                    result[config].append(dict(
                        archive=archive,
                        uuid=value['uuid'],
                        start_time=value['start_time'],
                    ))

            return result