]> git-server-git.apps.pok.os.sepia.ceph.com Git - s3-tests.git/commitdiff
S3 Fuzzer: Output and garbage data tweaks.
authorKyle Marsh <kyle.marsh@dreamhost.com>
Tue, 23 Aug 2011 22:08:18 +0000 (15:08 -0700)
committerKyle Marsh <kyle.marsh@dreamhost.com>
Mon, 12 Sep 2011 20:03:55 +0000 (13:03 -0700)
- Output tweaks
- added support for printable_no_whitespace and binary_no_whitespace

request_decision_graph.yml
s3tests/functional/test_fuzzer.py
s3tests/fuzz_headers.py

index 06dffd7bd19395a4fc463f679ed8f25026bea6c5..fa13eb5e99bd1d8f86d57e958655a5ffc78d28e5 100644 (file)
@@ -3,6 +3,9 @@ start:
         garbage:
             - '{random 10-3000 printable}'
             - '{random 10-1000 binary}'
+        garbage_no_whitespace:
+            - '{random 10-3000 printable_no_whitespace}'
+            - '{random 10-1000 binary_no_whitespace}'
     choices:
         - bucket
 
@@ -25,7 +28,7 @@ bucket_garbage_method:
             - '{bucket_not_readable}'
             - '{bucket_writable}'
             - '{bucket_not_writable}'
-            - '2 {garbage}'
+            - '2 {garbage_no_whitespace}'
     choices:
         - bucket_get_simple
         - bucket_get_filtered
@@ -40,12 +43,12 @@ bucket_delete:
         bucket:
             - '{bucket_writable}'
             - '{bucket_not_writable}'
-            - '2 {garbage}'
+            - '2 {garbage_no_whitespace}'
         query:
             - null
             - policy
             - website
-            - '2 {garbage}'
+            - '2 {garbage_no_whitespace}'
     choices: []
 
 bucket_get:
@@ -54,7 +57,7 @@ bucket_get:
         bucket:
             - '{bucket_readable}'
             - '{bucket_not_readable}'
-            - '2 {garbage}'
+            - '2 {garbage_no_whitespace}'
     choices:
         - 11 bucket_get_simple
         - bucket_get_filtered
@@ -72,56 +75,56 @@ bucket_get_simple:
             - requestPayment
             - versioning
             - website
-            - '2 {garbage}'
+            - '2 {garbage_no_whitespace}'
     choices: []
 
 bucket_get_uploads:
     set:
         delimiter:
             - null
-            - '3 delimiter={garbage}'
+            - '3 delimiter={garbage_no_whitespace}'
         prefix:
             - null
-            - '3 prefix={garbage}'
+            - '3 prefix={garbage_no_whitespace}'
         key_marker:
             - null
             - 'key-marker={object_readable}'
             - 'key-marker={object_not_readable}'
             - 'key-marker={invalid_key}'
-            - 'key-marker={random 100-1000 printable}'
+            - 'key-marker={random 100-1000 printable_no_whitespace}'
         max_uploads:
             - null
-            - 'max-uploads={random 1-5 binary}'
+            - 'max-uploads={random 1-5 binary_no_whitespace}'
             - 'max-uploads={random 1-1000 digits}'
         upload_id_marker:
             - null
-            - '3 upload-id-marker={random}'
+            - '3 upload-id-marker={random 0-1000 printable_no_whitespace}'
         query:
             - 'uploads'
             - 'uploads&{delimiter}&{prefix}'
             - 'uploads&{max_uploads}&{key_marker}&{upload_id_marker}'
-            - '2 {garbage}'
+            - '2 {garbage_no_whitespace}'
     choices: []
 
 bucket_get_filtered:
     set:
         delimiter:
-            - 'delimiter={garbage}'
+            - 'delimiter={garbage_no_whitespace}'
         prefix:
-            - 'prefix={garbage}'
+            - 'prefix={garbage_no_whitespace}'
         marker:
             - 'marker={object_readable}'
             - 'marker={object_not_readable}'
             - 'marker={invalid_key}'
-            - 'marker={random 100-1000 printable}'
+            - 'marker={random 100-1000 printable_no_whitespace}'
         max_keys:
-            - 'max-keys={random 1-5 binary}'
+            - 'max-keys={random 1-5 binary_no_whitespace}'
             - 'max-keys={random 1-1000 digits}'
         query:
             - null
             - '{delimiter}&{prefix}'
             - '{max-keys}&{marker}'
-            - '2 {garbage}'
+            - '2 {garbage_no_whitespace}'
     choices: []
 
 bucket_put:
@@ -129,7 +132,7 @@ bucket_put:
         bucket:
             - '{bucket_writable}'
             - '{bucket_not_writable}'
-            - '2 {garbage}'
+            - '2 {garbage_no_whitespace}'
         method: PUT
     choices:
         - bucket_put_simple
@@ -142,9 +145,14 @@ bucket_put_create:
             - '2 {garbage}'
             - '<CreateBucketConfiguration><LocationConstraint>{random 2-10 binary}</LocationConstraint></CreateBucketConfiguration>'
         acl:
-            - private
+            - 'private'
+            - 'public-read'
+            - 'public-read-write'
+            - 'authenticated-read'
+            - 'bucket-owner-read'
+            - 'bucket-owner-full-control'
             - '{random 3000 letters}'
-            - '{random 100-1000 binary}'
+            - '{random 100-1000 binary_no_whitespace}'
     headers:
         - ['0-1', 'x-amz-acl', '{acl}']
     choices: []
@@ -163,7 +171,7 @@ bucket_put_versioning:
             - '<MfaDelete>{random 2-10 binary}</MfaDelete>'
             - '<MfaDelete>{random 2000-3000 printable}</MfaDelete>'
         mfa_header:
-            - '{random 10-1000 printable} {random 10-1000 printable}'
+            - '{random 10-1000 printable_no_whitespace} {random 10-1000 printable_no_whitespace}'
     headers:
         - ['0-1', 'x-amz-mfa', '{mfa_header}']
     choices: []
@@ -225,7 +233,7 @@ bucket_put_simple:
         notification_body:
             - null
             - '<NotificationConfiguration />'
-            - '2 <NotificationConfiguration><TopicConfiguration>{topic}{event}</TopicConfiguration}</NotificationConfiguration>'
+            - '2 <NotificationConfiguration><TopicConfiguration>{topic}{event}</TopicConfiguration></NotificationConfiguration>'
         topic:
             - null
             - '2 <Topic>{garbage}</Topic>'
index eb2ab1fad70717403def7d5a5f0ba971d3b1bb3c..1039b55c063242f12e08aca15464574b8597eed5 100644 (file)
@@ -158,6 +158,20 @@ def test_expand_random_binary():
     eq(got, '\xdfj\xf1\xd80>a\xcd\xc4\xbb')
 
 
+def test_expand_random_printable_no_whitespace():
+    prng = random.Random(1)
+    for _ in xrange(1000):
+        got = expand({}, '{random 500 printable_no_whitespace}', prng)
+        assert_true(reduce(lambda x, y: x and y, [x not in string.whitespace and x in string.printable for x in got]))
+
+
+def test_expand_random_binary():
+    prng = random.Random(1)
+    for _ in xrange(1000):
+        got = expand({}, '{random 500 binary_no_whitespace}', prng)
+        assert_true(reduce(lambda x, y: x and y, [x not in string.whitespace for x in got]))
+
+
 def test_expand_random_no_args():
     prng = random.Random(1)
     for _ in xrange(1000):
index 79a8d47bc422c1429fece10c10b5f4cc6992d2e2..6e581b4f169cc2282f73c0ac667e9308d09dfb6f 100644 (file)
@@ -136,6 +136,7 @@ def expand(decision, value, prng):
 
 class RepeatExpandingFormatter(string.Formatter):
     charsets = {
+        'printable_no_whitespace': string.printable.translate(None, string.whitespace),
         'printable': string.printable,
         'punctuation': string.punctuation,
         'whitespace': string.whitespace,
@@ -161,8 +162,7 @@ class RepeatExpandingFormatter(string.Formatter):
         if self._recursion > 5:
             raise RecursionError(key)
         fmt = self.__class__(self.prng, _recursion=self._recursion+1)
-        # must use vformat not **kwargs so our SpecialVariables is not
-        # downgraded to just a dict
+
         n = fmt.vformat(val, args, kwargs)
         return n
 
@@ -185,10 +185,12 @@ class RepeatExpandingFormatter(string.Formatter):
         except IndexError:
             charset_arg = 'printable'
 
-        if charset_arg == 'binary':
+        if charset_arg == 'binary' or charset_arg == 'binary_no_whitespace':
             num_bytes = length + 8
             tmplist = [self.prng.getrandbits(64) for _ in xrange(num_bytes / 8)]
             tmpstring = struct.pack((num_bytes / 8) * 'Q', *tmplist)
+            if charset_arg == 'binary_no_whitespace':
+                tmpstring = ''.join(c for c in tmpstring if c not in string.whitespace)
             return tmpstring[0:length]
         else:
             charset = self.charsets[charset_arg]
@@ -198,14 +200,16 @@ class RepeatExpandingFormatter(string.Formatter):
 def parse_options():
     parser = OptionParser()
     parser.add_option('-O', '--outfile', help='write output to FILE. Defaults to STDOUT', metavar='FILE')
-    parser.add_option('--seed', dest='seed', type='int',  help='initial seed for the random number generator', metavar='SEED')
+    parser.add_option('--seed', dest='seed', type='int',  help='initial seed for the random number generator')
     parser.add_option('--seed-file', dest='seedfile', help='read seeds for specific requests from FILE', metavar='FILE')
     parser.add_option('-n', dest='num_requests', type='int',  help='issue NUM requests before stopping', metavar='NUM')
     parser.add_option('-v', '--verbose', dest='verbose', action="store_true",  help='turn on verbose output')
     parser.add_option('-d', '--debug', dest='debug', action="store_true",  help='turn on debugging (very verbose) output')
-    parser.add_option('--decision-graph', dest='graph_filename',  help='file in which to find the request decision graph', metavar='NUM')
+    parser.add_option('--decision-graph', dest='graph_filename',  help='file in which to find the request decision graph')
+    parser.add_option('--no-cleanup', dest='cleanup', action="store_false", help='turn off teardown so you can peruse the state of buckets after testing')
 
     parser.set_defaults(num_requests=5)
+    parser.set_defaults(cleanup=True)
     parser.set_defaults(graph_filename='request_decision_graph.yml')
     return parser.parse_args()
 
@@ -317,10 +321,10 @@ def _main():
         except KeyError:
             headers = {}
 
-        print>>VERBOSE, "%s %s" %(method[:100], path[:100])
+        print>>VERBOSE, "%r %r" %(method[:100], path[:100])
         for h, v in headers.iteritems():
-            print>>VERBOSE, "%s: %s" %(h[:50], v[:50])
-        print>>VERBOSE, "%s\n" % body[:100]
+            print>>VERBOSE, "%r: %r" %(h[:50], v[:50])
+        print>>VERBOSE, "%r\n" % body[:100]
 
         print>>DEBUG, 'FULL REQUEST'
         print>>DEBUG, 'Method: %r' %method
@@ -333,13 +337,22 @@ def _main():
         #response = s3_connection.make_request(method, path, data=body, headers=headers, override_num_retries=0)
         response = s3_connection.make_request(method, path, data=body, headers=headers)
 
+        failed = True if response.status in [500, 503] else False
+        if failed:
+            print>>OUT, 'FAILED:'
+            OLD_VERBOSE = VERBOSE
+            OLD_DEBUG = DEBUG
+            VERBOSE = DEBUG = OUT
         print>>VERBOSE, 'Response status code: %d %s' %(response.status, response.reason)
         print>>DEBUG, 'Body:\n%s' %response.read()
-        if response.status == 500 or response.status == 503:
-            print>>OUT, 'FAILED:\n%s' %request
         print>>VERBOSE, '='*80
+        if failed:
+            VERBOSE = OLD_VERBOSE
+            DEBUG = OLD_DEBUG
     print>>OUT, '...done fuzzing'
-    common.teardown()
+
+    if options.cleanup:
+        common.teardown()
 
 
 def main():