mirror of
https://github.com/ceph/s3-tests.git
synced 2024-11-28 09:31:38 +00:00
S3 Fuzzer: Output and garbage data tweaks.
- Output tweaks - added support for printable_no_whitespace and binary_no_whitespace
This commit is contained in:
parent
f45d28765d
commit
18c3fe53c2
3 changed files with 67 additions and 32 deletions
|
@ -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>'
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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():
|
||||
|
|
Loading…
Reference in a new issue