From 5fa6e9da346487bf99877ba6376b534d1851a46f Mon Sep 17 00:00:00 2001 From: Just van den Broecke Date: Sat, 19 Sep 2026 14:23:58 +0200 Subject: [PATCH] #506 fix - add timezone to checked_datetime in Run for Flush check --- GeoHealthCheck/models.py | 3 ++- pyproject.toml | 1 + tasks.py | 9 +++++++ tests/test_resources.py | 52 ++++++++++++++++++++++++++++++++++------ 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/GeoHealthCheck/models.py b/GeoHealthCheck/models.py index 15ea912f..a3802e72 100644 --- a/GeoHealthCheck/models.py +++ b/GeoHealthCheck/models.py @@ -56,7 +56,8 @@ def flush_runs(): all_runs = Run.query.all() run_count = 0 for run in all_runs: - days_old = (datetime.now(timezone.utc) - run.checked_datetime).days + days_old = (datetime.now(timezone.utc) - + run.checked_datetime.replace(tzinfo=timezone.utc)).days if days_old > retention_days: run_count += 1 DB.session.delete(run) diff --git a/pyproject.toml b/pyproject.toml index 7bca41a8..7bd8015e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -90,6 +90,7 @@ load-data = "invoke load-data" drop-data = "invoke drop-data" create-secret-key = "invoke create-secret-key" run = "python GeoHealthCheck/app.py" +flush-runs = "python GeoHealthCheck/models.py flush" docs = "invoke refresh-docs" clean = "invoke clean" runner-daemon = "invoke runner-daemon" diff --git a/tasks.py b/tasks.py index 3f834ead..4081e7c0 100644 --- a/tasks.py +++ b/tasks.py @@ -190,6 +190,15 @@ def drop_data(c): c.run(f'python {models_py} drop') +@task +def flush_runs(c): + """delete Runs older than retention time from database""" + + models_py = Path('GeoHealthCheck/models.py') + + c.run(f'python {models_py} flush') + + @task def create_hash(c, password): """Create hash, mainly for passwords""" diff --git a/tests/test_resources.py b/tests/test_resources.py index ab9df17e..263aeca1 100644 --- a/tests/test_resources.py +++ b/tests/test_resources.py @@ -30,9 +30,10 @@ import unittest import os +from datetime import timedelta from init import App -from models import (DB, Resource, Run, load_data, Recipient) +from models import (DB, Resource, Run, load_data, flush_runs, Recipient) from healthcheck import run_test_resource from notifications import _parse_webhook_location from resourceauth import ResourceAuth @@ -89,6 +90,43 @@ def testRunResoures(self): 'Run should be success for %s report=%s' % (resource.url, str(resource.runs[0]))) + def testFlushRuns(self): + # Do the one healthcheck for one Resource. + resource = Resource.query.first() + result = run_test_resource(resource) + print('resource: %s result=%s' % (resource.url, result.success)) + run = Run(resource, result) + + print('Adding Run: success=%s, response_time=%ss\n' + % (str(run.success), run.response_time)) + self.db.session.add(run) + self.db.session.commit() + self.db.session.close() + + flush_runs() + + # Verify + resource = Resource.query.first() + # Resource should have one recent Run + self.assertEqual( + resource.runs.count(), 1, + 'RunCount should be 1 for %s' % resource.url) + + run = resource.runs.first() + + # Outdate the Run + run.checked_datetime = run.checked_datetime - timedelta(days=365) + self.db.session.add(run) + self.db.session.commit() + self.db.session.close() + flush_runs() + # Verify + resource = Resource.query.first() + # Resource should have one recent Run + self.assertEqual( + resource.runs.count(), 0, + 'RunCount should be 0 for %s' % resource.url) + def testNotificationsApi(self): Rcp = Recipient test_emails = ['test@test.com', 'other@test.com', 'unused@test.com'] @@ -157,7 +195,7 @@ def testSetGetResoureAuth(self): 'data': { 'username': 'the_user', 'password': 'the_password' - } + } } resource.auth = auth_dict @@ -172,7 +210,7 @@ def testSetGetResoureAuth(self): 'type': 'Bearer Token', 'data': { 'token': 'a8KeTFOceitnRWT3M2rt' - } + } } resource.auth = auth_dict @@ -204,7 +242,7 @@ def testResoureAuthPlugins(self): 'data': { 'username': 'the_user', 'password': 'the_password' - } + } } auth_obj = ResourceAuth.create(auth_dict) @@ -223,7 +261,7 @@ def testResoureAuthPlugins(self): 'data': { 'username': '', 'password': '' - } + } } auth_obj = ResourceAuth.create(auth_dict) self.assertEqual(auth_obj.verify(), False) @@ -233,7 +271,7 @@ def testResoureAuthPlugins(self): 'data': { 'username': None, 'password': None - } + } } auth_obj = ResourceAuth.create(auth_dict) self.assertEqual(auth_obj.verify(), False) @@ -243,7 +281,7 @@ def testResoureAuthPlugins(self): 'type': 'Bearer Token', 'data': { 'token': 'a8KeTFOceitnRWT3M2rt' - } + } } auth_obj = ResourceAuth.create(auth_dict)