Ejemplo n.º 1
0
 def Cleanup(self):
     if cli_helpers.Ask('Should I clean up the temp dir with logs?'):
         shutil.rmtree(self.output_dir, ignore_errors=True)
     else:
         cli_helpers.Comment(
             'No problem. All logs will remain in %s - feel free to remove that '
             'directory when done.' % self.output_dir)
 def testAskNoDefaultCustomAnswersAsList(self, raw_input_mock, print_mock):
     raw_input_mock.side_effect = ['', 'FoO']
     self.assertEqual(cli_helpers.Ask('Ready?', ['foo', 'bar']), 'foo')
     self.assertListEqual(print_mock.mock_calls, [
         mock.call('\033[96mReady? [foo/bar] \033[0m', end=' '),
         mock.call('\033[91mPlease respond with "bar" or "foo".\033[0m'),
         mock.call('\033[96mReady? [foo/bar] \033[0m', end=' ')
     ])
 def testAskAgainOnInvalidAnswer(self, raw_input_mock, print_mock):
     raw_input_mock.side_effect = ['foobar', 'y']
     self.assertTrue(cli_helpers.Ask('Ready?'))
     self.assertListEqual(print_mock.mock_calls, [
         mock.call('\033[96mReady? [no/YES] \033[0m', end=' '),
         mock.call('\033[91mPlease respond with "no" or "yes".\033[0m'),
         mock.call('\033[96mReady? [no/YES] \033[0m', end=' ')
     ])
 def testAskWithCustomAnswersAndDefault(self, raw_input_mock, print_mock):
     raw_input_mock.side_effect = ['']
     self.assertFalse(
         cli_helpers.Ask('Ready?', {
             'foo': True,
             'bar': False
         },
                         default='bar'))
     print_mock.assert_called_once_with('\033[96mReady? [BAR/foo] \033[0m',
                                        end=' ')
Ejemplo n.º 5
0
    def AutoRun(self):
        # Let the quest begin...
        cli_helpers.Comment(
            'This script will help you update the recording of a story. It will go '
            'through the following stages, which you can also invoke manually via '
            'subcommand specified in parentheses:')
        cli_helpers.Comment('  - help create a new branch if needed')
        cli_helpers.Comment(
            '  - run story with live network connection (live)')
        cli_helpers.Comment('  - record story (record)')
        cli_helpers.Comment('  - replay the recording (replay)')
        cli_helpers.Comment(
            '  - upload the recording to Google Storage (upload)')
        cli_helpers.Comment(
            '  - upload CL with updated recording reference (review)')
        cli_helpers.Comment('  - trigger pinpoint tryjobs (pinpoint)')
        cli_helpers.Comment('  - post links to these jobs on the CL')
        cli_helpers.Comment(
            'Note that you can always enter prefix of the answer to any of the '
            'questions asked below, e.g. "y" for "yes" or "j" for "just-replay".'
        )

        # TODO(sergiyb): Detect if benchmark is not implemented and try to add it
        # automatically by copying the same benchmark without :<current-year> suffix
        # and changing name of the test, name of the benchmark and the year tag.

        # Create branch if needed.
        reuse_cl = False
        branch = _GetBranchName()
        if branch == 'HEAD':
            cli_helpers.Comment('You are not on a branch.')
            if not cli_helpers.Ask(
                    'Should script create a new branch automatically?'):
                cli_helpers.Comment(
                    'Please create a new branch and start this script again')
                return
            self._CreateBranch()
        else:
            issue = self._GetBranchIssueUrl()
            if issue is not None:
                issue_message = 'with an associated issue: %s' % issue
            else:
                issue_message = 'without an associated issue'
            cli_helpers.Comment(
                'You are on a branch {branch} {issue_message}. Please commit or '
                'stash any changes unrelated to the updated story before '
                'proceeding.',
                branch=branch,
                issue_message=issue_message)
            ans = cli_helpers.Ask(
                'Should the script create a new branch automatically, reuse '
                'existing one or exit?',
                answers=['create', 'reuse', 'exit'],
                default='create')
            if ans == 'create':
                self._CreateBranch()
            elif ans == 'reuse':
                reuse_cl = issue is not None
            elif ans == 'exit':
                return

        # Live run.
        live_out_file = self.LiveRun()
        cli_helpers.Comment(
            'Please inspect the live run results above for any errors.')
        ans = None
        while ans != 'continue':
            ans = cli_helpers.Ask(
                'Should I continue with recording, view metric results in a browser, '
                'view stdout/stderr output or stop?',
                ['continue', 'metrics', 'output', 'stop'],
                default='continue')
            if ans == 'stop':
                cli_helpers.Comment(
                    'Please update the story class to resolve the observed issues and '
                    'then run this script again.')
                return
            elif ans == 'metrics':
                _OpenBrowser('file://%s.results.html' % live_out_file)
            elif ans == 'output':
                _OpenEditor(live_out_file)

        # Record & replay.
        action = 'record'
        while action != 'continue':
            if action == 'record':
                self.RecordWpr()
            if action in ['record', 'just-replay']:
                replay_out_file = self.ReplayWpr()
                cli_helpers.Comment(
                    'Check that the console:error:all metrics above have low values '
                    'and are similar to the live run above.')
            if action == 'diff':
                diff_path = os.path.join(self.output_dir, 'live_replay.diff')
                with open(diff_path, 'w') as diff_file:
                    subprocess.call([
                        'diff', '--color',
                        self._FilterLogForDiff(live_out_file),
                        self._FilterLogForDiff(replay_out_file)
                    ],
                                    stdout=diff_file)
                _OpenEditor(diff_path)
            if action == 'stop':
                return
            action = cli_helpers.Ask(
                'Should I record and replay again, just replay, continue with '
                'uploading CL, stop and exit, or would you prefer to see diff '
                'between live/replay console logs?',
                ['record', 'just-replay', 'continue', 'stop', 'diff'],
                default='continue')

        # Upload WPR and create a WIP CL for the new story.
        if not self.UploadWpr():
            return
        while self.UploadCL(short_description=reuse_cl) != 0:
            if not cli_helpers.Ask('Upload failed. Should I try again?'):
                return

        # Gerrit needs some time to sync its backends, hence we sleep here for 5
        # seconds. Otherwise, pinpoint app may get an answer that the CL that we've
        # just uploaded does not exist yet.
        cli_helpers.Comment(
            'Waiting 20 seconds for the Gerrit backends to sync, so that Pinpoint '
            'app can detect the newly-created CL.')
        time.sleep(20)

        # Trigger pinpoint jobs.
        configs_to_trigger = None
        job_urls = []
        while True:
            new_job_urls, configs_to_trigger = self.StartPinpointJobs(
                configs_to_trigger)
            job_urls.extend(new_job_urls)
            if not configs_to_trigger or not cli_helpers.Ask(
                    'Do you want to try triggering the failed configs again?'):
                break

        if configs_to_trigger:
            if not cli_helpers.Ask(
                    'Some jobs failed to trigger. Do you still want to send created '
                    'CL for review?',
                    default='no'):
                return

        # Post a link to the triggered jobs, publish CL for review and open it.
        _SendCLForReview('Started the following Pinpoint jobs:\n%s' %
                         '\n'.join('  - %s' % url for url in job_urls))
        cli_helpers.Comment(
            'Posted a message with Pinpoint job URLs on the CL and sent it for '
            'review. Opening the CL in a browser...')
        _OpenBrowser(self._GetBranchIssueUrl())

        # Hooray, you won! :-)
        cli_helpers.Comment(
            'Thank you, you have successfully updated the recording for %s. Please '
            'wait for LGTM and land the created CL.' % self.story)
 def testAskWithInvalidDefaultAnswer(self):
     with self.assertRaises(ValueError):
         cli_helpers.Ask('Ready?', ['foo', 'bar'], 'baz')