def test_callback_retry(mocker, requests_mock, image: str): requests_mock.post( VALID_CALLBACK_CREDENTIALS['url'], [ { 'status_code': 404 }, { 'status_code': 500 }, { 'exc': requests.exceptions.ConnectTimeout }, { 'status_code': 200 }, # no JSON { 'status_code': 200, 'json': VALID_CALLBACK_RESPONSE } ]) mock_popen = mocker.patch('subprocess.Popen', new_callable=create_mock_popen) mocker.patch('time.sleep') # removes retry delays for testing my_action = mocker.Mock() with get_credential_manager( image=image, registry_credentials=VALID_CALLBACK_CREDENTIALS): my_action() assert mock_popen.call_count == 2 # login + logout my_action.assert_called_once_with()
def test_login_with_valid_credentials(mocker, requests_mock, image: str, credentials: Dict): # smoke test for all credential types my_action = mocker.Mock() mock_popen = mocker.patch('subprocess.Popen', new_callable=create_mock_popen) if credentials == VALID_CALLBACK_CREDENTIALS: requests_mock.post(VALID_CALLBACK_CREDENTIALS['url'], json=VALID_CALLBACK_RESPONSE) with get_credential_manager(image=image, registry_credentials=credentials): assert mock_popen.call_count == 1 # login my_action() assert mock_popen.call_count == 2 # login + logout my_action.assert_called_once_with()
def test_fallback_with_invalid_credential_configuration(mocker, missing_value): # when type or version is missing, we should fallback to dummy manager and do the action anyway, but with a warning del VALID_DOCKER_CREDENTIALS[missing_value] image = EXAMPLE_IMAGES[0] my_action = mocker.Mock() my_logging_callback = mocker.Mock() with get_credential_manager(image=image, registry_credentials=VALID_DOCKER_CREDENTIALS, log_status=my_logging_callback): my_action() my_action.assert_called_once_with() assert 'Unable to parse' in my_logging_callback.call_args[0][0]
def test_login_error(mocker): my_action = mocker.Mock() image = EXAMPLE_IMAGES[0] # make the mock subprocess to report non-zero return code mock_popen = mocker.patch('subprocess.Popen') mock_process = create_mock_process(returncode=1) mock_popen.return_value = mock_process with pytest.raises(DockerLoginFailed): with get_credential_manager( image=image, registry_credentials=VALID_DOCKER_CREDENTIALS): my_action() my_action.assert_not_called()
def test_changing_settings(mocker): my_action = mocker.Mock() # accept all subprocess calls that use the default 'docker' command mocker.patch( 'subprocess.Popen', wraps=lambda args, **kwargs: create_mock_process() if args[1] == 'docker' else None, ) with get_credential_manager(image=EXAMPLE_IMAGES[0], registry_credentials=VALID_DOCKER_CREDENTIALS): my_action() my_action.call_count = 1 # modify the settings and accept only subprocess calls that use the modified command custom_command = 'modified-docker' mocker.patch('laituri.settings.DOCKER_COMMAND', custom_command) mocker.patch('subprocess.Popen', wraps=lambda args, **kwargs: create_mock_process() if args[1] == custom_command else None) with get_credential_manager(image=EXAMPLE_IMAGES[0], registry_credentials=VALID_DOCKER_CREDENTIALS): my_action() my_action.call_count = 2
def test_login_timeout(mocker): my_action = mocker.Mock() image = EXAMPLE_IMAGES[0] def popen_mock(args, **kwargs): # force the login processes to raise TimeoutExpired if args[2] == 'login': mock_process = create_mock_process() mock_process.communicate.side_effect = subprocess.TimeoutExpired( cmd='docker login', timeout=30) return mock_process return create_mock_process() mocker.patch('subprocess.Popen', wraps=popen_mock) with pytest.raises(DockerLoginFailed): with get_credential_manager( image=image, registry_credentials=VALID_DOCKER_CREDENTIALS): my_action() my_action.assert_not_called()
def test_that_logout_error_doesnt_crash(mocker): my_action = mocker.Mock() image = EXAMPLE_IMAGES[0] mocker.patch('subprocess.Popen', new_callable=create_mock_popen) def check_call_mock(args, **kwargs): # force logout processes to error out if args[2] == 'logout': raise subprocess.CalledProcessError(returncode=1, cmd='docker logout', output=b'') return create_mock_process() mock_check_call = mocker.patch('subprocess.check_call', wraps=check_call_mock) with get_credential_manager(image=image, registry_credentials=VALID_DOCKER_CREDENTIALS): my_action() assert mock_check_call.call_count == 1 my_action.assert_called_once_with()
def test_that_context_manager_triggers_the_action_regardless_of_image_validity(mocker, image: str): my_action = mocker.Mock() with get_credential_manager(image=image): my_action() my_action.assert_called_once_with()