Skip to content

Commit e19f586

Browse files
committed
Add code to exercise wdctl
fire_wdctl.py randomly calls either 'wdctl status' or resets a client based on either IP or MAC address. Includes some refactoring and white space changes, but no functional changes in fire_requests.py.
1 parent c59ab21 commit e19f586

File tree

5 files changed

+140
-69
lines changed

5 files changed

+140
-69
lines changed

contrib/load-tester/common.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import socket
4+
import fcntl
5+
import struct
6+
7+
import argparse
8+
9+
# http://stackoverflow.com/questions/159137/getting-mac-address
10+
def get_mac_address(ifname):
11+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
12+
info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', ifname[:15]))
13+
return ':'.join(['%02x' % ord(char) for char in info[18:24]])
14+
15+
# http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter/
16+
def get_ip_address(ifname):
17+
print "ifname: %s" % ifname
18+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
19+
return socket.inet_ntoa(fcntl.ioctl(
20+
s.fileno(),
21+
0x8915, # SIOCGIFADDR
22+
struct.pack('256s', ifname[:15])
23+
)[20:24])
24+
25+
def get_argparser():
26+
parser = argparse.ArgumentParser(description='Hammer a wifidog'
27+
+ ' instance with requests')
28+
parser.add_argument(
29+
'--target-interface',
30+
required=True,
31+
help='Interface where Wifidog is listening')
32+
parser.add_argument(
33+
'--source-interface-prefix',
34+
required=True,
35+
help='Prefix of the virtual interfaces from which Wifidog' +
36+
' is exercised.')
37+
parser.add_argument(
38+
'--source-interface-count',
39+
required=True,
40+
help='Number of virtual interfaces, where interface is prefix+index')
41+
parser.add_argument(
42+
'--process-count',
43+
required=True,
44+
help='How many processes to run')
45+
return parser

contrib/load-tester/fire_requests.py

Lines changed: 45 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,97 +2,80 @@
22
# -*- coding: utf -*-
33

44

5-
import socket
6-
import fcntl
7-
import struct
8-
95
import uuid
10-
import sys
116
import random
127

13-
import argparse
148
import functools
159

16-
1710
from multiprocessing import Pool
1811

1912
from httplib import HTTPConnection
2013
from httplib import BadStatusLine
2114

15+
import common
16+
17+
2218
PORT = "2060"
2319

2420

2521
def main(targetIF, prefix, maxI):
26-
target = get_ip_address(targetIF)
22+
target = common.get_ip_address(targetIF)
2723
for i in xrange(int(maxI)):
2824
main_single(target, prefix, i)
2925

26+
3027
def main_single(target, prefix, i):
31-
source = get_ip_address(prefix + str(i))
32-
# source_address requires python 2.7
33-
# urllib2 does not nicely expose source_address, so use
34-
# lower-level API
35-
conn = HTTPConnection(target, PORT, timeout=10, source_address=(source, 0))
36-
conn.connect()
37-
conn.request("GET", "/")
38-
try:
39-
resp = conn.getresponse()
40-
resp.read()
41-
conn.close()
42-
except BadStatusLine as e:
43-
print "Got BadStatusLine for /: %s" % e
44-
conn = HTTPConnection(target, PORT, timeout=10, source_address=(source, 0))
28+
source = common.get_ip_address(prefix + str(i))
29+
# source_address requires python 2.7
30+
# urllib2 does not nicely expose source_address, so use
31+
# lower-level API
32+
conn = HTTPConnection(target, PORT, timeout=10,
33+
source_address=(source, 0))
34+
conn.connect()
35+
conn.request("GET", "/")
36+
try:
37+
resp = conn.getresponse()
38+
resp.read()
39+
conn.close()
40+
except BadStatusLine as e:
41+
print "Got BadStatusLine for /: %s" % e
42+
conn = HTTPConnection(target, PORT, timeout=10,
43+
source_address=(source, 0))
44+
conn.connect()
45+
token = str(uuid.uuid4())
46+
conn.request("GET", "/wifidog/auth?token=" + token)
47+
try:
48+
resp = conn.getresponse()
49+
# this causes wifidog to ask our mock auth server if the token is
50+
# correct
51+
resp.read()
52+
conn.close()
53+
except BadStatusLine as e:
54+
print "Got BadStatusLine for login: %s" % e
55+
# log out sometimes
56+
if random.choice([True, False, False]):
57+
conn = HTTPConnection(target, PORT, timeout=10,
58+
source_address=(source, 0))
4559
conn.connect()
46-
token = str(uuid.uuid4())
47-
conn.request("GET", "/wifidog/auth?token=" + token )
60+
conn.request("GET", "/wifidog/auth?logout=1&token=" + token)
4861
try:
4962
resp = conn.getresponse()
50-
# this causes wifidog to ask our mock auth server if the token is
51-
# correct
5263
resp.read()
5364
conn.close()
5465
except BadStatusLine as e:
55-
print "Got BadStatusLine for login: %s" % e
56-
# log out sometimes
57-
if random.choice([True, False, False]):
58-
conn = HTTPConnection(target, PORT, timeout=10, source_address=(source, 0))
59-
conn.connect()
60-
conn.request("GET", "/wifidog/auth?logout=1&token=" + token)
61-
try:
62-
resp = conn.getresponse()
63-
resp.read()
64-
conn.close()
65-
except BadStatusLine as e:
66-
print "Got BadStatusLine for logout: %s" % e
67-
68-
69-
# http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter/
70-
def get_ip_address(ifname):
71-
print "ifname: %s" % ifname
72-
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
73-
return socket.inet_ntoa(fcntl.ioctl(
74-
s.fileno(),
75-
0x8915, # SIOCGIFADDR
76-
struct.pack('256s', ifname[:15])
77-
)[20:24])
66+
print "Got BadStatusLine for logout: %s" % e
7867

79-
if __name__ == "__main__":
8068

81-
parser = argparse.ArgumentParser(description='Hammer a wifidog instance with requests')
82-
parser.add_argument('--target-interface', required=True,
83-
help='Interface where Wifidog is listening')
84-
parser.add_argument('--source-interface-prefix', required=True,
85-
help='Prefix of the virtual interfaces from which Wifidog is exercised.')
86-
parser.add_argument('--source-interface-count', required=True,
87-
help='Number of virtual interfaces, where interface is prefix+index')
88-
parser.add_argument('--process-count', required=True,
89-
help='How many processes to run')
69+
if __name__ == "__main__":
9070

71+
parser = common.get_argparser()
9172
args = parser.parse_args()
9273

93-
target = get_ip_address(args.target_interface)
74+
target = common.get_ip_address(args.target_interface)
9475
p = Pool(int(args.process_count))
95-
partial = functools.partial(main_single, target, args.source_interface_prefix)
76+
partial = functools.partial(
77+
main_single,
78+
target,
79+
args.source_interface_prefix)
9680
while True:
9781
p.map(partial, list(xrange(int(args.source_interface_count))))
98-

contrib/load-tester/fire_wdctl.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env python2
2+
# -*- coding: utf -*-
3+
4+
5+
import functools
6+
from multiprocessing import Pool
7+
import subprocess
8+
import random
9+
10+
11+
import common
12+
13+
14+
def main_single(target, prefix, i):
15+
"""
16+
Either calls 'wdctl status' or
17+
logs out the client specified by the interface prefix + i.
18+
"""
19+
binary = "../../src/wdctl"
20+
ip = common.get_ip_address(prefix + str(i))
21+
mac = common.get_mac_address(prefix + str(i))
22+
args = [["status"], ["reset", ip], ["reset", mac]]
23+
call = [binary]
24+
call.extend(random.choice(args))
25+
ret = subprocess.call(call)
26+
print "fire_wdctl.py: Return code %s" % ret
27+
28+
29+
if __name__ == "__main__":
30+
parser = common.get_argparser()
31+
args = parser.parse_args()
32+
33+
target = common.get_ip_address(args.target_interface)
34+
p = Pool(int(args.process_count))
35+
partial = functools.partial(
36+
main_single,
37+
target,
38+
args.source_interface_prefix)
39+
while True:
40+
p.map(partial, list(xrange(int(args.source_interface_count))))

contrib/load-tester/run.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,20 @@ function main() {
4646

4747
sleep 10
4848

49+
./fire_wdctl.py \
50+
--target-interface $IF \
51+
--source-interface-prefix mac \
52+
--source-interface-count $COUNT \
53+
--process-count 3 &
54+
WDCTL="$!"
55+
4956
sudo -u "$SUDO_USER" ./fire_requests.py \
5057
--target-interface $IF \
5158
--source-interface-prefix mac \
5259
--source-interface-count $COUNT \
5360
--process-count 3
61+
REQUESTS="$!"
5462

55-
#./generate_interfaces.sh stop
5663

5764
}
5865

@@ -61,6 +68,8 @@ function cleanup() {
6168
kill $MA_PID
6269
kill $WD_PID
6370
kill $M_PID
71+
kill $WDCTL
72+
kill $REQUESTS
6473
./generate_interfaces.sh stop $COUNT
6574

6675
}

contrib/load-tester/wdctl.sh

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)