blob: fca933543b1dc6b1b91af8ee370e82a70ddb5f62 [file] [log] [blame]
Chetan Gaonkercbe79642016-03-09 17:45:58 -08001import 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
11from Stats import Stats
12from OnosCtrl import OnosCtrl
13from DHCP import DHCPTest
14from EapTLS import TLSAuthTest
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -070015from Channels import Channels, IgmpChannel
Chetan Gaonker41d2e072016-03-15 16:41:31 -070016from subscriberDb import SubscriberDB
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -070017from threadPool import ThreadPool
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -070018from portmaps import g_subscriber_port_map
Chetan Gaonker7997bb42016-03-28 09:46:15 -070019from OltConfig import *
Chetan Gaonkercbe79642016-03-09 17:45:58 -080020log.setLevel('INFO')
21
22class Subscriber(Channels):
Chetan Gaonker7997bb42016-03-28 09:46:15 -070023 PORT_TX_DEFAULT = 2
24 PORT_RX_DEFAULT = 1
25 INTF_TX_DEFAULT = 'veth2'
26 INTF_RX_DEFAULT = 'veth0'
Chetan Gaonkercbe79642016-03-09 17:45:58 -080027 STATS_RX = 0
28 STATS_TX = 1
29 STATS_JOIN = 2
30 STATS_LEAVE = 3
Chetan Gaonker41d2e072016-03-15 16:41:31 -070031 SUBSCRIBER_SERVICES = 'DHCP IGMP TLS'
Chetan Gaonker7997bb42016-03-28 09:46:15 -070032 def __init__(self, name = 'sub', service = SUBSCRIBER_SERVICES, port_map = None,
33 num = 1, channel_start = 0,
34 tx_port = PORT_TX_DEFAULT, rx_port = PORT_RX_DEFAULT,
35 iface = INTF_RX_DEFAULT, iface_mcast = INTF_TX_DEFAULT,
Chetan Gaonkercbe79642016-03-09 17:45:58 -080036 mcast_cb = None, loginType = 'wireless'):
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -070037 self.tx_port = tx_port
38 self.rx_port = rx_port
Chetan Gaonker7997bb42016-03-28 09:46:15 -070039 self.port_map = port_map or g_subscriber_port_map
40 try:
41 self.tx_intf = self.port_map[tx_port]
42 self.rx_intf = self.port_map[rx_port]
43 except:
Chetan Gaonker3d163852016-03-28 12:20:25 -070044 self.tx_intf = self.port_map[self.PORT_TX_DEFAULT]
45 self.rx_intf = self.port_map[self.PORT_RX_DEFAULT]
Chetan Gaonker7997bb42016-03-28 09:46:15 -070046
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -070047 Channels.__init__(self, num, channel_start = channel_start,
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -070048 iface = self.rx_intf, iface_mcast = self.tx_intf, mcast_cb = mcast_cb)
Chetan Gaonker41d2e072016-03-15 16:41:31 -070049 self.name = name
50 self.service = service
51 self.service_map = {}
52 services = self.service.strip().split(' ')
53 for s in services:
54 self.service_map[s] = True
Chetan Gaonkercbe79642016-03-09 17:45:58 -080055 self.loginType = loginType
56 ##start streaming channels
57 self.join_map = {}
58 ##accumulated join recv stats
59 self.join_rx_stats = Stats()
60
Chetan Gaonker41d2e072016-03-15 16:41:31 -070061 def has_service(self, service):
62 if self.service_map.has_key(service):
63 return self.service_map[service]
64 if self.service_map.has_key(service.upper()):
65 return self.service_map[service.upper()]
66 return False
67
Chetan Gaonkercbe79642016-03-09 17:45:58 -080068 def channel_join_update(self, chan, join_time):
69 self.join_map[chan] = ( Stats(), Stats(), Stats(), Stats() )
70 self.channel_update(chan, self.STATS_JOIN, 1, t = join_time)
71
72 def channel_join(self, chan = 0, delay = 2):
73 '''Join a channel and create a send/recv stats map'''
74 if self.join_map.has_key(chan):
75 del self.join_map[chan]
76 self.delay = delay
77 chan, join_time = self.join(chan)
78 self.channel_join_update(chan, join_time)
79 return chan
80
81 def channel_join_next(self, delay = 2):
82 '''Joins the next channel leaving the last channel'''
83 if self.last_chan:
84 if self.join_map.has_key(self.last_chan):
85 del self.join_map[self.last_chan]
86 self.delay = delay
87 chan, join_time = self.join_next()
88 self.channel_join_update(chan, join_time)
89 return chan
90
91 def channel_jump(self, delay = 2):
92 '''Jumps randomly to the next channel leaving the last channel'''
93 if self.last_chan is not None:
94 if self.join_map.has_key(self.last_chan):
95 del self.join_map[self.last_chan]
96 self.delay = delay
97 chan, join_time = self.jump()
98 self.channel_join_update(chan, join_time)
99 return chan
100
101 def channel_leave(self, chan = 0):
102 if self.join_map.has_key(chan):
103 del self.join_map[chan]
104 self.leave(chan)
105
106 def channel_update(self, chan, stats_type, packets, t=0):
107 if type(chan) == type(0):
108 chan_list = (chan,)
109 else:
110 chan_list = chan
111 for c in chan_list:
112 if self.join_map.has_key(c):
113 self.join_map[c][stats_type].update(packets = packets, t = t)
114
115 def channel_receive(self, chan, cb = None, count = 1):
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700116 log.info('Subscriber %s receiving from group %s, channel %d' %(self.name, self.gaddr(chan), chan))
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800117 self.recv(chan, cb = cb, count = count)
118
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700119 def recv_channel_cb(self, pkt):
120 ##First verify that we have received the packet for the joined instance
121 log.debug('Packet received for group %s, subscriber %s' %(pkt[IP].dst, self.name))
122 chan = self.caddr(pkt[IP].dst)
123 assert_equal(chan in self.join_map.keys(), True)
124 recv_time = monotonic.monotonic() * 1000000
125 join_time = self.join_map[chan][self.STATS_JOIN].start
126 delta = recv_time - join_time
127 self.join_rx_stats.update(packets=1, t = delta, usecs = True)
128 self.channel_update(chan, self.STATS_RX, 1, t = delta)
129 log.debug('Packet received in %.3f usecs for group %s after join' %(delta, pkt[IP].dst))
130
131class subscriber_pool:
132
133 def __init__(self, subscriber, test_cbs):
134 self.subscriber = subscriber
135 self.test_cbs = test_cbs
136
137 def pool_cb(self):
138 for cb in self.test_cbs:
139 if cb:
140 cb(self.subscriber)
141
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800142class subscriber_exchange(unittest.TestCase):
143
144 apps = [ 'org.onosproject.aaa', 'org.onosproject.dhcp' ]
145
146 dhcp_server_config = {
147 "ip": "10.1.11.50",
148 "mac": "ca:fe:ca:fe:ca:fe",
149 "subnet": "255.255.252.0",
150 "broadcast": "10.1.11.255",
151 "router": "10.1.8.1",
152 "domain": "8.8.8.8",
153 "ttl": "63",
154 "delay": "2",
155 "startip": "10.1.11.51",
156 "endip": "10.1.11.100"
157 }
158
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700159 aaa_loaded = False
160
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800161 def setUp(self):
Chetan Gaonker7997bb42016-03-28 09:46:15 -0700162 '''Load the OLT config and activate relevant apps'''
163 self.olt = OltConfig()
164 self.port_map = self.olt.olt_port_map()
165 ##if no olt config, fall back to ovs port map
166 if not self.port_map:
167 self.port_map = g_subscriber_port_map
168 else:
169 log.info('Using OLT Port configuration for test setup')
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800170 for app in self.apps:
171 onos_ctrl = OnosCtrl(app)
172 status, _ = onos_ctrl.activate()
173 assert_equal(status, True)
174 time.sleep(2)
175
176 def teardown(self):
177 '''Deactivate the dhcp app'''
178 for app in self.apps:
179 onos_ctrl = OnosCtrl(app)
180 onos_ctrl.deactivate()
181
182 def onos_aaa_load(self):
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700183 if self.aaa_loaded:
184 return
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800185 aaa_dict = {'apps' : { 'org.onosproject.aaa' : { 'AAA' : { 'radiusSecret': 'radius_password',
186 'radiusIp': '172.17.0.2' } } } }
187 radius_ip = os.getenv('ONOS_AAA_IP') or '172.17.0.2'
188 aaa_dict['apps']['org.onosproject.aaa']['AAA']['radiusIp'] = radius_ip
189 self.onos_load_config('org.onosproject.aaa', aaa_dict)
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700190 self.aaa_loaded = True
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800191
192 def onos_dhcp_table_load(self, config = None):
193 dhcp_dict = {'apps' : { 'org.onosproject.dhcp' : { 'dhcp' : copy.copy(self.dhcp_server_config) } } }
194 dhcp_config = dhcp_dict['apps']['org.onosproject.dhcp']['dhcp']
195 if config:
196 for k in config.keys():
197 if dhcp_config.has_key(k):
198 dhcp_config[k] = config[k]
199 self.onos_load_config('org.onosproject.dhcp', dhcp_dict)
200
201 def onos_load_config(self, app, config):
202 onos_ctrl = OnosCtrl(app)
203 status, code = onos_ctrl.config(config)
204 if status is False:
205 log.info('JSON config request for app %s returned status %d' %(app, code))
206 assert_equal(status, True)
207 time.sleep(2)
208
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700209 def dhcp_sndrcv(self, dhcp, update_seed = False):
210 cip, sip = dhcp.discover(update_seed = update_seed)
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800211 assert_not_equal(cip, None)
212 assert_not_equal(sip, None)
213 log.info('Got dhcp client IP %s from server %s for mac %s' %
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700214 (cip, sip, dhcp.get_mac(cip)[0]))
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800215 return cip,sip
216
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700217 def dhcp_request(self, subscriber, seed_ip = '10.10.10.1', update_seed = False):
Chetan Gaonker00971202016-03-23 15:11:12 -0700218 config = {'startip':'10.10.10.20', 'endip':'10.10.10.200',
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800219 'ip':'10.10.10.2', 'mac': "ca:fe:ca:fe:ca:fe",
220 'subnet': '255.255.255.0', 'broadcast':'10.10.10.255', 'router':'10.10.10.1'}
221 self.onos_dhcp_table_load(config)
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700222 dhcp = DHCPTest(seed_ip = seed_ip, iface = subscriber.iface)
223 cip, sip = self.dhcp_sndrcv(dhcp, update_seed = update_seed)
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800224 return cip, sip
225
226 def recv_channel_cb(self, pkt):
227 ##First verify that we have received the packet for the joined instance
228 chan = self.subscriber.caddr(pkt[IP].dst)
229 assert_equal(chan in self.subscriber.join_map.keys(), True)
230 recv_time = monotonic.monotonic() * 1000000
231 join_time = self.subscriber.join_map[chan][self.subscriber.STATS_JOIN].start
232 delta = recv_time - join_time
233 self.subscriber.join_rx_stats.update(packets=1, t = delta, usecs = True)
234 self.subscriber.channel_update(chan, self.subscriber.STATS_RX, 1, t = delta)
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700235 log.debug('Packet received in %.3f usecs for group %s after join' %(delta, pkt[IP].dst))
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800236 self.test_status = True
237
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700238 def tls_verify(self, subscriber):
239 if subscriber.has_service('TLS'):
240 time.sleep(2)
241 tls = TLSAuthTest()
242 log.info('Running subscriber %s tls auth test' %subscriber.name)
243 tls.runTest()
244 self.test_status = True
245
246 def dhcp_verify(self, subscriber):
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700247 cip, sip = self.dhcp_request(subscriber, update_seed = True)
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700248 log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
249 subscriber.src_list = [cip]
250 self.test_status = True
251
252 def dhcp_jump_verify(self, subscriber):
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700253 cip, sip = self.dhcp_request(subscriber, seed_ip = '10.10.200.1')
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700254 log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
255 subscriber.src_list = [cip]
256 self.test_status = True
257
258 def dhcp_next_verify(self, subscriber):
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700259 cip, sip = self.dhcp_request(subscriber, seed_ip = '10.10.150.1')
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700260 log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
261 subscriber.src_list = [cip]
262 self.test_status = True
263
264 def igmp_verify(self, subscriber):
265 chan = 0
266 if subscriber.has_service('IGMP'):
267 for i in range(5):
268 log.info('Joining channel %d for subscriber %s' %(chan, subscriber.name))
269 subscriber.channel_join(chan, delay = 0)
270 subscriber.channel_receive(chan, cb = subscriber.recv_channel_cb, count = 1)
271 log.info('Leaving channel %d for subscriber %s' %(chan, subscriber.name))
272 subscriber.channel_leave(chan)
273 time.sleep(3)
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700274 log.info('Interface %s Join RX stats for subscriber %s, %s' %(subscriber.iface, subscriber.name,subscriber.join_rx_stats))
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700275 self.test_status = True
276
277 def igmp_jump_verify(self, subscriber):
278 if subscriber.has_service('IGMP'):
279 for i in xrange(subscriber.num):
280 log.info('Subscriber %s jumping channel' %subscriber.name)
281 chan = subscriber.channel_jump(delay=0)
282 subscriber.channel_receive(chan, cb = subscriber.recv_channel_cb, count = 1)
283 log.info('Verified receive for channel %d, subscriber %s' %(chan, subscriber.name))
284 time.sleep(3)
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700285 log.info('Interface %s Jump RX stats for subscriber %s, %s' %(subscriber.iface, subscriber.name, subscriber.join_rx_stats))
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700286 self.test_status = True
287
288 def igmp_next_verify(self, subscriber):
289 if subscriber.has_service('IGMP'):
290 for i in xrange(subscriber.num):
291 if i:
292 chan = subscriber.channel_join_next(delay=0)
293 else:
294 chan = subscriber.channel_join(i, delay=0)
295 log.info('Joined next channel %d for subscriber %s' %(chan, subscriber.name))
296 subscriber.channel_receive(chan, cb = subscriber.recv_channel_cb, count=1)
297 log.info('Verified receive for channel %d, subscriber %s' %(chan, subscriber.name))
298 time.sleep(3)
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700299 log.info('Interface %s Join Next RX stats for subscriber %s, %s' %(subscriber.iface, subscriber.name, subscriber.join_rx_stats))
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700300 self.test_status = True
301
Chetan Gaonker3d163852016-03-28 12:20:25 -0700302 def generate_port_list(self, subscribers, channels):
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700303 port_list = []
Chetan Gaonker3d163852016-03-28 12:20:25 -0700304 for i in xrange(subscribers):
305 if channels > 1:
306 rx_port = 2*i+1
307 tx_port = 2*i+2
308 else:
309 rx_port = Subscriber.PORT_RX_DEFAULT
310 tx_port = Subscriber.PORT_TX_DEFAULT
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700311 port_list.append((tx_port, rx_port))
312 return port_list
313
314 def subscriber_load(self, create = True, num = 10, num_channels = 1, channel_start = 0, port_list = []):
Chetan Gaonker41d2e072016-03-15 16:41:31 -0700315 '''Load the subscriber from the database'''
316 self.subscriber_db = SubscriberDB(create = create)
317 if create is True:
318 self.subscriber_db.generate(num)
319 self.subscriber_info = self.subscriber_db.read(num)
320 self.subscriber_list = []
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700321 if not port_list:
Chetan Gaonker3d163852016-03-28 12:20:25 -0700322 port_list = self.generate_port_list(num, num_channels)
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700323
324 index = 0
Chetan Gaonker41d2e072016-03-15 16:41:31 -0700325 for info in self.subscriber_info:
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700326 self.subscriber_list.append(Subscriber(name=info['Name'],
327 service=info['Service'],
Chetan Gaonker7997bb42016-03-28 09:46:15 -0700328 port_map = self.port_map,
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700329 num=num_channels,
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700330 channel_start = channel_start,
331 tx_port = port_list[index][0],
332 rx_port = port_list[index][1]))
Chetan Gaonker3d163852016-03-28 12:20:25 -0700333 if num_channels > 1:
334 channel_start += num_channels
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700335 index += 1
336
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700337 #load the ssm list for all subscriber channels
338 igmpChannel = IgmpChannel()
339 ssm_groups = map(lambda sub: sub.channels, self.subscriber_list)
340 ssm_list = reduce(lambda ssm1, ssm2: ssm1+ssm2, ssm_groups)
341 igmpChannel.igmp_load_ssm_config(ssm_list)
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700342 #load the subscriber to mcast port map for cord
343 cord_port_map = {}
344 for sub in self.subscriber_list:
345 for chan in sub.channels:
346 cord_port_map[chan] = (sub.tx_port, sub.rx_port)
347
348 igmpChannel.cord_port_table_load(cord_port_map)
Chetan Gaonker41d2e072016-03-15 16:41:31 -0700349
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700350 def subscriber_join_verify( self, num_subscribers = 10, num_channels = 1,
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700351 channel_start = 0, cbs = None, port_list = []):
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800352 self.test_status = False
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700353 self.num_subscribers = num_subscribers
Chetan Gaonker7997bb42016-03-28 09:46:15 -0700354 self.subscriber_load(create = True, num = num_subscribers,
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700355 num_channels = num_channels, channel_start = channel_start, port_list = port_list)
Chetan Gaonker55fc7882016-03-15 17:46:47 -0700356 self.onos_aaa_load()
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700357 self.thread_pool = ThreadPool(min(100, self.num_subscribers), queue_size=1, wait_timeout=1)
358 if cbs is None:
359 cbs = (self.tls_verify, self.dhcp_verify, self.igmp_verify)
Chetan Gaonker41d2e072016-03-15 16:41:31 -0700360 for subscriber in self.subscriber_list:
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700361 subscriber.start()
362 pool_object = subscriber_pool(subscriber, cbs)
363 self.thread_pool.addTask(pool_object.pool_cb)
364 self.thread_pool.cleanUpThreads()
365 for subscriber in self.subscriber_list:
366 subscriber.stop()
367 return self.test_status
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800368
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700369 def test_subscriber_join_recv(self):
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700370 """Test subscriber join and receive"""
371 num_subscribers = 50
Chetan Gaonker3d163852016-03-28 12:20:25 -0700372 num_channels = 1
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700373 test_status = self.subscriber_join_verify(num_subscribers = num_subscribers,
Chetan Gaonker3d163852016-03-28 12:20:25 -0700374 num_channels = num_channels,
375 port_list = self.generate_port_list(num_subscribers, num_channels))
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700376 assert_equal(test_status, True)
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800377
378 def test_subscriber_join_jump(self):
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700379 """Test subscriber join and receive for channel surfing"""
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700380 num_subscribers = 5
Chetan Gaonker3d163852016-03-28 12:20:25 -0700381 num_channels = 50
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700382 test_status = self.subscriber_join_verify(num_subscribers = num_subscribers,
Chetan Gaonker3d163852016-03-28 12:20:25 -0700383 num_channels = num_channels,
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700384 cbs = (self.tls_verify, self.dhcp_jump_verify, self.igmp_jump_verify),
Chetan Gaonker3d163852016-03-28 12:20:25 -0700385 port_list = self.generate_port_list(num_subscribers, num_channels))
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700386 assert_equal(test_status, True)
Chetan Gaonker4b959fc2016-03-09 19:20:16 -0800387
388 def test_subscriber_join_next(self):
389 """Test subscriber join next for channels"""
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700390 num_subscribers = 5
Chetan Gaonker3d163852016-03-28 12:20:25 -0700391 num_channels = 50
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700392 test_status = self.subscriber_join_verify(num_subscribers = num_subscribers,
Chetan Gaonker3d163852016-03-28 12:20:25 -0700393 num_channels = num_channels,
Chetan Gaonkera58ab6e2016-03-23 15:04:20 -0700394 cbs = (self.tls_verify, self.dhcp_next_verify, self.igmp_next_verify),
Chetan Gaonker3d163852016-03-28 12:20:25 -0700395 port_list = self.generate_port_list(num_subscribers, num_channels))
Chetan Gaonkercd86bdd2016-03-17 00:08:12 -0700396 assert_equal(test_status, True)