1616
1717import pathlib
1818import tempfile
19- import time
19+ import freezegun
2020import unittest
2121
2222from planet_auth .oidc .oidc_credential import FileBackedOidcCredential
@@ -164,7 +164,8 @@ def mock_api_call(under_test):
164164 # pre_request_hook()
165165 under_test .pre_request_hook ()
166166
167- def test_happy_path_1 (self ):
167+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
168+ def test_happy_path_1 (self , frozen_time ):
168169 # The first API call should trigger a token load from disk.
169170 # If the token is current, the auth client should be untouched.
170171 under_test = self .under_test_happy_path ()
@@ -185,13 +186,14 @@ def test_happy_path_1(self):
185186
186187 # When the token reaches the 3/4 life, the authenticator should
187188 # attempt a token refresh
188- time . sleep (((3 * TEST_TOKEN_TTL ) / 4 ) + 2 )
189+ frozen_time . tick (((3 * TEST_TOKEN_TTL ) / 4 ) + 2 )
189190 self .mock_api_call (under_test )
190191 self .assertEqual (1 , under_test ._auth_client .refresh .call_count )
191192 access_token_t3 = under_test ._credential .access_token ()
192193 self .assertNotEqual (access_token_t1 , access_token_t3 )
193194
194- def test_happy_path_1_in_memory (self ):
195+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
196+ def test_happy_path_1_in_memory (self , frozen_time ):
195197 # The first API call should trigger a token load from disk.
196198 # If the token is current, the auth client should be untouched.
197199 under_test = self .under_test_happy_path_in_memory ()
@@ -212,24 +214,26 @@ def test_happy_path_1_in_memory(self):
212214
213215 # When the token reaches the 3/4 life, the authenticator should
214216 # attempt a token refresh
215- time . sleep (((3 * TEST_TOKEN_TTL ) / 4 ) + 2 )
217+ frozen_time . tick (((3 * TEST_TOKEN_TTL ) / 4 ) + 2 )
216218 self .mock_api_call (under_test )
217219 self .assertEqual (1 , under_test ._auth_client .refresh .call_count )
218220 access_token_t3 = under_test ._credential .access_token ()
219221 self .assertNotEqual (access_token_t1 , access_token_t3 )
220222
221- def test_happy_path_2 (self ):
223+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
224+ def test_happy_path_2 (self , frozen_time ):
222225 # The first API call should trigger a token load.
223226 # If the token is past the refresh time, a token refresh should be
224227 # attempted before the first use
225228 under_test = self .under_test_happy_path ()
226229
227- time . sleep (TEST_TOKEN_TTL + 2 )
230+ frozen_time . tick (TEST_TOKEN_TTL + 2 )
228231 self .mock_api_call (under_test )
229232 self .assertIsNotNone (under_test ._credential .data ())
230233 self .assertEqual (1 , under_test ._auth_client .refresh .call_count )
231234
232- def test_refresh_fails (self ):
235+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
236+ def test_refresh_fails (self , frozen_time ):
233237 # Refresh could fail. If it does, this should be buried and we
234238 # should try to carry on with the token we have.
235239 # (this is why we refresh before expiry, so transient failures
@@ -242,15 +246,16 @@ def test_refresh_fails(self):
242246 self .assertEqual (0 , under_test ._auth_client .refresh .call_count )
243247 access_token_t1 = under_test ._credential .access_token ()
244248
245- time . sleep (TEST_TOKEN_TTL + 2 )
249+ frozen_time . tick (TEST_TOKEN_TTL + 2 )
246250
247251 self .mock_api_call (under_test )
248252 self .assertEqual (1 , under_test ._auth_client .refresh .call_count )
249253 access_token_t2 = under_test ._credential .access_token ()
250254
251255 self .assertEqual (access_token_t1 , access_token_t2 )
252256
253- def test_no_refresh_token (self ):
257+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
258+ def test_no_refresh_token (self , frozen_time ):
254259 # if we have no refresh token, what happens when we expect to
255260 # refresh? It's not expected that a user use the refreshing
256261 # authenticator when not using a refresh token (there is another
@@ -265,22 +270,23 @@ def test_no_refresh_token(self):
265270 access_token_t1 = under_test ._credential .access_token ()
266271 self .assertEqual (0 , under_test ._auth_client .refresh .call_count )
267272
268- time . sleep (TEST_TOKEN_TTL + 2 )
273+ frozen_time . tick (TEST_TOKEN_TTL + 2 )
269274
270275 self .mock_api_call (under_test )
271276 self .assertEqual (1 , under_test ._auth_client .refresh .call_count )
272277 access_token_t2 = under_test ._credential .access_token ()
273278 self .assertEqual (access_token_t1 , access_token_t2 )
274279
275- def test_no_auth_client (self ):
280+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
281+ def test_no_auth_client (self , frozen_time ):
276282 # when no auth client is provided, just authenticate with what we
277283 # have.
278284 under_test = self .under_test_no_auth_client ()
279285
280286 self .mock_api_call (under_test )
281287 access_token_t1 = under_test ._credential .access_token ()
282288
283- time . sleep (TEST_TOKEN_TTL + 2 )
289+ frozen_time . tick (TEST_TOKEN_TTL + 2 )
284290
285291 self .mock_api_call (under_test )
286292 access_token_t2 = under_test ._credential .access_token ()
@@ -304,7 +310,8 @@ def test_no_access_token(self):
304310 self .mock_api_call (under_test )
305311 self .assertEqual (1 , under_test ._auth_client .refresh .call_count )
306312
307- def test_out_of_band_update_1 (self ):
313+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
314+ def test_out_of_band_update_1 (self , frozen_time ):
308315 # Out of band credential update. We expect the refresher to reload
309316 # the credential file without attempting a refresh.
310317 under_test = self .under_test_happy_path ()
@@ -315,7 +322,7 @@ def test_out_of_band_update_1(self):
315322 self .assertEqual (0 , under_test ._auth_client .refresh .call_count )
316323 access_token_t1 = under_test ._credential .access_token ()
317324
318- time . sleep (TEST_TOKEN_TTL + 2 )
325+ frozen_time . tick (TEST_TOKEN_TTL + 2 )
319326
320327 credential_t1 = under_test ._credential
321328 oob_credential = self .stub_auth_client .refresh (credential_t1 .refresh_token ())
@@ -330,7 +337,8 @@ def test_out_of_band_update_1(self):
330337 self .assertNotEqual (access_token_t1 , access_token_t2 )
331338 self .assertEqual (access_token_oob , access_token_t2 )
332339
333- def test_out_of_band_update_2 (self ):
340+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
341+ def test_out_of_band_update_2 (self , frozen_time ):
334342 # Out of band credential update. Something updated the credential
335343 # on disk underneath us. We expect the refresher to reload
336344 # the credential file without attempting a refresh.
@@ -348,7 +356,7 @@ def test_out_of_band_update_2(self):
348356 oob_credential .save ()
349357 access_token_oob = oob_credential .access_token ()
350358
351- time . sleep (TEST_TOKEN_TTL + 2 )
359+ frozen_time . tick (TEST_TOKEN_TTL + 2 )
352360
353361 # The new token is outside TTL, even after the token is reloaded, this
354362 # should be detected and a refresh should still occur.
@@ -358,7 +366,8 @@ def test_out_of_band_update_2(self):
358366 self .assertNotEqual (access_token_t1 , access_token_t2 )
359367 self .assertNotEqual (access_token_oob , access_token_t2 )
360368
361- def test_side_band_update_credential (self ):
369+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
370+ def test_side_band_update_credential (self , frozen_time ):
362371 # a side-band update of the credential should reset our "refresh at" time,
363372 # cascading behavior from there. Where the above happens when someone
364373 # modifies a credential on disk, this happens when something in memory
@@ -378,7 +387,7 @@ def test_side_band_update_credential(self):
378387 self .assertEqual (0 , under_test ._auth_client .refresh .call_count )
379388
380389 # Get the sideband credential when we would have expected a refresh to probe behavior.
381- time . sleep (TEST_TOKEN_TTL + 2 )
390+ frozen_time . tick (TEST_TOKEN_TTL + 2 )
382391 sideband_credential_path = self .tmp_dir_path / "test_sideband.json"
383392 sideband_credential = self .mock_auth_login_and_command_initialize (
384393 credential_path = sideband_credential_path , auth_client = self .stub_auth_client
@@ -461,7 +470,8 @@ def mock_api_call(self, under_test):
461470 # pre_request_hook()
462471 under_test .pre_request_hook ()
463472
464- def test_refresh_token_calls_refresh (self ):
473+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
474+ def test_refresh_token_calls_refresh (self , frozen_time ):
465475 under_test = self .under_test_with_refresh_token ()
466476
467477 self .assertIsNone (under_test ._credential .data ())
@@ -471,15 +481,16 @@ def test_refresh_token_calls_refresh(self):
471481 self .assertEqual (0 , under_test ._auth_client .login .call_count )
472482 access_token_t1 = under_test ._credential .access_token ()
473483
474- time . sleep (TEST_TOKEN_TTL + 2 )
484+ frozen_time . tick (TEST_TOKEN_TTL + 2 )
475485
476486 self .mock_api_call (under_test )
477487 self .assertEqual (1 , under_test ._auth_client .refresh .call_count )
478488 self .assertEqual (0 , under_test ._auth_client .login .call_count )
479489 access_token_t2 = under_test ._credential .access_token ()
480490 self .assertNotEqual (access_token_t1 , access_token_t2 )
481491
482- def test_no_refresh_token_calls_login (self ):
492+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
493+ def test_no_refresh_token_calls_login (self , frozen_time ):
483494 under_test = self .under_test_without_refresh_token ()
484495
485496 self .assertIsNone (under_test ._credential .data ())
@@ -489,23 +500,24 @@ def test_no_refresh_token_calls_login(self):
489500 self .assertEqual (0 , under_test ._auth_client .login .call_count )
490501 access_token_t1 = under_test ._credential .access_token ()
491502
492- time . sleep (TEST_TOKEN_TTL + 2 )
503+ frozen_time . tick (TEST_TOKEN_TTL + 2 )
493504
494505 self .mock_api_call (under_test )
495506 self .assertEqual (0 , under_test ._auth_client .refresh .call_count )
496507 self .assertEqual (1 , under_test ._auth_client .login .call_count )
497508 access_token_t2 = under_test ._credential .access_token ()
498509 self .assertNotEqual (access_token_t1 , access_token_t2 )
499510
500- def test_no_auth_client (self ):
511+ @freezegun .freeze_time (as_kwarg = "frozen_time" )
512+ def test_no_auth_client (self , frozen_time ):
501513 # when no auth client is provided, just authenticate with what we
502514 # have.
503515 under_test = self .under_test_no_auth_client ()
504516
505517 self .mock_api_call (under_test )
506518 access_token_t1 = under_test ._credential .access_token ()
507519
508- time . sleep (TEST_TOKEN_TTL + 2 )
520+ frozen_time . tick (TEST_TOKEN_TTL + 2 )
509521
510522 self .mock_api_call (under_test )
511523 access_token_t2 = under_test ._credential .access_token ()
0 commit comments