diff --git a/request_decision_graph.yml b/request_decision_graph.yml index 774d391..d7b0206 100644 --- a/request_decision_graph.yml +++ b/request_decision_graph.yml @@ -1,5 +1,5 @@ start: - set: null + set: {} choice: - bucket @@ -22,15 +22,15 @@ bucket_delete: delete_bucket: set: query: null - choice: null + choice: [] delete_bucket_policy: set: query: 'policy' - choice: null + choice: [] delete_bucket_website: set: query: 'website' - choice: null + choice: [] diff --git a/s3tests/functional/test_fuzzer.py b/s3tests/functional/test_fuzzer.py index 0b28653..69dd8fc 100644 --- a/s3tests/functional/test_fuzzer.py +++ b/s3tests/functional/test_fuzzer.py @@ -19,17 +19,60 @@ def check_access_denied(fn, *args, **kwargs): eq(e.error_code, 'AccessDenied') -def read_graph(): +def build_graph(): + graph = {} + graph['start'] = { + 'set': {}, + 'choices': ['node1'] + } + graph['leaf'] = { + 'set': { + 'key1': 'value1', + 'key2': 'value2' + }, + 'choices': [] + } + graph['node1'] = { + 'set': { + 'key3': 'value3' + }, + 'choices': ['leaf'] + } + graph['bad_node'] = { + 'set': { + 'key1': 'value1' + }, + 'choices': ['leaf'] + } + return graph + + +def test_load_graph(): graph_file = open('request_decision_graph.yml', 'r') - return yaml.safe_load(graph_file) + graph = yaml.safe_load(graph_file) + graph['start'] -def test_assemble_decision(): - graph = read_graph() +def test_descend_leaf_node(): + graph = build_graph() prng = random.Random(1) - decision = assemble_decision(graph, prng) - decision['path'] - decision['method'] - decision['body'] - decision['headers'] + decision = descend_graph(graph, 'leaf', prng) + + eq(decision['key1'], 'value1') + eq(decision['key2'], 'value2') + e = assert_raises(KeyError, lambda x: decision[x], 'key3') + +def test_descend_node(): + graph = build_graph() + prng = random.Random(1) + decision = descend_graph(graph, 'node1', prng) + + eq(decision['key1'], 'value1') + eq(decision['key2'], 'value2') + eq(decision['key3'], 'value3') + +def test_descend_bad_node(): + graph = build_graph() + prng = random.Random(1) + assert_raises(KeyError, descend_graph, graph, 'bad_node', prng) diff --git a/s3tests/fuzz_headers.py b/s3tests/fuzz_headers.py index 9886b25..5d538dd 100644 --- a/s3tests/fuzz_headers.py +++ b/s3tests/fuzz_headers.py @@ -14,7 +14,27 @@ def assemble_decision(decision_graph, prng): """ Take in a graph describing the possible decision space and a random number generator and traverse the graph to build a decision """ - raise NotImplementedError + return descend_graph(decision_graph, 'start', prng) + + +def descend_graph(decision_graph, node_name, prng): + """ Given a graph and a particular node in that graph, set the values in + the node's "set" list, pick a choice from the "choice" list, and + recurse. Finally, return dictionary of values + """ + try: + choice = prng.choice(decision_graph[node_name]['choices']) + decision = descend_graph(decision_graph, choice, prng) + except IndexError: + decision = {} + + node = decision_graph[node_name] + + for key in node['set']: + if decision.has_key(key): + raise KeyError("Node %s tried to set '%s', but that key was already set by a lower node!" %(node_name, key)) + decision[key] = node['set'][key] + return decision def expand_decision(decision, prng):