blob: 7fee9ae33a433739ab604c59747753175cc42c02 [file] [log] [blame]
Chip Boling67b674a2019-02-08 11:42:18 -06001#
2# Copyright 2017 the original author or authors.
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#
Zack Williams84a71e92019-11-15 09:00:19 -070016from __future__ import absolute_import
Chip Boling67b674a2019-02-08 11:42:18 -060017import binascii
Chip Bolingce2daf62019-02-12 13:53:39 -060018from pyvoltha.adapters.common.frameio.frameio import hexify
Chip Boling67b674a2019-02-08 11:42:18 -060019from twisted.python.failure import Failure
20from unittest import TestCase, main, skip
Zack Williams84a71e92019-11-15 09:00:19 -070021from .mock.mock_adapter_agent import MockAdapterAgent
22from .mock.mock_onu_handler import MockOnuHandler
23from .mock.mock_olt_handler import MockOltHandler
24from .mock.mock_onu import MockOnu
Chip Boling67b674a2019-02-08 11:42:18 -060025from pyvoltha.adapters.extensions.omci.omci_defs import *
26from pyvoltha.adapters.extensions.omci.omci_frame import *
27from pyvoltha.adapters.extensions.omci.omci_entities import *
28from pyvoltha.adapters.extensions.omci.omci_me import ExtendedVlanTaggingOperationConfigurationDataFrame
29from pyvoltha.adapters.extensions.omci.omci_cc import OMCI_CC, UNKNOWN_CLASS_ATTRIBUTE_KEY,\
30 MAX_OMCI_REQUEST_AGE
Zack Williams84a71e92019-11-15 09:00:19 -070031from six.moves import range
Chip Boling67b674a2019-02-08 11:42:18 -060032
33DEFAULT_OLT_DEVICE_ID = 'default_olt_mock'
34DEFAULT_ONU_DEVICE_ID = 'default_onu_mock'
35DEFAULT_PON_ID = 0
36DEFAULT_ONU_ID = 0
37DEFAULT_ONU_SN = 'TEST00000001'
38
39OP = EntityOperations
40RC = ReasonCodes
41
42successful = False
43error_reason = None
44
45
46def chunk(indexable, chunk_size):
47 for i in range(0, len(indexable), chunk_size):
48 yield indexable[i:i + chunk_size]
49
50
51def hex2raw(hex_string):
52 return ''.join(chr(int(byte, 16)) for byte in chunk(hex_string, 2))
53
54
55class TestOmciCc(TestCase):
56 """
57 Test the Open OMCI Communication channels
58
59 Note also added some testing of MockOnu behaviour since its behaviour during more
60 complicated unit/integration tests may be performed in the future.
61 """
62 def setUp(self, let_msg_timeout=False):
63 self.adapter_agent = MockAdapterAgent()
64
65 def tearDown(self):
66 if self.adapter_agent is not None:
67 self.adapter_agent.tearDown()
68
69 def setup_mock_olt(self, device_id=DEFAULT_OLT_DEVICE_ID):
70 handler = MockOltHandler(self.adapter_agent, device_id)
71 self.adapter_agent.add_device(handler.device)
72 return handler
73
74 def setup_mock_onu(self, parent_id=DEFAULT_OLT_DEVICE_ID,
75 device_id=DEFAULT_ONU_DEVICE_ID,
76 pon_id=DEFAULT_PON_ID,
77 onu_id=DEFAULT_ONU_ID,
78 serial_no=DEFAULT_ONU_SN):
79 handler = MockOnuHandler(self.adapter_agent, parent_id, device_id, pon_id, onu_id)
80 handler.serial_number = serial_no
81 onu = MockOnu(serial_no, self.adapter_agent, handler.device_id) \
82 if serial_no is not None else None
83 handler.onu_mock = onu
84 return handler
85
86 def setup_one_of_each(self, timeout_messages=False):
87 # Most tests will use at lease one or more OLT and ONU
88 self.olt_handler = self.setup_mock_olt()
89 self.onu_handler = self.setup_mock_onu(parent_id=self.olt_handler.device_id)
90 self.onu_device = self.onu_handler.onu_mock
91 self.adapter_agent.timeout_the_message = timeout_messages
92
93 self.adapter_agent.add_child_device(self.olt_handler.device,
94 self.onu_handler.device)
95
96 def _is_omci_frame(self, results, omci_msg_type):
97 assert isinstance(results, OmciFrame), 'Not OMCI Frame'
98 assert 'omci_message' in results.fields, 'Not OMCI Frame'
99 if omci_msg_type is not None:
100 assert isinstance(results.fields['omci_message'], omci_msg_type)
101 return results
102
103 def _check_status(self, results, value):
104 if value is not None: assert results is not None, 'unexpected emtpy message'
105 status = results.fields['omci_message'].fields['success_code']
106 assert status == value,\
107 'Unexpected Status Code. Got {}, Expected: {}'.format(status, value)
108 return results
109
110 def _check_mib_sync(self, results, value):
111 assert self.onu_device.mib_data_sync == value, \
112 'Unexpected MIB DATA Sync value. Got {}, Expected: {}'.format(
113 self.onu_device.mib_data_sync, value)
114 return results
115
116 def _check_stats(self, results, _, stat, expected):
117 snapshot = self._snapshot_stats()
118 assert snapshot[stat] == expected, \
119 'Invalid statistic "{}". Got {}, Expected: {}'.format(stat,
120 snapshot[stat],
121 expected)
122 return results
123
124 def _check_value_equal(self, results, name, value, expected):
125 assert value == expected, \
126 'Value "{}" not equal. Got {}, Expected: {}'.format(name, value,
127 expected)
128 return results
129
130 def _default_errback(self, failure):
131 from twisted.internet.defer import TimeoutError
132 assert isinstance(failure.type, type(TimeoutError))
133
134 def _snapshot_stats(self):
135 omci_cc = self.onu_handler.omci_cc
136 return {
137 'tx_frames': omci_cc.tx_frames,
138 'rx_frames': omci_cc.rx_frames,
139 'rx_unknown_tid': omci_cc.rx_unknown_tid,
140 'rx_onu_frames': omci_cc.rx_onu_frames,
141 'rx_onu_discards': omci_cc.rx_onu_discards,
142 'rx_timeouts': omci_cc.rx_timeouts,
143 'rx_unknown_me': omci_cc.rx_unknown_me,
144 'rx_late': omci_cc.rx_late,
145 'tx_errors': omci_cc.tx_errors,
146 'consecutive_errors': omci_cc.consecutive_errors,
147 'reply_min': omci_cc.reply_min,
148 'reply_max': omci_cc.reply_max,
149 'reply_average': omci_cc.reply_average,
150 'hp_tx_queue_len': omci_cc.hp_tx_queue_len,
151 'lp_tx_queue_len': omci_cc.lp_tx_queue_len,
152 'max_hp_tx_queue': omci_cc.max_hp_tx_queue,
153 'max_lp_tx_queue': omci_cc._max_lp_tx_queue,
154 }
155
156 def test_default_init(self):
157 self.setup_one_of_each()
158 # Test default construction of OMCI_CC as well as
159 # various other parameter settings
160 omci_cc = self.onu_handler.omci_cc
161
162 # No device directly associated
163 self.assertIsNotNone(omci_cc._adapter_agent)
164 self.assertIsNone(omci_cc._proxy_address)
165
166 # No outstanding requests
167 self.assertEqual(len(omci_cc._pending[OMCI_CC.LOW_PRIORITY]), 0)
168 self.assertEqual(len(omci_cc._pending[OMCI_CC.HIGH_PRIORITY]), 0)
169
170 # No active requests
171 self.assertIsNone(omci_cc._tx_request[OMCI_CC.LOW_PRIORITY])
172 self.assertIsNone(omci_cc._tx_request[OMCI_CC.HIGH_PRIORITY])
173
174 # Flags/properties
175 self.assertFalse(omci_cc.enabled)
176
177 # Statistics
178 self.assertEqual(omci_cc.tx_frames, 0)
179 self.assertEqual(omci_cc.rx_frames, 0)
180 self.assertEqual(omci_cc.rx_unknown_tid, 0)
181 self.assertEqual(omci_cc.rx_onu_frames, 0)
182 self.assertEqual(omci_cc.rx_onu_discards, 0)
183 self.assertEqual(omci_cc.rx_unknown_me, 0)
184 self.assertEqual(omci_cc.rx_timeouts, 0)
185 self.assertEqual(omci_cc.rx_late, 0)
186 self.assertEqual(omci_cc.tx_errors, 0)
187 self.assertEqual(omci_cc.consecutive_errors, 0)
188 self.assertNotEquals(omci_cc.reply_min, 0.0)
189 self.assertEqual(omci_cc.reply_max, 0.0)
190 self.assertEqual(omci_cc.reply_average, 0.0)
191 self.assertEqual(omci_cc.lp_tx_queue_len, 0.0)
192 self.assertEqual(omci_cc.max_hp_tx_queue, 0.0)
193 self.assertEqual(omci_cc._max_hp_tx_queue, 0.0)
194 self.assertEqual(omci_cc._max_lp_tx_queue, 0.0)
195
196 def test_enable_disable(self):
197 self.setup_one_of_each()
198
199 # Test enable property
200 omci_cc = self.onu_handler.omci_cc
201
202 # Initially disabled
203 self.assertFalse(omci_cc.enabled)
204 omci_cc.enabled = False
205 self.assertFalse(omci_cc.enabled)
206
207 omci_cc.enabled = True
208 self.assertTrue(omci_cc.enabled)
209 self.assertIsNotNone(omci_cc._proxy_address)
210 self.assertEqual(len(omci_cc._pending[OMCI_CC.LOW_PRIORITY]), 0)
211 self.assertEqual(len(omci_cc._pending[OMCI_CC.HIGH_PRIORITY]), 0)
212
213 omci_cc.enabled = True # Should be a NOP
214 self.assertTrue(omci_cc.enabled)
215 self.assertIsNotNone(omci_cc._proxy_address)
216 self.assertEqual(len(omci_cc._pending[OMCI_CC.LOW_PRIORITY]), 0)
217 self.assertEqual(len(omci_cc._pending[OMCI_CC.HIGH_PRIORITY]), 0)
218
219 omci_cc.enabled = False
220 self.assertFalse(omci_cc.enabled)
221 self.assertIsNone(omci_cc._proxy_address)
222
223 def test_rx_discard_if_disabled(self):
224 # ME without a known decoder
225 self.setup_one_of_each()
226
227 omci_cc = self.onu_handler.omci_cc
228 omci_cc.enabled = False
229 snapshot = self._snapshot_stats()
230
231 msg = '00fc2e0a00020000ff780000e00000010000000c' \
232 '0000000000000000000000000000000000000000' \
233 '00000028105a86ef'
234
235 omci_cc.receive_message(hex2raw(msg))
236
237 # Note: No counter increments
238 self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'])
239 self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'])
240 self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'])
241 self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'])
242
243 def test_message_send_get(self):
244 # Various tests of sending an OMCI message and it either
245 # getting a response or send catching some errors of
246 # importance
247 self.setup_one_of_each()
248
249 omci_cc = self.onu_handler.omci_cc
250 omci_cc.enabled = True
251 snapshot = self._snapshot_stats()
252 mib_data_sync = self.onu_device.mib_data_sync
253
254 # GET
255 # d = omci_cc.send() # TODO: Implement
256 #
257 # d.addCallbacks(self._is_omci_frame, self._default_errback)
258 # d.addCallback(self._check_status, RC.Success.value)
259 # d.addCallback(self._check_mib_sync, mib_data_sync)
260 #
261 # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1)
262 # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1)
263 # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid'])
264 # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames'])
265 # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards'])
266 # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me'])
267 # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts'])
268 # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'])
269 # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors)
270
271 # return d
272
273 def test_message_send_set(self):
274 # Various tests of sending an OMCI message and it either
275 # getting a response or send catching some errors of
276 # importance
277 self.setup_one_of_each()
278
279 omci_cc = self.onu_handler.omci_cc
280 omci_cc.enabled = True
281 snapshot = self._snapshot_stats()
282 mib_data_sync = self.onu_device.mib_data_sync
283
284 # SET
285 # d = omci_cc.send() # TODO: Implement
286 #
287 # d.addCallbacks(self._is_omci_frame, self._default_errback)
288 # d.addCallback(self._check_status, RC.Success.value)
289 # d.addCallback(self._check_mib_sync, mib_data_sync + 1 if mib_data_sync < 255 else 1)
290 #
291 # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1)
292 # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1)
293 # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid'])
294 # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames'])
295 # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards'])
296 # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me'])
297 # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts'])
298 # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'])
299 # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors)
300
301 # return d
302 #
303 # # Also test mib_data_sync rollover. 255 -> 1 (zero reserved)
304 #
305 # self.onu_device.mib_data_sync = 255
306 # # SET
307 # self.assertTrue(True) # TODO: Implement (copy previous one here)
308 # self.assertEqual(1, self.onu_device.mib_data_sync)
309
310 def test_message_send_create(self):
311 # Various tests of sending an OMCI message and it either
312 # getting a response or send catching some errors of
313 # importance
314 self.setup_one_of_each()
315
316 omci_cc = self.onu_handler.omci_cc
317 omci_cc.enabled = True
318 snapshot = self._snapshot_stats()
319 mib_data_sync = self.onu_device.mib_data_sync
320
321 # Create
322 # d = omci_cc.send() # TODO: Implement
323 #
324 # d.addCallbacks(self._is_omci_frame, self._default_errback)
325 # d.addCallback(self._check_status, RC.Success.value)
326 # d.addCallback(self._check_mib_sync, mib_data_sync + 1 if mib_data_sync < 255 else 1)
327 #
328 # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1)
329 # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1)
330 # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid'])
331 # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames'])
332 # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards'])
333 # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me'])
334 # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts'])
335 # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'])
336 # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors)
337
338 # return d
339
340 def test_message_send_delete(self):
341 # Various tests of sending an OMCI message and it either
342 # getting a response or send catching some errors of
343 # importance
344 self.setup_one_of_each()
345
346 omci_cc = self.onu_handler.omci_cc
347 omci_cc.enabled = True
348 snapshot = self._snapshot_stats()
349 mib_data_sync = self.onu_device.mib_data_sync
350
351 # Delete
352 # d = omci_cc.send() # TODO: Implement
353 #
354 # d.addCallbacks(self._is_omci_frame, self._default_errback)
355 # d.addCallback(self._check_status, RC.Success.value)
356 # d.addCallback(self._check_mib_sync, mib_data_sync + 1 if mib_data_sync < 255 else 1)
357 #
358 # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1)
359 # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1)
360 # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid'])
361 # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames'])
362 # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards'])
363 # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me'])
364 # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts'])
365 # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'])
366 # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors)
367
368 # return d
369
370 def test_message_send_mib_reset(self):
371 self.setup_one_of_each()
372
373 omci_cc = self.onu_handler.omci_cc
374 omci_cc.enabled = True
375 self.onu_device.mib_data_sync = 10
376 snapshot = self._snapshot_stats()
377
378 # Successful MIB Reset
379 d = omci_cc.send_mib_reset(timeout=1.0)
380
381 d.addCallbacks(self._is_omci_frame, self._default_errback)
382 d.addCallback(self._check_status, RC.Success)
383 d.addCallback(self._check_mib_sync, 0)
384
385 d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1)
386 d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1)
387 d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid'])
388 d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames'])
389 d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards'])
390 d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me'])
391 d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts'])
392 d.addCallback(self._check_stats, snapshot, 'rx_late', snapshot['rx_late'])
393 d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'])
394 d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors)
395 return d
396
397 def test_message_send_mib_upload(self):
398 self.setup_one_of_each()
399
400 omci_cc = self.onu_handler.omci_cc
401 omci_cc.enabled = True
402 snapshot = self._snapshot_stats()
403 mib_data_sync = self.onu_device.mib_data_sync
404
405 # MIB Upload
406 d = omci_cc.send_mib_upload(timeout=1.0)
407
408 d.addCallbacks(self._is_omci_frame, self._default_errback)
409 d.addCallback(self._check_status, RC.Success)
410 d.addCallback(self._check_mib_sync, mib_data_sync)
411
412 # TODO: MIB Upload Results specific tests here
413
414 d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1)
415 d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1)
416 d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid'])
417 d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames'])
418 d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards'])
419 d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me'])
420 d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts'])
421 d.addCallback(self._check_stats, snapshot, 'rx_late', snapshot['rx_late'])
422 d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'])
423 d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors)
424 return d
425
426 def test_message_send_mib_upload_next(self):
427 self.setup_one_of_each()
428
429 omci_cc = self.onu_handler.omci_cc
430 omci_cc.enabled = True
431 snapshot = self._snapshot_stats()
432 mib_data_sync = self.onu_device.mib_data_sync
433
434 # # MIB Upload Next
435 # d = omci_cc.send_mib_upload_next(0, timeout=1.0)
436 #
437 # d.addCallbacks(self._is_omci_frame, self._default_errback)
438 # d.addCallback(self._check_status, RC.Success)
439 # d.addCallback(self._check_mib_sync, mib_data_sync)
440 #
441 # # TODO: MIB Upload Next Results specific tests here
442 #
443 # d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1)
444 # d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1)
445 # d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid'])
446 # d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames'])
447 # d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards'])
448 # d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me'])
449 # d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts'])
450 # d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'])
451 # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors)
452 # return d
453
454 def test_message_send_no_timeout(self):
455 self.setup_one_of_each()
456
457 omci_cc = self.onu_handler.omci_cc
458 omci_cc.enabled = True
459 self.onu_device.mib_data_sync = 10
460 snapshot = self._snapshot_stats()
461
462 d = omci_cc.send_mib_reset(timeout=0)
463 d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1)
464 d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'])
465 d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'])
466 return d
467
468 def test_message_send_bad_timeout(self):
469 self.setup_one_of_each()
470
471 omci_cc = self.onu_handler.omci_cc
472 omci_cc.enabled = True
473 self.onu_device.mib_data_sync = 10
474 snapshot = self._snapshot_stats()
475
476 d = omci_cc.send_mib_reset(timeout=MAX_OMCI_REQUEST_AGE + 1)
477 d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'])
478 d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'])
479 d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'] + 1)
480 return d
481
482 def test_message_send_not_a_frame(self):
483 self.setup_one_of_each()
484
485 omci_cc = self.onu_handler.omci_cc
486 omci_cc.enabled = True
487 self.onu_device.mib_data_sync = 10
488 snapshot = self._snapshot_stats()
489
490 d = omci_cc.send('hello world', timeout=1)
491 d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'])
492 d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'])
493 d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'] + 1)
494 return d
495
496 def test_message_send_reboot(self):
497 self.setup_one_of_each()
498
499 omci_cc = self.onu_handler.omci_cc
500 omci_cc.enabled = True
501 snapshot = self._snapshot_stats()
502
503 # ONU Reboot
504 d = omci_cc.send_reboot(timeout=1.0)
505
506 d.addCallbacks(self._is_omci_frame, self._default_errback)
507 d.addCallback(self._check_status, RC.Success)
508
509 d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 1)
510 d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 1)
511 d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid'])
512 d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames'])
513 d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards'])
514 d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me'])
515 d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts'])
516 d.addCallback(self._check_stats, snapshot, 'rx_late', snapshot['rx_late'])
517 d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'])
518 d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors)
519 return d
520
521 def test_message_send_with_omci_disabled(self):
522 self.setup_one_of_each()
523
524 omci_cc = self.onu_handler.omci_cc
525 self.assertFalse(omci_cc.enabled)
526
527 # Successful MIB Reset
528 d = omci_cc.send_mib_reset(timeout=1.0)
529
530 def success_is_bad(_results):
531 assert False, 'This test should throw a failure/error'
532
533 def fail_fast(_failure):
534 pass
535 return None
536
537 d.addCallbacks(success_is_bad, fail_fast)
538 return d
539
540 def test_message_send_get_with_latency(self):
541 # Various tests of sending an OMCI message and it either
542 # getting a response or send catching some errors of
543 # importance
544 self.setup_one_of_each()
545 self.olt_handler.latency = 0.500 # 1/2 second
546
547 omci_cc = self.onu_handler.omci_cc
548 omci_cc.enabled = True
549
550 # Successful MIB Reset
551 d = omci_cc.send_mib_reset(timeout=1.0)
552
553 d.addCallbacks(self._is_omci_frame, self._default_errback)
554 d.addCallback(self._check_status, RC.Success)
555
556 def check_latency_values(_):
557 self.assertGreaterEqual(omci_cc.reply_min, self.olt_handler.latency)
558 self.assertGreaterEqual(omci_cc.reply_max, self.olt_handler.latency)
559 self.assertGreaterEqual(omci_cc.reply_average, self.olt_handler.latency)
560
561 d.addCallback(check_latency_values)
562 return d
563
564 def test_message_failures(self):
565 # Various tests of sending an OMCI message and it fails
566 self.setup_one_of_each()
567
568 omci_cc = self.onu_handler.omci_cc
569 omci_cc.enabled = True
570 snapshot = self._snapshot_stats()
571
572 self.assertEqual(omci_cc.tx_frames, 0)
573 self.assertEqual(omci_cc.rx_frames, 0)
574 self.assertEqual(omci_cc.rx_unknown_tid, 0)
575 self.assertEqual(omci_cc.rx_timeouts, 0)
576 self.assertEqual(omci_cc.rx_late, 0)
577 self.assertEqual(omci_cc.tx_errors, 0)
578
579 # # Class ID not found
580 # d = omci_cc.send_mib_reset(timeout=1.0)
581 # self.assertTrue(True) # TODO: Implement
582 # todo: Test non-zero consecutive errors
583 #
584 # # Instance ID not found
585 # d = omci_cc.send_mib_reset(timeout=1.0)
586 # self.assertTrue(True) # TODO: Implement
587 # todo: Test non-zero consecutive errors
588 #
589 # # PON is disabled
590 # d = omci_cc.send_mib_reset(timeout=1.0)
591 # self.assertTrue(True) # TODO: Implement
592 # todo: Test non-zero consecutive errors
593 #
594 # # ONU is disabled
595 # d = omci_cc.send_mib_reset(timeout=1.0)
596 # self.assertTrue(True) # TODO: Implement
597 # todo: Test non-zero consecutive errors
598 #
599 # # ONU is not activated
600 # d = omci_cc.send_mib_reset(timeout=1.0)
601 # self.assertTrue(True) # TODO: Implement
602 # todo: Test non-zero consecutive errors
603
604 # TODO: make OLT send back an unknown TID (
605
606 # todo: Test non-zero consecutive errors
607 # todo: Send a good frame
608 # todo: Test zero consecutive errors
609 # d.addCallback(self._check_value_equal, 'consecutive_errors', 0, omci_cc.consecutive_errors)
610
611 def test_rx_unknown_me(self):
612 # ME without a known decoder
613 self.setup_one_of_each()
614
615 omci_cc = self.onu_handler.omci_cc
616 omci_cc.enabled = True
617 snapshot = self._snapshot_stats()
618
619 # This is the ID ------+
620 # v
621 msg = '00fc2e0a00020000ff780000e00000010000000c' \
622 '0000000000000000000000000000000000000000' \
623 '00000028'
624
625 omci_cc.receive_message(hex2raw(msg))
626
627 # Note: After successful frame decode, a lookup of the corresponding request by
628 # TID is performed. None should be found, so we should see the Rx Unknown TID
629 # increment.
William Kurkian16b767a2019-05-07 17:02:19 -0400630 self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'] + 1)
Chip Boling67b674a2019-02-08 11:42:18 -0600631 self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'] + 1)
632 self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'] + 1)
633 self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'])
634 self.assertEqual(omci_cc.consecutive_errors, 0)
635
636 def test_rx_decode_unknown_me(self):
637 # ME without a known decoder
638 self.setup_one_of_each()
639
640 omci_cc = self.onu_handler.omci_cc
641 omci_cc.enabled = True
642 snapshot = self._snapshot_stats()
643
644 # This is a MIB Upload Next Response. Where we would probably first see an
645 # unknown Class ID
646 #
647 # This is the ID ------+
648 # v
649 msg = '00fc2e0a00020000ff780001e000'
650 blob = '00010000000c0000000000000000000000000000000000000000'
651 msg += blob + '00000028'
652
653 # Dig into the internal method so we can get the returned frame
654 frame = omci_cc._decode_unknown_me(hex2raw(msg))
655
656 self.assertEqual(frame.fields['transaction_id'], 0x00fc)
657 self.assertEqual(frame.fields['message_type'], 0x2e)
658
659 omci_fields = frame.fields['omci_message'].fields
660
661 self.assertEqual(omci_fields['entity_class'], 0x0002)
662 self.assertEqual(omci_fields['entity_id'], 0x00)
663 self.assertEqual(omci_fields['object_entity_class'], 0x0ff78)
664 self.assertEqual(omci_fields['object_entity_id'], 0x01)
665 self.assertEqual(omci_fields['object_attributes_mask'], 0xe000)
666
667 data_fields = omci_fields['object_data']
668
669 decoded_blob = data_fields.get(UNKNOWN_CLASS_ATTRIBUTE_KEY)
670 self.assertIsNotNone(decoded_blob)
671 self.assertEqual(decoded_blob, blob)
672
William Kurkian16b767a2019-05-07 17:02:19 -0400673 def test_rx_unknown_me_avc(self):
674 # ME without a known decoder but is and attribute value change
Chip Boling67b674a2019-02-08 11:42:18 -0600675 self.setup_one_of_each()
676
677 omci_cc = self.onu_handler.omci_cc
678 omci_cc.enabled = True
679 snapshot = self._snapshot_stats()
680
William Kurkian16b767a2019-05-07 17:02:19 -0400681 msg = '0000110aff78000080000e000000' \
682 '00000000000000000000000000000000000000000000000000000' \
683 '00000028'
Chip Boling67b674a2019-02-08 11:42:18 -0600684
William Kurkian16b767a2019-05-07 17:02:19 -0400685 omci_cc.receive_message(hex2raw(msg))
Chip Boling67b674a2019-02-08 11:42:18 -0600686
William Kurkian16b767a2019-05-07 17:02:19 -0400687 # Blob decode should work and then it should be passed off to the
688 # ONU Autonomous frame processor
689 self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'])
690 self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'] + 1)
691 self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'])
692 self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'] + 1)
693 self.assertEqual(omci_cc.rx_onu_discards, snapshot['rx_onu_discards'])
694 self.assertEqual(omci_cc.consecutive_errors, 0)
Chip Boling67b674a2019-02-08 11:42:18 -0600695
696 def test_rx_discard_if_disabled(self):
697 # ME without a known decoder
698 self.setup_one_of_each()
699
700 omci_cc = self.onu_handler.omci_cc
701 omci_cc.enabled = False
702 snapshot = self._snapshot_stats()
703
704 msg = '00fc2e0a00020000ff780000e00000010000000c' \
705 '0000000000000000000000000000000000000000' \
706 '00000028105a86ef'
707
708 omci_cc.receive_message(hex2raw(msg))
709
710 # Note: No counter increments
711 self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'])
712 self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'])
713 self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'])
714 self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'])
715
716 def test_omci_alarm_decode(self):
717 """
718 This test covers an issue discovered in Sept 2018 (JIRA-1213). It was
719 an exception during frame decode.
720 """
721 self.setup_one_of_each()
722
723 omci_cc = self.onu_handler.omci_cc
724 omci_cc.enabled = True
725 snapshot = self._snapshot_stats()
726
727 # Frame from the JIRA issue
728 msg = '0000100a000b0102800000000000000000000000' \
729 '0000000000000000000000000000000000000015' \
730 '000000282d3ae0a6'
731
732 _results = omci_cc.receive_message(hex2raw(msg))
733
734 self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'])
735 self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'])
736 self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'])
737 self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'] + 1)
738 self.assertEqual(omci_cc.rx_onu_discards, snapshot['rx_onu_discards'])
739
740 def test_omci_avc_decode(self):
741 self.setup_one_of_each()
742
743 omci_cc = self.onu_handler.omci_cc
744 omci_cc.enabled = True
745 snapshot = self._snapshot_stats()
746
747 # Frame from the JIRA issue
748 msg = '0000110a0007000080004d4c2d33363236000000' \
749 '0000000020202020202020202020202020202020' \
750 '00000028'
751
752 _results = omci_cc.receive_message(hex2raw(msg))
753
754 self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'])
755 self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'])
756 self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'])
757 self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'] + 1)
758 self.assertEqual(omci_cc.rx_onu_discards, snapshot['rx_onu_discards'])
759
760 def test_omci_unknown_onu_decode(self):
761 self.setup_one_of_each()
762
763 omci_cc = self.onu_handler.omci_cc
764 omci_cc.enabled = True
765 snapshot = self._snapshot_stats()
766
767 # Frame from the JIRA issue
768 msg = '0000190a0007000080004d4c2d33363236000000' \
769 '0000000020202020202020202020202020202020' \
770 '00000028'
771
772 _results = omci_cc.receive_message(hex2raw(msg))
773
774 self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'])
775 self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'])
776 self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'])
777 self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'] + 1)
778 self.assertEqual(omci_cc.rx_onu_discards, snapshot['rx_onu_discards'] + 1)
779
780 def test_omci_bad_frame_decode(self):
781 self.setup_one_of_each()
782
783 omci_cc = self.onu_handler.omci_cc
784 omci_cc.enabled = True
785 snapshot = self._snapshot_stats()
786
787 # Frame from the JIRA issue
788 msg = '0020190a0007000080004d4c2d33363236000000' \
789 '0000000000000028'
790
791 _results = omci_cc.receive_message(hex2raw(msg))
792 # NOTE: Currently do not increment any Rx Discard counters, just throw it away
793 self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'] + 1)
794 self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'])
795 self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'] + 1)
796 self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'])
797 self.assertEqual(omci_cc.rx_onu_discards, snapshot['rx_onu_discards'])
798
799 def test_rx_decode_onu_g(self):
800 self.setup_one_of_each()
801
802 omci_cc = self.onu_handler.omci_cc
803 omci_cc.enabled = True
804 snapshot = self._snapshot_stats()
805
806 msg = '001e2e0a0002000001000000e000424657530000' \
807 '0000000000000000000000324246575300107496' \
808 '00000028e7fb4a91'
809
810 omci_cc.receive_message(hex2raw(msg))
811
812 # Note: No counter increments
813 self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'] + 1)
814 self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'])
815 self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'] + 1)
816 self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'])
817
818 def test_rx_decode_extvlantagging(self):
819 self.setup_one_of_each()
820
821 omci_cc = self.onu_handler.omci_cc
822 omci_cc.enabled = True
823 snapshot = self._snapshot_stats()
824
825 msg = '030a290a00ab0201000d00000000001031323334' \
826 '3536373839303132333435363738393031323334' \
827 '000000281166d283'
828
829 omci_cc.receive_message(hex2raw(msg))
830
831 self.assertEqual(omci_cc.rx_frames, snapshot['rx_frames'] + 1)
832 self.assertEqual(omci_cc.rx_unknown_me, snapshot['rx_unknown_me'])
833 self.assertEqual(omci_cc.rx_unknown_tid, snapshot['rx_unknown_tid'] + 1)
834 self.assertEqual(omci_cc.rx_onu_frames, snapshot['rx_onu_frames'])
835
836 def _check_vlan_tag_op(self, results, attr, expected):
837 omci_msg = results.fields['omci_message']
838 data = omci_msg.fields['data']
839 val = data[attr]
840 self.assertEqual(expected, val)
841 return results
842
Chip Boling67b674a2019-02-08 11:42:18 -0600843 #@deferred()
844 def test_rx_table_get_extvlantagging(self):
845 self.setup_one_of_each()
846
847 onu = self.onu_handler.onu_mock
848 entity_id = 1
849 vlan_tag_op1 = VlanTaggingOperation(
850 filter_outer_priority=15,
851 filter_outer_vid=4096,
852 filter_outer_tpid_de=2,
853 filter_inner_priority=15,
854 filter_inner_vid=4096,
855 filter_inner_tpid_de=0,
856 filter_ether_type=0,
857 treatment_tags_to_remove=0,
858 treatment_outer_priority=15,
859 treatment_outer_vid=1234,
860 treatment_outer_tpid_de=0,
861 treatment_inner_priority=0,
862 treatment_inner_vid=4091,
863 treatment_inner_tpid_de=4,
864 )
865 vlan_tag_op2 = VlanTaggingOperation(
866 filter_outer_priority=14,
867 filter_outer_vid=1234,
868 filter_outer_tpid_de=5,
869 filter_inner_priority=1,
870 filter_inner_vid=2345,
871 filter_inner_tpid_de=1,
872 filter_ether_type=0,
873 treatment_tags_to_remove=1,
874 treatment_outer_priority=15,
875 treatment_outer_vid=2222,
876 treatment_outer_tpid_de=1,
877 treatment_inner_priority=1,
878 treatment_inner_vid=3333,
879 treatment_inner_tpid_de=5,
880 )
881 vlan_tag_op3 = VlanTaggingOperation(
882 filter_outer_priority=13,
883 filter_outer_vid=55,
884 filter_outer_tpid_de=1,
885 filter_inner_priority=7,
886 filter_inner_vid=4567,
887 filter_inner_tpid_de=1,
888 filter_ether_type=0,
889 treatment_tags_to_remove=1,
890 treatment_outer_priority=2,
891 treatment_outer_vid=1111,
892 treatment_outer_tpid_de=1,
893 treatment_inner_priority=1,
894 treatment_inner_vid=3131,
895 treatment_inner_tpid_de=5,
896 )
897 tbl = [vlan_tag_op1, vlan_tag_op2, vlan_tag_op3]
898 tblstr = str(vlan_tag_op1) + str(vlan_tag_op2) + str(vlan_tag_op3)
899
900 onu._omci_response[OP.Get.value][ExtendedVlanTaggingOperationConfigurationData.class_id] = {
901 entity_id: OmciFrame(transaction_id=0,
902 message_type=OmciGetResponse.message_id,
903 omci_message=OmciGetResponse(
904 entity_class=ExtendedVlanTaggingOperationConfigurationData.class_id,
905 entity_id=1,
906 success_code=RC.Success.value,
907 attributes_mask=ExtendedVlanTaggingOperationConfigurationData.mask_for(
908 'received_frame_vlan_tagging_operation_table'),
909 data={'received_frame_vlan_tagging_operation_table': 16 * len(tbl)}
910 ))
911 }
912
913 rsp1 = binascii.a2b_hex(hexify(tblstr[0:OmciTableField.PDU_SIZE]))
914 rsp2 = binascii.a2b_hex(hexify(tblstr[OmciTableField.PDU_SIZE:]))
915 onu._omci_response[OP.GetNext.value][ExtendedVlanTaggingOperationConfigurationData.class_id] = {
916 entity_id: {0: {'failures':2,
917 'frame':OmciFrame(transaction_id=0,
918 message_type=OmciGetNextResponse.message_id,
919 omci_message=OmciGetNextResponse(
920 entity_class=ExtendedVlanTaggingOperationConfigurationData.class_id,
921 entity_id=1,
922 success_code=RC.Success.value,
923 attributes_mask=ExtendedVlanTaggingOperationConfigurationData.mask_for(
924 'received_frame_vlan_tagging_operation_table'),
925 data={'received_frame_vlan_tagging_operation_table': rsp1
926 }
927 ))},
928 1: OmciFrame(transaction_id=0,
929 message_type=OmciGetNextResponse.message_id,
930 omci_message=OmciGetNextResponse(
931 entity_class=ExtendedVlanTaggingOperationConfigurationData.class_id,
932 entity_id=1,
933 success_code=RC.Success.value,
934 attributes_mask=ExtendedVlanTaggingOperationConfigurationData.mask_for(
935 'received_frame_vlan_tagging_operation_table'),
936 data={'received_frame_vlan_tagging_operation_table': rsp2
937 }
938 ))
939 }
940 }
941
942 omci_cc = self.onu_handler.omci_cc
943 omci_cc.enabled = True
944
945 msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
946 entity_id,
947 attributes={'received_frame_vlan_tagging_operation_table':True}
948 )
949
950 snapshot = self._snapshot_stats()
951
952 frame = msg.get()
953 d = omci_cc.send(frame, timeout=5.0)
954
955 d.addCallbacks(self._is_omci_frame, self._default_errback, [OmciGetResponse])
956 d.addCallback(self._check_status, RC.Success)
957
958 d.addCallback(self._check_stats, snapshot, 'tx_frames', snapshot['tx_frames'] + 5)
959 d.addCallback(self._check_stats, snapshot, 'rx_frames', snapshot['rx_frames'] + 3)
960 d.addCallback(self._check_stats, snapshot, 'rx_unknown_tid', snapshot['rx_unknown_tid'])
961 d.addCallback(self._check_stats, snapshot, 'rx_onu_frames', snapshot['rx_onu_frames'])
962 d.addCallback(self._check_stats, snapshot, 'rx_onu_discards', snapshot['rx_onu_discards'])
963 d.addCallback(self._check_stats, snapshot, 'rx_unknown_me', snapshot['rx_unknown_me'])
964 d.addCallback(self._check_stats, snapshot, 'rx_timeouts', snapshot['rx_timeouts'] + 2)
965 d.addCallback(self._check_stats, snapshot, 'rx_late', snapshot['rx_late'])
966 d.addCallback(self._check_stats, snapshot, 'tx_errors', snapshot['tx_errors'])
967 d.addCallback(self._check_stats, snapshot, 'consecutive_errors', 0)
968 d.addCallback(self._check_vlan_tag_op, 'received_frame_vlan_tagging_operation_table', tbl)
969
970 return d
971
972 ##################################################################
973 # Start of tests specific to new stop_and_wait changes
974 #
975 def test_message_send_low_priority(self):
976 # self.setup_one_of_each(timeout_messages=True)
977 self.setup_one_of_each()
978
979 omci_cc = self.onu_handler.omci_cc
980 omci_cc.enabled = True
981 snapshot = self._snapshot_stats()
982
983 # MIB Upload
984 d = omci_cc.send_mib_upload(timeout=1.0, high_priority=False)
985 d.addCallback(self._check_stats, snapshot, 'lp_tx_queue_len', snapshot['lp_tx_queue_len'])
986 d.addCallback(self._check_stats, snapshot, 'hp_tx_queue_len', snapshot['hp_tx_queue_len'])
987 d.addCallback(self._check_stats, snapshot, 'max_lp_tx_queue', snapshot['max_lp_tx_queue'] + 1)
988 d.addCallback(self._check_stats, snapshot, 'max_hp_tx_queue', snapshot['max_hp_tx_queue'])
989
990 # Flush to get ready for next test (one frame queued)
991 omci_cc.flush()
992 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
993 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
994
995 self.adapter_agent.timeout_the_message = True
996 omci_cc.send_mib_upload(timeout=1.0, high_priority=False)
997 omci_cc.send_mib_upload(timeout=1.0, high_priority=False)
998
999 self.assertEqual(omci_cc.lp_tx_queue_len, 1)
1000 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1001 self.assertEqual(omci_cc.max_lp_tx_queue, 1)
1002 self.assertEqual(omci_cc.max_hp_tx_queue, 0)
1003
1004 # Flush to get ready for next test (two queued and new max)
1005 omci_cc.flush()
1006 omci_cc.send_mib_upload(timeout=1.0, high_priority=False)
1007 omci_cc.send_mib_upload(timeout=1.0, high_priority=False)
1008 omci_cc.send_mib_upload(timeout=1.0, high_priority=False)
1009
1010 self.assertEqual(omci_cc.lp_tx_queue_len, 2)
1011 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1012 self.assertEqual(omci_cc.max_lp_tx_queue, 2)
1013 self.assertEqual(omci_cc.max_hp_tx_queue, 0)
1014
1015 def test_message_send_high_priority(self):
1016 # self.setup_one_of_each(timeout_messages=True)
1017 self.setup_one_of_each()
1018
1019 omci_cc = self.onu_handler.omci_cc
1020 omci_cc.enabled = True
1021 snapshot = self._snapshot_stats()
1022
1023 # MIB Upload
1024 d = omci_cc.send_mib_upload(high_priority=True)
1025 d.addCallback(self._check_stats, snapshot, 'lp_tx_queue_len', snapshot['lp_tx_queue_len'])
1026 d.addCallback(self._check_stats, snapshot, 'hp_tx_queue_len', snapshot['hp_tx_queue_len'])
1027 d.addCallback(self._check_stats, snapshot, 'max_lp_tx_queue', snapshot['max_lp_tx_queue'])
1028 d.addCallback(self._check_stats, snapshot, 'max_hp_tx_queue', snapshot['max_hp_tx_queue'] + 1)
1029
1030 # Flush to get ready for next test (one frame queued)
1031 omci_cc.flush()
1032 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1033 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1034
1035 self.adapter_agent.timeout_the_message = True
1036 omci_cc.send_mib_upload(high_priority=True)
1037 omci_cc.send_mib_upload(high_priority=True)
1038
1039 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1040 self.assertEqual(omci_cc.hp_tx_queue_len, 1)
1041 self.assertEqual(omci_cc.max_lp_tx_queue, 0)
1042 self.assertEqual(omci_cc.max_hp_tx_queue, 1)
1043
1044 # Flush to get ready for next test (two queued and new max)
1045 omci_cc.flush()
1046 omci_cc.send_mib_upload(high_priority=True)
1047 omci_cc.send_mib_upload(high_priority=True)
1048 omci_cc.send_mib_upload(high_priority=True)
1049
1050 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1051 self.assertEqual(omci_cc.hp_tx_queue_len, 2)
1052 self.assertEqual(omci_cc.max_lp_tx_queue, 0)
1053 self.assertEqual(omci_cc.max_hp_tx_queue, 2)
1054
1055 def test_message_send_and_cancel(self):
1056 global error_reason
1057 global successful
1058 # Do not send messages to adapter_agent
1059 self.setup_one_of_each(timeout_messages=True)
1060
1061 omci_cc = self.onu_handler.omci_cc
1062 omci_cc.enabled = True
1063
1064 def success(_results):
1065 global successful
1066 successful = True
1067
1068 def failure(reason):
1069 global error_reason
1070 error_reason = reason
1071
1072 def notCalled(reason):
1073 assert isinstance(reason, Failure), 'Should not be called with success'
1074
1075 # Cancel one that is actively being sent
1076 d = omci_cc.send_mib_upload(high_priority=False)
1077 d.addCallbacks(success, failure)
1078 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1079 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1080
1081 d.cancel()
1082 self.assertIsInstance(error_reason, Failure)
1083 self.assertFalse(successful)
1084 self.assertTrue(d.called)
1085
1086 self.assertEqual(omci_cc.max_lp_tx_queue, 1)
1087 self.assertEqual(omci_cc.max_hp_tx_queue, 0)
1088
1089 # Flush to get ready for next test (one running, one queued, cancel the
1090 # running one, so queued runs)
1091 omci_cc.flush()
1092 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1093 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1094
1095 error_reason = None
1096 d1 = omci_cc.send_mib_upload(high_priority=False)
1097 d2 = omci_cc.send_mib_upload(high_priority=False)
1098 d1.addCallbacks(success, failure)
1099 d2.addCallbacks(notCalled, notCalled)
1100 self.assertEqual(omci_cc.lp_tx_queue_len, 1)
1101 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1102
1103 d1.cancel()
1104 self.assertIsInstance(error_reason, Failure)
1105 self.assertFalse(successful)
1106 self.assertTrue(d1.called)
1107 self.assertFalse(d2.called)
1108
1109 self.assertEqual(omci_cc.max_lp_tx_queue, 1)
1110 self.assertEqual(omci_cc.max_hp_tx_queue, 0)
1111 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1112 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1113
1114 # Flush to get ready for next test (one running, one queued, cancel the queued one)
1115
1116 omci_cc.flush()
1117 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1118 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1119
1120 error_reason = None
1121 d3 = omci_cc.send_mib_upload(timeout=55, high_priority=False)
1122 d4 = omci_cc.send_mib_upload(timeout=55, high_priority=False)
1123 d5 = omci_cc.send_mib_upload(timeout=55, high_priority=False)
1124 d3.addCallbacks(notCalled, notCalled)
1125 d4.addCallbacks(success, failure)
1126 d5.addCallbacks(notCalled, notCalled)
1127 self.assertEqual(omci_cc.lp_tx_queue_len, 2)
1128 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1129
1130 d4.cancel()
1131 self.assertIsInstance(error_reason, Failure)
1132 self.assertFalse(successful)
1133 self.assertFalse(d3.called)
1134 self.assertTrue(d4.called)
1135 self.assertFalse(d5.called)
1136
1137 def test_message_send_low_and_high_priority(self):
1138 self.setup_one_of_each(timeout_messages=True)
1139
1140 omci_cc = self.onu_handler.omci_cc
1141 omci_cc.enabled = True
1142
1143 omci_cc.send_mib_reset(high_priority=False)
1144 omci_cc.send_mib_reset(high_priority=True)
1145 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1146 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1147
1148 omci_cc.flush()
1149 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1150 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1151
1152 omci_cc.send_mib_reset(high_priority=False)
1153 omci_cc.send_mib_reset(high_priority=True)
1154 omci_cc.send_mib_reset(high_priority=False)
1155 omci_cc.send_mib_reset(high_priority=True)
1156 self.assertEqual(omci_cc.lp_tx_queue_len, 1)
1157 self.assertEqual(omci_cc.hp_tx_queue_len, 1)
1158
1159 def test_no_sw_download_and_mib_upload_at_same_time(self):
1160 # Section B.2.3 of ITU G.988-2017 specifies that a MIB
1161 # upload or software download at a given priority level
1162 # is not allowed while a similar action in the other
1163 # priority level is in progress. Relates to possible memory
1164 # consumption/needs on the ONU.
1165 #
1166 # OMCI_CC only checks if the commands are currently in
1167 # progress. ONU should reject messages if the upload/download
1168 # is in progress (but not an active request is in progress).
1169
1170 self.setup_one_of_each(timeout_messages=True)
1171 omci_cc = self.onu_handler.omci_cc
1172 omci_cc.enabled = True
1173
1174 mib_upload_msgs = [omci_cc.send_mib_upload,
1175 # omci_cc.send_mib_upload_next
1176 ]
1177 sw_download_msgs = [omci_cc.send_start_software_download,
1178 # omci_cc.send_download_section,
1179 # omci_cc.send_end_software_download
1180 ]
1181
1182 for upload in mib_upload_msgs:
1183 for download in sw_download_msgs:
1184 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1185 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1186
1187 upload(high_priority=False)
1188 download(1, 1, 1, high_priority=True) # Should stall send-next 50mS
1189 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1190 self.assertEqual(omci_cc.hp_tx_queue_len, 1)
1191
1192 omci_cc.flush()
1193 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1194 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1195
1196 upload(high_priority=True)
1197 download(1, 1, 1, high_priority=False) # Should stall send-next 50mS
1198 self.assertEqual(omci_cc.lp_tx_queue_len, 1)
1199 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1200
1201 omci_cc.flush()
1202 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1203 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1204
1205 download(1, 1, 1, high_priority=False)
1206 upload(high_priority=True) # Should stall send-next 50mS
1207 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1208 self.assertEqual(omci_cc.hp_tx_queue_len, 1)
1209
1210 omci_cc.flush()
1211 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1212 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1213
1214 download(1, 1, 1, high_priority=True)
1215 upload(high_priority=False) # Should stall send-next 50mS)
1216 self.assertEqual(omci_cc.lp_tx_queue_len, 1)
1217 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1218
1219 omci_cc.flush()
1220 self.assertEqual(omci_cc.lp_tx_queue_len, 0)
1221 self.assertEqual(omci_cc.hp_tx_queue_len, 0)
1222
1223 # Some more ideas for tests that we could add
1224 # Send explicit tid that is not valid
1225 # - Look at top of 'Send' method and test all the error conditions could may hit
1226
1227 # Send multiple and have the OLT proxy throw an exception. Should call errback and
1228 # schedule remainder in queue to still tx.
1229
1230 # Send a frame and then inject a response and test the RX logic out, including late
1231 # rx and retries by the OMCI_CC transmitter.
1232
1233
1234if __name__ == '__main__':
1235 main()