blob: a7e6105d419014ccc61b6122448e9397f720e1c5 [file] [log] [blame]
Roger Meier40cc2322014-06-11 11:09:14 +02001#!/usr/bin/env python
2
3#
4# Licensed to the Apache Software Foundation (ASF) under one
5# or more contributor license agreements. See the NOTICE file
6# distributed with this work for additional information
7# regarding copyright ownership. The ASF licenses this file
8# to you under the Apache License, Version 2.0 (the
9# "License"); you may not use this file except in compliance
10# with the License. You may obtain a copy of the License at
11#
12# http://www.apache.org/licenses/LICENSE-2.0
13#
14# Unless required by applicable law or agreed to in writing,
15# software distributed under the License is distributed on an
16# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17# KIND, either express or implied. See the License for the
18# specific language governing permissions and limitations
19# under the License.
20#
21
22from __future__ import division
23import time
24import socket
25import subprocess
26import sys
27import os
28import signal
29import json
cdwijayarathna75eb2a32014-07-28 21:54:56 +053030import platform
Roger Meier32f39822014-06-18 22:43:17 +020031import shutil
32import threading
Roger Meier40cc2322014-06-11 11:09:14 +020033from optparse import OptionParser
34
35parser = OptionParser()
36parser.add_option("--port", type="int", dest="port", default=9090,
37 help="port number for server to listen on")
38parser.add_option('-v', '--verbose', action="store_const",
39 dest="verbose", const=2,
40 help="verbose output")
41parser.add_option('-q', '--quiet', action="store_const",
42 dest="verbose", const=0,
43 help="minimal output")
cdwijayarathnad1041652014-08-15 23:42:20 +053044parser.add_option("--server", type="string", dest="servers", default="",
45 help="list of servers to test seperated by commas, eg:- --server=cpp,java")
46parser.add_option("--client", type="string", dest="clients", default="",
47 help="list of clients to test seperated by commas, eg:- --client=cpp,java")
Roger Meier40cc2322014-06-11 11:09:14 +020048parser.set_defaults(verbose=1)
49options, args = parser.parse_args()
50
cdwijayarathnad1041652014-08-15 23:42:20 +053051if options.servers == "":
52 serversList = []
53else:
54 serversList = options.servers.split(",")
55if options.clients == "":
56 clientsList = []
57else:
58 clientsList = options.clients.split(",")
59
Roger Meier40cc2322014-06-11 11:09:14 +020060def relfile(fname):
61 return os.path.join(os.path.dirname(__file__), fname)
62
cdwijayarathna3f679782014-07-09 14:00:33 +053063def getSocketArgs(socket_type):
64 if socket_type == 'ip':
65 return ""
66 elif socket_type == 'ip-ssl':
67 return "--ssl"
68 elif socket_type == 'domain':
69 return "--domain-socket=/tmp/ThriftTest.thrift"
70
Roger Meiere8bafb62014-08-01 23:39:32 +020071def runServiceTest(test_name, server_lib, server_executable, server_extra_args, client_lib, client_executable, client_extra_args, server_protocol, client_protocol, transport, port, use_zlib, socket_type):
Roger Meier40cc2322014-06-11 11:09:14 +020072 # Build command line arguments
Roger Meiere8bafb62014-08-01 23:39:32 +020073 server_args = []
74 cli_args = []
75 if server_lib == 'java':
cdwijayarathna0d4072b2014-08-09 21:32:21 +053076 server_args.append(server_executable[0])
77 server_args.append(server_executable[1])
78 server_args.append(relfile(server_executable[2]))
Roger Meiere8bafb62014-08-01 23:39:32 +020079 server_args.extend(['-Dtestargs','\"'])
80 else:
81 server_args = [relfile(server_executable)]
82 if client_lib == 'java':
cdwijayarathna0d4072b2014-08-09 21:32:21 +053083 cli_args.append(client_executable[0])
84 cli_args.append(client_executable[1])
85 cli_args.append(relfile(client_executable[2]))
Roger Meiere8bafb62014-08-01 23:39:32 +020086 cli_args.extend(['-Dtestargs','\"'])
87 else:
88 cli_args = [relfile(client_executable)]
89
cdwijayarathna3f679782014-07-09 14:00:33 +053090 server_args.append('--protocol=%s' % server_protocol)
91 cli_args.append('--protocol=%s' % client_protocol)
92
Roger Meier40cc2322014-06-11 11:09:14 +020093 for which in (server_args, cli_args):
Roger Meier40cc2322014-06-11 11:09:14 +020094 which.append('--transport=%s' % transport)
95 which.append('--port=%d' % port) # default to 9090
96 if use_zlib:
97 which.append('--zlib')
cdwijayarathna3f679782014-07-09 14:00:33 +053098 if socket_type == 'ip-ssl':
Roger Meier40cc2322014-06-11 11:09:14 +020099 which.append('--ssl')
cdwijayarathna3f679782014-07-09 14:00:33 +0530100 elif socket_type == 'domain':
101 which.append('--domain-socket=/tmp/ThriftTest.thrift')
Roger Meier40cc2322014-06-11 11:09:14 +0200102# if options.verbose == 0:
103# which.append('-q')
104# if options.verbose == 2:
105# which.append('-v')
Roger Meiere8bafb62014-08-01 23:39:32 +0200106 if server_lib == 'java':
107 server_args.append('\"')
108 if client_lib == 'java':
109 cli_args.append('\"')
Roger Meier40cc2322014-06-11 11:09:14 +0200110
111 server_args.extend(server_extra_args)
112 cli_args.extend(client_extra_args)
Roger Meiere8bafb62014-08-01 23:39:32 +0200113
cdwijayarathna0d4072b2014-08-09 21:32:21 +0530114 server_log=open(relfile("log/" + test_name + "_server.log"),"a")
115 client_log=open(relfile("log/" + test_name + "_client.log"),"a")
Roger Meier40cc2322014-06-11 11:09:14 +0200116
cdwijayarathna11066bd2014-07-26 23:02:13 +0530117 try:
118 if options.verbose > 0:
119 print 'Testing server: %s' % (' '.join(server_args))
120 serverproc = subprocess.Popen(server_args, stdout=server_log, stderr=server_log)
121 else:
122 serverproc = subprocess.Popen(server_args, stdout=server_log, stderr=server_log)
123 except OSError as e:
124 return "OS error({0}): {1}".format(e.errno, e.strerror)
cdwijayarathna3f679782014-07-09 14:00:33 +0530125
Roger Meier40cc2322014-06-11 11:09:14 +0200126 def ensureServerAlive():
127 if serverproc.poll() is not None:
cdwijayarathna11066bd2014-07-26 23:02:13 +0530128 return 'Server subprocess died, args: %s' % (' '.join(server_args))
Roger Meier40cc2322014-06-11 11:09:14 +0200129
130 # Wait for the server to start accepting connections on the given port.
131 sock = socket.socket()
132 sleep_time = 0.1 # Seconds
133 max_attempts = 100
134 try:
135 attempt = 0
cdwijayarathna3f679782014-07-09 14:00:33 +0530136
137 if socket_type != 'domain':
138 while sock.connect_ex(('127.0.0.1', port)) != 0:
139 attempt += 1
140 if attempt >= max_attempts:
cdwijayarathna11066bd2014-07-26 23:02:13 +0530141 return "TestServer not ready on port %d after %.2f seconds" % (port, sleep_time * attempt)
cdwijayarathna3f679782014-07-09 14:00:33 +0530142 ensureServerAlive()
143 time.sleep(sleep_time)
Roger Meier40cc2322014-06-11 11:09:14 +0200144 finally:
145 sock.close()
146
147 try:
Roger Meier32f39822014-06-18 22:43:17 +0200148 o = []
149 def target():
cdwijayarathna11066bd2014-07-26 23:02:13 +0530150 try:
151 if options.verbose > 0:
152 print 'Testing client: %s' % (' '.join(cli_args))
153 process = subprocess.Popen(cli_args, stdout=client_log, stderr=client_log)
154 o.append(process)
155 process.communicate()
156 else:
157 process = subprocess.Popen(cli_args, stdout=client_log, stderr=client_log)
158 o.append(process)
159 process.communicate()
160 except OSError as e:
161 return "OS error({0}): {1}".format(e.errno, e.strerror)
162 except:
163 return "Unexpected error:", sys.exc_info()[0]
Roger Meier32f39822014-06-18 22:43:17 +0200164 thread = threading.Thread(target=target)
165 thread.start()
166
167 thread.join(10)
168 if thread.is_alive():
169 print 'Terminating process'
170 o[0].terminate()
171 thread.join()
cdwijayarathna11066bd2014-07-26 23:02:13 +0530172 if(len(o)==0):
173 return "Client subprocess failed, args: %s" % (' '.join(cli_args))
Roger Meier32f39822014-06-18 22:43:17 +0200174 ret = o[0].returncode
Roger Meier40cc2322014-06-11 11:09:14 +0200175 if ret != 0:
176 return "Client subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(cli_args))
177 #raise Exception("Client subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(cli_args)))
178 finally:
179 # check that server didn't die
Roger Meier32f39822014-06-18 22:43:17 +0200180 #ensureServerAlive()
Roger Meier40cc2322014-06-11 11:09:14 +0200181 extra_sleep = 0
182 if extra_sleep > 0 and options.verbose > 0:
183 print ('Giving (protocol=%s,zlib=%s,ssl=%s) an extra %d seconds for child'
184 'processes to terminate via alarm'
185 % (protocol, use_zlib, use_ssl, extra_sleep))
186 time.sleep(extra_sleep)
cdwijayarathna0d4072b2014-08-09 21:32:21 +0530187 os.kill(serverproc.pid, signal.SIGTERM)
188 #serverproc.wait()
Roger Meier32f39822014-06-18 22:43:17 +0200189 client_log.flush()
190 server_log.flush()
191 client_log.close()
192 server_log.close()
Roger Meier40cc2322014-06-11 11:09:14 +0200193
194test_count = 0
195failed = 0
cdwijayarathna0d4072b2014-08-09 21:32:21 +0530196hard_fail_count = 0
cdwijayarathna75eb2a32014-07-28 21:54:56 +0530197platform = platform.system()
cdwijayarathna0d4072b2014-08-09 21:32:21 +0530198if os.path.exists(relfile('log')): shutil.rmtree(relfile('log'))
199os.makedirs(relfile('log'))
200if os.path.exists(relfile('results.json')): os.remove(relfile('results.json'))
201results_json = open(relfile("results.json"),"a")
cdwijayarathna3f679782014-07-09 14:00:33 +0530202results_json.write("[\n")
Roger Meier32f39822014-06-18 22:43:17 +0200203
cdwijayarathna0d4072b2014-08-09 21:32:21 +0530204with open(relfile('tests.json')) as data_file:
Roger Meier40cc2322014-06-11 11:09:14 +0200205 data = json.load(data_file)
206
Roger Meier32f39822014-06-18 22:43:17 +0200207#subprocess.call("export NODE_PATH=../lib/nodejs/test:../lib/nodejs/lib:${NODE_PATH}")
cdwijayarathna3f679782014-07-09 14:00:33 +0530208count = 0
Roger Meier40cc2322014-06-11 11:09:14 +0200209for server in data["server"]:
cdwijayarathnad1041652014-08-15 23:42:20 +0530210 if (server["lib"] in serversList or len(serversList) == 0) and platform in server["platform"]:
211 server_executable = server["executable"]
212 server_extra_args = ""
213 server_lib = server["lib"]
214 if "extra_args" in server:
215 server_extra_args = server["extra_args"]
216 for protocol in server["protocols"]:
217 for transport in server["transports"]:
218 for sock in server["sockets"]:
219 for client in data["client"]:
220 if (client["lib"] in clientsList or len(clientsList) == 0) and platform in client["platform"]:
221 client_executable = client["executable"]
222 client_extra_args = ""
223 client_lib = client["lib"]
224 if "extra_args" in client:
225 client_extra_args = client["extra_args"]
226 if protocol in client["protocols"]:
227 if transport in client["transports"]:
228 if sock in client["sockets"]:
229 if count != 0:
230 results_json.write(",\n")
231 count = 1
232 results_json.write("\t[\n\t\t\"" + server_lib + "\",\n\t\t\"" + client_lib + "\",\n\t\t\"" + protocol + "\",\n\t\t\"" + transport + "-" + sock + "\",\n" )
233 test_name = server_lib + "_" + client_lib + "_" + protocol + "_" + transport + "_" + sock
cdwijayarathna9ea3d2e2014-08-16 17:28:40 +0530234 ret = runServiceTest(test_name, server_lib, server_executable, server_extra_args, client_lib, client_executable, client_extra_args, protocol, protocol, transport, options.port, 0, sock)
cdwijayarathnad1041652014-08-15 23:42:20 +0530235 if ret != None:
236 failed += 1
237 if client["exit"] == "hard" and server["exit"] == "hard":
238 hard_fail_count +=1
239 print "Error: %s" % ret
240 print "Using"
241 print (' Server: %s --protocol=%s --transport=%s %s %s'
242 % (server_executable, protocol, transport, getSocketArgs(sock), ' '.join(server_extra_args)))
243 print (' Client: %s --protocol=%s --transport=%s %s %s'
244 % (client_executable, protocol, transport, getSocketArgs(sock), ''.join(client_extra_args)))
245 results_json.write("\t\t\"failure\",\n")
246 else:
247 results_json.write("\t\t\"success\",\n")
248 results_json.write("\t\t{\n\t\t\t\"Client\":\"log/" + test_name + "_client.log\",\n\t\t\t\"Server\":\"log/" + test_name + "_server.log\"\n\t\t}\n\t]")
249 test_count += 1
250 if protocol == 'binary' and 'accel' in client["protocols"]:
251 if transport in client["transports"]:
252 if sock in client["sockets"]:
253 if count != 0:
254 results_json.write(",\n")
255 count = 1
256 results_json.write("\t[\n\t\t\"" + server_lib + "\",\n\t\t\"" + client_lib + "\",\n\t\t\"accel-binary\",\n\t\t\"" + transport + "-" + sock + "\",\n" )
257 test_name = server_lib + "_" + client_lib + "_accel-binary_" + transport + "_" + sock
cdwijayarathna9ea3d2e2014-08-16 17:28:40 +0530258 ret = runServiceTest(test_name, server_lib,server_executable, server_extra_args, client_lib, client_executable, client_extra_args, protocol, 'accel', transport, options.port, 0, sock)
Roger Meiere8bafb62014-08-01 23:39:32 +0200259
cdwijayarathnad1041652014-08-15 23:42:20 +0530260 if ret != None:
261 failed += 1
262 if client["exit"] == "hard" and server["exit"] == "hard":
263 hard_fail_count +=1
264 print "Error: %s" % ret
265 print "Using"
266 print (' Server: %s --protocol=%s --transport=%s %s %s'
267 % (server_executable, protocol, transport, getSocketArgs(sock), ' '.join(server_extra_args)))
268 print (' Client: %s --protocol=%s --transport=%s %s %s'
269 % (client_executable, protocol, transport , getSocketArgs(sock), ''.join(client_extra_args)))
270 results_json.write("\t\t\"failure\",\n")
271 else:
272 results_json.write("\t\t\"success\",\n")
273 results_json.write("\t\t{\n\t\t\t\"Client\":\"log/" + test_name + "_client.log\",\n\t\t\t\"Server\":\"log/" + test_name + "_server.log\"\n\t\t}\n\t]")
274 test_count += 1
275 if protocol == 'accel' and 'binary' in client["protocols"]:
276 if transport in client["transports"]:
277 if sock in client["sockets"]:
278 if count != 0:
279 results_json.write(",\n")
280 count = 1
281 results_json.write("\t[\n\t\t\"" + server_lib + "\",\n\t\t\"" + client_lib + "\",\n\t\t\"binary-accel\",\n\t\t\"" + transport + "-" + sock + "\",\n" )
282 test_name = server_lib + "_" + client_lib + "_binary-accel_" + transport + "_" + sock
cdwijayarathna9ea3d2e2014-08-16 17:28:40 +0530283 ret = runServiceTest(test_name, server_lib,server_executable, server_extra_args, client_lib, client_executable, client_extra_args, protocol, 'binary', transport, options.port, 0, sock)
cdwijayarathnad1041652014-08-15 23:42:20 +0530284 if ret != None:
285 failed += 1
286 if client["exit"] == "hard" and server["exit"] == "hard":
287 hard_fail_count +=1
288 print "Error: %s" % ret
289 print "Using"
290 print (' Server: %s --protocol=%s --transport=%s %s %s'
291 % (server_executable, protocol, transport + sock, getSocketArgs(sock), ' '.join(server_extra_args)))
292 print (' Client: %s --protocol=%s --transport=%s %s %s'
293 % (client_executable, protocol, transport + sock, getSocketArgs(sock), ''.join(client_extra_args)))
294 results_json.write("\t\t\"failure\",\n")
295 else:
296 results_json.write("\t\t\"success\",\n")
297 results_json.write("\t\t{\n\t\t\t\"Client\":\"log/" + test_name + "_client.log\",\n\t\t\t\"Server\":\"log/" + test_name + "_server.log\"\n\t\t}\n\t]")
298 test_count += 1
cdwijayarathna3f679782014-07-09 14:00:33 +0530299results_json.write("\n]")
300results_json.flush()
301results_json.close()
cdwijayarathna0d4072b2014-08-09 21:32:21 +0530302print '%s failed of %s tests in total' % (failed, test_count)
303sys.exit(hard_fail_count)