#!/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()
