def testServerErrorPickleable(self): error = request.ServerError('api', *Response(500, 'Oops, I had a problem!')) error = pickle.loads(pickle.dumps(error)) self.assertIsInstance(error, request.ServerError) self.assertEqual(error.request, 'api') self.assertEqual(error.response.status, 500) self.assertEqual(error.content, 'Oops, I had a problem!')
class UpdateWprTest(unittest.TestCase): def setUp(self): self.maxDiff = None self._check_log = mock.patch('core.cli_helpers.CheckLog').start() self._run = mock.patch('core.cli_helpers.Run').start() self._check_output = mock.patch('subprocess.check_output').start() self._check_call = mock.patch('subprocess.check_call').start() self._info = mock.patch('core.cli_helpers.Info').start() self._comment = mock.patch('core.cli_helpers.Comment').start() self._open = mock.patch('__builtin__.open').start() datetime = mock.patch('datetime.datetime').start() datetime.now.return_value.strftime.return_value = '<tstamp>' 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.Error').start() mock.patch('core.cli_helpers.Step').start() mock.patch('os.environ').start().copy.return_value = {} mock.patch(WPR_UPDATER + 'SRC_ROOT', '...').start() mock.patch(WPR_UPDATER + 'RESULTS2JSON', '.../results2json').start() mock.patch(WPR_UPDATER + 'HISTOGRAM2CSV', '.../histograms2csv').start() mock.patch(WPR_UPDATER + 'RUN_BENCHMARK', '.../run_benchmark').start() mock.patch(WPR_UPDATER + 'DATA_DIR', '.../data/dir').start() mock.patch(WPR_UPDATER + 'RECORD_WPR', '.../record_wpr').start() mock.patch('os.path.join', lambda *parts: '/'.join(parts)).start() mock.patch('os.path.exists', return_value=True).start() mock.patch('time.sleep').start() self.wpr_updater = update_wpr.WprUpdater( argparse.Namespace(story='<story>', device_id=None, repeat=1, binary=None, bug_id=None, reviewers=['*****@*****.**'])) def tearDown(self): mock.patch.stopall() @mock.patch(WPR_UPDATER + 'WprUpdater') def testMain(self, wpr_updater_cls): update_wpr.Main([ '-s', 'foo:bar:story:2019', '-d', 'H2345234FC33', '--binary', '<binary>', '-b', '1234', '-r', '*****@*****.**', '-r', '*****@*****.**', 'live', ]) self.assertListEqual(wpr_updater_cls.mock_calls, [ mock.call( argparse.Namespace(binary='<binary>', command='live', device_id='H2345234FC33', repeat=1, story='foo:bar:story:2019', bug_id='1234', reviewers=[ '*****@*****.**', '*****@*****.**' ])), mock.call().LiveRun(), mock.call().Cleanup(), ]) @mock.patch('shutil.rmtree') @mock.patch('core.cli_helpers.Ask', return_value=False) def testCleanupManual(self, ask, rmtree): del ask # Unused. self.wpr_updater.Cleanup() self._comment.assert_called_once_with( 'No problem. All logs will remain in /tmp/dir - feel free to remove ' 'that directory when done.') rmtree.assert_not_called() @mock.patch('shutil.rmtree') @mock.patch('core.cli_helpers.Ask', return_value=True) def testCleanupAutomatic(self, ask, rmtree): del ask # Unused. self.wpr_updater.created_branch = 'foo' self.wpr_updater.Cleanup() rmtree.assert_called_once_with('/tmp/dir', ignore_errors=True) def testGetBranchName(self): self._check_output.return_value = 'master\n' 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._run.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>') # Mock low-level methods tested above. @mock.patch(WPR_UPDATER + '_GetBranchName', return_value='HEAD') @mock.patch(WPR_UPDATER + 'WprUpdater._GetBranchIssueUrl', return_value='<issue-url>') @mock.patch(WPR_UPDATER + 'WprUpdater._CreateBranch') @mock.patch(WPR_UPDATER + '_SendCLForReview') @mock.patch(WPR_UPDATER + '_OpenBrowser') # Mock high-level methods tested below. @mock.patch(WPR_UPDATER + 'WprUpdater.LiveRun') @mock.patch(WPR_UPDATER + 'WprUpdater.RecordWpr') @mock.patch(WPR_UPDATER + 'WprUpdater.ReplayWpr') @mock.patch(WPR_UPDATER + 'WprUpdater.UploadWpr', return_value=True) @mock.patch(WPR_UPDATER + 'WprUpdater.UploadCL', return_value=0) @mock.patch(WPR_UPDATER + 'WprUpdater.StartPinpointJobs', return_value=(['<url1>', '<url2>', '<url3>'], [])) # 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, ...? def testAutoRun(self, ask, start_pinpoint_jobs, upload_cl, upload_wpr, replay_wpr, record_wpr, live_run, open_browser, send_cl_for_review, create_branch, get_branch_issue_url, get_branch_name): del ask, create_branch, get_branch_issue_url, get_branch_name # Unused. 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>') @mock.patch(WPR_UPDATER + 'WprUpdater._RunSystemHealthMemoryBenchmark', return_value='<out-file>') @mock.patch(WPR_UPDATER + '_PrintRunInfo') def testLiveRun(self, print_run_info, run_benchmark): self.wpr_updater.LiveRun() run_benchmark.assert_called_once_with(log_name='live', live=True) print_run_info.assert_called_once_with('<out-file>', chrome_log_file=True) @mock.patch('os.rename') def testRunBenchmark(self, rename): self._check_output.return_value = ' <chrome-log>' self.wpr_updater._RunSystemHealthMemoryBenchmark('<log_name>', True) # Check correct arguments when running benchmark. self._check_log.assert_called_once_with( [ '.../run_benchmark', 'run', '--browser=system', 'system_health.memory_desktop', '--output-format=html', '--show-stdout', '--reset-results', '--story-filter=^\\<story\\>$', '--browser-logging-verbosity=verbose', '--pageset-repeat=1', '--output-dir', '/tmp/dir', '--use-live-sites' ], env={'LC_ALL': 'en_US.UTF-8'}, log_path='/tmp/dir/<log_name>_<tstamp>') # Check logs are correctly extracted. self.assertListEqual(rename.mock_calls, [ mock.call('/tmp/dir/results.html', '/tmp/dir/<log_name>_<tstamp>.results.html'), mock.call('<chrome-log>', '/tmp/dir/<log_name>_<tstamp>.chrome.log'), ]) def testPrintResultsHTMLInfo(self): self._open.return_value.__enter__.return_value.readlines.return_value = [ 'console:error:network,foo,bar', 'console:error:js,foo,bar', 'console:error:security,foo,bar', ] update_wpr._PrintResultsHTMLInfo('<outfile>') self.assertListEqual(self._run.mock_calls, [ mock.call([ '.../results2json', '<outfile>.results.html', '<outfile>.hist.json' ], env={'LC_ALL': 'en_US.UTF-8'}), mock.call([ '.../histograms2csv', '<outfile>.hist.json', '<outfile>.hist.csv' ], env={'LC_ALL': 'en_US.UTF-8'}), ]) self._open.assert_called_once_with('<outfile>.hist.csv') self.assertListEqual(self._info.mock_calls, [ mock.call('Metrics results: file://{path}', path='<outfile>.results.html'), mock.call(' [console:error:network]: bar'), mock.call(' [console:error:js]: bar'), mock.call(' [console:error:security]: bar') ]) def testCountLogLines(self): self._open.return_value.__enter__.return_value = [ 'foo yy', 'xx foobar', 'baz' ] self.assertEqual(update_wpr._CountLogLines('<out-file>', 'foo.*'), 2) self._open.assert_called_once_with('<out-file>') def testExtractMissingURLsFromLog(self): self._open.return_value.__enter__.return_value = [ 'some-timestamp [network]: Failed to load resource: the server responded ' 'with a status of 404 () http://www.google.com/1\n', '[network]: Failed to load resource: the server responded with a status ' 'of 404 () https://www.google.com/2 foobar\n', 'foobar', ] self.assertListEqual( update_wpr._ExtractMissingURLsFromLog('<log-file>'), ['http://www.google.com/1', 'https://www.google.com/2']) self._open.assert_called_once_with('<log-file>') @mock.patch(WPR_UPDATER + '_PrintResultsHTMLInfo', side_effect=[Exception()]) @mock.patch(WPR_UPDATER + '_CountLogLines', return_value=0) def testPrintRunInfo(self, count_log_lines, print_results): del count_log_lines # Unused. self._check_output.return_value = '0\n' update_wpr._PrintRunInfo('<outfile>', chrome_log_file=True, results_details=True) print_results.assert_called_once_with('<outfile>') self.assertListEqual(self._info.mock_calls, [ mock.call('Stdout/Stderr Log: <outfile>'), mock.call('Chrome Log: <outfile>.chrome.log'), mock.call(' Total output: 0'), mock.call(' Total Console: 0'), mock.call(' [security]: 0'), mock.call(' [network]: 0'), ]) @mock.patch('json.load', return_value={'issue_url': '<url>'}) def testGetBranchIssueUrl(self, json_load): del json_load # Unused. self.assertEqual(self.wpr_updater._GetBranchIssueUrl(), '<url>') self._check_output.assert_called_once_with( ['git', 'cl', 'issue', '--json', '/tmp/dir/git_cl_issue.json']) @mock.patch('os.remove') def testDeleteExistingWpr(self, os_remove): self._open.return_value.__enter__.return_value.read.return_value = ( '{"archives": {"<story>": {"DEFAULT": "<archive>"}}}') self.wpr_updater._DeleteExistingWpr() self.assertListEqual(os_remove.mock_calls, [ mock.call('.../data/dir/<archive>'), mock.call('.../data/dir/<archive>.sha1'), ]) @mock.patch('os.remove') def testDoesNotDeleteReusedWpr(self, os_remove): self._open.return_value.__enter__.return_value.read.return_value = ( '{"archives": {"<story>": {"DEFAULT": "<archive>"}, ' '"<other>": {"DEFAULT": "foo", "linux": "<arhive>"}}}') self.wpr_updater._DeleteExistingWpr() os_remove.assert_not_called() @mock.patch(WPR_UPDATER + '_ExtractMissingURLsFromLog', return_value=['foo', 'bar']) @mock.patch(WPR_UPDATER + 'WprUpdater._ExistingWpr', return_value='<archive>') @mock.patch('py_utils.binary_manager.BinaryManager', autospec=True) def testAddMissingURLsToArchive(self, bmanager, existing_wpr, extract_mock): del existing_wpr # Unused. bmanager.return_value.FetchPath.return_value = '<wpr-go-bin>' self.wpr_updater._AddMissingURLsToArchive('<replay-log>') extract_mock.assert_called_once_with('<replay-log>') self._check_call.assert_called_once_with( ['<wpr-go-bin>', 'add', '<archive>', 'foo', 'bar']) @mock.patch(WPR_UPDATER + '_PrintRunInfo') @mock.patch(WPR_UPDATER + 'WprUpdater._DeleteExistingWpr') def testRecordWprDesktop(self, delete_existing_wpr, print_run_info): del delete_existing_wpr # Unused. self.wpr_updater.RecordWpr() self._check_log.assert_called_once_with( [ '.../record_wpr', '--story-filter=^\\<story\\>$', '--browser=system', 'desktop_system_health_story_set' ], env={'LC_ALL': 'en_US.UTF-8'}, log_path='/tmp/dir/record_<tstamp>') print_run_info.assert_called_once_with('/tmp/dir/record_<tstamp>', chrome_log_file=True, results_details=False) @mock.patch(WPR_UPDATER + '_PrintRunInfo') @mock.patch(WPR_UPDATER + 'WprUpdater._DeleteExistingWpr') def testRecordWprMobile(self, delete_existing_wpr, print_run_info): del delete_existing_wpr # Unused. self.wpr_updater.device_id = '<serial>' self.wpr_updater.RecordWpr() self._check_log.assert_called_once_with( [ '.../record_wpr', '--story-filter=^\\<story\\>$', '--browser=android-system-chrome', '--device=<serial>', 'mobile_system_health_story_set' ], env={'LC_ALL': 'en_US.UTF-8'}, log_path='/tmp/dir/record_<tstamp>') print_run_info.assert_called_once_with('/tmp/dir/record_<tstamp>', chrome_log_file=False, results_details=False) @mock.patch(WPR_UPDATER + '_PrintRunInfo') @mock.patch(WPR_UPDATER + 'WprUpdater._RunSystemHealthMemoryBenchmark', return_value='<out-file>') def testReplayWpr(self, run_benchmark, print_run_info): self.wpr_updater.ReplayWpr() run_benchmark.assert_called_once_with(log_name='replay', live=False) print_run_info.assert_called_once_with('<out-file>', chrome_log_file=True) @mock.patch(WPR_UPDATER + 'WprUpdater._ExistingWpr', return_value=('<archive>', False)) def testUploadWPR(self, existing_wpr): del existing_wpr # Unused. self.wpr_updater.UploadWpr() self.assertListEqual(self._run.mock_calls, [ mock.call([ 'upload_to_google_storage.py', '--bucket=chrome-partner-telemetry', '<archive>' ]), mock.call(['git', 'add', '<archive>.sha1']) ]) @mock.patch('subprocess.call', return_value=1) def testUploadCL(self, subprocess_call): del subprocess_call # Unused. self._run.return_value = 42 self.assertEqual(self.wpr_updater.UploadCL(), 42) self.assertListEqual(self._run.mock_calls, [ mock.call([ 'git', 'commit', '-a', '-m', 'Add <story> system health story\n\n' 'This CL was created automatically with tools/perf/update_wpr script' ]), mock.call([ 'git', 'cl', 'upload', '--reviewers', '*****@*****.**', '--force', '--message-file', '/tmp/dir/commit_message.tmp' ], ok_fail=True), ]) @mock.patch(WPR_UPDATER + 'WprUpdater._GetBranchIssueUrl', return_value='<issue-url>') @mock.patch('core.services.pinpoint_service.NewJob', return_value={'jobUrl': '<url>'}) def testStartPinPointJobsDesktop(self, new_job, get_branch_issue_url): del get_branch_issue_url # Unused. self.assertEqual(self.wpr_updater.StartPinpointJobs(), (['<url>', '<url>', '<url>'], [])) new_job.assert_called_with( start_git_hash='HEAD', end_git_hash='HEAD', target='performance_test_suite', patch='<issue-url>', bug_id='', story='<story>', extra_test_args='--pageset-repeat=1', configuration='mac-10_12_laptop_low_end-perf', benchmark='system_health.common_desktop') self.assertEqual(new_job.call_count, 3) @mock.patch(WPR_UPDATER + 'WprUpdater._GetBranchIssueUrl', return_value='<issue-url>') @mock.patch('core.services.pinpoint_service.NewJob', side_effect=request.ServerError(mock.Mock(), mock.Mock(status=500), '')) def testStartPinPointJobsMobileFail(self, new_job, get_branch_issue_url): del get_branch_issue_url # Unused. self.wpr_updater.device_id = '<serial>' self.assertEqual(self.wpr_updater.StartPinpointJobs(['<config>']), ([], ['<config>'])) new_job.assert_called_once_with( start_git_hash='HEAD', end_git_hash='HEAD', target='performance_test_suite', patch='<issue-url>', bug_id='', story='<story>', extra_test_args='--pageset-repeat=1', configuration='<config>', benchmark='system_health.common_mobile')
def testErrorMessageToString(self): content = u'Something went wrong. That\u2019s all we know.'.encode( 'utf-8') error = request.ServerError('/endpoint', *Response(500, content)) self.assertIn('Something went wrong.', str(error))
def testJsonErrorMessageToString(self): message = u'Something went wrong. That\u2019s all we know.' error = request.ServerError( '/endpoint', *Response(500, json.dumps({'error': message}))) self.assertIn('Something went wrong.', str(error))