Repository: Kinto/kinto

Issue:
Add a clear cache command to kinto
For debugging purposes mainly we want to be able to clear the cache on time to time

Comments:

Patch:
diff --git a/docs/commandline.rst b/docs/commandline.rst
index e56d2080..7c1addef 100644
--- a/docs/commandline.rst
+++ b/docs/commandline.rst
@@ -139,3 +139,19 @@ For example:
 ::
 
     kinto rebuild-quotas --ini=config/postgresql.ini
+
+Flush Cache
+-----------
+
+Clears the Backend Cache.This can be useful for
+debugging. 
+
+::
+
+    kinto flush-cache [--ini INI_FILE]
+
+For example:
+
+::
+
+    kinto flush-cache --ini kinto.ini 
\ No newline at end of file
diff --git a/kinto/__main__.py b/kinto/__main__.py
index 4b935afe..dc2142b9 100644
--- a/kinto/__main__.py
+++ b/kinto/__main__.py
@@ -24,12 +24,13 @@ def main(args=None):
     if args is None:
         args = sys.argv[1:]
 
-    parser = argparse.ArgumentParser(description="Kinto Command-Line " "Interface")
+    parser = argparse.ArgumentParser(description="Kinto Command-Line Interface")
     commands = (
         "init",
         "start",
         "migrate",
         "delete-collection",
+        "flush-cache",
         "version",
         "rebuild-quotas",
         "create-user",
@@ -94,26 +95,34 @@ def main(args=None):
                 required=False,
                 default="127.0.0.1",
             )
+               
         elif command == "migrate":
             subparser.add_argument(
                 "--dry-run",
                 action="store_true",
-                help="Simulate the migration operations " "and show information",
+                help="Simulate the migration operations and show information",
                 dest="dry_run",
                 required=False,
                 default=False,
             )
+
         elif command == "delete-collection":
             subparser.add_argument(
-                "--bucket", help="The bucket where the collection " "belongs to.", required=True
+                "--bucket",
+                help="The bucket where the collection belongs to.",
+                required=True
+            )
+            subparser.add_argument(
+                "--collection",
+                help="The collection to remove.",
+                required=True
             )
-            subparser.add_argument("--collection", help="The collection to remove.", required=True)
 
         elif command == "rebuild-quotas":
             subparser.add_argument(
                 "--dry-run",
                 action="store_true",
-                help="Simulate the rebuild operation " "and show information",
+                help="Simulate the rebuild operation and show information",
                 dest="dry_run",
                 required=False,
                 default=False,
@@ -225,6 +234,10 @@ def main(args=None):
             env, parsed_args["bucket"], parsed_args["collection"]
         )
 
+    elif which_command == "flush-cache":
+        env = bootstrap(config_file, options={"command": "flush-cache"})
+        core_scripts.flush_cache(env)
+
     elif which_command == "rebuild-quotas":
         dry_run = parsed_args["dry_run"]
         env = bootstrap(config_file, options={"command": "rebuild-quotas"})
diff --git a/kinto/core/scripts.py b/kinto/core/scripts.py
index 83a4a5ff..5c89fb06 100644
--- a/kinto/core/scripts.py
+++ b/kinto/core/scripts.py
@@ -25,3 +25,10 @@ def migrate(env, dry_run=False):
                 logger.error(message)
             else:
                 getattr(registry, backend).initialize_schema(dry_run=dry_run)
+
+
+def flush_cache(env):
+    registry = env["registry"]
+    registry.cache.flush()
+    logger.info(f"Cache has been cleared.")
+    return 0


Test patch:
diff --git a/tests/core/test_scripts.py b/tests/core/test_scripts.py
index 4a00c8d2..6aa241c5 100644
--- a/tests/core/test_scripts.py
+++ b/tests/core/test_scripts.py
@@ -40,3 +40,8 @@ class InitSchemaTest(unittest.TestCase):
         reg.storage.initialize_schema.assert_called_with(dry_run=True)
         reg.cache.initialize_schema.assert_called_with(dry_run=True)
         reg.permission.initialize_schema.assert_called_with(dry_run=True)
+
+    def test_flush_cache_clear_the_cache_backend(self):
+        scripts.flush_cache({"registry": self.registry})
+        reg = self.registry
+        reg.cache.flush.assert_called_with()
diff --git a/tests/test_main.py b/tests/test_main.py
index 2dfe4a80..73acce40 100644
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -362,3 +362,22 @@ class TestMain(unittest.TestCase):
             mocked_logging.basicConfig.assert_called_with(
                 level=logging.INFO, format=DEFAULT_LOG_FORMAT
             )
+
+    def test_cli_flush_cache_command_runs_flush_cache_script(self):
+        # Build a temporary ini file.
+        res = main(
+            [
+                "init",
+                "--ini",
+                TEMP_KINTO_INI,
+                "--backend",
+                "memory",
+                "--cache-backend",
+                "memory",
+            ]
+        )
+        assert res == 0
+        with mock.patch("kinto.__main__.core_scripts.flush_cache") as mocked_cache_script:
+            res = main(["flush-cache", "--ini", TEMP_KINTO_INI])
+            assert res == 0
+            assert mocked_cache_script.call_count == 1