#!/usr/bin/env vpython # Copyright 2019 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Tests for reproduce.py""" import json import os import unittest import reproduce # From vpython import mock class ReproduceTest(unittest.TestCase): @mock.patch('reproduce.fetch_step_log') def test_parse_failed_steps_ci_build(self, fetch_log_mock): b = reproduce.Build('ci/linux-rel/123') b.patch_info = (False,) fetch_log_mock.side_effect = [ json.dumps({ 'canonical_step_name': 'gl_unittests' }) ] self.assertEqual( b._parse_failed_steps([{ 'name': 'bot update', 'status': 'FAILURE', }, { 'name': 'base_unittests', 'status': 'SUCCESS', 'logs': [{ 'name': 'step_metadata', }], }, { 'name': 'gl_unittests', 'status': 'FAILURE', 'logs': [{ 'name': 'step_metadata', }], }]), ['gl_unittests']) @mock.patch('reproduce.fetch_step_log') def test_parse_failed_steps_try_build(self, fetch_log_mock): b = reproduce.Build('ci/linux-rel/123') b.patch_info = (True,) fetch_log_mock.side_effect = [ json.dumps({ 'canonical_step_name': 'gl_unittests' }) ] self.assertEqual( b._parse_failed_steps([{ 'name': 'bot update', 'status': 'FAILURE', }, { 'name': 'base_unittests (with patch)', 'status': 'FAILURE', 'logs': [{ 'name': 'step_metadata', }], }, { 'name': 'gl_unittests (with patch)', 'status': 'FAILURE', 'logs': [{ 'name': 'step_metadata', }], }, { 'name': 'base_unittests (retry shards with patch)', 'status': 'SUCCESS', 'logs': [{ 'name': 'step_metadata', }], }, { 'name': 'gl_unittests (retry shards with patch)', 'status': 'FAILURE', 'logs': [{ 'name': 'step_metadata', }], }]), ['gl_unittests']) @mock.patch('__builtin__.print') @mock.patch('reproduce.guess_host_dimensions') @mock.patch('__builtin__.raw_input') @mock.patch('reproduce.run_command') def test_run_suite_gtest(self, run_mock, input_mock, guess_mock, print_mock): # Just want to mock this so if something weird happens with the test it # doesn't block for input. del input_mock, print_mock guess_mock.side_effect = [{ 'os': 'Windows', }] b = reproduce.Build('luci.chromium.ci/linux-rel/1') b._mastername = 'chromium.linux' b._test_results = { 'gl_unittests': ['test.1', 'test.2'] } with mock.patch.object(b, 'guess_swarming_dimensions') as dims_mock: dims_mock.side_effect = [{ 'os': 'Windows', }] with mock.patch.object(b, 'lookup_suite') as lookup_mock: entry = reproduce.TestSuiteEntry( 'gl_unittests', [], False, {} ) lookup_mock.side_effect = [entry] b.run_suite('gl_unittests', '//out/Default') run_mock.assert_called_with([ os.path.join(reproduce.CHROMIUM_ROOT, 'tools', 'mb', 'mb.py'), 'run', '-m', 'chromium.linux', '-b', 'linux-rel', '//out/Default', 'gl_unittests', '--', '--gtest_filter=test.1:test.2' ]) @mock.patch('__builtin__.print') @mock.patch('reproduce.guess_host_dimensions') @mock.patch('__builtin__.raw_input') @mock.patch('reproduce.run_command') def test_run_suite_isolated_script(self, run_mock, input_mock, guess_mock, print_mock): # Just want to mock this so if something weird happens with the test it # doesn't block for input. del input_mock, print_mock guess_mock.side_effect = [{ 'os': 'Windows', }] b = reproduce.Build('luci.chromium.ci/linux-rel/1') b._mastername = 'chromium.mac' b._test_results = { 'blink_web_tests': ['test.1', 'test.2'] } fake_tempfile_name = '/tmp/foobartmp' with mock.patch.object(b, 'guess_swarming_dimensions') as dims_mock: dims_mock.side_effect = [{ 'os': 'Windows', }] with mock.patch('reproduce.os.unlink') as unlink_mock: with mock.patch.object(b, 'lookup_suite') as lookup_mock: entry = reproduce.TestSuiteEntry( 'blink_web_tests', [], True, {} ) lookup_mock.side_effect = [entry] with mock.patch('reproduce.tempfile.mkstemp') as temp_mock: # The script tries to close the file handler to the temp file when # it creates it. Mock that out. with mock.patch('reproduce.os.close'): temp_mock.side_effect = [(5, fake_tempfile_name)] b.run_suite('blink_web_tests', '//out/Default') unlink_mock.assert_called_with(fake_tempfile_name) run_mock.assert_called_with([ os.path.join(reproduce.CHROMIUM_ROOT, 'tools', 'mb', 'mb.py'), 'run', '-m', 'chromium.mac', '-b', 'linux-rel', '//out/Default', 'blink_web_tests', '--', '--isolated-script-test-filter=test.1::test.2', '--isolated-script-test-output', fake_tempfile_name, ]) @mock.patch('__builtin__.print') @mock.patch('reproduce.guess_host_dimensions') @mock.patch('__builtin__.raw_input') @mock.patch('reproduce.run_command') def test_run_suite_dimension_prompt(self, run_mock, input_mock, guess_mock, print_mock): guess_mock.side_effect = [{ 'os': 'Windows', }] b = reproduce.Build('luci.chromium.ci/linux-rel/1') input_mock.side_effect = ['n'] with mock.patch.object(b, 'guess_swarming_dimensions') as dims_mock: dims_mock.side_effect = [{ 'os': 'Linux', }] with mock.patch.object(b, 'lookup_suite') as lookup_mock: entry = reproduce.TestSuiteEntry( 'blink_web_tests', [], True, {} ) lookup_mock.side_effect = [entry] result = b.run_suite('blink_web_tests', '//out/Default') self.assertEqual(result, 1) input_mock.assert_called_with('>> ') self.assertEqual(print_mock.call_count, 2) run_mock.assert_not_called() @mock.patch('__builtin__.print') @mock.patch('reproduce.guess_host_dimensions') @mock.patch('__builtin__.raw_input') @mock.patch('reproduce.run_command') def test_run_suite_already_prompted(self, run_mock, input_mock, guess_mock, print_mock): """Makes sure that the script remembers dimension warning bypassing.""" # Just want to mock these so if something weird happens with the test it # doesn't block for input. del input_mock, print_mock guess_mock.side_effect = [{ 'os': 'Windows', }] b = reproduce.Build('luci.chromium.ci/linux-rel/1') b._mastername = 'chromium.linux' b._test_results = { 'gl_unittests': ['test.1', 'test.2'] } b.acked_dimensions.add('os') with mock.patch.object(b, 'guess_swarming_dimensions') as dims_mock: dims_mock.side_effect = [{ 'os': 'Linux', }] with mock.patch.object(b, 'lookup_suite') as lookup_mock: entry = reproduce.TestSuiteEntry( 'gl_unittests', [], False, {} ) lookup_mock.side_effect = [entry] b.run_suite('gl_unittests', '//out/Default') run_mock.assert_called_with([ os.path.join(reproduce.CHROMIUM_ROOT, 'tools', 'mb', 'mb.py'), 'run', '-m', 'chromium.linux', '-b', 'linux-rel', '//out/Default', 'gl_unittests', '--', '--gtest_filter=test.1:test.2' ]) if __name__ == '__main__': unittest.main()