From 736fe82dc3c103fb54c883c3c0fc0ec1f383dc46 Mon Sep 17 00:00:00 2001 From: Michael Thornton Date: Mon, 16 Dec 2024 19:21:35 -0800 Subject: [PATCH] add integration test for refresh_token Cannot replicate the error with client with expired token --- nmdc_automation/api/nmdcapi.py | 36 +++++++++++----------- tests/site_configuration_test.toml | 2 +- tests/test_nmdcapi_integration.py | 48 +++++++++++++++++++++++++----- 3 files changed, 61 insertions(+), 25 deletions(-) diff --git a/nmdc_automation/api/nmdcapi.py b/nmdc_automation/api/nmdcapi.py index 2d0eac04..668a8913 100755 --- a/nmdc_automation/api/nmdcapi.py +++ b/nmdc_automation/api/nmdcapi.py @@ -49,7 +49,7 @@ def expiry_dt_from_now(days=0, hours=0, minutes=0, seconds=0): class NmdcRuntimeApi: token = None - expires_in_seconds = 0 + expires_at = 0 _base_url = None client_id = None client_secret = None @@ -67,7 +67,7 @@ def __init__(self, site_configuration: Union[str, Path, SiteConfig]): def refresh_token(func): def _get_token(self, *args, **kwargs): # If it expires in 60 seconds, refresh - if not self.token or self.expires_in_seconds + 60 > time(): + if not self.token or self.expires_at + 60 > time(): self.get_token() return func(self, *args, **kwargs) @@ -87,29 +87,31 @@ def get_token(self): "client_secret": self.client_secret, } url = self._base_url + "token" - resp = requests.post(url, headers=h, data=data).json() - expires = resp["expires"] + + resp = requests.post(url, headers=h, data=data) + + response_body = resp.json() # Expires can be in days, hours, minutes, seconds - sum them up and convert to seconds expires = 0 - if "days" in resp["expires"]: - expires += int(resp["expires"]["days"]) * SECONDS_IN_DAY - if "hours" in resp["expires"]: - expires += int(resp["expires"]["hours"]) * 3600 - if "minutes" in resp["expires"]: - expires += int(resp["expires"]["minutes"]) * 60 - if "seconds" in resp["expires"]: - expires += int(resp["expires"]["seconds"]) - - self.expires_in_seconds = time() + expires - - self.token = resp["access_token"] + if "days" in response_body["expires"]: + expires += int(response_body["expires"]["days"]) * SECONDS_IN_DAY + if "hours" in response_body["expires"]: + expires += int(response_body["expires"]["hours"]) * 3600 + if "minutes" in response_body["expires"]: + expires += int(response_body["expires"]["minutes"]) * 60 + if "seconds" in response_body["expires"]: + expires += int(response_body["expires"]["seconds"]) + + self.expires_at = time() + expires + + self.token = response_body["access_token"] self.header = { "accept": "application/json", "Content-Type": "application/json", "Authorization": "Bearer %s" % (self.token), } - return resp + return response_body def get_header(self): return self.header diff --git a/tests/site_configuration_test.toml b/tests/site_configuration_test.toml index 06173330..dec4f344 100644 --- a/tests/site_configuration_test.toml +++ b/tests/site_configuration_test.toml @@ -14,7 +14,7 @@ site = "Processing Site" [nmdc] url_root = "https://data.microbiomedata.org/data/" -api_url = "http://localhost" +api_url = "http://localhost:8000" [state] watch_state = "State File" diff --git a/tests/test_nmdcapi_integration.py b/tests/test_nmdcapi_integration.py index d03b2bc5..00a5175e 100644 --- a/tests/test_nmdcapi_integration.py +++ b/tests/test_nmdcapi_integration.py @@ -2,6 +2,7 @@ import pytest import requests +from time import time from nmdc_automation.api.nmdcapi import NmdcRuntimeApi as nmdcapi @@ -12,20 +13,53 @@ def test_integration_environment(): """ Test that the integration environment is set up correctly: - Runtime API server is running on localhost port 8000 - - MongoDB is running on localhost port 27017 - - The site 'NERSC' exists in the API + - The site 'NERSC' exists in the sites endpoint If any of these conditions are not met, the test will fail, and the remaining integration tests will be skipped. """ - # response = requests.get("http://localhost:8000") - # assert response.status_code == 200 - assert False, "Unimplemented" + response = requests.get("http://localhost:8000") + assert response.status_code == 200 + response = requests.get("http://localhost:8000/sites/NERSC") + assert response.status_code == 200 + response_body = response.json() + assert response_body["id"] == "NERSC" @pytest.mark.integration -def test_nmdcapi_basics(requests_mock, site_config_file): - assert False, "Unimplemented" +def test_nmdcapi_get_token(site_config_file): + n = nmdcapi(site_config_file) + + assert n.expires_at == 0 + token_resp = n.get_token() + assert token_resp["expires"]["days"] == 1 + + assert n.expires_at > 0 + assert n.token is not None + + +@pytest.mark.integration +def test_nmdcapi_list_jobs_refreshes_token(site_config_file): + # initial client state - no token + n = nmdcapi(site_config_file) + assert n.expires_at == 0 + assert n.token is None + + # list_jobs will invoke refresh_token + jobs = n.list_jobs() + assert jobs is not None + assert n.token is not None + # should be at least an hour in the future + assert n.expires_at > time() + 3600 + + # set the token to expire now + n.expires_at = time() + assert n.expires_at < time() + jobs = n.list_jobs() + assert jobs is not None + assert n.token is not None + # should be at least an hour in the future again + assert n.expires_at > time() + 3600