3 #############################################################################
4 # Copyright (c) 2017 Orange, Inc. and others. All rights reserved.
6 # All rights reserved. This program and the accompanying materials
7 # are made available under the terms of the Apache License, Version 2.0
8 # which accompanies this distribution, and is available at
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #############################################################################
12 # pylint: disable=no-member
13 # pylint: disable=too-many-public-methods
18 # pylint: disable=wrong-import-order
20 sys.path.append('transportpce_tests/common/')
21 # pylint: disable=wrong-import-position
22 # pylint: disable=import-error
23 import test_utils_rfc8040 # nopep8
26 class TransportOlmTesting(unittest.TestCase):
29 NODE_VERSION = '2.2.1'
33 cls.processes = test_utils_rfc8040.start_tpce()
34 cls.processes = test_utils_rfc8040.start_sims([('xpdra', cls.NODE_VERSION),
35 ('roadma', cls.NODE_VERSION),
36 ('roadmc', cls.NODE_VERSION),
37 ('xpdrc', cls.NODE_VERSION)])
40 def tearDownClass(cls):
41 # pylint: disable=not-an-iterable
42 for process in cls.processes:
43 test_utils_rfc8040.shutdown_process(process)
44 print("all processes killed")
47 # pylint: disable=consider-using-f-string
48 print("execution of {}".format(self.id().split(".")[-1]))
51 def test_01_xpdrA_device_connected(self):
52 response = test_utils_rfc8040.mount_device("XPDR-A1", ('xpdra', self.NODE_VERSION))
53 self.assertEqual(response.status_code, requests.codes.created, test_utils_rfc8040.CODE_SHOULD_BE_201)
55 def test_02_xpdrC_device_connected(self):
56 response = test_utils_rfc8040.mount_device("XPDR-C1", ('xpdrc', self.NODE_VERSION))
57 self.assertEqual(response.status_code, requests.codes.created, test_utils_rfc8040.CODE_SHOULD_BE_201)
59 def test_03_rdmA_device_connected(self):
60 response = test_utils_rfc8040.mount_device("ROADM-A1", ('roadma', self.NODE_VERSION))
61 self.assertEqual(response.status_code, requests.codes.created, test_utils_rfc8040.CODE_SHOULD_BE_201)
63 def test_04_rdmC_device_connected(self):
64 response = test_utils_rfc8040.mount_device("ROADM-C1", ('roadmc', self.NODE_VERSION))
65 self.assertEqual(response.status_code, requests.codes.created, test_utils_rfc8040.CODE_SHOULD_BE_201)
67 def test_05_connect_xprdA_to_roadmA(self):
68 response = test_utils_rfc8040.connect_xpdr_to_rdm_request(
69 {'xpdr-node': 'XPDR-A1', 'xpdr-num': '1', 'network-num': '1',
70 'rdm-node': 'ROADM-A1', 'srg-num': '1', 'termination-point-num': 'SRG1-PP1-TXRX'})
71 self.assertEqual(response.status_code, requests.codes.ok)
73 def test_06_connect_roadmA_to_xpdrA(self):
74 response = test_utils_rfc8040.connect_rdm_to_xpdr_request(
75 {'xpdr-node': 'XPDR-A1', 'xpdr-num': '1', 'network-num': '1',
76 'rdm-node': 'ROADM-A1', 'srg-num': '1', 'termination-point-num': 'SRG1-PP1-TXRX'})
77 self.assertEqual(response.status_code, requests.codes.ok)
79 def test_07_connect_xprdC_to_roadmC(self):
80 response = test_utils_rfc8040.connect_xpdr_to_rdm_request(
81 {'xpdr-node': 'XPDR-C1', 'xpdr-num': '1', 'network-num': '1',
82 'rdm-node': 'ROADM-C1', 'srg-num': '1', 'termination-point-num': 'SRG1-PP1-TXRX'})
83 self.assertEqual(response.status_code, requests.codes.ok)
85 def test_08_connect_roadmC_to_xpdrC(self):
86 response = test_utils_rfc8040.connect_rdm_to_xpdr_request(
87 {'xpdr-node': 'XPDR-C1', 'xpdr-num': '1', 'network-num': '1',
88 'rdm-node': 'ROADM-C1', 'srg-num': '1', 'termination-point-num': 'SRG1-PP1-TXRX'})
89 self.assertEqual(response.status_code, requests.codes.ok)
91 def test_09_create_OTS_ROADMA(self):
92 response = test_utils_rfc8040.device_renderer_create_ots_oms_request('ROADM-A1', 'DEG1-TTP-TXRX')
93 self.assertEqual(response.status_code, requests.codes.ok)
95 def test_10_create_OTS_ROADMC(self):
96 response = test_utils_rfc8040.device_renderer_create_ots_oms_request('ROADM-C1', 'DEG2-TTP-TXRX')
97 self.assertEqual(response.status_code, requests.codes.ok)
99 def test_11_get_PM_ROADMA(self):
100 response = test_utils_rfc8040.transportpce_api_rpc_request(
101 'transportpce-olm', 'get-pm',
103 'node-id': 'ROADM-A1',
104 'resource-type': 'interface',
105 'granularity': '15min',
106 'resource-identifier': {
107 'resource-name': 'OTS-DEG2-TTP-TXRX'
111 self.assertEqual(response['status_code'], requests.codes.ok)
113 'pmparameter-name': 'OpticalPowerOutput',
114 'pmparameter-value': '2.5'
115 }, response['output']['measurements'])
117 'pmparameter-name': 'OpticalReturnLoss',
118 'pmparameter-value': '40'
119 }, response['output']['measurements'])
121 'pmparameter-name': 'OpticalPowerInput',
122 'pmparameter-value': '-21.1'
123 }, response['output']['measurements'])
125 def test_12_get_PM_ROADMC(self):
126 response = test_utils_rfc8040.transportpce_api_rpc_request(
127 'transportpce-olm', 'get-pm',
129 'node-id': 'ROADM-C1',
130 'resource-type': 'interface',
131 'granularity': '15min',
132 'resource-identifier': {
133 'resource-name': 'OTS-DEG1-TTP-TXRX'
136 self.assertEqual(response['status_code'], requests.codes.ok)
138 'pmparameter-name': 'OpticalPowerOutput',
139 'pmparameter-value': '4.6'
140 }, response['output']['measurements'])
142 'pmparameter-name': 'OpticalReturnLoss',
143 'pmparameter-value': '49.1'
144 }, response['output']['measurements'])
146 'pmparameter-name': 'OpticalPowerInput',
147 'pmparameter-value': '-15.1'
148 }, response['output']['measurements'])
150 def test_13_calculate_span_loss_base_ROADMA_ROADMC(self):
151 response = test_utils_rfc8040.transportpce_api_rpc_request(
152 'transportpce-olm', 'calculate-spanloss-base',
155 'link-id': 'ROADM-A1-DEG2-DEG2-TTP-TXRXtoROADM-C1-DEG1-DEG1-TTP-TXRX'
157 self.assertEqual(response['status_code'], requests.codes.ok)
158 self.assertIn('Success',
159 response['output']['result'])
162 'link-id': 'ROADM-A1-DEG2-DEG2-TTP-TXRXtoROADM-C1-DEG1-DEG1-TTP-TXRX'
163 }, response['output']['spans'])
166 def test_14_calculate_span_loss_base_all(self):
167 response = test_utils_rfc8040.transportpce_api_rpc_request(
168 'transportpce-olm', 'calculate-spanloss-base',
172 self.assertEqual(response['status_code'], requests.codes.ok)
173 self.assertIn('Success',
174 response['output']['result'])
177 'link-id': 'ROADM-C1-DEG1-DEG1-TTP-TXRXtoROADM-A1-DEG2-DEG2-TTP-TXRX'
178 }, response['output']['spans'])
181 'link-id': 'ROADM-A1-DEG2-DEG2-TTP-TXRXtoROADM-C1-DEG1-DEG1-TTP-TXRX'
182 }, response['output']['spans'])
185 def test_15_get_OTS_DEG2_TTP_TXRX_ROADMA(self):
186 response = test_utils_rfc8040.check_node_attribute2_request(
187 'ROADM-A1', 'interface', 'OTS-DEG2-TTP-TXRX', 'org-openroadm-optical-transport-interfaces:ots')
188 self.assertEqual(response['status_code'], requests.codes.ok)
189 self.assertEqual(float(response['org-openroadm-optical-transport-interfaces:ots']['span-loss-transmit']), 17.6)
190 self.assertEqual(float(response['org-openroadm-optical-transport-interfaces:ots']['span-loss-receive']), 25.7)
192 def test_16_get_OTS_DEG1_TTP_TXRX_ROADMC(self):
193 response = test_utils_rfc8040.check_node_attribute2_request(
194 'ROADM-C1', 'interface', 'OTS-DEG1-TTP-TXRX', 'org-openroadm-optical-transport-interfaces:ots')
195 self.assertEqual(response['status_code'], requests.codes.ok)
196 self.assertEqual(float(response['org-openroadm-optical-transport-interfaces:ots']['span-loss-transmit']), 25.7)
197 self.assertEqual(float(response['org-openroadm-optical-transport-interfaces:ots']['span-loss-receive']), 17.6)
199 def test_17_servicePath_create_AToZ(self):
200 response = test_utils_rfc8040.transportpce_api_rpc_request(
201 'transportpce-device-renderer', 'service-path',
203 'service-name': 'test',
205 'modulation-format': 'dp-qpsk',
206 'operation': 'create',
208 [{'node-id': 'XPDR-A1',
209 'dest-tp': 'XPDR1-NETWORK1', 'src-tp': 'XPDR1-CLIENT1'},
210 {'node-id': 'ROADM-A1',
211 'dest-tp': 'DEG2-TTP-TXRX', 'src-tp': 'SRG1-PP1-TXRX'},
212 {'node-id': 'ROADM-C1',
213 'dest-tp': 'SRG1-PP1-TXRX', 'src-tp': 'DEG1-TTP-TXRX'},
214 {'node-id': 'XPDR-C1',
215 'dest-tp': 'XPDR1-CLIENT1', 'src-tp': 'XPDR1-NETWORK1'}],
216 'center-freq': 196.1,
220 'lower-spectral-slot-number': 761,
221 'higher-spectral-slot-number': 768
223 self.assertEqual(response['status_code'], requests.codes.ok)
224 self.assertIn('Interfaces created successfully for nodes: ', response['output']['result'])
227 def test_18_servicePath_create_ZToA(self):
228 response = test_utils_rfc8040.transportpce_api_rpc_request(
229 'transportpce-device-renderer', 'service-path',
231 'service-name': 'test',
233 'modulation-format': 'dp-qpsk',
234 'operation': 'create',
236 [{'node-id': 'XPDR-C1',
237 'dest-tp': 'XPDR1-NETWORK1', 'src-tp': 'XPDR1-CLIENT1'},
238 {'node-id': 'ROADM-C1',
239 'dest-tp': 'DEG1-TTP-TXRX', 'src-tp': 'SRG1-PP1-TXRX'},
240 {'node-id': 'ROADM-A1',
241 'src-tp': 'DEG2-TTP-TXRX', 'dest-tp': 'SRG1-PP1-TXRX'},
242 {'node-id': 'XPDR-A1',
243 'src-tp': 'XPDR1-NETWORK1', 'dest-tp': 'XPDR1-CLIENT1'}],
244 'center-freq': 196.1,
248 'lower-spectral-slot-number': 761,
249 'higher-spectral-slot-number': 768
251 self.assertEqual(response['status_code'], requests.codes.ok)
252 self.assertIn('Interfaces created successfully for nodes: ', response['output']['result'])
255 def test_19_service_power_setup_XPDRA_XPDRC(self):
256 response = test_utils_rfc8040.transportpce_api_rpc_request(
257 'transportpce-olm', 'service-power-setup',
259 'service-name': 'test',
263 'dest-tp': 'XPDR1-NETWORK1',
264 'src-tp': 'XPDR1-CLIENT1',
268 'dest-tp': 'DEG2-TTP-TXRX',
269 'src-tp': 'SRG1-PP1-TXRX',
270 'node-id': 'ROADM-A1'
273 'dest-tp': 'SRG1-PP1-TXRX',
274 'src-tp': 'DEG1-TTP-TXRX',
275 'node-id': 'ROADM-C1'
278 'dest-tp': 'XPDR1-CLIENT1',
279 'src-tp': 'XPDR1-NETWORK1',
283 'lower-spectral-slot-number': 761,
284 'higher-spectral-slot-number': 768
286 self.assertEqual(response['status_code'], requests.codes.ok)
287 self.assertIn('Success', response['output']['result'])
289 def test_20_get_interface_XPDRA_XPDR1_NETWORK1(self):
290 response = test_utils_rfc8040.check_node_attribute2_request(
291 'XPDR-A1', 'interface', 'XPDR1-NETWORK1-761:768', 'org-openroadm-optical-channel-interfaces:och')
292 self.assertEqual(response['status_code'], requests.codes.ok)
293 self.assertEqual(float(response['org-openroadm-optical-channel-interfaces:och']['transmit-power']), -5)
294 self.assertEqual(float(response['org-openroadm-optical-channel-interfaces:och']['frequency']), 196.1)
296 def test_21_get_roadmconnection_ROADMA(self):
297 response = test_utils_rfc8040.check_node_attribute_request(
298 'ROADM-A1', 'roadm-connections', 'SRG1-PP1-TXRX-DEG2-TTP-TXRX-761:768')
299 self.assertEqual(response['status_code'], requests.codes.ok)
300 self.assertEqual("gainLoss", response['roadm-connections'][0]['opticalControlMode'])
301 self.assertEqual(float(response['roadm-connections'][0]['target-output-power']), 0.21)
303 def test_22_get_roadmconnection_ROADMC(self):
304 response = test_utils_rfc8040.check_node_attribute_request(
305 'ROADM-C1', 'roadm-connections', 'DEG1-TTP-TXRX-SRG1-PP1-TXRX-761:768')
306 self.assertEqual(response['status_code'], requests.codes.ok)
307 self.assertEqual("power", response['roadm-connections'][0]['opticalControlMode'])
309 def test_23_service_power_setup_XPDRC_XPDRA(self):
310 response = test_utils_rfc8040.transportpce_api_rpc_request(
311 'transportpce-olm', 'service-power-setup',
313 'service-name': 'test',
317 'dest-tp': 'XPDR1-NETWORK1',
318 'src-tp': 'XPDR1-CLIENT1',
322 'dest-tp': 'DEG1-TTP-TXRX',
323 'src-tp': 'SRG1-PP1-TXRX',
324 'node-id': 'ROADM-C1'
327 'src-tp': 'DEG2-TTP-TXRX',
328 'dest-tp': 'SRG1-PP1-TXRX',
329 'node-id': 'ROADM-A1'
332 'src-tp': 'XPDR1-NETWORK1',
333 'dest-tp': 'XPDR1-CLIENT1',
337 'lower-spectral-slot-number': 761,
338 'higher-spectral-slot-number': 768
340 self.assertEqual(response['status_code'], requests.codes.ok)
341 self.assertIn('Success', response['output']['result'])
343 def test_24_get_interface_XPDRC_XPDR1_NETWORK1(self):
344 response = test_utils_rfc8040.check_node_attribute2_request(
345 'XPDR-C1', 'interface', 'XPDR1-NETWORK1-761:768', 'org-openroadm-optical-channel-interfaces:och')
346 self.assertEqual(response['status_code'], requests.codes.ok)
347 self.assertEqual(float(response['org-openroadm-optical-channel-interfaces:och']['transmit-power']), -5)
348 self.assertEqual(float(response['org-openroadm-optical-channel-interfaces:och']['frequency']), 196.1)
350 def test_25_get_roadmconnection_ROADMC(self):
351 response = test_utils_rfc8040.check_node_attribute_request(
352 'ROADM-C1', 'roadm-connections', 'SRG1-PP1-TXRX-DEG1-TTP-TXRX-761:768')
353 self.assertEqual(response['status_code'], requests.codes.ok)
354 self.assertEqual("gainLoss", response['roadm-connections'][0]['opticalControlMode'])
355 self.assertEqual(float(response['roadm-connections'][0]['target-output-power']), 2.0)
357 def test_26_service_power_turndown_XPDRA_XPDRC(self):
358 response = test_utils_rfc8040.transportpce_api_rpc_request(
359 'transportpce-olm', 'service-power-turndown',
361 'service-name': 'test',
365 'dest-tp': 'XPDR1-NETWORK1',
366 'src-tp': 'XPDR1-CLIENT1',
370 'dest-tp': 'DEG2-TTP-TXRX',
371 'src-tp': 'SRG1-PP1-TXRX',
372 'node-id': 'ROADM-A1'
375 'dest-tp': 'SRG1-PP1-TXRX',
376 'src-tp': 'DEG1-TTP-TXRX',
377 'node-id': 'ROADM-C1'
380 'dest-tp': 'XPDR1-CLIENT1',
381 'src-tp': 'XPDR1-NETWORK1',
385 'lower-spectral-slot-number': 761,
386 'higher-spectral-slot-number': 768
388 self.assertEqual(response['status_code'], requests.codes.ok)
389 self.assertIn('Success', response['output']['result'])
391 def test_27_get_roadmconnection_ROADMA(self):
392 response = test_utils_rfc8040.check_node_attribute_request(
393 'ROADM-A1', 'roadm-connections', 'SRG1-PP1-TXRX-DEG2-TTP-TXRX-761:768')
394 self.assertEqual(response['status_code'], requests.codes.ok)
395 self.assertEqual("off", response['roadm-connections'][0]['opticalControlMode'])
396 self.assertEqual(float(response['roadm-connections'][0]['target-output-power']), -60)
398 def test_28_get_roadmconnection_ROADMC(self):
399 response = test_utils_rfc8040.check_node_attribute_request(
400 'ROADM-C1', 'roadm-connections', 'DEG1-TTP-TXRX-SRG1-PP1-TXRX-761:768')
401 self.assertEqual(response['status_code'], requests.codes.ok)
402 self.assertEqual("off", response['roadm-connections'][0]['opticalControlMode'])
404 def test_29_servicePath_delete_AToZ(self):
405 response = test_utils_rfc8040.transportpce_api_rpc_request(
406 'transportpce-device-renderer', 'service-path',
408 'service-name': 'test',
410 'modulation-format': 'dp-qpsk',
411 'operation': 'delete',
413 [{'node-id': 'XPDR-A1',
414 'dest-tp': 'XPDR1-NETWORK1', 'src-tp': 'XPDR1-CLIENT1'},
415 {'node-id': 'ROADM-A1',
416 'dest-tp': 'DEG2-TTP-TXRX', 'src-tp': 'SRG1-PP1-TXRX'},
417 {'node-id': 'ROADM-C1',
418 'dest-tp': 'SRG1-PP1-TXRX', 'src-tp': 'DEG1-TTP-TXRX'},
419 {'node-id': 'XPDR-C1',
420 'dest-tp': 'XPDR1-CLIENT1', 'src-tp': 'XPDR1-NETWORK1'}],
421 'center-freq': 196.1,
425 'lower-spectral-slot-number': 761,
426 'higher-spectral-slot-number': 768
428 self.assertEqual(response['status_code'], requests.codes.ok)
429 self.assertIn('Request processed', response['output']['result'])
432 def test_30_servicePath_delete_ZToA(self):
433 response = test_utils_rfc8040.transportpce_api_rpc_request(
434 'transportpce-device-renderer', 'service-path',
436 'service-name': 'test',
438 'modulation-format': 'dp-qpsk',
439 'operation': 'delete',
441 [{'node-id': 'XPDR-C1',
442 'dest-tp': 'XPDR1-NETWORK1', 'src-tp': 'XPDR1-CLIENT1'},
443 {'node-id': 'ROADM-C1',
444 'dest-tp': 'DEG1-TTP-TXRX', 'src-tp': 'SRG1-PP1-TXRX'},
445 {'node-id': 'ROADM-A1',
446 'src-tp': 'DEG2-TTP-TXRX', 'dest-tp': 'SRG1-PP1-TXRX'},
447 {'node-id': 'XPDR-A1',
448 'src-tp': 'XPDR1-NETWORK1', 'dest-tp': 'XPDR1-CLIENT1'}],
449 'center-freq': 196.1,
453 'lower-spectral-slot-number': 761,
454 'higher-spectral-slot-number': 768
456 self.assertEqual(response['status_code'], requests.codes.ok)
457 self.assertIn('Request processed', response['output']['result'])
460 #"""to test case where SRG where the xpdr is connected to has no optical range data"""
462 def test_31_connect_xprdA_to_roadmA(self):
463 response = test_utils_rfc8040.connect_xpdr_to_rdm_request(
464 {'xpdr-node': 'XPDR-A1', 'xpdr-num': '1', 'network-num': '2',
465 'rdm-node': 'ROADM-A1', 'srg-num': '1', 'termination-point-num': 'SRG1-PP2-TXRX'})
466 self.assertEqual(response.status_code, requests.codes.ok)
468 def test_32_connect_roadmA_to_xpdrA(self):
469 response = test_utils_rfc8040.connect_rdm_to_xpdr_request(
470 {'xpdr-node': 'XPDR-A1', 'xpdr-num': '1', 'network-num': '2',
471 'rdm-node': 'ROADM-A1', 'srg-num': '1', 'termination-point-num': 'SRG1-PP2-TXRX'})
472 self.assertEqual(response.status_code, requests.codes.ok)
474 def test_33_servicePath_create_AToZ(self):
475 response = test_utils_rfc8040.transportpce_api_rpc_request(
476 'transportpce-device-renderer', 'service-path',
478 'service-name': 'test2',
480 'modulation-format': 'dp-qpsk',
481 'operation': 'create',
483 [{'node-id': 'XPDR-A1',
484 'dest-tp': 'XPDR1-NETWORK2', 'src-tp': 'XPDR1-CLIENT2'},
485 {'node-id': 'ROADM-A1',
486 'dest-tp': 'DEG2-TTP-TXRX', 'src-tp': 'SRG1-PP2-TXRX'}],
487 'center-freq': 196.1,
491 'lower-spectral-slot-number': 753,
492 'higher-spectral-slot-number': 760
494 self.assertEqual(response['status_code'], requests.codes.ok)
495 self.assertIn('Interfaces created successfully for nodes', response['output']['result'])
498 def test_34_get_interface_XPDRA_XPDR1_NETWORK2(self):
499 response = test_utils_rfc8040.check_node_attribute2_request(
500 'XPDR-A1', 'interface', 'XPDR1-NETWORK2-753:760', 'org-openroadm-optical-channel-interfaces:och')
501 self.assertEqual(response['status_code'], requests.codes.ok)
502 self.assertEqual(float(response['org-openroadm-optical-channel-interfaces:och']['transmit-power']), -5)
503 # self.assertEqual(2, response['org-openroadm-optical-channel-interfaces:och']['wavelength-number'])
505 def test_35_servicePath_delete_AToZ(self):
506 response = test_utils_rfc8040.transportpce_api_rpc_request(
507 'transportpce-device-renderer', 'service-path',
509 'service-name': 'test2',
511 'modulation-format': 'dp-qpsk',
512 'operation': 'delete',
514 [{'node-id': 'XPDR-A1',
515 'dest-tp': 'XPDR1-NETWORK2', 'src-tp': 'XPDR1-CLIENT2'},
516 {'node-id': 'ROADM-A1',
517 'dest-tp': 'DEG2-TTP-TXRX', 'src-tp': 'SRG1-PP2-TXRX'}],
518 'center-freq': 196.1,
522 'lower-spectral-slot-number': 753,
523 'higher-spectral-slot-number': 760
525 self.assertEqual(response['status_code'], requests.codes.ok)
526 self.assertIn('Request processed', response['output']['result'])
529 def test_36_xpdrA_device_disconnected(self):
530 response = test_utils_rfc8040.unmount_device("XPDR-A1")
531 self.assertIn(response.status_code, (requests.codes.ok, requests.codes.no_content))
533 def test_37_xpdrC_device_disconnected(self):
534 response = test_utils_rfc8040.unmount_device("XPDR-C1")
535 self.assertIn(response.status_code, (requests.codes.ok, requests.codes.no_content))
537 def test_38_calculate_span_loss_current(self):
538 response = test_utils_rfc8040.transportpce_api_rpc_request(
539 'transportpce-olm', 'calculate-spanloss-current',
541 self.assertEqual(response['status_code'], requests.codes.ok)
542 self.assertIn('Success',
543 response["output"]["result"])
546 def test_39_rdmA_device_disconnected(self):
547 response = test_utils_rfc8040.unmount_device("ROADM-A1")
548 self.assertIn(response.status_code, (requests.codes.ok, requests.codes.no_content))
550 def test_40_rdmC_device_disconnected(self):
551 response = test_utils_rfc8040.unmount_device("ROADM-C1")
552 self.assertIn(response.status_code, (requests.codes.ok, requests.codes.no_content))
555 if __name__ == "__main__":
556 unittest.main(verbosity=2)