#600 Cache passed results
Merged 3 years ago by lholecek. Opened 3 years ago by lholecek.
lholecek/greenwave cache-passed-results  into  master

Cache passed results
Lukas Holecek • 3 years ago  
file modified
+22
@@ -63,6 +63,16 @@ 

                      return [result]

              return []

  

+         # Try to get passing test case result from external cache.

+         external_cache_key = None

+         if testcase and not self.since:

+             external_cache_key = (

+                 "greenwave.resources:ResultsRetriever|"

+                 f"{subject.type} {subject.identifier} {testcase} {scenarios}")

+             results = self.get_external_cache(external_cache_key)

+             if results:

+                 return results

+ 

          params = {

              '_distinct_on': 'scenario,system_architecture,system_variant'

          }
@@ -81,6 +91,12 @@ 

          if not testcase:

              self.cache[cache_key] = results

  

+         # Store test case results in external cache if all are passing,

+         # otherwise retrieve from ResultsDB again later.

+         if external_cache_key and all(

+                 result.get('outcome') in ('PASSED', 'INFO') for result in results):

+             self.set_external_cache(external_cache_key, results)

+ 

          return results

  

      def _make_request(self, params, **request_args):
@@ -89,6 +105,12 @@ 

              params=params,

              **request_args)

  

+     def get_external_cache(self, key):

+         return current_app.cache.get(key)

+ 

+     def set_external_cache(self, key, value):

+         current_app.cache.set(key, value)

+ 

  

  class WaiversRetriever(BaseRetriever):

      """

@@ -44,12 +44,15 @@ 

          self.subject = subject

          self.testcase = testcase

          self.outcome = outcome

+         self.external_cache = {}

+         self.retrieve_data_called = 0

  

      def _retrieve_data(self, params):

+         self.retrieve_data_called += 1

          if (self.subject and (params.get('item') == self.subject.identifier or

                                params.get('nvr') == self.subject.identifier) and

                  ('type' not in params or self.subject.type in params['type'].split(',')) and

-                 params.get('testcases') == self.testcase):

+                 (params.get('testcases') is None or params.get('testcases') == self.testcase)):

              return [{

                  'id': 123,

                  'data': {
@@ -61,6 +64,12 @@ 

              }]

          return []

  

+     def get_external_cache(self, key):

+         return self.external_cache.get(key)

+ 

+     def set_external_cache(self, key, value):

+         self.external_cache[key] = value

+ 

  

  def test_summarize_answers():

      subject = create_test_subject('koji_build', 'nvr')
@@ -1442,3 +1451,46 @@ 

                  decision = policy.check('fedora-31', subject, results)

                  assert len(decision) == 1

                  assert isinstance(decision[0], TestResultFailed)

+ 

+ 

+ def test_cache_all_results_temporarily():

+     """

+     All results are stored in temporary cache (valid during single request).

+     """

+     subject = create_test_subject('bodhi_update', 'update-1')

+     results = DummyResultsRetriever(subject, 'sometest', 'FAILED')

+ 

+     retrieved = results.retrieve(subject, testcase=None)

+     assert results.retrieve_data_called == 1

+     assert retrieved

+ 

+     cached = results.retrieve(subject, testcase='sometest')

+     assert results.retrieve_data_called == 1

+     assert cached == retrieved

+ 

+ 

+ def test_cache_passing_results():

+     """

+     Passing results are stored in external cache because it's not expected that

+     the outcome changes once they passed.

+     """

+     subject = create_test_subject('bodhi_update', 'update-1')

+     results = DummyResultsRetriever(subject, 'sometest', 'FAILED')

+ 

+     retrieved = results.retrieve(subject, testcase=None)

+     assert results.retrieve_data_called == 1

+     assert retrieved

+ 

+     results2 = DummyResultsRetriever(subject, 'sometest', 'PASSED')

+     results2.external_cache = results.external_cache

+     retrieved2 = results2.retrieve(subject, testcase='sometest')

+     assert results2.retrieve_data_called == 1

+     assert retrieved2

+     assert retrieved2 != retrieved

+ 

+     # Result stays PASSED even if the latest is now FAILED.

+     results3 = DummyResultsRetriever(subject, 'sometest', 'FAILED')

+     results3.external_cache = results.external_cache

+     cached = results3.retrieve(subject, testcase='sometest')

+     assert results3.retrieve_data_called == 0

+     assert cached == retrieved2

Store passed test results in cache since it's not expected for them to
change to failed once they passed. This avoids doing additional
ResultsDB queries.

Signed-off-by: Lukas Holecek hluk@email.cz

rebased onto 6562bf3

3 years ago

Pull-Request has been merged by lholecek

3 years ago