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

« back to all changes in this revision

Viewing changes to neutron/plugins/bigswitch/tests/test_server.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
 
#!/usr/bin/env python
2
 
# Copyright 2012, Big Switch Networks, Inc.
3
 
# All Rights Reserved.
4
 
#
5
 
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
6
 
#    not use this file except in compliance with the License. You may obtain
7
 
#    a copy of the License at
8
 
#
9
 
#         http://www.apache.org/licenses/LICENSE-2.0
10
 
#
11
 
#    Unless required by applicable law or agreed to in writing, software
12
 
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
 
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
 
#    License for the specific language governing permissions and limitations
15
 
#    under the License.
16
 
 
17
 
"""Test server mocking a REST based network ctrl.
18
 
 
19
 
Used for NeutronRestProxy tests
20
 
"""
21
 
from __future__ import print_function
22
 
 
23
 
import re
24
 
 
25
 
from oslo.serialization import jsonutils
26
 
from six import moves
27
 
from wsgiref import simple_server
28
 
 
29
 
 
30
 
class TestNetworkCtrl(object):
31
 
 
32
 
    def __init__(self, host='', port=8000,
33
 
                 default_status='404 Not Found',
34
 
                 default_response='404 Not Found',
35
 
                 debug=False):
36
 
        self.host = host
37
 
        self.port = port
38
 
        self.default_status = default_status
39
 
        self.default_response = default_response
40
 
        self.debug = debug
41
 
        self.debug_env = False
42
 
        self.debug_resp = False
43
 
        self.matches = []
44
 
 
45
 
    def match(self, prior, method_regexp, uri_regexp, handler, data=None,
46
 
              multi=True):
47
 
        """Add to the list of expected inputs.
48
 
 
49
 
        The incoming request is matched in the order of priority. For same
50
 
        priority, match the oldest match request first.
51
 
 
52
 
        :param prior: integer priority of this match (e.g. 100)
53
 
        :param method_regexp: regexp to match method (e.g. 'PUT|POST')
54
 
        :param uri_regexp: regexp to match uri (e.g. '/quantum/v?.?/')
55
 
        :param handler: function with signature:
56
 
            lambda(method, uri, body, **kwargs) : status, body
57
 
              where
58
 
                  - method: HTTP method for this request
59
 
                  - uri: URI for this HTTP request
60
 
                  - body: body of this HTTP request
61
 
                  - kwargs are:
62
 
                      - data: data object that was in the match call
63
 
                      - node: TestNetworkCtrl object itself
64
 
                      - id: offset of the matching tuple
65
 
              and return values is:
66
 
                (status, body) where:
67
 
                - status: HTTP resp status (e.g. '200 OK').
68
 
                          If None, use default_status
69
 
                - body: HTTP resp body. If None, use ''
70
 
        """
71
 
        assert int(prior) == prior, 'Priority should an integer be >= 0'
72
 
        assert prior >= 0, 'Priority should an integer be >= 0'
73
 
 
74
 
        lo, hi = 0, len(self.matches)
75
 
        while lo < hi:
76
 
            mid = (lo + hi) // 2
77
 
            if prior < self.matches[mid][0]:
78
 
                hi = mid
79
 
            else:
80
 
                lo = mid + 1
81
 
        self.matches.insert(lo, (prior, method_regexp, uri_regexp, handler,
82
 
                            data, multi))
83
 
 
84
 
    def remove_id(self, id_):
85
 
        assert id_ >= 0, 'remove_id: id < 0'
86
 
        assert id_ <= len(self.matches), 'remove_id: id > len()'
87
 
        self.matches.pop(id_)
88
 
 
89
 
    def request_handler(self, method, uri, body):
90
 
        retstatus = self.default_status
91
 
        retbody = self.default_response
92
 
        for i in moves.xrange(len(self.matches)):
93
 
            (unused_prior, method_regexp, uri_regexp, handler, data,
94
 
             multi) = self.matches[i]
95
 
            if re.match(method_regexp, method) and re.match(uri_regexp, uri):
96
 
                kwargs = {
97
 
                    'data': data,
98
 
                    'node': self,
99
 
                    'id': i,
100
 
                }
101
 
                retstatus, retbody = handler(method, uri, body, **kwargs)
102
 
                if multi is False:
103
 
                    self.remove_id(i)
104
 
                break
105
 
        if retbody is None:
106
 
            retbody = ''
107
 
        return (retstatus, retbody)
108
 
 
109
 
    def server(self):
110
 
        def app(environ, start_response):
111
 
            uri = environ['PATH_INFO']
112
 
            method = environ['REQUEST_METHOD']
113
 
            headers = [('Content-type', 'text/json')]
114
 
            content_len_str = environ['CONTENT_LENGTH']
115
 
 
116
 
            content_len = 0
117
 
            request_data = None
118
 
            if content_len_str:
119
 
                content_len = int(content_len_str)
120
 
                request_data = environ.get('wsgi.input').read(content_len)
121
 
                if request_data:
122
 
                    try:
123
 
                        request_data = jsonutils.loads(request_data)
124
 
                    except Exception:
125
 
                        # OK for it not to be json! Ignore it
126
 
                        pass
127
 
 
128
 
            if self.debug:
129
 
                print('\n')
130
 
                if self.debug_env:
131
 
                    print('environ:')
132
 
                    for (key, value) in sorted(environ.iteritems()):
133
 
                        print('  %16s : %s' % (key, value))
134
 
 
135
 
                print('%s %s' % (method, uri))
136
 
                if request_data:
137
 
                    print('%s' %
138
 
                          jsonutils.dumps(
139
 
                              request_data, sort_keys=True, indent=4))
140
 
 
141
 
            status, body = self.request_handler(method, uri, None)
142
 
            body_data = None
143
 
            if body:
144
 
                try:
145
 
                    body_data = jsonutils.loads(body)
146
 
                except Exception:
147
 
                    # OK for it not to be json! Ignore it
148
 
                    pass
149
 
 
150
 
            start_response(status, headers)
151
 
            if self.debug:
152
 
                if self.debug_env:
153
 
                    print('%s: %s' % ('Response',
154
 
                          jsonutils.dumps(
155
 
                              body_data, sort_keys=True, indent=4)))
156
 
            return body
157
 
        return simple_server.make_server(self.host, self.port, app)
158
 
 
159
 
    def run(self):
160
 
        print("Serving on port %d ..." % self.port)
161
 
        try:
162
 
            self.server().serve_forever()
163
 
        except KeyboardInterrupt:
164
 
            pass
165
 
 
166
 
 
167
 
if __name__ == "__main__":
168
 
    import sys
169
 
 
170
 
    port = 8899
171
 
    if len(sys.argv) > 1:
172
 
        port = int(sys.argv[1])
173
 
 
174
 
    debug = False
175
 
    if len(sys.argv) > 2:
176
 
        if sys.argv[2].lower() in ['debug', 'true']:
177
 
            debug = True
178
 
 
179
 
    ctrl = TestNetworkCtrl(port=port,
180
 
                           default_status='200 OK',
181
 
                           default_response='{"status":"200 OK"}',
182
 
                           debug=debug)
183
 
    ctrl.match(100, 'GET', '/test',
184
 
               lambda m, u, b, **k: ('200 OK', '["200 OK"]'))
185
 
    ctrl.run()