def test_container_executor_skopeo_login_fail(mock_api_client, mock_tls_config, mock_isdir, mock_run_cmd, mock_add_file): mock_create_container = mock.MagicMock() mock_create_container.return_value = {"Id": "123"} mock_api_client.return_value.create_container = mock_create_container mock_start = mock.MagicMock() mock_api_client.return_value.start = mock_start mock_remove_container = mock.MagicMock() mock_api_client.return_value.remove_container = mock_remove_container mock_isdir.return_value = True mock_run_cmd.side_effect = [("not logged in", "nothing"), ("Login Failed", "nothing")] with command_executor.ContainerExecutor( "quay.io/some/image:1", base_url="some-url.com", timeout=120, verify_tls=True, cert_path="/some/path", ) as executor: with pytest.raises( RuntimeError, match="Login command didn't generate expected output.*"): executor.skopeo_login("some-host", "some-name", "some-password") assert mock_run_cmd.call_count == 2 assert mock_run_cmd.call_args_list[0] == mock.call( "skopeo login --get-login some-host", tolerate_err=True) assert mock_run_cmd.call_args_list[1] == mock.call( " sh -c 'cat /tmp/skopeo_password.txt | skopeo login --authfile $HOME/.docker/config.json " '-u "some-name" --password-stdin some-host\'') mock_add_file.assert_called_once_with("some-password", "skopeo_password.txt")
def test_container_executor_skopeo_login_already_logged( mock_api_client, mock_tls_config, mock_isdir, mock_run_cmd, mock_add_file): mock_create_container = mock.MagicMock() mock_create_container.return_value = {"Id": "123"} mock_api_client.return_value.create_container = mock_create_container mock_start = mock.MagicMock() mock_api_client.return_value.start = mock_start mock_remove_container = mock.MagicMock() mock_api_client.return_value.remove_container = mock_remove_container mock_isdir.return_value = True mock_run_cmd.return_value = ("some-name", "nothing") with command_executor.ContainerExecutor( "quay.io/some/image:1", base_url="some-url.com", timeout=120, verify_tls=True, cert_path="/some/path", ) as executor: executor.skopeo_login("some-host", "some-name", "some-password") mock_run_cmd.assert_called_once_with("skopeo login --get-login some-host", tolerate_err=True) mock_add_file.assert_not_called()
def test_container_executor_skopeo_login_missing_credential( mock_api_client, mock_tls_config, mock_isdir, mock_run_cmd, mock_add_file): mock_create_container = mock.MagicMock() mock_create_container.return_value = {"Id": "123"} mock_api_client.return_value.create_container = mock_create_container mock_start = mock.MagicMock() mock_api_client.return_value.start = mock_start mock_remove_container = mock.MagicMock() mock_api_client.return_value.remove_container = mock_remove_container mock_isdir.return_value = True mock_run_cmd.side_effect = [("not logged in", "nothing"), ("Login Succeeded", "nothing")] with command_executor.ContainerExecutor( "quay.io/some/image:1", base_url="some-url.com", timeout=120, verify_tls=True, cert_path="/some/path", ) as executor: with pytest.raises(ValueError, match="Skopeo login credentials are not present.*"): executor.skopeo_login("some-host", "some-name") mock_run_cmd.assert_called_once_with("skopeo login --get-login some-host", tolerate_err=True) mock_add_file.assert_not_called()
def test_container_executor_run_cmd_no_output(mock_api_client, mock_tls_config, mock_isdir): mock_create_container = mock.MagicMock() mock_create_container.return_value = {"Id": "123"} mock_api_client.return_value.create_container = mock_create_container mock_start = mock.MagicMock() mock_api_client.return_value.start = mock_start mock_remove_container = mock.MagicMock() mock_api_client.return_value.remove_container = mock_remove_container mock_isdir.return_value = True mock_exec_create = mock.MagicMock() mock_exec_create.return_value = {"Id": "321"} mock_api_client.return_value.exec_create = mock_exec_create mock_exec_start = mock.MagicMock() mock_exec_start.return_value = None mock_api_client.return_value.exec_start = mock_exec_start mock_exec_inspect = mock.MagicMock() mock_exec_inspect.return_value = {"ExitCode": 0} mock_api_client.return_value.exec_inspect = mock_exec_inspect with command_executor.ContainerExecutor( "quay.io/some/image:1", base_url="some-url.com", timeout=120, verify_tls=True, cert_path="/some/path", ) as executor: stdout, stderr = executor._run_cmd("cat file.txt") assert stdout == "" assert stderr == ""
def test_container_executor_run_cmd_error(mock_api_client, mock_tls_config, mock_isdir): mock_create_container = mock.MagicMock() mock_create_container.return_value = {"Id": "123"} mock_api_client.return_value.create_container = mock_create_container mock_start = mock.MagicMock() mock_api_client.return_value.start = mock_start mock_remove_container = mock.MagicMock() mock_api_client.return_value.remove_container = mock_remove_container mock_isdir.return_value = True mock_exec_create = mock.MagicMock() mock_exec_create.return_value = {"Id": "321"} mock_api_client.return_value.exec_create = mock_exec_create mock_exec_start = mock.MagicMock() mock_exec_start.return_value = b"some output" mock_api_client.return_value.exec_start = mock_exec_start mock_exec_inspect = mock.MagicMock() mock_exec_inspect.return_value = {"ExitCode": 1} mock_api_client.return_value.exec_inspect = mock_exec_inspect with command_executor.ContainerExecutor( "quay.io/some/image:1", base_url="some-url.com", timeout=120, verify_tls=True, cert_path="/some/path", ) as executor: with pytest.raises( RuntimeError, match="An error has occured when executing a command."): stdout, stderr = executor._run_cmd("cat file.txt")
def test_container_executor_add_file( mock_api_client, mock_tls_config, mock_isdir, mock_bytesio, mock_tarfile, mock_tarinfo, mock_time, ): mock_create_container = mock.MagicMock() mock_create_container.return_value = {"Id": "123"} mock_api_client.return_value.create_container = mock_create_container mock_start = mock.MagicMock() mock_api_client.return_value.start = mock_start mock_remove_container = mock.MagicMock() mock_api_client.return_value.remove_container = mock_remove_container mock_isdir.return_value = True mock_add_file = mock.MagicMock() mock_tarfile.return_value.addfile = mock_add_file mock_close = mock.MagicMock() mock_tarfile.return_value.close = mock_close mock_bytesio1 = mock.MagicMock() mock_bytesio2 = mock.MagicMock() mock_bytesio.side_effect = [mock_bytesio1, mock_bytesio2] mock_seek = mock.MagicMock() mock_bytesio1.seek = mock_seek mock_put_archive = mock.MagicMock() mock_put_archive.return_value = True mock_api_client.return_value.put_archive = mock_put_archive with command_executor.ContainerExecutor( "quay.io/some/image:1", base_url="some-url.com", timeout=120, verify_tls=True, cert_path="/some/path", ) as executor: executor._add_file("abcdefg", "some-file.txt") assert mock_bytesio.call_count == 2 mock_tarfile.assert_called_once_with(fileobj=mock_bytesio1, mode="w") mock_tarinfo.assert_called_once_with(name="some-file.txt") mock_add_file.assert_called_once_with(mock_tarinfo.return_value, mock_bytesio2) mock_close.assert_called_once_with() mock_seek.assert_called_once_with(0) mock_put_archive.assert_called_once_with(container="123", path="/tmp", data=mock_bytesio1)
def test_container_executor_add_file_fail( mock_api_client, mock_tls_config, mock_isdir, mock_bytesio, mock_tarfile, mock_tarinfo, mock_time, ): mock_create_container = mock.MagicMock() mock_create_container.return_value = {"Id": "123"} mock_api_client.return_value.create_container = mock_create_container mock_start = mock.MagicMock() mock_api_client.return_value.start = mock_start mock_remove_container = mock.MagicMock() mock_api_client.return_value.remove_container = mock_remove_container mock_isdir.return_value = True mock_add_file = mock.MagicMock() mock_tarfile.return_value.addfile = mock_add_file mock_close = mock.MagicMock() mock_tarfile.return_value.close = mock_close mock_bytesio1 = mock.MagicMock() mock_bytesio2 = mock.MagicMock() mock_bytesio.side_effect = [mock_bytesio1, mock_bytesio2] mock_seek = mock.MagicMock() mock_bytesio1.seek = mock_seek mock_put_archive = mock.MagicMock() mock_put_archive.return_value = False mock_api_client.return_value.put_archive = mock_put_archive with command_executor.ContainerExecutor( "quay.io/some/image:1", base_url="some-url.com", timeout=120, verify_tls=True, cert_path="/some/path", ) as executor: with pytest.raises( RuntimeError, match="File was not successfully added to the container"): executor._add_file("abcdefg", "some-file.txt")
def test_container_executor_init(mock_api_client, mock_tls_config, mock_isdir): mock_create_container = mock.MagicMock() mock_create_container.return_value = {"Id": "123"} mock_api_client.return_value.create_container = mock_create_container mock_start = mock.MagicMock() mock_api_client.return_value.start = mock_start mock_remove_container = mock.MagicMock() mock_api_client.return_value.remove_container = mock_remove_container mock_isdir.return_value = True with command_executor.ContainerExecutor( "quay.io/some/image:1", base_url="some-url.com", timeout=120, verify_tls=True, cert_path="/some/path", registry_username="******", registry_password="******", ): pass mock_tls_config.assert_called_once_with(client_cert=("/some/path/cert.pem", "/some/path/key.pem"), verify="/some/path/ca.pem") mock_api_client.assert_called_once_with(base_url="some-url.com", version="auto", timeout=120, tls=mock_tls_config.return_value) mock_create_container.assert_called_once_with("quay.io/some/image:1", detach=True, tty=True) mock_start.assert_called_once_with("123") mock_remove_container.assert_called_once_with("123", force=True) mock_api_client.return_value.login.assert_called_once_with( username="******", password="******", registry="quay.io", reauth=True) mock_api_client.return_value.pull.assert_called_once_with( "quay.io/some/image", tag="1")