浏览代码

Merge pull request #1455 from LadyMozzarella/verify-response-headers

Toolset: Verify headers are present
Hamilton Turner 10 年之前
父节点
当前提交
ae1a45acbe

+ 7 - 1
toolset/benchmark/test_types/db_type.py

@@ -18,7 +18,8 @@ class DBTestType(FrameworkTestType):
     '''
 
     url = base_url + self.db_url
-    body = self._curl(url)
+    response = self._curl(url)
+    body = self._curl_body(url)
     
     # Empty response
     if body is None:
@@ -26,6 +27,11 @@ class DBTestType(FrameworkTestType):
     elif len(body) == 0:
       return [('fail','Empty Response', url)]
 
+    # Ensure required response headers are present
+    if any(v not in response for v in ('Server','Date','Content-Type: application/json')) \
+       or all(v not in response for v in ('Content-Length','Transfer-Encoding')):
+      return [('warn','Required response header missing.',url)]
+
     # Valid JSON? 
     try: 
       response = json.loads(body)

+ 7 - 1
toolset/benchmark/test_types/fortune_type.py

@@ -18,7 +18,8 @@ class FortuneTestType(FrameworkTestType):
     valid fortune response
     '''
     url = base_url + self.fortune_url
-    body = self._curl(url)
+    response = self._curl(url)
+    body = self._curl_body(url)
     
     # Empty response
     if body is None:
@@ -26,6 +27,11 @@ class FortuneTestType(FrameworkTestType):
     elif len(body) == 0:
       return [('fail','Empty Response', url)]
 
+    # Ensure required response headers are present
+    if any(v not in response for v in ('Server','Date','Content-Type: text/html')) \
+       or all(v not in response for v in ('Content-Length','Transfer-Encoding')):
+      return [('warn','Required response header missing.',url)]
+
     parser = FortuneHTMLParser()
     parser.feed(body)
     (valid, diff) = parser.isValidFortune(self.out)

+ 9 - 1
toolset/benchmark/test_types/framework_test_type.py

@@ -58,7 +58,7 @@ class FrameworkTestType:
       raise AttributeError("A %s requires the benchmark_config to contain %s"%(self.name,self.args))
 
   def _curl(self, url):
-    '''Downloads a URL and returns the HTTP body'''
+    '''Downloads a URL and returns the HTTP response'''
     # Use -m 15 to make curl stop trying after 15sec.
     # Use -i to output response with headers
     # Don't use -f so that the HTTP response code is ignored.
@@ -72,6 +72,14 @@ class FrameworkTestType:
     self.out.write("Response: \n\"" + out+ "\"\n")
     if p.returncode != 0:
       return None
+    return out
+
+  def _curl_body(self, url):
+    '''Downloads a URL and returns the HTTP body'''
+    # Use -m 15 to make curl stop trying after 15sec.
+    # Use -i to output response with headers
+    # Don't use -f so that the HTTP response code is ignored.
+    # Use -sS to hide progress bar, but show errors.
     # Get response body
     p = subprocess.Popen(["curl", "-m", "15", "-s", url], stdout=PIPE, stderr=PIPE)
     (out, err) = p.communicate()

+ 8 - 2
toolset/benchmark/test_types/json_type.py

@@ -17,14 +17,20 @@ class JsonTestType(FrameworkTestType):
     '''
 
     url = base_url + self.json_url
-    body = self._curl(url)
+    response = self._curl(url)
+    body = self._curl_body(url)
     
     # Empty response
     if body is None:
       return [('fail','No response', url)]
     elif len(body) == 0:
       return [('fail','Empty Response', url)]
-  
+
+    # Ensure required response headers are present
+    if any(v not in response for v in ('Server','Date','Content-Type: application/json')) \
+       or all(v not in response for v in ('Content-Length','Transfer-Encoding')):
+      return [('warn','Required response header missing.',url)]
+
     # Valid JSON? 
     try: 
       response = json.loads(body)

+ 7 - 1
toolset/benchmark/test_types/plaintext_type.py

@@ -7,7 +7,8 @@ class PlaintextTestType(FrameworkTestType):
 
   def verify(self, base_url):
     url = base_url + self.plaintext_url
-    body = self._curl(url)
+    response = self._curl(url)
+    body = self._curl_body(url)
 
     # Empty response
     if body is None:
@@ -15,6 +16,11 @@ class PlaintextTestType(FrameworkTestType):
     elif len(body) == 0:
       return [('fail','Empty Response', url)]
 
+    # Ensure required response headers are present
+    if any(v not in response for v in ('Server','Date','Content-Type: text/plain')) \
+       or all(v not in response for v in ('Content-Length','Transfer-Encoding')):
+      return [('warn','Required response header missing.',url)]
+
     # Case insensitive
     orig = body
     body = body.lower()

+ 18 - 9
toolset/benchmark/test_types/query_type.py

@@ -24,24 +24,28 @@ class QueryTestType(DBTestType):
 
     problems = []
     
-    body = self._curl(url + '2')
-    problems += self._verifyQueryList(2, body, url + '2')
+    response = self._curl(url)
+    body = self._curl_body(url + '2')
+    problems += self._verifyQueryList(2, response, body, url + '2')
 
-    body = self._curl(url + '0')
-    problems += self._verifyQueryList(1, body, url + '0', 'warn')
+    response = self._curl(url)
+    body = self._curl_body(url + '0')
+    problems += self._verifyQueryList(1, response, body, url + '0', 'warn')
 
     # Note: A number of tests fail here because they only parse for 
     # a number and crash on 'foo'. For now we only warn about this
-    body = self._curl(url + 'foo')
+    response = self._curl(url)
+    body = self._curl_body(url + 'foo')
     if body is None:
       problems += [('warn','No response (this will be a failure in future rounds, please fix)', url)]
     elif len(body) == 0:
       problems += [('warn','Empty response (this will be a failure in future rounds, please fix)', url)]
     else:
-      problems += self._verifyQueryList(1, body, url + 'foo', 'warn')
+      problems += self._verifyQueryList(1, response, body, url + 'foo', 'warn')
 
-    body = self._curl(url + '501')
-    problems += self._verifyQueryList(500, body, url + '501', 'warn')
+    response = self._curl(url)
+    body = self._curl_body(url + '501')
+    problems += self._verifyQueryList(500, response, body, url + '501', 'warn')
 
     if len(problems) == 0:
       return [('pass','',url + '2'),
@@ -51,7 +55,7 @@ class QueryTestType(DBTestType):
     else:
       return problems
 
-  def _verifyQueryList(self, expectedLength, body, url, max_infraction='fail'):
+  def _verifyQueryList(self, expectedLength, curlResponse, body, url, max_infraction='fail'):
     '''Validates high-level structure (array length, object 
       types, etc) before calling into DBTestType to 
       validate a few individual JSON objects'''
@@ -61,6 +65,11 @@ class QueryTestType(DBTestType):
       return [(max_infraction,'No response', url)]
     elif len(body) == 0:
       return [(max_infraction,'Empty Response', url)]
+
+    # Ensure required response headers are present
+    if any(v not in curlResponse for v in ('Server','Date','Content-Type: application/json')) \
+       or all(v not in curlResponse for v in ('Content-Length','Transfer-Encoding')):
+      return [('warn','Required response header missing.',url)]
   
     # Valid JSON? 
     try: 

+ 12 - 8
toolset/benchmark/test_types/update_type.py

@@ -23,17 +23,21 @@ class UpdateTestType(QueryTestType):
     url = base_url + self.update_url
     problems = []
     
-    body = self._curl(url + '2')
-    problems += self._verifyQueryList(2, body, url + '2')
+    response = self._curl(url + '2')
+    body = self._curl_body(url + '2')
+    problems += self._verifyQueryList(2, response, body, url + '2')
 
-    body = self._curl(url + '0')
-    problems += self._verifyQueryList(1, body, url + '0', 'warn')
+    response = self._curl(url + '0')
+    body = self._curl_body(url + '0')
+    problems += self._verifyQueryList(1, response, body, url + '0', 'warn')
 
-    body = self._curl(url + 'foo')
-    problems += self._verifyQueryList(1, body, url + 'foo', 'warn')
+    response = self._curl(url + 'foo')
+    body = self._curl_body(url + 'foo')
+    problems += self._verifyQueryList(1, response, body, url + 'foo', 'warn')
 
-    body = self._curl(url + '501')
-    problems += self._verifyQueryList(500, body, url + '501', 'warn')
+    response = self._curl(url + '501')
+    body = self._curl_body(url + '501')
+    problems += self._verifyQueryList(500, response, body, url + '501', 'warn')
 
     if len(problems) == 0:
       return [('pass','',url + '2'),