blob: 8f803f61a49609c0309f56dadf985a586fe0a142 [file] [log] [blame]
Matteo Scandoload0c1752018-08-09 15:47:16 -07001
2# Copyright 2017-present Open Networking Foundation
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 implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
17import unittest
18from mock import patch, call, Mock, PropertyMock
19
20import os, sys
21
22test_path=os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
Matteo Scandoload0c1752018-08-09 15:47:16 -070023
Matteo Scandoload0c1752018-08-09 15:47:16 -070024
25class TestModelPolicyAttWorkflowDriverServiceInstance(unittest.TestCase):
26 def setUp(self):
27
28 self.sys_path_save = sys.path
Matteo Scandoload0c1752018-08-09 15:47:16 -070029
30 config = os.path.join(test_path, "../test_config.yaml")
31 from xosconfig import Config
32 Config.clear()
33 Config.init(config, 'synchronizer-config-schema.yaml')
34
Scott Baker71d20472019-02-01 12:05:35 -080035 from xossynchronizer.mock_modelaccessor_build import mock_modelaccessor_config
36 mock_modelaccessor_config(test_path, [("att-workflow-driver", "att-workflow-driver.xproto"),
37 ("olt-service", "volt.xproto"),
Matteo Scandoload6c8942019-02-14 13:02:08 -080038 ("rcord", "rcord.xproto")])
Matteo Scandoload0c1752018-08-09 15:47:16 -070039
Scott Baker71d20472019-02-01 12:05:35 -080040 import xossynchronizer.modelaccessor
41 import mock_modelaccessor
42 reload(mock_modelaccessor) # in case nose2 loaded it in a previous test
43 reload(xossynchronizer.modelaccessor) # in case nose2 loaded it in a previous test
44
45 from xossynchronizer.modelaccessor import model_accessor
46 from model_policy_att_workflow_driver_serviceinstance import AttWorkflowDriverServiceInstancePolicy, AttHelpers
47 self.AttHelpers = AttHelpers
Matteo Scandoload0c1752018-08-09 15:47:16 -070048
49 from mock_modelaccessor import MockObjectList
50
51 # import all class names to globals
52 for (k, v) in model_accessor.all_model_classes.items():
53 globals()[k] = v
54
55 # Some of the functions we call have side-effects. For example, creating a VSGServiceInstance may lead to creation of
56 # tags. Ideally, this wouldn't happen, but it does. So make sure we reset the world.
57 model_accessor.reset_all_object_stores()
58
Matteo Scandoloea529092018-09-11 16:36:39 -070059
Scott Baker71d20472019-02-01 12:05:35 -080060 self.policy = AttWorkflowDriverServiceInstancePolicy(model_accessor=model_accessor)
Matteo Scandoload0c1752018-08-09 15:47:16 -070061 self.si = AttWorkflowDriverServiceInstance()
62 self.si.owner = AttWorkflowDriverService()
Matteo Scandoloea529092018-09-11 16:36:39 -070063 self.si.serial_number = "BRCM1234"
Matteo Scandoload0c1752018-08-09 15:47:16 -070064
65 def tearDown(self):
66 sys.path = self.sys_path_save
Matteo Scandoload0c1752018-08-09 15:47:16 -070067
Matteo Scandoloc6ac74a2018-09-14 08:14:51 -070068 def test_update_onu(self):
69
70 onu = ONUDevice(
71 serial_number="BRCM1234",
72 admin_state="ENABLED"
73 )
74 with patch.object(ONUDevice.objects, "get_items") as get_onu, \
75 patch.object(onu, "save") as onu_save:
76 get_onu.return_value = [onu]
77
78 self.policy.update_onu("brcm1234", "ENABLED")
79 onu_save.assert_not_called()
80
81 self.policy.update_onu("brcm1234", "DISABLED")
82 self.assertEqual(onu.admin_state, "DISABLED")
Andy Bavier0d631eb2018-10-17 18:05:04 -070083 onu_save.assert_called_with(always_update_timestamp=True, update_fields=['admin_state', 'serial_number', 'updated'])
Matteo Scandoloc6ac74a2018-09-14 08:14:51 -070084
85
Matteo Scandoload0c1752018-08-09 15:47:16 -070086 def test_enable_onu(self):
Scott Baker71d20472019-02-01 12:05:35 -080087 with patch.object(self.AttHelpers, "validate_onu") as validate_onu, \
Matteo Scandoloea529092018-09-11 16:36:39 -070088 patch.object(self.policy, "update_onu") as update_onu, \
89 patch.object(self.si, "save") as save_si:
90 validate_onu.return_value = [True, "valid onu"]
Matteo Scandoload0c1752018-08-09 15:47:16 -070091
Andy Bavierafaf1762019-01-16 09:41:43 -070092 self.policy.process_onu_state(self.si)
Matteo Scandoload0c1752018-08-09 15:47:16 -070093
Matteo Scandoloea529092018-09-11 16:36:39 -070094 update_onu.assert_called_once()
95 update_onu.assert_called_with("BRCM1234", "ENABLED")
Matteo Scandoload0c1752018-08-09 15:47:16 -070096
Matteo Scandoloea529092018-09-11 16:36:39 -070097 self.assertIn("valid onu", self.si.status_message)
Matteo Scandoload0c1752018-08-09 15:47:16 -070098
Matteo Scandoloea529092018-09-11 16:36:39 -070099 def test_disable_onu(self):
Scott Baker71d20472019-02-01 12:05:35 -0800100 with patch.object(self.AttHelpers, "validate_onu") as validate_onu, \
Matteo Scandoloea529092018-09-11 16:36:39 -0700101 patch.object(self.policy, "update_onu") as update_onu, \
102 patch.object(self.si, "save") as save_si:
103 validate_onu.return_value = [False, "invalid onu"]
Matteo Scandoload0c1752018-08-09 15:47:16 -0700104
Andy Bavierafaf1762019-01-16 09:41:43 -0700105 self.policy.process_onu_state(self.si)
Matteo Scandoloea529092018-09-11 16:36:39 -0700106
107 update_onu.assert_called_once()
108 update_onu.assert_called_with("BRCM1234", "DISABLED")
109
110 self.assertIn("invalid onu", self.si.status_message)
111
112 def test_handle_update_validate_onu(self):
113 """
114 Testing that handle_update calls validate_onu with the correct parameters
115 when necessary
116 """
Andy Bavierafaf1762019-01-16 09:41:43 -0700117 with patch.object(self.policy, "process_onu_state") as process_onu_state, \
Matteo Scandoloea529092018-09-11 16:36:39 -0700118 patch.object(self.policy, "update_onu") as update_onu, \
119 patch.object(self.policy, "get_subscriber") as get_subscriber:
120 update_onu.return_value = None
121 get_subscriber.return_value = None
122
123 self.si.onu_state = "AWAITING"
Matteo Scandoload0c1752018-08-09 15:47:16 -0700124 self.policy.handle_update(self.si)
Andy Bavierafaf1762019-01-16 09:41:43 -0700125 process_onu_state.assert_called_with(self.si)
Matteo Scandoload0c1752018-08-09 15:47:16 -0700126
Matteo Scandoloea529092018-09-11 16:36:39 -0700127 self.si.onu_state = "ENABLED"
Matteo Scandoload0c1752018-08-09 15:47:16 -0700128 self.policy.handle_update(self.si)
Andy Bavierafaf1762019-01-16 09:41:43 -0700129 process_onu_state.assert_called_with(self.si)
Matteo Scandoload0c1752018-08-09 15:47:16 -0700130
Matteo Scandoloea529092018-09-11 16:36:39 -0700131 self.si.onu_state = "DISABLED"
132 self.policy.handle_update(self.si)
Andy Bavierafaf1762019-01-16 09:41:43 -0700133 process_onu_state.assert_called_with(self.si)
134
Matteo Scandoload0c1752018-08-09 15:47:16 -0700135
Matteo Scandoloea529092018-09-11 16:36:39 -0700136 def test_get_subscriber(self):
137
138 sub = RCORDSubscriber(
139 onu_device="BRCM1234"
140 )
141
142 with patch.object(RCORDSubscriber.objects, "get_items") as get_subscribers:
143 get_subscribers.return_value = [sub]
144
145 res = self.policy.get_subscriber("BRCM1234")
146 self.assertEqual(res, sub)
147
148 res = self.policy.get_subscriber("brcm1234")
149 self.assertEqual(res, sub)
150
151 res = self.policy.get_subscriber("foo")
152 self.assertEqual(res, None)
153
154 def test_update_subscriber(self):
155
156 sub = RCORDSubscriber(
157 onu_device="BRCM1234"
158 )
159
160 self.si.status_message = "some content"
161
162 with patch.object(sub, "save") as sub_save:
163 self.si.authentication_state = "AWAITING"
164 self.policy.update_subscriber(sub, self.si)
165 self.assertEqual(sub.status, "awaiting-auth")
Matteo Scandoloea529092018-09-11 16:36:39 -0700166 sub_save.assert_called()
167 sub_save.reset_mock()
Matteo Scandoloc6ac74a2018-09-14 08:14:51 -0700168 sub.status = None
Matteo Scandoloea529092018-09-11 16:36:39 -0700169
170 self.si.authentication_state = "REQUESTED"
171 self.policy.update_subscriber(sub, self.si)
172 self.assertEqual(sub.status, "awaiting-auth")
Matteo Scandoloea529092018-09-11 16:36:39 -0700173 sub_save.assert_called()
174 sub_save.reset_mock()
Matteo Scandoloc6ac74a2018-09-14 08:14:51 -0700175 sub.status = None
Matteo Scandoloea529092018-09-11 16:36:39 -0700176
177 self.si.authentication_state = "STARTED"
178 self.policy.update_subscriber(sub, self.si)
179 self.assertEqual(sub.status, "awaiting-auth")
Matteo Scandoloea529092018-09-11 16:36:39 -0700180 sub_save.assert_called()
181 sub_save.reset_mock()
Matteo Scandoloc6ac74a2018-09-14 08:14:51 -0700182 sub.status = None
Matteo Scandoloea529092018-09-11 16:36:39 -0700183
184 self.si.authentication_state = "APPROVED"
185 self.policy.update_subscriber(sub, self.si)
186 self.assertEqual(sub.status, "enabled")
Matteo Scandoloea529092018-09-11 16:36:39 -0700187 sub_save.assert_called()
188 sub_save.reset_mock()
Matteo Scandoloc6ac74a2018-09-14 08:14:51 -0700189 sub.status = None
Matteo Scandoloea529092018-09-11 16:36:39 -0700190
191 self.si.authentication_state = "DENIED"
192 self.policy.update_subscriber(sub, self.si)
193 self.assertEqual(sub.status, "auth-failed")
Matteo Scandoloea529092018-09-11 16:36:39 -0700194 sub_save.assert_called()
195 sub_save.reset_mock()
Matteo Scandoloc6ac74a2018-09-14 08:14:51 -0700196 sub.status = None
197
198 def test_update_subscriber_not(self):
199 sub = RCORDSubscriber(
200 onu_device="BRCM1234"
201 )
202
203 with patch.object(sub, "save") as sub_save:
204 sub.status = "awaiting-auth"
205 self.si.authentication_state = "AWAITING"
206 self.policy.update_subscriber(sub, self.si)
207 sub_save.assert_not_called()
208
209 sub.status = "awaiting-auth"
210 self.si.authentication_state = "REQUESTED"
211 self.policy.update_subscriber(sub, self.si)
212 sub_save.assert_not_called()
213
214 sub.status = "awaiting-auth"
215 self.si.authentication_state = "STARTED"
216 self.policy.update_subscriber(sub, self.si)
217 sub_save.assert_not_called()
218
219 sub.status = "enabled"
220 self.si.authentication_state = "APPROVED"
221 self.policy.update_subscriber(sub, self.si)
222 sub_save.assert_not_called()
223
224 sub.status = "auth-failed"
225 self.si.authentication_state = "DENIED"
226 self.policy.update_subscriber(sub, self.si)
227 sub_save.assert_not_called()
228
Matteo Scandolo74f63302018-11-01 14:05:01 -0700229 def test_update_subscriber_dhcp_with_exiting_ip(self):
Matteo Scandolode8cfa82018-10-16 13:49:05 -0700230 sub = RCORDSubscriber(
Matteo Scandolo74f63302018-11-01 14:05:01 -0700231 id=10,
232 onu_device="BRCM1234"
233 )
234
235 ip = RCORDIpAddress(
236 subscriber_id=sub.id,
237 ip='10.11.2.23'
238 )
239
Andy Bavier8ed30c92018-12-11 13:46:25 -0700240 self.si.authentication_state = "APPROVED"
Matteo Scandolo74f63302018-11-01 14:05:01 -0700241 self.si.dhcp_state = "DHCPACK"
242 self.si.ip_address = "10.11.2.23"
243 self.si.mac_address = "4321"
244
245 with patch.object(sub, "save") as sub_save, \
246 patch.object(RCORDIpAddress.objects, "get_items") as get_ips, \
247 patch.object(ip, "save_changed_fields") as ip_mock:
248
249 get_ips.return_value = [ip]
250 ip_mock.return_value = []
251
252 self.policy.update_subscriber(sub, self.si)
253 sub_save.assert_called()
254 self.assertEqual(sub.mac_address, self.si.mac_address)
255
256 ip_mock.assert_called_with()
257
258 def test_update_subscriber_dhcp_with_new_ip(self):
259 sub = RCORDSubscriber(
260 id=10,
Matteo Scandolode8cfa82018-10-16 13:49:05 -0700261 onu_device="BRCM1234"
262 )
263
Andy Bavier8ed30c92018-12-11 13:46:25 -0700264 self.si.authentication_state = "APPROVED"
Matteo Scandolode8cfa82018-10-16 13:49:05 -0700265 self.si.dhcp_state = "DHCPACK"
Matteo Scandolo74f63302018-11-01 14:05:01 -0700266 self.si.ip_address = "10.11.2.23"
Matteo Scandolode8cfa82018-10-16 13:49:05 -0700267 self.si.mac_address = "4321"
268
Matteo Scandolo74f63302018-11-01 14:05:01 -0700269 with patch.object(sub, "save") as sub_save, \
270 patch.object(RCORDIpAddress, "save", autospec=True) as ip_mock:
271
272 ip_mock.return_value = []
273
Matteo Scandolode8cfa82018-10-16 13:49:05 -0700274 self.policy.update_subscriber(sub, self.si)
275 sub_save.assert_called()
276 self.assertEqual(sub.mac_address, self.si.mac_address)
Matteo Scandolode8cfa82018-10-16 13:49:05 -0700277
Matteo Scandolo74f63302018-11-01 14:05:01 -0700278 saved_ip = ip_mock.call_args[0][0]
279 self.assertEqual(saved_ip.ip, self.si.ip_address)
280 self.assertEqual(saved_ip.subscriber_id, sub.id)
281 self.assertEqual(saved_ip.description, "DHCP Assigned IP Address")
Matteo Scandoloea529092018-09-11 16:36:39 -0700282
283 def test_handle_update_subscriber(self):
Matteo Scandoloe8c33d62018-08-16 14:37:24 -0700284 self.si.onu_state = "DISABLED"
Matteo Scandoload0c1752018-08-09 15:47:16 -0700285
Matteo Scandoloea529092018-09-11 16:36:39 -0700286 sub = RCORDSubscriber(
287 onu_device="BRCM1234"
Matteo Scandoloe8c33d62018-08-16 14:37:24 -0700288 )
289
Matteo Scandoloea529092018-09-11 16:36:39 -0700290 with patch.object(self.policy, "get_subscriber") as get_subscriber, \
Matteo Scandoloc5c558f2018-11-02 10:33:40 -0700291 patch.object(self.policy, "update_onu") as update_onu, \
Matteo Scandoloea529092018-09-11 16:36:39 -0700292 patch.object(self.policy, "update_subscriber") as update_subscriber:
Matteo Scandoload0c1752018-08-09 15:47:16 -0700293
Matteo Scandoloea529092018-09-11 16:36:39 -0700294 get_subscriber.return_value = None
Matteo Scandoload0c1752018-08-09 15:47:16 -0700295 self.policy.handle_update(self.si)
Matteo Scandoloc5c558f2018-11-02 10:33:40 -0700296 update_onu.assert_called_with(sub.onu_device, "DISABLED");
Matteo Scandoloea529092018-09-11 16:36:39 -0700297 self.assertEqual(update_subscriber.call_count, 0)
Matteo Scandoload0c1752018-08-09 15:47:16 -0700298
Matteo Scandoloea529092018-09-11 16:36:39 -0700299 get_subscriber.return_value = sub
Matteo Scandoload0c1752018-08-09 15:47:16 -0700300 self.policy.handle_update(self.si)
Matteo Scandoloea529092018-09-11 16:36:39 -0700301 update_subscriber.assert_called_with(sub, self.si)
302
Matteo Scandoload0c1752018-08-09 15:47:16 -0700303
Matteo Scandoload0c1752018-08-09 15:47:16 -0700304if __name__ == '__main__':
305 unittest.main()
306