From 6d597d34d301f176779be63db183d05961e50133 Mon Sep 17 00:00:00 2001 From: Andrew Williamson Date: Tue, 14 Oct 2025 17:48:31 +0100 Subject: [PATCH] replace freezegun with time-machine --- requirements/dev.txt | 93 ++++++++++- src/olympia/abuse/tests/test_tasks.py | 6 +- src/olympia/abuse/tests/test_views.py | 16 +- src/olympia/accounts/tests/test_verify.py | 8 +- src/olympia/accounts/tests/test_views.py | 10 +- src/olympia/addons/tests/test_commands.py | 8 +- src/olympia/addons/tests/test_tasks.py | 8 +- src/olympia/addons/tests/test_utils_.py | 42 ++--- src/olympia/addons/tests/test_views.py | 4 +- src/olympia/amo/tests/test_commands.py | 4 +- src/olympia/amo/tests/test_utils.py | 4 +- src/olympia/api/tests/test_authentication.py | 4 +- src/olympia/api/tests/test_throttling.py | 15 +- src/olympia/api/throttling.py | 2 +- src/olympia/blocklist/tests/test_admin.py | 63 ++++---- src/olympia/blocklist/tests/test_cron.py | 6 +- src/olympia/devhub/tests/test_forms.py | 6 +- src/olympia/devhub/tests/test_views.py | 20 ++- src/olympia/files/tests/test_views.py | 30 ++-- src/olympia/promoted/tests/test_tasks.py | 4 +- src/olympia/ratings/tests/test_tasks.py | 6 +- src/olympia/ratings/tests/test_views.py | 146 +++++++++--------- src/olympia/reviewers/tests/test_commands.py | 8 +- src/olympia/reviewers/tests/test_cron.py | 8 +- src/olympia/reviewers/tests/test_forms.py | 8 +- .../reviewers/tests/test_review_reports.py | 44 +++--- src/olympia/reviewers/tests/test_views.py | 12 +- src/olympia/scanners/tests/test_models.py | 9 +- src/olympia/search/tests/test_filters.py | 20 +-- src/olympia/signing/tests/test_views.py | 36 ++--- src/olympia/users/tests/test_models.py | 10 +- src/olympia/users/tests/test_user_utils.py | 4 +- src/olympia/versions/tests/test_utils.py | 14 +- 33 files changed, 393 insertions(+), 285 deletions(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 9af51089492d..7c411d925308 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -97,9 +97,6 @@ pytest-xdist==3.8.0 \ pytest-forked==1.6.0 \ --hash=sha256:4dafd46a9a600f65d822b8f605133ecf5b3e1941ebb3588e943b4e3eb71a5a3f \ --hash=sha256:810958f66a91afb1a1e2ae83089d8dc1cd2437ac96b12963042fbb9fb4d16af0 -freezegun==1.5.3 \ - --hash=sha256:1ce20ee4be61349ba52c3af64f5eaba8d08ff51acfcf1b3ea671f03e54c818f1 \ - --hash=sha256:d7c6204e33a50affd7c7aa284f4f92e04e96f72d63313b89ceaaf60d9c64bc5e responses==0.25.8 \ --hash=sha256:0c710af92def29c8352ceadff0c3fe340ace27cf5af1bbe46fb71275bcd2831c \ --hash=sha256:9374d047a575c8f781b94454db5cab590b6029505f488d12899ddb10a4af1cf4 @@ -351,3 +348,93 @@ networkx==3.5 \ pydot==4.0.1 \ --hash=sha256:869c0efadd2708c0be1f916eb669f3d664ca684bc57ffb7ecc08e70d5e93fee6 \ --hash=sha256:c2148f681c4a33e08bf0e26a9e5f8e4099a82e0e2a068098f32ce86577364ad5 +time-machine==2.19.0 \ + --hash=sha256:00bee4bb950ac6a08d62af78e4da0cf2b4fc2abf0de2320d0431bf610db06e7c \ + --hash=sha256:011954d951230a9f1079f22b39ed1a3a9abb50ee297dfb8c557c46351659d94d \ + --hash=sha256:011d7859089263204dc5fdf83dce7388f986fe833c9381d6106b4edfda2ebd3e \ + --hash=sha256:0390a1ea9fa7e9d772a39b7c61b34fdcca80eb9ffac339cc0441c6c714c81470 \ + --hash=sha256:0b529e262df3b9c449f427385f4d98250828c879168c2e00eec844439f40b370 \ + --hash=sha256:0fe81bae55b7aefc2c2a34eb552aa82e6c61a86b3353a3c70df79b9698cb02ca \ + --hash=sha256:13ed8b34430f1de79905877f5600adffa626793ab4546a70a99fb72c6a3350d8 \ + --hash=sha256:149072aff8e3690e14f4916103d898ea0d5d9c95531b6aa0995251c299533f7b \ + --hash=sha256:16f5d81f650c0a4d117ab08036dc30b5f8b262e11a4a0becc458e7f1c011b228 \ + --hash=sha256:206fcd6c9a6f00cac83db446ad1effc530a8cec244d2780af62db3a2d0a9871b \ + --hash=sha256:2415b7495ec4364c8067071e964fbadfe746dd4cdb43983f2f0bd6ebed13315c \ + --hash=sha256:2851825b524a988ee459c37c1c26bdfaa7eff78194efb2b562ea497a6f375b0a \ + --hash=sha256:29e84b8682645b16eb6f9e8ec11c35324ad091841a11cf4fc3fc7f6119094c89 \ + --hash=sha256:2eaa1c675d500dc3ccae19e9fb1feff84458a68c132bbea47a80cc3dd2df7072 \ + --hash=sha256:304315023999cd401ff02698870932b893369e1cfeb2248d09f6490507a92e97 \ + --hash=sha256:31cb43c8fd2d961f31bed0ff4e0026964d2b35e5de9e0fabbfecf756906d3612 \ + --hash=sha256:39733ef844e2984620ec9382a42d00cccc4757d75a5dd572be8c2572e86e50b9 \ + --hash=sha256:3ae0a8b869574301ec5637e32c270c7384cca5cd6e230f07af9d29271a7fa293 \ + --hash=sha256:426aba552f7af9604adad9ef570c859af7c1081d878db78089fac159cd911b0a \ + --hash=sha256:46f1c945934ce3d6b4f388b8e581fce7f87ec891ea90d7128e19520e434f96f0 \ + --hash=sha256:4a11f1c0e0d06023dc01614c964e256138913551d3ae6dca5148f79081156336 \ + --hash=sha256:4bb5bd43b1bdfac3007b920b51d8e761f024ed465cfeec63ac4296922a4ec428 \ + --hash=sha256:536bd1ac31ab06a1522e7bf287602188f502dc19d122b1502c4f60b1e8efac79 \ + --hash=sha256:554e4317de90e2f7605ff80d153c8bb56b38c0d0c0279feb17e799521e987b8c \ + --hash=sha256:56f26ab9f0201c453d18fe76bb7d1cf05fe58c1b9d9cb0c7d243d05132e01292 \ + --hash=sha256:57a235a6307c54df50e69f1906e2f199e47da91bde4b886ee05aff57fe4b6bf6 \ + --hash=sha256:5e172866753e6041d3b29f3037dc47c20525176a494a71bbd0998dfdc4f11f2f \ + --hash=sha256:5ee91664880434d98e41585c3446dac7180ec408c786347451ddfca110d19296 \ + --hash=sha256:60c46ab527bf2fa144b530f639cc9e12803524c9e1f111dc8c8f493bb6586eeb \ + --hash=sha256:645699616ec14e147094f601e6ab9553ff6cea37fad9c42720a6d7ed04bcd5dc \ + --hash=sha256:6567a5ec5538ed550539ac29be11b3cb36af1f9894e2a72940cba0292cc7c3c9 \ + --hash=sha256:67772c7197a3a712d1b970ed545c6e98db73524bd90e245fd3c8fa7ad7630768 \ + --hash=sha256:68d32b09ecfd7fef59255c091e8e7c24dd117f882c4880b5c7ab8c5c32a98f89 \ + --hash=sha256:6ba0303e9cc9f7f947e344f501e26bedfb68fab521e3c2729d370f4f332d2d55 \ + --hash=sha256:6c806cf3c1185baa1d807b7f51bed0db7a6506832c961d5d1b4c94c775749bc0 \ + --hash=sha256:714c40b2c90d1c57cc403382d5a9cf16e504cb525bfe9650095317da3c3d62b5 \ + --hash=sha256:7253791b8d7e7399fbeed7a8193cb01bc004242864306288797056badbdaf80b \ + --hash=sha256:72bf66cd19e27ffd26516b9cbe676d50c2e0b026153289765dfe0cf406708128 \ + --hash=sha256:72dbd4cbc3d96dec9dd281ddfbb513982102776b63e4e039f83afb244802a9e5 \ + --hash=sha256:77f9bb0b86758d1f2d9352642c874946ad5815df53ef4ca22eb9d532179fe50d \ + --hash=sha256:7837ef3fd5911eb9b480909bb93d922737b6bdecea99dfcedb0a03807de9b2d3 \ + --hash=sha256:7887e85275c4975fe54df03dcdd5f38bd36be973adc68a8c77e17441c3b443d6 \ + --hash=sha256:7c5065a8b3f2bbb449422c66ef71d114d3f909c276a6469642ecfffb6a0fcd29 \ + --hash=sha256:7e1c4e578cdd69b3531d8dd3fbcb92a0cd879dadb912ee37af99c3a9e3c0d285 \ + --hash=sha256:82e9ffe8dfff07b0d810a2ad015a82cd78c6a237f6c7cf185fa7f747a3256f8a \ + --hash=sha256:85bb7ed440fccf6f6d0c8f7d68d849e7c3d1f771d5e0b2cdf871fa6561da569f \ + --hash=sha256:8e20a6d8d6e23174bd7e931e134d9610b136db460b249d07e84ecdad029ec352 \ + --hash=sha256:8e9c6363893e7f52c226afbebb23e825259222d100e67dfd24c8a6d35f1a1907 \ + --hash=sha256:9199246e31cdc810e5d89cb71d09144c4d745960fdb0824da4994d152aca3303 \ + --hash=sha256:9247c4bb9bbd3ff584ef4efbdec8efd9f37aa08bcfc4728bde1e489c2cb445bd \ + --hash=sha256:95afc9bc65228b27be80c2756799c20b8eb97c4ef382a9b762b6d7888bc84099 \ + --hash=sha256:9765d4f003f263ea8bfd90d2d15447ca4b3dfa181922cf6cf808923b02ac180a \ + --hash=sha256:9f02199490906582302ce09edd32394fb393271674c75d7aa76c7a3245f16003 \ + --hash=sha256:a3b12028af1cdc09ccd595be2168b7b26f206c1e190090b048598fbe278beb8e \ + --hash=sha256:a3b8981f9c663b0906b05ab4d0ca211fae4b63b47c6ec26de5374fe56c836162 \ + --hash=sha256:a430e4d0e0556f021a9c78e9b9f68e5e8910bdace4aa34ed4d1a73e239ed9384 \ + --hash=sha256:a62fd1ab380012c86f4c042010418ed45eb31604f4bf4453e17c9fa60bc56a29 \ + --hash=sha256:b0f83308b29c7872006803f2e77318874eb84d0654f2afe0e48e3822e7a2e39b \ + --hash=sha256:b25ec853a4530a5800731257f93206b12cbdee85ede964ebf8011b66086a7914 \ + --hash=sha256:b30039dfd89855c12138095bee39c540b4633cbc3684580d684ef67a99a91587 \ + --hash=sha256:b32daa965d13237536ea3afaa5ad61ade2b2d9314bc3a20196a0d2e1d7b57c6a \ + --hash=sha256:b5169018ef47206997b46086ce01881cd3a4666fd2998c9d76a87858ca3e49e9 \ + --hash=sha256:bdf481a75afc6bff3e520db594501975b652f7def21cd1de6aa971d35ba644e6 \ + --hash=sha256:bf33016a1403c123373ffaeff25e26e69d63bf2c63b6163932efed94160db7ef \ + --hash=sha256:c261f073086cf081d1443cbf7684148c662659d3d139d06b772bfe3fe7cc71a6 \ + --hash=sha256:c85cf437dc3c07429456d8d6670ac90ecbd8241dcd0fbf03e8db2800576f91ff \ + --hash=sha256:cc29a50a0257d8750b08056b66d7225daab47606832dea1a69e8b017323bf511 \ + --hash=sha256:cd93996970e11c382b04d4937c3cd0b0167adeef14725ece35aae88d8a01733c \ + --hash=sha256:ce0be294c209928563fcce1c587963e60ec803436cf1e181acd5bc1e425d554b \ + --hash=sha256:d821c60efc08a97cc11e5482798e6fd5eba5c0f22a02db246b50895dbdc0de41 \ + --hash=sha256:d8bb00b30ec9fe56d01e9812df1ffe39f331437cef9bfaebcc81c83f7f8f8ee2 \ + --hash=sha256:d9238897e8ef54acdf59f5dff16f59ca0720e7c02d820c56b4397c11db5d3eb9 \ + --hash=sha256:dbfc6b90c10f288594e1bf89a728a98cc0030791fd73541bbdc6b090aff83143 \ + --hash=sha256:e17e3e089ac95f9a145ce07ff615e3c85674f7de36f2d92aaf588493a23ffb4b \ + --hash=sha256:e1af66550fa4685434f00002808a525f176f1f92746646c0019bb86fbff48b27 \ + --hash=sha256:e312c7d5d6bfffb96c6a7b39ff29e3046de100d7efaa3c01552654cfbd08f14c \ + --hash=sha256:e35726c7ba625f844c13b1fc0d4f81f394eefaee1d3a094a9093251521f2ef15 \ + --hash=sha256:e69e0b0f694728a00e72891ef8dd00c7542952cb1c87237db594b6b27d504a96 \ + --hash=sha256:e77a414e9597988af53b2b2e67242c9d2f409769df0d264b6d06fda8ca3360d4 \ + --hash=sha256:e84909af950e2448f4e2562ea5759c946248c99ab380d2b47d79b62bd76fa236 \ + --hash=sha256:ed3732b83a893d1c7b8cabde762968b4dc5680ee0d305b3ecca9bb516f4e3862 \ + --hash=sha256:f3589fee1ed0ab6ee424a55b0ea1ec694c4ba64cc26895bcd7d99f3d1bc6a28a \ + --hash=sha256:f379c6f8a6575a8284592179cf528ce89373f060301323edcc44f1fa1d37be12 \ + --hash=sha256:f583bbd0aa8ab4a7c45a684bf636d9e042d466e30bcbae1d13e7541e2cbe7207 \ + --hash=sha256:f70f68379bd6f542ae6775cce9a4fa3dcc20bf7959c42eaef871c14469e18097 \ + --hash=sha256:f8db99f6334432e9ffbf00c215caf2ae9773f17cec08304d77e9e90febc3507b \ + --hash=sha256:fb051aec7b3b6e96a200d911c225901e6133ff3da11e470e24111a53bbc13637 \ + --hash=sha256:fb4897c7a5120a4fd03f0670f332d83b7e55645886cd8864a71944c4c2e5b35b \ + --hash=sha256:fe59909d95a2ef5e01ce3354fdea3908404c2932c2069f00f66dff6f27e9363e diff --git a/src/olympia/abuse/tests/test_tasks.py b/src/olympia/abuse/tests/test_tasks.py index d32f9b65b453..8efa340f9479 100644 --- a/src/olympia/abuse/tests/test_tasks.py +++ b/src/olympia/abuse/tests/test_tasks.py @@ -7,8 +7,8 @@ import pytest import responses +import time_machine from celery.exceptions import Retry -from freezegun import freeze_time from olympia import amo from olympia.activity.models import ActivityLog @@ -194,7 +194,7 @@ def _high_abuse_reports_setup(field): return not_flagged, flagged -@freeze_time('2023-06-26 11:00') +@time_machine.travel('2023-06-26 11:00', tick=False) @pytest.mark.django_db def test_flag_high_abuse_reports_addons_according_to_review_tier(): set_config(amo.config_keys.EXTRA_REVIEW_TARGET_PER_DAY, '1') @@ -253,7 +253,7 @@ def test_flag_high_abuse_reports_addons_according_to_review_tier(): ] -@freeze_time('2023-06-26 11:00') +@time_machine.travel('2023-06-26 11:00', tick=False) @pytest.mark.django_db def test_block_high_abuse_reports_addons_according_to_review_tier(): not_blocked, blocked = _high_abuse_reports_setup( diff --git a/src/olympia/abuse/tests/test_views.py b/src/olympia/abuse/tests/test_views.py index 921afb19d810..442bf1c4d113 100644 --- a/src/olympia/abuse/tests/test_views.py +++ b/src/olympia/abuse/tests/test_views.py @@ -11,7 +11,7 @@ from django.urls import reverse from django.utils.encoding import force_bytes -from freezegun import freeze_time +import time_machine from pyquery import PyQuery as pq from rest_framework.test import APIRequestFactory from waffle.testutils import override_switch @@ -3188,7 +3188,7 @@ def test_throttling_initial_email_form(self): action=DECISION_ACTIONS.AMO_BAN_USER, addon=None, user=target ) self.abuse_report.update(guid=None, user=target) - with freeze_time() as frozen_time: + with time_machine.travel(datetime.now(), tick=False) as frozen_time: for _x in range(0, 20): self._add_fake_throttling_action( view_class=AbuseAppealEmailForm, @@ -3209,7 +3209,7 @@ def test_throttling_initial_email_form(self): assert doc('ul.errorlist').text() == expected_error_message # Advance 23 hours, still blocked for that IP. - frozen_time.tick(delta=timedelta(hours=21)) + frozen_time.shift(delta=timedelta(hours=21)) assert ( expected_error_message in response.context_data['appeal_email_form'].non_field_errors() @@ -3218,7 +3218,7 @@ def test_throttling_initial_email_form(self): assert doc('ul.errorlist').text() == expected_error_message # Advance one day to be able to submit again with the same IP. - frozen_time.tick(delta=timedelta(hours=24, seconds=1)) + frozen_time.shift(delta=timedelta(hours=24, seconds=1)) response = self.client.post( self.author_appeal_url, {'email': target.email}, @@ -3243,7 +3243,7 @@ def test_throttling_doesnt_reveal_validation_state_fields(self): action=DECISION_ACTIONS.AMO_BAN_USER, addon=None, user=target ) self.abuse_report.update(guid=None, user=target) - with freeze_time(): + with time_machine.travel(datetime.now(), tick=False): for _x in range(0, 20): self._add_fake_throttling_action( view_class=AbuseAppealEmailForm, @@ -3274,7 +3274,7 @@ def test_throttling_appeal_form(self): user = user_factory() self.addon.authors.add(user) self.client.force_login(user) - with freeze_time() as frozen_time: + with time_machine.travel(datetime.now(), tick=False) as frozen_time: for _x in range(0, 20): self._add_fake_throttling_action( view_class=AbuseAppealForm, @@ -3296,7 +3296,7 @@ def test_throttling_appeal_form(self): assert not doc('#appeal-thank-you') # Advance 23 hours, still blocked for that IP. - frozen_time.tick(delta=timedelta(hours=23)) + frozen_time.shift(delta=timedelta(hours=23)) assert ( expected_error_message in response.context_data['appeal_form'].non_field_errors() @@ -3306,7 +3306,7 @@ def test_throttling_appeal_form(self): assert not doc('#appeal-thank-you') # Advance one day to be able to submit again with the same IP. - frozen_time.tick(delta=timedelta(hours=24, seconds=1)) + frozen_time.shift(delta=timedelta(hours=24, seconds=1)) response = self.client.post( self.author_appeal_url, {'reason': 'I dont like this'}, diff --git a/src/olympia/accounts/tests/test_verify.py b/src/olympia/accounts/tests/test_verify.py index 8845c3c4d2f2..f1ab8f91484c 100644 --- a/src/olympia/accounts/tests/test_verify.py +++ b/src/olympia/accounts/tests/test_verify.py @@ -7,7 +7,7 @@ from django.test.utils import override_settings import pytest -from freezegun import freeze_time +import time_machine from olympia.accounts import verify from olympia.amo.tests import TestCase @@ -278,7 +278,7 @@ def test_session_access_token_expiry_okay(self): self.get_fxa_token_mock.assert_not_called() assert request.session['fxa_access_token_expiry'] == tomorrow - @freeze_time() + @time_machine.travel(datetime.now(), tick=False) def test_refresh_success(self): request = self.get_request() @@ -299,7 +299,7 @@ def test_refresh_success(self): == (self.get_fxa_token_mock.return_value['access_token_expiry']) ) - @freeze_time() + @time_machine.travel(datetime.now(), tick=False) def test_refresh_fail(self): yesterday = (datetime.now() - timedelta(days=1)).timestamp() request = self.get_request(yesterday) @@ -313,7 +313,7 @@ def test_refresh_fail(self): # i.e. it's still expired assert request.session['fxa_access_token_expiry'] == yesterday - @freeze_time() + @time_machine.travel(datetime.now(), tick=False) def test_refresh_token_missing(self): request = self.get_request() del request.session['fxa_refresh_token'] diff --git a/src/olympia/accounts/tests/test_views.py b/src/olympia/accounts/tests/test_views.py index 5f3d0adb4a8a..bfea226f3b2f 100644 --- a/src/olympia/accounts/tests/test_views.py +++ b/src/olympia/accounts/tests/test_views.py @@ -15,9 +15,9 @@ from django.urls import reverse from django.utils.encoding import force_str -import freezegun import jwt import responses +import time_machine from rest_framework import exceptions from rest_framework.settings import api_settings from rest_framework.test import APIClient, APIRequestFactory @@ -2411,7 +2411,7 @@ def test_post(self): with ( mock.patch(f'{class_path}.get_jwt_payload') as get_jwt_mock, mock.patch(f'{class_path}.process_event') as process_event_mock, - freezegun.freeze_time(), + time_machine.travel(datetime.now(), tick=False), ): get_jwt_mock.return_value = self.FXA_EVENT response = self.client.post(url) @@ -2424,7 +2424,7 @@ def test_post(self): @mock.patch('olympia.accounts.views.primary_email_change_event.delay') def test_process_event_email_change(self, event_mock): - with freezegun.freeze_time(): + with time_machine.travel(datetime.now(), tick=False): FxaNotificationView().process_event( self.FXA_ID, FxaNotificationView.FXA_PROFILE_CHANGE_EVENT, @@ -2440,7 +2440,7 @@ def test_process_event_email_change_integration(self): fxa_id=self.FXA_ID, email_changed=datetime(2017, 10, 11), ) - with freezegun.freeze_time(): + with time_machine.travel(datetime.now(), tick=False): FxaNotificationView().process_event( self.FXA_ID, FxaNotificationView.FXA_PROFILE_CHANGE_EVENT, @@ -2453,7 +2453,7 @@ def test_process_event_email_change_integration(self): @mock.patch('olympia.accounts.views.delete_user_event.delay') def test_process_event_delete(self, event_mock): - with freezegun.freeze_time(): + with time_machine.travel(datetime.now(), tick=False): FxaNotificationView().process_event( self.FXA_ID, FxaNotificationView.FXA_DELETE_EVENT, diff --git a/src/olympia/addons/tests/test_commands.py b/src/olympia/addons/tests/test_commands.py index e4ad9500fbea..8c56c8398fb2 100644 --- a/src/olympia/addons/tests/test_commands.py +++ b/src/olympia/addons/tests/test_commands.py @@ -8,7 +8,7 @@ from django.core.management.base import CommandError import pytest -from freezegun import freeze_time +import time_machine from olympia import amo from olympia.abuse.models import AbuseReport @@ -61,7 +61,7 @@ def _subtask_wrapper(*args, **kwargs): original_function.subtask = original_function_subtask -@freeze_time('2019-04-01') +@time_machine.travel('2019-04-01', tick=False) @pytest.mark.django_db def test_process_addons_limit_addons(): user_factory(id=settings.TASK_USER_ID) @@ -369,7 +369,7 @@ def test_basic(self, bump_addon_version_mock): file_kw = {'filename': 'webextension.xpi', 'is_signed': True} user_factory(id=settings.TASK_USER_ID) - with freeze_time('2019-04-01'): + with time_machine.travel('2019-04-01', tick=False): addon_with_history = addon_factory(file_kw=file_kw) # Create a few more versions for this add-on to test that we only # re-sign current versions @@ -389,7 +389,7 @@ def test_basic(self, bump_addon_version_mock): addon_factory(disabled_by_user=True, file_kw=file_kw) # Don't resign add-ons created after April 4th 2019 - with freeze_time('2019-05-01'): + with time_machine.travel('2019-05-01', tick=False): addon_factory(file_kw=file_kw) addon_factory(type=amo.ADDON_STATICTHEME, file_kw=file_kw) diff --git a/src/olympia/addons/tests/test_tasks.py b/src/olympia/addons/tests/test_tasks.py index aaa5d36613fc..12a7a0f7f13a 100644 --- a/src/olympia/addons/tests/test_tasks.py +++ b/src/olympia/addons/tests/test_tasks.py @@ -7,7 +7,7 @@ from django.conf import settings import pytest -from freezegun import freeze_time +import time_machine from PIL import Image from waffle.testutils import override_switch @@ -253,7 +253,7 @@ def test_update_addon_hotness(): assert addon2.hotness == 0 -@freeze_time('2023-05-15 11:00') +@time_machine.travel('2023-05-15 11:00', tick=False) @pytest.mark.django_db def test_flag_high_hotness_according_to_review_tier(): user_factory(pk=settings.TASK_USER_ID) @@ -397,7 +397,7 @@ def test_flag_high_hotness_according_to_review_tier(): ] -@freeze_time('2023-05-15 11:00') +@time_machine.travel('2023-05-15 11:00', tick=False) @pytest.mark.django_db def test_flag_high_hotness_according_to_review_tier_threshold_check( django_assert_num_queries, @@ -452,7 +452,7 @@ def test_flag_high_hotness_according_to_review_tier_threshold_check( ) -@freeze_time('2023-05-15 11:00') +@time_machine.travel('2023-05-15 11:00', tick=False) @pytest.mark.django_db def test_flag_high_hotness_according_to_review_tier_threshold_check_negative(): user_factory(pk=settings.TASK_USER_ID) diff --git a/src/olympia/addons/tests/test_utils_.py b/src/olympia/addons/tests/test_utils_.py index 0e003beee33b..4bf488cd690b 100644 --- a/src/olympia/addons/tests/test_utils_.py +++ b/src/olympia/addons/tests/test_utils_.py @@ -1,9 +1,9 @@ -from datetime import timedelta +from datetime import datetime, timedelta from django.forms import ValidationError import pytest -from freezegun import freeze_time +import time_machine from olympia.amo.tests import TestCase, addon_factory, user_factory from olympia.users.models import Group, GroupUser @@ -128,24 +128,24 @@ def test_get_filtered_fallbacks(self): assert len(recommendations) == 4 -@freeze_time(as_kwarg='frozen_time') -def test_delete_token_signer(frozen_time=None): +def test_delete_token_signer(): signer = DeleteTokenSigner() addon_id = 1234 - token = signer.generate(addon_id) - # generated token is valid - assert signer.validate(token, addon_id) - # generating with the same addon_id at the same time returns the same value - assert token == signer.generate(addon_id) - # generating with a different addon_id at the same time returns a different value - assert token != signer.generate(addon_id + 1) - # and the addon_id must match for it to be a valid token - assert not signer.validate(token, addon_id + 1) - - # token is valid for 60 seconds so after 59 is still valid - frozen_time.tick(timedelta(seconds=59)) - assert signer.validate(token, addon_id) - - # but not after 60 seconds - frozen_time.tick(timedelta(seconds=2)) - assert not signer.validate(token, addon_id) + with time_machine.travel(datetime.now(), tick=False) as frozen_time: + token = signer.generate(addon_id) + # generated token is valid + assert signer.validate(token, addon_id) + # generating with the same addon_id at the same time returns the same value + assert token == signer.generate(addon_id) + # generating with a different addon_id at the same time returns different value + assert token != signer.generate(addon_id + 1) + # and the addon_id must match for it to be a valid token + assert not signer.validate(token, addon_id + 1) + + # token is valid for 60 seconds so after 59 is still valid + frozen_time.shift(timedelta(seconds=59)) + assert signer.validate(token, addon_id) + + # but not after 60 seconds + frozen_time.shift(timedelta(seconds=2)) + assert not signer.validate(token, addon_id) diff --git a/src/olympia/addons/tests/test_views.py b/src/olympia/addons/tests/test_views.py index 5244e8700563..7948232f1956 100644 --- a/src/olympia/addons/tests/test_views.py +++ b/src/olympia/addons/tests/test_views.py @@ -21,8 +21,8 @@ from django.utils.http import urlsafe_base64_encode import pytest +import time_machine from elasticsearch import Elasticsearch -from freezegun import freeze_time from rest_framework.exceptions import ErrorDetail from rest_framework.test import APIRequestFactory from waffle import switch_is_active @@ -2878,7 +2878,7 @@ def setUp(self): 'addon-detail', kwargs={'pk': self.addon.pk}, api_version='v5' ) - @freeze_time() + @time_machine.travel(datetime.now(), tick=False) def test_delete_confirm(self): delete_confirm_url = f'{self.url}delete_confirm/' diff --git a/src/olympia/amo/tests/test_commands.py b/src/olympia/amo/tests/test_commands.py index 81a2694a5fe4..15fc3038c0be 100644 --- a/src/olympia/amo/tests/test_commands.py +++ b/src/olympia/amo/tests/test_commands.py @@ -15,7 +15,7 @@ import pytest import responses -from freezegun import freeze_time +import time_machine from responses import registries from olympia.amo.management import BaseDataCommand, storage_structure @@ -531,7 +531,7 @@ def setUp(self): self.addCleanup(patcher.stop) self.mocks[mock_name] = patcher.start() - @freeze_time('2023-06-26 11:00:44') + @time_machine.travel('2023-06-26 11:00:44', tick=False) def test_default_name(self): print('backup', self.backup_dir) backup_dir = os.path.join(self.backup_dir, '20230626110044') diff --git a/src/olympia/amo/tests/test_utils.py b/src/olympia/amo/tests/test_utils.py index fd6a804cc534..61800cd89c84 100644 --- a/src/olympia/amo/tests/test_utils.py +++ b/src/olympia/amo/tests/test_utils.py @@ -12,8 +12,8 @@ from django.utils.functional import cached_property from django.utils.http import quote_etag -import freezegun import pytest +import time_machine from babel import Locale from google.api_core.exceptions import PreconditionFailed @@ -314,7 +314,7 @@ def test_pngcrush_image(subprocess_mock): def test_utc_millesecs_from_epoch(): - with freezegun.freeze_time('2018-11-18 06:05:04.030201'): + with time_machine.travel('2018-11-18 06:05:04.030201', tick=False): timestamp = utc_millesecs_from_epoch() assert timestamp == 1542521104030 diff --git a/src/olympia/api/tests/test_authentication.py b/src/olympia/api/tests/test_authentication.py index 34a1b72b9415..52de04a1f876 100644 --- a/src/olympia/api/tests/test_authentication.py +++ b/src/olympia/api/tests/test_authentication.py @@ -10,7 +10,7 @@ from django.urls import reverse import jwt -from freezegun import freeze_time +import time_machine from rest_framework.exceptions import AuthenticationFailed from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response @@ -296,7 +296,7 @@ def test_still_valid_token(self): not_so_old_date = datetime.now() - timedelta( seconds=settings.SESSION_COOKIE_AGE - 30 ) - with freeze_time(not_so_old_date): + with time_machine.travel(not_so_old_date, tick=False): token = self.client.create_session(self.user) assert self._authenticate(token)[0] == self.user self.update_token_mock.assert_called() diff --git a/src/olympia/api/tests/test_throttling.py b/src/olympia/api/tests/test_throttling.py index b73aee7997ba..d188badb9c91 100644 --- a/src/olympia/api/tests/test_throttling.py +++ b/src/olympia/api/tests/test_throttling.py @@ -1,3 +1,4 @@ +from datetime import datetime from importlib import import_module from unittest import mock @@ -7,7 +8,7 @@ from django.test.utils import override_settings import pytest -from freezegun import freeze_time +import time_machine from rest_framework.test import APIRequestFactory, force_authenticate from rest_framework.throttling import BaseThrottle from rest_framework.viewsets import GenericViewSet @@ -124,13 +125,13 @@ def test_bypass_if_user_has_permission(self, allow_request_mock): assert self.throttle.allow_request(request, view) is True assert allow_request_mock.call_count == 0 - @freeze_time(as_kwarg='frozen_time') - def test_freeze_time_works_with_throttling(self, frozen_time): + def test_time_machine_works_with_throttling(self): self.throttle = self.throttle.__class__() - old_time = self.throttle.timer() - frozen_time.move_to('2019-04-08 15:16:23.42') - assert self.throttle.timer() == 1554736583.42 - assert old_time != 1554736583.42 + with time_machine.travel(datetime.now(), tick=False) as frozen_time: + old_time = self.throttle.timer() + frozen_time.move_to('2019-04-08 15:16:23.42') + assert self.throttle.timer() == 1554736583.42 + assert old_time != 1554736583.42 @mock.patch('rest_framework.throttling.UserRateThrottle.allow_request') def test_activity_log(self, allow_request_mock): diff --git a/src/olympia/api/throttling.py b/src/olympia/api/throttling.py index 098224b1c040..8a1414ed8cf3 100644 --- a/src/olympia/api/throttling.py +++ b/src/olympia/api/throttling.py @@ -41,7 +41,7 @@ class GranularUserRateThrottle(UserRateThrottle): def __init__(self): super().__init__() - # Re-initialize timer at __init__() to allow freeze_gun.freeze_time() + # Re-initialize timer at __init__() to allow time_machine.travel() # to work properly in tests. self.timer = time.time diff --git a/src/olympia/blocklist/tests/test_admin.py b/src/olympia/blocklist/tests/test_admin.py index c56d17a86317..f6e31e6d0675 100644 --- a/src/olympia/blocklist/tests/test_admin.py +++ b/src/olympia/blocklist/tests/test_admin.py @@ -10,7 +10,7 @@ from django.urls import reverse import responses -from freezegun import freeze_time +import time_machine from pyquery import PyQuery as pq from waffle.testutils import override_switch @@ -2201,38 +2201,43 @@ def test_blocking_addon_guid_already_denied(self): assert deleted_addon.status == amo.STATUS_DELETED # Should stay deleted assert DeniedGuid.objects.filter(guid=deleted_addon.guid).exists() - @freeze_time('2023-01-01 12:34:56', as_arg=True) - def test_add_with_delayed(frozen_time, self): + def test_add_with_delayed(self): delay_days = 2 addon_adu = settings.DUAL_SIGNOFF_AVERAGE_DAILY_USERS_THRESHOLD - 1 - ( - new_addon, - existing_and_full, - partial_addon, - existing_and_partial, - ) = self._test_add_multiple_submit(addon_adu=addon_adu, delay=delay_days) - # no new Block objects yet even though under the threshold - assert Block.objects.count() == 2 - multi = BlocklistSubmission.objects.get() - assert multi.signoff_state == BlocklistSubmission.SIGNOFF_STATES.AUTOAPPROVED - assert not multi.is_submission_ready + with time_machine.travel('2023-01-01 12:34:56', tick=False) as frozen_time: + ( + new_addon, + existing_and_full, + partial_addon, + existing_and_partial, + ) = self._test_add_multiple_submit(addon_adu=addon_adu, delay=delay_days) + # no new Block objects yet even though under the threshold + assert Block.objects.count() == 2 + multi = BlocklistSubmission.objects.get() + assert ( + multi.signoff_state == BlocklistSubmission.SIGNOFF_STATES.AUTOAPPROVED + ) + assert not multi.is_submission_ready - frozen_time.tick(delta=timedelta(days=delay_days, seconds=1)) - # Now we're past, the submission is ready - assert multi.is_submission_ready - assert multi.signoff_state == BlocklistSubmission.SIGNOFF_STATES.AUTOAPPROVED + frozen_time.shift(delta=timedelta(days=delay_days, seconds=1)) + # Now we're past, the submission is ready + assert multi.is_submission_ready + assert ( + multi.signoff_state == BlocklistSubmission.SIGNOFF_STATES.AUTOAPPROVED + ) - multi.save_to_block_objects() - self._test_add_multiple_verify_blocks( - new_addon, - existing_and_full, - partial_addon, - existing_and_partial, - has_signoff=False, - ) - assert ( - multi.reload().signoff_state == BlocklistSubmission.SIGNOFF_STATES.PUBLISHED - ) + multi.save_to_block_objects() + self._test_add_multiple_verify_blocks( + new_addon, + existing_and_full, + partial_addon, + existing_and_partial, + has_signoff=False, + ) + assert ( + multi.reload().signoff_state + == BlocklistSubmission.SIGNOFF_STATES.PUBLISHED + ) def test_approve_delayed(self): now = datetime.now() diff --git a/src/olympia/blocklist/tests/test_cron.py b/src/olympia/blocklist/tests/test_cron.py index 9ed030851cad..8b7d2f7ec0be 100644 --- a/src/olympia/blocklist/tests/test_cron.py +++ b/src/olympia/blocklist/tests/test_cron.py @@ -8,7 +8,7 @@ import pytest import responses -from freezegun import freeze_time +import time_machine from waffle.testutils import override_switch from olympia import amo @@ -37,7 +37,7 @@ STATSD_PREFIX = 'blocklist.cron.upload_mlbf_to_remote_settings.' -@freeze_time('2020-01-01 12:34:56') +@time_machine.travel('2020-01-01 12:34:56', tick=False) @override_switch('blocklist_mlbf_submit', active=True) class TestUploadToRemoteSettings(TestCase): def setUp(self): @@ -565,7 +565,7 @@ def test_pass_correct_arguments_to_upload_filter(self): class TestTimeMethods(TestCase): - @freeze_time('2024-10-10 12:34:56') + @time_machine.travel('2024-10-10 12:34:56', tick=False) def test_get_generation_time(self): assert get_generation_time() == datetime_to_ts() assert isinstance(get_generation_time(), int) diff --git a/src/olympia/devhub/tests/test_forms.py b/src/olympia/devhub/tests/test_forms.py index 556cae0ea5e5..5ef1ed437f4d 100644 --- a/src/olympia/devhub/tests/test_forms.py +++ b/src/olympia/devhub/tests/test_forms.py @@ -9,7 +9,7 @@ from django.utils import translation import pytest -from freezegun import freeze_time +import time_machine from pyquery import PyQuery as pq from waffle.testutils import override_switch @@ -220,7 +220,7 @@ def test_throttling(self, parse_addon_mock): request = req_factory_factory('/', post=True, data=data) request.user = user request.META['REMOTE_ADDR'] = '5.6.7.8' - with freeze_time('2019-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2019-04-08 15:16:23.42', tick=False) as frozen_time: for _x in range(0, 6): self._add_fake_throttling_action( view_class=AddonViewSet, @@ -236,7 +236,7 @@ def test_throttling(self, parse_addon_mock): 'Please try again after some time.' ] - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) form = forms.NewUploadForm(data, request=request) assert form.is_valid() diff --git a/src/olympia/devhub/tests/test_views.py b/src/olympia/devhub/tests/test_views.py index d1d3a3fcc7a1..ea3710086af1 100644 --- a/src/olympia/devhub/tests/test_views.py +++ b/src/olympia/devhub/tests/test_views.py @@ -14,10 +14,10 @@ from django.utils.encoding import force_str from django.utils.translation import trim_whitespace -import freezegun import markupsafe import pytest import responses +import time_machine from pyquery import PyQuery as pq from waffle.testutils import override_switch @@ -2431,8 +2431,10 @@ def test_get_confirmation_complete_with_timeout(self, mock_check_emails): assert not self.email_verification.is_expired assert not self.email_verification.is_timedout - with freezegun.freeze_time(self.email_verification.created) as frozen_time: - frozen_time.tick(timedelta(minutes=10, seconds=1)) + with time_machine.travel( + self.email_verification.created, tick=False + ) as frozen_time: + frozen_time.shift(timedelta(minutes=10, seconds=1)) response = self.client.get(url) assert len(mail.outbox) == 1 @@ -2458,8 +2460,10 @@ def test_get_verification_expired(self, mock_check_emails): mock_check_emails.return_value = [] self.with_email_verification() - with freezegun.freeze_time(self.email_verification.created) as frozen_time: - frozen_time.tick(timedelta(days=31)) + with time_machine.travel( + self.email_verification.created, tick=False + ) as frozen_time: + frozen_time.shift(timedelta(days=31)) self.client.force_login(self.user_profile) response = self.client.get(self.url) @@ -2501,8 +2505,10 @@ def test_get_verification_timedout(self, mock_check_emails): mock_check_emails.return_value = [] self.with_email_verification() - with freezegun.freeze_time(self.email_verification.created) as frozen_time: - frozen_time.tick(timedelta(minutes=10, seconds=31)) + with time_machine.travel( + self.email_verification.created, tick=False + ) as frozen_time: + frozen_time.shift(timedelta(minutes=10, seconds=31)) assert self.email_verification.is_timedout diff --git a/src/olympia/files/tests/test_views.py b/src/olympia/files/tests/test_views.py index 35375462d0c2..90ec81a50e4c 100644 --- a/src/olympia/files/tests/test_views.py +++ b/src/olympia/files/tests/test_views.py @@ -5,7 +5,7 @@ from django.test.utils import override_settings from django.urls import reverse -from freezegun import freeze_time +import time_machine from olympia import amo from olympia.amo.tests import ( @@ -207,7 +207,7 @@ def test_cannot_retrieve_other_uploads(self): def test_throttling_ip_burst(self): ip = '63.245.208.194' - with freeze_time('2019-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2019-04-08 15:16:23.42', tick=False) as frozen_time: for _ in range(0, 6): self._add_fake_throttling_action( view_class=FileUploadViewSet, @@ -223,13 +223,13 @@ def test_throttling_ip_burst(self): # 'Burst' throttling is 1 minute, so 61 seconds later we should be # allowed again. - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self._create_post(ip=ip) assert response.status_code == 201, response.content def test_throttling_ip_hourly(self): ip = '63.245.208.194' - with freeze_time('2019-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2019-04-08 15:16:23.42', tick=False) as frozen_time: for _ in range(0, 50): self._add_fake_throttling_action( view_class=FileUploadViewSet, @@ -245,18 +245,18 @@ def test_throttling_ip_hourly(self): # One minute later, past the 'burst' throttling period, we're still # blocked by the 'hourly' limit. - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self._create_post(ip=ip) assert response.status_code == 429 # 'hourly' throttling is 1 hour, so 3601 seconds later we should # be allowed again. - frozen_time.tick(delta=timedelta(seconds=3601)) + frozen_time.shift(delta=timedelta(seconds=3601)) response = self._create_post(ip=ip) assert response.status_code == 201 def test_throttling_user_burst(self): - with freeze_time('2019-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2019-04-08 15:16:23.42', tick=False) as frozen_time: for _ in range(0, 6): self._add_fake_throttling_action( view_class=FileUploadViewSet, @@ -272,12 +272,12 @@ def test_throttling_user_burst(self): # 'Burst' throttling is 1 minute, so 61 seconds later we should be # allowed again. - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self._create_post(ip=get_random_ip()) assert response.status_code == 201, response.content def test_throttling_user_hourly(self): - with freeze_time('2019-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2019-04-08 15:16:23.42', tick=False) as frozen_time: for _ in range(0, 20): self._add_fake_throttling_action( view_class=FileUploadViewSet, @@ -293,17 +293,17 @@ def test_throttling_user_hourly(self): # One minute later, past the 'burst' throttling period, we're still # blocked by the 'hourly' limit. - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self._create_post(ip=get_random_ip()) assert response.status_code == 429, response.content # 3601 seconds later we should be allowed again. - frozen_time.tick(delta=timedelta(seconds=3601)) + frozen_time.shift(delta=timedelta(seconds=3601)) response = self._create_post(ip=get_random_ip()) assert response.status_code == 201, response.content def test_throttling_user_daily(self): - with freeze_time('2019-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2019-04-08 15:16:23.42', tick=False) as frozen_time: for _ in range(0, 48): self._add_fake_throttling_action( view_class=FileUploadViewSet, @@ -319,17 +319,17 @@ def test_throttling_user_daily(self): # One minute later, past the 'burst' throttling period, we're still # blocked by the 'hourly' limit. - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self._create_post(ip=get_random_ip()) assert response.status_code == 429, response.content # After the hourly limit, still blocked. - frozen_time.tick(delta=timedelta(seconds=3601)) + frozen_time.shift(delta=timedelta(seconds=3601)) response = self._create_post(ip=get_random_ip()) assert response.status_code == 429, response.content # 86401 seconds later we should be allowed again (24h + 1s). - frozen_time.tick(delta=timedelta(seconds=86401)) + frozen_time.shift(delta=timedelta(seconds=86401)) response = self._create_post(ip=get_random_ip()) assert response.status_code == 201, response.content diff --git a/src/olympia/promoted/tests/test_tasks.py b/src/olympia/promoted/tests/test_tasks.py index b3bebc97b8f4..77016b9d90a5 100644 --- a/src/olympia/promoted/tests/test_tasks.py +++ b/src/olympia/promoted/tests/test_tasks.py @@ -3,7 +3,7 @@ from django.conf import settings import pytest -from freezegun import freeze_time +import time_machine from olympia import amo from olympia.addons.serializers import PromotedGroup @@ -98,7 +98,7 @@ def test_add_high_adu_extensions_to_notable(): deleted_extension_version = deleted_extension.current_version deleted_extension.delete() - with freeze_time(): + with time_machine.travel(datetime.now(), tick=False): now = datetime.now() add_high_adu_extensions_to_notable() diff --git a/src/olympia/ratings/tests/test_tasks.py b/src/olympia/ratings/tests/test_tasks.py index bb053c06fc34..08376d62a202 100644 --- a/src/olympia/ratings/tests/test_tasks.py +++ b/src/olympia/ratings/tests/test_tasks.py @@ -7,7 +7,7 @@ import pytest import responses -from freezegun import freeze_time +import time_machine from olympia import amo from olympia.amo.tests import TestCase, addon_factory, days_ago, user_factory @@ -239,7 +239,7 @@ def _high_ratings_setup(threshold_field): return not_flagged, flagged -@freeze_time('2023-06-26 11:00') +@time_machine.travel('2023-06-26 11:00', tick=False) @pytest.mark.django_db def test_flag_high_rating_addons_according_to_review_tier(): set_config(amo.config_keys.EXTRA_REVIEW_TARGET_PER_DAY, '1') @@ -298,7 +298,7 @@ def test_flag_high_rating_addons_according_to_review_tier(): ] -@freeze_time('2023-06-26 11:00') +@time_machine.travel('2023-06-26 11:00', tick=False) @pytest.mark.django_db def test_block_high_rating_addons_according_to_review_tier(): not_blocked, blocked = _high_ratings_setup( diff --git a/src/olympia/ratings/tests/test_views.py b/src/olympia/ratings/tests/test_views.py index 663177576587..a70cbb90061b 100644 --- a/src/olympia/ratings/tests/test_views.py +++ b/src/olympia/ratings/tests/test_views.py @@ -1,5 +1,5 @@ import json -from datetime import timedelta +from datetime import datetime, timedelta from ipaddress import IPv4Address from django.conf import settings @@ -7,7 +7,7 @@ from django.test.utils import override_settings from django.utils.encoding import force_str -from freezegun import freeze_time +import time_machine from rest_framework.exceptions import ErrorDetail from olympia import amo @@ -1319,7 +1319,7 @@ def test_throttle(self): user=self.user, ) - with freeze_time('2021-07-23') as frozen_time: + with time_machine.travel('2021-07-23', tick=False) as frozen_time: # And confirm we can rapidly delete them. self.client.login_api(self.user) response = self.client.delete( @@ -1347,7 +1347,7 @@ def test_throttle(self): assert response.status_code == 429 # You're free after a minute. - frozen_time.tick(delta=timedelta(minutes=1)) + frozen_time.shift(delta=timedelta(minutes=1)) addon_c = addon_factory() rating_c = Rating.objects.create( addon=addon_c, @@ -1513,7 +1513,7 @@ def test_edit_reply(self): def test_throttle(self): self.client.login_api(self.user) - with freeze_time('2021-07-23') as frozen_time: + with time_machine.travel('2021-07-23', tick=False) as frozen_time: for x in range(1, 6): response = self.client.patch( self.url, {'score': x, 'body': f'Blâh {x}'} @@ -1531,7 +1531,7 @@ def test_throttle(self): assert self.rating.rating == 5 # Everything back to normal after waiting a minute. - frozen_time.tick(delta=timedelta(minutes=1)) + frozen_time.shift(delta=timedelta(minutes=1)) response = self.client.patch(self.url, {'score': 1, 'body': 'I did it'}) assert response.status_code == 200 self.rating.reload() @@ -1542,7 +1542,7 @@ def test_throttle(self): def test_no_throttling_with_relevant_permission(self): self.client.login_api(self.user) - with freeze_time('2021-08-09') as frozen_time: + with time_machine.travel('2021-08-09', tick=False) as frozen_time: for x in range(1, 6): response = self.client.patch( self.url, @@ -1603,7 +1603,7 @@ def test_no_throttling_with_relevant_permission(self): assert new_rating.rating == 4 # Everything back to normal after waiting a minute. - frozen_time.tick(delta=timedelta(minutes=1)) + frozen_time.shift(delta=timedelta(minutes=1)) response = self.client.patch( new_url, {'score': 1, 'body': 'I did it'}, @@ -1615,33 +1615,33 @@ def test_no_throttling_with_relevant_permission(self): assert str(new_rating.body) == 'I did it' assert new_rating.rating == 1 - @freeze_time(as_arg=True) - def test_body_contains_banned_word_deny(frozen_time, self): + def test_body_contains_banned_word_deny(self): DeniedRatingWord.objects.create(word='body', moderation=False) DeniedRatingWord.objects.create(word='foo', moderation=False) # This wouldn't be matched, because it's a moderate word instead. DeniedRatingWord.objects.create(word='test', moderation=True) self.client.login_api(self.user) - response = self.client.patch( - self.url, - { - 'body': 'test bOdy_é', - 'score': 5, - }, - ) - assert response.status_code == 400 - assert response.data == { - 'body': ['The review text cannot contain the word: "body"'] - } + with time_machine.travel(datetime.now()) as frozen_time: + response = self.client.patch( + self.url, + { + 'body': 'test bOdy_é', + 'score': 5, + }, + ) + assert response.status_code == 400 + assert response.data == { + 'body': ['The review text cannot contain the word: "body"'] + } - frozen_time.tick(delta=timedelta(minutes=1)) - response = self.client.patch( - self.url, - { - 'body': 'test bOdy-é FOO', - 'score': 5, - }, - ) + frozen_time.shift(delta=timedelta(minutes=1)) + response = self.client.patch( + self.url, + { + 'body': 'test bOdy-é FOO', + 'score': 5, + }, + ) assert response.status_code == 400 assert response.data == { 'body': ['The review text cannot contain any of the words: "body", "foo"'] @@ -2222,7 +2222,7 @@ def test_post_twice_same_version(self): @override_settings(CACHES=locmem_cache) def test_throttle(self): - with freeze_time('2017-11-01') as frozen_time: + with time_machine.travel('2017-11-01') as frozen_time: self.user = user_factory() self.client.login_api(self.user) # First post, no problem. @@ -2252,7 +2252,7 @@ def test_throttle(self): assert response.status_code == 429 # Throttle is 1 minute so check we can go again - frozen_time.tick(delta=timedelta(seconds=60)) + frozen_time.shift(delta=timedelta(seconds=60)) # And we're good. response = self.client.post( self.url, @@ -2275,7 +2275,7 @@ def test_throttle(self): ) # We should be able to post one more today. new_version = version_factory(addon=self.addon) - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self.client.post( self.url, { @@ -2289,7 +2289,7 @@ def test_throttle(self): # Over the daily limit now... new_version = version_factory(addon=self.addon) - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self.client.post( self.url, { @@ -2303,7 +2303,7 @@ def test_throttle(self): # Wait a day and we're good. new_version = version_factory(addon=self.addon) - frozen_time.tick(delta=timedelta(hours=24, seconds=1)) + frozen_time.shift(delta=timedelta(hours=24, seconds=1)) response = self.client.post( self.url, { @@ -2317,7 +2317,7 @@ def test_throttle(self): @override_settings(CACHES=locmem_cache) def test_throttle_by_ip(self): - with freeze_time('2017-11-01') as frozen_time: + with time_machine.travel('2017-11-01') as frozen_time: self.user = user_factory() self.client.login_api(self.user) # First post, no problem. @@ -2354,7 +2354,7 @@ def test_throttle_by_ip(self): assert response.status_code == 429 # Throttle is 1 minute so check we can go again - frozen_time.tick(delta=timedelta(seconds=60)) + frozen_time.shift(delta=timedelta(seconds=60)) # And we're good. self.client.login_api(self.user) response = self.client.post( @@ -2376,7 +2376,7 @@ def test_throttle_by_ip(self): from olympia.users.models import UserProfile for x in range(3, 35): - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) self._add_fake_throttling_action( view_class=RatingViewSet, url=self.url, @@ -2385,7 +2385,7 @@ def test_throttle_by_ip(self): ) # We should be able to post one more today. new_version = version_factory(addon=self.addon) - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self.client.post( self.url, { @@ -2401,7 +2401,7 @@ def test_throttle_by_ip(self): # Over the daily limit for IPs now... new_version = version_factory(addon=self.addon) - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self.client.post( self.url, { @@ -2417,7 +2417,7 @@ def test_throttle_by_ip(self): # Wait a day and we're good. new_version = version_factory(addon=self.addon) - frozen_time.tick(delta=timedelta(hours=24, seconds=1)) + frozen_time.shift(delta=timedelta(hours=24, seconds=1)) response = self.client.post( self.url, { @@ -2433,7 +2433,7 @@ def test_throttle_by_ip(self): @override_settings(CACHES=locmem_cache) def test_rating_post_throttle_separated_from_other_throttles(self): - with freeze_time('2017-11-01') as frozen_time: + with time_machine.travel('2017-11-01') as frozen_time: self.user = user_factory() self.client.login_api(self.user) @@ -2490,7 +2490,7 @@ def test_rating_post_throttle_separated_from_other_throttles(self): assert response.status_code == 200 # Throttle is 1 minute so check we can go again - frozen_time.tick(delta=timedelta(seconds=60)) + frozen_time.shift(delta=timedelta(seconds=60)) # And we're good. response = self.client.post( @@ -2504,8 +2504,7 @@ def test_rating_post_throttle_separated_from_other_throttles(self): ) assert response.status_code == 201, response.content - @freeze_time(as_arg=True) - def test_body_contains_banned_word_deny(frozen_time, self): + def test_body_contains_banned_word_deny(self): DeniedRatingWord.objects.create(word='body', moderation=False) DeniedRatingWord.objects.create(word='foo', moderation=False) # This wouldn't be matched, because it's a moderate word instead. @@ -2513,30 +2512,31 @@ def test_body_contains_banned_word_deny(frozen_time, self): self.user = user_factory() self.client.login_api(self.user) assert not Rating.objects.exists() - response = self.client.post( - self.url, - { - 'addon': self.addon.pk, - 'body': 'test bOdy_é', - 'score': 5, - 'version': self.addon.current_version.pk, - }, - ) - assert response.status_code == 400 - assert response.data == { - 'body': ['The review text cannot contain the word: "body"'] - } + with time_machine.travel(datetime.now()) as frozen_time: + response = self.client.post( + self.url, + { + 'addon': self.addon.pk, + 'body': 'test bOdy_é', + 'score': 5, + 'version': self.addon.current_version.pk, + }, + ) + assert response.status_code == 400 + assert response.data == { + 'body': ['The review text cannot contain the word: "body"'] + } - frozen_time.tick(delta=timedelta(minutes=1)) - response = self.client.post( - self.url, - { - 'addon': self.addon.pk, - 'body': 'test bOdy-é FOO', - 'score': 5, - 'version': self.addon.current_version.pk, - }, - ) + frozen_time.shift(delta=timedelta(minutes=1)) + response = self.client.post( + self.url, + { + 'addon': self.addon.pk, + 'body': 'test bOdy-é FOO', + 'score': 5, + 'version': self.addon.current_version.pk, + }, + ) assert response.status_code == 400 assert response.data == { 'body': ['The review text cannot contain any of the words: "body", "foo"'] @@ -2891,7 +2891,7 @@ def test_throttle(self): ) url_b = reverse_ns(self.flag_url_name, kwargs={'pk': rating_b.pk}) - with freeze_time('2021-07-23') as frozen_time: + with time_machine.travel('2021-07-23') as frozen_time: response = self.client.post( self.url, data={'flag': 'review_flag_reason_spam'} ) @@ -2913,12 +2913,12 @@ def test_throttle(self): assert response.status_code == 429 # Even waiting an hour doesn't let you continue. - frozen_time.tick(delta=timedelta(hours=1)) + frozen_time.shift(delta=timedelta(hours=1)) response = self.client.post(url_b, data={'flag': 'review_flag_reason_spam'}) assert response.status_code == 429 # Waiting 24 hours (total) does. - frozen_time.tick(delta=timedelta(hours=23)) + frozen_time.shift(delta=timedelta(hours=23)) response = self.client.post(url_b, data={'flag': 'review_flag_reason_spam'}) assert response.status_code == 202 @@ -3141,7 +3141,7 @@ def test_throttle(self): ) other_url = reverse_ns(self.reply_url_name, kwargs={'pk': other_rating.pk}) - with freeze_time('2017-11-01') as frozen_time: + with time_machine.travel('2017-11-01') as frozen_time: self.client.login_api(self.addon_author) # First post, no problem. response = self.client.post( @@ -3153,7 +3153,7 @@ def test_throttle(self): assert response.status_code == 201 # Throttle is 1 per 5 seconds so after 4 seconds we have to wait - frozen_time.tick(delta=timedelta(seconds=4)) + frozen_time.shift(delta=timedelta(seconds=4)) # Second post, nope, have to wait a while. response = self.client.post( other_url, @@ -3163,7 +3163,7 @@ def test_throttle(self): ) assert response.status_code == 429 - frozen_time.tick(delta=timedelta(seconds=5)) + frozen_time.shift(delta=timedelta(seconds=5)) # And we're good. response = self.client.post( other_url, diff --git a/src/olympia/reviewers/tests/test_commands.py b/src/olympia/reviewers/tests/test_commands.py index 897d7057d5e8..3288cba9bad9 100644 --- a/src/olympia/reviewers/tests/test_commands.py +++ b/src/olympia/reviewers/tests/test_commands.py @@ -9,7 +9,7 @@ from django.test.testcases import TransactionTestCase import responses -from freezegun import freeze_time +import time_machine from olympia import amo from olympia.abuse.models import AbuseReport, CinderJob, CinderPolicy, ContentDecision @@ -1997,7 +1997,9 @@ def test_full_run(self): assert 'right to appeal' in mail.outbox[1].body -@freeze_time(backfill_reviewactionreasons_for_delayed_rejections.Command.MAX_DATE) +@time_machine.travel( + backfill_reviewactionreasons_for_delayed_rejections.Command.MAX_DATE, tick=False +) class TestBackfillReviewactionreasonsForDelayedRejections(TestCase): def check_log(self, alog, reasons, policies): alog.reload() @@ -2173,7 +2175,7 @@ def test_too_old_and_too_new(self): reason = ReviewActionReason.objects.create( name='the reason', canned_response='why', cinder_policy=policy ) - with freeze_time(date_after): + with time_machine.travel(date_after, tick=False): delayed = ActivityLog.objects.create( amo.LOG.REJECT_VERSION_DELAYED, addon, diff --git a/src/olympia/reviewers/tests/test_cron.py b/src/olympia/reviewers/tests/test_cron.py index 5601dc146aff..8e07b34ab63b 100644 --- a/src/olympia/reviewers/tests/test_cron.py +++ b/src/olympia/reviewers/tests/test_cron.py @@ -2,7 +2,7 @@ from django.conf import settings -from freezegun import freeze_time +import time_machine from olympia import amo from olympia.amo.tests import TestCase, addon_factory, user_factory @@ -25,7 +25,7 @@ def _test_expected_count(self, date): assert QueueCount.objects.filter(date=date).count() == expected_count def test_empty(self): - with freeze_time('2024-12-03'): + with time_machine.travel('2024-12-03', tick=False): expected_date = date.today() record_reviewer_queues_counts() @@ -69,7 +69,7 @@ def test_basic(self): }, ) - with freeze_time('2024-12-03'): + with time_machine.travel('2024-12-03', tick=False): expected_date = date.today() record_reviewer_queues_counts() @@ -100,7 +100,7 @@ def test_twice_different_day(self): is_active=False ) - with freeze_time('2024-12-04'): + with time_machine.travel('2024-12-04', tick=False): expected_date = date.today() record_reviewer_queues_counts() diff --git a/src/olympia/reviewers/tests/test_forms.py b/src/olympia/reviewers/tests/test_forms.py index 5ca64d1e765c..3ef9c00a0268 100644 --- a/src/olympia/reviewers/tests/test_forms.py +++ b/src/olympia/reviewers/tests/test_forms.py @@ -4,7 +4,7 @@ from django.core.files.base import ContentFile from django.utils.encoding import force_str -from freezegun import freeze_time +import time_machine from pyquery import PyQuery as pq from waffle.testutils import override_switch @@ -1110,7 +1110,7 @@ def test_versions_required(self): assert not form.is_valid() assert form.errors == {'versions': ['This field is required.']} - @freeze_time('2025-02-10 12:09') + @time_machine.travel('2025-02-10 12:09', tick=False) def test_delayed_rejection_date_is_readonly_for_regular_reviewers(self): # Regular reviewers can't customize the delayed rejection period. self.grant_permission(self.request.user, 'Addons:Review') @@ -1145,7 +1145,7 @@ def test_delayed_rejection_date_is_readonly_for_regular_reviewers(self): == 'change_or_clear_pending_rejection_multiple_versions' ) - @freeze_time('2025-01-23 12:52') + @time_machine.travel('2025-01-23 12:52', tick=False) def test_delayed_rejection_days_shows_up_for_admin_reviewers(self): # Admin reviewers can customize the delayed rejection period. self.grant_permission(self.request.user, 'Addons:Review') @@ -1180,7 +1180,7 @@ def test_delayed_rejection_days_shows_up_for_admin_reviewers(self): == 'change_or_clear_pending_rejection_multiple_versions' ) - @freeze_time('2025-01-23 12:52') + @time_machine.travel('2025-01-23 12:52', tick=False) def test_delayed_rejection_days_value_not_in_the_future(self): self.grant_permission(self.request.user, 'Addons:Review,Reviews:Admin') self.reason_a = ReviewActionReason.objects.create( diff --git a/src/olympia/reviewers/tests/test_review_reports.py b/src/olympia/reviewers/tests/test_review_reports.py index 28645b51cb34..22cf6145063c 100644 --- a/src/olympia/reviewers/tests/test_review_reports.py +++ b/src/olympia/reviewers/tests/test_review_reports.py @@ -3,7 +3,7 @@ from django.core import mail import pytest -from freezegun import freeze_time +import time_machine from olympia import amo from olympia.activity.models import ActivityLog @@ -23,9 +23,9 @@ class TestReviewReports: # 2019-01-07: part of the reported week is previous quarter (year even) # 2019-01-14: back to reported week being within the quarter @pytest.fixture(autouse=True, params=['2019-01-07', '2019-01-14']) - def freeze_date(self, request): - freezer = freeze_time(request.param) - freezer.start() + def travel_to_date(self, request): + machine = time_machine.travel(request.param, tick=False) + machine.start() self.today = date.today() self.last_week_begin = self.today - timedelta(days=self.today.weekday() + 7) @@ -35,7 +35,7 @@ def freeze_date(self, request): ) yield - freezer.stop() + machine.stop() def create_and_review_addon(self, user, weight, verdict, content_review): addon = addon_factory() @@ -48,7 +48,7 @@ def create_and_review_addon(self, user, weight, verdict, content_review): ActivityLog.objects.create(action, addon, addon.versions.all()[0], user=user) def generate_review_data(self): - with freeze_time(self.last_week_begin) as frozen_time: + with time_machine.travel(self.last_week_begin) as frozen_time: self.reviewer1 = user_factory(display_name='Volunteer A') self.reviewer2 = user_factory(display_name='Staff B') self.reviewer3 = user_factory(display_name=None) @@ -108,7 +108,7 @@ def generate_review_data(self): (self.reviewer5, 165, amo.AUTO_APPROVED, True), ] for review_action in data: - frozen_time.tick() + frozen_time.shift(1) self.create_and_review_addon( review_action[0], review_action[1], @@ -121,7 +121,7 @@ def generate_review_data(self): # Search plugin (submitted before auto-approval was implemented) search_plugin = addon_factory(type=4) - frozen_time.tick() + frozen_time.shift(1) ActivityLog.objects.create( amo.LOG.APPROVE_CONTENT, search_plugin, @@ -131,7 +131,7 @@ def generate_review_data(self): # Dictionary (submitted before auto-approval was implemented) dictionary = addon_factory(type=amo.ADDON_DICT) - frozen_time.tick() + frozen_time.shift(1) ActivityLog.objects.create( amo.LOG.APPROVE_CONTENT, dictionary, @@ -141,7 +141,7 @@ def generate_review_data(self): # Theme (should be filtered out of the reports) theme = addon_factory(type=amo.ADDON_STATICTHEME) - frozen_time.tick() + frozen_time.shift(1) ActivityLog.objects.create( amo.LOG.APPROVE_VERSION, theme, @@ -328,28 +328,28 @@ def test_empty_report_content_reviewer(self): def test_multiple_version_review_counted_once_addon_reviewer(self): self.reviewer1 = user_factory(display_name='Volunteer A') - with freeze_time(self.last_week_begin) as frozen_time: + with time_machine.travel(self.last_week_begin, tick=False) as frozen_time: ActivityLog.objects.create( amo.LOG.APPROVE_VERSION, (addon := addon_factory()), addon.versions.all()[0], user=self.reviewer1, ) - frozen_time.tick() + frozen_time.shift(1) ActivityLog.objects.create( amo.LOG.CONFIRM_AUTO_APPROVED, (addon := addon_factory()), addon.versions.all()[0], user=self.reviewer1, ) - frozen_time.tick() + frozen_time.shift(1) ActivityLog.objects.create( amo.LOG.APPROVE_VERSION, (addon := addon_factory()), addon.versions.all()[0], user=self.reviewer1, ) - frozen_time.tick() + frozen_time.shift(1) ActivityLog.objects.create( amo.LOG.REJECT_VERSION_DELAYED, (addon := addon_factory()), @@ -361,14 +361,14 @@ def test_multiple_version_review_counted_once_addon_reviewer(self): version_factory(addon=addon) version_factory(addon=addon) all_versions = list(addon.versions.all()) - frozen_time.tick() + frozen_time.shift(1) # As these are logged at the exact same time, only 1 should be counted for i in range(3): ActivityLog.objects.create( amo.LOG.REJECT_VERSION, addon, all_versions[i], user=self.reviewer1 ) # This should be ignored because it's an auto-rejection - frozen_time.tick() + frozen_time.shift(1) ActivityLog.objects.create( amo.LOG.REJECT_VERSION, (addon := addon_factory()), @@ -401,23 +401,23 @@ def test_multiple_version_review_counted_once_addon_reviewer(self): def test_multiple_version_review_counted_once_content_reviewer(self): self.reviewer1 = user_factory(display_name='Volunteer A') - with freeze_time(self.last_week_begin) as frozen_time: + with time_machine.travel(self.last_week_begin, tick=False) as frozen_time: for _i in range(3): - frozen_time.tick() + frozen_time.shift(1) ActivityLog.objects.create( amo.LOG.APPROVE_CONTENT, (addon := addon_factory()), addon.versions.all()[0], user=self.reviewer1, ) - frozen_time.tick() + frozen_time.shift(1) ActivityLog.objects.create( amo.LOG.REJECT_CONTENT, (addon := addon_factory()), addon.versions.all()[0], user=self.reviewer1, ) - frozen_time.tick() + frozen_time.shift(1) ActivityLog.objects.create( amo.LOG.REJECT_CONTENT_DELAYED, (addon := addon_factory()), @@ -429,14 +429,14 @@ def test_multiple_version_review_counted_once_content_reviewer(self): version_factory(addon=addon) version_factory(addon=addon) all_versions = list(addon.versions.all()) - frozen_time.tick() + frozen_time.shift(1) # As these are logged at the exact same time, only 1 should be counted for i in range(3): ActivityLog.objects.create( amo.LOG.REJECT_CONTENT, addon, all_versions[i], user=self.reviewer1 ) # This should be ignored because it's an auto-rejection - frozen_time.tick() + frozen_time.shift(1) ActivityLog.objects.create( amo.LOG.REJECT_CONTENT, (addon := addon_factory()), diff --git a/src/olympia/reviewers/tests/test_views.py b/src/olympia/reviewers/tests/test_views.py index b6d7b9b02e74..09887faf81b6 100644 --- a/src/olympia/reviewers/tests/test_views.py +++ b/src/olympia/reviewers/tests/test_views.py @@ -20,7 +20,7 @@ from django.utils.formats import localize import responses -from freezegun import freeze_time +import time_machine from lxml.html import HTMLParser, fromstring from pyquery import PyQuery as pq from waffle.testutils import override_switch @@ -313,7 +313,7 @@ def test_end_filter_wrong(self): assert pq(response.content)('#log-listing tr:not(.hide)').length == 3 def test_start_filter(self): - with freeze_time('2017-08-01 10:00'): + with time_machine.travel('2017-08-01 10:00', tick=False): self.make_approvals() # Make sure we show the stuff we just made. @@ -326,10 +326,10 @@ def test_start_filter(self): assert doc('tr.hide').eq(0).text() == 'youwin' def test_start_default_filter(self): - with freeze_time('2017-07-31 10:00'): + with time_machine.travel('2017-07-31 10:00', tick=False): self.make_approvals() - with freeze_time('2017-08-01 10:00'): + with time_machine.travel('2017-08-01 10:00', tick=False): addon = Addon.objects.first() ActivityLog.objects.create( @@ -341,7 +341,7 @@ def test_start_default_filter(self): ) # Make sure the default 'start' to the 1st of a month works properly - with freeze_time('2017-08-03 11:00'): + with time_machine.travel('2017-08-03 11:00', tick=False): response = self.client.get(self.url) assert response.status_code == 200 @@ -511,7 +511,7 @@ def test_content_rejection(self): 'Version 2.1.072 content rejected.' ) - @freeze_time('2017-08-03') + @time_machine.travel('2017-08-03', tick=False) def test_review_url(self): self.login_as_admin() addon = addon_factory() diff --git a/src/olympia/scanners/tests/test_models.py b/src/olympia/scanners/tests/test_models.py index 9e55a8dfee89..834e96d4ded0 100644 --- a/src/olympia/scanners/tests/test_models.py +++ b/src/olympia/scanners/tests/test_models.py @@ -1,11 +1,12 @@ import uuid +from datetime import datetime from unittest import mock from django.core.exceptions import ValidationError from django.test.utils import override_settings import pytest -from freezegun import freeze_time +import time_machine from olympia import amo from olympia.amo.tests import TestCase, addon_factory, user_factory @@ -548,10 +549,12 @@ def test_completion_rate_not_running(self): def test_query_rule_change_state_to_valid(current_state, target_state): rule = ScannerQueryRule(name='some_rule', scanner=YARA) rule.state = current_state - with freeze_time('2020-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2020-04-08 15:16:23.42', tick=False): rule.change_state_to(target_state) + now = datetime.now() if target_state == COMPLETED: - assert rule.completed == frozen_time() + assert rule.completed == now + assert rule.completed != datetime.now() else: assert rule.completed is None diff --git a/src/olympia/search/tests/test_filters.py b/src/olympia/search/tests/test_filters.py index 9da6e0b1974a..7b79290f9638 100644 --- a/src/olympia/search/tests/test_filters.py +++ b/src/olympia/search/tests/test_filters.py @@ -7,8 +7,8 @@ from django.utils import translation from django.utils.http import urlsafe_base64_encode +import time_machine from elasticsearch_dsl import Search -from freezegun import freeze_time from rest_framework import serializers from olympia import amo @@ -533,7 +533,7 @@ def test_sort_random_restrictions(self): self._filter(data={'q': 'something', 'promoted': 'line', 'sort': 'random'}) assert context.exception.detail == [expected] - @freeze_time('2023-12-24') + @time_machine.travel('2023-12-24', tick=False) def test_sort_random_featured(self): qs = self._filter(data={'featured': 'true', 'sort': 'random'}) # Note: this test does not call AddonFeaturedQueryParam so it won't @@ -545,7 +545,7 @@ def test_sort_random_featured(self): ] def test_sort_random_seed(self): - with freeze_time('2023-12-24') as frozen_time: + with time_machine.travel('2023-12-24', tick=False) as frozen_time: qs = self._filter(data={'featured': 'true', 'sort': 'random'}) assert qs['sort'] == ['_score'] assert qs['query']['function_score']['functions'] == [ @@ -553,7 +553,7 @@ def test_sort_random_seed(self): ] # Stable within the hour - frozen_time.tick(delta=timedelta(minutes=59, seconds=59)) + frozen_time.shift(delta=timedelta(minutes=59, seconds=59)) qs = self._filter(data={'featured': 'true', 'sort': 'random'}) assert qs['sort'] == ['_score'] assert qs['query']['function_score']['functions'] == [ @@ -561,7 +561,7 @@ def test_sort_random_seed(self): ] # Changes once hour changes. - frozen_time.tick(delta=timedelta(seconds=1)) + frozen_time.shift(delta=timedelta(seconds=1)) qs = self._filter(data={'featured': 'true', 'sort': 'random'}) assert qs['sort'] == ['_score'] assert qs['query']['function_score']['functions'] == [ @@ -569,7 +569,7 @@ def test_sort_random_seed(self): ] # Stays stable again until next hour. - frozen_time.tick(delta=timedelta(minutes=59)) + frozen_time.shift(delta=timedelta(minutes=59)) qs = self._filter(data={'featured': 'true', 'sort': 'random'}) assert qs['sort'] == ['_score'] assert qs['query']['function_score']['functions'] == [ @@ -577,7 +577,7 @@ def test_sort_random_seed(self): ] # Changes again once hour changes again. - frozen_time.tick(delta=timedelta(minutes=1)) + frozen_time.shift(delta=timedelta(minutes=1)) qs = self._filter(data={'featured': 'true', 'sort': 'random'}) assert qs['sort'] == ['_score'] assert qs['query']['function_score']['functions'] == [ @@ -592,7 +592,7 @@ def test_sort_random_seed(self): {'random_score': {'seed': 17733072 + 24, 'field': 'id'}} ] - @freeze_time('2023-12-24') + @time_machine.travel('2023-12-24', tick=False) def test_sort_random(self): qs = self._filter(data={'promoted': 'recommended', 'sort': 'random'}) # Note: this test does not call AddonPromotedQueryParam so it won't @@ -1542,7 +1542,7 @@ def test_combined(self): } assert expected in should - @freeze_time('2023-12-24') + @time_machine.travel('2023-12-24', tick=False) def test_filter_featured_sort_random(self): qs = self._filter(data={'featured': 'true', 'sort': 'random'}) bool_ = qs['query']['bool'] @@ -1560,7 +1560,7 @@ def test_filter_featured_sort_random(self): {'random_score': {'seed': 17733072, 'field': 'id'}} ] - @freeze_time('2023-12-24') + @time_machine.travel('2023-12-24', tick=False) def test_filter_promoted_sort_random(self): qs = self._filter(data={'promoted': 'spotlight', 'sort': 'random'}) bool_ = qs['query']['bool'] diff --git a/src/olympia/signing/tests/test_views.py b/src/olympia/signing/tests/test_views.py index 94296c7c278b..fb5767d67783 100644 --- a/src/olympia/signing/tests/test_views.py +++ b/src/olympia/signing/tests/test_views.py @@ -10,7 +10,7 @@ from django.utils import translation import responses -from freezegun import freeze_time +import time_machine from rest_framework.response import Response from olympia import amo @@ -594,7 +594,7 @@ def _test_throttling_verb_ip_burst(self, verb, url, expected_status=201): ] UserProfile.objects.bulk_create(users) users = UserProfile.objects.filter(email__startswith='bulk') - with freeze_time('2019-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2019-04-08 15:16:23.42', tick=False) as frozen_time: for user in users: self._add_fake_throttling_action( view_class=self.view_class, @@ -618,7 +618,7 @@ def _test_throttling_verb_ip_burst(self, verb, url, expected_status=201): # 'Burst' throttling is 1 minute, so 61 seconds later we should be # allowed again. - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self.request( verb, url=url, @@ -639,7 +639,7 @@ def _test_throttling_verb_ip_hourly(self, verb, url, expected_status=201): ] UserProfile.objects.bulk_create(users) users = UserProfile.objects.filter(email__startswith='bulk') - with freeze_time('2019-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2019-04-08 15:16:23.42', tick=False) as frozen_time: for user in users: # Make the user different every time so that we test the ip # throttling. @@ -665,7 +665,7 @@ def _test_throttling_verb_ip_hourly(self, verb, url, expected_status=201): # One minute later, past the 'burst' throttling period, we're still # blocked by the 'hourly' limit. - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self.request( verb, url=url, @@ -679,7 +679,7 @@ def _test_throttling_verb_ip_hourly(self, verb, url, expected_status=201): # 'hourly' throttling is 1 hour, so 3601 seconds later we should # be allowed again. - frozen_time.tick(delta=timedelta(seconds=3601)) + frozen_time.shift(delta=timedelta(seconds=3601)) response = self.request( verb, url=url, @@ -692,7 +692,7 @@ def _test_throttling_verb_ip_hourly(self, verb, url, expected_status=201): assert response.status_code == expected_status def _test_throttling_verb_user_burst(self, verb, url, expected_status=201): - with freeze_time('2019-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2019-04-08 15:16:23.42', tick=False) as frozen_time: for _x in range(0, 6): # Make the IP different every time so that we test the user # throttling. @@ -718,7 +718,7 @@ def _test_throttling_verb_user_burst(self, verb, url, expected_status=201): # 'Burst' throttling is 1 minute, so 61 seconds later we should be # allowed again. - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self.request( verb, url=url, @@ -731,7 +731,7 @@ def _test_throttling_verb_user_burst(self, verb, url, expected_status=201): assert response.status_code == expected_status def _test_throttling_verb_user_hourly(self, verb, url, expected_status=201): - with freeze_time('2019-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2019-04-08 15:16:23.42', tick=False) as frozen_time: # 21 is above the hourly limit but below the daily one. for _x in range(0, 21): # Make the IP different every time so that we test the user @@ -758,7 +758,7 @@ def _test_throttling_verb_user_hourly(self, verb, url, expected_status=201): # One minute later, past the 'burst' throttling period, we're still # blocked by the 'hourly' limit. - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self.request( verb, url=url, @@ -771,7 +771,7 @@ def _test_throttling_verb_user_hourly(self, verb, url, expected_status=201): assert response.status_code == 429 # 3601 seconds later we should be allowed again. - frozen_time.tick(delta=timedelta(seconds=3601)) + frozen_time.shift(delta=timedelta(seconds=3601)) response = self.request( verb, url=url, @@ -784,7 +784,7 @@ def _test_throttling_verb_user_hourly(self, verb, url, expected_status=201): assert response.status_code == expected_status, response.json() def _test_throttling_verb_user_daily(self, verb, url, expected_status=201): - with freeze_time('2019-04-08 15:16:23.42') as frozen_time: + with time_machine.travel('2019-04-08 15:16:23.42', tick=False) as frozen_time: for _x in range(0, 50): # Make the IP different every time so that we test the user # throttling. @@ -810,7 +810,7 @@ def _test_throttling_verb_user_daily(self, verb, url, expected_status=201): # One minute later, past the 'burst' throttling period, we're still # blocked by the 'hourly' limit. - frozen_time.tick(delta=timedelta(seconds=61)) + frozen_time.shift(delta=timedelta(seconds=61)) response = self.request( verb, url=url, @@ -823,7 +823,7 @@ def _test_throttling_verb_user_daily(self, verb, url, expected_status=201): assert response.status_code == 429 # After the hourly limit, still blocked. - frozen_time.tick(delta=timedelta(seconds=3601)) + frozen_time.shift(delta=timedelta(seconds=3601)) response = self.request( verb, url=url, @@ -836,7 +836,7 @@ def _test_throttling_verb_user_daily(self, verb, url, expected_status=201): assert response.status_code == 429 # 86401 seconds later we should be allowed again (24h + 1s). - frozen_time.tick(delta=timedelta(seconds=86401)) + frozen_time.shift(delta=timedelta(seconds=86401)) response = self.request( verb, url=url, @@ -893,7 +893,7 @@ def test_throttling_ignored_for_special_users(self): self.user, ':'.join(amo.permissions.API_BYPASS_THROTTLING) ) url = self.url(self.guid, '3.0') - with freeze_time('2019-04-08 15:16:23.42'): + with time_machine.travel('2019-04-08 15:16:23.42', tick=False): for _x in range(0, 60): # With that many actions all throttling classes should prevent # the user from submitting an addon... @@ -1262,7 +1262,7 @@ class TestTestUploadVersionWebextensionTransactions( def test_activity_log_saved_on_throttling(self): url = reverse_ns('signing.version', api_version='v4') - with freeze_time('2019-04-08 15:16:23.42'): + with time_machine.travel('2019-04-08 15:16:23.42', tick=False): for _x in range(0, 3): self._add_fake_throttling_action( view_class=self.view_class, @@ -1451,7 +1451,7 @@ def test_not_throttling_get(self): self.create_version('3.0') url = self.url(self.guid, '3.0') - with freeze_time('2019-04-08 15:16:23.42'): + with time_machine.travel('2019-04-08 15:16:23.42', tick=False): for _x in range(0, 60): # With that many actions all throttling classes should prevent # the user from submitting an addon... diff --git a/src/olympia/users/tests/test_models.py b/src/olympia/users/tests/test_models.py index 95df469188a2..97c3cf77b11f 100644 --- a/src/olympia/users/tests/test_models.py +++ b/src/olympia/users/tests/test_models.py @@ -15,7 +15,7 @@ import pytest import responses -from freezegun import freeze_time +import time_machine from olympia import amo, core from olympia.access.models import Group, GroupUser @@ -1775,7 +1775,9 @@ def test_is_expired(self): ) assert not email_verification.is_expired - with freeze_time(email_verification.created + timedelta(days=31)): + with time_machine.travel( + email_verification.created + timedelta(days=31), tick=False + ): assert email_verification.is_expired def test_is_timedout(self): @@ -1784,5 +1786,7 @@ def test_is_timedout(self): ) assert not email_verification.is_timedout - with freeze_time(email_verification.created + timedelta(minutes=10, seconds=1)): + with time_machine.travel( + email_verification.created + timedelta(minutes=10, seconds=1), tick=False + ): assert email_verification.is_timedout diff --git a/src/olympia/users/tests/test_user_utils.py b/src/olympia/users/tests/test_user_utils.py index e0a94fcc1abd..3f4900cc143c 100644 --- a/src/olympia/users/tests/test_user_utils.py +++ b/src/olympia/users/tests/test_user_utils.py @@ -10,7 +10,7 @@ import pytest import responses -from freezegun import freeze_time +import time_machine from olympia import amo, core from olympia.activity.models import ActivityLog @@ -412,7 +412,7 @@ def test_auth_header_present(self): in responses.calls[0].request.headers['authorization'] ) - @freeze_time('2023-06-26 11:00') + @time_machine.travel('2023-06-26 11:00', tick=False) def test_format_date_params(self): self.with_verification() diff --git a/src/olympia/versions/tests/test_utils.py b/src/olympia/versions/tests/test_utils.py index b3d0134e0e3b..8973e6513994 100644 --- a/src/olympia/versions/tests/test_utils.py +++ b/src/olympia/versions/tests/test_utils.py @@ -10,7 +10,7 @@ from django.utils.encoding import force_str import pytest -from freezegun import freeze_time +import time_machine from PIL import Image, ImageChops from olympia import amo @@ -208,12 +208,12 @@ def test_get_review_due_date(): ) -@freeze_time('2023-05-22 11:00') +@time_machine.travel('2023-05-22 11:00', tick=False) def test_get_review_due_date_default_starting_date_now(): assert get_review_due_date() == datetime(2023, 5, 25, 11, 0) -@freeze_time('2023-05-16 11:00') +@time_machine.travel('2023-05-16 11:00', tick=False) @pytest.mark.django_db def test_get_staggered_review_due_date_generator(): # Default config is to start from now + REVIEWER_STANDARD_REVIEW_TIME, and @@ -241,7 +241,7 @@ def test_get_staggered_review_due_date_generator(): assert due == datetime(2023, 5, 23, 2, 0) -@freeze_time('2023-05-16 11:00') +@time_machine.travel('2023-05-16 11:00', tick=False) def test_get_staggered_review_due_date_generator_default_target_provided(): generator = get_staggered_review_due_date_generator(target_per_day=2) due = next(generator) @@ -252,7 +252,7 @@ def test_get_staggered_review_due_date_generator_default_target_provided(): assert due == datetime(2023, 5, 22, 11, 0) -@freeze_time('2023-05-19 11:00') +@time_machine.travel('2023-05-19 11:00', tick=False) def test_get_staggered_review_due_date_generator_default_initial_days_delay(): generator = get_staggered_review_due_date_generator( initial_days_delay=2, target_per_day=8 @@ -273,7 +273,7 @@ def test_get_staggered_review_due_date_generator_default_initial_starting_date() assert due == datetime(2023, 5, 26, 11, 0) -@freeze_time('2023-05-16 11:00') +@time_machine.travel('2023-05-16 11:00', tick=False) @pytest.mark.django_db def test_get_staggered_review_due_date_generator_custom_config(): set_config(amo.config_keys.EXTRA_REVIEW_TARGET_PER_DAY.key, 4) @@ -289,7 +289,7 @@ def test_get_staggered_review_due_date_generator_custom_config(): @mock.patch('olympia.zadmin.models.log') -@freeze_time('2023-05-16 11:00') +@time_machine.travel('2023-05-16 11:00', tick=False) @pytest.mark.django_db def test_get_staggered_review_due_date_generator_garbage_config(log_mock): set_config(amo.config_keys.EXTRA_REVIEW_TARGET_PER_DAY, 'lolweird')