From d01077577d4b5e4101d7e1707df77fe08c9507be Mon Sep 17 00:00:00 2001 From: Lukas Holecek Date: Mar 25 2021 14:23:11 +0000 Subject: Cache passing results in ResultsDB consumer --- diff --git a/greenwave/resources.py b/greenwave/resources.py index 89d4fad..646af8e 100644 --- a/greenwave/resources.py +++ b/greenwave/resources.py @@ -69,12 +69,12 @@ class ResultsRetriever(BaseRetriever): # Try to get passing test case result from external cache. external_cache_key = None - if testcase and not self.since: + if testcase: external_cache_key = ( "greenwave.resources:ResultsRetriever|" f"{subject.type} {subject.identifier} {testcase} {scenarios}") results = self.get_external_cache(external_cache_key) - if results: + if results and self._results_match_time(results): return results params = { @@ -110,6 +110,13 @@ class ResultsRetriever(BaseRetriever): params=params, **request_args) + def _results_match_time(self, results): + if not self.since: + return True + + until = self.since.split(',')[1] + return all(result['submit_time'] < until for result in results) + def get_external_cache(self, key): return current_app.cache.get(key) diff --git a/greenwave/tests/test_policies.py b/greenwave/tests/test_policies.py index e354c30..fd9ac1d 100644 --- a/greenwave/tests/test_policies.py +++ b/greenwave/tests/test_policies.py @@ -27,6 +27,7 @@ from greenwave.safe_yaml import SafeYAMLError from greenwave.subjects.factory import create_subject from greenwave.waivers import waive_answers from greenwave.config import TestingConfig, Config +from greenwave.utils import add_to_timestamp @pytest.fixture(autouse=True) @@ -37,10 +38,10 @@ def app(): class DummyResultsRetriever(ResultsRetriever): - def __init__(self, subject=None, testcase=None, outcome='PASSED'): + def __init__(self, subject=None, testcase=None, outcome='PASSED', when=''): super(DummyResultsRetriever, self).__init__( ignore_ids=[], - when='', + when=when, url='') self.subject = subject self.testcase = testcase @@ -62,6 +63,7 @@ class DummyResultsRetriever(ResultsRetriever): }, 'testcase': {'name': self.testcase}, 'outcome': self.outcome, + 'submit_time': '2021-03-25T07:26:56.191741', }] return [] @@ -1539,3 +1541,19 @@ def test_cache_passing_results(): cached = results3.retrieve(subject, testcase='sometest') assert results3.retrieve_data_called == 0 assert cached == retrieved2 + + # Match submit_time with "since" parameter. + when1 = retrieved2[0]['submit_time'] + when2 = add_to_timestamp(when1, microseconds=1) + + results3 = DummyResultsRetriever(subject, 'sometest', 'FAILED', when=when1) + results3.external_cache = results.external_cache + not_cached = results3.retrieve(subject, testcase='sometest') + assert results3.retrieve_data_called == 1 + assert not_cached == retrieved + + results4 = DummyResultsRetriever(subject, 'sometest', 'FAILED', when=when2) + results4.external_cache = results.external_cache + cached = results4.retrieve(subject, testcase='sometest') + assert results4.retrieve_data_called == 0 + assert cached == retrieved2 diff --git a/greenwave/utils.py b/greenwave/utils.py index ab48e6e..d09fec9 100644 --- a/greenwave/utils.py +++ b/greenwave/utils.py @@ -131,7 +131,7 @@ def sha1_mangle_key(key): return hashlib.sha1(key.encode('utf-8')).hexdigest() -def right_before_this_time(timestamp): +def add_to_timestamp(timestamp, **kwargs): """ A utility function that takes a timestamp with format %Y-%m-%dT%H:%M:%S.%f and returns the microsecond before that timestamp. It returns always a @@ -139,6 +139,8 @@ def right_before_this_time(timestamp): ask for a decision before a specific timestamp (example: the creation of a result). """ + delta = datetime.timedelta(**kwargs) + date_format = '%Y-%m-%dT%H:%M:%S.%f' if timestamp.endswith(' UTC'): @@ -148,8 +150,12 @@ def right_before_this_time(timestamp): from_date_format = date_format return datetime.datetime.strftime( - datetime.datetime.strptime(timestamp, from_date_format) - - datetime.timedelta(microseconds=1), date_format) + datetime.datetime.strptime(timestamp, from_date_format) + delta, + date_format) + + +def right_before_this_time(timestamp): + return add_to_timestamp(timestamp, microseconds=-1) def remove_duplicates(func):