| #!/usr/bin/env python3 |
| # -*- coding: utf-8 -*- |
| # Copyright 2019 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. |
| |
| """Download image unittest.""" |
| |
| from __future__ import print_function |
| |
| import os |
| import unittest |
| import unittest.mock as mock |
| |
| import download_images |
| from cros_utils import command_executer |
| from cros_utils import logger |
| |
| import test_flag |
| |
| MOCK_LOGGER = logger.GetLogger(log_dir='', mock=True) |
| |
| |
| class ImageDownloaderTestcast(unittest.TestCase): |
| """The image downloader test class.""" |
| |
| def __init__(self, *args, **kwargs): |
| super(ImageDownloaderTestcast, self).__init__(*args, **kwargs) |
| self.called_download_image = False |
| self.called_uncompress_image = False |
| self.called_get_build_id = False |
| self.called_download_autotest_files = False |
| self.called_download_debug_file = False |
| |
| @mock.patch.object(os, 'makedirs') |
| @mock.patch.object(os.path, 'exists') |
| def test_download_image(self, mock_path_exists, mock_mkdirs): |
| |
| # Set mock and test values. |
| mock_cmd_exec = mock.Mock(spec=command_executer.CommandExecuter) |
| test_chroot = '/usr/local/home/chromeos' |
| test_build_id = 'lumpy-release/R36-5814.0.0' |
| image_path = ('gs://chromeos-image-archive/%s/chromiumos_test_image.tar.xz' |
| % test_build_id) |
| |
| downloader = download_images.ImageDownloader( |
| logger_to_use=MOCK_LOGGER, cmd_exec=mock_cmd_exec) |
| |
| # Set os.path.exists to always return False and run downloader |
| mock_path_exists.return_value = False |
| test_flag.SetTestMode(True) |
| self.assertRaises(download_images.MissingImage, downloader.DownloadImage, |
| test_chroot, test_build_id, image_path) |
| |
| # Verify os.path.exists was called twice, with proper arguments. |
| self.assertEqual(mock_path_exists.call_count, 2) |
| mock_path_exists.assert_called_with( |
| '/usr/local/home/chromeos/chroot/tmp/lumpy-release/' |
| 'R36-5814.0.0/chromiumos_test_image.bin') |
| mock_path_exists.assert_any_call( |
| '/usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0') |
| |
| # Verify we called os.mkdirs |
| self.assertEqual(mock_mkdirs.call_count, 1) |
| mock_mkdirs.assert_called_with( |
| '/usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0') |
| |
| # Verify we called RunCommand once, with proper arguments. |
| self.assertEqual(mock_cmd_exec.RunCommand.call_count, 1) |
| expected_args = ( |
| '/usr/local/home/chromeos/src/chromium/depot_tools/gsutil.py ' |
| 'cp gs://chromeos-image-archive/lumpy-release/R36-5814.0.0/' |
| 'chromiumos_test_image.tar.xz ' |
| '/usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0') |
| |
| mock_cmd_exec.RunCommand.assert_called_with(expected_args) |
| |
| # Reset the velues in the mocks; set os.path.exists to always return True. |
| mock_path_exists.reset_mock() |
| mock_cmd_exec.reset_mock() |
| mock_path_exists.return_value = True |
| |
| # Run downloader |
| downloader.DownloadImage(test_chroot, test_build_id, image_path) |
| |
| # Verify os.path.exists was called twice, with proper arguments. |
| self.assertEqual(mock_path_exists.call_count, 2) |
| mock_path_exists.assert_called_with( |
| '/usr/local/home/chromeos/chroot/tmp/lumpy-release/' |
| 'R36-5814.0.0/chromiumos_test_image.bin') |
| mock_path_exists.assert_any_call( |
| '/usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0') |
| |
| # Verify we made no RunCommand or ChrootRunCommand calls (since |
| # os.path.exists returned True, there was no work do be done). |
| self.assertEqual(mock_cmd_exec.RunCommand.call_count, 0) |
| self.assertEqual(mock_cmd_exec.ChrootRunCommand.call_count, 0) |
| |
| @mock.patch.object(os.path, 'exists') |
| def test_uncompress_image(self, mock_path_exists): |
| |
| # set mock and test values. |
| mock_cmd_exec = mock.Mock(spec=command_executer.CommandExecuter) |
| test_chroot = '/usr/local/home/chromeos' |
| test_build_id = 'lumpy-release/R36-5814.0.0' |
| |
| downloader = download_images.ImageDownloader( |
| logger_to_use=MOCK_LOGGER, cmd_exec=mock_cmd_exec) |
| |
| # Set os.path.exists to always return False and run uncompress. |
| mock_path_exists.return_value = False |
| self.assertRaises(download_images.MissingImage, downloader.UncompressImage, |
| test_chroot, test_build_id) |
| |
| # Verify os.path.exists was called once, with correct arguments. |
| self.assertEqual(mock_path_exists.call_count, 1) |
| mock_path_exists.assert_called_with( |
| '/usr/local/home/chromeos/chroot/tmp/lumpy-release/' |
| 'R36-5814.0.0/chromiumos_test_image.bin') |
| |
| # Verify RunCommand was called twice with correct arguments. |
| self.assertEqual(mock_cmd_exec.RunCommand.call_count, 2) |
| # Call 1, should have 2 arguments |
| self.assertEqual(len(mock_cmd_exec.RunCommand.call_args_list[0]), 2) |
| actual_arg = mock_cmd_exec.RunCommand.call_args_list[0][0] |
| expected_arg = ( |
| 'cd /usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0 ; ' |
| 'tar -Jxf chromiumos_test_image.tar.xz ',) |
| self.assertEqual(expected_arg, actual_arg) |
| # 2nd arg must be exception handler |
| except_handler_string = 'RunCommandExceptionHandler.HandleException' |
| self.assertTrue( |
| except_handler_string in repr(mock_cmd_exec.RunCommand.call_args_list[0] |
| [1])) |
| |
| # Call 2, should have 2 arguments |
| self.assertEqual(len(mock_cmd_exec.RunCommand.call_args_list[1]), 2) |
| actual_arg = mock_cmd_exec.RunCommand.call_args_list[1][0] |
| expected_arg = ( |
| 'cd /usr/local/home/chromeos/chroot/tmp/lumpy-release/R36-5814.0.0 ; ' |
| 'rm -f chromiumos_test_image.bin ',) |
| self.assertEqual(expected_arg, actual_arg) |
| # 2nd arg must be empty |
| self.assertTrue('{}' in repr(mock_cmd_exec.RunCommand.call_args_list[1][1])) |
| |
| # Set os.path.exists to always return True and run uncompress. |
| mock_path_exists.reset_mock() |
| mock_cmd_exec.reset_mock() |
| mock_path_exists.return_value = True |
| downloader.UncompressImage(test_chroot, test_build_id) |
| |
| # Verify os.path.exists was called once, with correct arguments. |
| self.assertEqual(mock_path_exists.call_count, 1) |
| mock_path_exists.assert_called_with( |
| '/usr/local/home/chromeos/chroot/tmp/lumpy-release/' |
| 'R36-5814.0.0/chromiumos_test_image.bin') |
| |
| # Verify RunCommand was not called. |
| self.assertEqual(mock_cmd_exec.RunCommand.call_count, 0) |
| |
| def test_run(self): |
| |
| # Set test arguments |
| test_chroot = '/usr/local/home/chromeos' |
| test_build_id = 'remote/lumpy/latest-dev' |
| test_empty_autotest_path = '' |
| test_empty_debug_path = '' |
| test_autotest_path = '/tmp/autotest' |
| test_debug_path = '/tmp/debug' |
| download_debug = True |
| |
| # Set values to test/check. |
| self.called_download_image = False |
| self.called_uncompress_image = False |
| self.called_get_build_id = False |
| self.called_download_autotest_files = False |
| self.called_download_debug_file = False |
| |
| # Define fake stub functions for Run to call |
| def FakeGetBuildID(unused_root, unused_xbuddy_label): |
| self.called_get_build_id = True |
| return 'lumpy-release/R36-5814.0.0' |
| |
| def GoodDownloadImage(root, build_id, image_path): |
| if root or build_id or image_path: |
| pass |
| self.called_download_image = True |
| return 'chromiumos_test_image.bin' |
| |
| def BadDownloadImage(root, build_id, image_path): |
| if root or build_id or image_path: |
| pass |
| self.called_download_image = True |
| raise download_images.MissingImage('Could not download image') |
| |
| def FakeUncompressImage(root, build_id): |
| if root or build_id: |
| pass |
| self.called_uncompress_image = True |
| return 0 |
| |
| def FakeDownloadAutotestFiles(root, build_id): |
| if root or build_id: |
| pass |
| self.called_download_autotest_files = True |
| return 'autotest' |
| |
| def FakeDownloadDebugFile(root, build_id): |
| if root or build_id: |
| pass |
| self.called_download_debug_file = True |
| return 'debug' |
| |
| # Initialize downloader |
| downloader = download_images.ImageDownloader(logger_to_use=MOCK_LOGGER) |
| |
| # Set downloader to call fake stubs. |
| downloader.GetBuildID = FakeGetBuildID |
| downloader.UncompressImage = FakeUncompressImage |
| downloader.DownloadImage = GoodDownloadImage |
| downloader.DownloadAutotestFiles = FakeDownloadAutotestFiles |
| downloader.DownloadDebugFile = FakeDownloadDebugFile |
| |
| # Call Run. |
| image_path, autotest_path, debug_path = downloader.Run( |
| test_chroot, test_build_id, test_empty_autotest_path, |
| test_empty_debug_path, download_debug) |
| |
| # Make sure it called both _DownloadImage and _UncompressImage |
| self.assertTrue(self.called_download_image) |
| self.assertTrue(self.called_uncompress_image) |
| # Make sure it called DownloadAutotestFiles |
| self.assertTrue(self.called_download_autotest_files) |
| # Make sure it called DownloadDebugFile |
| self.assertTrue(self.called_download_debug_file) |
| # Make sure it returned an image and autotest path returned from this call |
| self.assertTrue(image_path == 'chromiumos_test_image.bin') |
| self.assertTrue(autotest_path == 'autotest') |
| self.assertTrue(debug_path == 'debug') |
| |
| # Call Run with a non-empty autotest and debug path |
| self.called_download_autotest_files = False |
| self.called_download_debug_file = False |
| |
| image_path, autotest_path, debug_path = downloader.Run( |
| test_chroot, test_build_id, test_autotest_path, test_debug_path, |
| download_debug) |
| |
| # Verify that downloadAutotestFiles was not called |
| self.assertFalse(self.called_download_autotest_files) |
| # Make sure it returned the specified autotest path returned from this call |
| self.assertTrue(autotest_path == test_autotest_path) |
| # Make sure it returned the specified debug path returned from this call |
| self.assertTrue(debug_path == test_debug_path) |
| |
| # Reset values; Now use fake stub that simulates DownloadImage failing. |
| self.called_download_image = False |
| self.called_uncompress_image = False |
| self.called_download_autotest_files = False |
| self.called_download_debug_file = False |
| downloader.DownloadImage = BadDownloadImage |
| |
| # Call Run again. |
| self.assertRaises(download_images.MissingImage, downloader.Run, test_chroot, |
| test_autotest_path, test_debug_path, test_build_id, |
| download_debug) |
| |
| # Verify that UncompressImage and downloadAutotestFiles were not called, |
| # since _DownloadImage "failed" |
| self.assertTrue(self.called_download_image) |
| self.assertFalse(self.called_uncompress_image) |
| self.assertFalse(self.called_download_autotest_files) |
| self.assertFalse(self.called_download_debug_file) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |