Browse Source

fakezhmc: Enforce type for 'port' and 'element-id'

The HMC treates the 'port' attribute of a vswitch as int, but an
adapter ports 'element-id' as str. Both have the same value set.
This is confusing and might lead to problems if not considered
like it happened with bug [1].

This patch makes the fakezhmcclient aware of the different types and
enforces it. All tests that were still using wrong types also needed
aaption.

[1] https://bugs.launchpad.net/networking-dpm/+bug/1673185

Change-Id: Iede6e26a6ef94cac0587ab1ad147409bbb141778
Andreas Scheuring 2 years ago
parent
commit
b69b3ca202

+ 13
- 8
networking_dpm/tests/unit/fake_zhmcclient.py View File

@@ -82,16 +82,15 @@ class _NIC(_BaseObject):
82 82
 
83 83
 class _Port(_BaseObject):
84 84
     def __init__(self, port_json):
85
+        # Ports 'element-id' attribute is of type string, while a
86
+        # vswitchs 'port' attribute is a int
87
+        element_id = port_json.get('element-id')
88
+        if (element_id is not None and
89
+                not isinstance(element_id, str)):
90
+            raise TypeError("Element-id attribute must be of type 'str', but "
91
+                            "is of type '%s'." % type(element_id))
85 92
         super(_Port, self).__init__(port_json)
86 93
 
87
-    def get_property(self, name):
88
-        value = super(_Port, self).get_property(name)
89
-        # TODO(andreas_s) zhmcclient treats element-id as string
90
-        # https://github.com/zhmcclient/python-zhmcclient/issues/125
91
-        if name == 'element-id' and type(value) == int:
92
-            value = str(value)
93
-        return value
94
-
95 94
 
96 95
 class _Adapter(_BaseObject):
97 96
     def __init__(self, adapter_json):
@@ -102,6 +101,12 @@ class _Adapter(_BaseObject):
102 101
 class _VSwitch(_BaseObject):
103 102
     def __init__(self, vswitch_json):
104 103
         self.nics = [_NIC(nic) for nic in vswitch_json.pop('nics', [])]
104
+        # vswitch 'port' attribute is of type int, while an adapter ports
105
+        # 'element-id' is a string
106
+        port = vswitch_json.get('port')
107
+        if port is not None and not isinstance(port, int):
108
+            raise TypeError("Port attribute must be of type 'int', but is of "
109
+                            "type '%s'." % type(port))
105 110
         super(_VSwitch, self).__init__(vswitch_json)
106 111
 
107 112
     def get_connected_nics(self):

+ 8
- 8
networking_dpm/tests/unit/ml2/test_dpm_neutron_agent.py View File

@@ -177,10 +177,10 @@ class TestPhysnetMapping(base.BaseTestCase):
177 177
         hmc = {"cpcs": [{"object-id": "cpcpid", "vswitches": [
178 178
             {"backing-adapter-uri": "/api/adapters/uuid-1",
179 179
              "object-id": "vswitch-uuid-1",
180
-             "port": "0"},
180
+             "port": 0},
181 181
             {"backing-adapter-uri": "/api/adapters/uuid-3",
182 182
              "object-id": "vswitch-uuid-3",
183
-             "port": "0"}], "adapters": adapters}]}
183
+             "port": 0}], "adapters": adapters}]}
184 184
         cpc = fake_zhmcclient.get_cpc(hmc)
185 185
         self.assertRaises(SystemExit,
186 186
                           dpm_map.create_mapping,
@@ -243,19 +243,19 @@ class TestDPMManager(base.BaseTestCase):
243 243
         hmc = {"cpcs": [{"object-id": "cpcpid", "vswitches": [
244 244
             {"backing-adapter-uri": "/api/adapters/uuid-1",
245 245
              "object-id": "vswitch-uuid-1",
246
-             "port": "0",
246
+             "port": 0,
247 247
              "nics": [{"description": "foomac=00:00:00:00:00:11bar"},
248 248
                       {"description": "foomac=00:00:00:00:00:33bar"}]},
249 249
             {"backing-adapter-uri": "/api/adapters/uuid-2",
250 250
              "object-id": "vswitch-uuid-2",
251
-             "port": "1",
251
+             "port": 1,
252 252
              "nics": [{"description": "foomac=00:00:00:00:00:22bar"}]},
253 253
             {"backing-adapter-uri": "/api/adapters/uuid-3",
254 254
              "object-id": "vswitch-uuid-3",
255
-             "port": "0"},
255
+             "port": 0},
256 256
             {"backing-adapter-uri": "/api/adapters/not-configured",
257 257
              "object-id": "not-configured",
258
-             "port": "1",
258
+             "port": 1,
259 259
              "nics": [{"description": "not-configured"}]},
260 260
         ]}]}
261 261
 
@@ -276,7 +276,7 @@ class TestDPMManager(base.BaseTestCase):
276 276
         hmc = {"cpcs": [{"object-id": "cpcpid", "vswitches": [
277 277
             {"backing-adapter-uri": "/api/adapters/uuid-1",
278 278
              "object-id": "vswitch-uuid-1",
279
-             "port": "0",
279
+             "port": 0,
280 280
              "nics": [{"description": "OpenStack foo"}]},
281 281
         ]}]}
282 282
 
@@ -291,7 +291,7 @@ class TestDPMManager(base.BaseTestCase):
291 291
         hmc = {"cpcs": [{"object-id": "cpcpid", "vswitches": [
292 292
             {"backing-adapter-uri": "/api/adapters/uuid-1",
293 293
              "object-id": "vswitch-uuid-1",
294
-             "port": "0",
294
+             "port": 0,
295 295
              "nics": [{"name": "port-id-1"}]},
296 296
         ]}]}
297 297
         cpc = self.mgr.cpc = fake_zhmcclient.get_cpc(hmc)

+ 34
- 14
networking_dpm/tests/unit/test_fake_zhmcclient.py View File

@@ -103,22 +103,42 @@ class TestFakeZHMC(base.BaseTestCase):
103 103
 
104 104
         self.assertEqual(0, len(cpc1.vswitches.list()))
105 105
 
106
-    def test_port_element_id(self):
107
-        """zhmcclient treats element-id as string
108
-
109
-        https://github.com/zhmcclient/python-zhmcclient/issues/125
106
+    def test_port_element_id_int_fail(self):
107
+        """zhmcclient treats element-id as string"""
108
+        port_json = {'element-id': 0}
109
+        try:
110
+            fake_zhmcclient._Port(port_json)
111
+            self.fail("Type error should be thrown, as port-element-id was "
112
+                      "provided as int")
113
+        except TypeError:
114
+            pass
115
+
116
+    def test_port_element_id_string_ok(self):
117
+        """zhmcclient treats element-id as string"""
118
+        port_json = {'element-id': '0'}
119
+        self.assertIsNotNone(fake_zhmcclient._Port(port_json))
120
+
121
+    def test_vswitch_port_string_fail(self):
122
+        """zhmcclient treats vswitch 'port' attribute as int
123
+
124
+        But 'port-element-id' of the adapter is treated as String
110 125
         """
111
-        ports_json = [{'element-id': 0}, {'element-id': '1'}]
112
-        adapter_json = {'object-id': 'oid1', 'ports': ports_json}
113
-
114
-        adapt = fake_zhmcclient._Adapter(adapter_json)
115
-        self.assertRaises(fake_zhmcclient.NotFound,
116
-                          adapt.ports.find, **{'element-id': 0})
117
-        self.assertRaises(fake_zhmcclient.NotFound,
118
-                          adapt.ports.find, **{'element-id': 1})
126
+        vswitches_json = {'port': '0'}
127
+        try:
128
+            fake_zhmcclient._VSwitch(vswitches_json)
129
+            self.fail("Type error should be thrown, as port was provided as "
130
+                      "int")
131
+        except TypeError:
132
+            pass
133
+
134
+    def test_vswitch_port_int_ok(self):
135
+        """zhmcclient treats vswitch 'port' attribute as int
136
+
137
+        But 'port-element-id' of the adapter is treated as String
138
+        """
139
+        vswitches_json = {'port': 0}
119 140
 
120
-        self.assertIsNotNone(adapt.ports.find(**{'element-id': '0'}))
121
-        self.assertIsNotNone(adapt.ports.find(**{'element-id': '1'}))
141
+        self.assertIsNotNone(fake_zhmcclient._VSwitch(vswitches_json))
122 142
 
123 143
     def test_fakehmc_consistency_fail(self):
124 144
         vswitches = [{'backing-adapter-uri': '/api/adapters/uuid-0',

Loading…
Cancel
Save