diff options
author | Zuul <zuul@review.openstack.org> | 2018-07-13 14:51:40 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2018-07-13 14:51:40 +0000 |
commit | e8168345ef06052dde1652776cb3dfac4324ce7e (patch) | |
tree | 39065f193c42624467c2cee0e1187f26301a39d5 | |
parent | 8f27c2a165e3da1bacac7653da6d53a4fb2121f1 (diff) | |
parent | a034e8e0f877e769c4d378e12e511d5c7851f2e7 (diff) |
Merge "Refactor duplicated implementation of _get_policy_obj"
-rw-r--r-- | neutron/core_extensions/qos.py | 15 | ||||
-rw-r--r-- | neutron/db/l3_fip_qos.py | 11 | ||||
-rw-r--r-- | neutron/objects/qos/policy.py | 18 | ||||
-rw-r--r-- | neutron/services/qos/qos_plugin.py | 31 | ||||
-rw-r--r-- | neutron/tests/unit/core_extensions/test_qos.py | 15 | ||||
-rw-r--r-- | neutron/tests/unit/objects/qos/test_policy.py | 6 | ||||
-rw-r--r-- | neutron/tests/unit/services/qos/test_qos_plugin.py | 3 |
7 files changed, 51 insertions, 48 deletions
diff --git a/neutron/core_extensions/qos.py b/neutron/core_extensions/qos.py index e3257d4..72eecff 100644 --- a/neutron/core_extensions/qos.py +++ b/neutron/core_extensions/qos.py | |||
@@ -32,12 +32,6 @@ class QosCoreResourceExtension(base.CoreResourceExtension): | |||
32 | plugin_constants.QOS in directory.get_plugins()) | 32 | plugin_constants.QOS in directory.get_plugins()) |
33 | return self._plugin_loaded | 33 | return self._plugin_loaded |
34 | 34 | ||
35 | def _get_policy_obj(self, context, policy_id): | ||
36 | obj = policy_object.QosPolicy.get_object(context, id=policy_id) | ||
37 | if obj is None: | ||
38 | raise n_exc.QosPolicyNotFound(policy_id=policy_id) | ||
39 | return obj | ||
40 | |||
41 | def _check_policy_change_permission(self, context, old_policy): | 35 | def _check_policy_change_permission(self, context, old_policy): |
42 | """An existing policy can be modified only if one of the following is | 36 | """An existing policy can be modified only if one of the following is |
43 | true: | 37 | true: |
@@ -59,7 +53,8 @@ class QosCoreResourceExtension(base.CoreResourceExtension): | |||
59 | 53 | ||
60 | qos_policy_id = port_changes.get(qos_consts.QOS_POLICY_ID) | 54 | qos_policy_id = port_changes.get(qos_consts.QOS_POLICY_ID) |
61 | if qos_policy_id is not None: | 55 | if qos_policy_id is not None: |
62 | policy = self._get_policy_obj(context, qos_policy_id) | 56 | policy = policy_object.QosPolicy.get_policy_obj( |
57 | context, qos_policy_id) | ||
63 | policy.attach_port(port['id']) | 58 | policy.attach_port(port['id']) |
64 | port[qos_consts.QOS_POLICY_ID] = qos_policy_id | 59 | port[qos_consts.QOS_POLICY_ID] = qos_policy_id |
65 | 60 | ||
@@ -72,7 +67,8 @@ class QosCoreResourceExtension(base.CoreResourceExtension): | |||
72 | qos_policy_id = policy_obj.qos_policy_id | 67 | qos_policy_id = policy_obj.qos_policy_id |
73 | 68 | ||
74 | if qos_policy_id is not None: | 69 | if qos_policy_id is not None: |
75 | policy = self._get_policy_obj(context, qos_policy_id) | 70 | policy = policy_object.QosPolicy.get_policy_obj( |
71 | context, qos_policy_id) | ||
76 | policy.attach_network(network['id']) | 72 | policy.attach_network(network['id']) |
77 | network[qos_consts.QOS_POLICY_ID] = qos_policy_id | 73 | network[qos_consts.QOS_POLICY_ID] = qos_policy_id |
78 | 74 | ||
@@ -85,7 +81,8 @@ class QosCoreResourceExtension(base.CoreResourceExtension): | |||
85 | 81 | ||
86 | qos_policy_id = network_changes.get(qos_consts.QOS_POLICY_ID) | 82 | qos_policy_id = network_changes.get(qos_consts.QOS_POLICY_ID) |
87 | if qos_policy_id is not None: | 83 | if qos_policy_id is not None: |
88 | policy = self._get_policy_obj(context, qos_policy_id) | 84 | policy = policy_object.QosPolicy.get_policy_obj( |
85 | context, qos_policy_id) | ||
89 | policy.attach_network(network['id']) | 86 | policy.attach_network(network['id']) |
90 | network[qos_consts.QOS_POLICY_ID] = qos_policy_id | 87 | network[qos_consts.QOS_POLICY_ID] = qos_policy_id |
91 | 88 | ||
diff --git a/neutron/db/l3_fip_qos.py b/neutron/db/l3_fip_qos.py index 4476d90..c4fbad0 100644 --- a/neutron/db/l3_fip_qos.py +++ b/neutron/db/l3_fip_qos.py | |||
@@ -15,7 +15,6 @@ | |||
15 | from neutron_lib.api.definitions import l3 as l3_apidef | 15 | from neutron_lib.api.definitions import l3 as l3_apidef |
16 | from neutron_lib.services.qos import constants as qos_consts | 16 | from neutron_lib.services.qos import constants as qos_consts |
17 | 17 | ||
18 | from neutron.common import exceptions as n_exc | ||
19 | from neutron.db import _resource_extend as resource_extend | 18 | from neutron.db import _resource_extend as resource_extend |
20 | from neutron.objects.qos import policy as policy_object | 19 | from neutron.objects.qos import policy as policy_object |
21 | 20 | ||
@@ -34,18 +33,12 @@ class FloatingQoSDbMixin(object): | |||
34 | fip_res[qos_consts.QOS_POLICY_ID] = None | 33 | fip_res[qos_consts.QOS_POLICY_ID] = None |
35 | return fip_res | 34 | return fip_res |
36 | 35 | ||
37 | def _get_policy_obj(self, context, policy_id): | ||
38 | obj = policy_object.QosPolicy.get_object(context, id=policy_id) | ||
39 | if obj is None: | ||
40 | raise n_exc.QosPolicyNotFound(policy_id=policy_id) | ||
41 | return obj | ||
42 | |||
43 | def _create_fip_qos_db(self, context, fip_id, policy_id): | 36 | def _create_fip_qos_db(self, context, fip_id, policy_id): |
44 | policy = self._get_policy_obj(context, policy_id) | 37 | policy = policy_object.QosPolicy.get_policy_obj(context, policy_id) |
45 | policy.attach_floatingip(fip_id) | 38 | policy.attach_floatingip(fip_id) |
46 | 39 | ||
47 | def _delete_fip_qos_db(self, context, fip_id, policy_id): | 40 | def _delete_fip_qos_db(self, context, fip_id, policy_id): |
48 | policy = self._get_policy_obj(context, policy_id) | 41 | policy = policy_object.QosPolicy.get_policy_obj(context, policy_id) |
49 | policy.detach_floatingip(fip_id) | 42 | policy.detach_floatingip(fip_id) |
50 | 43 | ||
51 | def _process_extra_fip_qos_create(self, context, fip_id, fip): | 44 | def _process_extra_fip_qos_create(self, context, fip_id, fip): |
diff --git a/neutron/objects/qos/policy.py b/neutron/objects/qos/policy.py index 85302e7..870f4ac 100644 --- a/neutron/objects/qos/policy.py +++ b/neutron/objects/qos/policy.py | |||
@@ -126,6 +126,24 @@ class QosPolicy(rbac_db.NeutronRbacObject): | |||
126 | return _dict | 126 | return _dict |
127 | 127 | ||
128 | @classmethod | 128 | @classmethod |
129 | def get_policy_obj(cls, context, policy_id): | ||
130 | """Fetch a QoS policy. | ||
131 | |||
132 | :param context: neutron api request context | ||
133 | :type context: neutron.context.Context | ||
134 | :param policy_id: the id of the QosPolicy to fetch | ||
135 | :type policy_id: str uuid | ||
136 | |||
137 | :returns: a QosPolicy object | ||
138 | :raises: n_exc.QosPolicyNotFound | ||
139 | """ | ||
140 | |||
141 | obj = cls.get_object(context, id=policy_id) | ||
142 | if obj is None: | ||
143 | raise exceptions.QosPolicyNotFound(policy_id=policy_id) | ||
144 | return obj | ||
145 | |||
146 | @classmethod | ||
129 | def get_object(cls, context, **kwargs): | 147 | def get_object(cls, context, **kwargs): |
130 | # We want to get the policy regardless of its tenant id. We'll make | 148 | # We want to get the policy regardless of its tenant id. We'll make |
131 | # sure the tenant has permission to access the policy later on. | 149 | # sure the tenant has permission to access the policy later on. |
diff --git a/neutron/services/qos/qos_plugin.py b/neutron/services/qos/qos_plugin.py index 4f24241..e428850 100644 --- a/neutron/services/qos/qos_plugin.py +++ b/neutron/services/qos/qos_plugin.py | |||
@@ -192,7 +192,8 @@ class QoSPlugin(qos.QoSPluginBase): | |||
192 | """ | 192 | """ |
193 | policy_data = policy['policy'] | 193 | policy_data = policy['policy'] |
194 | with db_api.context_manager.writer.using(context): | 194 | with db_api.context_manager.writer.using(context): |
195 | policy_obj = self._get_policy_obj(context, policy_id) | 195 | policy_obj = policy_object.QosPolicy.get_policy_obj( |
196 | context, policy_id) | ||
196 | policy_obj.update_fields(policy_data, reset_changes=True) | 197 | policy_obj.update_fields(policy_data, reset_changes=True) |
197 | policy_obj.update() | 198 | policy_obj.update() |
198 | self.driver_manager.call(qos_consts.UPDATE_POLICY_PRECOMMIT, | 199 | self.driver_manager.call(qos_consts.UPDATE_POLICY_PRECOMMIT, |
@@ -223,22 +224,6 @@ class QoSPlugin(qos.QoSPluginBase): | |||
223 | self.driver_manager.call(qos_consts.DELETE_POLICY, | 224 | self.driver_manager.call(qos_consts.DELETE_POLICY, |
224 | context, policy) | 225 | context, policy) |
225 | 226 | ||
226 | def _get_policy_obj(self, context, policy_id): | ||
227 | """Fetch a QoS policy. | ||
228 | |||
229 | :param context: neutron api request context | ||
230 | :type context: neutron.context.Context | ||
231 | :param policy_id: the id of the QosPolicy to fetch | ||
232 | :type policy_id: str uuid | ||
233 | |||
234 | :returns: a QosPolicy object | ||
235 | :raises: n_exc.QosPolicyNotFound | ||
236 | """ | ||
237 | obj = policy_object.QosPolicy.get_object(context, id=policy_id) | ||
238 | if obj is None: | ||
239 | raise n_exc.QosPolicyNotFound(policy_id=policy_id) | ||
240 | return obj | ||
241 | |||
242 | @db_base_plugin_common.filter_fields | 227 | @db_base_plugin_common.filter_fields |
243 | @db_base_plugin_common.convert_result_to_dict | 228 | @db_base_plugin_common.convert_result_to_dict |
244 | def get_policy(self, context, policy_id, fields=None): | 229 | def get_policy(self, context, policy_id, fields=None): |
@@ -251,7 +236,7 @@ class QoSPlugin(qos.QoSPluginBase): | |||
251 | 236 | ||
252 | :returns: a QosPolicy object | 237 | :returns: a QosPolicy object |
253 | """ | 238 | """ |
254 | return self._get_policy_obj(context, policy_id) | 239 | return policy_object.QosPolicy.get_policy_obj(context, policy_id) |
255 | 240 | ||
256 | @db_base_plugin_common.filter_fields | 241 | @db_base_plugin_common.filter_fields |
257 | @db_base_plugin_common.convert_result_to_dict | 242 | @db_base_plugin_common.convert_result_to_dict |
@@ -314,7 +299,7 @@ class QoSPlugin(qos.QoSPluginBase): | |||
314 | 299 | ||
315 | with db_api.autonested_transaction(context.session): | 300 | with db_api.autonested_transaction(context.session): |
316 | # Ensure that we have access to the policy. | 301 | # Ensure that we have access to the policy. |
317 | policy = self._get_policy_obj(context, policy_id) | 302 | policy = policy_object.QosPolicy.get_policy_obj(context, policy_id) |
318 | checker.check_bandwidth_rule_conflict(policy, rule_data) | 303 | checker.check_bandwidth_rule_conflict(policy, rule_data) |
319 | rule = rule_cls(context, qos_policy_id=policy_id, **rule_data) | 304 | rule = rule_cls(context, qos_policy_id=policy_id, **rule_data) |
320 | checker.check_rules_conflict(policy, rule) | 305 | checker.check_rules_conflict(policy, rule) |
@@ -351,7 +336,7 @@ class QoSPlugin(qos.QoSPluginBase): | |||
351 | 336 | ||
352 | with db_api.autonested_transaction(context.session): | 337 | with db_api.autonested_transaction(context.session): |
353 | # Ensure we have access to the policy. | 338 | # Ensure we have access to the policy. |
354 | policy = self._get_policy_obj(context, policy_id) | 339 | policy = policy_object.QosPolicy.get_policy_obj(context, policy_id) |
355 | # Ensure the rule belongs to the policy. | 340 | # Ensure the rule belongs to the policy. |
356 | checker.check_bandwidth_rule_conflict(policy, rule_data) | 341 | checker.check_bandwidth_rule_conflict(policy, rule_data) |
357 | policy.get_rule_by_id(rule_id) | 342 | policy.get_rule_by_id(rule_id) |
@@ -384,7 +369,7 @@ class QoSPlugin(qos.QoSPluginBase): | |||
384 | """ | 369 | """ |
385 | with db_api.autonested_transaction(context.session): | 370 | with db_api.autonested_transaction(context.session): |
386 | # Ensure we have access to the policy. | 371 | # Ensure we have access to the policy. |
387 | policy = self._get_policy_obj(context, policy_id) | 372 | policy = policy_object.QosPolicy.get_policy_obj(context, policy_id) |
388 | rule = policy.get_rule_by_id(rule_id) | 373 | rule = policy.get_rule_by_id(rule_id) |
389 | rule.delete() | 374 | rule.delete() |
390 | policy.obj_load_attr('rules') | 375 | policy.obj_load_attr('rules') |
@@ -413,7 +398,7 @@ class QoSPlugin(qos.QoSPluginBase): | |||
413 | """ | 398 | """ |
414 | with db_api.autonested_transaction(context.session): | 399 | with db_api.autonested_transaction(context.session): |
415 | # Ensure we have access to the policy. | 400 | # Ensure we have access to the policy. |
416 | self._get_policy_obj(context, policy_id) | 401 | policy_object.QosPolicy.get_policy_obj(context, policy_id) |
417 | rule = rule_cls.get_object(context, id=rule_id) | 402 | rule = rule_cls.get_object(context, id=rule_id) |
418 | if not rule: | 403 | if not rule: |
419 | raise n_exc.QosRuleNotFound(policy_id=policy_id, rule_id=rule_id) | 404 | raise n_exc.QosRuleNotFound(policy_id=policy_id, rule_id=rule_id) |
@@ -438,7 +423,7 @@ class QoSPlugin(qos.QoSPluginBase): | |||
438 | """ | 423 | """ |
439 | with db_api.autonested_transaction(context.session): | 424 | with db_api.autonested_transaction(context.session): |
440 | # Ensure we have access to the policy. | 425 | # Ensure we have access to the policy. |
441 | self._get_policy_obj(context, policy_id) | 426 | policy_object.QosPolicy.get_policy_obj(context, policy_id) |
442 | filters = filters or dict() | 427 | filters = filters or dict() |
443 | filters[qos_consts.QOS_POLICY_ID] = policy_id | 428 | filters[qos_consts.QOS_POLICY_ID] = policy_id |
444 | pager = base_obj.Pager(sorts, limit, page_reverse, marker) | 429 | pager = base_obj.Pager(sorts, limit, page_reverse, marker) |
diff --git a/neutron/tests/unit/core_extensions/test_qos.py b/neutron/tests/unit/core_extensions/test_qos.py index 02e6d77..89c6831 100644 --- a/neutron/tests/unit/core_extensions/test_qos.py +++ b/neutron/tests/unit/core_extensions/test_qos.py | |||
@@ -66,7 +66,7 @@ class QosCoreResourceExtensionTestCase(base.BaseTestCase): | |||
66 | actual_port = {'id': mock.Mock(), | 66 | actual_port = {'id': mock.Mock(), |
67 | qos_consts.QOS_POLICY_ID: qos_policy_id} | 67 | qos_consts.QOS_POLICY_ID: qos_policy_id} |
68 | qos_policy = mock.MagicMock() | 68 | qos_policy = mock.MagicMock() |
69 | self.policy_m.get_object = mock.Mock(return_value=qos_policy) | 69 | self.policy_m.get_policy_obj = mock.Mock(return_value=qos_policy) |
70 | self.core_extension.process_fields( | 70 | self.core_extension.process_fields( |
71 | self.context, base_core.PORT, base_core.EVENT_UPDATE, | 71 | self.context, base_core.PORT, base_core.EVENT_UPDATE, |
72 | {qos_consts.QOS_POLICY_ID: qos_policy_id}, | 72 | {qos_consts.QOS_POLICY_ID: qos_policy_id}, |
@@ -85,7 +85,8 @@ class QosCoreResourceExtensionTestCase(base.BaseTestCase): | |||
85 | self.policy_m.get_port_policy = mock.Mock( | 85 | self.policy_m.get_port_policy = mock.Mock( |
86 | return_value=old_qos_policy) | 86 | return_value=old_qos_policy) |
87 | new_qos_policy = mock.MagicMock() | 87 | new_qos_policy = mock.MagicMock() |
88 | self.policy_m.get_object = mock.Mock(return_value=new_qos_policy) | 88 | self.policy_m.get_policy_obj = mock.Mock( |
89 | return_value=new_qos_policy) | ||
89 | self.core_extension.process_fields( | 90 | self.core_extension.process_fields( |
90 | self.context, base_core.PORT, base_core.EVENT_UPDATE, | 91 | self.context, base_core.PORT, base_core.EVENT_UPDATE, |
91 | {qos_consts.QOS_POLICY_ID: qos_policy2_id}, | 92 | {qos_consts.QOS_POLICY_ID: qos_policy2_id}, |
@@ -184,7 +185,7 @@ class QosCoreResourceExtensionTestCase(base.BaseTestCase): | |||
184 | actual_network = {'id': mock.Mock(), | 185 | actual_network = {'id': mock.Mock(), |
185 | qos_consts.QOS_POLICY_ID: qos_policy_id} | 186 | qos_consts.QOS_POLICY_ID: qos_policy_id} |
186 | qos_policy = mock.MagicMock() | 187 | qos_policy = mock.MagicMock() |
187 | self.policy_m.get_object = mock.Mock(return_value=qos_policy) | 188 | self.policy_m.get_policy_obj = mock.Mock(return_value=qos_policy) |
188 | self.core_extension.process_fields( | 189 | self.core_extension.process_fields( |
189 | self.context, base_core.NETWORK, base_core.EVENT_UPDATE, | 190 | self.context, base_core.NETWORK, base_core.EVENT_UPDATE, |
190 | {qos_consts.QOS_POLICY_ID: qos_policy_id}, actual_network) | 191 | {qos_consts.QOS_POLICY_ID: qos_policy_id}, actual_network) |
@@ -202,7 +203,8 @@ class QosCoreResourceExtensionTestCase(base.BaseTestCase): | |||
202 | self.policy_m.get_network_policy = mock.Mock( | 203 | self.policy_m.get_network_policy = mock.Mock( |
203 | return_value=old_qos_policy) | 204 | return_value=old_qos_policy) |
204 | new_qos_policy = mock.MagicMock() | 205 | new_qos_policy = mock.MagicMock() |
205 | self.policy_m.get_object = mock.Mock(return_value=new_qos_policy) | 206 | self.policy_m.get_policy_obj = mock.Mock( |
207 | return_value=new_qos_policy) | ||
206 | self.core_extension.process_fields( | 208 | self.core_extension.process_fields( |
207 | self.context, base_core.NETWORK, base_core.EVENT_UPDATE, | 209 | self.context, base_core.NETWORK, base_core.EVENT_UPDATE, |
208 | {qos_consts.QOS_POLICY_ID: qos_policy_id}, actual_network) | 210 | {qos_consts.QOS_POLICY_ID: qos_policy_id}, actual_network) |
@@ -262,7 +264,7 @@ class QosCoreResourceExtensionTestCase(base.BaseTestCase): | |||
262 | self.policy_m.get_network_policy = mock.Mock( | 264 | self.policy_m.get_network_policy = mock.Mock( |
263 | return_value=qos_policy_id) | 265 | return_value=qos_policy_id) |
264 | qos_policy = mock.MagicMock() | 266 | qos_policy = mock.MagicMock() |
265 | self.policy_m.get_object = mock.Mock(return_value=qos_policy) | 267 | self.policy_m.get_policy_obj = mock.Mock(return_value=qos_policy) |
266 | self.core_extension.process_fields( | 268 | self.core_extension.process_fields( |
267 | self.context, base_core.NETWORK, base_core.EVENT_CREATE, | 269 | self.context, base_core.NETWORK, base_core.EVENT_CREATE, |
268 | actual_network, actual_network) | 270 | actual_network, actual_network) |
@@ -279,7 +281,8 @@ class QosCoreResourceExtensionTestCase(base.BaseTestCase): | |||
279 | qos_policy = mock.MagicMock() | 281 | qos_policy = mock.MagicMock() |
280 | with mock.patch.object(policy.QosPolicyDefault, "get_object", | 282 | with mock.patch.object(policy.QosPolicyDefault, "get_object", |
281 | return_value=qos_policy_id) as mock_get_default_policy_id: | 283 | return_value=qos_policy_id) as mock_get_default_policy_id: |
282 | self.policy_m.get_object = mock.Mock(return_value=qos_policy) | 284 | self.policy_m.get_policy_obj = mock.Mock( |
285 | return_value=qos_policy) | ||
283 | self.core_extension.process_fields( | 286 | self.core_extension.process_fields( |
284 | self.context, base_core.NETWORK, base_core.EVENT_CREATE, | 287 | self.context, base_core.NETWORK, base_core.EVENT_CREATE, |
285 | actual_network, actual_network) | 288 | actual_network, actual_network) |
diff --git a/neutron/tests/unit/objects/qos/test_policy.py b/neutron/tests/unit/objects/qos/test_policy.py index b0e9f76..f57c499 100644 --- a/neutron/tests/unit/objects/qos/test_policy.py +++ b/neutron/tests/unit/objects/qos/test_policy.py | |||
@@ -123,6 +123,12 @@ class QosPolicyObjectTestCase(test_base.BaseObjectIfaceTestCase): | |||
123 | (super(QosPolicyObjectTestCase, self). | 123 | (super(QosPolicyObjectTestCase, self). |
124 | test_to_dict_makes_primitive_field_value()) | 124 | test_to_dict_makes_primitive_field_value()) |
125 | 125 | ||
126 | def test_get_policy_obj_not_found(self): | ||
127 | context = self.context.elevated() | ||
128 | self.assertRaises(n_exc.QosPolicyNotFound, | ||
129 | policy.QosPolicy.get_policy_obj, | ||
130 | context, "fake_id") | ||
131 | |||
126 | 132 | ||
127 | class QosPolicyDbObjectTestCase(test_base.BaseDbObjectTestCase, | 133 | class QosPolicyDbObjectTestCase(test_base.BaseDbObjectTestCase, |
128 | testlib_api.SqlTestCase): | 134 | testlib_api.SqlTestCase): |
diff --git a/neutron/tests/unit/services/qos/test_qos_plugin.py b/neutron/tests/unit/services/qos/test_qos_plugin.py index aa01f41..39ab249 100644 --- a/neutron/tests/unit/services/qos/test_qos_plugin.py +++ b/neutron/tests/unit/services/qos/test_qos_plugin.py | |||
@@ -930,7 +930,8 @@ class TestQosPlugin(base.BaseQosTestCase): | |||
930 | 930 | ||
931 | # some actions get rule from policy | 931 | # some actions get rule from policy |
932 | get_rule_mock_call = getattr( | 932 | get_rule_mock_call = getattr( |
933 | mock.call.QosPolicy.get_object().get_rule_by_id(), action)() | 933 | mock.call.QosPolicy.get_policy_obj().get_rule_by_id(), |
934 | action)() | ||
934 | # some actions construct rule from class reference | 935 | # some actions construct rule from class reference |
935 | rule_mock_call = getattr(mock.call.RuleCls(), action)() | 936 | rule_mock_call = getattr(mock.call.RuleCls(), action)() |
936 | 937 | ||