예제 #1
0
    def test_fetch_when_wpt_dir_does_not_exist(self):
        host = MockHost()
        local_wpt = LocalWPT(host, 'token')
        local_wpt.fetch()

        self.assertEqual(host.executive.calls, [
            ['git', 'clone', 'https://[email protected]/web-platform-tests/wpt.git', '/tmp/wpt'],
        ])
예제 #2
0
    def test_seek_change_id(self):
        host = MockHost()
        local_wpt = LocalWPT(host, 'token')

        local_wpt.seek_change_id('Ifake-change-id')
        self.assertEqual(
            host.executive.calls,
            [['git', 'log', '-1', '--grep', '^Change-Id: Ifake-change-id']])
예제 #3
0
    def test_seek_commit_position(self):
        host = MockHost()
        local_wpt = LocalWPT(host, 'token')

        local_wpt.seek_commit_position('refs/heads/master@{12345}')
        self.assertEqual(host.executive.calls, [[
            'git', 'log', '-1', '--grep',
            '^Cr-Commit-Position: refs/heads/master@{12345}'
        ]])
예제 #4
0
    def test_is_commit_affecting_directory(self):
        host = MockHost()
        # return_exit_code=True is passed to run() in the method under test,
        # so the mock return value should be exit code instead of output.
        host.executive = mock_git_commands({'diff-tree': 1}, strict=True)
        local_wpt = LocalWPT(host, 'token')

        self.assertTrue(local_wpt.is_commit_affecting_directory('HEAD', 'css/'))
        self.assertEqual(host.executive.calls, [['git', 'diff-tree', '--quiet', '--no-commit-id', 'HEAD', '--', 'css/']])
예제 #5
0
    def test_commits_in_range(self):
        host = MockHost()
        host.executive = mock_git_commands({
            'rev-list': '34ab6c3f5aee8bf05207b674edbcb6affb179545 Fix presubmit errors\n'
                        '8c596b820634a623dfd7a2b0f36007ce2f7a0c9f test\n'
        }, strict=True)
        local_wpt = LocalWPT(host, 'token')

        self.assertTrue(local_wpt.commits_in_range('HEAD~2', 'HEAD'))
        self.assertEqual(host.executive.calls, [['git', 'rev-list', '--pretty=oneline', 'HEAD~2..HEAD']])
예제 #6
0
    def test_fetch_when_wpt_dir_exists(self):
        host = MockHost()
        host.filesystem = MockFileSystem(files={'/tmp/wpt': ''})

        local_wpt = LocalWPT(host, 'token')
        local_wpt.fetch()

        self.assertEqual(host.executive.calls, [
            ['git', 'fetch', 'origin'],
            ['git', 'reset', '--hard', 'origin/master'],
        ])
예제 #7
0
    def test_test_patch_error(self):
        def _run_fn(args):
            if args[0] == 'git' and args[1] == 'apply':
                raise ScriptError('MOCK failed applying patch')
            return ''

        host = MockHost()
        host.executive = MockExecutive(run_command_fn=_run_fn)
        local_wpt = LocalWPT(host, 'token')

        self.assertEqual(local_wpt.test_patch('dummy patch'), (False, 'MOCK failed applying patch'))
예제 #8
0
    def test_test_patch_empty_diff(self):
        host = MockHost()
        host.executive = mock_git_commands({
            'apply': '',
            'add': '',
            'diff': '',
            'reset': '',
            'clean': '',
            'checkout': '',
        }, strict=True)
        local_wpt = LocalWPT(host, 'token')

        self.assertEqual(local_wpt.test_patch('dummy patch'), (False, ''))
예제 #9
0
    def test_fetch_when_wpt_dir_does_not_exist(self):
        host = MockHost()
        local_wpt = LocalWPT(host, 'token')
        local_wpt.fetch()

        self.assertEqual(host.executive.calls, [
            [
                'git', 'clone',
                'https://[email protected]/web-platform-tests/wpt.git',
                '/tmp/wpt'
            ],
            ['git', 'config', 'user.name', DEFAULT_WPT_COMMITTER_NAME],
            ['git', 'config', 'user.email', DEFAULT_WPT_COMMITTER_EMAIL],
        ])
예제 #10
0
    def main(self, argv=None):
        """Creates PRs for in-flight CLs and merges changes that land on master.

        Returns:
            A boolean: True if success, False if there were any patch failures.
        """
        options = self.parse_args(argv)

        self.dry_run = options.dry_run
        log_level = logging.DEBUG if options.verbose else logging.INFO
        configure_logging(logging_level=log_level, include_time=True)
        if options.verbose:
            # Print out the full output when executive.run_command fails.
            self.host.executive.error_output_limit = None

        credentials = read_credentials(self.host, options.credentials_json)
        if not (credentials.get('GH_USER') and credentials.get('GH_TOKEN')):
            _log.error('You must provide your GitHub credentials for this '
                       'script to work.')
            _log.error('See https://chromium.googlesource.com/chromium/src'
                       '/+/master/docs/testing/web_platform_tests.md'
                       '#GitHub-credentials for instructions on how to set '
                       'your credentials up.')
            return False

        self.wpt_github = self.wpt_github or WPTGitHub(
            self.host, credentials['GH_USER'], credentials['GH_TOKEN'])
        self.gerrit = self.gerrit or GerritAPI(
            self.host, credentials['GERRIT_USER'], credentials['GERRIT_TOKEN'])
        self.local_wpt = self.local_wpt or LocalWPT(self.host,
                                                    credentials['GH_TOKEN'])
        self.local_wpt.fetch()

        _log.info('Searching for exportable in-flight CLs.')
        # The Gerrit search API is slow and easy to fail, so we wrap it in a try
        # statement to continue exporting landed commits when it fails.
        try:
            open_gerrit_cls = self.gerrit.query_exportable_open_cls()
        except GerritError as e:
            _log.info(
                'In-flight CLs cannot be exported due to the following error:')
            _log.error(str(e))
            gerrit_error = True
        else:
            self.process_gerrit_cls(open_gerrit_cls)
            gerrit_error = False

        _log.info('Searching for exportable Chromium commits.')
        exportable_commits, git_errors = self.get_exportable_commits()
        self.process_chromium_commits(exportable_commits)
        if git_errors:
            _log.info(
                'Attention: The following errors have prevented some commits from being '
                'exported:')
            for error in git_errors:
                _log.error(error)

        return not (gerrit_error or git_errors)
예제 #11
0
    def test_create_branch_with_patch(self):
        host = MockHost()
        local_wpt = LocalWPT(host, 'token')
        local_wpt.fetch()

        local_wpt.create_branch_with_patch('chromium-export-decafbad',
                                           'message', 'patch',
                                           'author <*****@*****.**>')
        self.assertEqual(
            host.executive.calls,
            [[
                'git', 'clone',
                'https://[email protected]/web-platform-tests/wpt.git',
                '/tmp/wpt'
            ], ['git', 'config', 'user.name', DEFAULT_WPT_COMMITTER_NAME],
             ['git', 'config', 'user.email', DEFAULT_WPT_COMMITTER_EMAIL],
             ['git', 'reset', '--hard', 'HEAD'], ['git', 'clean', '-fdx'],
             ['git', 'checkout', 'origin/master'],
             ['git', 'branch', '-D', 'chromium-export-decafbad'],
             ['git', 'checkout', '-b', 'chromium-export-decafbad'],
             ['git', 'apply', '-'], ['git', 'add', '.'],
             [
                 'git', 'commit', '--author', 'author <*****@*****.**>',
                 '-am', 'message'
             ], ['git', 'push', 'origin', 'chromium-export-decafbad']])
예제 #12
0
 def test_apply_exportable_commits_locally(self):
     # TODO(robertma): Consider using MockLocalWPT.
     host = self.mock_host()
     importer = self._get_test_importer(
         host, wpt_github=MockWPTGitHub(pull_requests=[]))
     importer.wpt_git = MockGit(cwd='/tmp/wpt', executive=host.executive)
     fake_commit = MockChromiumCommit(
         host,
         subject='My fake commit',
         patch=('Fake patch contents...\n'
                '--- a/' + RELATIVE_WEB_TESTS +
                'external/wpt/css/css-ui-3/outline-004.html\n'
                '+++ b/' + RELATIVE_WEB_TESTS +
                'external/wpt/css/css-ui-3/outline-004.html\n'
                '@@ -20,7 +20,7 @@\n'
                '...'))
     importer.exportable_but_not_exported_commits = lambda _: [fake_commit]
     applied = importer.apply_exportable_commits_locally(LocalWPT(host))
     self.assertEqual(applied, [fake_commit])
     # This assertion is implementation details of LocalWPT.apply_patch.
     # TODO(robertma): Move this to local_wpt_unittest.py.
     self.assertEqual(host.executive.full_calls, [
         MockCall(MANIFEST_INSTALL_CMD,
                  kwargs={
                      'input': None,
                      'cwd': None,
                      'env': None
                  }),
         MockCall(
             ['git', 'apply', '-'], {
                 'input': ('Fake patch contents...\n'
                           '--- a/css/css-ui-3/outline-004.html\n'
                           '+++ b/css/css-ui-3/outline-004.html\n'
                           '@@ -20,7 +20,7 @@\n'
                           '...'),
                 'cwd':
                 '/tmp/wpt',
                 'env':
                 None
             }),
         MockCall(['git', 'add', '.'],
                  kwargs={
                      'input': None,
                      'cwd': '/tmp/wpt',
                      'env': None
                  })
     ])
     self.assertEqual(
         importer.wpt_git.local_commits(),
         [['Applying patch 14fd77e88e42147c57935c49d9e3b2412b8491b7']])
예제 #13
0
    def main(self, argv=None):
        # TODO(robertma): Test this method! Split it to make it easier to test
        # if necessary.

        options = self.parse_args(argv)

        self.verbose = options.verbose
        log_level = logging.DEBUG if self.verbose else logging.INFO
        configure_logging(logging_level=log_level, include_time=True)

        # Having the full output when executive.run_command fails is useful when
        # investigating a failed import, as all we have are logs.
        self.executive.error_output_limit = None

        if options.auto_update and options.auto_upload:
            _log.error(
                '--auto-upload and --auto-update cannot be used together.')
            return 1

        if not self.checkout_is_okay():
            return 1

        credentials = read_credentials(self.host, options.credentials_json)
        gh_user = credentials.get('GH_USER')
        gh_token = credentials.get('GH_TOKEN')
        if not gh_user or not gh_token:
            _log.warning('You have not set your GitHub credentials. This '
                         'script may fail with a network error when making '
                         'an API request to GitHub.')
            _log.warning('See https://chromium.googlesource.com/chromium/src'
                         '/+/master/docs/testing/web_platform_tests.md'
                         '#GitHub-credentials for instructions on how to set '
                         'your credentials up.')
        self.wpt_github = self.wpt_github or WPTGitHub(self.host, gh_user,
                                                       gh_token)
        self.git_cl = GitCL(
            self.host, auth_refresh_token_json=options.auth_refresh_token_json)

        _log.debug('Noting the current Chromium revision.')
        chromium_revision = self.chromium_git.latest_git_commit()

        # Instantiate Git after local_wpt.fetch() to make sure the path exists.
        local_wpt = LocalWPT(self.host, gh_token=gh_token)
        local_wpt.fetch()
        self.wpt_git = self.host.git(local_wpt.path)

        if options.revision is not None:
            _log.info('Checking out %s', options.revision)
            self.wpt_git.run(['checkout', options.revision])

        _log.debug('Noting the revision we are importing.')
        self.wpt_revision = self.wpt_git.latest_git_commit()
        self.last_wpt_revision = self._get_last_imported_wpt_revision()
        import_commit = 'wpt@%s' % self.wpt_revision

        _log.info('Importing %s to Chromium %s', import_commit,
                  chromium_revision)

        if options.ignore_exportable_commits:
            commit_message = self._commit_message(chromium_revision,
                                                  import_commit)
        else:
            commits = self.apply_exportable_commits_locally(local_wpt)
            if commits is None:
                _log.error('Could not apply some exportable commits cleanly.')
                _log.error('Aborting import to prevent clobbering commits.')
                return 1
            commit_message = self._commit_message(
                chromium_revision,
                import_commit,
                locally_applied_commits=commits)

        self._clear_out_dest_path()

        _log.info('Copying the tests from the temp repo to the destination.')
        test_copier = TestCopier(self.host, local_wpt.path)
        test_copier.do_import()

        # TODO(robertma): Implement `add --all` in Git (it is different from `commit --all`).
        self.chromium_git.run(['add', '--all', self.dest_path])

        # Remove expectations for tests that were deleted and rename tests
        # in expectations for renamed tests.
        self._expectations_updater.cleanup_test_expectations_files()

        self._generate_manifest()

        # TODO(crbug.com/800570 robertma): Re-enable it once we fix the bug.
        # self._delete_orphaned_baselines()


        if not self.chromium_git.has_working_directory_changes():
            _log.info('Done: no changes to import.')
            return 0

        if self._only_wpt_manifest_changed():
            _log.info('Only manifest was updated; skipping the import.')
            return 0

        self._commit_changes(commit_message)
        _log.info('Changes imported and committed.')

        if not options.auto_upload and not options.auto_update:
            return 0

        self._upload_cl()
        _log.info('Issue: %s', self.git_cl.run(['issue']).strip())

        if not self.update_expectations_for_cl():
            return 1

        if not options.auto_update:
            return 0

        if not self.run_commit_queue_for_cl():
            return 1

        if not self.send_notifications(local_wpt, options.auto_file_bugs,
                                       options.monorail_auth_json):
            return 1

        return 0
예제 #14
0
 def test_run(self):
     host = MockHost()
     local_wpt = LocalWPT(host, 'token')
     local_wpt.run(['echo', 'rutabaga'])
     self.assertEqual(host.executive.calls, [['echo', 'rutabaga']])
예제 #15
0
 def test_constructor(self):
     host = MockHost()
     LocalWPT(host, 'token')
     self.assertEqual(len(host.executive.calls), 0)