Mobrovac has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/386116 )

Change subject: [WIP] Improve the checking procedure and emit better messages
......................................................................

[WIP] Improve the checking procedure and emit better messages

Bug: T150560
Change-Id: Ide292c7ae8ced694e97fd7cde84ab65c28a69185
---
M servicechecker/swagger.py
1 file changed, 62 insertions(+), 6 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/software/service-checker 
refs/changes/16/386116/1

diff --git a/servicechecker/swagger.py b/servicechecker/swagger.py
index ab7137f..27bcbb1 100755
--- a/servicechecker/swagger.py
+++ b/servicechecker/swagger.py
@@ -116,7 +116,8 @@
                     if key == 'get':
                         default_example = [{
                             'request': {},
-                            'response': self.default_response
+                            'response': self.default_response,
+                            'title': 'Untitled test'
                         }]
                     else:
                         # Only GETs have default examples
@@ -124,6 +125,9 @@
                     examples = d.get('x-amples', default_example)
                     for x in examples:
                         x['http_method'] = key
+                        ### TODO finish this
+                        #if not 'request' in x or not 'response' in x:
+                        ###
                         # Merge query parameters with defaults
                         # In Py 3.5 we could do {**default_query, **query}
                         query = default_query.copy()
@@ -349,6 +353,29 @@
         elif t == 're':
             return lambda x: re.search(arg, x)
 
+    def _set_warning(prefix, data):
+        """
+        Sets self.status and self.msg to WARNING with
+        an appropriate message, based on the args. If
+        the status is set to something other than OK or
+        WARNING, it does not update the state, so as
+        not to potentially overwrite a CRITICAL message.
+
+        Args:
+            prefix (str): the body path being chcked
+
+            data (mixed): the data to use in the message
+        """
+        if not self.status in ['OK', 'WARNING']:
+            return False
+        if self.status == 'OK':
+            self.msg = ''
+        self.status = "WARNING"
+        self.msg += ("Test {} responds with "
+                    "unexpected value at path {} => {}\n".format(
+                        self.title, prefix, data))
+        return True
+
     def _check_json_chunk(self, data, model, prefix=''):
         """
         Recursively check a json chunk of the response.
@@ -360,23 +387,52 @@
 
             prefix (str): the depth we're checking at
         """
+        if model is None:
+            # if the model happens to be None, there is nothing
+            # we can say about the validity of the received value
+            return True
+        elif data is None:
+            # assume that means 'empty'
+            if type(model).__name__ in ['dict', 'list', 'int', 'float']:
+                data = type(model)()
+            else:
+                data = ''
         if isinstance(model, dict):
+            if not isinstance(data, dict):
+                self._set_warning(prefix, "Expected dict, "
+                                  "gotten a {}".format(type(data).__name__))
+                return True
+            missing_keys = []
             for k, v in model.items():
+                if not k in d:
+                    missing_keys.append(k)
+                    continue
                 p = prefix + '/' + k
                 d = data.get(k, None)
                 self._check_json_chunk(d, v, prefix=p)
+            if len(missing_keys) > 0:
+                self._set_warning(prefix,
+                                  "Missing keys: {}".format(missing_keys))
         elif isinstance(model, list):
+            if not isinstance(data, list):
+                self._set_warning(prefix, "Expected list, "
+                                  "gotten a {}".format(type(data).__name__))
+                return True
+            if len(model) == 0:
+                return True
+            if len(model) == 1 and len(data) > 1:
+                model *= len(data)
+            elif len(data) != len(model):
+                self._set_warning(prefix, "Expected {} array elements, "
+                                  "gotten {}".format(len(model), len(data))
+                return True
             for i in range(len(model)):
                 p = prefix + '[%d]' % i
                 self._check_json_chunk(data[i], model[i], prefix=p)
         else:
             check = self._verify(model)
             if not check(str(data)):
-                self.status = "WARNING"
-                self.msg = ("Test {} responds with "
-                            "unexpected body: {} => {}".format(
-                                self.title, prefix, data))
-                raise CheckError("{} => {}".format(prefix, data))
+                self._set_warning(prefix, data)
         return True
 
 

-- 
To view, visit https://gerrit.wikimedia.org/r/386116
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ide292c7ae8ced694e97fd7cde84ab65c28a69185
Gerrit-PatchSet: 1
Gerrit-Project: operations/software/service-checker
Gerrit-Branch: master
Gerrit-Owner: Mobrovac <mobro...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to