File: testStackFlavors.py

package info (click to toggle)
resiprocate 1%3A1.11.0~beta1-3%2Bdeb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 37,944 kB
  • sloc: cpp: 206,325; xml: 12,515; sh: 12,418; ansic: 6,973; makefile: 2,315; php: 1,150; python: 355; sql: 142; objc: 91; perl: 21; csh: 5
file content (172 lines) | stat: -rwxr-xr-x 5,431 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/usr/bin/python

# Linux-configuration
# Some of the test flavors require many open ports, and your system must be
# configured to enabled this. In particular:
# * This script opens up more than 1024 ports which means it needs to run
#   as root. Thus do:
#	sudo ./testStackFlavors.py
# * Ports 11000 thru 31000 will be bound. Ports in this range must not be
#   bound (kill any servers you have running in this range). Further,
#   client TCP connections must not be configured to run in this range.
#   This is configured via
#	/proc/sys/net/ipv4/ip_local_port_range
#   The default is "32678 61000" which is good. The left number must be
#   larger than 31000.
# * TCP connections will enter TIME_WAIT when each test completes,
#   which may not leave enough ports for the next test.
#   The script has a 5sec delay between tests that might help with this.
#   You might need to tweak one of the following to work:
#	/proc/sys/net/ipv4/tcp_tw_recycle
#	/proc/sys/net/ipv4/tcp_tw_reuse
#	/proc/sys/net/ipv4/tcp_fin_timeout
#   I don't claim to fully understand this.

import os
import subprocess
import re
import platform
import datetime
import time

def TryUnlink(path):
    try:
	os.unlink(path)
    except OSError:
        pass
    return


def RunTest(tag, testArgs):
    cmdExec = "./testStack"
    cmdFull = cmdExec + " " + testArgs
    TryUnlink("./gmon.out")
    # XXX: perhaps should close stdin
    p = subprocess.Popen(cmdFull,shell=True,close_fds=True,stdout=subprocess.PIPE)
    result = None
    while p.stdout:
	line = p.stdout.readline()
	if len(line)==0:
	    break
        print "%s: %s" % (tag, line.rstrip())
	mo = re.match(r'(\d+).* performed in (\d+).* ms.*of (\d+).* per second',line)
	if mo:
	    result = {}
	    result['runs'] = int(mo.group(1))
	    result['dur'] = int(mo.group(2))
	    result['tps'] = int(mo.group(3))
	    # XXX: for calls, need to convert cps into tps!

    p.wait()

    if p.returncode!=0:
	print "%s: test failed (sts %d)!" % (tag, p.returncode)
	print "%s: command was:\n---------\n%s\n---------" % (tag, cmdFull)
	raise ValueError # fix this

    if result is None:
	print "%s: failed to find transaction rate in test output!"
	raise ValueError # fix this

    print "%s: runs=%d dur=%dms rate=%dtps" % (tag,
	     result['runs'], result['dur'], result['tps'])
    return result

class RunParam:
    def __init__(self, paramName, optionName, optionValues):
	self.paramName = paramName
	self.optionName = optionName
	# assert optionValue is list
	self.optionValues = optionValues

# Compute and return a runSet
# A runSet is list of paramSets
# A paramSet is a hash. The hashKey is the paramName, and the hash value
# is the specific value for this paramSet.

def CalcRunSet(ptbl):
    restRunSet = []
    if len(ptbl)==0:
	return restRunSet
    if len(ptbl)>1:
        restRunSet = CalcRunSet(ptbl[1:])
    if len(restRunSet)==0:
	restRunSet = [{}]
    doParam = ptbl[0]
    #print "CalcRunSet: expanding param %s" % (doParam.paramName)
    runSet = []
    for optVal in doParam.optionValues:
        #print "CalcRunSet: add param %s = %s" % (doParam.paramName, optVal)
	for restParamSet in restRunSet:
	    paramSet = restParamSet.copy()
	    paramSet[doParam.paramName] = optVal
	    runSet.append(paramSet)
    return runSet

def CalcParamStr(ptbl, pset):
   popts = ["--%s=%s" % (pdef.optionName, pset[pdef.paramName]) for pdef in ptbl]
   return ' '.join(popts)

def CalcParamCsv(ptbl, pset):
   # TBD: excape and commas
   popts = ["%s=,%s" % (pdef.paramName, pset[pdef.paramName]) for pdef in ptbl]
   return ','.join(popts)

def IsParamSetValid(pset):
    usingEpoll = pset['intepoll'] or pset['thread']=='epoll'
    if pset['intepoll'] and (pset['thread'] in ('epoll','fdset')):
	return False	# redundant/silly
    if pset['ports'] > 100 and not usingEpoll:
	return False
    if pset['listen']==0 and pset['protocol']=='udp':
        return False
    if usingEpoll and platform.system()=='Windows':
	return False
    return True

def RunParamTbl(ptbl):
    runSet = CalcRunSet(ptbl)
    #print runSet

    resfile = open('testStack.results.csv', 'a')

    platdesc = '-'.join(
	    [platform.system(),platform.release(),platform.machine()])
    platnode = platform.node()

    runCnt = 0
    for pset in runSet:
	runCnt += 1
	pstr = CalcParamStr(ptbl, pset)
	if not IsParamSetValid(pset):
	    print "skipping pstr: %s" % pstr
	    continue
	print "running pstr: %s" % pstr
	result = RunTest(runCnt, "--bind=127.0.0.1 " + pstr)
	assert( result['runs'] == pset['runs'] )
	now = datetime.datetime.now()
	nowfmt = now.strftime("%Y%m%d.%H%M%S")
	resstr = "tag=,%s,date=,%s,plat=,%s,node=,%s," % (runCnt,nowfmt,platdesc,platnode)
	resstr += CalcParamCsv(ptbl, pset)
	resstr += ",dur=,%d,tps=,%d" % (result['dur'], result['tps'])
	resstr += "\n"
	resfile.write(resstr)
	# TCP ports just entered TIME_WAIT. That may create problems
	# for next test if it tries to bind one of those ports
	# and/or needs more client ports. Try waiting short time
	# See comments at top re system configuration.
	time.sleep(5)

    resfile.close()


TheParamTbl = [
  RunParam('runs', 'num-runs', [50000]),
  RunParam('protocol', 'protocol', ['tcp','udp']),
  RunParam('intepoll', 'intepoll', [0,1]),
  RunParam('ports', 'numports', [1, 100, 10000]),
  RunParam('listen', 'listen', [1,0]),
  RunParam('thread', 'thread-type', ['common','intr','epoll','fdset']),
]

RunParamTbl(TheParamTbl)