def test_wait_for_request_timeout(timeout, caplog): request_url = '{}/api/v1/requests/{}'.format(CACHITO_URL, CACHITO_REQUEST_ID) updated = datetime.utcnow().isoformat() response_data = {'id': CACHITO_REQUEST_ID, 'state': 'in_progress', 'updated': updated} responses.add( responses.GET, request_url, content_type='application/json', status=200, body=json.dumps(response_data), ) flexmock(time).should_receive('time').and_return(2000, 1000).one_by_one() # Hit the timeout during bursting to make the test faster burst_params = {'burst_retry': 0.001, 'burst_length': 0.02} with pytest.raises(CachitoAPIRequestTimeout): api = CachitoAPI(CACHITO_URL, timeout=timeout) api.wait_for_request(CACHITO_REQUEST_ID, **burst_params) in_progress_response_json = json.dumps(response_data, indent=4) expect_in_logs = dedent( """\ Request {} not completed after {} seconds of not being updated Details: {} """ ).format(request_url, timeout, in_progress_response_json) # Since Python 3.7 logger adds additional whitespaces by default -> checking without them assert re.sub(r'\s+', " ", expect_in_logs) in re.sub(r'\s+', " ", caplog.text)
def test_request_sources(additional_params, caplog): response_data = {'id': CACHITO_REQUEST_ID} def handle_request_sources(http_request): body_json = json.loads(http_request.body) assert body_json['repo'] == CACHITO_REQUEST_REPO assert body_json['ref'] == CACHITO_REQUEST_REF for key, value in additional_params.items(): assert body_json[key] == value return (201, {}, json.dumps(response_data)) responses.add_callback(responses.POST, '{}/api/v1/requests'.format(CACHITO_URL), content_type='application/json', callback=handle_request_sources) api = CachitoAPI(CACHITO_URL) response = api.request_sources(CACHITO_REQUEST_REPO, CACHITO_REQUEST_REF, **additional_params) assert response['id'] == CACHITO_REQUEST_ID response_json = 'Cachito response:\n{}'.format( json.dumps(response_data, indent=4)) # Since Python 3.7 logger adds additional whitespaces by default -> checking without them assert re.sub(r'\s+', " ", response_json) in re.sub(r'\s+', " ", caplog.text)
def test_non_json_data_for_get_request_env_vars(): responses.add( responses.GET, f'{CACHITO_URL}/api/v1/requests/{CACHITO_REQUEST_ID}/environment-variables', body='something wrong', ) session = CachitoAPI(CACHITO_URL) with pytest.raises(ValueError, match=r'JSON data.*something wrong'): session.get_request_env_vars(CACHITO_REQUEST_ID)
def test_get_request_env_vars(): env_vars = { 'GO111MODULE': {'kind': 'literal', 'value': 'on'}, 'GOPATH': {'kind': 'path', 'value': 'deps/gomod'}, 'GOCACHE': {'kind': 'path', 'value': 'deps/gomod'}, } responses.add( responses.GET, f'{CACHITO_URL}/api/v1/requests/{CACHITO_REQUEST_ID}/environment-variables', json=env_vars, ) session = CachitoAPI(CACHITO_URL) assert env_vars == session.get_request_env_vars(CACHITO_REQUEST_ID)
def test_wait_for_unsuccessful_request(error_state, caplog): states = ['in_progress', 'in_progress', error_state] expected_total_responses_calls = len(states) def handle_wait_for_request(http_request): state = states.pop(0) return (200, {}, json.dumps({ 'id': CACHITO_REQUEST_ID, 'state': state })) responses.add_callback(responses.GET, '{}/api/v1/requests/{}'.format( CACHITO_URL, CACHITO_REQUEST_ID), content_type='application/json', callback=handle_wait_for_request) burst_params = {'burst_retry': 0.001, 'burst_length': 0.5} with pytest.raises(CachitoAPIUnsuccessfulRequest): CachitoAPI(CACHITO_URL).wait_for_request(CACHITO_REQUEST_ID, **burst_params) assert len(responses.calls) == expected_total_responses_calls failed_response_json = json.dumps( { 'id': CACHITO_REQUEST_ID, 'state': error_state }, indent=4) expect_in_logs = dedent("""\ Request {} is in "{}" state: Unknown Details: {} """).format(CACHITO_REQUEST_ID, error_state, failed_response_json) # Since Python 3.7 logger adds additional whitespaces by default -> checking without them assert re.sub(r'\s+', " ", expect_in_logs) in re.sub(r'\s+', " ", caplog.text)
def test_wait_for_request_timeout(caplog): request_url = '{}/api/v1/requests/{}'.format(CACHITO_URL, CACHITO_REQUEST_ID) response_data = {'id': CACHITO_REQUEST_ID, 'state': 'in_progress'} responses.add( responses.GET, request_url, content_type='application/json', status=200, body=json.dumps(response_data), ) # Hit the timeout during bursting to make the test faster burst_params = { 'burst_retry': 0.001, 'burst_length': 0.02, 'timeout': 0.01 } with pytest.raises(CachitoAPIRequestTimeout): CachitoAPI(CACHITO_URL).wait_for_request(CACHITO_REQUEST_ID, **burst_params) in_progress_response_json = json.dumps(response_data, indent=4) expect_in_logs = dedent("""\ Request {} not completed after 0.01 seconds Details: {} """).format(request_url, in_progress_response_json) # Since Python 3.7 logger adds additional whitespaces by default -> checking without them assert re.sub(r'\s+', " ", expect_in_logs) in re.sub(r'\s+', " ", caplog.text)
def test_check_CachitoAPIUnsuccessfulRequest_text(error_state, error_reason, caplog): states = ['in_progress', 'in_progress', error_state] updated = datetime.utcnow().isoformat() expected_total_responses_calls = len(states) cachito_request_url = '{}/api/v1/requests/{}'.format(CACHITO_URL, CACHITO_REQUEST_ID) def handle_wait_for_request(http_request): state = states.pop(0) return (200, {}, json.dumps({'state_reason': error_reason, 'repo': CACHITO_REQUEST_REPO, 'state': state, 'ref': CACHITO_REQUEST_REF, 'id': CACHITO_REQUEST_ID, 'updated': updated, })) responses.add_callback( responses.GET, '{}/api/v1/requests/{}'.format(CACHITO_URL, CACHITO_REQUEST_ID), content_type='application/json', callback=handle_wait_for_request) burst_params = {'burst_retry': 0.001, 'burst_length': 0.5} expected_exc_text = dedent('''\ Cachito request is in "{}" state, reason: {} Request {} ({}) tried to get repo '{}' at reference '{}'. '''.format(error_state, error_reason, CACHITO_REQUEST_ID, cachito_request_url, CACHITO_REQUEST_REPO, CACHITO_REQUEST_REF)) with pytest.raises(CachitoAPIUnsuccessfulRequest) as excinfo: CachitoAPI(CACHITO_URL).wait_for_request(CACHITO_REQUEST_ID, **burst_params) assert len(responses.calls) == expected_total_responses_calls assert expected_exc_text in str(excinfo.value)
def test_wait_for_request(burst_params, cachito_request, caplog): states = ['in_progress', 'in_progress', 'complete'] updated = datetime.utcnow().isoformat() expected_total_responses_calls = len(states) expected_final_state = states[-1] def handle_wait_for_request(http_request): state = states.pop(0) return (200, {}, json.dumps({'id': CACHITO_REQUEST_ID, 'state': state, 'updated': updated})) request_url = '{}/api/v1/requests/{}'.format(CACHITO_URL, CACHITO_REQUEST_ID) responses.add_callback( responses.GET, request_url, content_type='application/json', callback=handle_wait_for_request) response = CachitoAPI(CACHITO_URL).wait_for_request(cachito_request, **burst_params) assert response['id'] == CACHITO_REQUEST_ID assert response['state'] == expected_final_state assert len(responses.calls) == expected_total_responses_calls expect_in_logs = dedent( """\ Request {} is complete Request url: {} """ ).format(CACHITO_REQUEST_ID, request_url) # Since Python 3.7 logger adds additional whitespaces by default -> checking without them assert re.sub(r'\s+', " ", expect_in_logs) in re.sub(r'\s+', r" ", caplog.text)
def test_get_request_config_files(): config_files = [ { "path": "app/.npmrc", "type": "base64", "content": "<base64 encoded content>" }, ] responses.add( responses.GET, f'{CACHITO_URL}/api/v1/requests/{CACHITO_REQUEST_ID}/configuration-files', json=config_files, ) session = CachitoAPI(CACHITO_URL) assert config_files == session.get_request_config_files(CACHITO_REQUEST_ID)
def test_download_sources(tmpdir, cachito_request): blob = 'glop-glop-I\'m-a-blob' expected_dest_path = os.path.join(str(tmpdir), 'remote-source.tar.gz') responses.add( responses.GET, '{}/api/v1/requests/{}/download'.format(CACHITO_URL, CACHITO_REQUEST_ID), body=blob) dest_path = CachitoAPI(CACHITO_URL).download_sources(cachito_request, str(tmpdir)) assert dest_path == expected_dest_path with open(dest_path) as f: assert f.read() == blob
def get_cachito_session(workflow): config = get_cachito(workflow) api_kwargs = {'insecure': config.get('insecure', False)} ssl_certs_dir = config['auth'].get('ssl_certs_dir') if ssl_certs_dir: cert_path = os.path.join(ssl_certs_dir, 'cert') if os.path.exists(cert_path): api_kwargs['cert'] = cert_path else: raise RuntimeError("Cachito ssl_certs_dir doesn't exist") return CachitoAPI(config['api_url'], **api_kwargs)
def test_request_sources_error(status_code, error, error_body, caplog): responses.add( responses.POST, '{}/api/v1/requests'.format(CACHITO_URL), content_type='application/json', body=error_body, status=status_code, ) with pytest.raises(error): CachitoAPI(CACHITO_URL).request_sources(CACHITO_REQUEST_REPO, CACHITO_REQUEST_REF) try: response_data = json.loads(error_body) except ValueError: # json.JSONDecodeError in py3 assert 'Cachito response' not in caplog.text else: response_json = 'Cachito response:\n{}'.format(json.dumps(response_data, indent=4)) # Since Python 3.7 logger adds additional whitespaces by default -> checking without them assert re.sub(r'\s+', " ", response_json) in re.sub(r'\s+', " ", caplog.text)
def test_assemble_download_url(tmpdir, cachito_request): url = CachitoAPI(CACHITO_URL).assemble_download_url(cachito_request) assert url == CACHITO_REQUEST_DOWNLOAD_URL
def test_download_sources_bad_request_type(tmpdir): with pytest.raises(ValueError, match=r'Unexpected request type'): CachitoAPI(CACHITO_URL).download_sources('spam', str(tmpdir))
def test_wait_for_request_bad_request_type(): with pytest.raises(ValueError, match=r'Unexpected request type'): CachitoAPI(CACHITO_URL).wait_for_request('spam')