From 0d42dd46d67ac9a7028493b14e9314e250cbbe0f Mon Sep 17 00:00:00 2001
From: Paul Marillonnet <pmarillonnet@entrouvert.com>
Date: Fri, 17 Apr 2020 10:46:28 +0200
Subject: [PATCH] tests: add cache clearance autouse fixture (#41813)

---
 tests/auth_fc/conftest.py | 15 +++++++++++++--
 tests/conftest.py         | 20 ++++++++++++++++++--
 tests/test_auth_oidc.py   | 13 -------------
 tests/test_idp_oidc.py    | 13 -------------
 tests/test_manager.py     |  8 --------
 5 files changed, 31 insertions(+), 38 deletions(-)

diff --git a/tests/auth_fc/conftest.py b/tests/auth_fc/conftest.py
index f277abb02..0655f66e6 100644
--- a/tests/auth_fc/conftest.py
+++ b/tests/auth_fc/conftest.py
@@ -19,7 +19,11 @@ import pytest
 import django_webtest
 
 from django.contrib.auth import get_user_model
+from django.core.cache import cache
 from django_rbac.utils import get_ou_model
+
+from authentic2 import hooks as a2_hooks
+from authentic2.manager.utils import get_ou_count
 from authentic2_auth_fc.models import FcAccount
 
 
@@ -102,11 +106,18 @@ def user_cartman(db, ou_southpark):
                        email='ecartman@southpark.org', ou=ou_southpark, federation=CARTMAN_FC_INFO)
 
 
+@pytest.fixture(autouse=True)
+def clear_cache():
+    OU = get_ou_model()
+
+    cache.clear()
+    for cached_el in (OU.cached, a2_hooks.get_hooks, get_ou_count):
+        cached_el.cache.clear()
+
+
 class AllHook(object):
     def __init__(self):
         self.calls = {}
-        from authentic2 import hooks
-        hooks.get_hooks.cache.clear()
 
     def __call__(self, hook_name, *args, **kwargs):
         calls = self.calls.setdefault(hook_name, [])
diff --git a/tests/conftest.py b/tests/conftest.py
index 179c28c28..831a26f76 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -22,14 +22,21 @@ import mock
 import django_webtest
 
 from django.contrib.auth import get_user_model
+from django.core.cache import cache
 from django_rbac.utils import get_ou_model, get_role_model
 from django.conf import settings
 from django.utils.six.moves.urllib import parse as urlparse
 
 from pytest_django.migrations import DisableMigrations
 
+from authentic2 import hooks as a2_hooks
 from authentic2.models import Service
+from authentic2.utils.evaluate import BaseExpressionValidator
 from authentic2.a2_rbac.utils import get_default_ou
+from authentic2.manager.utils import get_ou_count
+from authentic2_auth_oidc.utils import get_providers
+from authentic2_auth_oidc.utils import get_provider_by_issuer
+from authentic2_auth_oidc.utils import has_providers
 from authentic2_idp_oidc.models import OIDCClient
 from authentic2.authentication import OIDCUser
 
@@ -267,11 +274,20 @@ def api_user(request, oidc_client, superuser, user_ou1, user_ou2,
     return locals().get(request.param)
 
 
+@pytest.fixture(autouse=True)
+def clear_cache():
+    OU = get_ou_model()
+
+    cache.clear()
+    BaseExpressionValidator.__call__.cache_clear()
+    for cached_el in (OU.cached, a2_hooks.get_hooks, get_providers,
+            get_provider_by_issuer, get_ou_count, has_providers):
+        cached_el.cache.clear()
+
+
 class AllHook(object):
     def __init__(self):
         self.calls = {}
-        from authentic2 import hooks
-        hooks.get_hooks.cache.clear()
 
     def __call__(self, hook_name, *args, **kwargs):
         calls = self.calls.setdefault(hook_name, [])
diff --git a/tests/test_auth_oidc.py b/tests/test_auth_oidc.py
index 664d94fac..7ba8b153d 100644
--- a/tests/test_auth_oidc.py
+++ b/tests/test_auth_oidc.py
@@ -153,9 +153,6 @@ def make_oidc_provider(
         idtoken_algo=OIDCProvider._meta.get_field('idtoken_algo').default,
         jwkset=None,
         claims_parameter_supported=False):
-    from authentic2_auth_oidc.utils import get_provider, get_provider_by_issuer
-    get_provider.cache.clear()
-    get_provider_by_issuer.cache.clear()
 
     if jwkset is not None:
         jwkset = json.loads(jwkset.export())
@@ -453,7 +450,6 @@ def test_login_with_conditionnal_authenticators(oidc_provider, app, settings, ca
 def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, hooks):
     OU = get_ou_model()
     cassis = OU.objects.create(name='Cassis', slug='cassis')
-    OU.cached.cache.clear()
 
     response = app.get('/admin/').maybe_follow()
     assert oidc_provider.name in response.text
@@ -567,9 +563,6 @@ def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, hooks):
 
 
 def test_show_on_login_page(app, oidc_provider):
-    # we have a 5 seconds cache on list of providers, we have to work around it
-    get_providers.cache.clear()
-    has_providers.cache.clear()
     response = app.get('/login/')
     assert 'oidc-a-oididp' in response.text
 
@@ -586,8 +579,6 @@ def test_show_on_login_page(app, oidc_provider):
 
 def test_strategy_find_uuid(app, caplog, code, oidc_provider, oidc_provider_jwkset, simple_user):
 
-    get_providers.cache.clear()
-    has_providers.cache.clear()
     # no mapping please
     OIDCClaimMapping.objects.all().delete()
     oidc_provider.strategy = oidc_provider.STRATEGY_FIND_UUID
@@ -674,8 +665,6 @@ def test_required_keys(db, oidc_provider, caplog):
 def test_invalid_kid(app, caplog, code, oidc_provider_rsa,
                      oidc_provider_jwkset, simple_user):
 
-    get_providers.cache.clear()
-    has_providers.cache.clear()
     # no mapping please
     OIDCClaimMapping.objects.all().delete()
 
@@ -701,8 +690,6 @@ def test_invalid_kid(app, caplog, code, oidc_provider_rsa,
 
 
 def test_templated_claim_mapping(app, caplog, code, oidc_provider, oidc_provider_jwkset):
-    get_providers.cache.clear()
-    has_providers.cache.clear()
 
     Attribute.objects.create(
         name='pro_phone',
diff --git a/tests/test_idp_oidc.py b/tests/test_idp_oidc.py
index baf2399fc..6eeb58451 100644
--- a/tests/test_idp_oidc.py
+++ b/tests/test_idp_oidc.py
@@ -25,7 +25,6 @@ from jwcrypto.jwk import JWKSet, JWK
 
 import utils
 
-from django.core.cache import cache
 from django.core.urlresolvers import reverse
 from django.core.files import File
 from django.db import connection
@@ -1290,7 +1289,6 @@ def test_filter_api_users(app, oidc_client, admin, simple_user, role_random):
 
 
 def test_credentials_grant(app, oidc_client, admin, simple_user):
-    cache.clear()
     oidc_client.authorization_flow = OIDCClient.FLOW_RESOURCE_OWNER_CRED
     oidc_client.scope = 'openid'
     oidc_client.save()
@@ -1342,7 +1340,6 @@ def test_credentials_grant_ratelimitation_invalid_client(
         app, oidc_client, admin, simple_user, oidc_settings, freezer):
     freezer.move_to('2020-01-01')
 
-    cache.clear()
     oidc_client.authorization_flow = OIDCClient.FLOW_RESOURCE_OWNER_CRED
     oidc_client.save()
     token_url = make_url('oidc-token')
@@ -1366,7 +1363,6 @@ def test_credentials_grant_ratelimitation_valid_client(
         app, oidc_client, admin, simple_user, oidc_settings, freezer):
     freezer.move_to('2020-01-01')
 
-    cache.clear()
     oidc_client.authorization_flow = OIDCClient.FLOW_RESOURCE_OWNER_CRED
     oidc_client.save()
     token_url = make_url('oidc-token')
@@ -1388,7 +1384,6 @@ def test_credentials_grant_retrytimout(
         app, oidc_client, admin, simple_user, settings, freezer):
     freezer.move_to('2020-01-01')
 
-    cache.clear()
     settings.A2_LOGIN_EXPONENTIAL_RETRY_TIMEOUT_DURATION = 2
     oidc_client.authorization_flow = OIDCClient.FLOW_RESOURCE_OWNER_CRED
     oidc_client.save()
@@ -1419,7 +1414,6 @@ def test_credentials_grant_retrytimout(
 
 def test_credentials_grant_invalid_flow(
         app, oidc_client, admin, simple_user, settings):
-    cache.clear()
     params = {
         'client_id': oidc_client.client_id,
         'client_secret': oidc_client.client_secret,
@@ -1435,7 +1429,6 @@ def test_credentials_grant_invalid_flow(
 
 def test_credentials_grant_invalid_client(
         app, oidc_client, admin, simple_user, settings):
-    cache.clear()
     oidc_client.authorization_flow = OIDCClient.FLOW_RESOURCE_OWNER_CRED
     oidc_client.save()
     params = {
@@ -1453,7 +1446,6 @@ def test_credentials_grant_invalid_client(
 
 def test_credentials_grant_unauthz_client(
         app, oidc_client, admin, simple_user, settings):
-    cache.clear()
     params = {
         'client_id': oidc_client.client_id,
         'client_secret': oidc_client.client_secret,
@@ -1469,7 +1461,6 @@ def test_credentials_grant_unauthz_client(
 
 def test_credentials_grant_invalid_content_type(
         app, oidc_client, admin, simple_user, settings):
-    cache.clear()
     oidc_client.authorization_flow = OIDCClient.FLOW_RESOURCE_OWNER_CRED
     oidc_client.save()
     params = {
@@ -1490,7 +1481,6 @@ def test_credentials_grant_invalid_content_type(
 
 def test_credentials_grant_ou_selection_simple(
         app, oidc_client, admin, user_ou1, user_ou2, ou1, ou2, settings):
-    cache.clear()
     oidc_client.authorization_flow = OIDCClient.FLOW_RESOURCE_OWNER_CRED
     oidc_client.save()
     params = {
@@ -1511,7 +1501,6 @@ def test_credentials_grant_ou_selection_simple(
 
 def test_credentials_grant_ou_selection_username_not_unique(
         app, oidc_client, admin, user_ou1, admin_ou2, ou1, ou2, settings):
-    cache.clear()
     settings.A2_USERNAME_IS_UNIQUE = False
     oidc_client.authorization_flow = OIDCClient.FLOW_RESOURCE_OWNER_CRED
     oidc_client.save()
@@ -1539,7 +1528,6 @@ def test_credentials_grant_ou_selection_username_not_unique(
 
 def test_credentials_grant_ou_selection_username_not_unique_wrong_ou(
         app, oidc_client, admin, user_ou1, admin_ou2, ou1, ou2, settings):
-    cache.clear()
     settings.A2_USERNAME_IS_UNIQUE = False
     oidc_client.authorization_flow = OIDCClient.FLOW_RESOURCE_OWNER_CRED
     oidc_client.save()
@@ -1562,7 +1550,6 @@ def test_credentials_grant_ou_selection_username_not_unique_wrong_ou(
 
 def test_credentials_grant_ou_selection_invalid_ou(
         app, oidc_client, admin, user_ou1, settings):
-    cache.clear()
     params = {
         'client_id': oidc_client.client_id,
         'client_secret': oidc_client.client_secret,
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 180d84e4f..7452b80a2 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -69,10 +69,6 @@ def test_manager_create_ou(superuser_or_admin, app):
 
 
 def test_manager_create_role(superuser_or_admin, app):
-    # clear cache from previous runs
-    from authentic2.manager.utils import get_ou_count
-    get_ou_count.cache.cache = {}
-
     non_admin_roles = Role.objects.exclude(slug__startswith='_')
 
     ou_add = login(app, superuser_or_admin, reverse('a2-manager-role-add'))
@@ -185,10 +181,6 @@ def test_role_members_show_all_ou(app, superuser, settings):
 
 
 def test_manager_create_user(superuser_or_admin, app, settings):
-    # clear cache from previous runs
-    from authentic2.manager.utils import get_ou_count
-    get_ou_count.cache.clear()
-
     ou1 = OU.objects.create(name='OU1', slug='ou1')
     ou2 = OU.objects.create(name='OU2', slug='ou2', email_is_unique=True)
 
-- 
2.26.1

