[Patchew-devel] [PATCH 5/8] rest: include log directly in /.../results/xyz response

Paolo Bonzini pbonzini at redhat.com
Sat Mar 24 13:37:16 UTC 2018


Returning all the logs in the list view might make the response too large,
but we include it when retrieving a single result.  This also makes sense
because a POST or PUT request for a result should include the log.

Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
 api/models.py         |  6 +++---
 api/rest.py           | 18 +++++++++++++-----
 mods/git.py           |  4 ++--
 mods/testing.py       |  8 ++++++--
 tests/test_git.py     |  5 +++++
 tests/test_testing.py |  4 ++++
 6 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/api/models.py b/api/models.py
index 6141ac1..96d514a 100644
--- a/api/models.py
+++ b/api/models.py
@@ -595,13 +595,13 @@ class Module(models.Model):
     def __str__(self):
         return self.name
 
-class Result(namedtuple("Result", "name status log_url obj data")):
+class Result(namedtuple("Result", "name status log log_url obj data")):
     __slots__ = ()
 
-    def __new__(cls, name, status, obj, log_url=None, data=None, request=None):
+    def __new__(cls, name, status, obj, log=None, log_url=None, data=None, request=None):
         if log_url is not None and request is not None:
             log_url = request.build_absolute_uri(log_url)
         if status not in ('pending', 'success', 'failure'):
             raise ValueError("invalid value '%s' for status field" % status)
-        return super(cls, Result).__new__(cls, status=status, log_url=log_url,
+        return super(cls, Result).__new__(cls, status=status, log=log, log_url=log_url,
                                           obj=obj, data=data, name=name)
diff --git a/api/rest.py b/api/rest.py
index 1e2b774..9b1f103 100644
--- a/api/rest.py
+++ b/api/rest.py
@@ -330,8 +330,10 @@ class ResultSerializer(serializers.Serializer):
     log_url = CharField(required=False)
     data = JSONField(required=False)
 
+class ResultSerializerFull(ResultSerializer):
+    log = CharField(required=False)
+
 class SeriesResultsViewSet(viewsets.ViewSet, generics.GenericAPIView):
-    serializer_class = ResultSerializer
     lookup_field = 'name'
     lookup_value_regex = '[^/]+'
 
@@ -339,7 +341,12 @@ class SeriesResultsViewSet(viewsets.ViewSet, generics.GenericAPIView):
         return Message.objects.filter(project=self.kwargs['projects_pk'],
                                       message_id=self.kwargs['series_message_id'])
 
-    def get_results(self):
+    def get_serializer_class(self, *args, **kwargs):
+        if self.lookup_field in self.kwargs:
+            return ResultSerializerFull
+        return ResultSerializer
+
+    def get_results(self, detailed):
         queryset = self.get_queryset()
         try:
             obj = queryset[0]
@@ -347,11 +354,12 @@ class SeriesResultsViewSet(viewsets.ViewSet, generics.GenericAPIView):
             raise Http404
         results = []
         dispatch_module_hook("rest_results_hook", request=self.request,
-                             obj=obj, results=results)
+                             obj=obj, results=results,
+                             detailed=detailed)
         return {x.name: x for x in results}
 
     def list(self, request, *args, **kwargs):
-        results = self.get_results().values()
+        results = self.get_results(detailed=False).values()
         serializer = self.get_serializer(results, many=True)
         # Fake paginator response for forwards-compatibility, in case
         # this ViewSet becomes model-based
@@ -361,7 +369,7 @@ class SeriesResultsViewSet(viewsets.ViewSet, generics.GenericAPIView):
         ]))
 
     def retrieve(self, request, name, *args, **kwargs):
-        results = self.get_results()
+        results = self.get_results(detailed=True)
         try:
             result = results[name]
         except KeyError:
diff --git a/mods/git.py b/mods/git.py
index 13c3642..6d4f365 100644
--- a/mods/git.py
+++ b/mods/git.py
@@ -111,7 +111,7 @@ class GitModule(PatchewModule):
             raise Exception("Project git repo invalid: %s" % project_git)
         return upstream, branch
 
-    def rest_results_hook(self, request, obj, results):
+    def rest_results_hook(self, request, obj, results, detailed=False):
         log = obj.get_property("git.apply-log")
         data = None
         if log:
@@ -127,7 +127,7 @@ class GitModule(PatchewModule):
             status = 'pending'
             log_url = None
         results.append(Result(name='git', obj=obj, status=status,
-                              log_url=log_url, data=data,
+                              log=log, log_url=log_url, data=data,
                               request=request))
 
     def prepare_message_hook(self, request, message, detailed):
diff --git a/mods/testing.py b/mods/testing.py
index 21942d5..306c99f 100644
--- a/mods/testing.py
+++ b/mods/testing.py
@@ -276,7 +276,7 @@ class TestingModule(PatchewModule):
         return reverse("testing-get-prop",
                        kwargs={"project_or_series": obj.message_id})
 
-    def rest_results_hook(self, request, obj, results):
+    def rest_results_hook(self, request, obj, results, detailed=False):
         for pn, p in obj.get_properties().items():
             if not pn.startswith("testing.report."):
                 continue
@@ -284,11 +284,15 @@ class TestingModule(PatchewModule):
             failed = not p["passed"]
             log_url = self.reverse_testing_log(obj, tn, request=request, html=False)
             passed_str = "failure" if failed else "success"
+            if detailed:
+                log = obj.get_property("testing.log." + tn)
+            else:
+                log = None
 
             data = p.copy()
             del data['passed']
             results.append(Result(name='testing.' + tn, obj=obj, status=passed_str,
-                                  log_url=log_url, request=request, data=data))
+                                  log=log, log_url=log_url, request=request, data=data))
 
     def prepare_message_hook(self, request, message, detailed):
         if not message.is_series_head:
diff --git a/tests/test_git.py b/tests/test_git.py
index 8bff7d5..38a3c50 100755
--- a/tests/test_git.py
+++ b/tests/test_git.py
@@ -105,6 +105,7 @@ class GitTest(PatchewTestCase):
         resp = self.api_client.get('%sseries/%s/results/git/' % (self.PROJECT_BASE, MESSAGE_ID))
         self.assertEqual(resp.data['status'], 'pending')
         self.assertEqual(resp.data['log_url'], None)
+        self.assertEqual(resp.data['log'], None)
 
     def test_rest_apply_failure(self):
         self.cli_import("0014-bar-patch.mbox.gz")
@@ -115,6 +116,8 @@ class GitTest(PatchewTestCase):
 
         resp = self.api_client.get('%sseries/%s/results/' % (self.PROJECT_BASE, MESSAGE_ID))
         self.assertEqual(resp.data['results'][0]['name'], 'git')
+        self.assertEqual('log' in resp.data['results'][0], False)
+        self.assertEqual('log_url' in resp.data['results'][0], True)
 
         resp = self.api_client.get('%sseries/%s/results/git/' % (self.PROJECT_BASE, MESSAGE_ID))
         self.assertEqual(resp.data['status'], 'failure')
@@ -122,6 +125,7 @@ class GitTest(PatchewTestCase):
         self.assertEqual('tag' in resp.data, False)
         log = self.client.get(resp.data['log_url'])
         self.assertEqual(log.status_code, 200)
+        self.assertEqual(log.content.decode(), resp.data['log'])
 
     def test_rest_apply_success(self):
         self.cli_import("0013-foo-patch.mbox.gz")
@@ -135,6 +139,7 @@ class GitTest(PatchewTestCase):
         self.assertEqual(resp.data['data']['tag'], "refs/tags/patchew/20160628014747.20971-1-famz at redhat.com")
         log = self.client.get(resp.data['log_url'])
         self.assertEqual(log.status_code, 200)
+        self.assertEqual(log.content.decode(), resp.data['log'])
 
 if __name__ == '__main__':
     main()
diff --git a/tests/test_testing.py b/tests/test_testing.py
index 369a806..a8345d8 100755
--- a/tests/test_testing.py
+++ b/tests/test_testing.py
@@ -97,6 +97,7 @@ class TestingTest(PatchewTestCase):
         self.msg_testing_done(log='everything good!', passed=True)
         resp = self.api_client.get('%sseries/%s/results/testing.tests/' % (self.PROJECT_BASE, self.msg.message_id))
         self.assertEquals(resp.data['status'], 'success')
+        self.assertEquals(resp.data['log'], 'everything good!')
         log = self.client.get(resp.data['log_url'])
         self.assertEquals(log.status_code, 200)
         self.assertEquals(log.content, b'everything good!')
@@ -106,6 +107,7 @@ class TestingTest(PatchewTestCase):
         resp = self.api_client.get('%sseries/%s/results/testing.tests/' % (self.PROJECT_BASE, self.msg.message_id))
         self.assertEquals(resp.data['status'], 'failure')
         self.assertEquals(resp.data['data']['random_stuff'], 'xyz')
+        self.assertEquals(resp.data['log'], 'sorry no good')
         log = self.client.get(resp.data['log_url'])
         self.assertEquals(log.status_code, 200)
         self.assertEquals(log.content, b'sorry no good')
@@ -117,6 +119,7 @@ class TestingTest(PatchewTestCase):
         self.assertEquals(resp.data['data']['is_timeout'], False)
         self.assertEquals(resp.data['status'], 'success')
         log = self.client.get(resp.data['log_url'])
+        self.assertEquals(resp.data['log'], 'everything good!')
         self.assertEquals(log.status_code, 200)
         self.assertEquals(log.content, b'everything good!')
 
@@ -126,6 +129,7 @@ class TestingTest(PatchewTestCase):
         resp = self.api_client.get('%sseries/%s/results/testing.a/' % (self.PROJECT_BASE, self.msg.message_id))
         self.assertEquals(resp.data['data']['is_timeout'], False)
         self.assertEquals(resp.data['status'], 'failure')
+        self.assertEquals(resp.data['log'], 'sorry no good')
         log = self.client.get(resp.data['log_url'])
         self.assertEquals(log.status_code, 200)
         self.assertEquals(log.content, b'sorry no good')
-- 
2.16.2





More information about the Patchew-devel mailing list