Browse Source

OSP-250: Add support for python3

This PR did a few changes that are mostly related to Python3:

- Convert iterators to lists as needed
- Separate most mock paths and store in an individual file
- Use http.client for py3 (handled by six)
- Use upstream HTTPS Connection directly, instead of a customed one
- Update requirements and project configs
- Fix various compatibility issues
- Oranization/Refactor
- Use explicted calls for super
- Other minor fix/improvements

Change-Id: I186f182de82cb9da2ea8215da374bd42eaf1767a
Weifan Fu 5 months ago
parent
commit
206be47aa2
29 changed files with 509 additions and 533 deletions
  1. 12
    0
      .zuul.yaml
  2. 1
    1
      networking_bigswitch/__init__.py
  3. 3
    3
      networking_bigswitch/plugins/bigswitch/agent/restproxy_agent.py
  4. 1
    2
      networking_bigswitch/plugins/bigswitch/config.py
  5. 4
    7
      networking_bigswitch/plugins/bigswitch/l3_router_plugin.py
  6. 2
    2
      networking_bigswitch/plugins/bigswitch/plugin.py
  7. 113
    59
      networking_bigswitch/plugins/bigswitch/servermanager.py
  8. 2
    0
      networking_bigswitch/plugins/bigswitch/utils.py
  9. 1
    2
      networking_bigswitch/plugins/bigswitch/version.py
  10. 7
    7
      networking_bigswitch/plugins/ml2/drivers/mech_bigswitch/driver.py
  11. 6
    45
      networking_bigswitch/tests/unit/bigswitch/fake_server.py
  12. 93
    0
      networking_bigswitch/tests/unit/bigswitch/mock_paths.py
  13. 3
    3
      networking_bigswitch/tests/unit/bigswitch/test_agent_scheduler.py
  14. 30
    32
      networking_bigswitch/tests/unit/bigswitch/test_base.py
  15. 10
    11
      networking_bigswitch/tests/unit/bigswitch/test_capabilities.py
  16. 2
    1
      networking_bigswitch/tests/unit/bigswitch/test_networktemplate_db.py
  17. 2
    1
      networking_bigswitch/tests/unit/bigswitch/test_networktemplateassignment_db.py
  18. 2
    1
      networking_bigswitch/tests/unit/bigswitch/test_reachabilityquicktest_db.py
  19. 2
    1
      networking_bigswitch/tests/unit/bigswitch/test_reachabilitytest_db.py
  20. 31
    31
      networking_bigswitch/tests/unit/bigswitch/test_restproxy_agent.py
  21. 15
    15
      networking_bigswitch/tests/unit/bigswitch/test_restproxy_plugin.py
  22. 13
    13
      networking_bigswitch/tests/unit/bigswitch/test_router_db.py
  23. 2
    2
      networking_bigswitch/tests/unit/bigswitch/test_security_groups.py
  24. 69
    127
      networking_bigswitch/tests/unit/bigswitch/test_servermanager.py
  25. 38
    157
      networking_bigswitch/tests/unit/bigswitch/test_ssl.py
  26. 7
    8
      networking_bigswitch/tests/unit/ml2/drivers/test_bigswitch_mech.py
  27. 22
    1
      requirements.txt
  28. 3
    0
      setup.cfg
  29. 13
    1
      tox.ini

+ 12
- 0
.zuul.yaml View File

@@ -20,6 +20,14 @@
20 20
             required-projects:
21 21
               - name: openstack/neutron
22 22
               - name: openstack/tap-as-a-service
23
+        - openstack-tox-py35:
24
+            required-projects:
25
+              - name: openstack/neutron
26
+              - name: openstack/tap-as-a-service
27
+        - openstack-tox-py36:
28
+            required-projects:
29
+              - name: openstack/neutron
30
+              - name: openstack/tap-as-a-service
23 31
     gate:
24 32
       jobs:
25 33
         - openstack-tox-pep8:
@@ -30,3 +38,7 @@
30 38
             required-projects:
31 39
               - name: openstack/neutron
32 40
               - name: openstack/tap-as-a-service
41
+        - openstack-tox-py35:
42
+            required-projects:
43
+              - name: openstack/neutron
44
+              - name: openstack/tap-as-a-service

+ 1
- 1
networking_bigswitch/__init__.py View File

@@ -14,8 +14,8 @@
14 14
 #    under the License.
15 15
 
16 16
 import gettext
17
-import six
18 17
 
18
+import six
19 19
 
20 20
 if six.PY2:
21 21
     # E1123: unexpected keyword argument

+ 3
- 3
networking_bigswitch/plugins/bigswitch/agent/restproxy_agent.py View File

@@ -92,13 +92,13 @@ class IVSBridge(object):
92 92
         try:
93 93
             resp = self.run_vsctl(['list-ports'], True,
94 94
                                   log_fail_as_error=False).strip().splitlines()
95
-            port_names = map(lambda x: x.strip(), resp)
95
+            port_names = [x.strip() for x in resp]
96 96
         except RuntimeError:
97 97
             resp = self.run_vsctl(['show'], True)
98 98
             # get rid of stats and blank lines
99 99
             lines = resp.split('ivs:')[1].split('ports:')[1].splitlines()
100 100
             ports = [x for x in lines if 'packets=' not in x and x.strip()]
101
-            port_names = map(lambda x: x.strip().split(' ')[1], ports)
101
+            port_names = [x.strip().split(' ')[1] for x in ports]
102 102
         LOG.debug("Ports on IVS: %s", port_names)
103 103
         return port_names
104 104
 
@@ -174,7 +174,7 @@ class FilterDeviceIDMixin(sg_rpc.SecurityGroupAgentRpc):
174 174
                 self.firewall.prepare_port_filter(device)
175 175
             if self.use_enhanced_rpc:
176 176
                 LOG.debug("Update security group information for ports %s",
177
-                          devices.keys())
177
+                          list(devices.keys()))
178 178
                 self._update_security_group_info(
179 179
                     security_groups, security_group_member_ips)
180 180
 

+ 1
- 2
networking_bigswitch/plugins/bigswitch/config.py View File

@@ -17,11 +17,10 @@
17 17
 This module manages configuration options
18 18
 """
19 19
 
20
-from oslo_config import cfg
21
-
22 20
 from neutron.conf.agent import common as agconfig
23 21
 from neutron_lib.api.definitions import portbindings
24 22
 from neutron_lib.utils import net
23
+from oslo_config import cfg
25 24
 
26 25
 restproxy_opts = [
27 26
     cfg.ListOpt('servers', default=['localhost:8800'],

+ 4
- 7
networking_bigswitch/plugins/bigswitch/l3_router_plugin.py View File

@@ -22,16 +22,9 @@ Big Switch core plugin.
22 22
 """
23 23
 import copy
24 24
 
25
-from oslo_log import helpers as log_helper
26
-from oslo_log import log as logging
27
-from oslo_utils import excutils
28
-from oslo_utils import uuidutils
29
-
30 25
 from neutron.api import extensions as neutron_extensions
31 26
 from neutron.db import dns_db
32 27
 from neutron.db import l3_db
33
-
34
-
35 28
 from neutron_lib.api.definitions import l3 as l3_apidef
36 29
 from neutron_lib.callbacks import events
37 30
 from neutron_lib.callbacks import registry
@@ -41,6 +34,10 @@ from neutron_lib.db import api as db_api
41 34
 from neutron_lib import exceptions
42 35
 from neutron_lib.plugins import constants as plugin_constants
43 36
 from neutron_lib.plugins import directory
37
+from oslo_log import helpers as log_helper
38
+from oslo_log import log as logging
39
+from oslo_utils import excutils
40
+from oslo_utils import uuidutils
44 41
 
45 42
 from networking_bigswitch.plugins.bigswitch.db import tenant_policy_db
46 43
 from networking_bigswitch.plugins.bigswitch import extensions

+ 2
- 2
networking_bigswitch/plugins/bigswitch/plugin.py View File

@@ -42,7 +42,6 @@ on port-attach) on an additional PUT to do a bulk dump of all persistent data.
42 42
 
43 43
 import copy
44 44
 import functools
45
-import httplib
46 45
 import re
47 46
 
48 47
 import eventlet
@@ -50,6 +49,7 @@ from oslo_config import cfg
50 49
 from oslo_log import log as logging
51 50
 import oslo_messaging
52 51
 from oslo_utils import importutils
52
+from six.moves import http_client
53 53
 from sqlalchemy.orm import exc as sqlexc
54 54
 
55 55
 from neutron.agent import rpc as agent_rpc
@@ -928,7 +928,7 @@ class NeutronRestProxyV2Base(db_base_plugin_v2.NeutronDbPluginV2,
928 928
             # and the data in the backend.
929 929
             # Run a sync to get it consistent.
930 930
             if (cfg.CONF.RESTPROXY.auto_sync_on_failure and
931
-                    e.status == httplib.NOT_FOUND and
931
+                    e.status == http_client.NOT_FOUND and
932 932
                     servermanager.NXNETWORK in e.reason):
933 933
                 LOG.error("Inconsistency with backend controller "
934 934
                           "triggering full synchronization.")

+ 113
- 59
networking_bigswitch/plugins/bigswitch/servermanager.py View File

@@ -27,32 +27,32 @@ The following functionality is handled by this module:
27 27
 
28 28
 """
29 29
 import base64
30
-import httplib
30
+import os
31 31
 import re
32 32
 import socket
33 33
 import ssl
34 34
 import time
35 35
 
36
-from neutron_lib import exceptions
37
-
38
-from oslo_log import log as logging
39
-
40 36
 import eventlet
41 37
 import eventlet.corolocal
42 38
 from keystoneauth1.identity import v3
43 39
 from keystoneauth1 import session
44 40
 from keystoneclient.v3 import client as ksclient
41
+from neutron_lib import exceptions
42
+from oslo_config import cfg
43
+from oslo_log import log as logging
44
+from oslo_serialization import jsonutils
45
+from oslo_utils import excutils
46
+import six
47
+from six.moves import http_client
48
+from sqlalchemy.types import Enum
49
+
45 50
 from networking_bigswitch.plugins.bigswitch.db import consistency_db as cdb
46 51
 from networking_bigswitch.plugins.bigswitch.i18n import _
47 52
 from networking_bigswitch.plugins.bigswitch.i18n import _LE
48 53
 from networking_bigswitch.plugins.bigswitch.i18n import _LI
49 54
 from networking_bigswitch.plugins.bigswitch.i18n import _LW
50 55
 from networking_bigswitch.plugins.bigswitch.utils import Util
51
-import os
52
-from oslo_config import cfg
53
-from oslo_serialization import jsonutils
54
-from oslo_utils import excutils
55
-from sqlalchemy.types import Enum
56 56
 
57 57
 LOG = logging.getLogger(__name__)
58 58
 
@@ -97,7 +97,7 @@ HTTP_SERVICE_UNAVAILABLE_RETRY_INTERVAL = 3
97 97
 
98 98
 KEYSTONE_SYNC_RATE_LIMIT = 30  # Limit KeyStone sync to once in 30 secs
99 99
 # TOPO_SYNC Responses
100
-TOPO_RESPONSE_OK = (httplib.OK, httplib.OK, True, True)
100
+TOPO_RESPONSE_OK = (http_client.OK, http_client.OK, True, True)
101 101
 TOPO_RESPONSE_FAIL = (0, None, None, None)
102 102
 
103 103
 # RE pattern for checking BCF supported names
@@ -252,11 +252,11 @@ def get_keystoneauth_cfg(conf, name):
252 252
 class ServerProxy(object):
253 253
     """REST server proxy to a network controller."""
254 254
 
255
-    def __init__(self, server, port, ssl, auth, neutron_id, timeout,
255
+    def __init__(self, server, port, is_ssl_enabled, auth, neutron_id, timeout,
256 256
                  base_uri, name, mypool, combined_cert):
257 257
         self.server = server
258 258
         self.port = port
259
-        self.ssl = ssl
259
+        self.is_ssl_enabled = is_ssl_enabled
260 260
         self.base_uri = base_uri
261 261
         self.timeout = timeout
262 262
         self.name = name
@@ -268,16 +268,40 @@ class ServerProxy(object):
268 268
         self.capabilities = []
269 269
         # enable server to reference parent pool
270 270
         self.mypool = mypool
271
-        # cache connection here to avoid a SSL handshake for every connection
272
-        self.currentconn = None
271
+
272
+        # TODO(weifan): cache connection to avoid a SSL handshake for every
273
+        # connection
274
+        self.cached_conn = None
275
+
276
+        # ssl_context is the new standard interface for handling certificates
277
+        # initialize ssl context
278
+        self.ssl_context = None
273 279
 
274 280
         if auth:
275 281
             if ':' in auth:
276
-                self.auth = 'Basic ' + base64.encodestring(auth).strip()
282
+                if six.PY2:
283
+                    self.auth = 'Basic ' + base64.encodestring(auth).strip()
284
+                else:
285
+                    self.auth = 'Basic ' + base64.b64encode(auth.encode(
286
+                        'utf-8')).decode('utf-8')
277 287
             else:
278 288
                 self.auth_token = 'session_cookie="' + auth + '"'
279 289
 
280
-        self.combined_cert = combined_cert
290
+        if is_ssl_enabled:
291
+            # initialize ssl context
292
+            self.ssl_context = None
293
+
294
+            # Uses PROTOCOL_TLS (new default)
295
+            # or PROTOCOL_SSLv23(deprecated, old default)
296
+            # both works with BCF TLS connections
297
+            self.ssl_context = ssl.create_default_context(cafile=combined_cert)
298
+
299
+            if six.PY2:
300
+                # Monkey Patch to skip hostname check for ssl in py2
301
+                # There is a bug with the old version
302
+                ssl.match_hostname = lambda cert, hostname: True
303
+            else:
304
+                self.ssl_context.check_hostname = False
281 305
 
282 306
     def get_capabilities(self):
283 307
         try:
@@ -317,8 +341,9 @@ class ServerProxy(object):
317 341
             headers['Authorization'] = self.auth
318 342
 
319 343
         LOG.debug("ServerProxy: server=%(server)s, port=%(port)d, "
320
-                  "ssl=%(ssl)r",
321
-                  {'server': self.server, 'port': self.port, 'ssl': self.ssl})
344
+                  "is_ssl_enabled=%(is_ssl_enabled)r",
345
+                  {'server': self.server, 'port': self.port,
346
+                   'is_ssl_enabled': self.is_ssl_enabled})
322 347
         LOG.debug("ServerProxy: resource=%(resource)s, data=%(data)r, "
323 348
                   "headers=%(headers)r, action=%(action)s",
324 349
                   {'resource': resource, 'data': data, 'headers': headers,
@@ -333,26 +358,39 @@ class ServerProxy(object):
333 358
             # need a new connection if timeout has changed
334 359
             reconnect = True
335 360
 
336
-        if not self.currentconn or reconnect:
337
-            if self.currentconn:
338
-                self.currentconn.close()
339
-            if self.ssl:
340
-                currentconn = HTTPSConnectionWithValidation(
341
-                    self.server, self.port, timeout=timeout)
361
+        if not self.cached_conn or reconnect:
362
+            if self.cached_conn:
363
+                self.cached_conn.close()
364
+            if self.is_ssl_enabled:
365
+                currentconn = http_client.HTTPSConnection(
366
+                    self.server, self.port, timeout=timeout,
367
+                    context=self.ssl_context)
368
+
342 369
                 if currentconn is None:
343 370
                     LOG.error('ServerProxy: Could not establish HTTPS '
344 371
                               'connection')
345 372
                     return 0, None, None, None
346
-                currentconn.combined_cert = self.combined_cert
373
+
374
+                # TODO(weifan): cache connection and reuse
375
+                # require keep-alive
376
+                # self.cached_conn = currentconn
377
+
347 378
             else:
348
-                currentconn = httplib.HTTPConnection(
379
+                currentconn = http_client.HTTPConnection(
349 380
                     self.server, self.port, timeout=timeout)
350 381
                 if currentconn is None:
351 382
                     LOG.error('ServerProxy: Could not establish HTTP '
352 383
                               'connection')
353 384
                     return 0, None, None, None
354 385
 
386
+                # TODO(weifan): cache connection and reuse
387
+                # require keep-alive
388
+                # self.cached_conn = currentconn
389
+
355 390
         try:
391
+            # TODO(weifan): use cache connection instead of currentconn
392
+            # require keep alive
393
+
356 394
             bcf_request_time = time.time()
357 395
             currentconn.request(action, uri, body, headers)
358 396
             response = currentconn.getresponse()
@@ -369,7 +407,12 @@ class ServerProxy(object):
369 407
                     pass
370 408
 
371 409
             ret = (response.status, response.reason, respstr, respdata)
372
-        except httplib.HTTPException:
410
+
411
+            # TODO(weifan): use cache connection
412
+            # currently closing every connection after use
413
+            currentconn.close()
414
+
415
+        except http_client.HTTPException:
373 416
             # If we were using a cached connection, try again with a new one.
374 417
             with excutils.save_and_reraise_exception() as ctxt:
375 418
                 currentconn.close()
@@ -393,6 +436,7 @@ class ServerProxy(object):
393 436
                                                  'reason': ret[1],
394 437
                                                  'ret': ret[2],
395 438
                                                  'data': ret[3]})
439
+
396 440
         return ret
397 441
 
398 442
 
@@ -415,7 +459,7 @@ class ServerPool(object):
415 459
         # till next failure). Use 'server_auth' to encode api-key
416 460
         servers = cfg.CONF.RESTPROXY.servers
417 461
         self.auth = cfg.CONF.RESTPROXY.server_auth
418
-        self.ssl = cfg.CONF.RESTPROXY.server_ssl
462
+        self.is_ssl_enabled = cfg.CONF.RESTPROXY.server_ssl
419 463
         self.neutron_id = cfg.CONF.RESTPROXY.neutron_id
420 464
         # unicode config
421 465
         self.cfg_unicode_enabled = cfg.CONF.RESTPROXY.naming_scheme_unicode
@@ -609,9 +653,12 @@ class ServerPool(object):
609 653
             return False
610 654
 
611 655
     def server_proxy_for(self, server, port):
656
+        # TODO(weifan): use ssl_context to load certificates instead of our
657
+        # own codes
612 658
         combined_cert = self._get_combined_cert_for_server(server, port)
613
-        return ServerProxy(server, port, self.ssl, self.auth, self.neutron_id,
614
-                           self.timeout, self.base_uri, self.name, mypool=self,
659
+        return ServerProxy(server, port, self.is_ssl_enabled, self.auth,
660
+                           self.neutron_id, self.timeout, self.base_uri,
661
+                           self.name, mypool=self,
615 662
                            combined_cert=combined_cert)
616 663
 
617 664
     def _get_combined_cert_for_server(self, server, port):
@@ -619,7 +666,7 @@ class ServerPool(object):
619 666
         # so we make one containing the trusted CAs and the corresponding
620 667
         # host cert for this server
621 668
         combined_cert = None
622
-        if self.ssl and not cfg.CONF.RESTPROXY.no_ssl_validation:
669
+        if self.is_ssl_enabled and not cfg.CONF.RESTPROXY.no_ssl_validation:
623 670
             base_ssl = cfg.CONF.RESTPROXY.ssl_cert_directory
624 671
             host_dir = os.path.join(base_ssl, 'host_certs')
625 672
             ca_dir = os.path.join(base_ssl, 'ca_certs')
@@ -675,15 +722,45 @@ class ServerPool(object):
675 722
                  if name.endswith('.pem')]
676 723
         return certs
677 724
 
725
+    def py34_get_server_certificate(self, server_info):
726
+        """Temp Fix for py34
727
+
728
+        :param server_info: (server, port)  # tuple
729
+        :return:
730
+        """
731
+        # There is some issue with ssl.get_server_certificate in PY3.4
732
+        # 'with' statements are causing __exit__ errors
733
+        # The code here is basically duplicate logic of upstream ssl
734
+        # Except that it does not use 'with' keyword
735
+        # https://github.com/python/cpython/blob/3.4/Lib/ssl.py#L933
736
+        # Note: This error is only observed in OSP, it seems to work in
737
+        # interactive console.
738
+        ctx = ssl.create_default_context()
739
+        ctx.check_hostname = False
740
+        ctx.verify_mode = ssl.CERT_NONE
741
+        conn = socket.create_connection(server_info)
742
+        ssl_sock = ctx.wrap_socket(conn)
743
+        dercert = ssl_sock.getpeercert(True)
744
+        cert = ssl.DER_cert_to_PEM_cert(dercert)
745
+        ssl_sock.close()
746
+        conn.close()
747
+        return cert
748
+
678 749
     def _fetch_and_store_cert(self, server, port, path):
679 750
         """_fetch_and_store_cert
680 751
 
681 752
         Grabs a certificate from a server and writes it to
682 753
         a given path.
683 754
         """
755
+
684 756
         try:
685
-            cert = ssl.get_server_certificate((server, port),
686
-                                              ssl_version=ssl.PROTOCOL_SSLv23)
757
+            if six.PY2:
758
+                # TODO(weifan): Test if this works in PY3.5
759
+                # or some later PY3 versions
760
+                cert = ssl.get_server_certificate((server, port))
761
+            else:
762
+                cert = self.py34_get_server_certificate((server, port))
763
+
687 764
         except Exception as e:
688 765
             raise cfg.Error(_('Could not retrieve initial '
689 766
                               'certificate from controller %(server)s. '
@@ -692,6 +769,7 @@ class ServerPool(object):
692 769
 
693 770
         LOG.warning("Storing to certificate for host %(server)s "
694 771
                     "at %(path)s", {'server': server, 'path': path})
772
+
695 773
         self._file_put_contents(path, cert)
696 774
 
697 775
         return cert
@@ -734,7 +812,7 @@ class ServerPool(object):
734 812
                 ret = active_server.rest_call(action, resource, data, headers,
735 813
                                               timeout,
736 814
                                               reconnect=self.always_reconnect)
737
-                if ret[0] != httplib.SERVICE_UNAVAILABLE:
815
+                if ret[0] != http_client.SERVICE_UNAVAILABLE:
738 816
                     break
739 817
                 eventlet.sleep(HTTP_SERVICE_UNAVAILABLE_RETRY_INTERVAL)
740 818
 
@@ -1186,27 +1264,3 @@ class ServerPool(object):
1186 1264
         while True:
1187 1265
             eventlet.sleep(polling_interval)
1188 1266
             self._update_tenant_cache()
1189
-
1190
-
1191
-class HTTPSConnectionWithValidation(httplib.HTTPSConnection):
1192
-
1193
-    # If combined_cert is None, the connection will continue without
1194
-    # any certificate validation.
1195
-    combined_cert = None
1196
-
1197
-    def connect(self):
1198
-        sock = socket.create_connection((self.host, self.port),
1199
-                                        self.timeout, self.source_address)
1200
-        if self._tunnel_host:
1201
-            self.sock = sock
1202
-            self._tunnel()
1203
-
1204
-        if self.combined_cert:
1205
-            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
1206
-                                        cert_reqs=ssl.CERT_REQUIRED,
1207
-                                        ca_certs=self.combined_cert,
1208
-                                        ssl_version=ssl.PROTOCOL_SSLv23)
1209
-        else:
1210
-            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
1211
-                                        cert_reqs=ssl.CERT_NONE,
1212
-                                        ssl_version=ssl.PROTOCOL_SSLv23)

+ 2
- 0
networking_bigswitch/plugins/bigswitch/utils.py View File

@@ -14,6 +14,8 @@
14 14
 #    under the License.
15 15
 from neutron_lib import exceptions as n_exc
16 16
 
17
+from networking_bigswitch.plugins.bigswitch.i18n import _
18
+
17 19
 
18 20
 class Util(object):
19 21
     """Util

+ 1
- 2
networking_bigswitch/plugins/bigswitch/version.py View File

@@ -24,8 +24,7 @@ YEAR, COUNT, REVISION = vcsversion.NEUTRONRESTPROXY_VERSION
24 24
 
25 25
 
26 26
 def canonical_version_string():
27
-    return '.'.join(filter(None,
28
-                           vcsversion.NEUTRONRESTPROXY_VERSION))
27
+    return '.'.join([_f for _f in vcsversion.NEUTRONRESTPROXY_VERSION if _f])
29 28
 
30 29
 
31 30
 def version_string():

+ 7
- 7
networking_bigswitch/plugins/ml2/drivers/mech_bigswitch/driver.py View File

@@ -14,15 +14,9 @@
14 14
 #    under the License.
15 15
 import copy
16 16
 import datetime
17
-import httplib
18 17
 import os
19 18
 
20 19
 import eventlet
21
-from oslo_config import cfg
22
-from oslo_log import log
23
-import oslo_messaging
24
-from oslo_utils import excutils
25
-from oslo_utils import timeutils
26 20
 
27 21
 from neutron.extensions import securitygroup as ext_sg
28 22
 from neutron_lib.api.definitions import portbindings
@@ -34,6 +28,12 @@ from neutron_lib import context as ctx
34 28
 from neutron_lib.plugins import directory
35 29
 from neutron_lib.plugins.ml2 import api
36 30
 from neutron_lib import rpc as lib_rpc
31
+from oslo_config import cfg
32
+from oslo_log import log
33
+import oslo_messaging
34
+from oslo_utils import excutils
35
+from oslo_utils import timeutils
36
+from six.moves import http_client
37 37
 
38 38
 from networking_bigswitch.plugins.bigswitch import config as pl_config
39 39
 from networking_bigswitch.plugins.bigswitch.i18n import _
@@ -391,7 +391,7 @@ class BigSwitchMechanismDriver(plugin.NeutronRestProxyV2Base,
391 391
             except servermanager.RemoteRestError as e:
392 392
                 with excutils.save_and_reraise_exception() as ctxt:
393 393
                     if (cfg.CONF.RESTPROXY.auto_sync_on_failure and
394
-                            e.status == httplib.NOT_FOUND and
394
+                            e.status == http_client.NOT_FOUND and
395 395
                             servermanager.NXNETWORK in e.reason):
396 396
                         ctxt.reraise = False
397 397
                         LOG.error("Inconsistency with backend controller "

+ 6
- 45
networking_bigswitch/tests/unit/bigswitch/fake_server.py View File

@@ -58,7 +58,7 @@ class HTTPResponseMock500(HTTPResponseMock):
58 58
 
59 59
 class HTTPConnectionMock(object):
60 60
 
61
-    def __init__(self, server, port, timeout):
61
+    def __init__(self, host, port, timeout):
62 62
         self.response = None
63 63
         self.broken = False
64 64
         # Port 9000 is the broken server
@@ -101,14 +101,14 @@ class HTTPConnectionMock(object):
101 101
 
102 102
 class HTTPConnectionMock404(HTTPConnectionMock):
103 103
 
104
-    def __init__(self, server, port, timeout):
104
+    def __init__(self, host, port, timeout):
105 105
         self.response = HTTPResponseMock404(None)
106 106
         self.broken = True
107 107
 
108 108
 
109 109
 class HTTPConnectionMock500(HTTPConnectionMock):
110 110
 
111
-    def __init__(self, server, port, timeout):
111
+    def __init__(self, host, port, timeout):
112 112
         self.response = HTTPResponseMock500(None)
113 113
         self.broken = True
114 114
 
@@ -138,47 +138,8 @@ class VerifyMultiTenantFloatingIP(HTTPConnectionMock):
138 138
 
139 139
 
140 140
 class HTTPSMockBase(HTTPConnectionMock):
141
-    expected_cert = ''
142
-    combined_cert = None
143
-
144
-    def __init__(self, host, port=None, key_file=None, cert_file=None,
145
-                 strict=None, timeout=None, source_address=None):
141
+    def __init__(self, host, port=None, context=None, timeout=None,
142
+                 source_address=None):
146 143
         self.host = host
144
+        self.ssl_context = context
147 145
         super(HTTPSMockBase, self).__init__(host, port, timeout)
148
-
149
-    def request(self, method, url, body=None, headers=None):
150
-        self.connect()
151
-        if headers is None:
152
-            headers = {}
153
-        super(HTTPSMockBase, self).request(method, url, body, headers)
154
-
155
-
156
-class HTTPSNoValidation(HTTPSMockBase):
157
-
158
-    def connect(self):
159
-        if self.combined_cert:
160
-            raise Exception('combined_cert set on NoValidation')
161
-
162
-
163
-class HTTPSCAValidation(HTTPSMockBase):
164
-    expected_cert = 'DUMMYCERTIFICATEAUTHORITY'
165
-
166
-    def connect(self):
167
-        contents = get_cert_contents(self.combined_cert)
168
-        if self.expected_cert not in contents:
169
-            raise Exception('No dummy CA cert in cert_file')
170
-
171
-
172
-class HTTPSHostValidation(HTTPSMockBase):
173
-    expected_cert = 'DUMMYCERTFORHOST%s'
174
-
175
-    def connect(self):
176
-        contents = get_cert_contents(self.combined_cert)
177
-        expected = self.expected_cert % self.host
178
-        if expected not in contents:
179
-            raise Exception(_('No host cert for %(server)s in cert %(cert)s'),
180
-                            {'server': self.host, 'cert': contents})
181
-
182
-
183
-def get_cert_contents(path):
184
-    raise Exception('METHOD MUST BE MOCKED FOR TEST')

+ 93
- 0
networking_bigswitch/tests/unit/bigswitch/mock_paths.py View File

@@ -0,0 +1,93 @@
1
+# Copyright 2018 Big Switch Networks, Inc.
2
+# All Rights Reserved.
3
+#
4
+# Licensed under the Apache License, Version 2.0 (the "License");
5
+# you may not use this file except in compliance with the License.
6
+# You may obtain 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,
12
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+# implied.
14
+# See the License for the specific language governing permissions and
15
+# limitations under the License.
16
+
17
+import six
18
+
19
+"""For storing paths used for mocking, this is used in various test files.
20
+"""
21
+# Keystone
22
+KEYSTONE_CLIENT = 'keystoneclient.v3.client.Client'
23
+
24
+# Neutron
25
+DHCP_NOTIFIER = ('neutron.api.rpc.agentnotifiers.dhcp_rpc_agent_api'
26
+                 '.DhcpAgentNotifyAPI.notify')
27
+
28
+NEUTRON_AGENT = 'neutron.agent'
29
+OVS_BRIDGE = NEUTRON_AGENT + '.common.ovs_lib.OVSBridge'
30
+PLUGIN_API = NEUTRON_AGENT + '.rpc.PluginApi'
31
+CONSUMER_CREATE = NEUTRON_AGENT + '.rpc.create_consumers'
32
+
33
+SG_RPC = NEUTRON_AGENT + '.securitygroups_rpc'
34
+
35
+CONTEXT = 'neutron_lib.context'
36
+
37
+NEUTRON_CFG = 'neutron.common.config'
38
+LIB_RPC_TRANSPORT = 'neutron_lib.rpc.TRANSPORT'
39
+
40
+# BSN
41
+BSN_DIR = 'networking_bigswitch.plugins.bigswitch'
42
+
43
+# Config
44
+PL_CONFIG = BSN_DIR + '.config'
45
+
46
+# DB
47
+CONSISTENCY_DB = BSN_DIR + '.db.consistency_db'
48
+
49
+# Driver
50
+DRIVER_MOD = 'networking_bigswitch.plugins.ml2.drivers.mech_bigswitch.driver'
51
+DRIVER = DRIVER_MOD + '.BigSwitchMechanismDriver'
52
+
53
+
54
+# plugin/l3_plugin path
55
+PLUGIN_PATH = BSN_DIR + '.plugin'
56
+L3_PLUGIN_PATH = BSN_DIR + '.l3_router_plugin'
57
+BSN_SERVICE_PLUGIN_PATH = BSN_DIR + '.bsn_service_plugin'
58
+
59
+NOTIFIER = PLUGIN_PATH + '.AgentNotifierApi'
60
+SPAWN = PLUGIN_PATH + '.eventlet.GreenPool.spawn_n'
61
+MAP_DISPLAY_NAME_OR_TENANT = (PLUGIN_PATH + '.NeutronRestProxyV2Base'
62
+                              '._map_display_name_or_tenant')
63
+
64
+# Agent
65
+AGENT_MOD = BSN_DIR + '.agent.restproxy_agent'
66
+SG_AGENT = AGENT_MOD + '.FilterDeviceIDMixin'
67
+IVS_BRIDGE = AGENT_MOD + '.IVSBridge'
68
+NFV_SW_BRIDGE = AGENT_MOD + '.NFVSwitchBridge'
69
+
70
+# SERVER MANAGER
71
+SERVER_MANAGER = BSN_DIR + '.servermanager'
72
+SERVER_REST_CALL = SERVER_MANAGER + '.ServerProxy.rest_call'
73
+HTTPCON = SERVER_MANAGER + '.http_client.HTTPConnection'
74
+HTTPSCON = SERVER_MANAGER + '.http_client.HTTPSConnection'
75
+
76
+SERVER_POOL = SERVER_MANAGER + '.ServerPool'
77
+POOL_REST_ACTION = SERVER_POOL + '.rest_action'
78
+POOL_REST_CALL = SERVER_POOL + '.rest_call'
79
+BACKGROUND = SERVER_POOL + '.start_background_tasks'
80
+POOL_TOPO_SYNC = SERVER_POOL + '.force_topo_sync'
81
+POOL_UPDATE_TENANT_CACHE = SERVER_POOL + '._update_tenant_cache'
82
+POOL_GET_CAPABILITIES = SERVER_POOL + '.get_capabilities'
83
+IS_UNICODE_ENABLED = SERVER_POOL + '.is_unicode_enabled'
84
+
85
+# SSL Cert Related
86
+if six.PY2:
87
+    GET_SERVER_CERTIFICATE = SERVER_MANAGER + '.ssl.get_server_certificate'
88
+else:
89
+    GET_SERVER_CERTIFICATE = SERVER_POOL + '.py34_get_server_certificate'
90
+SSL_CREATE_DEFAULT_CONTEXT = SERVER_MANAGER + '.ssl.create_default_context'
91
+CERT_COMBINER = SERVER_POOL + '._combine_certs_to_file'
92
+FILE_PUT = SERVER_POOL + '._file_put_contents'
93
+GET_CA_CERTS = SERVER_POOL + '._get_ca_cert_paths'

+ 3
- 3
networking_bigswitch/tests/unit/bigswitch/test_agent_scheduler.py View File

@@ -13,9 +13,9 @@
13 13
 # See the License for the specific language governing permissions and
14 14
 # limitations under the License.
15 15
 
16
+from neutron.tests.unit.db import test_agentschedulers_db
16 17
 
17 18
 from networking_bigswitch.tests.unit.bigswitch import test_base
18
-from neutron.tests.unit.db import test_agentschedulers_db
19 19
 
20 20
 
21 21
 class BigSwitchDhcpAgentNotifierTestCase(
@@ -23,12 +23,12 @@ class BigSwitchDhcpAgentNotifierTestCase(
23 23
         test_base.BigSwitchTestBase):
24 24
 
25 25
     plugin_str = ('%s.NeutronRestProxyV2' %
26
-                  test_base.RESTPROXY_PKG_PATH)
26
+                  test_base.PLUGIN_PATH)
27 27
 
28 28
     def setUp(self):
29 29
         self.setup_config_files()
30 30
         self.setup_patches()
31
-        super(BigSwitchDhcpAgentNotifierTestCase, self).setUp()
31
+        test_agentschedulers_db.OvsDhcpAgentNotifierTestCase.setUp(self)
32 32
         self.setup_db()
33 33
         self.startHttpPatch()
34 34
         self.dhcp_notifier_p.stop()

+ 30
- 32
networking_bigswitch/tests/unit/bigswitch/test_base.py View File

@@ -17,10 +17,9 @@
17 17
 import os
18 18
 
19 19
 import mock
20
-from oslo_config import cfg
21
-
22 20
 import neutron.common.test_lib as test_lib
23 21
 from neutron.db import api  # noqa
22
+from oslo_config import cfg
24 23
 
25 24
 from networking_bigswitch.plugins.bigswitch import config
26 25
 from networking_bigswitch.plugins.bigswitch.db import consistency_db
@@ -31,36 +30,32 @@ from networking_bigswitch.plugins.bigswitch.servermanager\
31 30
     import TOPO_RESPONSE_OK
32 31
 from networking_bigswitch.tests.unit.bigswitch import fake_server
33 32
 
34
-
35
-RESTPROXY_PKG_PATH = 'networking_bigswitch.plugins.bigswitch.plugin'
36
-L3_RESTPROXY_PKG_PATH = ('networking_bigswitch.plugins.bigswitch'
37
-                         '.l3_router_plugin')
38
-BSN_SERVICE_PLUGIN_PATH = ('networking_bigswitch.plugins.bigswitch'
39
-                           '.bsn_service_plugin')
40
-NOTIFIER = 'networking_bigswitch.plugins.bigswitch.plugin.AgentNotifierApi'
41
-DHCP_NOTIFIER = ('neutron.api.rpc.agentnotifiers.dhcp_rpc_agent_api.'
42
-                 'DhcpAgentNotifyAPI.notify')
43
-CERTFETCH = ('networking_bigswitch.plugins.bigswitch.servermanager.ServerPool'
44
-             '._fetch_cert')  # noqa
45
-SERVER_MANAGER = 'networking_bigswitch.plugins.bigswitch.servermanager'
46
-HTTPCON = ('networking_bigswitch.plugins.bigswitch.servermanager.httplib'
47
-           '.HTTPConnection')
48
-SPAWN = ('networking_bigswitch.plugins.bigswitch.plugin.eventlet.GreenPool'
49
-         '.spawn_n')
50
-KSCLIENT = 'keystoneclient.v3.client.Client'
51
-BACKGROUND = SERVER_MANAGER + '.ServerPool.start_background_tasks'
52
-MAP_DISPLAY_NAME_OR_TENANT = ('networking_bigswitch.plugins.bigswitch.plugin.'
53
-                              'NeutronRestProxyV2Base.'
54
-                              '_map_display_name_or_tenant')
55
-IS_UNICODE_ENABLED = ('networking_bigswitch.plugins.bigswitch.servermanager.'
56
-                      'ServerPool.is_unicode_enabled')
57
-LIB_RPC_TRANSPORT = ('neutron_lib.rpc.TRANSPORT')
33
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import BACKGROUND
34
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
35
+    BSN_SERVICE_PLUGIN_PATH
36
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import DHCP_NOTIFIER
37
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import HTTPCON
38
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
39
+    IS_UNICODE_ENABLED
40
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
41
+    KEYSTONE_CLIENT
42
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import L3_PLUGIN_PATH
43
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
44
+    LIB_RPC_TRANSPORT
45
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
46
+    MAP_DISPLAY_NAME_OR_TENANT
47
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import NOTIFIER
48
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import PLUGIN_PATH
49
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
50
+    POOL_TOPO_SYNC
51
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import SERVER_MANAGER
52
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import SPAWN
58 53
 
59 54
 
60 55
 class BigSwitchTestBase(object):
61 56
 
62
-    _plugin_name = ('%s.NeutronRestProxyV2' % RESTPROXY_PKG_PATH)
63
-    _l3_plugin_name = ('%s.L3RestProxy' % L3_RESTPROXY_PKG_PATH)
57
+    _plugin_name = ('%s.NeutronRestProxyV2' % PLUGIN_PATH)
58
+    _l3_plugin_name = ('%s.L3RestProxy' % L3_PLUGIN_PATH)
64 59
     _bsn_service_plugin_name = ('%s.BSNServicePlugin'
65 60
                                 % BSN_SERVICE_PLUGIN_PATH)
66 61
 
@@ -101,20 +96,24 @@ class BigSwitchTestBase(object):
101 96
         # disable exception log to prevent json parse error from showing
102 97
         self.log_exc_p = mock.patch(SERVER_MANAGER + ".LOG.exception",
103 98
                                     new=lambda *args, **kwargs: None)
104
-        self.ksclient_p = mock.patch(KSCLIENT)
99
+
100
+        self.ksclient_p = mock.patch(KEYSTONE_CLIENT)
101
+
105 102
         self.map_display_name_or_tenant_p = mock.patch(
106 103
             MAP_DISPLAY_NAME_OR_TENANT,
107 104
             side_effect=self.map_tenant_name_side_effect)
108 105
         self.is_unicode_enabled_p = mock.patch(
109 106
             IS_UNICODE_ENABLED,
110 107
             side_effect=self.is_unicode_enabled_side_effect)
108
+        # TODO(weifan): Find out why Mocking Transport does not work
109
+        # This mock fixes problems on zuul, but it is still broken locally
111 110
         self.lib_rpc_transport_p = mock.patch(LIB_RPC_TRANSPORT)
112 111
         # start all mock patches
113 112
         self.log_exc_p.start()
114 113
         self.plugin_notifier_p.start()
114
+        self.dhcp_notifier_p.start()
115 115
         self.spawn_p.start()
116 116
         self.watch_p.start()
117
-        self.dhcp_notifier_p.start()
118 117
         self.ksclient_p.start()
119 118
         self.map_display_name_or_tenant_p.start()
120 119
         self.is_unicode_enabled_p.start()
@@ -127,8 +126,7 @@ class BigSwitchTestBase(object):
127 126
 
128 127
     def startTopoSyncPatch(self):
129 128
         self.topo_sync_p = \
130
-            mock.patch(SERVER_MANAGER + '.ServerPool.force_topo_sync',
131
-                       return_value=(True, TOPO_RESPONSE_OK))
129
+            mock.patch(POOL_TOPO_SYNC, return_value=(True, TOPO_RESPONSE_OK))
132 130
         self.topo_sync_p.start()
133 131
 
134 132
     def setup_db(self):

+ 10
- 11
networking_bigswitch/tests/unit/bigswitch/test_capabilities.py View File

@@ -22,22 +22,21 @@ from neutron_lib.plugins import directory
22 22
 
23 23
 from networking_bigswitch.tests.unit.bigswitch import test_router_db
24 24
 
25
-PLUGIN = 'networking_bigswitch.plugins.bigswitch.plugin'
26
-SERVERMANAGER = PLUGIN + '.servermanager'
27
-SERVERPOOL = SERVERMANAGER + '.ServerPool'
28
-SERVERRESTCALL = SERVERMANAGER + '.ServerProxy.rest_call'
29
-HTTPCON = SERVERMANAGER + '.httplib.HTTPConnection'
25
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import HTTPCON
26
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import SERVER_POOL
27
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
28
+    SERVER_REST_CALL
30 29
 
31 30
 
32 31
 class CapabilitiesTests(test_router_db.RouterDBTestBase):
33 32
 
34 33
     def test_floating_ip_capability(self):
35 34
         with\
36
-            mock.patch(SERVERRESTCALL,
35
+            mock.patch(SERVER_REST_CALL,
37 36
                        return_value=(200, None, '["floatingip"]', None)),\
38
-            mock.patch(SERVERPOOL + '.rest_create_floatingip',
37
+            mock.patch(SERVER_POOL + '.rest_create_floatingip',
39 38
                        return_value=(200, None, None, None)) as mock_create,\
40
-            mock.patch(SERVERPOOL + '.rest_delete_floatingip',
39
+            mock.patch(SERVER_POOL + '.rest_delete_floatingip',
41 40
                        return_value=(200, None, None, None)) as mock_delete:
42 41
             with self.floatingip_with_assoc() as fip:
43 42
                 # we have to grab the floating ip object from the service
@@ -58,9 +57,9 @@ class CapabilitiesTests(test_router_db.RouterDBTestBase):
58 57
 
59 58
     def test_floating_ip_capability_neg(self):
60 59
         with\
61
-            mock.patch(SERVERRESTCALL,
60
+            mock.patch(SERVER_REST_CALL,
62 61
                        return_value=(200, None, '[""]', None)),\
63
-            mock.patch(SERVERPOOL + '.rest_update_network',
62
+            mock.patch(SERVER_POOL + '.rest_update_network',
64 63
                        return_value=(200, None, None, None)) as mock_netupdate:
65 64
             with self.floatingip_with_assoc() as fip:
66 65
                 pass
@@ -75,7 +74,7 @@ class CapabilitiesTests(test_router_db.RouterDBTestBase):
75 74
                       "their assignment to the servermanager object is not "
76 75
                       "thread-safe")
77 76
         with mock.patch(
78
-            SERVERRESTCALL, return_value=(200, None, '["keep-alive"]', None)
77
+            SERVER_REST_CALL, return_value=(200, None, '["keep-alive"]', None)
79 78
         ):
80 79
             # perform a task to cause capabilities to be retrieved
81 80
             with self.floatingip_with_assoc():

+ 2
- 1
networking_bigswitch/tests/unit/bigswitch/test_networktemplate_db.py View File

@@ -14,10 +14,11 @@
14 14
 #
15 15
 # Adapted from neutron.tests.unit.db.test_agents_db.py
16 16
 
17
-from networking_bigswitch.plugins.bigswitch.db import network_template_db
18 17
 from neutron.tests.unit import testlib_api
19 18
 from neutron_lib import context
20 19
 
20
+from networking_bigswitch.plugins.bigswitch.db import network_template_db
21
+
21 22
 
22 23
 class TestNetworkTemplateDbMixin(testlib_api.SqlTestCase):
23 24
     def setUp(self):

+ 2
- 1
networking_bigswitch/tests/unit/bigswitch/test_networktemplateassignment_db.py View File

@@ -14,10 +14,11 @@
14 14
 #
15 15
 # Adapted from neutron.tests.unit.db.test_agents_db.py
16 16
 
17
-from networking_bigswitch.plugins.bigswitch.db import network_template_db
18 17
 from neutron.tests.unit import testlib_api
19 18
 from neutron_lib import context
20 19
 
20
+from networking_bigswitch.plugins.bigswitch.db import network_template_db
21
+
21 22
 
22 23
 class TestNetworkTemplateAssignmentDbMixin(testlib_api.SqlTestCase):
23 24
     def setUp(self):

+ 2
- 1
networking_bigswitch/tests/unit/bigswitch/test_reachabilityquicktest_db.py View File

@@ -14,10 +14,11 @@
14 14
 #
15 15
 # Adapted from neutron.tests.unit.db.test_agents_db.py
16 16
 
17
-from networking_bigswitch.plugins.bigswitch.db import reachability_test_db
18 17
 from neutron.tests.unit import testlib_api
19 18
 from neutron_lib import context
20 19
 
20
+from networking_bigswitch.plugins.bigswitch.db import reachability_test_db
21
+
21 22
 
22 23
 class TestReachabilityQuickTestDbMixin(testlib_api.SqlTestCase):
23 24
     def setUp(self):

+ 2
- 1
networking_bigswitch/tests/unit/bigswitch/test_reachabilitytest_db.py View File

@@ -14,10 +14,11 @@
14 14
 #
15 15
 # Adapted from neutron.tests.unit.db.test_agents_db.py
16 16
 
17
-from networking_bigswitch.plugins.bigswitch.db import reachability_test_db
18 17
 from neutron.tests.unit import testlib_api
19 18
 from neutron_lib import context
20 19
 
20
+from networking_bigswitch.plugins.bigswitch.db import reachability_test_db
21
+
21 22
 
22 23
 class TestReachabilityTestDbMixin(testlib_api.SqlTestCase):
23 24
     def setUp(self):

+ 31
- 31
networking_bigswitch/tests/unit/bigswitch/test_restproxy_agent.py View File

@@ -14,23 +14,23 @@
14 14
 #    under the License.
15 15
 
16 16
 import mock
17
-from oslo_utils import importutils
18
-
19 17
 from neutron.tests import base
18
+from oslo_utils import importutils
20 19
 
21 20
 from networking_bigswitch.plugins.bigswitch import config as pl_config
22 21
 
23
-OVSBRIDGE = 'neutron.agent.common.ovs_lib.OVSBridge'
24
-PLUGINAPI = 'neutron.agent.rpc.PluginApi'
25
-CONTEXT = 'neutron_lib.context'
26
-CONSUMERCREATE = 'neutron.agent.rpc.create_consumers'
27
-SGRPC = 'neutron.agent.securitygroups_rpc'
28
-AGENTMOD = 'networking_bigswitch.plugins.bigswitch.agent.restproxy_agent'
29
-SGAGENT = AGENTMOD + '.FilterDeviceIDMixin'
30
-IVSBRIDGE = AGENTMOD + '.IVSBridge'
31
-NFVSWBRIDGE = AGENTMOD + '.NFVSwitchBridge'
32
-NEUTRONCFG = 'neutron.common.config'
33
-PLCONFIG = 'networking_bigswitch.plugins.bigswitch.config'
22
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import AGENT_MOD
23
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
24
+    CONSUMER_CREATE
25
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import CONTEXT
26
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import IVS_BRIDGE
27
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import NEUTRON_CFG
28
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import NFV_SW_BRIDGE
29
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import OVS_BRIDGE
30
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import PL_CONFIG
31
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import PLUGIN_API
32
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import SG_AGENT
33
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import SG_RPC
34 34
 
35 35
 
36 36
 class BaseAgentTestCase(base.BaseTestCase):
@@ -38,19 +38,19 @@ class BaseAgentTestCase(base.BaseTestCase):
38 38
     def setUp(self):
39 39
         pl_config.register_config()
40 40
         super(BaseAgentTestCase, self).setUp()
41
-        self.mod_agent = importutils.import_module(AGENTMOD)
41
+        self.mod_agent = importutils.import_module(AGENT_MOD)
42 42
 
43 43
 
44 44
 class TestRestProxyAgentOVS(BaseAgentTestCase):
45 45
     def setUp(self):
46 46
         super(TestRestProxyAgentOVS, self).setUp()
47
-        self.plapi = mock.patch(PLUGINAPI).start()
48
-        self.ovsbridge_p = mock.patch(OVSBRIDGE)
47
+        self.plapi = mock.patch(PLUGIN_API).start()
48
+        self.ovsbridge_p = mock.patch(OVS_BRIDGE)
49 49
         self.ovsbridge = self.ovsbridge_p.start()
50 50
         self.context = mock.patch(CONTEXT).start()
51
-        self.rpc = mock.patch(CONSUMERCREATE).start()
52
-        self.sg_agent = mock.patch(SGAGENT).start()
53
-        self.sg_rpc = mock.patch(SGRPC).start()
51
+        self.rpc = mock.patch(CONSUMER_CREATE).start()
52
+        self.sg_agent = mock.patch(SG_AGENT).start()
53
+        self.sg_rpc = mock.patch(SG_RPC).start()
54 54
 
55 55
     def mock_agent(self):
56 56
         mock_context = mock.Mock(return_value='abc')
@@ -170,10 +170,10 @@ class TestRestProxyAgent(BaseAgentTestCase):
170 170
                      'CONF.AGENT.root_helper': 'helper',
171 171
                      'CONF.AGENT.report_interval': 60}
172 172
         with\
173
-            mock.patch(AGENTMOD + '.cfg', **cfg_attrs) as mock_conf,\
174
-            mock.patch(AGENTMOD + '.config.init'),\
175
-            mock.patch(NEUTRONCFG) as mock_log_conf,\
176
-                mock.patch(PLCONFIG):
173
+            mock.patch(AGENT_MOD + '.cfg', **cfg_attrs) as mock_conf,\
174
+            mock.patch(AGENT_MOD + '.config.init'),\
175
+            mock.patch(NEUTRON_CFG) as mock_log_conf,\
176
+                mock.patch(PL_CONFIG):
177 177
             self.mod_agent.main()
178 178
 
179 179
         mock_log_conf.assert_has_calls([
@@ -182,7 +182,7 @@ class TestRestProxyAgent(BaseAgentTestCase):
182 182
 
183 183
     def test_main(self):
184 184
         agent_attrs = {'daemon_loop.side_effect': SystemExit(0)}
185
-        with mock.patch(AGENTMOD + '.RestProxyAgent',
185
+        with mock.patch(AGENT_MOD + '.RestProxyAgent',
186 186
                         **agent_attrs) as mock_agent:
187 187
             self.assertRaises(SystemExit, self.mock_main)
188 188
 
@@ -199,7 +199,7 @@ class TestRestProxyAgentIVS(TestRestProxyAgentOVS):
199 199
         # we don't want to mock out the whole class, just the part that
200 200
         # tries to run commands on the system
201 201
         self.ovsbridge_p.stop()
202
-        self.runvsctl = mock.patch(IVSBRIDGE + '.run_vsctl').start()
202
+        self.runvsctl = mock.patch(IVS_BRIDGE + '.run_vsctl').start()
203 203
 
204 204
     def mock_agent(self):
205 205
         mock_context = mock.Mock(return_value='abc')
@@ -219,7 +219,7 @@ class TestRestProxyAgentIVS(TestRestProxyAgentOVS):
219 219
     def test_port_update_not_vifport(self):
220 220
         port = {'id': '1', 'security_groups': 'default'}
221 221
 
222
-        with mock.patch(IVSBRIDGE + '.get_vif_port_by_id',
222
+        with mock.patch(IVS_BRIDGE + '.get_vif_port_by_id',
223 223
                         return_value=False) as get_vif:
224 224
             self.mock_port_update(port=port)
225 225
 
@@ -229,7 +229,7 @@ class TestRestProxyAgentIVS(TestRestProxyAgentOVS):
229 229
     def test_port_update_without_secgroup(self):
230 230
         port = {'id': '1'}
231 231
 
232
-        with mock.patch(IVSBRIDGE + '.get_vif_port_by_id',
232
+        with mock.patch(IVS_BRIDGE + '.get_vif_port_by_id',
233 233
                         return_value='1') as get_vif:
234 234
             self.mock_port_update(port=port)
235 235
 
@@ -239,7 +239,7 @@ class TestRestProxyAgentIVS(TestRestProxyAgentOVS):
239 239
     def test_port_update(self):
240 240
         port = {'id': '1', 'security_groups': 'default'}
241 241
 
242
-        with mock.patch(IVSBRIDGE + '.get_vif_port_by_id',
242
+        with mock.patch(IVS_BRIDGE + '.get_vif_port_by_id',
243 243
                         return_value='1') as get_vif:
244 244
             self.mock_port_update(port=port)
245 245
 
@@ -347,7 +347,7 @@ class TestRestProxyAgentNFVSwitch(TestRestProxyAgentOVS):
347 347
     def test_port_update_not_vifport(self):
348 348
         port = {'id': '1', 'security_groups': 'default'}
349 349
 
350
-        with mock.patch(NFVSWBRIDGE + '.get_vif_port_by_id',
350
+        with mock.patch(NFV_SW_BRIDGE + '.get_vif_port_by_id',
351 351
                         return_value=False) as get_vif:
352 352
             self.mock_port_update(port=port)
353 353
 
@@ -357,7 +357,7 @@ class TestRestProxyAgentNFVSwitch(TestRestProxyAgentOVS):
357 357
     def test_port_update_without_secgroup(self):
358 358
         port = {'id': '1'}
359 359
 
360
-        with mock.patch(NFVSWBRIDGE + '.get_vif_port_by_id',
360
+        with mock.patch(NFV_SW_BRIDGE + '.get_vif_port_by_id',
361 361
                         return_value=False) as get_vif:
362 362
             self.mock_port_update(port=port)
363 363
 
@@ -367,7 +367,7 @@ class TestRestProxyAgentNFVSwitch(TestRestProxyAgentOVS):
367 367
     def test_port_update(self):
368 368
         port = {'id': '1', 'security_groups': 'default'}
369 369
 
370
-        with mock.patch(NFVSWBRIDGE + '.get_vif_port_by_id',
370
+        with mock.patch(NFV_SW_BRIDGE + '.get_vif_port_by_id',
371 371
                         return_value=False) as get_vif:
372 372
             self.mock_port_update(port=port)
373 373
 

+ 15
- 15
networking_bigswitch/tests/unit/bigswitch/test_restproxy_plugin.py View File

@@ -15,9 +15,7 @@
15 15
 # limitations under the License.
16 16
 
17 17
 import mock
18
-from oslo_config import cfg
19
-import webob.exc
20
-
18
+from mock import patch
21 19
 from neutron.tests.unit import _test_extension_portbindings as test_bindings
22 20
 from neutron.tests.unit.api.v2 import test_base
23 21
 from neutron.tests.unit.db import test_allowedaddresspairs_db as test_addr_pair
@@ -26,20 +24,20 @@ from neutron_lib.api.definitions import portbindings
26 24
 from neutron_lib import constants
27 25
 from neutron_lib import context
28 26
 from neutron_lib.plugins import directory
27
+from oslo_config import cfg
28
+import webob.exc
29 29
 
30 30
 from networking_bigswitch.plugins.bigswitch import config as pl_config
31 31
 from networking_bigswitch.plugins.bigswitch import constants as bsn_constants
32
-from networking_bigswitch.plugins.bigswitch.servermanager import\
32
+from networking_bigswitch.plugins.bigswitch.servermanager import \
33 33
     TenantIDNotFound
34 34
 from networking_bigswitch.tests.unit.bigswitch import fake_server
35 35
 from networking_bigswitch.tests.unit.bigswitch \
36 36
     import test_base as bsn_test_base
37 37
 
38
-patch = mock.patch
39
-HTTPCON = ('networking_bigswitch.plugins.bigswitch.servermanager.httplib'
40
-           '.HTTPConnection')
41
-IS_UNICODE_ENABLED = ('networking_bigswitch.plugins.bigswitch.servermanager.'
42
-                      'ServerPool.is_unicode_enabled')
38
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import HTTPCON
39
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
40
+    IS_UNICODE_ENABLED
43 41
 
44 42
 
45 43
 class BigSwitchProxyPluginV2TestCase(bsn_test_base.BigSwitchTestBase,
@@ -60,10 +58,11 @@ class BigSwitchProxyPluginV2TestCase(bsn_test_base.BigSwitchTestBase,
60 58
             service_plugins.update(bsn_service_plugins)
61 59
         else:
62 60
             service_plugins = bsn_service_plugins
63
-        super(BigSwitchProxyPluginV2TestCase,
64
-              self).setUp(self._plugin_name,
65
-                          service_plugins=service_plugins,
66
-                          ext_mgr=ext_mgr)
61
+
62
+        test_plugin.NeutronDbPluginV2TestCase.setUp(
63
+            self, self._plugin_name,
64
+            service_plugins=service_plugins,
65
+            ext_mgr=ext_mgr)
67 66
 
68 67
         self.port_create_status = 'BUILD'
69 68
         self.startHttpPatch()
@@ -108,7 +107,7 @@ class TestBigSwitchProxyPortsV2(test_plugin.TestPortsV2,
108 107
         with self.port(name='test'):
109 108
             ports = directory.get_plugin().get_ports(
110 109
                 context.get_admin_context(), fields=['name'])
111
-            self.assertEqual(['name'], ports[0].keys())
110
+            self.assertEqual(['name'], list(ports[0].keys()))
112 111
 
113 112
     def test_router_port_status_active(self):
114 113
         # router ports screw up port auto-deletion so it has to be
@@ -217,8 +216,9 @@ class TestBigSwitchProxyPortsV2(test_plugin.TestPortsV2,
217 216
             self.subnet() as s,\
218 217
             patch(HTTPCON, create=True,
219 218
                   new=fake_server.HTTPConnectionMock404),\
220
-            patch(bsn_test_base.RESTPROXY_PKG_PATH +
219
+            patch(bsn_test_base.PLUGIN_PATH +
221 220
                   '.NeutronRestProxyV2._send_all_data') as mock_send_all:
221
+
222 222
             with self.port(subnet=s, device_id='somedevid') as p:
223 223
                 # wait for the async port thread to finish
224 224
                 plugin = directory.get_plugin()

+ 13
- 13
networking_bigswitch/tests/unit/bigswitch/test_router_db.py View File

@@ -15,6 +15,12 @@
15 15
 # Adapted from neutron.tests.unit.extensions,test_l3
16 16
 
17 17
 import mock
18
+from neutron.extensions import l3
19
+from neutron.tests.unit.api.v2 import test_base
20
+from neutron.tests.unit.extensions import test_extra_dhcp_opt as test_dhcpopts
21
+from neutron.tests.unit.extensions import test_l3 as test_l3
22
+from neutron_lib import context
23
+from neutron_lib.plugins import directory
18 24
 from oslo_config import cfg
19 25
 from oslo_serialization import jsonutils
20 26
 from oslo_utils import uuidutils
@@ -24,16 +30,9 @@ from networking_bigswitch.plugins.bigswitch.db import tenant_policy_db  # noqa
24 30
 from networking_bigswitch.tests.unit.bigswitch import fake_server
25 31
 from networking_bigswitch.tests.unit.bigswitch \
26 32
     import test_base as bsn_test_base
27
-from neutron.extensions import l3
28
-from neutron.tests.unit.api.v2 import test_base
29
-from neutron.tests.unit.extensions import test_extra_dhcp_opt as test_dhcpopts
30
-from neutron.tests.unit.extensions import test_l3 as test_l3
31
-from neutron_lib import context
32
-from neutron_lib.plugins import directory
33 33
 
34
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import HTTPCON
34 35
 
35
-HTTPCON = ('networking_bigswitch.plugins.bigswitch.servermanager.httplib'
36
-           '.HTTPConnection')
37 36
 _uuid = uuidutils.generate_uuid
38 37
 
39 38
 
@@ -55,8 +54,7 @@ class DHCPOptsTestCase(bsn_test_base.BigSwitchTestBase,
55 54
     def setUp(self, plugin=None):
56 55
         self.setup_patches()
57 56
         self.setup_config_files()
58
-        super(test_dhcpopts.ExtraDhcpOptDBTestCase,
59
-              self).setUp(plugin=self._plugin_name)
57
+        test_dhcpopts.TestExtraDhcpOpt.setUp(self, plugin=self._plugin_name)
60 58
         self.setup_db()
61 59
         self.startHttpPatch()
62 60
 
@@ -72,9 +70,11 @@ class RouterDBTestBase(bsn_test_base.BigSwitchTestBase,
72 70
         self.setup_config_files()
73 71
         ext_mgr = RouterRulesTestExtensionManager()
74 72
         service_plugins = {'L3_ROUTER_NAT': self._l3_plugin_name}
75
-        super(RouterDBTestBase, self).setUp(plugin=self._plugin_name,
76
-                                            ext_mgr=ext_mgr,
77
-                                            service_plugins=service_plugins)
73
+        test_l3.L3BaseForIntTests.setUp(self,
74
+                                        plugin=self._plugin_name,
75
+                                        ext_mgr=ext_mgr,
76
+                                        service_plugins=service_plugins)
77
+
78 78
         self.setup_db()
79 79
         cfg.CONF.set_default('allow_overlapping_ips', False)
80 80
         self.plugin_obj = directory.get_plugin('L3_ROUTER_NAT')

+ 2
- 2
networking_bigswitch/tests/unit/bigswitch/test_security_groups.py View File

@@ -23,14 +23,14 @@ from networking_bigswitch.tests.unit.bigswitch import test_base
23 23
 class RestProxySecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase,
24 24
                                       test_base.BigSwitchTestBase):
25 25
     plugin_str = ('%s.NeutronRestProxyV2' %
26
-                  test_base.RESTPROXY_PKG_PATH)
26
+                  test_base.PLUGIN_PATH)
27 27
 
28 28
     def setUp(self, plugin=None):
29 29
         test_sg_rpc.set_firewall_driver(test_sg_rpc.FIREWALL_HYBRID_DRIVER)
30 30
         self.setup_config_files()
31 31
         self.setup_patches()
32 32
         self._attribute_map_bk_ = {}
33
-        super(RestProxySecurityGroupsTestCase, self).setUp(self.plugin_str)
33
+        test_sg.SecurityGroupDBTestCase.setUp(self, self.plugin_str)
34 34
         self.setup_db()
35 35
         plugin = directory.get_plugin()
36 36
         self.notifier = plugin.notifier

+ 69
- 127
networking_bigswitch/tests/unit/bigswitch/test_servermanager.py View File

@@ -11,40 +11,55 @@
11 11
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 12
 #    License for the specific language governing permissions and limitations
13 13
 #    under the License.
14
-import httplib
14
+
15 15
 import socket
16
-import ssl
17 16
 import time
18 17
 
19 18
 import mock
19
+from neutron_lib.plugins import directory
20 20
 from oslo_config import cfg
21 21
 from oslo_db import exception as db_exc
22 22
 from oslo_utils import importutils
23
+from six.moves import http_client
23 24
 
24 25
 from networking_bigswitch.plugins.bigswitch.db import consistency_db
25 26
 from networking_bigswitch.plugins.bigswitch import servermanager
26 27
 from networking_bigswitch.tests.unit.bigswitch \
27 28
     import test_restproxy_plugin as test_rp
28
-from neutron_lib.plugins import directory
29 29
 
30
-SERVERMANAGER = 'networking_bigswitch.plugins.bigswitch.servermanager'
31
-CONSISTENCYDB = 'networking_bigswitch.plugins.bigswitch.db.consistency_db'
32
-HTTPCON = SERVERMANAGER + '.httplib.HTTPConnection'
33
-HTTPSCON = SERVERMANAGER + '.HTTPSConnectionWithValidation'
34
-SERVER_GET_CAPABILITIES = SERVERMANAGER + '.ServerPool.get_capabilities'
30
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import CERT_COMBINER
31
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import CONSISTENCY_DB
32
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
33
+    GET_SERVER_CERTIFICATE
34
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import HTTPCON
35
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import HTTPSCON
36
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
37
+    POOL_GET_CAPABILITIES
38
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
39
+    POOL_REST_ACTION
40
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
41
+    POOL_REST_CALL
42
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
43
+    POOL_TOPO_SYNC
44
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
45
+    POOL_UPDATE_TENANT_CACHE
46
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import SERVER_MANAGER
47
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
48
+    SERVER_REST_CALL
35 49
 
36 50
 
37 51
 class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
38 52
 
39 53
     def setUp(self):
40 54
         self.socket_mock = mock.patch(
41
-            SERVERMANAGER + '.socket.create_connection').start()
42
-        self.wrap_mock = mock.patch(SERVERMANAGER + '.ssl.wrap_socket').start()
55
+            SERVER_MANAGER + '.socket.create_connection').start()
56
+        self.wrap_mock = mock.patch(SERVER_MANAGER +
57
+                                    '.ssl.wrap_socket').start()
43 58
         super(ServerManagerTests, self).setUp()
44 59
         # http patch must not be running or it will mangle the servermanager
45 60
         # import where the https connection classes are defined
46 61
         self.httpPatch.stop()
47
-        self.sm = importutils.import_module(SERVERMANAGER)
62
+        self.sm = importutils.import_module(SERVER_MANAGER)
48 63
 
49 64
     def test_no_servers(self):
50 65
         cfg.CONF.set_override('servers', [], 'RESTPROXY')
@@ -64,18 +79,17 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
64 79
 
65 80
     def test_sticky_cert_fetch_fail(self):
66 81
         pl = directory.get_plugin()
67
-        pl.servers.ssl = True
68
-        with mock.patch(
69
-            'ssl.get_server_certificate',
70
-            side_effect=Exception('There is no more entropy in the universe')
71
-        ) as sslgetmock:
82
+        pl.servers.is_ssl_enabled = True
83
+
84
+        with mock.patch(GET_SERVER_CERTIFICATE,
85
+                        side_effect=Exception('There is no more entropy in the'
86
+                                              'universe')) as sslgetmock:
72 87
             self.assertRaises(
73 88
                 cfg.Error,
74 89
                 pl.servers._get_combined_cert_for_server,
75 90
                 *('example.org', 443)
76 91
             )
77
-            sslgetmock.assert_has_calls([mock.call(
78
-                ('example.org', 443), ssl_version=ssl.PROTOCOL_SSLv23)])
92
+            sslgetmock.assert_has_calls([mock.call(('example.org', 443))])
79 93
 
80 94
     def test_consistency_watchdog_stops_with_0_polling_interval(self):
81 95
         pl = directory.get_plugin()
@@ -93,12 +107,12 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
93 107
 
94 108
         with mock.patch('eventlet.sleep') as smock,\
95 109
                 mock.patch(
96
-                    SERVERMANAGER + '.ServerPool.rest_call',
110
+                    POOL_REST_CALL,
97 111
                     side_effect=servermanager.RemoteRestError(
98 112
                         reason='Failure to trigger except clause.'))\
99 113
                 as rmock,\
100 114
                 mock.patch(
101
-                    SERVERMANAGER + '.LOG.exception',
115
+                    SERVER_MANAGER + '.LOG.exception',
102 116
                     side_effect=KeyError('Failure to break loop'))\
103 117
                 as lmock:
104 118
             # should return immediately without consistency capability
@@ -113,7 +127,7 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
113 127
 
114 128
     def test_file_put_contents(self):
115 129
         pl = directory.get_plugin()
116
-        with mock.patch(SERVERMANAGER + '.open', create=True) as omock:
130
+        with mock.patch(SERVER_MANAGER + '.open', create=True) as omock:
117 131
             pl.servers._file_put_contents('somepath', 'contents')
118 132
             omock.assert_has_calls([mock.call('somepath', 'w')])
119 133
             omock.return_value.__enter__.return_value.assert_has_calls([
@@ -122,7 +136,7 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
122 136
 
123 137
     def test_combine_certs_to_file(self):
124 138
         pl = directory.get_plugin()
125
-        with mock.patch(SERVERMANAGER + '.open', create=True) as omock:
139
+        with mock.patch(SERVER_MANAGER + '.open', create=True) as omock:
126 140
             omock.return_value.__enter__().read.return_value = 'certdata'
127 141
             pl.servers._combine_certs_to_file(['cert1.pem', 'cert2.pem'],
128 142
                                               'combined.pem')
@@ -239,7 +253,7 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
239 253
             self.assertEqual(resp, (0, None, None, None))
240 254
         # verify same behavior on ssl class
241 255
         sp.servers[0].currentcon = False
242
-        sp.servers[0].ssl = True
256
+        sp.servers[0].is_ssl_enabled = True
243 257
         with mock.patch(HTTPSCON, return_value=None):
244 258
             resp = sp.servers[0].rest_call('GET', '/')
245 259
             self.assertEqual(resp, (0, None, None, None))
@@ -256,7 +270,7 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
256 270
             sp.servers[0].rest_call('GET', '/first')
257 271
             # raise an error on re-use to verify reconnect
258 272
             # return okay the second time so the reconnect works
259
-            rv.request.side_effect = [httplib.ImproperConnectionState(),
273
+            rv.request.side_effect = [http_client.ImproperConnectionState(),
260 274
                                       mock.MagicMock()]
261 275
             sp.servers[0].rest_call('GET', '/second')
262 276
         uris = [c[1][1] for c in rv.request.mock_calls]
@@ -282,8 +296,8 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
282 296
             sp.servers[0].rest_call('GET', '/first')
283 297
             # after retrying once, the rest call should raise the
284 298
             # exception up
285
-            rv.request.side_effect = httplib.ImproperConnectionState()
286
-            self.assertRaises(httplib.ImproperConnectionState,
299
+            rv.request.side_effect = http_client.ImproperConnectionState()
300
+            self.assertRaises(http_client.ImproperConnectionState,
287 301
                               sp.servers[0].rest_call,
288 302
                               *('GET', '/second'))
289 303
             # 1 for the first call, 2 for the second with retry
@@ -298,7 +312,7 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
298 312
 
299 313
     def test_cert_get_fail(self):
300 314
         pl = directory.get_plugin()
301
-        pl.servers.ssl = True
315
+        pl.servers.is_ssl_enabled = True
302 316
         with mock.patch('os.path.exists', return_value=False):
303 317
             self.assertRaises(cfg.Error,
304 318
                               pl.servers._get_combined_cert_for_server,
@@ -306,16 +320,14 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
306 320
 
307 321
     def test_cert_make_dirs(self):
308 322
         pl = directory.get_plugin()
309
-        pl.servers.ssl = True
323
+        pl.servers.is_ssl_enabled = True
310 324
         cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY')
311 325
         # pretend base dir exists, 3 children don't, and host cert does
312 326
         with mock.patch('os.path.exists',
313 327
                         side_effect=[True, False, False,
314 328
                                      False, True]) as exmock,\
315 329
                 mock.patch('os.makedirs') as makemock,\
316
-                mock.patch(
317
-                    SERVERMANAGER + '.ServerPool._combine_certs_to_file')\
318
-                as combmock:
330
+                mock.patch(CERT_COMBINER) as combmock:
319 331
             # will raise error because no certs found
320 332
             self.assertIn(
321 333
                 'example.org',
@@ -330,7 +342,7 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
330 342
 
331 343
     def test_no_cert_error(self):
332 344
         pl = directory.get_plugin()
333
-        pl.servers.ssl = True
345
+        pl.servers.is_ssl_enabled = True
334 346
         cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY')
335 347
         # pretend base dir exists and 3 children do, but host cert doesn't
336 348
         with mock.patch(
@@ -358,10 +370,10 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
358 370
 
359 371
     def test_retry_on_unavailable(self):
360 372
         pl = directory.get_plugin()
361
-        with mock.patch(SERVERMANAGER + '.ServerProxy.rest_call',
362
-                        return_value=(httplib.SERVICE_UNAVAILABLE,
373
+        with mock.patch(SERVER_REST_CALL,
374
+                        return_value=(http_client.SERVICE_UNAVAILABLE,
363 375
                                       0, 0, 0)) as srestmock,\
364
-                mock.patch(SERVERMANAGER + '.eventlet.sleep') as tmock:
376
+                mock.patch(SERVER_MANAGER + '.eventlet.sleep') as tmock:
365 377
             # making a call should trigger retries with sleeps in between
366 378
             pl.servers.rest_call('GET', '/', '', None, [])
367 379
             rest_call = [mock.call('GET', '/', '', None, False,
@@ -377,10 +389,10 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
377 389
 
378 390
     def test_delete_failure_forces_topo_sync(self):
379 391
         pl = directory.get_plugin()
380
-        with mock.patch(SERVERMANAGER + '.ServerProxy.rest_call',
381
-                        return_value=(httplib.INTERNAL_SERVER_ERROR,
392
+        with mock.patch(SERVER_REST_CALL,
393
+                        return_value=(http_client.INTERNAL_SERVER_ERROR,
382 394
                                       0, 0, 0)), \
383
-                mock.patch(SERVERMANAGER + '.ServerPool.force_topo_sync',
395
+                mock.patch(POOL_TOPO_SYNC,
384 396
                            return_value=(False,
385 397
                                          servermanager.TOPO_RESPONSE_OK)) \
386 398
                 as topo_mock:
@@ -396,10 +408,10 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
396 408
 
397 409
     def test_post_failure_forces_topo_sync(self):
398 410
         pl = directory.get_plugin()
399
-        with mock.patch(SERVERMANAGER + '.ServerProxy.rest_call',
400
-                        return_value=(httplib.INTERNAL_SERVER_ERROR,
411
+        with mock.patch(SERVER_REST_CALL,
412
+                        return_value=(http_client.INTERNAL_SERVER_ERROR,
401 413
                                       0, 0, 0)), \
402
-                mock.patch(SERVERMANAGER + '.ServerPool.force_topo_sync',
414
+                mock.patch(POOL_TOPO_SYNC,
403 415
                            return_value=(False,
404 416
                                          servermanager.TOPO_RESPONSE_OK)) \
405 417
                 as topo_mock:
@@ -414,10 +426,10 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
414 426
 
415 427
     def test_topo_sync_failure_does_not_force_topo_sync(self):
416 428
         pl = directory.get_plugin()
417
-        with mock.patch(SERVERMANAGER + '.ServerProxy.rest_call',
418
-                        return_value=(httplib.INTERNAL_SERVER_ERROR,
429
+        with mock.patch(SERVER_REST_CALL,
430
+                        return_value=(http_client.INTERNAL_SERVER_ERROR,
419 431
                                       0, 0, 0)), \
420
-                mock.patch(SERVERMANAGER + '.ServerPool.force_topo_sync',
432
+                mock.patch(POOL_TOPO_SYNC,
421 433
                            return_value=(False,
422 434
                                          servermanager.TOPO_RESPONSE_OK)) \
423 435
                 as topo_mock:
@@ -436,8 +448,8 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
436 448
         pl.servers.get_topo_function = None
437 449
         with \
438 450
             mock.patch(
439
-                SERVERMANAGER + '.ServerProxy.rest_call',
440
-                return_value=(httplib.NOT_FOUND, 0, 0, 0)):
451
+                SERVER_REST_CALL,
452
+                return_value=(http_client.NOT_FOUND, 0, 0, 0)):
441 453
             # making a call should trigger a conflict sync that will
442 454
             # error without the topology function set
443 455
             self.assertRaises(
@@ -449,10 +461,10 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
449 461
     def test_no_sync_without_keystone(self):
450 462
         pl = directory.get_plugin()
451 463
         with\
452
-            mock.patch(SERVERMANAGER + '.ServerPool._update_tenant_cache',
453
-                       return_value=(False)),\
454
-            mock.patch(SERVERMANAGER + '.ServerProxy.rest_call',
455
-                       return_value=(httplib.CONFLICT, 0, 0, 0)) as srestmock:
464
+            mock.patch(POOL_UPDATE_TENANT_CACHE, return_value=(False)),\
465
+            mock.patch(SERVER_REST_CALL,
466
+                       return_value=(http_client.CONFLICT, 0, 0,
467
+                                     0)) as srestmock:
456 468
             # making a call should trigger a conflict sync
457 469
             pl.servers.rest_call('GET', '/', '', None, [])
458 470
             srestmock.assert_called_once_with(
@@ -460,9 +472,8 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
460 472
 
461 473
     def test_no_send_all_data_without_keystone(self):
462 474
         pl = directory.get_plugin()
463
-        with mock.patch(SERVERMANAGER + '.ServerPool._update_tenant_cache',
464
-                        return_value=(False)), \
465
-            mock.patch(SERVERMANAGER + '.ServerPool.force_topo_sync',
475
+        with mock.patch(POOL_UPDATE_TENANT_CACHE, return_value=(False)), \
476
+            mock.patch(POOL_TOPO_SYNC,
466 477
                        return_value=(False, servermanager.TOPO_RESPONSE_OK)) \
467 478
                 as tmock:
468 479
             # making a call should trigger a conflict sync
@@ -471,7 +482,7 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
471 482
 
472 483
     def test_floating_calls(self):
473 484
         pl = directory.get_plugin()
474
-        with mock.patch(SERVERMANAGER + '.ServerPool.rest_action') as ramock:
485
+        with mock.patch(POOL_REST_ACTION) as ramock:
475 486
             body1 = {'id': 'somefloat'}
476 487
             body2 = {'name': 'myfl'}
477 488
             pl.servers.rest_create_floatingip('tenant', body1)
@@ -488,58 +499,6 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
488 499
                           errstr=u'Unable to delete floating IP: %s')
489 500
             ])
490 501
 
491
-    def test_HTTPSConnectionWithValidation_without_cert(self):
492
-        con = self.sm.HTTPSConnectionWithValidation(
493
-            'www.example.org', 443, timeout=90)
494
-        con.source_address = '127.0.0.1'
495
-        con.request("GET", "/")
496
-        self.socket_mock.assert_has_calls([mock.call(
497
-            ('www.example.org', 443), 90, '127.0.0.1'
498
-        )])
499
-        self.wrap_mock.assert_has_calls([mock.call(
500
-            self.socket_mock(), None, None, cert_reqs=ssl.CERT_NONE,
501
-            ssl_version=ssl.PROTOCOL_SSLv23
502
-        )])
503
-        self.assertEqual(con.sock, self.wrap_mock())
504
-
505
-    def test_HTTPSConnectionWithValidation_with_cert(self):
506
-        con = self.sm.HTTPSConnectionWithValidation(
507
-            'www.example.org', 443, timeout=90)
508
-        con.combined_cert = 'SOMECERTS.pem'
509
-        con.source_address = '127.0.0.1'
510
-        con.request("GET", "/")
511
-        self.socket_mock.assert_has_calls([mock.call(
512
-            ('www.example.org', 443), 90, '127.0.0.1'
513
-        )])
514
-        self.wrap_mock.assert_has_calls([mock.call(
515
-            self.socket_mock(), None, None, ca_certs='SOMECERTS.pem',
516
-            cert_reqs=ssl.CERT_REQUIRED,
517
-            ssl_version=ssl.PROTOCOL_SSLv23
518
-        )])
519
-        self.assertEqual(con.sock, self.wrap_mock())
520
-
521
-    def test_HTTPSConnectionWithValidation_tunnel(self):
522
-        tunnel_mock = mock.patch.object(
523
-            self.sm.HTTPSConnectionWithValidation,
524
-            '_tunnel').start()
525
-        con = self.sm.HTTPSConnectionWithValidation(
526
-            'www.example.org', 443, timeout=90)
527
-        con.source_address = '127.0.0.1'
528
-        con.set_tunnel('myproxy.local', 3128)
529
-        con.request("GET", "/")
530
-        self.socket_mock.assert_has_calls([mock.call(
531
-            ('www.example.org', 443), 90, '127.0.0.1'
532
-        )])
533
-        self.wrap_mock.assert_has_calls([mock.call(
534
-            self.socket_mock(), None, None, cert_reqs=ssl.CERT_NONE,
535
-            ssl_version=ssl.PROTOCOL_SSLv23
536
-        )])
537
-        # _tunnel() doesn't take any args
538
-        tunnel_mock.assert_has_calls([mock.call()])
539
-        self.assertEqual(con._tunnel_host, 'myproxy.local')
540
-        self.assertEqual(con._tunnel_port, 3128)
541
-        self.assertEqual(con.sock, self.wrap_mock())
542
-
543 502
     def test_is_unicode_enabled(self):
544 503
         """Verify that unicode is enabled only when both conditions are True:
545 504
 
@@ -557,11 +516,11 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
557 516
             return ['dummy']
558 517
 
559 518
         patch_supported = mock.patch(
560
-            SERVER_GET_CAPABILITIES,
519
+            POOL_GET_CAPABILITIES,
561 520
             side_effect=capability_unicode_supported)
562 521
 
563 522
         patch_unsupported = mock.patch(
564
-            SERVER_GET_CAPABILITIES,
523
+            POOL_GET_CAPABILITIES,
565 524
             side_effect=capability_unicode_unsupported)
566 525
 
567 526
         # Create a server pool with default naming_scheme_unicode
@@ -594,23 +553,6 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
594 553
         patch_unsupported.stop()
595 554
 
596 555
 
597
-class TestSockets(test_rp.BigSwitchProxyPluginV2TestCase):
598
-
599
-    def setUp(self):
600
-        super(TestSockets, self).setUp()
601
-        # http patch must not be running or it will mangle the servermanager
602
-        # import where the https connection classes are defined
603
-        self.httpPatch.stop()
604
-        self.sm = importutils.import_module(SERVERMANAGER)
605
-
606
-    def test_socket_create_attempt(self):
607
-        # exercise the socket creation to make sure it works on both python
608
-        # versions
609
-        con = self.sm.HTTPSConnectionWithValidation('127.0.0.1', 0, timeout=1)
610
-        # if httpcon was created, a connect attempt should raise a socket error
611
-        self.assertRaises(socket.error, con.connect)
612
-
613
-
614 556
 class HashLockingTests(test_rp.BigSwitchProxyPluginV2TestCase):
615 557
 
616 558
     def _get_hash_from_handler_db(self, handler):
@@ -669,7 +611,7 @@ class HashLockingTests(test_rp.BigSwitchProxyPluginV2TestCase):
669 611
         hh2_ts_hh1_ts_plus_1780 = float(handler1.lock_ts) + 1780
670 612
         handler2 = consistency_db.HashHandler(
671 613
             hash_id='1', timestamp_ms=hh2_ts_hh1_ts_plus_1780)
672
-        with mock.patch(CONSISTENCYDB + '.eventlet.sleep',
614
+        with mock.patch(CONSISTENCY_DB + '.eventlet.sleep',
673 615
                         side_effect=[Exception]) as emock:
674 616
             try:
675 617
                 handler2.lock(check_ts=False)
@@ -755,7 +697,7 @@ class HashLockingTests(test_rp.BigSwitchProxyPluginV2TestCase):
755 697
         handler2 = consistency_db.HashHandler()
756 698
 
757 699
         with mock.patch.object(handler2._FACADE, 'get_engine') as ge, \
758
-                mock.patch(CONSISTENCYDB + '.eventlet.sleep',
700
+                mock.patch(CONSISTENCY_DB + '.eventlet.sleep',
759 701
                            side_effect=[None]) as emock:
760 702
             conn = ge.return_value.begin.return_value.__enter__.return_value
761 703
             firstresult = mock.Mock()

+ 38
- 157
networking_bigswitch/tests/unit/bigswitch/test_ssl.py View File

@@ -12,38 +12,33 @@
12 12
 #    License for the specific language governing permissions and limitations
13 13
 #    under the License.
14 14
 import os
15
-import ssl
16 15
 
17 16
 import mock
18
-from oslo_config import cfg
19
-from oslo_log import log as logging
20
-import webob.exc
21
-
22 17
 from neutron.tests.unit.api.v2 import test_base
23 18
 from neutron.tests.unit.db import test_db_base_plugin_v2 as test_plugin
19
+from oslo_config import cfg
20
+from oslo_log import log as logging
24 21
 
25
-from networking_bigswitch.tests.unit.bigswitch import fake_server
26 22
 from networking_bigswitch.tests.unit.bigswitch \
27 23
     import test_base as bsn_test_base
28 24
 
29
-LOG = logging.getLogger(__name__)
25
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import CERT_COMBINER
26
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import FILE_PUT
27
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import GET_CA_CERTS
28
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
29
+    GET_SERVER_CERTIFICATE
30
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import HTTPSCON
31
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import \
32
+    SSL_CREATE_DEFAULT_CONTEXT
30 33
 
31
-SERVERMANAGER = 'networking_bigswitch.plugins.bigswitch.servermanager'
32
-HTTPS = SERVERMANAGER + '.HTTPSConnectionWithValidation'
33
-CERTCOMBINER = SERVERMANAGER + '.ServerPool._combine_certs_to_file'
34
-FILEPUT = SERVERMANAGER + '.ServerPool._file_put_contents'
35
-GETCACERTS = SERVERMANAGER + '.ServerPool._get_ca_cert_paths'
36
-GETHOSTCERT = SERVERMANAGER + '.ServerPool._get_host_cert_path'
37
-SSLGETCERT = SERVERMANAGER + '.ssl.get_server_certificate'
38
-FAKECERTGET = ('networking_bigswitch.tests.unit.bigswitch.fake_server'
39
-               '.get_cert_contents')
34
+LOG = logging.getLogger(__name__)
40 35
 
41 36
 
42 37
 class test_ssl_certificate_base(test_plugin.NeutronDbPluginV2TestCase,
43 38
                                 bsn_test_base.BigSwitchTestBase):
44 39
 
45 40
     plugin_str = ('%s.NeutronRestProxyV2' %
46
-                  bsn_test_base.RESTPROXY_PKG_PATH)
41
+                  bsn_test_base.PLUGIN_PATH)
47 42
     servername = None
48 43
     cert_base = None
49 44
 
@@ -70,20 +65,17 @@ class test_ssl_certificate_base(test_plugin.NeutronDbPluginV2TestCase,
70 65
         self.setup_patches()
71 66
 
72 67
         # Mock method SSL lib uses to grab cert from server
73
-        self.sslgetcert_m = mock.patch(SSLGETCERT, create=True).start()
68
+        self.sslgetcert_m = mock.patch(GET_SERVER_CERTIFICATE,
69
+                                       create=True).start()
74 70
         self.sslgetcert_m.return_value = self.host_cert_val
75 71
 
76 72
         # Mock methods that write and read certs from the file-system
77
-        self.fileput_m = mock.patch(FILEPUT, create=True).start()
78
-        self.certcomb_m = mock.patch(CERTCOMBINER, create=True).start()
79
-        self.getcacerts_m = mock.patch(GETCACERTS, create=True).start()
80
-
81
-        # this is used to configure what certificate contents the fake HTTPS
82
-        # lib should expect to receive
83
-        self.fake_certget_m = mock.patch(FAKECERTGET, create=True).start()
73
+        self.fileput_m = mock.patch(FILE_PUT, create=True).start()
74
+        self.certcomb_m = mock.patch(CERT_COMBINER, create=True).start()
75
+        self.getcacerts_m = mock.patch(GET_CA_CERTS, create=True).start()
84 76
 
85 77
     def setUp(self):
86
-        super(test_ssl_certificate_base, self).setUp(self.plugin_str)
78
+        test_plugin.NeutronDbPluginV2TestCase.setUp(self, self.plugin_str)
87 79
         self.setup_db()
88 80
 
89 81
 
@@ -94,155 +86,44 @@ class TestSslSticky(test_ssl_certificate_base):
94 86
         cfg.CONF.set_override('server_ssl', True, 'RESTPROXY')
95 87
         cfg.CONF.set_override('ssl_sticky', True, 'RESTPROXY')
96 88
         self._setUp()
97
-        # Set fake HTTPS connection's expectation
98
-        self.fake_certget_m.return_value = self.host_cert_val
89
+        # # Set fake HTTPS connection's expectation
90
+        # self.fake_certget_m.return_value = self.host_cert_val
99 91
         # No CA certs for this test
100 92
         self.getcacerts_m.return_value = []
93
+
94
+        self.ssl_create_default_context_m = mock.patch(
95
+            SSL_CREATE_DEFAULT_CONTEXT,
96
+            create=True).start()
101 97
         super(TestSslSticky, self).setUp()
102 98
 
103 99
     def test_sticky_cert(self):
100
+        """Test certificate is stored, and https connection is used
101
+
102
+        :return:
103
+        """
104 104
         # SSL connection should be successful and cert should be cached
105
-        with mock.patch(HTTPS, new=fake_server.HTTPSHostValidation),\
106
-                self.network():
105
+        with mock.patch(HTTPSCON) as https_mock, self.network():
107 106
             # CA certs should have been checked for
108 107
             self.getcacerts_m.assert_has_calls([mock.call(self.ca_certs_path)])
109 108
             # cert should have been fetched via SSL lib
110 109
             self.sslgetcert_m.assert_has_calls(
111
-                [mock.call((self.servername, 443),
112
-                           ssl_version=ssl.PROTOCOL_SSLv23)]
110
+                [mock.call((self.servername, 443))]
113 111
             )
114 112
 
115 113
             # cert should have been recorded
116 114
             self.fileput_m.assert_has_calls([mock.call(self.host_cert_path,
117 115
                                                        self.host_cert_val)])
118
-            # no ca certs, so host cert only for this combined cert
119
-            self.certcomb_m.assert_has_calls([mock.call([self.host_cert_path],
120
-                                                        self.comb_cert_path)])
121 116
 
122
-
123
-class TestSslHostCert(test_ssl_certificate_base):
124
-
125
-    def setUp(self):
126
-        self.setup_config_files()
127
-        cfg.CONF.set_override('server_ssl', True, 'RESTPROXY')
128
-        cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY')
129
-        self.httpsPatch = mock.patch(HTTPS, create=True,
130
-                                     new=fake_server.HTTPSHostValidation)
131
-        self.httpsPatch.start()
132
-        self._setUp()
133
-        # Set fake HTTPS connection's expectation
134
-        self.fake_certget_m.return_value = self.host_cert_val
135
-        # No CA certs for this test
136
-        self.getcacerts_m.return_value = []
137
-        # Pretend host cert exists
138
-        self.hcertpath_p = mock.patch(GETHOSTCERT,
139
-                                      return_value=(self.host_cert_path, True),
140
-                                      create=True).start()
141
-        super(TestSslHostCert, self).setUp()
142
-
143
-    def test_host_cert(self):
144
-        # SSL connection should be successful because of pre-configured cert
145
-        with self.network():
146
-            self.hcertpath_p.assert_has_calls([
147
-                mock.call(os.path.join(self.cert_base, 'host_certs'),
148
-                          self.servername)
149
-            ])
150
-            # sticky is disabled, no fetching allowed
151
-            self.assertFalse(self.sslgetcert_m.call_count)
152
-            # no ca certs, so host cert is only for this combined cert
117
+            # no ca certs, so host cert only for this combined cert
153 118
             self.certcomb_m.assert_has_calls([mock.call([self.host_cert_path],
154 119
                                                         self.comb_cert_path)])
155 120
 
121
+            # confirm that ssl_context is created
122
+            self.ssl_create_default_context_m.assert_called_once()
156 123
 
157
-class TestSslCaCert(test_ssl_certificate_base):
124
+            # Test HTTPS Connection is used for REST Calls
125
+            https_mock.assert_called_once()
158 126
 
159
-    def setUp(self):
160
-        self.setup_config_files()
161
-        cfg.CONF.set_override('server_ssl', True, 'RESTPROXY')
162
-        cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY')
163
-        self.httpsPatch = mock.patch(HTTPS, create=True,
164
-                                     new=fake_server.HTTPSCAValidation)
165
-        self.httpsPatch.start()
166
-        self._setUp()
167
-
168
-        # pretend to have a few ca certs
169
-        self.getcacerts_m.return_value = ['ca1.pem', 'ca2.pem']
170
-
171
-        # Set fake HTTPS connection's expectation
172
-        self.fake_certget_m.return_value = 'DUMMYCERTIFICATEAUTHORITY'
173
-
174
-        super(TestSslCaCert, self).setUp()
175
-
176
-    def test_ca_cert(self):
177
-        # SSL connection should be successful because CA cert was present
178
-        # If not, attempting to create a network would raise an exception
179
-        with self.network():
180
-            # sticky is disabled, no fetching allowed
181
-            self.assertFalse(self.sslgetcert_m.call_count)
182
-            # 2 CAs and no host cert so combined should only contain both CAs
183
-            self.certcomb_m.assert_has_calls([mock.call(['ca1.pem', 'ca2.pem'],
184
-                                                        self.comb_cert_path)])
185
-
186
-
187
-class TestSslWrongHostCert(test_ssl_certificate_base):
188
-
189
-    def setUp(self):
190
-        self.setup_config_files()
191
-        cfg.CONF.set_override('server_ssl', True, 'RESTPROXY')
192
-        cfg.CONF.set_override('ssl_sticky', True, 'RESTPROXY')
193
-        self._setUp()
194
-
195
-        # Set fake HTTPS connection's expectation to something wrong
196
-        self.fake_certget_m.return_value = 'OTHERCERT'
197
-
198
-        # No CA certs for this test
199
-        self.getcacerts_m.return_value = []
200
-
201
-        # Pretend host cert exists
202
-        self.hcertpath_p = mock.patch(GETHOSTCERT,
203
-                                      return_value=(self.host_cert_path, True),
204
-                                      create=True).start()
205
-        super(TestSslWrongHostCert, self).setUp()
206
-
207
-    def test_error_no_cert(self):
208
-        # since there will already be a host cert, sticky should not take
209
-        # effect and there will be an error because the host cert's contents
210
-        # will be incorrect
211
-        tid = test_base._uuid()
212
-        data = {}
213
-        data['network'] = {'tenant_id': tid, 'name': 'name',
214
-                           'admin_state_up': True}
215
-        with mock.patch(HTTPS, new=fake_server.HTTPSHostValidation):
216
-            req = self.new_create_request('networks', data, 'json')
217
-            res = req.get_response(self.api)
218
-        self.assertEqual(res.status_int,
219
-                         webob.exc.HTTPInternalServerError.code)
220
-        self.hcertpath_p.assert_has_calls([
221
-            mock.call(os.path.join(self.cert_base, 'host_certs'),
222
-                      self.servername)
223
-        ])
224
-        # sticky is enabled, but a host cert already exists so it shant fetch
225
-        self.assertFalse(self.sslgetcert_m.call_count)
226
-        # no ca certs, so host cert only for this combined cert
227
-        self.certcomb_m.assert_has_calls([mock.call([self.host_cert_path],
228
-                                                    self.comb_cert_path)])
229
-
230
-
231
-class TestSslNoValidation(test_ssl_certificate_base):
232
-
233
-    def setUp(self):
234
-        self.setup_config_files()
235
-        cfg.CONF.set_override('server_ssl', True, 'RESTPROXY')
236
-        cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY')
237
-        cfg.CONF.set_override('no_ssl_validation', True, 'RESTPROXY')
238
-        self._setUp()
239
-        super(TestSslNoValidation, self).setUp()
240
-
241
-    def test_validation_disabled(self):
242
-        # SSL connection should be successful without any certificates
243
-        # If not, attempting to create a network will raise an exception
244
-        with mock.patch(HTTPS, new=fake_server.HTTPSNoValidation),\
245
-                self.network():
246
-            # no sticky grabbing and no cert combining with no enforcement
247
-            self.assertFalse(self.sslgetcert_m.call_count)
248
-            self.assertFalse(self.certcomb_m.call_count)
127
+            # confirm that ssl_context is passed
128
+            self.assertTrue(https_mock.
129
+                            call_args_list[0][1].get('context'))

+ 7
- 8
networking_bigswitch/tests/unit/ml2/drivers/test_bigswitch_mech.py View File

@@ -17,8 +17,6 @@
17 17
 import functools
18 18
 
19 19
 import mock
20
-from oslo_serialization import jsonutils
21
-
22 20
 from neutron.conf.plugins.ml2 import config as ml2_config
23 21
 from neutron.db import l3_db
24 22
 from neutron.plugins.ml2.drivers import type_vlan as vlan_config
@@ -32,6 +30,8 @@ from neutron_lib import context as neutron_context
32 30
 from neutron_lib import exceptions as n_exc
33 31
 from neutron_lib.plugins import constants as plugin_constants
34 32
 from neutron_lib.plugins import directory
33
+from oslo_serialization import jsonutils
34
+from oslo_utils import uuidutils
35 35
 
36 36
 from networking_bigswitch.plugins.bigswitch import config as pl_config
37 37
 from networking_bigswitch.plugins.bigswitch import servermanager
@@ -40,18 +40,17 @@ from networking_bigswitch.plugins.ml2.drivers.mech_bigswitch \
40 40
 # from networking_bigswitch.tests.unit.bigswitch.fake_server \
41 41
 #     import HTTPResponseMock
42 42
 import networking_bigswitch.tests.unit.bigswitch.test_restproxy_plugin as trp
43
-from oslo_utils import uuidutils
43
+
44
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import DRIVER
45
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import DRIVER_MOD
46
+# from networking_bigswitch.tests.unit.bigswitch.mock_paths import HTTPCON
47
+from networking_bigswitch.tests.unit.bigswitch.mock_paths import SERVER_POOL
44 48
 
45 49
 _uuid = uuidutils.generate_uuid
46 50
 
47 51
 PHYS_NET = 'physnet1'
48 52
 VLAN_START = 1000
49 53
 VLAN_END = 1100
50
-SERVER_MANAGER = 'networking_bigswitch.plugins.bigswitch.servermanager'
51
-SERVER_POOL = SERVER_MANAGER + '.ServerPool'
52
-DRIVER_MOD = 'networking_bigswitch.plugins.ml2.drivers.mech_bigswitch.driver'
53
-DRIVER = DRIVER_MOD + '.BigSwitchMechanismDriver'
54
-HTTPCON = SERVER_MANAGER + '.httplib.HTTPConnection'
55 54
 
56 55
 
57 56
 class TestBigSwitchMechDriverBase(trp.BigSwitchProxyPluginV2TestCase):

+ 22
- 1
requirements.txt View File

@@ -3,7 +3,28 @@
3 3
 # setup the requirements. If any packages are added that are
4 4
 # specific to bsnstack lib, put them here.
5 5
 
6
-six>=1.10.0 # MIT
6
+alembic>=1.0.0 # MIT
7
+distro>=1.3.0 # Apache-2.0
8
+eventlet>=0.24.1 # MIT
9
+keystoneauth1>=3.11.1 # Apache-2.0
10
+mock>=2.0.0 # BSD
11
+neutron_lib>=1.20.0 # Apache-2.0
12
+os_net_config>=10.0.0 # Apache-2.0
13
+oslo.i18n>=3.22.1 # Apache-2.0
14
+oslo.serialization>=2.28.1 # Apache-2.0
15
+oslo.utils>=3.37.1 # Apache-2.0
16
+oslo_config>=6.7.0 # Apache-2.0
17
+oslo_db>=4.42.0 # Apache-2.0
18
+oslo_log>=3.40.1 # Apache-2.0
19
+oslo_messaging>=9.2.0 # Apache-2.0
20
+oslo_service>=1.33.0 # Apache-2.0
21
+oslotest>=3.7.0 # Apache-2.0
22
+python-keystoneclient>=3.18.0 # Apache-2.0
23
+requests>=2.18.4 # Apache-2.0
24
+setuptools>=18.5 # MIT
25
+six>=1.11.0 # MIT
26
+SQLAlchemy>=1.2.12 # MIT
27
+WebOb>=1.8.4 # MIT
7 28
 
8 29
 # These repos are installed from git in OpenStack CI if the job
9 30
 # configures them as required-projects:

+ 3
- 0
setup.cfg View File

@@ -15,6 +15,9 @@ classifier =
15 15
     Programming Language :: Python
16 16
     Programming Language :: Python :: 2
17 17
     Programming Language :: Python :: 2.7
18
+    Programming Language :: Python :: 3
19
+    Programming Language :: Python :: 3.5
20
+    Programming Language :: Python :: 3.6
18 21
 
19 22
 [files]
20 23
 data_files =

+ 13
- 1
tox.ini View File

@@ -1,5 +1,5 @@
1 1
 [tox]
2
-envlist = py27,pep8
2
+envlist = py36,py35,py27,pep8
3 3
 minversion = 2.0
4 4
 skipsdist = True
5 5
 
@@ -100,6 +100,18 @@ commands =
100 100
     {[testenv:dev]commands}
101 101
     {[testenv]commands}
102 102
 
103
+[testenv:py35-dev]
104
+basepython = python3.5
105
+commands =
106
+    {[testenv:dev]commands}
107
+    {[testenv]commands}
108
+
109
+[testenv:py36-dev]
110
+basepython = python3.6
111
+commands =
112
+    {[testenv:dev]commands}
113
+    {[testenv]commands}
114
+
103 115
 [testenv:pep8-dev]
104 116
 basepython = python3
105 117
 commands =

Loading…
Cancel
Save