blob: 7a52092b0aa4f0d08d4a0ca485295c817c4c5b8f [file] [log] [blame]
A R Karthickb7e80902016-05-17 09:38:31 -07001import unittest
2from nose.tools import *
3from nose.twistedtools import reactor, deferred
4from twisted.internet import defer
5from scapy.all import *
6import time, monotonic
7import os, sys
8import tempfile
9import random
10import threading
11import json
A R Karthick65c4d722016-07-18 14:20:17 -070012import requests
A R Karthickb7e80902016-05-17 09:38:31 -070013from Stats import Stats
14from OnosCtrl import OnosCtrl
15from DHCP import DHCPTest
16from EapTLS import TLSAuthTest
17from Channels import Channels, IgmpChannel
18from subscriberDb import SubscriberDB
19from threadPool import ThreadPool
A.R Karthick95d044e2016-06-10 18:44:36 -070020from portmaps import g_subscriber_port_map
A R Karthickb7e80902016-05-17 09:38:31 -070021from OltConfig import *
A R Karthickb7e80902016-05-17 09:38:31 -070022from CordTestServer import cord_test_onos_restart
23
24log.setLevel('INFO')
25
26class Subscriber(Channels):
27 PORT_TX_DEFAULT = 2
28 PORT_RX_DEFAULT = 1
29 INTF_TX_DEFAULT = 'veth2'
30 INTF_RX_DEFAULT = 'veth0'
31 STATS_RX = 0
32 STATS_TX = 1
33 STATS_JOIN = 2
34 STATS_LEAVE = 3
35 SUBSCRIBER_SERVICES = 'DHCP IGMP TLS'
36 def __init__(self, name = 'sub', service = SUBSCRIBER_SERVICES, port_map = None,
37 num = 1, channel_start = 0,
38 tx_port = PORT_TX_DEFAULT, rx_port = PORT_RX_DEFAULT,
39 iface = INTF_RX_DEFAULT, iface_mcast = INTF_TX_DEFAULT,
40 mcast_cb = None, loginType = 'wireless'):
41 self.tx_port = tx_port
42 self.rx_port = rx_port
43 self.port_map = port_map or g_subscriber_port_map
44 try:
45 self.tx_intf = self.port_map[tx_port]
46 self.rx_intf = self.port_map[rx_port]
47 except:
48 self.tx_intf = self.port_map[self.PORT_TX_DEFAULT]
49 self.rx_intf = self.port_map[self.PORT_RX_DEFAULT]
50
A R Karthick338268f2016-06-21 17:12:13 -070051 log.info('Subscriber %s, rx interface %s, uplink interface %s' %(name, self.rx_intf, self.tx_intf))
A.R Karthick95d044e2016-06-10 18:44:36 -070052 Channels.__init__(self, num, channel_start = channel_start,
A R Karthickb7e80902016-05-17 09:38:31 -070053 iface = self.rx_intf, iface_mcast = self.tx_intf, mcast_cb = mcast_cb)
54 self.name = name
55 self.service = service
56 self.service_map = {}
57 services = self.service.strip().split(' ')
58 for s in services:
59 self.service_map[s] = True
60 self.loginType = loginType
61 ##start streaming channels
62 self.join_map = {}
63 ##accumulated join recv stats
64 self.join_rx_stats = Stats()
A R Karthick338268f2016-06-21 17:12:13 -070065 self.recv_timeout = False
A R Karthickb7e80902016-05-17 09:38:31 -070066
67 def has_service(self, service):
68 if self.service_map.has_key(service):
69 return self.service_map[service]
70 if self.service_map.has_key(service.upper()):
71 return self.service_map[service.upper()]
72 return False
73
74 def channel_join_update(self, chan, join_time):
75 self.join_map[chan] = ( Stats(), Stats(), Stats(), Stats() )
76 self.channel_update(chan, self.STATS_JOIN, 1, t = join_time)
77
78 def channel_join(self, chan = 0, delay = 2):
79 '''Join a channel and create a send/recv stats map'''
80 if self.join_map.has_key(chan):
81 del self.join_map[chan]
82 self.delay = delay
83 chan, join_time = self.join(chan)
84 self.channel_join_update(chan, join_time)
85 return chan
86
87 def channel_join_next(self, delay = 2):
88 '''Joins the next channel leaving the last channel'''
89 if self.last_chan:
90 if self.join_map.has_key(self.last_chan):
91 del self.join_map[self.last_chan]
92 self.delay = delay
93 chan, join_time = self.join_next()
94 self.channel_join_update(chan, join_time)
95 return chan
96
97 def channel_jump(self, delay = 2):
98 '''Jumps randomly to the next channel leaving the last channel'''
99 if self.last_chan is not None:
100 if self.join_map.has_key(self.last_chan):
101 del self.join_map[self.last_chan]
102 self.delay = delay
103 chan, join_time = self.jump()
104 self.channel_join_update(chan, join_time)
105 return chan
106
107 def channel_leave(self, chan = 0):
108 if self.join_map.has_key(chan):
109 del self.join_map[chan]
110 self.leave(chan)
111
112 def channel_update(self, chan, stats_type, packets, t=0):
113 if type(chan) == type(0):
114 chan_list = (chan,)
115 else:
116 chan_list = chan
A.R Karthick95d044e2016-06-10 18:44:36 -0700117 for c in chan_list:
A R Karthickb7e80902016-05-17 09:38:31 -0700118 if self.join_map.has_key(c):
119 self.join_map[c][stats_type].update(packets = packets, t = t)
120
A R Karthick338268f2016-06-21 17:12:13 -0700121 def channel_receive(self, chan, cb = None, count = 1, timeout = 5):
122 log.info('Subscriber %s on port %s receiving from group %s, channel %d' %
123 (self.name, self.rx_intf, self.gaddr(chan), chan))
124 r = self.recv(chan, cb = cb, count = count, timeout = timeout)
125 if self.recv_timeout:
126 ##Negative test case is disabled for now
127 assert_equal(len(r), 0)
A R Karthickb7e80902016-05-17 09:38:31 -0700128
129 def recv_channel_cb(self, pkt):
130 ##First verify that we have received the packet for the joined instance
A R Karthick338268f2016-06-21 17:12:13 -0700131 log.info('Packet received for group %s, subscriber %s, port %s' %
132 (pkt[IP].dst, self.name, self.rx_intf))
133 if self.recv_timeout:
134 return
A R Karthickb7e80902016-05-17 09:38:31 -0700135 chan = self.caddr(pkt[IP].dst)
136 assert_equal(chan in self.join_map.keys(), True)
137 recv_time = monotonic.monotonic() * 1000000
138 join_time = self.join_map[chan][self.STATS_JOIN].start
139 delta = recv_time - join_time
140 self.join_rx_stats.update(packets=1, t = delta, usecs = True)
141 self.channel_update(chan, self.STATS_RX, 1, t = delta)
142 log.debug('Packet received in %.3f usecs for group %s after join' %(delta, pkt[IP].dst))
143
144class subscriber_pool:
145
146 def __init__(self, subscriber, test_cbs):
147 self.subscriber = subscriber
148 self.test_cbs = test_cbs
149
150 def pool_cb(self):
151 for cb in self.test_cbs:
152 if cb:
153 cb(self.subscriber)
A.R Karthick95d044e2016-06-10 18:44:36 -0700154
A R Karthickb7e80902016-05-17 09:38:31 -0700155class subscriber_exchange(unittest.TestCase):
156
A.R Karthick95d044e2016-06-10 18:44:36 -0700157 apps = ('org.opencord.aaa', 'org.onosproject.dhcp')
158 olt_apps = () #'org.opencord.cordmcast')
A R Karthickb7e80902016-05-17 09:38:31 -0700159 table_app = 'org.ciena.cordigmp'
160 dhcp_server_config = {
161 "ip": "10.1.11.50",
162 "mac": "ca:fe:ca:fe:ca:fe",
163 "subnet": "255.255.252.0",
164 "broadcast": "10.1.11.255",
165 "router": "10.1.8.1",
166 "domain": "8.8.8.8",
167 "ttl": "63",
168 "delay": "2",
169 "startip": "10.1.11.51",
170 "endip": "10.1.11.100"
171 }
172
173 aaa_loaded = False
174 test_path = os.path.dirname(os.path.realpath(__file__))
A R Karthick4b72d4b2016-06-15 11:09:17 -0700175 table_app_file = os.path.join(test_path, '..', 'apps/ciena-cordigmp-multitable-2.0-SNAPSHOT.oar')
176 app_file = os.path.join(test_path, '..', 'apps/ciena-cordigmp-2.0-SNAPSHOT.oar')
A R Karthickb7e80902016-05-17 09:38:31 -0700177 onos_config_path = os.path.join(test_path, '..', 'setup/onos-config')
A R Karthickb03cecd2016-07-27 10:27:55 -0700178 olt_conf_file = os.path.join(test_path, '..', 'setup/olt_config.json')
A R Karthickb7e80902016-05-17 09:38:31 -0700179 cpqd_path = os.path.join(test_path, '..', 'setup')
180 ovs_path = cpqd_path
A R Karthick65c4d722016-07-18 14:20:17 -0700181 test_services = ('IGMP', 'TRAFFIC')
A R Karthick338268f2016-06-21 17:12:13 -0700182 num_joins = 0
183 num_subscribers = 0
184 num_channels = 0
185 recv_timeout = False
A R Karthicka478df42016-07-27 16:51:08 -0700186 onos_restartable = not bool(int(os.getenv('ONOS_RESTART_DISABLED', 0)))
A R Karthickb7e80902016-05-17 09:38:31 -0700187
188 @classmethod
A R Karthickd44cea12016-07-20 12:16:41 -0700189 def load_device_id(cls):
A R Karthickb03cecd2016-07-27 10:27:55 -0700190 '''Configure the device id'''
191 did = OnosCtrl.get_device_id()
A R Karthickd44cea12016-07-20 12:16:41 -0700192 #Set the default config
193 cls.device_id = did
194 cls.device_dict = { "devices" : {
195 "{}".format(did) : {
196 "basic" : {
197 "driver" : "pmc-olt"
198 }
199 }
200 },
201 }
202 return did
203
204 @classmethod
A R Karthickb7e80902016-05-17 09:38:31 -0700205 def setUpClass(cls):
206 '''Load the OLT config and activate relevant apps'''
A R Karthickd44cea12016-07-20 12:16:41 -0700207 did = cls.load_device_id()
A R Karthick4b72d4b2016-06-15 11:09:17 -0700208 network_cfg = { "devices" : {
A R Karthickd44cea12016-07-20 12:16:41 -0700209 "{}".format(did) : {
A R Karthick4b72d4b2016-06-15 11:09:17 -0700210 "basic" : {
211 "driver" : "pmc-olt"
212 }
213 }
214 },
215 }
A R Karthick4b72d4b2016-06-15 11:09:17 -0700216 ## Restart ONOS with cpqd driver config for OVS
217 cls.start_onos(network_cfg = network_cfg)
A R Karthickb7e80902016-05-17 09:38:31 -0700218 cls.install_app_table()
A R Karthickb7e80902016-05-17 09:38:31 -0700219 cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
220 OnosCtrl.cord_olt_config(cls.olt.olt_device_data())
A R Karthickb03cecd2016-07-27 10:27:55 -0700221 cls.port_map, cls.port_list = cls.olt.olt_port_map()
A R Karthickb7e80902016-05-17 09:38:31 -0700222 cls.activate_apps(cls.apps + cls.olt_apps)
223
224 @classmethod
225 def tearDownClass(cls):
226 '''Deactivate the olt apps and restart OVS back'''
227 apps = cls.olt_apps + ( cls.table_app,)
228 for app in apps:
229 onos_ctrl = OnosCtrl(app)
230 onos_ctrl.deactivate()
231 cls.uninstall_app_table()
A R Karthicke0f33fa2016-06-22 13:36:02 -0700232 cls.start_onos(network_cfg = {})
A R Karthickb7e80902016-05-17 09:38:31 -0700233
234 @classmethod
235 def activate_apps(cls, apps):
236 for app in apps:
237 onos_ctrl = OnosCtrl(app)
238 status, _ = onos_ctrl.activate()
239 assert_equal(status, True)
240 time.sleep(2)
241
242 @classmethod
243 def install_app_table(cls):
244 ##Uninstall the existing app if any
245 OnosCtrl.uninstall_app(cls.table_app)
246 time.sleep(2)
247 log.info('Installing the multi table app %s for subscriber test' %(cls.table_app_file))
248 OnosCtrl.install_app(cls.table_app_file)
249 time.sleep(3)
250
251 @classmethod
252 def uninstall_app_table(cls):
253 ##Uninstall the table app on class exit
254 OnosCtrl.uninstall_app(cls.table_app)
255 time.sleep(2)
256 log.info('Installing back the cord igmp app %s for subscriber test on exit' %(cls.app_file))
257 OnosCtrl.install_app(cls.app_file)
258
259 @classmethod
260 def start_onos(cls, network_cfg = None):
A R Karthicka478df42016-07-27 16:51:08 -0700261 if cls.onos_restartable is False:
A R Karthick65c4d722016-07-18 14:20:17 -0700262 log.info('ONOS restart is disabled. Skipping ONOS restart')
263 return
A R Karthickb7e80902016-05-17 09:38:31 -0700264 if network_cfg is None:
A R Karthick4b72d4b2016-06-15 11:09:17 -0700265 network_cfg = cls.device_dict
A R Karthickb7e80902016-05-17 09:38:31 -0700266
267 if type(network_cfg) is tuple:
268 res = []
269 for v in network_cfg:
270 res += v.items()
271 config = dict(res)
272 else:
273 config = network_cfg
274 log.info('Restarting ONOS with new network configuration')
A R Karthick338268f2016-06-21 17:12:13 -0700275 return cord_test_onos_restart(config = config)
A R Karthick4b72d4b2016-06-15 11:09:17 -0700276
277 @classmethod
278 def remove_onos_config(cls):
279 try:
280 os.unlink('{}/network-cfg.json'.format(cls.onos_config_path))
281 except: pass
A R Karthickb7e80902016-05-17 09:38:31 -0700282
283 @classmethod
284 def start_cpqd(cls, mac = '00:11:22:33:44:55'):
285 dpid = mac.replace(':', '')
286 cpqd_file = os.sep.join( (cls.cpqd_path, 'cpqd.sh') )
287 cpqd_cmd = '{} {}'.format(cpqd_file, dpid)
288 ret = os.system(cpqd_cmd)
289 assert_equal(ret, 0)
290 time.sleep(10)
A R Karthick4b72d4b2016-06-15 11:09:17 -0700291 device_id = 'of:{}{}'.format('0'*4, dpid)
292 return device_id
A R Karthickb7e80902016-05-17 09:38:31 -0700293
294 @classmethod
295 def start_ovs(cls):
A R Karthick4b72d4b2016-06-15 11:09:17 -0700296 ovs_file = os.sep.join( (cls.ovs_path, 'of-bridge.sh') )
A R Karthickb7e80902016-05-17 09:38:31 -0700297 ret = os.system(ovs_file)
298 assert_equal(ret, 0)
A R Karthick4b72d4b2016-06-15 11:09:17 -0700299 time.sleep(30)
A R Karthickb7e80902016-05-17 09:38:31 -0700300
301 def onos_aaa_load(self):
302 if self.aaa_loaded:
303 return
A.R Karthick95d044e2016-06-10 18:44:36 -0700304 aaa_dict = {'apps' : { 'org.onosproject.aaa' : { 'AAA' : { 'radiusSecret': 'radius_password',
A R Karthickb7e80902016-05-17 09:38:31 -0700305 'radiusIp': '172.17.0.2' } } } }
306 radius_ip = os.getenv('ONOS_AAA_IP') or '172.17.0.2'
307 aaa_dict['apps']['org.onosproject.aaa']['AAA']['radiusIp'] = radius_ip
308 self.onos_load_config('org.onosproject.aaa', aaa_dict)
309 self.aaa_loaded = True
310
311 def onos_dhcp_table_load(self, config = None):
312 dhcp_dict = {'apps' : { 'org.onosproject.dhcp' : { 'dhcp' : copy.copy(self.dhcp_server_config) } } }
313 dhcp_config = dhcp_dict['apps']['org.onosproject.dhcp']['dhcp']
314 if config:
315 for k in config.keys():
316 if dhcp_config.has_key(k):
317 dhcp_config[k] = config[k]
318 self.onos_load_config('org.onosproject.dhcp', dhcp_dict)
319
320 def onos_load_config(self, app, config):
321 status, code = OnosCtrl.config(config)
322 if status is False:
323 log.info('JSON config request for app %s returned status %d' %(app, code))
324 assert_equal(status, True)
325 time.sleep(2)
326
327 def dhcp_sndrcv(self, dhcp, update_seed = False):
328 cip, sip = dhcp.discover(update_seed = update_seed)
329 assert_not_equal(cip, None)
330 assert_not_equal(sip, None)
331 log.info('Got dhcp client IP %s from server %s for mac %s' %
332 (cip, sip, dhcp.get_mac(cip)[0]))
333 return cip,sip
334
335 def dhcp_request(self, subscriber, seed_ip = '10.10.10.1', update_seed = False):
336 config = {'startip':'10.10.10.20', 'endip':'10.10.10.200',
337 'ip':'10.10.10.2', 'mac': "ca:fe:ca:fe:ca:fe",
338 'subnet': '255.255.255.0', 'broadcast':'10.10.10.255', 'router':'10.10.10.1'}
339 self.onos_dhcp_table_load(config)
340 dhcp = DHCPTest(seed_ip = seed_ip, iface = subscriber.iface)
341 cip, sip = self.dhcp_sndrcv(dhcp, update_seed = update_seed)
342 return cip, sip
343
344 def recv_channel_cb(self, pkt):
345 ##First verify that we have received the packet for the joined instance
346 chan = self.subscriber.caddr(pkt[IP].dst)
347 assert_equal(chan in self.subscriber.join_map.keys(), True)
348 recv_time = monotonic.monotonic() * 1000000
349 join_time = self.subscriber.join_map[chan][self.subscriber.STATS_JOIN].start
350 delta = recv_time - join_time
351 self.subscriber.join_rx_stats.update(packets=1, t = delta, usecs = True)
352 self.subscriber.channel_update(chan, self.subscriber.STATS_RX, 1, t = delta)
353 log.debug('Packet received in %.3f usecs for group %s after join' %(delta, pkt[IP].dst))
354 self.test_status = True
355
A R Karthick65c4d722016-07-18 14:20:17 -0700356 def traffic_verify(self, subscriber):
357 if subscriber.has_service('TRAFFIC'):
358 url = 'http://www.google.com'
359 resp = requests.get(url)
360 self.test_status = resp.ok
361 if resp.ok == False:
362 log.info('Subscriber %s failed get from url %s with status code %d'
363 %(subscriber.name, url, resp.status_code))
364 else:
365 log.info('GET request from %s succeeded for subscriber %s'
366 %(url, subscriber.name))
367
A R Karthickb7e80902016-05-17 09:38:31 -0700368 def tls_verify(self, subscriber):
369 if subscriber.has_service('TLS'):
370 time.sleep(2)
A R Karthick4b72d4b2016-06-15 11:09:17 -0700371 tls = TLSAuthTest(intf = subscriber.rx_intf)
A R Karthickb7e80902016-05-17 09:38:31 -0700372 log.info('Running subscriber %s tls auth test' %subscriber.name)
373 tls.runTest()
374 self.test_status = True
375
376 def dhcp_verify(self, subscriber):
A R Karthick4b72d4b2016-06-15 11:09:17 -0700377 if subscriber.has_service('DHCP'):
378 cip, sip = self.dhcp_request(subscriber, update_seed = True)
379 log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
380 subscriber.src_list = [cip]
381 self.test_status = True
382 else:
383 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
384 self.test_status = True
A R Karthickb7e80902016-05-17 09:38:31 -0700385
386 def dhcp_jump_verify(self, subscriber):
A R Karthick4b72d4b2016-06-15 11:09:17 -0700387 if subscriber.has_service('DHCP'):
388 cip, sip = self.dhcp_request(subscriber, seed_ip = '10.10.200.1')
389 log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
390 subscriber.src_list = [cip]
391 self.test_status = True
392 else:
393 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
394 self.test_status = True
A R Karthickb7e80902016-05-17 09:38:31 -0700395
396 def dhcp_next_verify(self, subscriber):
A R Karthick4b72d4b2016-06-15 11:09:17 -0700397 if subscriber.has_service('DHCP'):
398 cip, sip = self.dhcp_request(subscriber, seed_ip = '10.10.150.1')
399 log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
400 subscriber.src_list = [cip]
401 self.test_status = True
402 else:
403 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
404 self.test_status = True
A R Karthickb7e80902016-05-17 09:38:31 -0700405
406 def igmp_verify(self, subscriber):
407 chan = 0
408 if subscriber.has_service('IGMP'):
A R Karthick338268f2016-06-21 17:12:13 -0700409 ##We wait for all the subscribers to join before triggering leaves
410 if subscriber.rx_port > 1:
411 time.sleep(5)
412 subscriber.channel_join(chan, delay = 0)
413 self.num_joins += 1
414 while self.num_joins < self.num_subscribers:
415 time.sleep(5)
416 log.info('All subscribers have joined the channel')
417 for i in range(10):
418 subscriber.channel_receive(chan, cb = subscriber.recv_channel_cb, count = 10)
A R Karthickb7e80902016-05-17 09:38:31 -0700419 log.info('Leaving channel %d for subscriber %s' %(chan, subscriber.name))
420 subscriber.channel_leave(chan)
A R Karthick338268f2016-06-21 17:12:13 -0700421 time.sleep(5)
A R Karthickb7e80902016-05-17 09:38:31 -0700422 log.info('Interface %s Join RX stats for subscriber %s, %s' %(subscriber.iface, subscriber.name,subscriber.join_rx_stats))
A R Karthick338268f2016-06-21 17:12:13 -0700423 #Should not receive packets for this subscriber
424 self.recv_timeout = True
425 subscriber.recv_timeout = True
426 subscriber.channel_receive(chan, cb = subscriber.recv_channel_cb, count = 10)
427 subscriber.recv_timeout = False
428 self.recv_timeout = False
429 log.info('Joining channel %d for subscriber %s' %(chan, subscriber.name))
430 subscriber.channel_join(chan, delay = 0)
A R Karthickb7e80902016-05-17 09:38:31 -0700431 self.test_status = True
432
433 def igmp_jump_verify(self, subscriber):
434 if subscriber.has_service('IGMP'):
435 for i in xrange(subscriber.num):
436 log.info('Subscriber %s jumping channel' %subscriber.name)
437 chan = subscriber.channel_jump(delay=0)
438 subscriber.channel_receive(chan, cb = subscriber.recv_channel_cb, count = 1)
439 log.info('Verified receive for channel %d, subscriber %s' %(chan, subscriber.name))
440 time.sleep(3)
441 log.info('Interface %s Jump RX stats for subscriber %s, %s' %(subscriber.iface, subscriber.name, subscriber.join_rx_stats))
442 self.test_status = True
443
444 def igmp_next_verify(self, subscriber):
445 if subscriber.has_service('IGMP'):
446 for i in xrange(subscriber.num):
447 if i:
448 chan = subscriber.channel_join_next(delay=0)
449 else:
450 chan = subscriber.channel_join(i, delay=0)
451 log.info('Joined next channel %d for subscriber %s' %(chan, subscriber.name))
452 subscriber.channel_receive(chan, cb = subscriber.recv_channel_cb, count=1)
453 log.info('Verified receive for channel %d, subscriber %s' %(chan, subscriber.name))
454 time.sleep(3)
455 log.info('Interface %s Join Next RX stats for subscriber %s, %s' %(subscriber.iface, subscriber.name, subscriber.join_rx_stats))
456 self.test_status = True
457
458 def generate_port_list(self, subscribers, channels):
459 return self.port_list[:subscribers]
460
461 def subscriber_load(self, create = True, num = 10, num_channels = 1, channel_start = 0, port_list = []):
462 '''Load the subscriber from the database'''
A R Karthick4b72d4b2016-06-15 11:09:17 -0700463 self.subscriber_db = SubscriberDB(create = create, services = self.test_services)
A R Karthickb7e80902016-05-17 09:38:31 -0700464 if create is True:
465 self.subscriber_db.generate(num)
466 self.subscriber_info = self.subscriber_db.read(num)
467 self.subscriber_list = []
468 if not port_list:
469 port_list = self.generate_port_list(num, num_channels)
470
471 index = 0
472 for info in self.subscriber_info:
A.R Karthick95d044e2016-06-10 18:44:36 -0700473 self.subscriber_list.append(Subscriber(name=info['Name'],
A R Karthickb7e80902016-05-17 09:38:31 -0700474 service=info['Service'],
475 port_map = self.port_map,
476 num=num_channels,
477 channel_start = channel_start,
478 tx_port = port_list[index][0],
479 rx_port = port_list[index][1]))
480 if num_channels > 1:
481 channel_start += num_channels
482 index += 1
483
484 #load the ssm list for all subscriber channels
485 igmpChannel = IgmpChannel()
486 ssm_groups = map(lambda sub: sub.channels, self.subscriber_list)
487 ssm_list = reduce(lambda ssm1, ssm2: ssm1+ssm2, ssm_groups)
488 igmpChannel.igmp_load_ssm_config(ssm_list)
489
A.R Karthick95d044e2016-06-10 18:44:36 -0700490 def subscriber_join_verify( self, num_subscribers = 10, num_channels = 1,
A R Karthickb7e80902016-05-17 09:38:31 -0700491 channel_start = 0, cbs = None, port_list = []):
492 self.test_status = False
493 self.num_subscribers = num_subscribers
494 self.subscriber_load(create = True, num = num_subscribers,
495 num_channels = num_channels, channel_start = channel_start, port_list = port_list)
496 self.onos_aaa_load()
497 self.thread_pool = ThreadPool(min(100, self.num_subscribers), queue_size=1, wait_timeout=1)
A R Karthick338268f2016-06-21 17:12:13 -0700498 chan_leave = False #for single channel, multiple subscribers
A R Karthickb7e80902016-05-17 09:38:31 -0700499 if cbs is None:
A R Karthick65c4d722016-07-18 14:20:17 -0700500 cbs = (self.tls_verify, self.dhcp_verify, self.igmp_verify, self.traffic_verify)
A R Karthick338268f2016-06-21 17:12:13 -0700501 chan_leave = True
A R Karthickb7e80902016-05-17 09:38:31 -0700502 for subscriber in self.subscriber_list:
503 subscriber.start()
504 pool_object = subscriber_pool(subscriber, cbs)
505 self.thread_pool.addTask(pool_object.pool_cb)
506 self.thread_pool.cleanUpThreads()
507 for subscriber in self.subscriber_list:
508 subscriber.stop()
A R Karthick338268f2016-06-21 17:12:13 -0700509 if chan_leave is True:
510 subscriber.channel_leave(0)
511 self.num_subscribers = 0
A R Karthickb7e80902016-05-17 09:38:31 -0700512 return self.test_status
513
514 def test_subscriber_join_recv(self):
ChetanGaonkerf9c2f8b2016-07-19 15:49:41 -0700515 """Test subscriber join and receive for channel surfing"""
A R Karthick338268f2016-06-21 17:12:13 -0700516 self.num_subscribers = 5
517 self.num_channels = 1
A R Karthicka478df42016-07-27 16:51:08 -0700518 test_status = True
519 ##Run this test only if ONOS can be restarted as it incurs a network-cfg change
520 if self.onos_restartable is True:
521 test_status = self.subscriber_join_verify(num_subscribers = self.num_subscribers,
522 num_channels = self.num_channels,
523 port_list = self.generate_port_list(self.num_subscribers,
524 self.num_channels))
A R Karthickb7e80902016-05-17 09:38:31 -0700525 assert_equal(test_status, True)
526
527 def test_subscriber_join_jump(self):
A R Karthicka478df42016-07-27 16:51:08 -0700528 """Test subscriber join jump for channel surfing"""
A R Karthick338268f2016-06-21 17:12:13 -0700529 self.num_subscribers = 5
530 self.num_channels = 10
531 test_status = self.subscriber_join_verify(num_subscribers = self.num_subscribers,
532 num_channels = self.num_channels,
A R Karthick65c4d722016-07-18 14:20:17 -0700533 cbs = (self.tls_verify, self.dhcp_jump_verify,
534 self.igmp_jump_verify, self.traffic_verify),
A R Karthick338268f2016-06-21 17:12:13 -0700535 port_list = self.generate_port_list(self.num_subscribers,
536 self.num_channels))
A R Karthickb7e80902016-05-17 09:38:31 -0700537 assert_equal(test_status, True)
538
539 def test_subscriber_join_next(self):
ChetanGaonkerf9c2f8b2016-07-19 15:49:41 -0700540 """Test subscriber join next for channel surfing"""
A R Karthick338268f2016-06-21 17:12:13 -0700541 self.num_subscribers = 5
542 self.num_channels = 10
543 test_status = self.subscriber_join_verify(num_subscribers = self.num_subscribers,
544 num_channels = self.num_channels,
A R Karthick65c4d722016-07-18 14:20:17 -0700545 cbs = (self.tls_verify, self.dhcp_next_verify,
546 self.igmp_next_verify, self.traffic_verify),
A R Karthick338268f2016-06-21 17:12:13 -0700547 port_list = self.generate_port_list(self.num_subscribers,
548 self.num_channels))
A R Karthickb7e80902016-05-17 09:38:31 -0700549 assert_equal(test_status, True)