def test_exception_on_failed_make_install(self, mock_isdir, mock_makedirs, mock_cwd, mock_chdir, mock_popen, mock_open): mock_isdir.side_effect = [ True, # Global package cache first access False, # Local package cache first access True, # Global package cache second access True, # Local package cache second access True, # Global package cache third access True # Local package cache third access ] mock_popen.side_effect = [ MockProcess("CMAKE_OUT", "ERR", 0), MockProcess("MAKE_OUT", "ERR", 0), MockProcess("MAKE_INSTALL_OUT", "ERR", 1) ] self.assertRaises(PackageInstallerException, self.installer.install_packages, self.package_list) popen_calls = [ call([ "cmake", ".", "-DCMAKE_INSTALL_PREFIX=" + self.conf["LocalPackageCache"] ], stdout=subprocess.PIPE, stderr=subprocess.PIPE), call(["make"], stdout=subprocess.PIPE, stderr=subprocess.PIPE), call(["make", "install"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) ] mock_popen.assert_has_calls(popen_calls, any_order=False)
def test_build_happy_case(self, mock_makedirs, mock_popen, mock_isdir, mock_chdir, mock_getcwd): # Mock popen calls p_cmake = MockProcess("OUT", "ERR", TestCppCmake.EXIT_SUCCESS) p_make = MockProcess("OUT", "ERR", TestCppCmake.EXIT_SUCCESS) # Argument captors makedirs_calls = [call(self.config_obj["BuildDir"])] isdir_calls = [call(self.config_obj["BuildDir"])] chdir_calls = [ call(self.config_obj["BuildDir"]), call(self.config_obj["ProjectRoot"]) ] popen_calls = [ call([ "cmake", self.config_obj["ProjectRoot"], "-DPACKAGE_CACHE=" + self.config_obj["LocalPackageCache"] ], stdout=subprocess.PIPE), call(["make"]) ] mock_popen.side_effect = [p_cmake, p_make] self.builder.build() mock_isdir.assert_has_calls(isdir_calls, any_order=False) mock_makedirs.assert_has_calls(makedirs_calls, any_order=False) mock_chdir.assert_has_calls(chdir_calls, any_order=False) mock_popen.assert_has_calls(popen_calls, any_order=False)
def test_exception_on_failed_wget(self, mock_file, mock_tarfile, mock_popen, mock_makedirs, mock_isdir, mock_isfile): wget_1 = MockProcess("ERR", "ERROR occured", TestPackageDownloader.EXIT_FAILURE) wget_2 = MockProcess("ERR", "OUT", TestPackageDownloader.EXIT_SUCCESS) mock_popen.side_effect = [wget_1, wget_2] self.assertRaises(PackageDownloaderException, self.downloader.download_and_extract, self.package_list)
def test_exception_on_extract_fail(self, mock_file, mock_tarfile, mock_popen, mock_makedirs, mock_isdir, mock_isfile): wget_1 = MockProcess("ERR", "OUT", TestPackageDownloader.EXIT_SUCCESS) wget_2 = MockProcess("ERR", "OUT", TestPackageDownloader.EXIT_SUCCESS) mock_popen.side_effect = [wget_1, wget_2] tarfile_pointer = MockTarfilePointer() mock_tarfile.side_effect = [tarfile_pointer] tarfile_pointer.set_exception() self.assertRaises(PackageDownloaderException, self.downloader.download_and_extract, self.package_list)
def test_exception_on_failed_snapcraft_command(self, mock_temp_dir, mock_makedirs, mock_open, mock_getcwd, mock_chdir, mock_subprocess, mock_listdir, mock_copyfile, mock_isfile): # Set up mocks mock_temp_dir.side_effect = [ MockTemporaryDirectory("MY_TEMPORARY_DIRECTORY") ] snap_yaml_fp = MockFilePointer() mock_open.side_effect = [snap_yaml_fp] snap_process = MockProcess("OUT", "ERR", 1) mock_subprocess.side_effect = [snap_process] dirs = ["papaya.snap"] mock_listdir.side_effect = [dirs] # Make the package call conf = copy.deepcopy(self.conf) for key in self.package_step: conf[key] = self.package_step[key] snapper = SnapCMake(conf) self.assertRaises(SnapCMakeException, snapper.package)
def test_happy_case(self, mock_temp_dir, mock_makedirs, mock_open, mock_getcwd, mock_chdir, mock_subprocess, mock_listdir, mock_copyfile, mock_isfile): # Set up mocks mock_temp_dir.side_effect = [ MockTemporaryDirectory("MY_TEMPORARY_DIRECTORY") ] snap_yaml_fp = MockFilePointer() print() mock_open.side_effect = [snap_yaml_fp] snap_process = MockProcess("OUT", "ERR", 0) mock_subprocess.side_effect = [snap_process] dirs = ["papaya.snap"] mock_listdir.side_effect = [dirs] # Make the package call conf = copy.deepcopy(self.conf) for key in self.package_step: conf[key] = self.package_step[key] snapper = SnapCMake(conf) snapper.package() # Validate chdir to temp dir and back mock_chdir_calls = [call("MY_TEMPORARY_DIRECTORY"), call("CWD")] mock_chdir.assert_has_calls(mock_chdir_calls) # Validate creation of snapcraft.yaml file yaml_contents = yaml.load(snap_yaml_fp.invocations["write"][0]) for key in self.package_step: # Skip checking the Apps section here if key != "Apps": self.assertEquals(self.package_step[key], yaml_contents[key.lower()]) self.assertEquals(self.package_step["Apps"][0]["Command"], yaml_contents["apps"]["MY_APP_1"]["command"]) self.assertEquals(self.package_step["Apps"][1]["Command"], yaml_contents["apps"]["MY_APP_2"]["command"]) self.assertEquals("A", list(yaml_contents["parts"].keys())[0]) self.assertEquals("cmake", yaml_contents["parts"]["A"]["plugin"]) source = os.path.join(self.conf["GlobalPackageCache"], self.conf["Dependencies"][0]["Name"], self.conf["Dependencies"][0]["Version"], self.conf["Dependencies"][0]["Name"] + ".tar") self.assertEquals(source, yaml_contents["parts"]["A"]["source"]) self.assertEquals(1, len(snap_yaml_fp.invocations["write"])) # Validate it called snapcraft command popen_calls = [call(["snapcraft"])] mock_subprocess.assert_has_calls(popen_calls) # Validate it copied the snap back to the build folder mock_copyfile_calls = [ call(os.path.join("MY_TEMPORARY_DIRECTORY", "papaya.snap"), os.path.join(self.conf["BuildFolder"], "papaya.snap")) ] mock_copyfile.assert_has_calls(mock_copyfile_calls)
def test_exception_on_make_error_during_build(self, mock_makedirs, mock_popen, mock_isdir, mock_chdir, mock_getcwd): mock_popen.side_effect = [ MockProcess("OUT", "ERR", TestCppCmake.EXIT_SUCCESS), OSError("No such file") ] self.assertRaises(BuildException, self.builder.build)
def test_exception_on_failure_to_extract(self, mock_file, mock_tarfile, mock_popen, mock_makedirs, mock_isdir): # Mocks wget_1 = MockProcess("ERR", "OUT", TestPackageDownloader.EXIT_FAILURE) wget_2 = MockProcess("ERR", "OUT", TestPackageDownloader.EXIT_SUCCESS) tarfile_open = MockTarfilePointer() tarfile_open.set_exception() file_open = MockFilePointer() mock_tarfile.side_effect = [tarfile_open, tarfile_open, tarfile_open] mock_file.side_effect = [file_open] mock_popen.side_effect = [wget_1, wget_2] self.assertRaises(PackageDownloaderException, self.downloader.download_and_extract, self.package_list)
def test_exception_on_failed_s3_download(self, mock_s3, mock_file, mock_tarfile, mock_popen, mock_makedirs, mock_isdir, mock_isfile): # Mocks mock_isfile.side_effect = [True, False, True] wget_1 = MockProcess("ERR", "OUT", TestPackageDownloader.EXIT_FAILURE) wget_2 = MockProcess("ERR", "OUT", TestPackageDownloader.EXIT_SUCCESS) tarfile_open = MockTarfilePointer() file_open = MockFilePointer() mock_tarfile.side_effect = [tarfile_open, tarfile_open, tarfile_open] mock_file.side_effect = [file_open] mock_popen.side_effect = [wget_1, wget_2] downloader = PackageDownloader(self.config_obj) downloader.s3_client.set_up_client_error() self.assertRaises(PackageDownloaderException, downloader.download_and_extract, self.package_list)
def test_run_test_happy_case(self, mock_popen, mock_isdir, mock_chdir, mock_getcwd): # Mock popen calls p_make = MockProcess("OUT", "ERR", TestCppCmake.EXIT_SUCCESS) # Argument captors isdir_calls = [call(self.config_obj["BuildDir"])] chdir_calls = [ call(self.config_obj["BuildDir"]), call(self.config_obj["ProjectRoot"]) ] popen_calls = [call(["make", "test"])] mock_popen.side_effect = [p_make] self.builder.run_tests() mock_isdir.assert_has_calls(isdir_calls, any_order=False) mock_chdir.assert_has_calls(chdir_calls, any_order=False) mock_popen.assert_has_calls(popen_calls, any_order=False)
class TestPackageInstaller(unittest.TestCase): def setUp(self): self.conf = { "GlobalPackageCache": "GLOBAL_CACHE", "LocalPackageCache": "LOCAL_CACHE", "Logger": MockLog() } self.package_list = [{ "Name": "A", "Version": "1.0" }, { "Name": "B", "Version": "2.0" }] self.md = { "A": { "Dependencies": [{ "Name": "C", "Version": "3.0" }], "TestDeps": [{ "Name": "B", "Version": "2.0" }] }, "B": { "BuildDeps": [{ "Name": "Z", "Version": "1.0" }], "RuntimeDeps": [{ "Name": "X", "Version": "0.0" }] } } self.installer = PackageInstaller(self.conf) @patch("builtins.open", autospec=True) @patch("subprocess.Popen", return_value=MockProcess("OUT", "ERR", 0)) @patch("os.chdir", return_value=None) @patch("os.getcwd", return_value="CWD") @patch("os.makedirs", return_value=None) @patch("os.path.isdir", autospec=True) def test_package_installer_happy_case(self, mock_isdir, mock_makedirs, mock_cwd, mock_chdir, mock_popen, mock_open): mock_isdir.side_effect = [ True, # Global package cache first access False, # Local package cache first access True, # Global package cache second access True, # Local package cache second access True, # Global package cache third access True # Local package cache third access ] md_file_A = MockFilePointer(read_text=json.dumps(self.md["A"])) md_file_B = MockFilePointer(read_text=json.dumps(self.md["B"])) mock_open.side_effect = [md_file_A, md_file_B] actual_deps = self.installer.install_packages(self.package_list) expexted_deps = {} for dep in self.md["A"]["Dependencies"] + self.md["A"][ "TestDeps"] + self.md["B"]["RuntimeDeps"] + self.md["B"][ "BuildDeps"]: expexted_deps[dep["Name"]] = dep self.assertEqual(expexted_deps, actual_deps) isdir_calls = [ call( os.path.join(self.conf["GlobalPackageCache"], self.package_list[0]["Name"], self.package_list[0]["Version"])), call(self.conf["LocalPackageCache"]), call( os.path.join(self.conf["GlobalPackageCache"], self.package_list[1]["Name"], self.package_list[1]["Version"])), call(self.conf["LocalPackageCache"]) ] mock_isdir.assert_has_calls(isdir_calls, any_order=False) makedirs_calls = [call(self.conf["LocalPackageCache"])] mock_makedirs.assert_has_calls(makedirs_calls, any_order=False) def get_chdir_call(i): return [ call( os.path.join(self.conf["GlobalPackageCache"], self.package_list[i]["Name"], self.package_list[i]["Version"])), call("CWD") ] * 3 chdir_calls = get_chdir_call(0) + get_chdir_call(1) mock_chdir.assert_has_calls(chdir_calls, any_order=False) popen_calls = [ call([ "cmake", ".", "-DCMAKE_INSTALL_PREFIX=" + self.conf["LocalPackageCache"] ], stdout=subprocess.PIPE, stderr=subprocess.PIPE), call(["make"], stdout=subprocess.PIPE, stderr=subprocess.PIPE), call(["make", "install"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) ] * 2 mock_popen.assert_has_calls(popen_calls, any_order=False) @patch("builtins.open", autospec=True) @patch("subprocess.Popen", autospec=True) @patch("os.chdir", return_value=None) @patch("os.getcwd", return_value="CWD") @patch("os.makedirs", return_value=None) @patch("os.path.isdir", autospec=True) def test_exception_on_absent_package(self, mock_isdir, mock_makedirs, mock_cwd, mock_chdir, mock_popen, mock_open): mock_isdir.side_effect = [ False, # Global package cache first access False, # Local package cache first access True, # Global package cache second access True, # Local package cache second access True, # Global package cache third access True # Local package cache third access ] md_file_A = MockFilePointer(read_text=json.dumps(self.md["A"])) md_file_B = MockFilePointer(read_text=json.dumps(self.md["B"])) mock_open.side_effect = [md_file_A, md_file_B] self.assertRaises(PackageInstallerException, self.installer.install_packages, self.package_list) @patch("builtins.open", autospec=True) @patch("subprocess.Popen", return_value=MockProcess("OUT", "ERR", 0)) @patch("os.chdir", return_value=None) @patch("os.getcwd", return_value="CWD") @patch("os.makedirs", return_value=None) @patch("os.path.isdir", autospec=True) def test_exception_on_absent_cmake(self, mock_isdir, mock_makedirs, mock_cwd, mock_chdir, mock_popen, mock_open): mock_isdir.side_effect = [ True, # Global package cache first access False, # Local package cache first access True, # Global package cache second access True, # Local package cache second access True, # Global package cache third access True # Local package cache third access ] mock_popen.side_effect = OSError() self.assertRaises(PackageInstallerException, self.installer.install_packages, self.package_list) popen_calls = [ call([ "cmake", ".", "-DCMAKE_INSTALL_PREFIX=" + self.conf["LocalPackageCache"] ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) ] mock_popen.assert_has_calls(popen_calls, any_order=False) @patch("builtins.open", autospec=True) @patch("subprocess.Popen", return_value=MockProcess("OUT", "ERR", 0)) @patch("os.chdir", return_value=None) @patch("os.getcwd", return_value="CWD") @patch("os.makedirs", return_value=None) @patch("os.path.isdir", autospec=True) def test_exception_on_absent_make(self, mock_isdir, mock_makedirs, mock_cwd, mock_chdir, mock_popen, mock_open): mock_isdir.side_effect = [ True, # Global package cache first access False, # Local package cache first access True, # Global package cache second access True, # Local package cache second access True, # Global package cache third access True # Local package cache third access ] mock_popen.side_effect = [MockProcess("OUT", "ERR", 0), OSError()] self.assertRaises(PackageInstallerException, self.installer.install_packages, self.package_list) popen_calls = [ call([ "cmake", ".", "-DCMAKE_INSTALL_PREFIX=" + self.conf["LocalPackageCache"] ], stdout=subprocess.PIPE, stderr=subprocess.PIPE), call(["make"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) ] mock_popen.assert_has_calls(popen_calls, any_order=False) @patch("builtins.open", autospec=True) @patch("subprocess.Popen", return_value=MockProcess("OUT", "ERR", 0)) @patch("os.chdir", return_value=None) @patch("os.getcwd", return_value="CWD") @patch("os.makedirs", return_value=None) @patch("os.path.isdir", autospec=True) def test_exception_on_failed_cmake(self, mock_isdir, mock_makedirs, mock_cwd, mock_chdir, mock_popen, mock_open): mock_isdir.side_effect = [ True, # Global package cache first access False, # Local package cache first access True, # Global package cache second access True, # Local package cache second access True, # Global package cache third access True # Local package cache third access ] mock_popen.side_effect = [MockProcess("CMAKE_OUT", "ERR", 1)] self.assertRaises(PackageInstallerException, self.installer.install_packages, self.package_list) popen_calls = [ call([ "cmake", ".", "-DCMAKE_INSTALL_PREFIX=" + self.conf["LocalPackageCache"] ], stdout=subprocess.PIPE, stderr=subprocess.PIPE), ] mock_popen.assert_has_calls(popen_calls, any_order=False) @patch("builtins.open", autospec=True) @patch("subprocess.Popen", return_value=MockProcess("OUT", "ERR", 0)) @patch("os.chdir", return_value=None) @patch("os.getcwd", return_value="CWD") @patch("os.makedirs", return_value=None) @patch("os.path.isdir", autospec=True) def test_exception_on_failed_make(self, mock_isdir, mock_makedirs, mock_cwd, mock_chdir, mock_popen, mock_open): mock_isdir.side_effect = [ True, # Global package cache first access False, # Local package cache first access True, # Global package cache second access True, # Local package cache second access True, # Global package cache third access True # Local package cache third access ] mock_popen.side_effect = [ MockProcess("CMAKE_OUT", "ERR", 0), MockProcess("MAKE_OUT", "ERR", 1) ] self.assertRaises(PackageInstallerException, self.installer.install_packages, self.package_list) popen_calls = [ call([ "cmake", ".", "-DCMAKE_INSTALL_PREFIX=" + self.conf["LocalPackageCache"] ], stdout=subprocess.PIPE, stderr=subprocess.PIPE), call(["make"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) ] mock_popen.assert_has_calls(popen_calls, any_order=False) @patch("builtins.open", autospec=True) @patch("subprocess.Popen", return_value=MockProcess("OUT", "ERR", 0)) @patch("os.chdir", return_value=None) @patch("os.getcwd", return_value="CWD") @patch("os.makedirs", return_value=None) @patch("os.path.isdir", autospec=True) def test_exception_on_failed_make_install(self, mock_isdir, mock_makedirs, mock_cwd, mock_chdir, mock_popen, mock_open): mock_isdir.side_effect = [ True, # Global package cache first access False, # Local package cache first access True, # Global package cache second access True, # Local package cache second access True, # Global package cache third access True # Local package cache third access ] mock_popen.side_effect = [ MockProcess("CMAKE_OUT", "ERR", 0), MockProcess("MAKE_OUT", "ERR", 0), MockProcess("MAKE_INSTALL_OUT", "ERR", 1) ] self.assertRaises(PackageInstallerException, self.installer.install_packages, self.package_list) popen_calls = [ call([ "cmake", ".", "-DCMAKE_INSTALL_PREFIX=" + self.conf["LocalPackageCache"] ], stdout=subprocess.PIPE, stderr=subprocess.PIPE), call(["make"], stdout=subprocess.PIPE, stderr=subprocess.PIPE), call(["make", "install"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) ] mock_popen.assert_has_calls(popen_calls, any_order=False) @patch("builtins.open", autospec=True) @patch("subprocess.Popen", return_value=MockProcess("OUT", "ERR", 0)) @patch("os.chdir", return_value=None) @patch("os.getcwd", return_value="CWD") @patch("os.makedirs", return_value=None) @patch("os.path.isdir", autospec=True) def test_exception_on_invalid_metadata_file(self, mock_isdir, mock_makedirs, mock_cwd, mock_chdir, mock_popen, mock_open): mock_isdir.side_effect = [ True, # Global package cache first access False, # Local package cache first access True, # Global package cache second access True, # Local package cache second access True, # Global package cache third access True # Local package cache third access ] md_file_A = MockFilePointer(read_text="Bad json") md_file_B = MockFilePointer(read_text=json.dumps(self.md["B"])) mock_open.side_effect = [md_file_A, md_file_B] self.assertRaises(PackageInstallerException, self.installer.install_packages, self.package_list) @patch("builtins.open", autospec=True) @patch("subprocess.Popen", return_value=MockProcess("OUT", "ERR", 0)) @patch("os.chdir", return_value=None) @patch("os.getcwd", return_value="CWD") @patch("os.makedirs", return_value=None) @patch("os.path.isdir", autospec=True) def test_exception_on_invalid_absent_file(self, mock_isdir, mock_makedirs, mock_cwd, mock_chdir, mock_popen, mock_open): mock_isdir.side_effect = [ True, # Global package cache first access False, # Local package cache first access True, # Global package cache second access True, # Local package cache second access True, # Global package cache third access True # Local package cache third access ] md_file_A = OSError() md_file_B = MockFilePointer(read_text=json.dumps(self.md["B"])) mock_open.side_effect = [md_file_A, md_file_B] self.assertRaises(PackageInstallerException, self.installer.install_packages, self.package_list) def test_init_errors(self): self.assertRaises(PackageInstallerException, PackageInstaller, {}) self.assertRaises(PackageInstallerException, PackageInstaller, 10)
def test_packages_downloaded_happy_case(self, mock_file, mock_tarfile, mock_popen, mock_makedirs, mock_isdir, mock_isfile): # Mocks wget_1 = MockProcess("ERR", "OUT", TestPackageDownloader.EXIT_SUCCESS) wget_2 = MockProcess("ERR", "OUT", TestPackageDownloader.EXIT_SUCCESS) tarfile_open = MockTarfilePointer() file_open = MockFilePointer() # Argument captors isdir_calls = [ call(self.config_obj["GlobalPackageCache"]), call( os.path.join(self.config_obj["GlobalPackageCache"], "A", "1.0")), call(self.config_obj["GlobalPackageCache"]), call( os.path.join(self.config_obj["GlobalPackageCache"], "B", "2.0")), call(self.config_obj["GlobalPackageCache"]), call( os.path.join(self.config_obj["GlobalPackageCache"], "C", "3.0")) ] makedirs_calls = [ call(self.config_obj["GlobalPackageCache"]), call( os.path.join(self.config_obj["GlobalPackageCache"], self.package_list[0]["Name"], self.package_list[0]["Version"])), call( os.path.join(self.config_obj["GlobalPackageCache"], self.package_list[1]["Name"], self.package_list[1]["Version"])), call( os.path.join(self.config_obj["GlobalPackageCache"], self.package_list[2]["Name"], self.package_list[2]["Version"])) ] wget_url_1 = "/".join([ self.config_obj["PackageSource"]["Url"], self.package_list[0]["Name"], self.package_list[0]["Version"], self.package_list[0]["Name"] + ".tar" ]) dest_1 = os.path.join(self.config_obj["GlobalPackageCache"], self.package_list[0]["Name"], self.package_list[0]["Version"], self.package_list[0]["Name"] + ".tar") wget_url_2 = "/".join([ self.package_list[2]["PackageSource"]["Url"], self.package_list[2]["Name"], self.package_list[2]["Version"], self.package_list[2]["Name"] + ".tar" ]) dest_2 = os.path.join(self.config_obj["GlobalPackageCache"], self.package_list[2]["Name"], self.package_list[2]["Version"], self.package_list[2]["Name"] + ".tar") popen_calls = [ call(["wget", wget_url_1, "-O", dest_1], stdout=subprocess.PIPE, stderr=subprocess.PIPE), call(["wget", wget_url_2, "-O", dest_2], stdout=subprocess.PIPE, stderr=subprocess.PIPE) ] s3_key = os.path.join(self.package_list[1]["Name"], self.package_list[1]["Version"], self.package_list[1]["Name"] + ".tar") tarfile_opens = [ os.path.join(self.config_obj["GlobalPackageCache"], self.package_list[0]["Name"], self.package_list[0]["Version"]), os.path.join(self.config_obj["GlobalPackageCache"], self.package_list[1]["Name"], self.package_list[1]["Version"]), os.path.join(self.config_obj["GlobalPackageCache"], self.package_list[2]["Name"], self.package_list[2]["Version"]) ] mock_isdir.side_effect = [False, False, True, False, True, False] mock_tarfile.side_effect = [tarfile_open, tarfile_open, tarfile_open] mock_file.side_effect = [file_open] mock_popen.side_effect = [wget_1, wget_2] self.downloader.download_and_extract(self.package_list) mock_isdir.assert_has_calls(isdir_calls, any_order=False) mock_makedirs.assert_has_calls(makedirs_calls, any_order=False) mock_popen.assert_has_calls(popen_calls) self.assertEqual(1, len(self.downloader.s3_client.invocations)) self.assertEqual((self.package_list[1]["PackageSource"]["Bucket"], s3_key, file_open), self.downloader.s3_client.invocations[0]) self.assertEqual(tarfile_opens, tarfile_open.invocations["extractall"])