blob: 24134572a146ffc59932a9cfd8b49ed7fd602259 [file] [log] [blame]
Rachit Shrivastavab9809da2017-07-12 11:09:10 -04001from tests.itests.voltha.rest_base import RestBase
2
Rachit Shrivastava5a2d5692017-07-17 10:29:20 -04003from google.protobuf.json_format import MessageToDict, ParseDict
Rachit Shrivastavab9809da2017-07-12 11:09:10 -04004import unittest
5
6from voltha.protos import bbf_fiber_base_pb2 as fb
Rachit Shrivastavab9809da2017-07-12 11:09:10 -04007from voltha.protos.device_pb2 import Device
Nikolay Titov176f1db2017-08-10 12:38:43 -04008from voltha.protos import bbf_fiber_gemport_body_pb2 as gemport
9from voltha.protos import bbf_fiber_tcont_body_pb2 as tcont
10from voltha.protos import bbf_fiber_traffic_descriptor_profile_body_pb2 as tdp
Rachit Shrivastavab9809da2017-07-12 11:09:10 -040011from common.utils.consulhelpers import get_endpoint_from_consul
12
Rachit Shrivastava5a2d5692017-07-17 10:29:20 -040013'''
Rachit Shrivastavaa182e912017-07-28 15:18:34 -040014These tests use the Ponsim OLT to verify create, update, and delete
15functionalities of ChannelgroupConfig, ChannelpartitionConfig,
16ChannelpairConfig, ChannelterminationConfig, VOntAni, OntAni, and VEnets
17for xPON
Rachit Shrivastava5a2d5692017-07-17 10:29:20 -040018The prerequisite for this test are:
19 1. voltha ensemble is running
20 docker-compose -f compose/docker-compose-system-test.yml up -d
21 2. ponsim olt is running with PONSIM-OLT
22 sudo -s
23 . ./env.sh
24 ./ponsim/main.py -v
25'''
26
Rachit Shrivastavab9809da2017-07-12 11:09:10 -040027device_type = 'ponsim_olt'
28host_and_port = '172.17.0.1:50060'
29scenario = [
Rachit Shrivastavaa182e912017-07-28 15:18:34 -040030 {'cg-add': {
31 'pb2': fb.ChannelgroupConfig(),
32 'rpc': {
33 "interface": {
34 "enabled": True,
35 "name": "Manhattan",
36 "description": "Channel Group for Manhattan.."
37 },
38 "data": {
39 "polling_period": 100,
40 "system_id": "000000",
41 "raman_mitigation": "RAMAN_NONE"
42 },
43 "name": "Manhattan"
Rachit Shrivastava8f4f9bf2017-07-20 11:59:30 -040044 }
Rachit Shrivastava8f4f9bf2017-07-20 11:59:30 -040045 }
Rachit Shrivastavaa182e912017-07-28 15:18:34 -040046 },
47 {'cpart-add': {
48 'pb2': fb.ChannelpartitionConfig(),
49 'rpc': {
50 "interface": {
51 "enabled": True,
52 "name": "Freedom Tower",
53 "description":"Channel Partition for Freedom Tower in Manhattan"
54 },
55 "data": {
56 "differential_fiber_distance": 20,
57 "closest_ont_distance": 0,
58 "fec_downstream": False,
59 "multicast_aes_indicator": False,
60 "authentication_method": "SERIAL_NUMBER",
61 "channelgroup_ref": "Manhattan"
62 },
63 "name": "Freedom Tower"
64 }
65 }
66 },
67 {'cpair-add': {
68 'pb2': fb.ChannelpairConfig(),
69 'rpc': {
70 "interface": {
71 "enabled": True,
72 "name": "PON port",
73 "description": "Channel Pair for Freedom Tower"
74 },
75 "data": {
76 "channelpair_linerate": "down_10_up_10",
77 "channelpair_type": "channelpair",
78 "channelgroup_ref": "Manhattan",
79 "gpon_ponid_interval": 0,
80 "channelpartition_ref": "Freedom Tower",
81 "gpon_ponid_odn_class": "CLASS_A"
82 },
83 "name": "PON port"
84 }
85 }
86 },
87 {'cterm-add': {
88 'pb2': fb.ChannelterminationConfig(),
89 'rpc': {
90 "interface": {
91 "enabled": True,
92 "name": "PON port",
93 "description": "Channel Termination for Freedom Tower"
94 },
95 "data": {
96 "channelpair_ref": "PON port",
97 "location": "Freedom Tower OLT"
98 },
99 "name": "PON port"
100 }
101 }
102 },
103 {'vontani-add': {
104 'pb2': fb.VOntaniConfig(),
105 'rpc': {
106 "interface": {
107 "enabled": True,
108 "name": "Golden User",
109 "description": "Golden User in Freedom Tower"
110 },
111 "data": {
112 "preferred_chanpair": "PON port",
113 "expected_serial_number": "PSMO00000001",
114 "parent_ref": "Freedom Tower",
115 "onu_id": 1
116 },
117 "name": "Golden User"
118 }
119 }
120 },
121 {'ontani-add': {
122 'pb2': fb.OntaniConfig(),
123 'rpc': {
124 "interface": {
125 "enabled": True,
126 "name": "Golden User",
127 "description": "Golden User in Freedom Tower"
128 },
129 "data": {
130 "upstream_fec_indicator": True,
131 "mgnt_gemport_aes_indicator": False
132 },
133 "name": "Golden User"
134 }
135 }
136 },
137 {'venet-add': {
138 'pb2': fb.VEnetConfig(),
139 'rpc': {
140 "interface": {
141 "enabled": True,
142 "name": "Enet UNI 1",
143 "description": "Ethernet port - 1"
144 },
145 "data": {
146 "v_ontani_ref": "Golden User"
147 },
148 "name": "Enet UNI 1"
149 }
150 }
151 },
Nikolay Titov176f1db2017-08-10 12:38:43 -0400152 {'tdp-add': {
153 'pb2': tdp.TrafficDescriptorProfileData(),
154 'rpc': {
155 "name": "TDP 1",
156 "assured_bandwidth": "500000",
157 "additional_bw_eligibility_indicator": \
158"ADDITIONAL_BW_ELIGIBILITY_INDICATOR_NONE",
159 "fixed_bandwidth": "100000",
160 "maximum_bandwidth": "1000000",
161 }
162 }
163 },
164 {'tcont-add': {
165 'pb2': tcont.TcontsConfigData(),
166 'rpc': {
167 "interface_reference": "Golden User",
168 "traffic_descriptor_profile_ref": "TDP 1",
169 "name": "TCont 1"
170 }
171 }
172 },
173 {'gemport-add': {
174 'pb2': gemport.GemportsConfigData(),
175 'rpc': {
176 "aes_indicator": True,
177 "name": "GEMPORT 1",
178 "traffic_class": 0,
179 "itf_ref": "Enet UNI 1",
180 "tcont_ref": "TCont 1",
181 }
182 }
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400183 }
184]
Rachit Shrivastava5a2d5692017-07-17 10:29:20 -0400185
Rachit Shrivastava8f4f9bf2017-07-20 11:59:30 -0400186#for ordering the test cases
187id = 3
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400188LOCAL_CONSUL = "localhost:8500"
189# Retrieve details of the REST entry point
190rest_endpoint = get_endpoint_from_consul(LOCAL_CONSUL, 'chameleon-rest')
191# Construct the base_url
192base_url = 'https://' + rest_endpoint
193
194class GlobalPreChecks(RestBase):
195 def test_000_get_root(self):
196 res = self.get('/#!/', expected_content_type='text/html')
197 self.assertGreaterEqual(res.find('swagger'), 0)
198
199 def test_001_get_health(self):
200 res = self.get('/health')
201 self.assertEqual(res['state'], 'HEALTHY')
202
203class TestXPon(RestBase):
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400204 def test_002_setup_device(self):
205 global device
206 device = self.add_device()
207 self.verify_device_preprovisioned_state(device['id'])
208 self.activate_device(device['id'])
209
Nikolay Titov7253ff22017-08-14 18:24:17 -0400210 def _remove_device(self):
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400211 self.deactivate_device(device['id'])
212 self.delete_device(device['id'])
213
214 #~~~~~~~~~~~~~~~~~~~~~~ Helper Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
215 # Create a new simulated device
216 def add_device(self):
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400217 return self.post('/api/v1/devices',
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400218 MessageToDict(Device(
219 type=device_type,
220 host_and_port=host_and_port
221 )),
222 expected_code=200)
223
224 def verify_device_preprovisioned_state(self, olt_id):
225 # we also check that so far what we read back is same as what we get
226 # back on create
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400227 device = self.get('/api/v1/devices/{}'.format(olt_id))
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400228 self.assertNotEqual(device['id'], '')
229 self.assertEqual(device['adapter'], 'ponsim_olt')
230 self.assertEqual(device['admin_state'], 'PREPROVISIONED')
231 self.assertEqual(device['oper_status'], 'UNKNOWN')
232
233 # Active the simulated device.
234 # This will trigger the simulation of random alarms
235 def activate_device(self, device_id):
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400236 path = '/api/v1/devices/{}'.format(device_id)
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400237 self.post(path + '/enable', expected_code=200)
238 device = self.get(path)
239 self.assertEqual(device['admin_state'], 'ENABLED')
240
241 def deactivate_device(self, device_id):
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400242 path = '/api/v1/devices/{}'.format(device_id)
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400243 self.post(path + '/disable', expected_code=200)
244 device = self.get(path)
245 self.assertEqual(device['admin_state'], 'DISABLED')
246
247 def delete_device(self, device_id):
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400248 path = '/api/v1/devices/{}'.format(device_id)
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400249 self.delete(path + '/delete', expected_code=200)
250 device = self.get(path, expected_code=404)
251 self.assertIsNone(device)
252
253 # Add cg, cpair, cpart
254 def add(self, type, config, req, name):
255 res = self.verify(type)
256 prev_len = len(res[config])
257 self.post(self.get_path(type, name, ''),
258 MessageToDict(req, preserving_proto_field_name = True),
259 expected_code = 200)
260 return self.verify(type), prev_len
261
262 # Modify the existing cg, cpair, cpart
263 def modify(self, type, req, name):
264 self.post(self.get_path(type, name, '/modify'),
265 MessageToDict(req, preserving_proto_field_name = True),
266 expected_code = 200)
267 return self.verify(type)
268
269 # Delete cg, cpair, cpart
270 def remove(self, type, config, name):
271 res = self.verify(type)
272 prev_len = len(res[config])
273 self.delete(self.get_path(type, name, '/delete'),
274 expected_code = 200)
275 return self.verify(type), prev_len
276
277 # Retrieve the desired item upon Post message
278 def verify(self, type):
279 if(type == 'channel_terminations'):
Rachit Shrivastava8f4f9bf2017-07-20 11:59:30 -0400280 return self.get('/api/v1/devices/{}/{}'.format(device['id'], type))
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400281 return self.get('/api/v1/{}'.format(type))
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400282
283 def get_path(self, type, name, operation):
284 if(type == 'channel_terminations'):
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400285 return '/api/v1/devices/{}/{}/{}{}'.format(device['id'],
Rachit Shrivastava8f4f9bf2017-07-20 11:59:30 -0400286 type, name, operation)
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400287 return '/api/v1/{}/{}{}'.format(type, name, operation)
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400288
289 # Method to check if the result is same as the change requested
290 def search(self, req, result):
Nikolay Titov176f1db2017-08-10 12:38:43 -0400291 dict1 = MessageToDict(req,
292 including_default_value_fields = True,
293 preserving_proto_field_name = True)
Nikolay Titov7253ff22017-08-14 18:24:17 -0400294 #skip comparison of READ-ONLY fields
Nikolay Titov176f1db2017-08-10 12:38:43 -0400295 result['id'] = ''
Nikolay Titov7253ff22017-08-14 18:24:17 -0400296 if isinstance(req, fb.ChannelgroupConfig):
297 result['cg_index'] = 0
298 elif isinstance(req, tcont.TcontsConfigData):
299 result['alloc_id'] = 0
300 elif isinstance(req, gemport.GemportsConfigData):
301 result['gemport_id'] = 0
Nikolay Titov176f1db2017-08-10 12:38:43 -0400302 return dict1 == result
303
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400304
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400305#~~~~~~~~~~~~~~ Function to create test cases on the fly ~~~~~~~~~~~~~~~~
306def create_dynamic_method(key, value):
307 obj_type_config = {
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400308 'cg': {'type':'channel_groups',
309 'config':'channelgroup_config'},
310 'cpart': {'type':'channel_partitions',
311 'config':'channelpartition_config'},
312 'cpair': {'type':'channel_pairs',
313 'config':'channelpair_config'},
314 'cterm': {'type':'channel_terminations',
315 'config':'channeltermination_config'},
316 'vontani':{'type':'v_ont_anis',
317 'config':'v_ontani_config'},
318 'ontani': {'type':'ont_anis',
319 'config':'ontani_config'},
320 'venet': {'type':'v_enets',
Nikolay Titov176f1db2017-08-10 12:38:43 -0400321 'config':'v_enet_config'},
322 'gemport':{'type':'gemports',
323 'config':'gemports_config'},
324 'tcont': {'type':'tconts',
325 'config':'tconts_config'},
326 'tdp': {'type':'traffic_descriptor_profiles',
327 'config':'traffic_descriptor_profiles'}
Rachit Shrivastava8f4f9bf2017-07-20 11:59:30 -0400328 }
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400329
330 def _add(self, type, config, req, name):
331 result, prev_len = self.add(type, config, req, name)
332 self.assertEqual(result[config][prev_len]['name'], name)
333 self.assertEqual(len(result[config]), prev_len+1)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400334 self.assertEqual(self.search(req, result[config][0]), True)
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400335
336 def _mod(self, type, config, req, name):
337 result = self.modify(type, req, name)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400338 self.assertEqual(self.search(req, result[config][0]), True)
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400339
340 def _del(self, type, config, req, name):
341 result, prev_len = self.remove(type, config, name)
342 self.assertEqual(len(result[config]), prev_len-1)
343
344 def _operate(self, obj_action, type_config, req, name):
345 if obj_action == 'add':
346 _add(self, type_config['type'], type_config['config'], req, name)
347 elif obj_action == 'mod':
348 _mod(self, type_config['type'], type_config['config'], req, name)
349 elif obj_action == 'del':
350 _del(self, type_config['type'], type_config['config'], req, name)
Rachit Shrivastava5a2d5692017-07-17 10:29:20 -0400351
352 def _config(self):
353 ParseDict(value['rpc'], value['pb2'])
354 return value['pb2']
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400355
356 def dynamic_test_method(self):
Rachit Shrivastava5a2d5692017-07-17 10:29:20 -0400357 _obj_action = [val for val in key.split('-')]
358 _type_config = obj_type_config[_obj_action[0]]
359 _req = _config(self)
360 _operate(self, _obj_action[1], _type_config, _req, value['rpc']['name'])
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400361
362 return dynamic_test_method
363
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400364#read the set instructions for tests
365#dynamically create test cases in desired sequence
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400366for item in scenario:
367 id = id + 1
368 if(isinstance(item, dict)):
369 for k,v in item.items():
370 dynamic_method = create_dynamic_method(k, v)
Rachit Shrivastavaa182e912017-07-28 15:18:34 -0400371 dynamic_method.__name__ = 'test_{:3d}_{}'.format(id, k).replace(
372 ' ', '0')
Rachit Shrivastavab9809da2017-07-12 11:09:10 -0400373 setattr(TestXPon, dynamic_method.__name__, dynamic_method)
374 del dynamic_method
375
376if __name__ == '__main__':
Rachit Shrivastava5a2d5692017-07-17 10:29:20 -0400377 unittest.main()