blob: 35f81589f3dc01e648eac6df07f7f5be47245977 [file] [log] [blame]
Marc Koderer6ee82dc2014-02-17 10:26:29 +01001# Copyright 2014 Deutsche Telekom AG
2# All Rights Reserved.
3#
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
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
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
14# under the License.
15
16import jsonschema
17
18from tempest.openstack.common import log as logging
19
20LOG = logging.getLogger(__name__)
21
22
23def _check_for_expected_result(name, schema):
24 expected_result = None
25 if "results" in schema:
26 if name in schema["results"]:
27 expected_result = schema["results"][name]
28 return expected_result
29
30
31def generator_type(*args):
32 def wrapper(func):
33 func.types = args
34 return func
35 return wrapper
36
37
38def simple_generator(fn):
39 """
40 Decorator for simple generators that return one value
41 """
42 def wrapped(self, schema):
43 result = fn(self, schema)
44 if result is not None:
45 expected_result = _check_for_expected_result(fn.__name__, schema)
46 return (fn.__name__, result, expected_result)
47 return
48 return wrapped
49
50
51class BasicGeneratorSet(object):
52 _instance = None
53
54 schema = {
55 "type": "object",
56 "properties": {
57 "name": {"type": "string"},
58 "http-method": {
59 "enum": ["GET", "PUT", "HEAD",
60 "POST", "PATCH", "DELETE", 'COPY']
61 },
62 "url": {"type": "string"},
63 "json-schema": jsonschema._utils.load_schema("draft4"),
64 "resources": {
65 "type": "array",
66 "items": {
67 "oneOf": [
68 {"type": "string"},
69 {
70 "type": "object",
71 "properties": {
72 "name": {"type": "string"},
73 "expected_result": {"type": "integer"}
74 }
75 }
76 ]
77 }
78 },
79 "results": {
80 "type": "object",
81 "properties": {}
82 }
83 },
84 "required": ["name", "http-method", "url"],
85 "additionalProperties": False,
86 }
87
88 def __new__(cls, *args, **kwargs):
89 if not cls._instance:
90 cls._instance = super(BasicGeneratorSet, cls).__new__(cls, *args,
91 **kwargs)
92 return cls._instance
93
94 def __init__(self):
95 self.types_dict = {}
96 for m in dir(self):
97 if callable(getattr(self, m)) and not'__' in m:
98 method = getattr(self, m)
99 if hasattr(method, "types"):
100 for type in method.types:
101 if type not in self.types_dict:
102 self.types_dict[type] = []
103 self.types_dict[type].append(method)
104
105 def validate_schema(self, schema):
106 jsonschema.validate(schema, self.schema)
107
108 def generate(self, schema):
109 """
110 Generate an json dictionary based on a schema.
111 Only one value is mis-generated for each dictionary created.
112
113 Any generator must return a list of tuples or a single tuple.
114 The values of this tuple are:
115 result[0]: Name of the test
116 result[1]: json schema for the test
117 result[2]: expected result of the test (can be None)
118 """
119 LOG.debug("generate_invalid: %s" % schema)
120 schema_type = schema["type"]
121 if isinstance(schema_type, list):
122 if "integer" in schema_type:
123 schema_type = "integer"
124 else:
125 raise Exception("non-integer list types not supported")
126 result = []
127 if schema_type not in self.types_dict:
128 raise Exception("generator (%s) doesn't support type: %s"
129 % (self.__class__.__name__, schema_type))
130 for generator in self.types_dict[schema_type]:
131 ret = generator(schema)
132 if ret is not None:
133 if isinstance(ret, list):
134 result.extend(ret)
135 elif isinstance(ret, tuple):
136 result.append(ret)
137 else:
138 raise Exception("generator (%s) returns invalid result: %s"
139 % (generator, ret))
140 LOG.debug("result: %s" % result)
141 return result