1
# Copyright 2014 Deutsche Telekom AG
4
# Licensed under the Apache License, Version 2.0 (the "License"); you may
5
# not use this file except in compliance with the License. You may obtain
6
# a copy of the License at
8
# http://www.apache.org/licenses/LICENSE-2.0
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
# License for the specific language governing permissions and limitations
21
from oslo_log import log as logging
23
LOG = logging.getLogger(__name__)
26
def _check_for_expected_result(name, schema):
27
expected_result = None
28
if "results" in schema:
29
if name in schema["results"]:
30
expected_result = schema["results"][name]
31
return expected_result
34
def generator_type(*args, **kwargs):
38
setattr(func, key, kwargs[key])
43
def simple_generator(fn):
45
Decorator for simple generators that return one value
48
def wrapped(self, schema):
49
result = fn(self, schema)
50
if result is not None:
51
expected_result = _check_for_expected_result(fn.__name__, schema)
52
return (fn.__name__, result, expected_result)
57
class BasicGeneratorSet(object):
63
"name": {"type": "string"},
65
"enum": ["GET", "PUT", "HEAD",
66
"POST", "PATCH", "DELETE", 'COPY']
68
"admin_client": {"type": "boolean"},
69
"url": {"type": "string"},
70
"default_result_code": {"type": "integer"},
80
"name": {"type": "string"},
81
"expected_result": {"type": "integer"}
92
"required": ["name", "http-method", "url"],
93
"additionalProperties": False,
99
if callable(getattr(self, m)) and not'__' in m:
100
method = getattr(self, m)
101
if hasattr(method, "types"):
102
for type in method.types:
103
if type not in self.types_dict:
104
self.types_dict[type] = []
105
self.types_dict[type].append(method)
107
def validate_schema(self, schema):
108
if "json-schema" in schema:
109
jsonschema.Draft4Validator.check_schema(schema['json-schema'])
110
jsonschema.validate(schema, self.schema)
112
def generate_scenarios(self, schema, path=None):
114
Generates the scenario (all possible test cases) out of the given
117
:param schema: a dict style schema (see ``BasicGeneratorSet.schema``)
118
:param path: the schema path if the given schema is a subschema
120
schema_type = schema['type']
123
if schema_type == 'object':
124
properties = schema["properties"]
125
for attribute, definition in properties.iteritems():
126
current_path = copy.copy(path)
128
current_path.append(attribute)
130
current_path = [attribute]
132
self.generate_scenarios(definition, current_path))
133
elif isinstance(schema_type, list):
134
if "integer" in schema_type:
135
schema_type = "integer"
137
raise Exception("non-integer list types not supported")
138
for generator in self.types_dict[schema_type]:
139
if hasattr(generator, "needed_property"):
140
prop = generator.needed_property
141
if (prop not in schema or
142
schema[prop] is None or
143
schema[prop] is False):
146
name = generator.__name__
147
if ("exclude_tests" in schema and
148
name in schema["exclude_tests"]):
151
name = "%s_%s" % ("_".join(path), name)
153
"_negtest_name": name,
154
"_negtest_generator": generator,
155
"_negtest_schema": schema,
156
"_negtest_path": path})
159
def generate_payload(self, test, schema):
161
Generates one jsonschema out of the given test. It's mandatory to use
162
generate_scenarios before to register all needed variables to the test.
164
:param test: A test object (scenario) with all _negtest variables on it
165
:param schema: schema for the test
167
generator = test._negtest_generator
168
ret = generator(test._negtest_schema)
169
path = copy.copy(test._negtest_path)
170
expected_result = None
173
generator_result = generator(test._negtest_schema)
174
invalid_snippet = generator_result[1]
175
expected_result = generator_result[2]
178
schema_snip = reduce(dict.get, path, schema)
179
schema_snip[element] = invalid_snippet
181
schema[element] = invalid_snippet
182
return expected_result