#!/usr/bin/python2 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import mock import mox import unittest import common from autotest_lib.client.common_lib.cros import kernel_utils from autotest_lib.server.cros import provisioner class _StubUpdateError(provisioner._AttributedUpdateError): STUB_MESSAGE = 'Stub message' STUB_PATTERN = 'Stub pattern matched' _SUMMARY = 'Stub summary' _CLASSIFIERS = [ (STUB_MESSAGE, STUB_MESSAGE), ('Stub .*', STUB_PATTERN), ] def __init__(self, info, msg): super(_StubUpdateError, self).__init__('Stub %s' % info, msg) class TestErrorClassifications(unittest.TestCase): """Test error message handling in `_AttributedUpdateError`.""" def test_exception_message(self): """Test that the exception string includes its arguments.""" info = 'info marker' msg = 'an error message' stub = _StubUpdateError(info, msg) self.assertIn(info, str(stub)) self.assertIn(msg, str(stub)) def test_classifier_message(self): """Test that the exception classifier can match a simple string.""" info = 'info marker' stub = _StubUpdateError(info, _StubUpdateError.STUB_MESSAGE) self.assertNotIn(info, stub.failure_summary) self.assertIn(_StubUpdateError._SUMMARY, stub.failure_summary) self.assertIn(_StubUpdateError.STUB_MESSAGE, stub.failure_summary) def test_classifier_pattern(self): """Test that the exception classifier can match a regex.""" info = 'info marker' stub = _StubUpdateError(info, 'Stub this is a test') self.assertNotIn(info, stub.failure_summary) self.assertIn(_StubUpdateError._SUMMARY, stub.failure_summary) self.assertIn(_StubUpdateError.STUB_PATTERN, stub.failure_summary) def test_classifier_unmatched(self): """Test exception summary when no classifier matches.""" info = 'info marker' stub = _StubUpdateError(info, 'This matches no pattern') self.assertNotIn(info, stub.failure_summary) self.assertIn(_StubUpdateError._SUMMARY, stub.failure_summary) def test_host_update_error(self): """Sanity test the `HostUpdateError` classifier.""" exception = provisioner.HostUpdateError('chromeos6-row3-rack3-host19', 'Fake message') self.assertTrue(isinstance(exception.failure_summary, str)) def test_image_install_error(self): """Sanity test the `ImageInstallError` classifier.""" exception = provisioner.ImageInstallError( 'chromeos6-row3-rack3-host19', 'chromeos4-devserver7.cros', 'Fake message') self.assertTrue(isinstance(exception.failure_summary, str)) def test_new_build_update_error(self): """Sanity test the `NewBuildUpdateError` classifier.""" exception = provisioner.NewBuildUpdateError('R68-10621.0.0', 'Fake message') self.assertTrue(isinstance(exception.failure_summary, str)) class TestProvisioner(mox.MoxTestBase): """Test provisioner module.""" def testParseBuildFromUpdateUrlwithUpdate(self): """Test that we properly parse the build from an update_url.""" update_url = ('http://172.22.50.205:8082/update/lumpy-release/' 'R27-3837.0.0') expected_value = 'lumpy-release/R27-3837.0.0' self.assertEqual(provisioner.url_to_image_name(update_url), expected_value) def testGetRemoteScript(self): """Test _get_remote_script() behaviors.""" update_url = ('http://172.22.50.205:8082/update/lumpy-chrome-perf/' 'R28-4444.0.0-b2996') script_name = 'fubar' local_script = '/usr/local/bin/%s' % script_name host = self.mox.CreateMockAnything() cros_provisioner = provisioner.ChromiumOSProvisioner(update_url, host=host) host.path_exists(local_script).AndReturn(True) self.mox.ReplayAll() # Simple case: file exists on DUT self.assertEqual(cros_provisioner._get_remote_script(script_name), local_script) self.mox.VerifyAll() self.mox.ResetAll() fake_shell = '/bin/ash' tmp_script = '/usr/local/tmp/%s' % script_name fake_result = self.mox.CreateMockAnything() fake_result.stdout = '#!%s\n' % fake_shell host.path_exists(local_script).AndReturn(False) host.run(mox.IgnoreArg()) host.run(mox.IgnoreArg()).AndReturn(fake_result) self.mox.ReplayAll() # Complicated case: script not on DUT, so try to download it. self.assertEqual(cros_provisioner._get_remote_script(script_name), '%s %s' % (fake_shell, tmp_script)) self.mox.VerifyAll() class TestProvisioner2(unittest.TestCase): """Another test for provisioner module that using mock.""" def testAlwaysRunQuickProvision(self): """Tests that we call quick provsion for all kinds of builds.""" image = 'foo-whatever/R65-1234.5.6' devserver = 'http://mock_devserver' provisioner.dev_server = mock.MagicMock() provisioner.metrics = mock.MagicMock() host = mock.MagicMock() update_url = '%s/update/%s' % (devserver, image) cros_provisioner = provisioner.ChromiumOSProvisioner(update_url, host) cros_provisioner.check_update_status = mock.MagicMock() kernel_utils.verify_kernel_state_after_update = mock.MagicMock() kernel_utils.verify_kernel_state_after_update.return_value = 3 kernel_utils.verify_boot_expectations = mock.MagicMock() cros_provisioner.run_provision() host.run.assert_any_call( '/usr/local/bin/quick-provision --noreboot %s ' '%s/download/chromeos-image-archive' % (image, devserver)) if __name__ == '__main__': unittest.main()