blob: 75b6e7bb57394f6aa1859e50883c0653f45d0f38 [file] [log] [blame]
lmr4c607f22009-06-02 11:50:38 +00001import os, time, logging
mbligh67a72f92009-01-13 19:31:08 +00002from autotest_lib.client.bin import test, utils
3from autotest_lib.client.common_lib import error
mbligh9f857922008-06-05 16:19:07 +00004
mbligh56a91f02006-09-14 17:55:19 +00005
6class netperf2(test.test):
mbligha5630a52008-09-03 22:09:50 +00007 version = 2
mbligh56a91f02006-09-14 17:55:19 +00008
mbligha5630a52008-09-03 22:09:50 +00009 # ftp://ftp.netperf.org/netperf/netperf-2.4.4.tar.gz
10 def setup(self, tarball = 'netperf-2.4.4.tar.gz'):
mbligh8b352852008-06-07 01:07:08 +000011 tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir)
mbligh53da18e2009-01-05 21:13:26 +000012 utils.extract_tarball_to_dir(tarball, self.srcdir)
jadmanski0afbb632008-06-06 21:10:57 +000013 os.chdir(self.srcdir)
mbligh56a91f02006-09-14 17:55:19 +000014
mblighc21cb462008-10-22 03:34:40 +000015 # Fixing up a compile issue under newer systems that have
16 # CPU_SET_S defined on /usr/include/sched.h, backported from
17 # upstream svn trunk
mbligh1eb6e9e2009-03-11 17:14:45 +000018 utils.system('patch -p0 < ../fix_netperf_build.patch')
jadmanski0afbb632008-06-06 21:10:57 +000019 utils.system('./configure')
20 utils.system('make')
mbligh54e56842006-09-23 06:02:54 +000021
22
jadmanski0afbb632008-06-06 21:10:57 +000023 def initialize(self):
mbligha5630a52008-09-03 22:09:50 +000024 self.job.require_gcc()
25
26 self.server_path = '%s&' % os.path.join(self.srcdir,
27 'src/netserver')
28 # Add server_ip and arguments later
29 self.client_path = '%s %%s %%s' % os.path.join(self.srcdir,
30 'src/netperf -H')
31
mblighb405b982008-09-10 20:35:52 +000032 self.valid_tests = ['TCP_STREAM', 'TCP_RR', 'TCP_CRR', 'TCP_SENDFILE',
mbligh52fa6922008-09-05 20:37:08 +000033 'UDP_STREAM', 'UDP_RR']
mbligha5630a52008-09-03 22:09:50 +000034 self.results = []
mbligh865ee822008-10-03 16:03:34 +000035 self.actual_times = []
mbligh56a91f02006-09-14 17:55:19 +000036
mbligh6f5bbce2007-08-10 19:18:37 +000037
mbligha5630a52008-09-03 22:09:50 +000038 def run_once(self, server_ip, client_ip, role, test='TCP_STREAM',
39 test_time=10, stream_list=[1]):
40 if test not in self.valid_tests:
41 raise error.TestError('invalid test specified')
42 self.role = role
mbligh52fa6922008-09-05 20:37:08 +000043 self.test = test
mbligh865ee822008-10-03 16:03:34 +000044 self.test_time = test_time
mbligh52fa6922008-09-05 20:37:08 +000045 self.stream_list = stream_list
mbligha5630a52008-09-03 22:09:50 +000046
jadmanski0afbb632008-06-06 21:10:57 +000047 server_tag = server_ip + '#netperf-server'
48 client_tag = client_ip + '#netperf-client'
49 all = [server_tag, client_tag]
mbligha5630a52008-09-03 22:09:50 +000050
mbligha5630a52008-09-03 22:09:50 +000051 for num_streams in stream_list:
52 if role == 'server':
53 self.server_start()
54 try:
mbligh15b8a262008-09-16 16:50:49 +000055 # Wait up to ten minutes for the client to reach this
mbligh52fa6922008-09-05 20:37:08 +000056 # point.
mbligh15b8a262008-09-16 16:50:49 +000057 self.job.barrier(server_tag, 'start_%d' % num_streams,
58 600).rendevous(*all)
59 # Wait up to test_time + 5 minutes for the test to
mbligh52fa6922008-09-05 20:37:08 +000060 # complete
mbligh15b8a262008-09-16 16:50:49 +000061 self.job.barrier(server_tag, 'stop_%d' % num_streams,
62 test_time+300).rendevous(*all)
mbligha5630a52008-09-03 22:09:50 +000063 finally:
64 self.server_stop()
65
66 elif role == 'client':
mbligh15b8a262008-09-16 16:50:49 +000067 # Wait up to ten minutes for the server to start
68 self.job.barrier(client_tag, 'start_%d' % num_streams,
69 600).rendevous(*all)
mbligha5630a52008-09-03 22:09:50 +000070 self.client(server_ip, test, test_time, num_streams)
mbligh15b8a262008-09-16 16:50:49 +000071 # Wait up to 5 minutes for the server to also reach this point
72 self.job.barrier(client_tag, 'stop_%d' % num_streams,
73 300).rendevous(*all)
mbligha5630a52008-09-03 22:09:50 +000074 else:
75 raise error.TestError('invalid role specified')
mbligh54e56842006-09-23 06:02:54 +000076
mbligh56a91f02006-09-14 17:55:19 +000077
jadmanski0afbb632008-06-06 21:10:57 +000078 def server_start(self):
mbligh78be24a2008-06-13 21:40:08 +000079 utils.system('killall netserver', ignore_status=True)
mbligha5630a52008-09-03 22:09:50 +000080 self.results.append(utils.system_output(self.server_path,
81 retain_output=True))
mbligh56a91f02006-09-14 17:55:19 +000082
mbligh54e56842006-09-23 06:02:54 +000083
jadmanski0afbb632008-06-06 21:10:57 +000084 def server_stop(self):
mbligha5630a52008-09-03 22:09:50 +000085 utils.system('killall netserver', ignore_status=True)
mbligh56a91f02006-09-14 17:55:19 +000086
mbligh54e56842006-09-23 06:02:54 +000087
mbligha5630a52008-09-03 22:09:50 +000088 def client(self, server_ip, test, test_time, num_streams):
89 args = '-t %s -l %d' % (test, test_time)
90 cmd = self.client_path % (server_ip, args)
mbligh56a91f02006-09-14 17:55:19 +000091
mbligha5630a52008-09-03 22:09:50 +000092 try:
mbligh865ee822008-10-03 16:03:34 +000093 t0 = time.time()
mbligha5630a52008-09-03 22:09:50 +000094 self.results.append(utils.get_cpu_percentage(
mbligh52fa6922008-09-05 20:37:08 +000095 utils.system_output_parallel, [cmd]*num_streams,
96 timeout=test_time+60, retain_output=True))
mbligh865ee822008-10-03 16:03:34 +000097 t1 = time.time()
98
99 self.actual_times.append(t1 - t0)
100
mbligha5630a52008-09-03 22:09:50 +0000101 except error.CmdError, e:
102 """ Catch errors due to timeout, but raise others
103 The actual error string is:
104 "Command did not complete within %d seconds"
105 called in function join_bg_job in the file common_lib/utils.py
mblighe8fa3af2006-09-28 23:14:56 +0000106
mbligha5630a52008-09-03 22:09:50 +0000107 Looking for 'within' is probably not the best way to do this but
108 works for now"""
109
mbligh52fa6922008-09-05 20:37:08 +0000110 if ('within' in e.additional_text
111 or 'non-zero' in e.additional_text):
lmr4c607f22009-06-02 11:50:38 +0000112 logging.debug(e.additional_text)
mbligh52fa6922008-09-05 20:37:08 +0000113 # Results are cpu%, outputs
114 self.results.append((0, None))
mbligh865ee822008-10-03 16:03:34 +0000115 self.actual_times.append(1)
mbligha5630a52008-09-03 22:09:50 +0000116 else:
117 raise
118
119
120 def postprocess(self):
mbligh52fa6922008-09-05 20:37:08 +0000121 if self.role == 'client':
122 if len(self.stream_list) != len(self.results):
123 raise error.TestError('Mismatched number of results')
124
125 function = None
126 keys = None
127
128 # Each of the functions return tuples in which the keys define
129 # what that item in the tuple represents
mblighb405b982008-09-10 20:35:52 +0000130 if self.test in ['TCP_STREAM', 'TCP_SENDFILE']:
mbligh52fa6922008-09-05 20:37:08 +0000131 function = self.process_tcp_stream
132 keys = ('Throughput',)
133 elif self.test == 'UDP_STREAM':
134 function = self.process_udp_stream
135 keys = ('Throughput', 'Errors')
136 elif self.test in ['TCP_RR', 'TCP_CRR', 'UDP_RR']:
137 function = self.process_request_response
138 keys = ('Transfer_Rate',)
139 else:
140 raise error.TestError('Unhandled test')
141
142 # self.results is a list of tuples. The first element in each
143 # tuple is the cpu utilization for that run, and the second
144 # element is a list containing the output for each stream in that
145 # run.
146 for i, streams in enumerate(self.stream_list):
147 attr = {'stream_count':streams}
148 keyval = {}
149 temp_vals = []
150 keyval['CPU'], outputs = self.results[i]
mbligh865ee822008-10-03 16:03:34 +0000151 actual_time = self.actual_times[i]
mbligh52fa6922008-09-05 20:37:08 +0000152
153 # Short circuit to handle errors due to client timeouts
154 if not outputs:
mbligh52fa6922008-09-05 20:37:08 +0000155 self.write_iteration_keyval(attr, keyval)
156 continue
157
158 for result in outputs:
159 temp_vals.append(function(result))
160
mbligh6d858fa2008-09-19 21:19:03 +0000161 # Compute the sum of elements returned from function which
mbligh52fa6922008-09-05 20:37:08 +0000162 # represent the string contained in keys
163 for j, key in enumerate(keys):
164 vals = [x[j] for x in temp_vals]
mbligh865ee822008-10-03 16:03:34 +0000165 # scale result by the actual time taken
166 keyval[key] = sum(vals)*self.test_time/actual_time
167
168 # record 'Efficiency' as perf/CPU
169 keyval['Efficieny'] = keyval[keys[0]]/keyval['CPU']
mbligh52fa6922008-09-05 20:37:08 +0000170
171 self.write_iteration_keyval(attr, keyval)
172
173
174 def process_tcp_stream(self, output):
mblighb405b982008-09-10 20:35:52 +0000175 """Parses the following (works for both TCP_STREAM and TCP_SENDFILE)
176 and returns a singleton containing throughput.
mbligh52fa6922008-09-05 20:37:08 +0000177
mbligh1d7f7202009-01-30 00:28:58 +0000178 TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to foo (10.1.1.1) port 0 AF_INET
mbligh52fa6922008-09-05 20:37:08 +0000179 Recv Send Send
180 Socket Socket Message Elapsed
181 Size Size Size Time Throughput
182 bytes bytes bytes secs. 10^6bits/sec
183
184 87380 16384 16384 2.00 941.28
185 """
186
187 return float(output.splitlines()[6].split()[4]),
188
189
190 def process_udp_stream(self, output):
191 """Parses the following and returns a touple containing throughput
192 and the number of errors.
193
mbligh1d7f7202009-01-30 00:28:58 +0000194 UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to foo (10.1.1.1) port 0 AF_INET
mbligh52fa6922008-09-05 20:37:08 +0000195 Socket Message Elapsed Messages
196 Size Size Time Okay Errors Throughput
197 bytes bytes secs # # 10^6bits/sec
198
199 129024 65507 2.00 3673 0 961.87
200 131072 2.00 3673 961.87
201 """
202
203 line_tokens = output.splitlines()[5].split()
204 return float(line_tokens[5]), int(line_tokens[4])
205
206
207 def process_request_response(self, output):
208 """Parses the following which works for both rr (TCP and UDP) and crr
209 tests and returns a singleton containing transfer rate.
210
mbligh1d7f7202009-01-30 00:28:58 +0000211 TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to foo (10.1.1.1) port 0 AF_INET
mbligh52fa6922008-09-05 20:37:08 +0000212 Local /Remote
213 Socket Size Request Resp. Elapsed Trans.
214 Send Recv Size Size Time Rate
215 bytes Bytes bytes bytes secs. per sec
216
217 16384 87380 1 1 2.00 14118.53
218 16384 87380
219 """
220
221 return float(output.splitlines()[6].split()[5]),