summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-05-17 12:32:43 +0000
committerGerrit Code Review <review@openstack.org>2018-05-17 12:32:43 +0000
commit50ca126676cce7c7d2aa35a4e7e288e6673d239e (patch)
treebf97f82c5a2b9db3ebd286b2b09072cd8066c831
parent9b2d1d53c8bb43d1fd9bf9f2c929fa42cdc9c626 (diff)
parent5e59cd2a5fcac205e3452efa20a1738c54834520 (diff)
Merge "Refactor for L3 router QoS extensions"
-rw-r--r--neutron/agent/l3/extensions/qos/__init__.py0
-rw-r--r--neutron/agent/l3/extensions/qos/base.py166
-rw-r--r--neutron/agent/l3/extensions/qos/fip.py (renamed from neutron/agent/l3/extensions/fip_qos.py)155
-rw-r--r--neutron/tests/functional/agent/l3/extensions/qos/__init__.py0
-rw-r--r--neutron/tests/functional/agent/l3/extensions/qos/test_fip_qos_extension.py (renamed from neutron/tests/functional/agent/l3/extensions/test_fip_qos_extension.py)2
-rw-r--r--neutron/tests/unit/agent/l3/extensions/qos/__init__.py0
-rw-r--r--neutron/tests/unit/agent/l3/extensions/qos/test_base.py81
-rw-r--r--neutron/tests/unit/agent/l3/extensions/qos/test_fip.py (renamed from neutron/tests/unit/agent/l3/extensions/test_fip_qos.py)51
-rw-r--r--setup.cfg2
9 files changed, 270 insertions, 187 deletions
diff --git a/neutron/agent/l3/extensions/qos/__init__.py b/neutron/agent/l3/extensions/qos/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/neutron/agent/l3/extensions/qos/__init__.py
diff --git a/neutron/agent/l3/extensions/qos/base.py b/neutron/agent/l3/extensions/qos/base.py
new file mode 100644
index 0000000..8ab50b1
--- /dev/null
+++ b/neutron/agent/l3/extensions/qos/base.py
@@ -0,0 +1,166 @@
1# Copyright 2017 OpenStack Foundation
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16import collections
17
18from neutron_lib import constants
19from neutron_lib.db import constants as db_consts
20from neutron_lib.services.qos import constants as qos_consts
21from oslo_log import log as logging
22
23from neutron.agent.linux import l3_tc_lib as tc_lib
24from neutron.api.rpc.callbacks.consumer import registry
25from neutron.api.rpc.callbacks import resources
26from neutron.api.rpc.handlers import resources_rpc
27from neutron.common import rpc as n_rpc
28
29LOG = logging.getLogger(__name__)
30
31SUPPORTED_RULES = {
32 qos_consts.RULE_TYPE_BANDWIDTH_LIMIT: {
33 qos_consts.MAX_KBPS: {
34 'type:range': [0, db_consts.DB_INTEGER_MAX_VALUE]},
35 qos_consts.MAX_BURST: {
36 'type:range': [0, db_consts.DB_INTEGER_MAX_VALUE]},
37 qos_consts.DIRECTION: {
38 'type:values': constants.VALID_DIRECTIONS}
39 }
40}
41
42# We use the default values to illustrate:
43# 1. QoS policy does not have some direction `bandwidth_limit`, then we use
44# the default value.
45# 2. default value 0 will be treated as no limit.
46# 3. if one IP's rate was changed from x to 0, the extension will do
47# a tc filter clean procedure.
48IP_DEFAULT_RATE = 0
49IP_DEFAULT_BURST = 0
50
51
52class RateLimitMaps(object):
53
54 def __init__(self):
55 self.qos_policy_resources = collections.defaultdict(dict)
56 self.known_policies = {}
57 self.resource_policies = {}
58
59 def update_policy(self, policy):
60 self.known_policies[policy.id] = policy
61
62 def get_policy(self, policy_id):
63 return self.known_policies.get(policy_id)
64
65 def get_resources(self, policy):
66 return self.qos_policy_resources[policy.id].values()
67
68 def get_resource_policy(self, resource):
69 policy_id = self.resource_policies.get(resource)
70 return self.get_policy(policy_id)
71
72 def set_resource_policy(self, resource, policy):
73 """Attach a resource to policy
74
75 and return any previous policy on resource.
76 """
77
78 old_policy = self.get_resource_policy(resource)
79 self.update_policy(policy)
80 self.resource_policies[resource] = policy.id
81 self.qos_policy_resources[policy.id][resource] = resource
82 if old_policy and old_policy.id != policy.id:
83 del self.qos_policy_resources[old_policy.id][resource]
84
85 def clean_by_resource(self, resource):
86 """Detach resource from policy
87
88 and cleanup data we don't need anymore.
89 """
90
91 if resource in self.resource_policies:
92 del self.resource_policies[resource]
93 for qos_policy_id, res_dict in self.qos_policy_resources.items():
94 if resource in res_dict:
95 del res_dict[resource]
96 if not res_dict:
97 self._clean_policy_info(qos_policy_id)
98 return
99 LOG.debug("L3 QoS extension did not have "
100 "information on floating IP %s", resource)
101
102 def _clean_policy_info(self, qos_policy_id):
103 del self.qos_policy_resources[qos_policy_id]
104 del self.known_policies[qos_policy_id]
105
106
107class L3QosAgentExtensionBase(object):
108 SUPPORTED_RESOURCE_TYPES = [resources.QOS_POLICY]
109
110 def consume_api(self, agent_api):
111 self.agent_api = agent_api
112
113 def _handle_notification(self, context, resource_type,
114 qos_policies, event_type):
115 pass
116
117 def _process_update_policy(self, qos_policy):
118 pass
119
120 def _policy_rules_modified(self, old_policy, policy):
121 return not (len(old_policy.rules) == len(policy.rules) and
122 all(i in old_policy.rules for i in policy.rules))
123
124 def _register_rpc_consumers(self):
125 registry.register(self._handle_notification, resources.QOS_POLICY)
126
127 self._connection = n_rpc.Connection()
128 endpoints = [resources_rpc.ResourcesPushRpcCallback()]
129 topic = resources_rpc.resource_type_versioned_topic(
130 resources.QOS_POLICY)
131 self._connection.create_consumer(topic, endpoints, fanout=True)
132 self._connection.consume_in_threads()
133
134 def _get_tc_wrapper(self, device):
135 return tc_lib.FloatingIPTcCommand(device.name,
136 namespace=device.namespace)
137
138 def get_policy_rates(self, policy):
139 rates = {}
140 for rule in policy.rules:
141 # NOTE(liuyulong): for now, the L3 agent QoS extensions only
142 # use ``bandwidth_limit`` rules.
143 if rule.rule_type in SUPPORTED_RULES:
144 if rule.direction not in rates:
145 rates[rule.direction] = {"rate": rule.max_kbps,
146 "burst": rule.max_burst_kbps}
147
148 # The return rates dict must contain all directions. If there is no
149 # one specific direction QoS rule, use the default values.
150 for direction in constants.VALID_DIRECTIONS:
151 if direction not in rates:
152 LOG.debug("Policy %(id)s does not have '%(direction)s' "
153 "bandwidth_limit rule, use default value instead.",
154 {"id": policy.id,
155 "direction": direction})
156 rates[direction] = {"rate": IP_DEFAULT_RATE,
157 "burst": IP_DEFAULT_BURST}
158 return rates
159
160 def _get_router_info(self, router_id):
161 router_info = self.agent_api.get_router_info(router_id)
162 if router_info:
163 return router_info
164 LOG.debug("Router %s is not managed by this agent. "
165 "It was possibly deleted concurrently.",
166 router_id)
diff --git a/neutron/agent/l3/extensions/fip_qos.py b/neutron/agent/l3/extensions/qos/fip.py
index 1bf1654..9b79bd9 100644
--- a/neutron/agent/l3/extensions/fip_qos.py
+++ b/neutron/agent/l3/extensions/qos/fip.py
@@ -13,52 +13,23 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16import collections
17
18from neutron_lib.agent import l3_extension 16from neutron_lib.agent import l3_extension
19from neutron_lib import constants 17from neutron_lib import constants
20from neutron_lib.db import constants as db_consts
21from neutron_lib.services.qos import constants as qos_consts 18from neutron_lib.services.qos import constants as qos_consts
22from oslo_concurrency import lockutils 19from oslo_concurrency import lockutils
23from oslo_log import log as logging 20from oslo_log import log as logging
24 21
22from neutron.agent.l3.extensions.qos import base as qos_base
25from neutron.agent.linux import ip_lib 23from neutron.agent.linux import ip_lib
26from neutron.agent.linux import l3_tc_lib as tc_lib
27from neutron.api.rpc.callbacks.consumer import registry
28from neutron.api.rpc.callbacks import events 24from neutron.api.rpc.callbacks import events
29from neutron.api.rpc.callbacks import resources 25from neutron.api.rpc.callbacks import resources
30from neutron.api.rpc.handlers import resources_rpc 26from neutron.api.rpc.handlers import resources_rpc
31from neutron.common import rpc as n_rpc
32 27
33LOG = logging.getLogger(__name__) 28LOG = logging.getLogger(__name__)
34 29
35SUPPORTED_RULES = {
36 qos_consts.RULE_TYPE_BANDWIDTH_LIMIT: {
37 qos_consts.MAX_KBPS: {
38 'type:range': [0, db_consts.DB_INTEGER_MAX_VALUE]},
39 qos_consts.MAX_BURST: {
40 'type:range': [0, db_consts.DB_INTEGER_MAX_VALUE]},
41 qos_consts.DIRECTION: {
42 'type:values': constants.VALID_DIRECTIONS}
43 }
44}
45
46# We use the default values to illustrate:
47# 1. QoS policy does not have some direction `bandwidth_limit`, then we use
48# the default value.
49# 2. default value 0 will be treated as no limit.
50# 3. if one floating IP's rate was changed from x to 0, the extension will do
51# a tc filter clean procedure.
52FIP_DEFAULT_RATE = 0
53FIP_DEFAULT_BURST = 0
54
55
56class RouterFipRateLimitMaps(object):
57 def __init__(self):
58 self.qos_policy_fips = collections.defaultdict(dict)
59 self.known_policies = {}
60 self.fip_policies = {}
61 30
31class RouterFipRateLimitMaps(qos_base.RateLimitMaps):
32 def __init__(self):
62 """ 33 """
63 The router_floating_ips will be: 34 The router_floating_ips will be:
64 router_floating_ips = { 35 router_floating_ips = {
@@ -72,52 +43,14 @@ class RouterFipRateLimitMaps(object):
72 The rate limits dict will be: 43 The rate limits dict will be:
73 xxx_ratelimits = { 44 xxx_ratelimits = {
74 fip_1: (rate, burst), 45 fip_1: (rate, burst),
75 fip_2: (FIP_DEFAULT_RATE, FIP_DEFAULT_BURST), # default 46 fip_2: (IP_DEFAULT_RATE, IP_DEFAULT_BURST), # default
76 fip_3: (1, 2), 47 fip_3: (1, 2),
77 fip_4: (3, 4), 48 fip_4: (3, 4),
78 } 49 }
79 """ 50 """
80 self.ingress_ratelimits = {} 51 self.ingress_ratelimits = {}
81 self.egress_ratelimits = {} 52 self.egress_ratelimits = {}
82 53 super(RouterFipRateLimitMaps, self).__init__()
83 def update_policy(self, policy):
84 self.known_policies[policy.id] = policy
85
86 def get_policy(self, policy_id):
87 return self.known_policies.get(policy_id)
88
89 def get_fips(self, policy):
90 return self.qos_policy_fips[policy.id].values()
91
92 def get_fip_policy(self, fip):
93 policy_id = self.fip_policies.get(fip)
94 return self.get_policy(policy_id)
95
96 def set_fip_policy(self, fip, policy):
97 """Attach a fip to policy and return any previous policy on fip."""
98 old_policy = self.get_fip_policy(fip)
99 self.update_policy(policy)
100 self.fip_policies[fip] = policy.id
101 self.qos_policy_fips[policy.id][fip] = fip
102 if old_policy and old_policy.id != policy.id:
103 del self.qos_policy_fips[old_policy.id][fip]
104
105 def clean_by_fip(self, fip):
106 """Detach fip from policy and cleanup data we don't need anymore."""
107 if fip in self.fip_policies:
108 del self.fip_policies[fip]
109 for qos_policy_id, fip_dict in self.qos_policy_fips.items():
110 if fip in fip_dict:
111 del fip_dict[fip]
112 if not fip_dict:
113 self._clean_policy_info(qos_policy_id)
114 return
115 LOG.debug("Floating IP QoS extension did not have "
116 "information on floating IP %s", fip)
117
118 def _clean_policy_info(self, qos_policy_id):
119 del self.qos_policy_fips[qos_policy_id]
120 del self.known_policies[qos_policy_id]
121 54
122 def find_fip_router_id(self, fip): 55 def find_fip_router_id(self, fip):
123 for router_id, ips in self.router_floating_ips.items(): 56 for router_id, ips in self.router_floating_ips.items():
@@ -125,8 +58,8 @@ class RouterFipRateLimitMaps(object):
125 return router_id 58 return router_id
126 59
127 60
128class FipQosAgentExtension(l3_extension.L3AgentExtension): 61class FipQosAgentExtension(qos_base.L3QosAgentExtensionBase,
129 SUPPORTED_RESOURCE_TYPES = [resources.QOS_POLICY] 62 l3_extension.L3AgentExtension):
130 63
131 def initialize(self, connection, driver_type): 64 def initialize(self, connection, driver_type):
132 """Initialize agent extension.""" 65 """Initialize agent extension."""
@@ -134,9 +67,6 @@ class FipQosAgentExtension(l3_extension.L3AgentExtension):
134 self.fip_qos_map = RouterFipRateLimitMaps() 67 self.fip_qos_map = RouterFipRateLimitMaps()
135 self._register_rpc_consumers() 68 self._register_rpc_consumers()
136 69
137 def consume_api(self, agent_api):
138 self.agent_api = agent_api
139
140 @lockutils.synchronized('qos-fip') 70 @lockutils.synchronized('qos-fip')
141 def _handle_notification(self, context, resource_type, 71 def _handle_notification(self, context, resource_type,
142 qos_policies, event_type): 72 qos_policies, event_type):
@@ -144,15 +74,11 @@ class FipQosAgentExtension(l3_extension.L3AgentExtension):
144 for qos_policy in qos_policies: 74 for qos_policy in qos_policies:
145 self._process_update_policy(qos_policy) 75 self._process_update_policy(qos_policy)
146 76
147 def _policy_rules_modified(self, old_policy, policy):
148 return not (len(old_policy.rules) == len(policy.rules) and
149 all(i in old_policy.rules for i in policy.rules))
150
151 def _process_update_policy(self, qos_policy): 77 def _process_update_policy(self, qos_policy):
152 old_qos_policy = self.fip_qos_map.get_policy(qos_policy.id) 78 old_qos_policy = self.fip_qos_map.get_policy(qos_policy.id)
153 if old_qos_policy: 79 if old_qos_policy:
154 if self._policy_rules_modified(old_qos_policy, qos_policy): 80 if self._policy_rules_modified(old_qos_policy, qos_policy):
155 for fip in self.fip_qos_map.get_fips(qos_policy): 81 for fip in self.fip_qos_map.get_resources(qos_policy):
156 router_id = self.fip_qos_map.find_fip_router_id(fip) 82 router_id = self.fip_qos_map.find_fip_router_id(fip)
157 router_info = self._get_router_info(router_id) 83 router_info = self._get_router_info(router_id)
158 if not router_info: 84 if not router_info:
@@ -172,27 +98,13 @@ class FipQosAgentExtension(l3_extension.L3AgentExtension):
172 self.fip_qos_map.update_policy(qos_policy) 98 self.fip_qos_map.update_policy(qos_policy)
173 99
174 def _process_reset_fip(self, fip): 100 def _process_reset_fip(self, fip):
175 self.fip_qos_map.clean_by_fip(fip) 101 self.fip_qos_map.clean_by_resource(fip)
176
177 def _register_rpc_consumers(self):
178 registry.register(self._handle_notification, resources.QOS_POLICY)
179
180 self._connection = n_rpc.Connection()
181 endpoints = [resources_rpc.ResourcesPushRpcCallback()]
182 topic = resources_rpc.resource_type_versioned_topic(
183 resources.QOS_POLICY)
184 self._connection.create_consumer(topic, endpoints, fanout=True)
185 self._connection.consume_in_threads()
186
187 def _get_tc_wrapper(self, device):
188 return tc_lib.FloatingIPTcCommand(device.name,
189 namespace=device.namespace)
190 102
191 def process_ip_rate_limit(self, ip, direction, device, rate, burst): 103 def process_ip_rate_limit(self, ip, direction, device, rate, burst):
192 rate_limits_direction = direction + "_ratelimits" 104 rate_limits_direction = direction + "_ratelimits"
193 rate_limits = getattr(self.fip_qos_map, rate_limits_direction, {}) 105 rate_limits = getattr(self.fip_qos_map, rate_limits_direction, {})
194 old_rate, old_burst = rate_limits.get(ip, (FIP_DEFAULT_RATE, 106 old_rate, old_burst = rate_limits.get(ip, (qos_base.IP_DEFAULT_RATE,
195 FIP_DEFAULT_BURST)) 107 qos_base.IP_DEFAULT_BURST))
196 108
197 if old_rate == rate and old_burst == burst: 109 if old_rate == rate and old_burst == burst:
198 # Two possibilities here: 110 # Two possibilities here:
@@ -202,7 +114,8 @@ class FipQosAgentExtension(l3_extension.L3AgentExtension):
202 114
203 tc_wrapper = self._get_tc_wrapper(device) 115 tc_wrapper = self._get_tc_wrapper(device)
204 116
205 if rate == FIP_DEFAULT_RATE and burst == FIP_DEFAULT_BURST: 117 if (rate == qos_base.IP_DEFAULT_RATE and
118 burst == qos_base.IP_DEFAULT_BURST):
206 # According to the agreements of default value definition, 119 # According to the agreements of default value definition,
207 # floating IP bandwidth was changed to default value (no limit). 120 # floating IP bandwidth was changed to default value (no limit).
208 # NOTE: l3_tc_lib will ignore exception FilterIDForIPNotFound. 121 # NOTE: l3_tc_lib will ignore exception FilterIDForIPNotFound.
@@ -255,37 +168,17 @@ class FipQosAgentExtension(l3_extension.L3AgentExtension):
255 self._process_reset_fip(fip) 168 self._process_reset_fip(fip)
256 # process_ip_rate_limit will treat value 0 as 169 # process_ip_rate_limit will treat value 0 as
257 # cleaning the tc filters if exits or no action. 170 # cleaning the tc filters if exits or no action.
258 return {constants.INGRESS_DIRECTION: {"rate": FIP_DEFAULT_RATE, 171 return {constants.INGRESS_DIRECTION: {
259 "burst": FIP_DEFAULT_BURST}, 172 "rate": qos_base.IP_DEFAULT_RATE,
260 constants.EGRESS_DIRECTION: {"rate": FIP_DEFAULT_RATE, 173 "burst": qos_base.IP_DEFAULT_BURST},
261 "burst": FIP_DEFAULT_BURST}} 174 constants.EGRESS_DIRECTION: {
175 "rate": qos_base.IP_DEFAULT_RATE,
176 "burst": qos_base.IP_DEFAULT_BURST}}
262 policy = self.resource_rpc.pull( 177 policy = self.resource_rpc.pull(
263 context, resources.QOS_POLICY, policy_id) 178 context, resources.QOS_POLICY, policy_id)
264 self.fip_qos_map.set_fip_policy(fip, policy) 179 self.fip_qos_map.set_resource_policy(fip, policy)
265 return self.get_policy_rates(policy) 180 return self.get_policy_rates(policy)
266 181
267 def get_policy_rates(self, policy):
268 rates = {}
269 for rule in policy.rules:
270 # NOTE(liuyulong): for now, the L3 agent floating IP QoS
271 # extension only uses ``bandwidth_limit`` rules..
272 if rule.rule_type in SUPPORTED_RULES:
273 if rule.direction not in rates:
274 rates[rule.direction] = {"rate": rule.max_kbps,
275 "burst": rule.max_burst_kbps}
276
277 # The return rates dict must contain all directions. If there is no
278 # one specific direction QoS rule, use the default values.
279 for direction in constants.VALID_DIRECTIONS:
280 if direction not in rates:
281 LOG.debug("Policy %(id)s does not have '%(direction)s' "
282 "bandwidth_limit rule, use default value instead.",
283 {"id": policy.id,
284 "direction": direction})
285 rates[direction] = {"rate": FIP_DEFAULT_RATE,
286 "burst": FIP_DEFAULT_BURST}
287 return rates
288
289 def process_ip_rates(self, fip, device, rates, with_cache=True): 182 def process_ip_rates(self, fip, device, rates, with_cache=True):
290 for direction in constants.VALID_DIRECTIONS: 183 for direction in constants.VALID_DIRECTIONS:
291 rate = rates.get(direction) 184 rate = rates.get(direction)
@@ -380,14 +273,6 @@ class FipQosAgentExtension(l3_extension.L3AgentExtension):
380 self._remove_fip_rate_limit(dvr_fip_device, fip) 273 self._remove_fip_rate_limit(dvr_fip_device, fip)
381 self._process_reset_fip(fip) 274 self._process_reset_fip(fip)
382 275
383 def _get_router_info(self, router_id):
384 router_info = self.agent_api.get_router_info(router_id)
385 if router_info:
386 return router_info
387 LOG.debug("Router %s is not managed by this agent. "
388 "It was possibly deleted concurrently.",
389 router_id)
390
391 @lockutils.synchronized('qos-fip') 276 @lockutils.synchronized('qos-fip')
392 def add_router(self, context, data): 277 def add_router(self, context, data):
393 router_info = self._get_router_info(data['id']) 278 router_info = self._get_router_info(data['id'])
diff --git a/neutron/tests/functional/agent/l3/extensions/qos/__init__.py b/neutron/tests/functional/agent/l3/extensions/qos/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/neutron/tests/functional/agent/l3/extensions/qos/__init__.py
diff --git a/neutron/tests/functional/agent/l3/extensions/test_fip_qos_extension.py b/neutron/tests/functional/agent/l3/extensions/qos/test_fip_qos_extension.py
index 7d54ed6..68d185e 100644
--- a/neutron/tests/functional/agent/l3/extensions/test_fip_qos_extension.py
+++ b/neutron/tests/functional/agent/l3/extensions/qos/test_fip_qos_extension.py
@@ -18,7 +18,7 @@ from neutron_lib import constants
18from oslo_utils import uuidutils 18from oslo_utils import uuidutils
19 19
20from neutron.agent.l3 import agent as neutron_l3_agent 20from neutron.agent.l3 import agent as neutron_l3_agent
21from neutron.agent.l3.extensions import fip_qos 21from neutron.agent.l3.extensions.qos import fip as fip_qos
22from neutron.agent.linux import ip_lib 22from neutron.agent.linux import ip_lib
23from neutron.common import exceptions 23from neutron.common import exceptions
24from neutron.common import utils as common_utils 24from neutron.common import utils as common_utils
diff --git a/neutron/tests/unit/agent/l3/extensions/qos/__init__.py b/neutron/tests/unit/agent/l3/extensions/qos/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/neutron/tests/unit/agent/l3/extensions/qos/__init__.py
diff --git a/neutron/tests/unit/agent/l3/extensions/qos/test_base.py b/neutron/tests/unit/agent/l3/extensions/qos/test_base.py
new file mode 100644
index 0000000..5c626cf
--- /dev/null
+++ b/neutron/tests/unit/agent/l3/extensions/qos/test_base.py
@@ -0,0 +1,81 @@
1# Copyright 2017 OpenStack Foundation
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16import mock
17from oslo_utils import uuidutils
18
19from neutron.agent.l3.extensions.qos import base as qos_base
20from neutron.objects.qos import policy
21from neutron.tests import base
22
23_uuid = uuidutils.generate_uuid
24TEST_POLICY = policy.QosPolicy(context=None,
25 name='test1', id=_uuid())
26TEST_POLICY2 = policy.QosPolicy(context=None,
27 name='test2', id=_uuid())
28
29TEST_RES_1 = "res1"
30TEST_RES_2 = "res2"
31
32
33class RateLimitMapsTestCase(base.BaseTestCase):
34
35 def setUp(self):
36 super(RateLimitMapsTestCase, self).setUp()
37 self.policy_map = qos_base.RateLimitMaps()
38
39 def test_update_policy(self):
40 self.policy_map.update_policy(TEST_POLICY)
41 self.assertEqual(TEST_POLICY,
42 self.policy_map.known_policies[TEST_POLICY.id])
43
44 def _set_resources(self):
45 self.policy_map.set_resource_policy(TEST_RES_1, TEST_POLICY)
46 self.policy_map.set_resource_policy(TEST_RES_2, TEST_POLICY2)
47
48 def test_set_resource_policy(self):
49 self._set_resources()
50 self.assertEqual(TEST_POLICY,
51 self.policy_map.known_policies[TEST_POLICY.id])
52 self.assertIn(TEST_RES_1,
53 self.policy_map.qos_policy_resources[TEST_POLICY.id])
54
55 def test_get_resource_policy(self):
56 self._set_resources()
57 self.assertEqual(TEST_POLICY,
58 self.policy_map.get_resource_policy(TEST_RES_1))
59 self.assertEqual(TEST_POLICY2,
60 self.policy_map.get_resource_policy(TEST_RES_2))
61
62 def test_get_resources(self):
63 self._set_resources()
64 self.assertEqual([TEST_RES_1],
65 list(self.policy_map.get_resources(TEST_POLICY)))
66
67 self.assertEqual([TEST_RES_2],
68 list(self.policy_map.get_resources(TEST_POLICY2)))
69
70 def test_clean_by_resource(self):
71 self._set_resources()
72 self.policy_map.clean_by_resource(TEST_RES_1)
73 self.assertNotIn(TEST_POLICY.id, self.policy_map.known_policies)
74 self.assertNotIn(TEST_RES_1, self.policy_map.resource_policies)
75 self.assertIn(TEST_POLICY2.id, self.policy_map.known_policies)
76
77 def test_clean_by_resource_for_unknown_resource(self):
78 self.policy_map._clean_policy_info = mock.Mock()
79 self.policy_map.clean_by_resource(TEST_RES_1)
80
81 self.policy_map._clean_policy_info.assert_not_called()
diff --git a/neutron/tests/unit/agent/l3/extensions/test_fip_qos.py b/neutron/tests/unit/agent/l3/extensions/qos/test_fip.py
index 3142443..f287238 100644
--- a/neutron/tests/unit/agent/l3/extensions/test_fip_qos.py
+++ b/neutron/tests/unit/agent/l3/extensions/qos/test_fip.py
@@ -20,7 +20,7 @@ from neutron_lib.services.qos import constants as qos_consts
20from oslo_utils import uuidutils 20from oslo_utils import uuidutils
21 21
22from neutron.agent.l3 import agent as l3_agent 22from neutron.agent.l3 import agent as l3_agent
23from neutron.agent.l3.extensions import fip_qos 23from neutron.agent.l3.extensions.qos import fip as fip_qos
24from neutron.agent.l3 import l3_agent_extension_api as l3_ext_api 24from neutron.agent.l3 import l3_agent_extension_api as l3_ext_api
25from neutron.agent.l3 import router_info as l3router 25from neutron.agent.l3 import router_info as l3router
26from neutron.api.rpc.callbacks.consumer import registry 26from neutron.api.rpc.callbacks.consumer import registry
@@ -32,11 +32,6 @@ from neutron.tests import base
32from neutron.tests.unit.agent.l3 import test_agent 32from neutron.tests.unit.agent.l3 import test_agent
33 33
34_uuid = uuidutils.generate_uuid 34_uuid = uuidutils.generate_uuid
35TEST_POLICY = policy.QosPolicy(context=None,
36 name='test1', id=_uuid())
37TEST_POLICY2 = policy.QosPolicy(context=None,
38 name='test2', id=_uuid())
39
40 35
41TEST_QOS_FIP = "3.3.3.3" 36TEST_QOS_FIP = "3.3.3.3"
42 37
@@ -382,50 +377,6 @@ class RouterFipRateLimitMapsTestCase(base.BaseTestCase):
382 super(RouterFipRateLimitMapsTestCase, self).setUp() 377 super(RouterFipRateLimitMapsTestCase, self).setUp()
383 self.policy_map = fip_qos.RouterFipRateLimitMaps() 378 self.policy_map = fip_qos.RouterFipRateLimitMaps()
384 379
385 def test_update_policy(self):
386 self.policy_map.update_policy(TEST_POLICY)
387 self.assertEqual(TEST_POLICY,
388 self.policy_map.known_policies[TEST_POLICY.id])
389
390 def _set_fips(self):
391 self.policy_map.set_fip_policy(TEST_FIP, TEST_POLICY)
392 self.policy_map.set_fip_policy(TEST_FIP2, TEST_POLICY2)
393
394 def test_set_fip_policy(self):
395 self._set_fips()
396 self.assertEqual(TEST_POLICY,
397 self.policy_map.known_policies[TEST_POLICY.id])
398 self.assertIn(TEST_FIP,
399 self.policy_map.qos_policy_fips[TEST_POLICY.id])
400
401 def test_get_fip_policy(self):
402 self._set_fips()
403 self.assertEqual(TEST_POLICY,
404 self.policy_map.get_fip_policy(TEST_FIP))
405 self.assertEqual(TEST_POLICY2,
406 self.policy_map.get_fip_policy(TEST_FIP2))
407
408 def test_get_fips(self):
409 self._set_fips()
410 self.assertEqual([TEST_FIP],
411 list(self.policy_map.get_fips(TEST_POLICY)))
412
413 self.assertEqual([TEST_FIP2],
414 list(self.policy_map.get_fips(TEST_POLICY2)))
415
416 def test_clean_by_fip(self):
417 self._set_fips()
418 self.policy_map.clean_by_fip(TEST_FIP)
419 self.assertNotIn(TEST_POLICY.id, self.policy_map.known_policies)
420 self.assertNotIn(TEST_FIP, self.policy_map.fip_policies)
421 self.assertIn(TEST_POLICY2.id, self.policy_map.known_policies)
422
423 def test_clean_by_fip_for_unknown_fip(self):
424 self.policy_map._clean_policy_info = mock.Mock()
425 self.policy_map.clean_by_fip(TEST_FIP)
426
427 self.policy_map._clean_policy_info.assert_not_called()
428
429 def test_find_fip_router_id(self): 380 def test_find_fip_router_id(self):
430 router_id = _uuid() 381 router_id = _uuid()
431 self.policy_map.router_floating_ips[router_id] = set([TEST_FIP, 382 self.policy_map.router_floating_ips[router_id] = set([TEST_FIP,
diff --git a/setup.cfg b/setup.cfg
index f80d0ae..28c78ac 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -106,7 +106,7 @@ neutron.agent.l2.extensions =
106 fdb = neutron.agent.l2.extensions.fdb_population:FdbPopulationAgentExtension 106 fdb = neutron.agent.l2.extensions.fdb_population:FdbPopulationAgentExtension
107 log = neutron.services.logapi.agent.log_extension:LoggingExtension 107 log = neutron.services.logapi.agent.log_extension:LoggingExtension
108neutron.agent.l3.extensions = 108neutron.agent.l3.extensions =
109 fip_qos = neutron.agent.l3.extensions.fip_qos:FipQosAgentExtension 109 fip_qos = neutron.agent.l3.extensions.qos.fip:FipQosAgentExtension
110neutron.services.logapi.drivers = 110neutron.services.logapi.drivers =
111 ovs = neutron.services.logapi.drivers.openvswitch.ovs_firewall_log:OVSFirewallLoggingDriver 111 ovs = neutron.services.logapi.drivers.openvswitch.ovs_firewall_log:OVSFirewallLoggingDriver
112neutron.qos.agent_drivers = 112neutron.qos.agent_drivers =