~ubuntu-branches/ubuntu/vivid/neutron/vivid-updates

« back to all changes in this revision

Viewing changes to neutron/tests/tempest/common/generator/base_generator.py

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-03-30 11:17:19 UTC
  • mfrom: (1.1.21)
  • Revision ID: package-import@ubuntu.com-20150330111719-h0gx7233p4jkkgfh
Tags: 1:2015.1~b3-0ubuntu1
* New upstream milestone release:
  - d/control: Align version requirements with upstream.
  - d/control: Add new dependency on oslo-log.
  - d/p/*: Rebase.
  - d/control,d/neutron-plugin-hyperv*: Dropped, decomposed into
    separate project upstream.
  - d/control,d/neutron-plugin-openflow*: Dropped, decomposed into
    separate project upstream.
  - d/neutron-common.install: Add neutron-rootwrap-daemon and 
    neutron-keepalived-state-change binaries.
  - d/rules: Ignore neutron-hyperv-agent when installing; only for Windows.
  - d/neutron-plugin-cisco.install: Drop neutron-cisco-cfg-agent as
    decomposed into separate project upstream.
  - d/neutron-plugin-vmware.install: Drop neutron-check-nsx-config and
    neutron-nsx-manage as decomposed into separate project upstream.
  - d/control: Add dependency on python-neutron-fwaas to neutron-l3-agent.
* d/pydist-overrides: Add overrides for oslo packages.
* d/control: Fixup type in package description (LP: #1263539).
* d/p/fixup-driver-test-execution.patch: Cherry pick fix from upstream VCS
  to support unit test exection in out-of-tree vendor drivers.
* d/neutron-common.postinst: Allow general access to /etc/neutron but limit
  access to root/neutron to /etc/neutron/neutron.conf to support execution
  of unit tests in decomposed vendor drivers.
* d/control: Add dependency on python-neutron-fwaas to neutron-l3-agent
  package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# 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
 
 
16
import copy
 
17
import functools
 
18
 
 
19
import jsonschema
 
20
 
 
21
from oslo_log import log as logging
 
22
 
 
23
LOG = logging.getLogger(__name__)
 
24
 
 
25
 
 
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
 
32
 
 
33
 
 
34
def generator_type(*args, **kwargs):
 
35
    def wrapper(func):
 
36
        func.types = args
 
37
        for key in kwargs:
 
38
            setattr(func, key, kwargs[key])
 
39
        return func
 
40
    return wrapper
 
41
 
 
42
 
 
43
def simple_generator(fn):
 
44
    """
 
45
    Decorator for simple generators that return one value
 
46
    """
 
47
    @functools.wraps(fn)
 
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)
 
53
        return
 
54
    return wrapped
 
55
 
 
56
 
 
57
class BasicGeneratorSet(object):
 
58
    _instance = None
 
59
 
 
60
    schema = {
 
61
        "type": "object",
 
62
        "properties": {
 
63
            "name": {"type": "string"},
 
64
            "http-method": {
 
65
                "enum": ["GET", "PUT", "HEAD",
 
66
                         "POST", "PATCH", "DELETE", 'COPY']
 
67
            },
 
68
            "admin_client": {"type": "boolean"},
 
69
            "url": {"type": "string"},
 
70
            "default_result_code": {"type": "integer"},
 
71
            "json-schema": {},
 
72
            "resources": {
 
73
                "type": "array",
 
74
                "items": {
 
75
                    "oneOf": [
 
76
                        {"type": "string"},
 
77
                        {
 
78
                            "type": "object",
 
79
                            "properties": {
 
80
                                "name": {"type": "string"},
 
81
                                "expected_result": {"type": "integer"}
 
82
                            }
 
83
                        }
 
84
                    ]
 
85
                }
 
86
            },
 
87
            "results": {
 
88
                "type": "object",
 
89
                "properties": {}
 
90
            }
 
91
        },
 
92
        "required": ["name", "http-method", "url"],
 
93
        "additionalProperties": False,
 
94
    }
 
95
 
 
96
    def __init__(self):
 
97
        self.types_dict = {}
 
98
        for m in dir(self):
 
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)
 
106
 
 
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)
 
111
 
 
112
    def generate_scenarios(self, schema, path=None):
 
113
        """
 
114
        Generates the scenario (all possible test cases) out of the given
 
115
        schema.
 
116
 
 
117
        :param schema: a dict style schema (see ``BasicGeneratorSet.schema``)
 
118
        :param path: the schema path if the given schema is a subschema
 
119
        """
 
120
        schema_type = schema['type']
 
121
        scenarios = []
 
122
 
 
123
        if schema_type == 'object':
 
124
            properties = schema["properties"]
 
125
            for attribute, definition in properties.iteritems():
 
126
                current_path = copy.copy(path)
 
127
                if path is not None:
 
128
                    current_path.append(attribute)
 
129
                else:
 
130
                    current_path = [attribute]
 
131
                scenarios.extend(
 
132
                    self.generate_scenarios(definition, current_path))
 
133
        elif isinstance(schema_type, list):
 
134
            if "integer" in schema_type:
 
135
                schema_type = "integer"
 
136
            else:
 
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):
 
144
                    continue
 
145
 
 
146
            name = generator.__name__
 
147
            if ("exclude_tests" in schema and
 
148
               name in schema["exclude_tests"]):
 
149
                continue
 
150
            if path is not None:
 
151
                name = "%s_%s" % ("_".join(path), name)
 
152
            scenarios.append({
 
153
                "_negtest_name": name,
 
154
                "_negtest_generator": generator,
 
155
                "_negtest_schema": schema,
 
156
                "_negtest_path": path})
 
157
        return scenarios
 
158
 
 
159
    def generate_payload(self, test, schema):
 
160
        """
 
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.
 
163
 
 
164
        :param test: A test object (scenario) with all _negtest variables on it
 
165
        :param schema: schema for the test
 
166
        """
 
167
        generator = test._negtest_generator
 
168
        ret = generator(test._negtest_schema)
 
169
        path = copy.copy(test._negtest_path)
 
170
        expected_result = None
 
171
 
 
172
        if ret is not None:
 
173
            generator_result = generator(test._negtest_schema)
 
174
            invalid_snippet = generator_result[1]
 
175
            expected_result = generator_result[2]
 
176
            element = path.pop()
 
177
            if len(path) > 0:
 
178
                schema_snip = reduce(dict.get, path, schema)
 
179
                schema_snip[element] = invalid_snippet
 
180
            else:
 
181
                schema[element] = invalid_snippet
 
182
        return expected_result