netperf2.py revision 865ee82c4d530f88d8c41ca934920ad6d85bd019
1865ee82c4d530f88d8c41ca934920ad6d85bd019mblighimport os,time 29f8579202a07a123a3f73c1eb2211d8fe9553b11mblighfrom autotest_lib.client.bin import test, autotest_utils 39f8579202a07a123a3f73c1eb2211d8fe9553b11mblighfrom autotest_lib.client.common_lib import utils, error 49f8579202a07a123a3f73c1eb2211d8fe9553b11mbligh 556a91f076c57a1cfbbbcf9663af1a6e35d949ba4mbligh 656a91f076c57a1cfbbbcf9663af1a6e35d949ba4mblighclass netperf2(test.test): 7a5630a5382d4b04a02728684aebec3dce984e2bfmbligh version = 2 80afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 9a5630a5382d4b04a02728684aebec3dce984e2bfmbligh # ftp://ftp.netperf.org/netperf/netperf-2.4.4.tar.gz 10a5630a5382d4b04a02728684aebec3dce984e2bfmbligh def setup(self, tarball = 'netperf-2.4.4.tar.gz'): 118b352856e457518fde6bab947d8fcdb3f53a39admbligh tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir) 120afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski autotest_utils.extract_tarball_to_dir(tarball, self.srcdir) 130afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski os.chdir(self.srcdir) 140afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 150afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski utils.system('./configure') 160afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski utils.system('make') 170afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 180afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 190afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski def initialize(self): 20a5630a5382d4b04a02728684aebec3dce984e2bfmbligh self.job.require_gcc() 21a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 22a5630a5382d4b04a02728684aebec3dce984e2bfmbligh self.server_path = '%s&' % os.path.join(self.srcdir, 23a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 'src/netserver') 24a5630a5382d4b04a02728684aebec3dce984e2bfmbligh # Add server_ip and arguments later 25a5630a5382d4b04a02728684aebec3dce984e2bfmbligh self.client_path = '%s %%s %%s' % os.path.join(self.srcdir, 26a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 'src/netperf -H') 27a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 28b405b98fa552b9fc15b17ce11660f6b7034b11c1mbligh self.valid_tests = ['TCP_STREAM', 'TCP_RR', 'TCP_CRR', 'TCP_SENDFILE', 2952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 'UDP_STREAM', 'UDP_RR'] 30a5630a5382d4b04a02728684aebec3dce984e2bfmbligh self.results = [] 31865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh self.actual_times = [] 320afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 330afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 34a5630a5382d4b04a02728684aebec3dce984e2bfmbligh def run_once(self, server_ip, client_ip, role, test='TCP_STREAM', 35a5630a5382d4b04a02728684aebec3dce984e2bfmbligh test_time=10, stream_list=[1]): 36a5630a5382d4b04a02728684aebec3dce984e2bfmbligh if test not in self.valid_tests: 37a5630a5382d4b04a02728684aebec3dce984e2bfmbligh raise error.TestError('invalid test specified') 38a5630a5382d4b04a02728684aebec3dce984e2bfmbligh self.role = role 3952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh self.test = test 40865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh self.test_time = test_time 4152fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh self.stream_list = stream_list 42a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 430afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski server_tag = server_ip + '#netperf-server' 440afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski client_tag = client_ip + '#netperf-client' 450afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski all = [server_tag, client_tag] 46a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 47a5630a5382d4b04a02728684aebec3dce984e2bfmbligh for num_streams in stream_list: 48a5630a5382d4b04a02728684aebec3dce984e2bfmbligh if role == 'server': 49a5630a5382d4b04a02728684aebec3dce984e2bfmbligh self.server_start() 50a5630a5382d4b04a02728684aebec3dce984e2bfmbligh try: 5115b8a26d5ba95adacb523305f940ca010c191ef1mbligh # Wait up to ten minutes for the client to reach this 5252fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh # point. 5315b8a26d5ba95adacb523305f940ca010c191ef1mbligh self.job.barrier(server_tag, 'start_%d' % num_streams, 5415b8a26d5ba95adacb523305f940ca010c191ef1mbligh 600).rendevous(*all) 5515b8a26d5ba95adacb523305f940ca010c191ef1mbligh # Wait up to test_time + 5 minutes for the test to 5652fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh # complete 5715b8a26d5ba95adacb523305f940ca010c191ef1mbligh self.job.barrier(server_tag, 'stop_%d' % num_streams, 5815b8a26d5ba95adacb523305f940ca010c191ef1mbligh test_time+300).rendevous(*all) 59a5630a5382d4b04a02728684aebec3dce984e2bfmbligh finally: 60a5630a5382d4b04a02728684aebec3dce984e2bfmbligh self.server_stop() 61a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 62a5630a5382d4b04a02728684aebec3dce984e2bfmbligh elif role == 'client': 6315b8a26d5ba95adacb523305f940ca010c191ef1mbligh # Wait up to ten minutes for the server to start 6415b8a26d5ba95adacb523305f940ca010c191ef1mbligh self.job.barrier(client_tag, 'start_%d' % num_streams, 6515b8a26d5ba95adacb523305f940ca010c191ef1mbligh 600).rendevous(*all) 66a5630a5382d4b04a02728684aebec3dce984e2bfmbligh self.client(server_ip, test, test_time, num_streams) 6715b8a26d5ba95adacb523305f940ca010c191ef1mbligh # Wait up to 5 minutes for the server to also reach this point 6815b8a26d5ba95adacb523305f940ca010c191ef1mbligh self.job.barrier(client_tag, 'stop_%d' % num_streams, 6915b8a26d5ba95adacb523305f940ca010c191ef1mbligh 300).rendevous(*all) 70a5630a5382d4b04a02728684aebec3dce984e2bfmbligh else: 71a5630a5382d4b04a02728684aebec3dce984e2bfmbligh raise error.TestError('invalid role specified') 720afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 730afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 740afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski def server_start(self): 7578be24a78e28a0352197593345d097a71f9e1e14mbligh utils.system('killall netserver', ignore_status=True) 76a5630a5382d4b04a02728684aebec3dce984e2bfmbligh self.results.append(utils.system_output(self.server_path, 77a5630a5382d4b04a02728684aebec3dce984e2bfmbligh retain_output=True)) 780afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 790afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 800afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski def server_stop(self): 81a5630a5382d4b04a02728684aebec3dce984e2bfmbligh utils.system('killall netserver', ignore_status=True) 820afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 830afbb6369aa5aa9a75ea67dd9e95ec4b21c0c181jadmanski 84a5630a5382d4b04a02728684aebec3dce984e2bfmbligh def client(self, server_ip, test, test_time, num_streams): 85a5630a5382d4b04a02728684aebec3dce984e2bfmbligh args = '-t %s -l %d' % (test, test_time) 86a5630a5382d4b04a02728684aebec3dce984e2bfmbligh cmd = self.client_path % (server_ip, args) 87a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 88a5630a5382d4b04a02728684aebec3dce984e2bfmbligh try: 89865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh t0 = time.time() 90a5630a5382d4b04a02728684aebec3dce984e2bfmbligh self.results.append(utils.get_cpu_percentage( 9152fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh utils.system_output_parallel, [cmd]*num_streams, 9252fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh timeout=test_time+60, retain_output=True)) 93865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh t1 = time.time() 94865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh 95865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh self.actual_times.append(t1 - t0) 96865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh 97a5630a5382d4b04a02728684aebec3dce984e2bfmbligh except error.CmdError, e: 98a5630a5382d4b04a02728684aebec3dce984e2bfmbligh """ Catch errors due to timeout, but raise others 99a5630a5382d4b04a02728684aebec3dce984e2bfmbligh The actual error string is: 100a5630a5382d4b04a02728684aebec3dce984e2bfmbligh "Command did not complete within %d seconds" 101a5630a5382d4b04a02728684aebec3dce984e2bfmbligh called in function join_bg_job in the file common_lib/utils.py 102a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 103a5630a5382d4b04a02728684aebec3dce984e2bfmbligh Looking for 'within' is probably not the best way to do this but 104a5630a5382d4b04a02728684aebec3dce984e2bfmbligh works for now""" 105a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 10652fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh if ('within' in e.additional_text 10752fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh or 'non-zero' in e.additional_text): 108a5630a5382d4b04a02728684aebec3dce984e2bfmbligh print e.additional_text 10952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh # Results are cpu%, outputs 11052fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh self.results.append((0, None)) 111865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh self.actual_times.append(1) 112a5630a5382d4b04a02728684aebec3dce984e2bfmbligh else: 113a5630a5382d4b04a02728684aebec3dce984e2bfmbligh raise 114a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 115a5630a5382d4b04a02728684aebec3dce984e2bfmbligh 116a5630a5382d4b04a02728684aebec3dce984e2bfmbligh def postprocess(self): 11752fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh if self.role == 'client': 11852fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh if len(self.stream_list) != len(self.results): 11952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh raise error.TestError('Mismatched number of results') 12052fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 12152fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh function = None 12252fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh keys = None 12352fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 12452fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh # Each of the functions return tuples in which the keys define 12552fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh # what that item in the tuple represents 126b405b98fa552b9fc15b17ce11660f6b7034b11c1mbligh if self.test in ['TCP_STREAM', 'TCP_SENDFILE']: 12752fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh function = self.process_tcp_stream 12852fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh keys = ('Throughput',) 12952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh elif self.test == 'UDP_STREAM': 13052fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh function = self.process_udp_stream 13152fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh keys = ('Throughput', 'Errors') 13252fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh elif self.test in ['TCP_RR', 'TCP_CRR', 'UDP_RR']: 13352fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh function = self.process_request_response 13452fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh keys = ('Transfer_Rate',) 13552fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh else: 13652fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh raise error.TestError('Unhandled test') 13752fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 13852fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh # self.results is a list of tuples. The first element in each 13952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh # tuple is the cpu utilization for that run, and the second 14052fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh # element is a list containing the output for each stream in that 14152fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh # run. 14252fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh for i, streams in enumerate(self.stream_list): 14352fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh attr = {'stream_count':streams} 14452fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh keyval = {} 14552fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh temp_vals = [] 14652fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh keyval['CPU'], outputs = self.results[i] 147865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh actual_time = self.actual_times[i] 14852fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 14952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh # Short circuit to handle errors due to client timeouts 15052fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh if not outputs: 15152fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh self.write_iteration_keyval(attr, keyval) 15252fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh continue 15352fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 15452fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh for result in outputs: 15552fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh temp_vals.append(function(result)) 15652fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 1576d858fa16693074e41b51b8068aa0d5a670c6e56mbligh # Compute the sum of elements returned from function which 15852fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh # represent the string contained in keys 15952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh for j, key in enumerate(keys): 16052fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh vals = [x[j] for x in temp_vals] 161865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh # scale result by the actual time taken 162865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh keyval[key] = sum(vals)*self.test_time/actual_time 163865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh 164865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh # record 'Efficiency' as perf/CPU 165865ee82c4d530f88d8c41ca934920ad6d85bd019mbligh keyval['Efficieny'] = keyval[keys[0]]/keyval['CPU'] 16652fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 16752fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh self.write_iteration_keyval(attr, keyval) 16852fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 16952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 17052fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh def process_tcp_stream(self, output): 171b405b98fa552b9fc15b17ce11660f6b7034b11c1mbligh """Parses the following (works for both TCP_STREAM and TCP_SENDFILE) 172b405b98fa552b9fc15b17ce11660f6b7034b11c1mbligh and returns a singleton containing throughput. 17352fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 17452fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 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 17552fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh Recv Send Send 17652fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh Socket Socket Message Elapsed 17752fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh Size Size Size Time Throughput 17852fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh bytes bytes bytes secs. 10^6bits/sec 17952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 18052fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 87380 16384 16384 2.00 941.28 18152fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh """ 18252fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 18352fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh return float(output.splitlines()[6].split()[4]), 18452fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 18552fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 18652fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh def process_udp_stream(self, output): 18752fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh """Parses the following and returns a touple containing throughput 18852fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh and the number of errors. 18952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 19052fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 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 19152fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh Socket Message Elapsed Messages 19252fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh Size Size Time Okay Errors Throughput 19352fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh bytes bytes secs # # 10^6bits/sec 19452fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 19552fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 129024 65507 2.00 3673 0 961.87 19652fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 131072 2.00 3673 961.87 19752fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh """ 19852fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 19952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh line_tokens = output.splitlines()[5].split() 20052fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh return float(line_tokens[5]), int(line_tokens[4]) 20152fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 20252fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 20352fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh def process_request_response(self, output): 20452fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh """Parses the following which works for both rr (TCP and UDP) and crr 20552fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh tests and returns a singleton containing transfer rate. 20652fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 20752fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 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 20852fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh Local /Remote 20952fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh Socket Size Request Resp. Elapsed Trans. 21052fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh Send Recv Size Size Time Rate 21152fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh bytes Bytes bytes bytes secs. per sec 21252fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 21352fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 16384 87380 1 1 2.00 14118.53 21452fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 16384 87380 21552fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh """ 21652fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh 21752fa69285dbeb9e9a0d49de4b1e12b52cda39fc6mbligh return float(output.splitlines()[6].split()[5]), 218