blob: cc0589fa6df75c22d6230406689a234cca77c1f2 [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
15from Channels import Channels
Chetan Gaonker41d2e072016-03-15 16:41:31 -070016from subscriberDb import SubscriberDB
Chetan Gaonkercbe79642016-03-09 17:45:58 -080017log.setLevel('INFO')
18
19class Subscriber(Channels):
20
21 STATS_RX = 0
22 STATS_TX = 1
23 STATS_JOIN = 2
24 STATS_LEAVE = 3
Chetan Gaonker41d2e072016-03-15 16:41:31 -070025 SUBSCRIBER_SERVICES = 'DHCP IGMP TLS'
26 def __init__(self, name = 'sub', service = SUBSCRIBER_SERVICES, num = 1, iface = 'veth0', iface_mcast = 'veth2',
Chetan Gaonkercbe79642016-03-09 17:45:58 -080027 mcast_cb = None, loginType = 'wireless'):
28 Channels.__init__(self, num, iface = iface, iface_mcast = iface_mcast, mcast_cb = mcast_cb)
Chetan Gaonker41d2e072016-03-15 16:41:31 -070029 self.name = name
30 self.service = service
31 self.service_map = {}
32 services = self.service.strip().split(' ')
33 for s in services:
34 self.service_map[s] = True
Chetan Gaonkercbe79642016-03-09 17:45:58 -080035 self.loginType = loginType
36 ##start streaming channels
37 self.join_map = {}
38 ##accumulated join recv stats
39 self.join_rx_stats = Stats()
40
Chetan Gaonker41d2e072016-03-15 16:41:31 -070041 def has_service(self, service):
42 if self.service_map.has_key(service):
43 return self.service_map[service]
44 if self.service_map.has_key(service.upper()):
45 return self.service_map[service.upper()]
46 return False
47
Chetan Gaonkercbe79642016-03-09 17:45:58 -080048 def channel_join_update(self, chan, join_time):
49 self.join_map[chan] = ( Stats(), Stats(), Stats(), Stats() )
50 self.channel_update(chan, self.STATS_JOIN, 1, t = join_time)
51
52 def channel_join(self, chan = 0, delay = 2):
53 '''Join a channel and create a send/recv stats map'''
54 if self.join_map.has_key(chan):
55 del self.join_map[chan]
56 self.delay = delay
57 chan, join_time = self.join(chan)
58 self.channel_join_update(chan, join_time)
59 return chan
60
61 def channel_join_next(self, delay = 2):
62 '''Joins the next channel leaving the last channel'''
63 if self.last_chan:
64 if self.join_map.has_key(self.last_chan):
65 del self.join_map[self.last_chan]
66 self.delay = delay
67 chan, join_time = self.join_next()
68 self.channel_join_update(chan, join_time)
69 return chan
70
71 def channel_jump(self, delay = 2):
72 '''Jumps randomly to the next channel leaving the last channel'''
73 if self.last_chan is not None:
74 if self.join_map.has_key(self.last_chan):
75 del self.join_map[self.last_chan]
76 self.delay = delay
77 chan, join_time = self.jump()
78 self.channel_join_update(chan, join_time)
79 return chan
80
81 def channel_leave(self, chan = 0):
82 if self.join_map.has_key(chan):
83 del self.join_map[chan]
84 self.leave(chan)
85
86 def channel_update(self, chan, stats_type, packets, t=0):
87 if type(chan) == type(0):
88 chan_list = (chan,)
89 else:
90 chan_list = chan
91 for c in chan_list:
92 if self.join_map.has_key(c):
93 self.join_map[c][stats_type].update(packets = packets, t = t)
94
95 def channel_receive(self, chan, cb = None, count = 1):
96 self.recv(chan, cb = cb, count = count)
97
98class subscriber_exchange(unittest.TestCase):
99
100 apps = [ 'org.onosproject.aaa', 'org.onosproject.dhcp' ]
101
102 dhcp_server_config = {
103 "ip": "10.1.11.50",
104 "mac": "ca:fe:ca:fe:ca:fe",
105 "subnet": "255.255.252.0",
106 "broadcast": "10.1.11.255",
107 "router": "10.1.8.1",
108 "domain": "8.8.8.8",
109 "ttl": "63",
110 "delay": "2",
111 "startip": "10.1.11.51",
112 "endip": "10.1.11.100"
113 }
114
115 def setUp(self):
116 ''' Activate the dhcp and igmp apps'''
117 for app in self.apps:
118 onos_ctrl = OnosCtrl(app)
119 status, _ = onos_ctrl.activate()
120 assert_equal(status, True)
121 time.sleep(2)
122
123 def teardown(self):
124 '''Deactivate the dhcp app'''
125 for app in self.apps:
126 onos_ctrl = OnosCtrl(app)
127 onos_ctrl.deactivate()
128
129 def onos_aaa_load(self):
130 aaa_dict = {'apps' : { 'org.onosproject.aaa' : { 'AAA' : { 'radiusSecret': 'radius_password',
131 'radiusIp': '172.17.0.2' } } } }
132 radius_ip = os.getenv('ONOS_AAA_IP') or '172.17.0.2'
133 aaa_dict['apps']['org.onosproject.aaa']['AAA']['radiusIp'] = radius_ip
134 self.onos_load_config('org.onosproject.aaa', aaa_dict)
135
136 def onos_dhcp_table_load(self, config = None):
137 dhcp_dict = {'apps' : { 'org.onosproject.dhcp' : { 'dhcp' : copy.copy(self.dhcp_server_config) } } }
138 dhcp_config = dhcp_dict['apps']['org.onosproject.dhcp']['dhcp']
139 if config:
140 for k in config.keys():
141 if dhcp_config.has_key(k):
142 dhcp_config[k] = config[k]
143 self.onos_load_config('org.onosproject.dhcp', dhcp_dict)
144
145 def onos_load_config(self, app, config):
146 onos_ctrl = OnosCtrl(app)
147 status, code = onos_ctrl.config(config)
148 if status is False:
149 log.info('JSON config request for app %s returned status %d' %(app, code))
150 assert_equal(status, True)
151 time.sleep(2)
152
153 def dhcp_sndrcv(self, update_seed = False):
154 cip, sip = self.dhcp.discover(update_seed = update_seed)
155 assert_not_equal(cip, None)
156 assert_not_equal(sip, None)
157 log.info('Got dhcp client IP %s from server %s for mac %s' %
158 (cip, sip, self.dhcp.get_mac(cip)[0]))
159 return cip,sip
160
161 def dhcp_request(self, seed_ip = '10.10.10.1', iface = 'veth0'):
162 config = {'startip':'10.10.10.20', 'endip':'10.10.10.69',
163 'ip':'10.10.10.2', 'mac': "ca:fe:ca:fe:ca:fe",
164 'subnet': '255.255.255.0', 'broadcast':'10.10.10.255', 'router':'10.10.10.1'}
165 self.onos_dhcp_table_load(config)
166 self.dhcp = DHCPTest(seed_ip = seed_ip, iface = iface)
167 cip, sip = self.dhcp_sndrcv()
168 return cip, sip
169
170 def recv_channel_cb(self, pkt):
171 ##First verify that we have received the packet for the joined instance
172 chan = self.subscriber.caddr(pkt[IP].dst)
173 assert_equal(chan in self.subscriber.join_map.keys(), True)
174 recv_time = monotonic.monotonic() * 1000000
175 join_time = self.subscriber.join_map[chan][self.subscriber.STATS_JOIN].start
176 delta = recv_time - join_time
177 self.subscriber.join_rx_stats.update(packets=1, t = delta, usecs = True)
178 self.subscriber.channel_update(chan, self.subscriber.STATS_RX, 1, t = delta)
179 log.info('Packet received in %.3f usecs for group %s after join' %(delta, pkt[IP].dst))
180 self.test_status = True
181
Chetan Gaonker41d2e072016-03-15 16:41:31 -0700182 def subscriber_load(self, create = True, num = 10):
183 '''Load the subscriber from the database'''
184 self.subscriber_db = SubscriberDB(create = create)
185 if create is True:
186 self.subscriber_db.generate(num)
187 self.subscriber_info = self.subscriber_db.read(num)
188 self.subscriber_list = []
189 for info in self.subscriber_info:
190 self.subscriber_list.append(Subscriber(info['Name'], info['Service']))
191
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800192 def test_subscriber_join_recv( self, chan = 0):
193 """Test 1 subscriber join and receive"""
194 self.test_status = False
Chetan Gaonker3c390b62016-03-15 17:43:42 -0700195 self.num_subscribers = 5
Chetan Gaonker41d2e072016-03-15 16:41:31 -0700196 self.subscriber_load(create = True, num = self.num_subscribers)
Chetan Gaonker55fc7882016-03-15 17:46:47 -0700197 self.onos_aaa_load()
Chetan Gaonker41d2e072016-03-15 16:41:31 -0700198 for subscriber in self.subscriber_list:
199 self.subscriber = subscriber
200 self.subscriber.start()
201 log.info('Testing subscriber %s for %s' %(subscriber.name, subscriber.service))
202 if self.subscriber.has_service('TLS'):
Chetan Gaonker41d2e072016-03-15 16:41:31 -0700203 time.sleep(2)
204 tls = TLSAuthTest()
205 tls.runTest()
206 self.test_status = True
207 if self.subscriber.has_service('DHCP'):
208 cip, sip = self.dhcp_request(iface = self.subscriber.iface)
209 log.info('Got client ip %s from server %s' %(cip, sip))
210 self.subscriber.src_list = [cip]
211 self.test_status = True
212 if self.subscriber.has_service('IGMP'):
213 for i in range(5):
214 log.info('Joining channel %d' %chan)
215 self.subscriber.channel_join(chan, delay = 0)
216 self.subscriber.channel_receive(chan, cb = self.recv_channel_cb, count = 1)
217 log.info('Leaving channel %d' %chan)
218 self.subscriber.channel_leave(chan)
219 time.sleep(3)
220 log.info('Join RX stats %s' %self.subscriber.join_rx_stats)
221 self.subscriber.stop()
Chetan Gaonkercbe79642016-03-09 17:45:58 -0800222 ##Terminate the tests on success
223 assert_equal(self.test_status, True)
224
225
226 def test_subscriber_join_jump(self):
227 """Test 1 subscriber join and receive"""
228 self.test_status = False
229 self.subscriber = Subscriber(50)
230 self.subscriber.start()
231 self.onos_aaa_load()
232 #tls = TLSAuthTest()
233 #tls.runTest()
234 ##Next get dhcp
235 cip, sip = self.dhcp_request(seed_ip = '10.10.200.1', iface = self.subscriber.iface)
236 log.info('Got client ip %s from server %s' %(cip, sip))
237 self.subscriber.src_list = [cip]
238 for i in range(50):
239 log.info('Jumping channel')
240 chan = self.subscriber.channel_jump(delay=0)
241 self.subscriber.channel_receive(chan, cb = self.recv_channel_cb, count = 1)
242 log.info('Verified receive for channel %d' %chan)
243 time.sleep(3)
244
245 log.info('Join RX stats %s' %self.subscriber.join_rx_stats)
246 self.subscriber.stop()
247 ##Terminate the tests on success
248 assert_equal(self.test_status, True)
Chetan Gaonker4b959fc2016-03-09 19:20:16 -0800249
250 def test_subscriber_join_next(self):
251 """Test subscriber join next for channels"""
252 self.test_status = False
253 self.subscriber = Subscriber(10)
254 self.subscriber.start()
255 self.onos_aaa_load()
256 #tls = TLSAuthTest()
257 #tls.runTest()
258 ##Next get dhcp
259 cip, sip = self.dhcp_request(seed_ip = '10.10.150.1', iface = self.subscriber.iface)
260 log.info('Got client ip %s from server %s' %(cip, sip))
261 self.subscriber.src_list = [cip]
262 for i in range(10):
263 if i:
264 chan = self.subscriber.channel_join_next(delay=0)
265 else:
266 chan = self.subscriber.channel_join(i, delay=0)
267 log.info('Joined next channel %d' %chan)
268 self.subscriber.channel_receive(chan, cb = self.recv_channel_cb, count=1)
269 log.info('Verified receive for channel %d' %chan)
270 time.sleep(3)
271
272 log.info('Join Next RX stats %s' %self.subscriber.join_rx_stats)
273 self.subscriber.stop()
274 ##Terminate the tests on success
275 assert_equal(self.test_status, True)