S3 Fuzzer: Handle null choices

Sometimes you might want to have your current node terminate the descent or
set something to the empty string.
This commit is contained in:
Kyle Marsh 2011-08-11 12:25:13 -07:00
parent d7b49713f7
commit 62bd05a390
3 changed files with 64 additions and 22 deletions

View file

@ -5,7 +5,7 @@ start:
bucket:
set:
urlpath: '/{bucket}'
urlpath: /{bucket}
choice:
- bucket_get
- bucket_put
@ -13,24 +13,10 @@ bucket:
bucket_delete:
set:
method: 'DELETE'
choice:
- delete_bucket
- delete_bucket_policy
- delete_bucket_website
delete_bucket:
set:
query: null
choice: []
delete_bucket_policy:
set:
query: 'policy'
choice: []
delete_bucket_website:
set:
query: 'website'
method: DELETE
query:
- null
- policy
- website
choice: []

View file

@ -65,6 +65,10 @@ def build_graph():
},
'choices': ['leaf']
}
graph['nonexistant_child_node'] = {
'set': {},
'choices': ['leafy_greens']
}
graph['weighted_node'] = {
'set': {
'k1': [
@ -79,6 +83,14 @@ def build_graph():
'1 baz'
]
}
graph['null_choice_node'] = {
'set': {},
'choices': [None]
}
graph['weighted_null_choice_node'] = {
'set': {},
'choices': ['3 null']
}
return graph
@ -114,6 +126,12 @@ def test_descend_bad_node():
assert_raises(KeyError, descend_graph, graph, 'bad_node', prng)
def test_descend_nonexistant_child():
graph = build_graph()
prng = random.Random(1)
assert_raises(KeyError, descend_graph, graph, 'nonexistant_child_node', prng)
def test_SpecialVariables_dict():
prng = random.Random(1)
testdict = {'foo': 'bar'}
@ -128,6 +146,7 @@ def test_SpecialVariables_binary():
eq(tester['random 10-15 binary'], '\xdfj\xf1\xd80>a\xcd\xc4\xbb')
def test_assemble_decision():
graph = build_graph()
prng = random.Random(1)
@ -140,6 +159,7 @@ def test_assemble_decision():
eq(decision['path'], '/{bucket_readable}')
assert_raises(KeyError, lambda x: decision[x], 'key3')
def test_expand_key():
prng = random.Random(1)
test_decision = {
@ -158,6 +178,7 @@ def test_expand_key():
eq(dbl_indirect, 'value1')
eq(randkey, 'value-[/pNI$;92@')
def test_expand_loop():
prng = random.Random(1)
test_decision = {
@ -167,6 +188,7 @@ def test_expand_loop():
decision = SpecialVariables(test_decision, prng)
assert_raises(RuntimeError, expand_key, decision, test_decision['key1'])
def test_expand_decision():
graph = build_graph()
prng = random.Random(1)
@ -182,6 +204,7 @@ def test_expand_decision():
eq(request['randkey'], 'value-cx+*~G@&uW_[OW3')
assert_raises(KeyError, lambda x: decision[x], 'key3')
def test_weighted_choices():
graph = build_graph()
prng = random.Random(1)
@ -201,6 +224,31 @@ def test_weighted_choices():
nose.tools.assert_almost_equal(bar_percentage, 0.50, 1)
nose.tools.assert_almost_equal(baz_percentage, 0.25, 1)
def test_null_choices():
graph = build_graph()
prng = random.Random(1)
choice = make_choice(graph['null_choice_node']['choices'], prng)
eq(choice, '')
def test_weighted_null_choices():
graph = build_graph()
prng = random.Random(1)
choice = make_choice(graph['weighted_null_choice_node']['choices'], prng)
eq(choice, '')
def test_null_child():
graph = build_graph()
prng = random.Random(1)
decision = descend_graph(graph, 'null_choice_node', prng)
eq(decision, {})
def test_weighted_set():
graph = build_graph()
prng = random.Random(1)
@ -220,6 +268,7 @@ def test_weighted_set():
nose.tools.assert_almost_equal(bar_percentage, 0.50, 1)
nose.tools.assert_almost_equal(baz_percentage, 0.25, 1)
def test_header_presence():
graph = build_graph()
prng = random.Random(1)
@ -241,7 +290,6 @@ def test_header_presence():
nose.tools.assert_true(next(c2))
def test_header_expansion():
graph = build_graph()
prng = random.Random(1)

View file

@ -29,7 +29,10 @@ def descend_graph(decision_graph, node_name, prng):
try:
choice = make_choice(node['choices'], prng)
decision = descend_graph(decision_graph, choice, prng)
if choice == '':
decision = {}
else:
decision = descend_graph(decision_graph, choice, prng)
except IndexError:
decision = {}
@ -72,6 +75,9 @@ def make_choice(choices, prng):
return choices
weighted_choices = []
for option in choices:
if option is None:
weighted_choices.append('')
continue
fields = option.split(None, 1)
if len(fields) == 1:
weight = 1
@ -79,6 +85,8 @@ def make_choice(choices, prng):
else:
weight = int(fields[0])
value = fields[1]
if value == 'null' or value == 'None':
value = ''
for _ in xrange(weight):
weighted_choices.append(value)