Skip to content

Commit d10db95

Browse files
committed
Merge pull request #194 from mhaas/load-tester-wdctl
Load tester wdctl
2 parents 8bd9427 + e19f586 commit d10db95

File tree

5 files changed

+176
-101
lines changed

5 files changed

+176
-101
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: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,63 +4,76 @@
44
# echo "core.%e.%p" > /proc/sys/kernel/core_pattern
55
# http://stackoverflow.com/a/18368068
66

7+
function main() {
8+
if [[ -z "$SUDO_USER" ]]; then
9+
echo "Hey, you should run this with sudo"
10+
exit 1
11+
fi
712

8-
if [[ -z "$SUDO_USER" ]]; then
9-
echo "Hey, you should run this with sudo"
10-
exit 1
11-
fi
13+
echo "core.%e.%p" > /proc/sys/kernel/core_pattern
14+
ulimit -c unlimited
1215

13-
echo "core.%e.%p" > /proc/sys/kernel/core_pattern
14-
ulimit -c unlimited
16+
COUNT=40
17+
echo "Make sure to configure GatewayInterface in wifidog_mock.conf"
1518

16-
COUNT=40
17-
echo "Make sure to configure GatewayInterface in wifidog_mock.conf"
19+
./generate_interfaces.sh start $COUNT || exit 1
1820

19-
./generate_interfaces.sh start $COUNT || exit 1
21+
sudo -u "$SUDO_USER" ./mock_auth.py &
22+
MA_PID="$!"
2023

21-
sudo -u "$SUDO_USER" ./mock_auth.py &
22-
MA_PID="$!"
24+
# work around libtool stuff - do not execute wrapper!
25+
#EXEC="../../src/.libs/wifidog"
26+
#export LD_LIBRARY_PATH="../../libhttpd/.libs/"
27+
# trace-children is necessary because of the libtool wrapper -.-
28+
#valgrind --leak-check=full --trace-children=yes --trace-children-skip=/bin/sh \
29+
# --log-file=valgrind.log $EXEC -d 7 -f -c wifidog-mock.conf -a /tmp/arp 2> wifidog.log &
2330

24-
# work around libtool stuff - do not execute wrapper!
25-
#EXEC="../../src/.libs/wifidog"
26-
#export LD_LIBRARY_PATH="../../libhttpd/.libs/"
27-
# trace-children is necessary because of the libtool wrapper -.-
28-
#valgrind --leak-check=full --trace-children=yes --trace-children-skip=/bin/sh \
29-
# --log-file=valgrind.log $EXEC -d 7 -f -c wifidog-mock.conf -a /tmp/arp 2> wifidog.log &
31+
# for -fsanitize=address
32+
export ASAN_OPTIONS=check_initialization_order=1
33+
export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.5
3034

31-
# for -fsanitize=address
32-
export ASAN_OPTIONS=check_initialization_order=1
33-
export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.5
3435

36+
../../src/wifidog -d 7 -f -c wifidog-mock.conf -a /tmp/arp &> wifidog.log &
37+
WD_PID="$!"
3538

36-
../../src/wifidog -d 7 -f -c wifidog-mock.conf -a /tmp/arp &> wifidog.log &
37-
WD_PID="$!"
3839

40+
sudo -u "$SUDO_USER" ./plot_memory.sh $WD_PID &
41+
M_PID="$!"
3942

40-
sudo -u "$SUDO_USER" ./plot_memory.sh $WD_PID &
41-
M_PID="$!"
43+
IF=`sudo -u "$SUDO_USER" grep GatewayInterface wifidog-mock.conf | cut -f 2 -d ' '`
4244

43-
IF=`sudo -u "$SUDO_USER" grep GatewayInterface wifidog-mock.conf | cut -f 2 -d ' '`
45+
echo "Waiting for wifidog to come up"
4446

45-
echo "Waiting for wifidog to come up"
47+
sleep 10
4648

47-
sleep 10
49+
./fire_wdctl.py \
50+
--target-interface $IF \
51+
--source-interface-prefix mac \
52+
--source-interface-count $COUNT \
53+
--process-count 3 &
54+
WDCTL="$!"
4855

49-
sudo -u "$SUDO_USER" ./fire_requests.py \
50-
--target-interface $IF \
51-
--source-interface-prefix mac \
52-
--source-interface-count $COUNT \
53-
--process-count 3
56+
sudo -u "$SUDO_USER" ./fire_requests.py \
57+
--target-interface $IF \
58+
--source-interface-prefix mac \
59+
--source-interface-count $COUNT \
60+
--process-count 3
61+
REQUESTS="$!"
5462

55-
#./generate_interfaces.sh stop
63+
64+
}
5665

5766
function cleanup() {
5867

5968
kill $MA_PID
6069
kill $WD_PID
6170
kill $M_PID
71+
kill $WDCTL
72+
kill $REQUESTS
6273
./generate_interfaces.sh stop $COUNT
6374

6475
}
6576

6677
trap cleanup EXIT
78+
79+
main

contrib/load-tester/wdctl.sh

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

0 commit comments

Comments
 (0)