blob: 24130bbfa72b82bc8da5b53bdc1743a5f48b4ffa [file] [log] [blame]
Chetan Gaonkerc1df33a2017-08-18 01:29:54 +00001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
17#
18# Copyright 2016-present Ciena Corporation
19#
20# Licensed under the Apache License, Version 2.0 (the "License");
21# you may not use this file except in compliance with the License.
22# You may obtain a copy of the License at
23#
24# http://www.apache.org/licenses/LICENSE-2.0
25#
26# Unless required by applicable law or agreed to in writing, software
27# distributed under the License is distributed on an "AS IS" BASIS,
28# WITHOUT WARRANTIES OR CONDITIONS OF AeY KIND, either express or implied.
29# See the License for the specific language governing permissions and
30# limitations under the License.
31#
32import unittest
33from nose.tools import *
34from nose.twistedtools import reactor, deferred
35from twisted.internet import defer
36import time
37import os, sys
38from DHCP import DHCPTest
39from CordTestUtils import get_mac, log_test
40from OnosCtrl import OnosCtrl
41from OltConfig import OltConfig
42from CordTestServer import cord_test_onos_restart
43from CordLogger import CordLogger
44from portmaps import g_subscriber_port_map
45import threading, random
46from threading import current_thread
47log_test.setLevel('INFO')
48
49class dhcpl2relay_exchange(CordLogger):
50
51 app = 'org.opencord.dhcpl2relay'
52 sadis_app = 'org.opencord.sadis'
53 app_dhcp = 'org.onosproject.dhcp'
54 relay_interfaces_last = ()
55 interface_to_mac_map = {}
56 host_ip_map = {}
57 test_path = os.path.dirname(os.path.realpath(__file__))
58 dhcp_data_dir = os.path.join(test_path, '..', 'setup')
59 olt_conf_file = os.getenv('OLT_CONFIG_FILE', os.path.join(test_path, '..', 'setup/olt_config.json'))
60 default_config = { 'default-lease-time' : 600, 'max-lease-time' : 7200, }
61 default_options = [ ('subnet-mask', '255.255.255.0'),
62 ('broadcast-address', '192.168.1.255'),
63 ('domain-name-servers', '192.168.1.1'),
64 ('domain-name', '"mydomain.cord-tester"'),
65 ]
66 default_subnet_config = [ ('192.168.1.2',
67'''
68subnet 192.168.1.0 netmask 255.255.255.0 {
69 range 192.168.1.10 192.168.1.100;
70}
71'''), ]
72
73 lock = threading.Condition()
74 ip_count = 0
75 failure_count = 0
76 start_time = 0
77 diff = 0
78
79 transaction_count = 0
80 transactions = 0
81 running_time = 0
82 total_success = 0
83 total_failure = 0
84 #just in case we want to reset ONOS to default network cfg after relay tests
85 onos_restartable = bool(int(os.getenv('ONOS_RESTART', 0)))
86 configs = {}
87
88 @classmethod
89 def setUpClass(cls):
90 ''' Activate the cord dhcpl2relay app'''
91 OnosCtrl(cls.app_dhcp).deactivate()
92 time.sleep(3)
93 cls.onos_ctrl = OnosCtrl(cls.app)
94 status, _ = cls.onos_ctrl.activate()
95 assert_equal(status, True)
96 time.sleep(3)
97 cls.onos_ctrl = OnosCtrl(cls.sadis_app)
98 status, _ = cls.onos_ctrl.activate()
99 assert_equal(status, True)
100 time.sleep(3)
101 cls.dhcp_l2_relay_setup()
102 ##start dhcpd initially with default config
103 cls.dhcpd_start()
104
105 @classmethod
106 def tearDownClass(cls):
107 '''Deactivate the cord dhcpl2relay app'''
108 try:
109 os.unlink('{}/dhcpd.conf'.format(cls.dhcp_data_dir))
110 os.unlink('{}/dhcpd.leases'.format(cls.dhcp_data_dir))
111 except: pass
112 cls.onos_ctrl.deactivate()
113 cls.dhcpd_stop()
114 cls.dhcp_l2_relay_cleanup()
115
116 @classmethod
117 def dhcp_l2_relay_setup(cls):
118 did = OnosCtrl.get_device_id()
119 cls.relay_device_id = did
120 cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
121 cls.port_map, _ = cls.olt.olt_port_map()
122 if cls.port_map:
123 ##Per subscriber, we use 1 relay port
124 try:
125 relay_port = cls.port_map[cls.port_map['relay_ports'][0]]
126 except:
127 relay_port = cls.port_map['uplink']
128 cls.relay_interface_port = relay_port
129 cls.relay_interfaces = (cls.port_map[cls.relay_interface_port],)
130 else:
131 cls.relay_interface_port = 100
132 cls.relay_interfaces = (g_subscriber_port_map[cls.relay_interface_port],)
133 cls.relay_interfaces_last = cls.relay_interfaces
134 if cls.port_map:
135 ##generate a ip/mac client virtual interface config for onos
136 interface_list = []
137 for port in cls.port_map['ports']:
138 port_num = cls.port_map[port]
139 if port_num == cls.port_map['uplink']:
140 continue
141 ip = cls.get_host_ip(port_num)
142 mac = cls.get_mac(port)
143 interface_list.append((port_num, ip, mac))
144
145 #configure dhcp server virtual interface on the same subnet as first client interface
146 relay_ip = cls.get_host_ip(interface_list[0][0])
147 relay_mac = cls.get_mac(cls.port_map[cls.relay_interface_port])
148 interface_list.append((cls.relay_interface_port, relay_ip, relay_mac))
149 cls.onos_interface_load(interface_list)
150
151 @classmethod
152 def dhcp_l2_relay_cleanup(cls):
153 ##reset the ONOS port configuration back to default
154 for config in cls.configs.items():
155 OnosCtrl.delete(config)
156 # if cls.onos_restartable is True:
157 # log_test.info('Cleaning up dhcp relay config by restarting ONOS with default network cfg')
158 # return cord_test_onos_restart(config = {})
159
160 @classmethod
161 def onos_load_config(cls, config):
162 status, code = OnosCtrl.config(config)
163 if status is False:
164 log_test.info('JSON request returned status %d' %code)
165 assert_equal(status, True)
166 time.sleep(3)
167
168 @classmethod
169 def onos_interface_load(cls, interface_list):
170 interface_dict = { 'ports': {} }
171 for port_num, ip, mac in interface_list:
172 port_map = interface_dict['ports']
173 port = '{}/{}'.format(cls.relay_device_id, port_num)
174 port_map[port] = { 'interfaces': [] }
175 interface_list = port_map[port]['interfaces']
176 interface_map = { 'ips' : [ '{}/{}'.format(ip, 24) ],
177 'mac' : mac,
178 'name': 'vir-{}'.format(port_num)
179 }
180 interface_list.append(interface_map)
181
182 cls.onos_load_config(interface_dict)
183 cls.configs['interface_config'] = interface_dict
184
185 @classmethod
186 def cord_l2_relay_load(cls):
187 relay_device_id = '{}'.format(cls.relay_device_id)
188 dhcp_dict = {'apps':{'org.opencord.dhcpl2relay':{'dhcpl2relay':
189 {'dhcpserverConnectPoint':[relay_device_id]}
190 }
191 }
192 }
193 cls.onos_load_config(dhcp_dict)
194 cls.configs['relay_config'] = dhcp_dict
195
196 @classmethod
197 def cord_sadis_load(cls):
198 relay_device_id = '{}'.format(cls.relay_device_id)
199 sadis_dict = {'apps':{ "org.opencord.sadis" : {
200 "sadis" : {
201 "integration" : {
202 "cache" : {
203 "enabled" : true,
204 "maxsize" : 50,
205 "ttl" : "PT1m"
206 }
207 },
208 "entries" : [ {
209 "id" : "uni-254", # (This is an entry for a subscriber) Same as the portName of the Port as seen in onos ports command
210 "cTag" : 202, # C-tag of the subscriber
211 "sTag" : 222, # S-tag of the subscriber
212 "nasPortId" : "uni-254" # NAS Port Id of the subscriber, could be different from the id above
213 }, {
214 "id" : "eaf78b733390456d80fb24113f5150fd", # (This is an entry for an OLT device) Same as the serial of the OLT logical device as seen in the onos devices command
215 "hardwareIdentifier" : "00:1b:22:00:b1:78", # MAC address to be used for this OLT
216 "ipAddress" : "192.168.1.252", # IP address to be used for this OLT
217 "nasId" : "B100-NASID", # NAS ID to be used for this OLT
218 "circuitId" : "",
219 "remoteId" : ""
220 } ]
221 }
222 }
223 }
224 }
225 cls.onos_load_config(sadis_dict)
226 cls.configs['relay_config'] = sadis_dict
227
228 @classmethod
229 def get_host_ip(cls, port):
230 if cls.host_ip_map.has_key(port):
231 return cls.host_ip_map[port]
232 cls.host_ip_map[port] = '192.168.1.{}'.format(port)
233 return cls.host_ip_map[port]
234
235 @classmethod
236 def host_load(cls, iface):
237 '''Have ONOS discover the hosts for dhcp-relay responses'''
238 port = g_subscriber_port_map[iface]
239 host = '173.17.1.{}'.format(port)
240 cmds = ( 'ifconfig {} 0'.format(iface),
241 'ifconfig {0} {1}'.format(iface, host),
242 'arping -I {0} {1} -c 2'.format(iface, host),
243 'ifconfig {} 0'.format(iface), )
244 for c in cmds:
245 os.system(c)
246
247 @classmethod
248 def dhcpd_conf_generate(cls, config = default_config, options = default_options,
249 subnet = default_subnet_config):
250 conf = ''
251 for k, v in config.items():
252 conf += '{} {};\n'.format(k, v)
253
254 opts = ''
255 for k, v in options:
256 opts += 'option {} {};\n'.format(k, v)
257
258 subnet_config = ''
259 for _, v in subnet:
260 subnet_config += '{}\n'.format(v)
261
262 return '{}{}{}'.format(conf, opts, subnet_config)
263
264 @classmethod
265 def dhcpd_start(cls, intf_list = None,
266 config = default_config, options = default_options,
267 subnet = default_subnet_config):
268 '''Start the dhcpd server by generating the conf file'''
269 if intf_list is None:
270 intf_list = cls.relay_interfaces
271 ##stop dhcpd if already running
272 cls.dhcpd_stop()
273 dhcp_conf = cls.dhcpd_conf_generate(config = config, options = options,
274 subnet = subnet)
275 ##first touch dhcpd.leases if it doesn't exist
276 lease_file = '{}/dhcpd.leases'.format(cls.dhcp_data_dir)
277 if os.access(lease_file, os.F_OK) is False:
278 with open(lease_file, 'w') as fd: pass
279
280 conf_file = '{}/dhcpd.conf'.format(cls.dhcp_data_dir)
281 with open(conf_file, 'w') as fd:
282 fd.write(dhcp_conf)
283
284 #now configure the dhcpd interfaces for various subnets
285 index = 0
286 intf_info = []
287 for ip,_ in subnet:
288 intf = intf_list[index]
289 mac = cls.get_mac(intf)
290 intf_info.append((ip, mac))
291 index += 1
292 os.system('ifconfig {} {}'.format(intf, ip))
293
294 intf_str = ','.join(intf_list)
295 dhcpd_cmd = '/usr/sbin/dhcpd -4 --no-pid -cf {0} -lf {1} {2}'.format(conf_file, lease_file, intf_str)
296 log_test.info('Starting DHCPD server with command: %s' %dhcpd_cmd)
297 ret = os.system(dhcpd_cmd)
298 assert_equal(ret, 0)
299 time.sleep(3)
300 cls.relay_interfaces_last = cls.relay_interfaces
301 cls.relay_interfaces = intf_list
302 cls.cord_l2_relay_load()
303 cls.cord_sadis_load()
304
305 @classmethod
306 def dhcpd_stop(cls):
307 os.system('pkill -9 dhcpd')
308 for intf in cls.relay_interfaces:
309 os.system('ifconfig {} 0'.format(intf))
310
311 cls.relay_interfaces = cls.relay_interfaces_last
312
313 @classmethod
314 def get_mac(cls, iface):
315 if cls.interface_to_mac_map.has_key(iface):
316 return cls.interface_to_mac_map[iface]
317 mac = get_mac(iface, pad = 0)
318 cls.interface_to_mac_map[iface] = mac
319 return mac
320
321 def stats(self,success_rate = False, only_discover = False, iface = 'veth0'):
322
323 self.ip_count = 0
324 self.failure_count = 0
325 self.start_time = 0
326 self.diff = 0
327 self.transaction_count = 0
328
329 mac = self.get_mac(iface)
330 self.host_load(iface)
331 ##we use the defaults for this test that serves as an example for others
332 ##You don't need to restart dhcpd server if retaining default config
333 config = self.default_config
334 options = self.default_options
335 subnet = self.default_subnet_config
336 dhcpd_interface_list = self.relay_interfaces
337 self.dhcpd_start(intf_list = dhcpd_interface_list,
338 config = config,
339 options = options,
340 subnet = subnet)
341 self.dhcp = DHCPTest(seed_ip = '182.17.0.1', iface = iface)
342 self.start_time = time.time()
343
344 while self.diff <= 60:
345
346 if only_discover:
347 cip, sip, mac, _ = self.dhcp.only_discover(multiple = True)
348 log_test.info('Got dhcp client IP %s from server %s for mac %s' %
349 (cip, sip, mac))
350 else:
351 cip, sip = self.send_recv(mac=mac, update_seed = True, validate = False)
352
353 if cip:
354 self.ip_count +=1
355 elif cip == None:
356 self.failure_count += 1
357 log_test.info('Failed to get ip')
358 if success_rate and self.ip_count > 0:
359 break
360
361 self.diff = round(time.time() - self.start_time, 0)
362
363 self.transaction_count = round((self.ip_count+self.failure_count)/self.diff, 2)
364 self.transactions += (self.ip_count+self.failure_count)
365 self.running_time += self.diff
366 self.total_success += self.ip_count
367 self.total_failure += self.failure_count
368
369 def send_recv(self, mac=None, update_seed = False, validate = True):
370 cip, sip = self.dhcp.discover(mac = mac, update_seed = update_seed)
371 if validate:
372 assert_not_equal(cip, None)
373 assert_not_equal(sip, None)
374 log_test.info('Got dhcp client IP %s from server %s for mac %s' %
375 (cip, sip, self.dhcp.get_mac(cip)[0]))
376 return cip,sip
377
378 def test_dhcpl2relay_with_one_request(self, iface = 'veth0'):
379 mac = self.get_mac(iface)
380 self.host_load(iface)
381 ##we use the defaults for this test that serves as an example for others
382 ##You don't need to restart dhcpd server if retaining default config
383 config = self.default_config
384 options = self.default_options
385 subnet = self.default_subnet_config
386 dhcpd_interface_list = self.relay_interfaces
387 self.dhcpd_start(intf_list = dhcpd_interface_list,
388 config = config,
389 options = options,
390 subnet = subnet)
391 self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
392 self.send_recv(mac=mac)
393
394 def test_dhcpl2relay_for_one_request_with_invalid_source_mac_broadcast(self, iface = 'veth0'):
395 mac = self.get_mac(iface)
396 self.host_load(iface)
397 ##we use the defaults for this test that serves as an example for others
398 ##You don't need to restart dhcpd server if retaining default config
399 config = self.default_config
400 options = self.default_options
401 subnet = self.default_subnet_config
402 dhcpd_interface_list = self.relay_interfaces
403 self.dhcpd_start(intf_list = dhcpd_interface_list,
404 config = config,
405 options = options,
406 subnet = subnet)
407 self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
408 cip, sip, mac, _ = self.dhcp.only_discover(mac='ff:ff:ff:ff:ff:ff')
409 assert_equal(cip,None)
410 log_test.info('dhcp server rejected client discover with invalid source mac, as expected')
411
412 def test_dhcpl2relay_for_one_request_with_invalid_source_mac_multicast(self, iface = 'veth0'):
413 mac = self.get_mac(iface)
414 self.host_load(iface)
415 ##we use the defaults for this test that serves as an example for others
416 ##You don't need to restart dhcpd server if retaining default config
417 config = self.default_config
418 options = self.default_options
419 subnet = self.default_subnet_config
420 dhcpd_interface_list = self.relay_interfaces
421 self.dhcpd_start(intf_list = dhcpd_interface_list,
422 config = config,
423 options = options,
424 subnet = subnet)
425 self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
426 cip, sip, mac, _ = self.dhcp.only_discover(mac='01:80:c2:01:98:05')
427 assert_equal(cip,None)
428 log_test.info('dhcp server rejected client discover with invalid source mac, as expected')
429
430 def test_dhcpl2relay_for_one_request_with_invalid_source_mac_zero(self, iface = 'veth0'):
431 mac = self.get_mac(iface)
432 self.host_load(iface)
433 ##we use the defaults for this test that serves as an example for others
434 ##You don't need to restart dhcpd server if retaining default config
435 config = self.default_config
436 options = self.default_options
437 subnet = self.default_subnet_config
438 dhcpd_interface_list = self.relay_interfaces
439 self.dhcpd_start(intf_list = dhcpd_interface_list,
440 config = config,
441 options = options,
442 subnet = subnet)
443 self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
444 cip, sip, mac, _ = self.dhcp.only_discover(mac='00:00:00:00:00:00')
445 assert_equal(cip,None)
446 log_test.info('dhcp server rejected client discover with invalid source mac, as expected')
447
448 def test_dhcpl2relay_with_N_requests(self, iface = 'veth0',requests=10):
449 mac = self.get_mac(iface)
450 self.host_load(iface)
451 ##we use the defaults for this test that serves as an example for others
452 ##You don't need to restart dhcpd server if retaining default config
453 config = self.default_config
454 options = self.default_options
455 subnet = self.default_subnet_config
456 dhcpd_interface_list = self.relay_interfaces
457 self.dhcpd_start(intf_list = dhcpd_interface_list,
458 config = config,
459 options = options,
460 subnet = subnet)
461 self.dhcp = DHCPTest(seed_ip = '192.169.1.1', iface = iface)
462 ip_map = {}
463 for i in range(requests):
464 #mac = RandMAC()._fix()
465 #log_test.info('mac is %s'%mac)
466 cip, sip = self.send_recv(update_seed = True)
467 if ip_map.has_key(cip):
468 log_test.info('IP %s given out multiple times' %cip)
469 assert_equal(False, ip_map.has_key(cip))
470 ip_map[cip] = sip
471 time.sleep(1)
472
473 def test_dhcpl2relay_with_one_release(self, iface = 'veth0'):
474 mac = self.get_mac(iface)
475 self.host_load(iface)
476 ##we use the defaults for this test that serves as an example for others
477 ##You don't need to restart dhcpd server if retaining default config
478 config = self.default_config
479 options = self.default_options
480 subnet = self.default_subnet_config
481 dhcpd_interface_list = self.relay_interfaces
482 self.dhcpd_start(intf_list = dhcpd_interface_list,
483 config = config,
484 options = options,
485 subnet = subnet)
486 self.dhcp = DHCPTest(seed_ip = '10.10.100.10', iface = iface)
487 cip, sip = self.send_recv(mac=mac)
488 log_test.info('Releasing ip %s to server %s' %(cip, sip))
489 assert_equal(self.dhcp.release(cip), True)
490 log_test.info('Triggering DHCP discover again after release')
491 cip2, sip2 = self.send_recv(mac=mac)
492 log_test.info('Verifying released IP was given back on rediscover')
493 assert_equal(cip, cip2)
494 log_test.info('Test done. Releasing ip %s to server %s' %(cip2, sip2))
495 assert_equal(self.dhcp.release(cip2), True)
496
497 def test_dhcpl2relay_with_Nreleases(self, iface = 'veth0'):
498 mac = None
499 self.host_load(iface)
500 ##we use the defaults for this test that serves as an example for others
501 ##You don't need to restart dhcpd server if retaining default config
502 config = self.default_config
503 options = self.default_options
504 subnet = self.default_subnet_config
505 dhcpd_interface_list = self.relay_interfaces
506 self.dhcpd_start(intf_list = dhcpd_interface_list,
507 config = config,
508 options = options,
509 subnet = subnet)
510 self.dhcp = DHCPTest(seed_ip = '192.170.1.10', iface = iface)
511 ip_map = {}
512 for i in range(10):
513 cip, sip = self.send_recv(mac=mac, update_seed = True)
514 if ip_map.has_key(cip):
515 log_test.info('IP %s given out multiple times' %cip)
516 assert_equal(False, ip_map.has_key(cip))
517 ip_map[cip] = sip
518
519 for ip in ip_map.keys():
520 log_test.info('Releasing IP %s' %ip)
521 assert_equal(self.dhcp.release(ip), True)
522
523 ip_map2 = {}
524 log_test.info('Triggering DHCP discover again after release')
525 self.dhcp = DHCPTest(seed_ip = '192.170.1.10', iface = iface)
526 for i in range(len(ip_map.keys())):
527 cip, sip = self.send_recv(mac=mac, update_seed = True)
528 ip_map2[cip] = sip
529
530 log_test.info('Verifying released IPs were given back on rediscover')
531 if ip_map != ip_map2:
532 log_test.info('Map before release %s' %ip_map)
533 log_test.info('Map after release %s' %ip_map2)
534 assert_equal(ip_map, ip_map2)
535
536 def test_dhcpl2relay_starvation(self, iface = 'veth0'):
537 mac = self.get_mac(iface)
538 self.host_load(iface)
539 ##we use the defaults for this test that serves as an example for others
540 ##You don't need to restart dhcpd server if retaining default config
541 config = self.default_config
542 options = self.default_options
543 subnet = self.default_subnet_config
544 dhcpd_interface_list = self.relay_interfaces
545 self.dhcpd_start(intf_list = dhcpd_interface_list,
546 config = config,
547 options = options,
548 subnet = subnet)
549 self.dhcp = DHCPTest(seed_ip = '182.17.0.1', iface = iface)
550 log_test.info('Verifying 1 ')
551 count = 0
552 while True:
553 #mac = RandMAC()._fix()
554 cip, sip = self.send_recv(update_seed = True,validate = False)
555 if cip is None:
556 break
557 else:
558 count += 1
559 assert_equal(count,91)
560 log_test.info('Verifying 2 ')
561 cip, sip = self.send_recv(mac=mac, update_seed = True, validate = False)
562 assert_equal(cip, None)
563 assert_equal(sip, None)
564
565 def test_dhcpl2relay_with_same_client_and_multiple_discovers(self, iface = 'veth0'):
566 mac = self.get_mac(iface)
567 self.host_load(iface)
568 ##we use the defaults for this test that serves as an example for others
569 ##You don't need to restart dhcpd server if retaining default config
570 config = self.default_config
571 options = self.default_options
572 subnet = self.default_subnet_config
573 dhcpd_interface_list = self.relay_interfaces
574 self.dhcpd_start(intf_list = dhcpd_interface_list,
575 config = config,
576 options = options,
577 subnet = subnet)
578 self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
579 cip, sip, mac, _ = self.dhcp.only_discover()
580 log_test.info('Got dhcp client IP %s from server %s for mac %s . Not going to send DHCPREQUEST.' %
581 (cip, sip, mac) )
582 assert_not_equal(cip, None)
583 log_test.info('Triggering DHCP discover again.')
584 new_cip, new_sip, new_mac, _ = self.dhcp.only_discover()
585 assert_equal(new_cip, cip)
586 log_test.info('got same ip to smae the client when sent discover again, as expected')
587
588 def test_dhcpl2relay_with_same_client_and_multiple_requests(self, iface = 'veth0'):
589 mac = self.get_mac(iface)
590 self.host_load(iface)
591 ##we use the defaults for this test that serves as an example for others
592 ##You don't need to restart dhcpd server if retaining default config
593 config = self.default_config
594 options = self.default_options
595 subnet = self.default_subnet_config
596 dhcpd_interface_list = self.relay_interfaces
597 self.dhcpd_start(intf_list = dhcpd_interface_list,
598 config = config,
599 options = options,
600 subnet = subnet)
601 self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
602 log_test.info('Sending DHCP discover and DHCP request.')
603 cip, sip = self.send_recv(mac=mac)
604 mac = self.dhcp.get_mac(cip)[0]
605 log_test.info("Sending DHCP request again.")
606 new_cip, new_sip = self.dhcp.only_request(cip, mac)
607 assert_equal(new_cip, cip)
608 log_test.info('got same ip to smae the client when sent request again, as expected')
609
610 def test_dhcpl2relay_with_clients_desired_address(self, iface = 'veth0'):
611 mac = self.get_mac(iface)
612 self.host_load(iface)
613 ##we use the defaults for this test that serves as an example for others
614 ##You don't need to restart dhcpd server if retaining default config
615 config = self.default_config
616 options = self.default_options
617 subnet = self.default_subnet_config
618 dhcpd_interface_list = self.relay_interfaces
619 self.dhcpd_start(intf_list = dhcpd_interface_list,
620 config = config,
621 options = options,
622 subnet = subnet)
623 self.dhcp = DHCPTest(seed_ip = '192.168.1.31', iface = iface)
624 cip, sip, mac, _ = self.dhcp.only_discover(desired = True)
625 assert_equal(cip,self.dhcp.seed_ip)
626 log_test.info('Got dhcp client desired IP %s from server %s for mac %s as expected' %
627 (cip, sip, mac) )
628
629 def test_dhcpl2relay_with_clients_desired_address_in_out_of_pool(self, iface = 'veth0'):
630 mac = self.get_mac(iface)
631
632 self.host_load(iface)
633 ##we use the defaults for this test that serves as an example for others
634 ##You don't need to restart dhcpd server if retaining default config
635 config = self.default_config
636 options = self.default_options
637 subnet = self.default_subnet_config
638 dhcpd_interface_list = self.relay_interfaces
639 self.dhcpd_start(intf_list = dhcpd_interface_list,
640 config = config,
641 options = options,
642 subnet = subnet)
643 self.dhcp = DHCPTest(seed_ip = '20.20.20.35', iface = iface)
644 cip, sip, mac, _ = self.dhcp.only_discover(desired = True)
645 assert_not_equal(cip,None)
646 assert_not_equal(cip,self.dhcp.seed_ip)
647 log_test.info('server offered IP from its pool when requested out of pool IP, as expected')
648
649 def test_dhcpl2relay_nak_packet(self, iface = 'veth0'):
650 mac = self.get_mac(iface)
651 self.host_load(iface)
652 ##we use the defaults for this test that serves as an example for others
653 ##You don't need to restart dhcpd server if retaining default config
654 config = self.default_config
655 options = self.default_options
656 subnet = self.default_subnet_config
657 dhcpd_interface_list = self.relay_interfaces
658 self.dhcpd_start(intf_list = dhcpd_interface_list,
659 config = config,
660 options = options,
661 subnet = subnet)
662 self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
663 cip, sip, mac, _ = self.dhcp.only_discover()
664 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
665 (cip, sip, mac) )
666 assert_not_equal(cip, None)
667 new_cip, new_sip = self.dhcp.only_request('20.20.20.31', mac)
668 assert_equal(new_cip, None)
669 log_test.info('server sent NAK packet when requested other IP than that server offered')
670
671 def test_dhcpl2relay_client_requests_with_specific_lease_time_in_discover_message(self, iface = 'veth0',lease_time=700):
672 mac = self.get_mac(iface)
673 self.host_load(iface)
674 ##we use the defaults for this test that serves as an example for others
675 ##You don't need to restart dhcpd server if retaining default config
676 config = self.default_config
677 options = self.default_options
678 subnet = self.default_subnet_config
679 dhcpd_interface_list = self.relay_interfaces
680 self.dhcpd_start(intf_list = dhcpd_interface_list,
681 config = config,
682 options = options,
683 subnet = subnet)
684 self.dhcp = DHCPTest(seed_ip = '10.10.10.70', iface = iface)
685 self.dhcp.return_option = 'lease'
686 cip, sip, mac, lval = self.dhcp.only_discover(lease_time=True,lease_value=lease_time)
687 assert_equal(lval, lease_time)
688 log_test.info('dhcp server offered IP address with client requested lease time')
689
690 def test_dhcpl2relay_client_request_after_reboot(self, iface = 'veth0'):
691 mac = self.get_mac(iface)
692 self.host_load(iface)
693 ##we use the defaults for this test that serves as an example for others
694 ##You don't need to restart dhcpd server if retaining default config
695 config = self.default_config
696 options = self.default_options
697 subnet = self.default_subnet_config
698 dhcpd_interface_list = self.relay_interfaces
699 self.dhcpd_start(intf_list = dhcpd_interface_list,
700 config = config,
701 options = options,
702 subnet = subnet)
703 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
704 cip, sip, mac, _ = self.dhcp.only_discover()
705 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
706 (cip, sip, mac) )
707 assert_not_equal(cip, None)
708 new_cip, new_sip = self.dhcp.only_request(cip, mac)
709 log_test.info('client rebooting...')
710 os.system('ifconfig '+iface+' down')
711 time.sleep(5)
712 os.system('ifconfig '+iface+' up')
713 new_cip2, new_sip = self.dhcp.only_request(cip, mac, cl_reboot = True)
714 assert_equal(new_cip2, cip)
715 log_test.info('client got same IP after reboot, as expected')
716
717
718 def test_dhcpl2relay_after_server_reboot(self, iface = 'veth0'):
719 mac = self.get_mac(iface)
720 self.host_load(iface)
721 ##we use the defaults for this test that serves as an example for others
722 ##You don't need to restart dhcpd server if retaining default config
723 config = self.default_config
724 options = self.default_options
725 subnet = self.default_subnet_config
726 dhcpd_interface_list = self.relay_interfaces
727 self.dhcpd_start(intf_list = dhcpd_interface_list,
728 config = config,
729 options = options,
730 subnet = subnet)
731 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
732 cip, sip, mac, _ = self.dhcp.only_discover()
733 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
734 (cip, sip, mac) )
735 assert_not_equal(cip, None)
736 new_cip, new_sip = self.dhcp.only_request(cip, mac)
737 log_test.info('server rebooting...')
738 self.tearDownClass()
739 new_cip, new_sip = self.dhcp.only_request(cip, mac)
740 assert_equal(new_cip,None)
741 self.setUpClass()
742 new_cip, new_sip = self.dhcp.only_request(cip, mac)
743 assert_equal(new_cip, cip)
744 log_test.info('client got same IP after server rebooted, as expected')
745
746 def test_dhcpl2relay_specific_lease_time_only_in_discover_but_not_in_request_packet(self, iface = 'veth0',lease_time=700):
747 mac = self.get_mac(iface)
748 self.host_load(iface)
749 ##we use the defaults for this test that serves as an example for others
750 ##You don't need to restart dhcpd server if retaining default config
751 config = self.default_config
752 options = self.default_options
753 subnet = self.default_subnet_config
754 dhcpd_interface_list = self.relay_interfaces
755 self.dhcpd_start(intf_list = dhcpd_interface_list,
756 config = config,
757 options = options,
758 subnet = subnet)
759 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
760 self.dhcp.return_option = 'lease'
761 log_test.info('Sending DHCP discover with lease time of 700')
762 cip, sip, mac, lval = self.dhcp.only_discover(lease_time = True, lease_value=lease_time)
763 assert_equal(lval,lease_time)
764 new_cip, new_sip, lval = self.dhcp.only_request(cip, mac, lease_time = True)
765 assert_equal(new_cip,cip)
766 assert_not_equal(lval, lease_time) #Negative Test Case
767 log_test.info('client requested lease time in discover packer is not seen in server ACK packet as expected')
768
769 def test_dhcpl2relay_specific_lease_time_only_in_request_but_not_in_discover_packet(self, iface = 'veth0',lease_time=800):
770 mac = self.get_mac(iface)
771 self.host_load(iface)
772 ##we use the defaults for this test that serves as an example for others
773 ##You don't need to restart dhcpd server if retaining default config
774 config = self.default_config
775 options = self.default_options
776 subnet = self.default_subnet_config
777 dhcpd_interface_list = self.relay_interfaces
778 self.dhcpd_start(intf_list = dhcpd_interface_list,
779 config = config,
780 options = options,
781 subnet = subnet)
782 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
783 cip, sip, mac, _ = self.dhcp.only_discover()
784 new_cip, new_sip, lval = self.dhcp.only_request(cip, mac, lease_time = True,lease_value=lease_time)
785 assert_equal(new_cip,cip)
786 assert_equal(lval, lease_time)
787 log_test.info('client requested lease time in request packet seen in servre replied ACK packet as expected')
788
789 def test_dhcpl2relay_client_renew_time(self, iface = 'veth0'):
790 mac = self.get_mac(iface)
791 self.host_load(iface)
792 ##we use the defaults for this test that serves as an example for others
793 ##You don't need to restart dhcpd server if retaining default config
794 config = self.default_config
795 new_options = [('dhcp-renewal-time', 100), ('dhcp-rebinding-time', 125)]
796 options = self.default_options + new_options
797 subnet = self.default_subnet_config
798 dhcpd_interface_list = self.relay_interfaces
799 self.dhcpd_start(intf_list = dhcpd_interface_list,
800 config = config,
801 options = options,
802 subnet = subnet)
803 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
804 cip, sip, mac, _ = self.dhcp.only_discover()
805 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
806 (cip, sip, mac) )
807 assert_not_equal(cip,None)
808 new_cip, new_sip, lval = self.dhcp.only_request(cip, mac, renew_time = True)
809 log_test.info('waiting for renew time..')
810 time.sleep(lval)
811 latest_cip, latest_sip = self.dhcp.only_request(new_cip, mac, unicast = True)
812 assert_equal(latest_cip, cip)
813 log_test.info('server renewed client IP when client sends request after renew time, as expected')
814
815 def test_dhcpl2relay_client_rebind_time(self, iface = 'veth0'):
816 mac = self.get_mac(iface)
817 self.host_load(iface)
818 ##we use the defaults for this test that serves as an example for others
819 ##You don't need to restart dhcpd server if retaining default config
820 config = self.default_config
821 new_options = [('dhcp-renewal-time', 100), ('dhcp-rebinding-time', 125)]
822 options = self.default_options + new_options
823 subnet = self.default_subnet_config
824 dhcpd_interface_list = self.relay_interfaces
825 self.dhcpd_start(intf_list = dhcpd_interface_list,
826 config = config,
827 options = options,
828 subnet = subnet)
829 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
830 cip, sip, mac, _ = self.dhcp.only_discover()
831 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
832 (cip, sip, mac) )
833 assert_not_equal(cip,None)
834 new_cip, new_sip, lval = self.dhcp.only_request(cip, mac, rebind_time = True)
835 log_test.info('waiting for rebind time..')
836 time.sleep(lval)
837 latest_cip, latest_sip = self.dhcp.only_request(new_cip, mac)
838 assert_equal(latest_cip, cip)
839 log_test.info('server renewed client IP when client sends request after rebind time, as expected')
840
841 def test_dhcpl2relay_client_expected_subnet_mask(self, iface = 'veth0'):
842 mac = self.get_mac(iface)
843 self.host_load(iface)
844 ##we use the defaults for this test that serves as an example for others
845 ##You don't need to restart dhcpd server if retaining default config
846 config = self.default_config
847 options = self.default_options
848 subnet = self.default_subnet_config
849 dhcpd_interface_list = self.relay_interfaces
850 self.dhcpd_start(intf_list = dhcpd_interface_list,
851 config = config,
852 options = options,
853 subnet = subnet)
854 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
855 expected_subnet = '255.255.255.0'
856 self.dhcp.return_option = 'subnet'
857
858 cip, sip, mac, subnet_mask = self.dhcp.only_discover()
859 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
860 (cip, sip, mac) )
861 assert_equal(subnet_mask,expected_subnet)
862 log_test.info('subnet mask in server offer packet is same as configured subnet mask in dhcp server')
863
864 def test_dhcpl2relay_client_sends_dhcp_request_with_wrong_subnet_mask(self, iface = 'veth0'):
865 mac = self.get_mac(iface)
866 self.host_load(iface)
867 ##we use the defaults for this test that serves as an example for others
868 ##You don't need to restart dhcpd server if retaining default config
869 config = self.default_config
870 options = self.default_options
871 subnet = self.default_subnet_config
872 dhcpd_interface_list = self.relay_interfaces
873 self.dhcpd_start(intf_list = dhcpd_interface_list,
874 config = config,
875 options = options,
876 subnet = subnet)
877 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
878
879 cip, sip, mac, _ = self.dhcp.only_discover()
880 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
881 (cip, sip, mac) )
882 assert_not_equal(cip,None)
883 self.dhcp.send_different_option = 'subnet'
884 new_cip, new_sip = self.dhcp.only_request(cip, mac)
885 assert_equal(new_cip, cip)
886 log_test.info("Got DHCP Ack despite of specifying wrong Subnet Mask in DHCP Request.")
887
888 def test_dhcpl2relay_client_expected_router_address(self, iface = 'veth0'):
889 mac = self.get_mac(iface)
890 self.host_load(iface)
891 ##we use the defaults for this test that serves as an example for others
892 ##You don't need to restart dhcpd server if retaining default config
893 config = self.default_config
894 config = self.default_config
895 new_options = [('routers', '20.20.20.1')]
896 options = self.default_options + new_options
897 subnet = self.default_subnet_config
898 dhcpd_interface_list = self.relay_interfaces
899 self.dhcpd_start(intf_list = dhcpd_interface_list,
900 config = config,
901 options = options,
902 subnet = subnet)
903 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
904 expected_router_address = '20.20.20.1'
905 self.dhcp.return_option = 'router'
906
907 cip, sip, mac, router_address_value = self.dhcp.only_discover()
908 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
909 (cip, sip, mac) )
910 assert_equal(expected_router_address, router_address_value)
911 log_test.info('router address in server offer packet is same as configured router address in dhcp server')
912
913 def test_dhcpl2relay_client_sends_dhcp_request_with_wrong_router_address(self, iface = 'veth0'):
914 mac = self.get_mac(iface)
915 self.host_load(iface)
916 ##we use the defaults for this test that serves as an example for others
917 ##You don't need to restart dhcpd server if retaining default config
918 config = self.default_config
919 options = self.default_options
920 subnet = self.default_subnet_config
921 dhcpd_interface_list = self.relay_interfaces
922 self.dhcpd_start(intf_list = dhcpd_interface_list,
923 config = config,
924 options = options,
925 subnet = subnet)
926 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
927
928 cip, sip, mac, _ = self.dhcp.only_discover()
929 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
930 (cip, sip, mac) )
931 assert_not_equal(cip,None)
932 self.dhcp.send_different_option = 'router'
933 new_cip, new_sip = self.dhcp.only_request(cip, mac)
934 assert_equal(new_cip, cip)
935 log_test.info("Got DHCP Ack despite of specifying wrong Router Address in DHCP Request.")
936
937 def test_dhcpl2relay_with_client_expecting_broadcast_address(self, iface = 'veth0'):
938 mac = self.get_mac(iface)
939 self.host_load(iface)
940 ##we use the defaults for this test that serves as an example for others
941 ##You don't need to restart dhcpd server if retaining default config
942 config = self.default_config
943 options = self.default_options
944 subnet = self.default_subnet_config
945 dhcpd_interface_list = self.relay_interfaces
946 self.dhcpd_start(intf_list = dhcpd_interface_list,
947 config = config,
948 options = options,
949 subnet = subnet)
950 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
951 expected_broadcast_address = '192.168.1.255'
952 self.dhcp.return_option = 'broadcast_address'
953
954 cip, sip, mac, broadcast_address_value = self.dhcp.only_discover()
955 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
956 (cip, sip, mac) )
957 assert_equal(expected_broadcast_address, broadcast_address_value)
958 log_test.info('broadcast address in server offer packet is same as configured broadcast address in dhcp server')
959
960 def test_dhcpl2relay_client_sends_dhcp_request_with_wrong_broadcast_address(self, iface = 'veth0'):
961 mac = self.get_mac(iface)
962 self.host_load(iface)
963 ##we use the defaults for this test that serves as an example for others
964 ##You don't need to restart dhcpd server if retaining default config
965 config = self.default_config
966 options = self.default_options
967 subnet = self.default_subnet_config
968 dhcpd_interface_list = self.relay_interfaces
969 self.dhcpd_start(intf_list = dhcpd_interface_list,
970 config = config,
971 options = options,
972 subnet = subnet)
973 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
974
975 cip, sip, mac, _ = self.dhcp.only_discover()
976 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
977 (cip, sip, mac) )
978 assert_not_equal(cip,None)
979 self.dhcp.send_different_option = 'broadcast_address'
980 new_cip, new_sip = self.dhcp.only_request(cip, mac)
981 assert_equal(new_cip, cip)
982 log_test.info("Got DHCP Ack despite of specifying wrong Broadcast Address in DHCP Request.")
983
984 def test_dhcpl2relay_client_expecting_dns_address(self, iface = 'veth0'):
985 mac = self.get_mac(iface)
986 self.host_load(iface)
987 ##we use the defaults for this test that serves as an example for others
988 ##You don't need to restart dhcpd server if retaining default config
989 config = self.default_config
990 options = self.default_options
991 subnet = self.default_subnet_config
992 dhcpd_interface_list = self.relay_interfaces
993 self.dhcpd_start(intf_list = dhcpd_interface_list,
994 config = config,
995 options = options,
996 subnet = subnet)
997 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
998 expected_dns_address = '192.168.1.1'
999 self.dhcp.return_option = 'dns'
1000
1001 cip, sip, mac, dns_address_value = self.dhcp.only_discover()
1002 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
1003 (cip, sip, mac) )
1004 assert_equal(expected_dns_address, dns_address_value)
1005 log_test.info('dns address in server offer packet is same as configured dns address in dhcp server')
1006
1007 def test_dhcpl2relay_client_sends_request_with_wrong_dns_address(self, iface = 'veth0'):
1008 mac = self.get_mac(iface)
1009 self.host_load(iface)
1010 ##we use the defaults for this test that serves as an example for others
1011 ##You don't need to restart dhcpd server if retaining default config
1012 config = self.default_config
1013 options = self.default_options
1014 subnet = self.default_subnet_config
1015 dhcpd_interface_list = self.relay_interfaces
1016 self.dhcpd_start(intf_list = dhcpd_interface_list,
1017 config = config,
1018 options = options,
1019 subnet = subnet)
1020 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
1021
1022 cip, sip, mac, _ = self.dhcp.only_discover()
1023 log_test.info('Got dhcp client IP %s from server %s for mac %s .' %
1024 (cip, sip, mac) )
1025 assert_not_equal(cip,None)
1026 self.dhcp.send_different_option = 'dns'
1027 new_cip, new_sip = self.dhcp.only_request(cip, mac)
1028 assert_equal(new_cip, cip)
1029 log_test.info("Got DHCP Ack despite of specifying wrong DNS Address in DHCP Request.")
1030
1031
1032 def test_dhcpl2relay_transactions_per_second(self, iface = 'veth0'):
1033
1034 for i in range(1,4):
1035 self.stats()
1036 log_test.info("Statistics for run %d",i)
1037 log_test.info("----------------------------------------------------------------------------------")
1038 log_test.info("No. of transactions No. of successes No. of failures Running Time ")
1039 log_test.info(" %d %d %d %d" %(self.ip_count+self.failure_count, self.ip_count, self.failure_count, self.diff))
1040 log_test.info("----------------------------------------------------------------------------------")
1041 log_test.info("No. of transactions per second in run %d:%f" %(i, self.transaction_count))
1042
1043 log_test.info("Final Statistics for total transactions")
1044 log_test.info("----------------------------------------------------------------------------------")
1045 log_test.info("Total transactions Total No. of successes Total No. of failures Running Time ")
1046 log_test.info(" %d %d %d %d" %(self.transactions,
1047 self.total_success, self.total_failure, self.running_time))
1048 log_test.info("----------------------------------------------------------------------------------")
1049 log_test.info("Average no. of transactions per second: %d", round(self.transactions/self.running_time,0))
1050
1051 def test_dhcpl2relay_consecutive_successes_per_second(self, iface = 'veth0'):
1052
1053 for i in range(1,4):
1054 self.stats(success_rate = True)
1055 log_test.info("Statistics for run %d",i)
1056 log_test.info("----------------------------------------------------------------------------------")
1057 log_test.info("No. of consecutive successful transactions Running Time ")
1058 log_test.info(" %d %d " %(self.ip_count, self.diff))
1059 log_test.info("----------------------------------------------------------------------------------")
1060 log_test.info("No. of successful transactions per second in run %d:%f" %(i, self.transaction_count))
1061 log_test.info("----------------------------------------------------------------------------------")
1062
1063 log_test.info("Final Statistics for total successful transactions")
1064 log_test.info("----------------------------------------------------------------------------------")
1065 log_test.info("Total transactions Total No. of consecutive successes Running Time ")
1066 log_test.info(" %d %d %d " %(self.transactions,
1067 self.total_success, self.running_time))
1068 log_test.info("----------------------------------------------------------------------------------")
1069 log_test.info("Average no. of consecutive successful transactions per second: %d", round(self.total_success/self.running_time,0))
1070 log_test.info("----------------------------------------------------------------------------------")
1071
1072 def test_dhcpl2relay_with_max_clients_per_second(self, iface = 'veth0'):
1073
1074 for i in range(1,4):
1075 self.stats(only_discover = True)
1076 log_test.info("----------------------------------------------------------------------------------")
1077 log_test.info("Statistics for run %d of sending only DHCP Discover",i)
1078 log_test.info("----------------------------------------------------------------------------------")
1079 log_test.info("No. of transactions No. of successes No. of failures Running Time ")
1080 log_test.info(" %d %d %d %d" %(self.ip_count+self.failure_count, self.ip_count, self.failure_count, self.diff))
1081 log_test.info("----------------------------------------------------------------------------------")
1082 log_test.info("No. of clients per second in run %d:%f "
1083 %(i, self.transaction_count))
1084 log_test.info("----------------------------------------------------------------------------------")
1085 log_test.info("Final Statistics for total transactions of sending only DHCP Discover")
1086 log_test.info("----------------------------------------------------------------------------------")
1087 log_test.info("Total transactions Total No. of successes Total No. of failures Running Time ")
1088 log_test.info(" %d %d %d %d" %(self.transactions,
1089 self.total_success, self.total_failure, self.running_time))
1090 log_test.info("----------------------------------------------------------------------------------")
1091 log_test.info("Average no. of clients per second: %d ",
1092 round(self.transactions/self.running_time,0))
1093 log_test.info("----------------------------------------------------------------------------------")
1094
1095 def test_dhcpl2relay_consecutive_successful_clients_per_second(self, iface = 'veth0'):
1096
1097 for i in range(1,4):
1098 self.stats(success_rate = True, only_discover = True)
1099 log_test.info("----------------------------------------------------------------------------------")
1100 log_test.info("Statistics for run %d for sending only DHCP Discover",i)
1101 log_test.info("----------------------------------------------------------------------------------")
1102 log_test.info("No. of consecutive successful transactions Running Time ")
1103 log_test.info(" %d %d " %(self.ip_count, self.diff))
1104 log_test.info("----------------------------------------------------------------------------------")
1105 log_test.info("No. of consecutive successful clients per second in run %d:%f" %(i, self.transaction_count))
1106 log_test.info("----------------------------------------------------------------------------------")
1107
1108 log_test.info("Final Statistics for total successful transactions")
1109 log_test.info("----------------------------------------------------------------------------------")
1110 log_test.info("Total transactions Total No. of consecutive successes Running Time ")
1111 log_test.info(" %d %d %d " %(self.transactions,
1112 self.total_success, self.running_time))
1113 log_test.info("----------------------------------------------------------------------------------")
1114 log_test.info("Average no. of consecutive successful clients per second: %d", round(self.total_success/self.running_time,0))
1115 log_test.info("----------------------------------------------------------------------------------")
1116
1117 def test_dhcpl2relay_concurrent_transactions_per_second(self, iface = 'veth0'):
1118
1119 config = self.default_config
1120 options = self.default_options
1121 subnet = [ ('192.168.1.2',
1122'''
1123subnet 192.168.0.0 netmask 255.255.0.0 {
1124 range 192.168.1.10 192.168.2.100;
1125}
1126'''), ]
1127
1128 dhcpd_interface_list = self.relay_interfaces
1129 self.dhcpd_start(intf_list = dhcpd_interface_list,
1130 config = config,
1131 options = options,
1132 subnet = subnet)
1133
1134 for key in (key for key in g_subscriber_port_map if key < 100):
1135 self.host_load(g_subscriber_port_map[key])
1136
1137 def thread_fun(i):
1138 mac = self.get_mac('veth{}'.format(i))
1139 cip, sip = DHCPTest(iface = 'veth{}'.format(i)).discover(mac = mac)
1140 log_test.info('Got dhcp client IP %s from server %s for mac %s'%(cip, sip, mac))
1141 self.lock.acquire()
1142
1143 if cip:
1144 self.ip_count += 1
1145
1146 elif cip is None:
1147 self.failure_count += 1
1148
1149 self.lock.notify_all()
1150 self.lock.release()
1151
1152 for i in range (1,4):
1153 self.ip_count = 0
1154 self.failure_count = 0
1155 self.start_time = 0
1156 self.diff = 0
1157 self.transaction_count = 0
1158 self.start_time = time.time()
1159
1160 while self.diff <= 60:
1161 t = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(0, random.randrange(1,40,1), 1)})
1162 t1 = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(42, random.randrange(43,80,1), 1)})
1163 t2 = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(82, random.randrange(83,120,1), 1)})
1164 t3 = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(122, random.randrange(123,160,1), 1)})
1165 t4 = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(162, random.randrange(163,180,1), 1)})
1166 t5 = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(182, random.randrange(183,196,1), 1)})
1167
1168 t.start()
1169 t1.start()
1170 t2.start()
1171 t3.start()
1172 t4.start()
1173 t5.start()
1174
1175 t.join()
1176 t1.join()
1177 t2.join()
1178 t3.join()
1179 t4.join()
1180 t5.join()
1181
1182 self.diff = round(time.time() - self.start_time, 0)
1183
1184 self.transaction_count = round((self.ip_count+self.failure_count)/self.diff, 2)
1185
1186 self.transactions += (self.ip_count+self.failure_count)
1187 self.running_time += self.diff
1188 self.total_success += self.ip_count
1189 self.total_failure += self.failure_count
1190
1191
1192 log_test.info("----------------------------------------------------------------------------------")
1193 log_test.info("Statistics for run %d",i)
1194 log_test.info("----------------------------------------------------------------------------------")
1195 log_test.info("No. of transactions No. of successes No. of failures Running Time ")
1196 log_test.info(" %d %d %d %d"
1197 %(self.ip_count+self.failure_count,self.ip_count, self.failure_count, self.diff))
1198 log_test.info("----------------------------------------------------------------------------------")
1199 log_test.info("No. of transactions per second in run %d:%f" %(i, self.transaction_count))
1200 log_test.info("----------------------------------------------------------------------------------")
1201
1202 log_test.info("----------------------------------------------------------------------------------")
1203 log_test.info("Final Statistics for total transactions")
1204 log_test.info("----------------------------------------------------------------------------------")
1205 log_test.info("Total transactions Total No. of successes Total No. of failures Running Time ")
1206 log_test.info(" %d %d %d %d" %(self.transactions,
1207 self.total_success, self.total_failure, self.running_time))
1208
1209 log_test.info("----------------------------------------------------------------------------------")
1210 log_test.info("Average no. of transactions per second: %d", round(self.transactions/self.running_time,0))
1211 log_test.info("----------------------------------------------------------------------------------")
1212
1213 def test_dhcpl2relay_concurrent_consecutive_successes_per_second(self, iface = 'veth0'):
1214
1215 config = self.default_config
1216 options = self.default_options
1217 subnet = [ ('192.168.1.2',
1218'''
1219subnet 192.168.0.0 netmask 255.255.0.0 {
1220 range 192.168.1.10 192.168.2.100;
1221}
1222'''), ]
1223
1224 dhcpd_interface_list = self.relay_interfaces
1225 self.dhcpd_start(intf_list = dhcpd_interface_list,
1226 config = config,
1227 options = options,
1228 subnet = subnet)
1229 failure_dir = {}
1230
1231 for key in (key for key in g_subscriber_port_map if key != 100):
1232 self.host_load(g_subscriber_port_map[key])
1233
1234 def thread_fun(i, j):
1235# log_test.info("Thread Name:%s",current_thread().name)
1236# failure_dir[current_thread().name] = True
1237 while failure_dir.has_key(current_thread().name) is False:
1238 mac = RandMAC()._fix()
1239 cip, sip = DHCPTest(iface = 'veth{}'.format(i)).discover(mac = mac)
1240 i += 2
1241 log_test.info('Got dhcp client IP %s from server %s for mac %s'%(cip, sip, mac))
1242 self.lock.acquire()
1243
1244 if cip:
1245 self.ip_count += 1
1246 self.lock.notify_all()
1247 self.lock.release()
1248 elif cip is None:
1249 self.failure_count += 1
1250 failure_dir[current_thread().name] = True
1251 self.lock.notify_all()
1252 self.lock.release()
1253 break
1254# self.lock.notify_all()
1255# self.lock.release()
1256
1257 for i in range (1,4):
1258 failure_dir = {}
1259 self.ip_count = 0
1260 self.failure_count = 0
1261 self.start_time = 0
1262 self.diff = 0
1263 self.transaction_count = 0
1264 self.start_time = time.time()
1265
1266 while len(failure_dir) != 6:
1267 t = threading.Thread(target = thread_fun, kwargs = {'i': 0, 'j': 2})
1268 t1 = threading.Thread(target = thread_fun, kwargs = {'i': 0, 'j': 2})
1269 t2 = threading.Thread(target = thread_fun, kwargs = {'i': 0, 'j': 2})
1270 t3 = threading.Thread(target = thread_fun, kwargs = {'i': 0, 'j': 2})
1271 t4 = threading.Thread(target = thread_fun, kwargs = {'i': 0, 'j': 2})
1272 t5 = threading.Thread(target = thread_fun, kwargs = {'i': 0, 'j': 2})
1273
1274 t.start()
1275 t1.start()
1276 t2.start()
1277 t3.start()
1278 t4.start()
1279 t5.start()
1280
1281 t.join()
1282 t1.join()
1283 t2.join()
1284 t3.join()
1285 t4.join()
1286 t5.join()
1287
1288 self.diff = round(time.time() - self.start_time, 0)
1289 self.transaction_count = round((self.ip_count)/self.diff, 2)
1290
1291 self.transactions += (self.ip_count+self.failure_count)
1292 self.running_time += self.diff
1293 self.total_success += self.ip_count
1294 self.total_failure += self.failure_count
1295
1296
1297 log_test.info("Statistics for run %d",i)
1298 log_test.info("----------------------------------------------------------------------------------")
1299 log_test.info("No. of consecutive successful transactions Running Time ")
1300 log_test.info(" %d %d " %(self.ip_count, self.diff))
1301 log_test.info("----------------------------------------------------------------------------------")
1302 log_test.info("No. of successful transactions per second in run %d:%f" %(i, self.transaction_count))
1303 log_test.info("----------------------------------------------------------------------------------")
1304
1305 log_test.info("Final Statistics for total successful transactions")
1306 log_test.info("----------------------------------------------------------------------------------")
1307 log_test.info("Total transactions Total No. of consecutive successes Running Time ")
1308 log_test.info(" %d %d %d " %(self.transactions,
1309 self.total_success, self.running_time))
1310 log_test.info("----------------------------------------------------------------------------------")
1311 log_test.info("Average no. of consecutive successful transactions per second: %d", round(self.total_success/self.running_time,2))
1312 log_test.info("----------------------------------------------------------------------------------")
1313
1314 def test_dhcpl2relay_concurrent_clients_per_second(self, iface = 'veth0'):
1315
1316 config = self.default_config
1317 options = self.default_options
1318 subnet = [ ('192.168.1.2',
1319'''
1320subnet 192.168.0.0 netmask 255.255.0.0 {
1321 range 192.168.1.10 192.168.2.100;
1322}
1323'''), ]
1324
1325 dhcpd_interface_list = self.relay_interfaces
1326 self.dhcpd_start(intf_list = dhcpd_interface_list,
1327 config = config,
1328 options = options,
1329 subnet = subnet)
1330
1331 for key in (key for key in g_subscriber_port_map if key < 100):
1332 self.host_load(g_subscriber_port_map[key])
1333
1334 def thread_fun(i):
1335# mac = self.get_mac('veth{}'.format(i))
1336 cip, sip, mac, _ = DHCPTest(iface = 'veth{}'.format(i)).only_discover(mac = RandMAC()._fix())
1337 log_test.info('Got dhcp client IP %s from server %s for mac %s'%(cip, sip, mac))
1338 self.lock.acquire()
1339
1340 if cip:
1341 self.ip_count += 1
1342 elif cip is None:
1343 self.failure_count += 1
1344
1345 self.lock.notify_all()
1346 self.lock.release()
1347
1348 for i in range (1,4):
1349 self.ip_count = 0
1350 self.failure_count = 0
1351 self.start_time = 0
1352 self.diff = 0
1353 self.transaction_count = 0
1354 self.start_time = time.time()
1355
1356 while self.diff <= 60:
1357 t = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(0, random.randrange(1,40,1), 1)})
1358 t1 = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(42, random.randrange(43,80,1), 1)})
1359 t2 = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(82, random.randrange(83,120,1), 1)})
1360 t3 = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(122, random.randrange(123,160,1), 1)})
1361 t4 = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(162, random.randrange(163,180,1), 1)})
1362 t5 = threading.Thread(target = thread_fun, kwargs = {'i': random.randrange(182, random.randrange(183,196,1), 1)})
1363
1364 t.start()
1365 t1.start()
1366 t2.start()
1367 t3.start()
1368 t4.start()
1369 t5.start()
1370
1371 t.join()
1372 t1.join()
1373 t2.join()
1374 t3.join()
1375 t4.join()
1376 t5.join()
1377
1378 self.diff = round(time.time() - self.start_time, 0)
1379 self.transaction_count = round((self.ip_count+self.failure_count)/self.diff, 2)
1380 self.transactions += (self.ip_count+self.failure_count)
1381 self.running_time += self.diff
1382 self.total_success += self.ip_count
1383 self.total_failure += self.failure_count
1384
1385 log_test.info("----------------------------------------------------------------------------------")
1386 log_test.info("Statistics for run %d of sending only DHCP Discover",i)
1387 log_test.info("----------------------------------------------------------------------------------")
1388 log_test.info("No. of transactions No. of successes No. of failures Running Time ")
1389 log_test.info(" %d %d %d %d" %(self.ip_count+self.failure_count, self.ip_count, self.failure_count, self.diff))
1390 log_test.info("----------------------------------------------------------------------------------")
1391 log_test.info("No. of clients per second in run %d:%f "
1392 %(i, self.transaction_count))
1393 log_test.info("----------------------------------------------------------------------------------")
1394
1395 log_test.info("Final Statistics for total transactions of sending only DHCP Discover")
1396 log_test.info("----------------------------------------------------------------------------------")
1397 log_test.info("Total transactions Total No. of successes Total No. of failures Running Time ")
1398 log_test.info(" %d %d %d %d" %(self.transactions,
1399 self.total_success, self.total_failure, self.running_time))
1400 log_test.info("----------------------------------------------------------------------------------")
1401 log_test.info("Average no. of clients per second: %d ",
1402 round(self.transactions/self.running_time,0))
1403 log_test.info("----------------------------------------------------------------------------------")
1404
1405 def test_dhcpl2relay_client_conflict(self, iface = 'veth0'):
1406 mac = self.get_mac(iface)
1407 self.host_load(iface)
1408 self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
1409 cip, sip, mac, _ = self.dhcp.only_discover()
1410 log_test.info('Got dhcp client IP %s from server %s for mac %s.' %
1411 (cip, sip, mac) )
1412 self.dhcp1 = DHCPTest(seed_ip = cip, iface = iface)
1413 new_cip, new_sip, new_mac, _ = self.dhcp1.only_discover(desired = True)
1414 new_cip, new_sip = self.dhcp1.only_request(new_cip, new_mac)
1415 log_test.info('Got dhcp client IP %s from server %s for mac %s.' %
1416 (new_cip, new_sip, new_mac) )
1417 log_test.info("IP %s alredy consumed by mac %s." % (new_cip, new_mac))
1418 log_test.info("Now sending DHCP Request for old DHCP discover.")
1419 new_cip, new_sip = self.dhcp.only_request(cip, mac)
1420 if new_cip is None:
1421 log_test.info('Got dhcp client IP %s from server %s for mac %s.Which is expected behavior.'
1422 %(new_cip, new_sip, new_mac) )
1423 elif new_cip:
1424 log_test.info('Got dhcp client IP %s from server %s for mac %s.Which is not expected behavior as IP %s is already consumed.'
1425 %(new_cip, new_sip, new_mac, new_cip) )
1426 assert_equal(new_cip, None)