Commit 944829b6 authored by Sergiy Belozorov's avatar Sergiy Belozorov Committed by Commit Bot

Reland "Implement auto command in the update_wpr script"

This is a reland of 68ef4428

Original change's description:
> Implement auto command in the update_wpr script
>
> R=perezju@chromium.org
>
> Bug: 895891
> Change-Id: Ib4b6b0ea123b64d0333cb0911930358dcb3ff2ad
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1496871
> Commit-Queue: Sergiy Belozorov <sergiyb@chromium.org>
> Reviewed-by: Juan Antonio Navarro Pérez <perezju@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#637677}

Bug: 895891, 938487
Change-Id: I4dbf7e1adee233598a78772024d71dfebc23e562
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1504014Reviewed-by: default avatarJuan Antonio Navarro Pérez <perezju@chromium.org>
Commit-Queue: Sergiy Belozorov <sergiyb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638049}
parent ade26b75
...@@ -35,6 +35,7 @@ class UpdateWprTest(unittest.TestCase): ...@@ -35,6 +35,7 @@ class UpdateWprTest(unittest.TestCase):
datetime.now.return_value.strftime.return_value = '<tstamp>' datetime.now.return_value.strftime.return_value = '<tstamp>'
mock.patch('tempfile.mkdtemp', return_value='/tmp/dir').start() mock.patch('tempfile.mkdtemp', return_value='/tmp/dir').start()
mock.patch('random.randint', return_value=1234).start()
mock.patch('core.cli_helpers.Fatal').start() mock.patch('core.cli_helpers.Fatal').start()
mock.patch('core.cli_helpers.Error').start() mock.patch('core.cli_helpers.Error').start()
mock.patch('core.cli_helpers.Step').start() mock.patch('core.cli_helpers.Step').start()
...@@ -47,6 +48,7 @@ class UpdateWprTest(unittest.TestCase): ...@@ -47,6 +48,7 @@ class UpdateWprTest(unittest.TestCase):
mock.patch(WPR_UPDATER + 'RECORD_WPR', '.../record_wpr').start() mock.patch(WPR_UPDATER + 'RECORD_WPR', '.../record_wpr').start()
mock.patch('os.path.join', lambda *parts: '/'.join(parts)).start() mock.patch('os.path.join', lambda *parts: '/'.join(parts)).start()
mock.patch('os.path.exists', return_value=True).start() mock.patch('os.path.exists', return_value=True).start()
mock.patch('time.sleep').start()
self.wpr_updater = update_wpr.WprUpdater(argparse.Namespace( self.wpr_updater = update_wpr.WprUpdater(argparse.Namespace(
story='<story>', device_id=None, repeat=1, binary=None, bug_id=None, story='<story>', device_id=None, repeat=1, binary=None, bug_id=None,
...@@ -58,13 +60,13 @@ class UpdateWprTest(unittest.TestCase): ...@@ -58,13 +60,13 @@ class UpdateWprTest(unittest.TestCase):
def testMain(self): def testMain(self):
wpr_updater_cls = mock.patch(WPR_UPDATER + 'WprUpdater').start() wpr_updater_cls = mock.patch(WPR_UPDATER + 'WprUpdater').start()
update_wpr.Main([ update_wpr.Main([
'live',
'-s', 'foo:bar:story:2019', '-s', 'foo:bar:story:2019',
'-d', 'H2345234FC33', '-d', 'H2345234FC33',
'--binary', '<binary>', '--binary', '<binary>',
'-b', '1234', '-b', '1234',
'-r', 'test_user1@chromium.org', '-r', 'test_user1@chromium.org',
'-r', 'test_user2@chromium.org', '-r', 'test_user2@chromium.org',
'live',
]) ])
self.assertListEqual(wpr_updater_cls.mock_calls, [ self.assertListEqual(wpr_updater_cls.mock_calls, [
mock.call(argparse.Namespace( mock.call(argparse.Namespace(
...@@ -90,6 +92,83 @@ class UpdateWprTest(unittest.TestCase): ...@@ -90,6 +92,83 @@ class UpdateWprTest(unittest.TestCase):
self.wpr_updater.Cleanup() self.wpr_updater.Cleanup()
rmtree.assert_called_once_with('/tmp/dir', ignore_errors=True) rmtree.assert_called_once_with('/tmp/dir', ignore_errors=True)
def testGetBranchName(self):
self._check_output.return_value = 'master'
self.assertEqual(update_wpr._GetBranchName(), 'master')
self._check_output.assert_called_once_with(
['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
def testCreateBranch(self):
self.wpr_updater._CreateBranch()
self._check_call.assert_called_once_with(
['git', 'new-branch', 'update-wpr--story--1234'])
def testSendCLForReview(self):
update_wpr._SendCLForReview('comment')
self._check_call.assert_called_once_with(
['git', 'cl', 'comments', '--publish', '--add-comment', 'comment'])
@mock.patch('os.dup')
@mock.patch('os.close')
@mock.patch('os.dup2')
@mock.patch('webbrowser.open')
def testOpenBrowser(self, webbrowser_open, os_dup2, os_close, os_dup):
del os_dup2, os_close, os_dup # unused
update_wpr._OpenBrowser('<url>')
webbrowser_open.assert_called_once_with('<url>')
def testAutoRun(self):
# Mock low-level methods tested above.
mock.patch(WPR_UPDATER + '_GetBranchName', return_value='HEAD').start()
mock.patch(
WPR_UPDATER + 'WprUpdater._GetBranchIssueUrl',
return_value='<issue-url>').start()
mock.patch(WPR_UPDATER + 'WprUpdater._CreateBranch').start()
send_cl_for_review = mock.patch(WPR_UPDATER + '_SendCLForReview').start()
open_browser = mock.patch(WPR_UPDATER + '_OpenBrowser').start()
# Mock high-level methods tested below.
live_run = mock.patch(WPR_UPDATER + 'WprUpdater.LiveRun').start()
record_wpr = mock.patch(WPR_UPDATER + 'WprUpdater.RecordWpr').start()
replay_wpr = mock.patch(WPR_UPDATER + 'WprUpdater.ReplayWpr').start()
upload_wpr = mock.patch(
WPR_UPDATER + 'WprUpdater.UploadWpr', return_value=True).start()
upload_cl = mock.patch(
WPR_UPDATER + 'WprUpdater.UploadCL', return_value=0).start()
start_pinpoint_jobs = mock.patch(
WPR_UPDATER + 'WprUpdater.StartPinpointJobs',
return_value=(['<url1>', '<url2>', '<url3>'], [])).start()
# Mock user interaction.
mock.patch('core.cli_helpers.Ask', side_effect=[
True, # Should script create a new branch automatically?
'continue', # Should I continue with recording, ...?
'continue', # Should I record and replay again, ...?
]).start()
self.wpr_updater.AutoRun()
# Run once to make sure story works.
live_run.assert_called_once_with()
# Run again to create a recording.
record_wpr.assert_called_once_with()
# Replay to verify the recording.
replay_wpr.assert_called_once_with()
# Upload the recording.
upload_wpr.assert_called_once_with()
# Upload the CL.
upload_cl.assert_called_once_with(short_description=False)
# Start pinpoint jobs to verify recording works on the bots.
start_pinpoint_jobs.assert_called_once_with(None)
# Send CL for review with a comment listing triggered Pinpoint jobs.
send_cl_for_review.assert_called_once_with(
'Started the following Pinpoint jobs:\n'
' - <url1>\n'
' - <url2>\n'
' - <url3>')
# Open the CL in browser,
open_browser.assert_called_once_with('<issue-url>')
def testLiveRun(self): def testLiveRun(self):
run_benchmark = mock.patch( run_benchmark = mock.patch(
WPR_UPDATER + 'WprUpdater._RunSystemHealthMemoryBenchmark', WPR_UPDATER + 'WprUpdater._RunSystemHealthMemoryBenchmark',
......
...@@ -137,6 +137,15 @@ def Ask(question, answers=None, default=None): ...@@ -137,6 +137,15 @@ def Ask(question, answers=None, default=None):
', '.join(choices[:-1]), choices[-1])) ', '.join(choices[:-1]), choices[-1]))
def Prompt(question, accept_empty=False):
while True:
print(Colored(question, color='cyan'))
answer = raw_input().strip()
if answer or accept_empty:
return answer
Error('Please enter non-empty answer')
def CheckLog(command, log_path, env=None): def CheckLog(command, log_path, env=None):
"""Executes a command and writes its stdout to a specified log file. """Executes a command and writes its stdout to a specified log file.
......
...@@ -11,6 +11,7 @@ from core import cli_helpers ...@@ -11,6 +11,7 @@ from core import cli_helpers
from telemetry import decorators from telemetry import decorators
@decorators.Disabled('android', 'chromeos')
class CLIHelpersTest(unittest.TestCase): class CLIHelpersTest(unittest.TestCase):
def testUnsupportedColor(self): def testUnsupportedColor(self):
with self.assertRaises(AssertionError): with self.assertRaises(AssertionError):
...@@ -85,8 +86,6 @@ class CLIHelpersTest(unittest.TestCase): ...@@ -85,8 +86,6 @@ class CLIHelpersTest(unittest.TestCase):
mock.call('\033[96mReady? [foo/bar] \033[0m', end=' ') mock.call('\033[96mReady? [foo/bar] \033[0m', end=' ')
]) ])
# https://crbug.com/937654.
@decorators.Disabled('android', 'chromeos')
def testAskWithInvalidDefaultAnswer(self): def testAskWithInvalidDefaultAnswer(self):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
cli_helpers.Ask('Ready?', ['foo', 'bar'], 'baz') cli_helpers.Ask('Ready?', ['foo', 'bar'], 'baz')
...@@ -158,6 +157,16 @@ class CLIHelpersTest(unittest.TestCase): ...@@ -158,6 +157,16 @@ class CLIHelpersTest(unittest.TestCase):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
cli_helpers.Run('cmd with args') cli_helpers.Run('cmd with args')
@mock.patch('__builtin__.print')
@mock.patch('__builtin__.raw_input')
def testPrompt(self, raw_input_mock, print_mock):
raw_input_mock.side_effect = ['', '42']
self.assertEqual(cli_helpers.Prompt(
'What is the ultimate meaning of life, universe and everything?'), '42')
self.assertEqual(raw_input_mock.call_count, 2)
self.assertEqual(print_mock.call_count, 3)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment