blob: 6ac7d0cf1ba2a5abbb7f6b27bc59acae9c820913 [file] [log] [blame]
mbligh34d01172008-06-05 16:26:31 +00001import os
mbligh9f857922008-06-05 16:19:07 +00002from autotest_lib.client.bin import test, autotest_utils
3from autotest_lib.client.common_lib import utils, error
4
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)
jadmanski0afbb632008-06-06 21:10:57 +000012 autotest_utils.extract_tarball_to_dir(tarball, self.srcdir)
13 os.chdir(self.srcdir)
mbligh56a91f02006-09-14 17:55:19 +000014
jadmanski0afbb632008-06-06 21:10:57 +000015 utils.system('./configure')
16 utils.system('make')
mbligh54e56842006-09-23 06:02:54 +000017
18
jadmanski0afbb632008-06-06 21:10:57 +000019 def initialize(self):
mbligha5630a52008-09-03 22:09:50 +000020 self.job.require_gcc()
21
22 self.server_path = '%s&' % os.path.join(self.srcdir,
23 'src/netserver')
24 # Add server_ip and arguments later
25 self.client_path = '%s %%s %%s' % os.path.join(self.srcdir,
26 'src/netperf -H')
27
mblighb405b982008-09-10 20:35:52 +000028 self.valid_tests = ['TCP_STREAM', 'TCP_RR', 'TCP_CRR', 'TCP_SENDFILE',
mbligh52fa6922008-09-05 20:37:08 +000029 'UDP_STREAM', 'UDP_RR']
mbligha5630a52008-09-03 22:09:50 +000030 self.results = []
mbligh56a91f02006-09-14 17:55:19 +000031
mbligh6f5bbce2007-08-10 19:18:37 +000032
mbligha5630a52008-09-03 22:09:50 +000033 def run_once(self, server_ip, client_ip, role, test='TCP_STREAM',
34 test_time=10, stream_list=[1]):
35 if test not in self.valid_tests:
36 raise error.TestError('invalid test specified')
37 self.role = role
mbligh52fa6922008-09-05 20:37:08 +000038 self.test = test
39 self.stream_list = stream_list
mbligha5630a52008-09-03 22:09:50 +000040
jadmanski0afbb632008-06-06 21:10:57 +000041 server_tag = server_ip + '#netperf-server'
42 client_tag = client_ip + '#netperf-client'
43 all = [server_tag, client_tag]
mbligha5630a52008-09-03 22:09:50 +000044
mbligha5630a52008-09-03 22:09:50 +000045 for num_streams in stream_list:
46 if role == 'server':
47 self.server_start()
48 try:
mbligh15b8a262008-09-16 16:50:49 +000049 # Wait up to ten minutes for the client to reach this
mbligh52fa6922008-09-05 20:37:08 +000050 # point.
mbligh15b8a262008-09-16 16:50:49 +000051 self.job.barrier(server_tag, 'start_%d' % num_streams,
52 600).rendevous(*all)
53 # Wait up to test_time + 5 minutes for the test to
mbligh52fa6922008-09-05 20:37:08 +000054 # complete
mbligh15b8a262008-09-16 16:50:49 +000055 self.job.barrier(server_tag, 'stop_%d' % num_streams,
56 test_time+300).rendevous(*all)
mbligha5630a52008-09-03 22:09:50 +000057 finally:
58 self.server_stop()
59
60 elif role == 'client':
mbligh15b8a262008-09-16 16:50:49 +000061 # Wait up to ten minutes for the server to start
62 self.job.barrier(client_tag, 'start_%d' % num_streams,
63 600).rendevous(*all)
mbligha5630a52008-09-03 22:09:50 +000064 self.client(server_ip, test, test_time, num_streams)
mbligh15b8a262008-09-16 16:50:49 +000065 # Wait up to 5 minutes for the server to also reach this point
66 self.job.barrier(client_tag, 'stop_%d' % num_streams,
67 300).rendevous(*all)
mbligha5630a52008-09-03 22:09:50 +000068 else:
69 raise error.TestError('invalid role specified')
mbligh54e56842006-09-23 06:02:54 +000070
mbligh56a91f02006-09-14 17:55:19 +000071
jadmanski0afbb632008-06-06 21:10:57 +000072 def server_start(self):
mbligh78be24a2008-06-13 21:40:08 +000073 utils.system('killall netserver', ignore_status=True)
mbligha5630a52008-09-03 22:09:50 +000074 self.results.append(utils.system_output(self.server_path,
75 retain_output=True))
mbligh56a91f02006-09-14 17:55:19 +000076
mbligh54e56842006-09-23 06:02:54 +000077
jadmanski0afbb632008-06-06 21:10:57 +000078 def server_stop(self):
mbligha5630a52008-09-03 22:09:50 +000079 utils.system('killall netserver', ignore_status=True)
mbligh56a91f02006-09-14 17:55:19 +000080
mbligh54e56842006-09-23 06:02:54 +000081
mbligha5630a52008-09-03 22:09:50 +000082 def client(self, server_ip, test, test_time, num_streams):
83 args = '-t %s -l %d' % (test, test_time)
84 cmd = self.client_path % (server_ip, args)
mbligh56a91f02006-09-14 17:55:19 +000085
mbligha5630a52008-09-03 22:09:50 +000086 try:
87 self.results.append(utils.get_cpu_percentage(
mbligh52fa6922008-09-05 20:37:08 +000088 utils.system_output_parallel, [cmd]*num_streams,
89 timeout=test_time+60, retain_output=True))
mbligha5630a52008-09-03 22:09:50 +000090 except error.CmdError, e:
91 """ Catch errors due to timeout, but raise others
92 The actual error string is:
93 "Command did not complete within %d seconds"
94 called in function join_bg_job in the file common_lib/utils.py
mblighe8fa3af2006-09-28 23:14:56 +000095
mbligha5630a52008-09-03 22:09:50 +000096 Looking for 'within' is probably not the best way to do this but
97 works for now"""
98
mbligh52fa6922008-09-05 20:37:08 +000099 if ('within' in e.additional_text
100 or 'non-zero' in e.additional_text):
mbligha5630a52008-09-03 22:09:50 +0000101 print e.additional_text
mbligh52fa6922008-09-05 20:37:08 +0000102 # Results are cpu%, outputs
103 self.results.append((0, None))
mbligha5630a52008-09-03 22:09:50 +0000104 else:
105 raise
106
107
108 def postprocess(self):
mbligh52fa6922008-09-05 20:37:08 +0000109 if self.role == 'client':
110 if len(self.stream_list) != len(self.results):
111 raise error.TestError('Mismatched number of results')
112
113 function = None
114 keys = None
115
116 # Each of the functions return tuples in which the keys define
117 # what that item in the tuple represents
mblighb405b982008-09-10 20:35:52 +0000118 if self.test in ['TCP_STREAM', 'TCP_SENDFILE']:
mbligh52fa6922008-09-05 20:37:08 +0000119 function = self.process_tcp_stream
120 keys = ('Throughput',)
121 elif self.test == 'UDP_STREAM':
122 function = self.process_udp_stream
123 keys = ('Throughput', 'Errors')
124 elif self.test in ['TCP_RR', 'TCP_CRR', 'UDP_RR']:
125 function = self.process_request_response
126 keys = ('Transfer_Rate',)
127 else:
128 raise error.TestError('Unhandled test')
129
130 # self.results is a list of tuples. The first element in each
131 # tuple is the cpu utilization for that run, and the second
132 # element is a list containing the output for each stream in that
133 # run.
134 for i, streams in enumerate(self.stream_list):
135 attr = {'stream_count':streams}
136 keyval = {}
137 temp_vals = []
138 keyval['CPU'], outputs = self.results[i]
139
140 # Short circuit to handle errors due to client timeouts
141 if not outputs:
142 for key in keys:
143 keyval[key] = 0
144 self.write_iteration_keyval(attr, keyval)
145 continue
146
147 for result in outputs:
148 temp_vals.append(function(result))
149
mbligh6d858fa2008-09-19 21:19:03 +0000150 # Compute the sum of elements returned from function which
mbligh52fa6922008-09-05 20:37:08 +0000151 # represent the string contained in keys
152 for j, key in enumerate(keys):
153 vals = [x[j] for x in temp_vals]
mbligh6d858fa2008-09-19 21:19:03 +0000154 keyval[key] = sum(vals)
mbligh52fa6922008-09-05 20:37:08 +0000155
156 self.write_iteration_keyval(attr, keyval)
157
158
159 def process_tcp_stream(self, output):
mblighb405b982008-09-10 20:35:52 +0000160 """Parses the following (works for both TCP_STREAM and TCP_SENDFILE)
161 and returns a singleton containing throughput.
mbligh52fa6922008-09-05 20:37:08 +0000162
163 TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to kcqz13.prod.google.com (10.75.222.13) port 0 AF_INET
164 Recv Send Send
165 Socket Socket Message Elapsed
166 Size Size Size Time Throughput
167 bytes bytes bytes secs. 10^6bits/sec
168
169 87380 16384 16384 2.00 941.28
170 """
171
172 return float(output.splitlines()[6].split()[4]),
173
174
175 def process_udp_stream(self, output):
176 """Parses the following and returns a touple containing throughput
177 and the number of errors.
178
179 UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to kcqz13.prod.google.com (10.75.222.13) port 0 AF_INET
180 Socket Message Elapsed Messages
181 Size Size Time Okay Errors Throughput
182 bytes bytes secs # # 10^6bits/sec
183
184 129024 65507 2.00 3673 0 961.87
185 131072 2.00 3673 961.87
186 """
187
188 line_tokens = output.splitlines()[5].split()
189 return float(line_tokens[5]), int(line_tokens[4])
190
191
192 def process_request_response(self, output):
193 """Parses the following which works for both rr (TCP and UDP) and crr
194 tests and returns a singleton containing transfer rate.
195
196 TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to kcqz13.prod.google.com (10.75.222.13) port 0 AF_INET
197 Local /Remote
198 Socket Size Request Resp. Elapsed Trans.
199 Send Recv Size Size Time Rate
200 bytes Bytes bytes bytes secs. per sec
201
202 16384 87380 1 1 2.00 14118.53
203 16384 87380
204 """
205
206 return float(output.splitlines()[6].split()[5]),