blob: c281ccdae6e889bd8bbf44bf6d17bb562550aa2c [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
Roger Meier32f39822014-06-18 22:43:17 +020030import shutil
31import threading
Roger Meier40cc2322014-06-11 11:09:14 +020032from optparse import OptionParser
33
34parser = OptionParser()
35parser.add_option("--port", type="int", dest="port", default=9090,
36 help="port number for server to listen on")
37parser.add_option('-v', '--verbose', action="store_const",
38 dest="verbose", const=2,
39 help="verbose output")
40parser.add_option('-q', '--quiet', action="store_const",
41 dest="verbose", const=0,
42 help="minimal output")
43parser.set_defaults(verbose=1)
44options, args = parser.parse_args()
45
46def relfile(fname):
47 return os.path.join(os.path.dirname(__file__), fname)
48
cdwijayarathna3f679782014-07-09 14:00:33 +053049def getSocketArgs(socket_type):
50 if socket_type == 'ip':
51 return ""
52 elif socket_type == 'ip-ssl':
53 return "--ssl"
54 elif socket_type == 'domain':
55 return "--domain-socket=/tmp/ThriftTest.thrift"
56
57def runServiceTest(test_name, server_executable, server_extra_args, client_executable, client_extra_args, server_protocol, client_protocol, transport, port, use_zlib, socket_type):
Roger Meier40cc2322014-06-11 11:09:14 +020058 # Build command line arguments
59 server_args = [relfile(server_executable)]
60 cli_args = [relfile(client_executable)]
cdwijayarathna3f679782014-07-09 14:00:33 +053061 server_args.append('--protocol=%s' % server_protocol)
62 cli_args.append('--protocol=%s' % client_protocol)
63
Roger Meier40cc2322014-06-11 11:09:14 +020064 for which in (server_args, cli_args):
Roger Meier40cc2322014-06-11 11:09:14 +020065 which.append('--transport=%s' % transport)
66 which.append('--port=%d' % port) # default to 9090
67 if use_zlib:
68 which.append('--zlib')
cdwijayarathna3f679782014-07-09 14:00:33 +053069 if socket_type == 'ip-ssl':
Roger Meier40cc2322014-06-11 11:09:14 +020070 which.append('--ssl')
cdwijayarathna3f679782014-07-09 14:00:33 +053071 elif socket_type == 'domain':
72 which.append('--domain-socket=/tmp/ThriftTest.thrift')
Roger Meier40cc2322014-06-11 11:09:14 +020073# if options.verbose == 0:
74# which.append('-q')
75# if options.verbose == 2:
76# which.append('-v')
77
78 server_args.extend(server_extra_args)
79 cli_args.extend(client_extra_args)
Roger Meier32f39822014-06-18 22:43:17 +020080 server_log=open("log/" + test_name + "_server.log","a")
81 client_log=open("log/" + test_name + "_client.log","a")
Roger Meier40cc2322014-06-11 11:09:14 +020082
cdwijayarathna11066bd2014-07-26 23:02:13 +053083 try:
84 if options.verbose > 0:
85 print 'Testing server: %s' % (' '.join(server_args))
86 serverproc = subprocess.Popen(server_args, stdout=server_log, stderr=server_log)
87 else:
88 serverproc = subprocess.Popen(server_args, stdout=server_log, stderr=server_log)
89 except OSError as e:
90 return "OS error({0}): {1}".format(e.errno, e.strerror)
cdwijayarathna3f679782014-07-09 14:00:33 +053091
Roger Meier40cc2322014-06-11 11:09:14 +020092 def ensureServerAlive():
93 if serverproc.poll() is not None:
cdwijayarathna11066bd2014-07-26 23:02:13 +053094 return 'Server subprocess died, args: %s' % (' '.join(server_args))
Roger Meier40cc2322014-06-11 11:09:14 +020095
96 # Wait for the server to start accepting connections on the given port.
97 sock = socket.socket()
98 sleep_time = 0.1 # Seconds
99 max_attempts = 100
100 try:
101 attempt = 0
cdwijayarathna3f679782014-07-09 14:00:33 +0530102
103 if socket_type != 'domain':
104 while sock.connect_ex(('127.0.0.1', port)) != 0:
105 attempt += 1
106 if attempt >= max_attempts:
cdwijayarathna11066bd2014-07-26 23:02:13 +0530107 return "TestServer not ready on port %d after %.2f seconds" % (port, sleep_time * attempt)
cdwijayarathna3f679782014-07-09 14:00:33 +0530108 ensureServerAlive()
109 time.sleep(sleep_time)
Roger Meier40cc2322014-06-11 11:09:14 +0200110 finally:
111 sock.close()
112
113 try:
Roger Meier32f39822014-06-18 22:43:17 +0200114 o = []
115 def target():
cdwijayarathna11066bd2014-07-26 23:02:13 +0530116 try:
117 if options.verbose > 0:
118 print 'Testing client: %s' % (' '.join(cli_args))
119 process = subprocess.Popen(cli_args, stdout=client_log, stderr=client_log)
120 o.append(process)
121 process.communicate()
122 else:
123 process = subprocess.Popen(cli_args, stdout=client_log, stderr=client_log)
124 o.append(process)
125 process.communicate()
126 except OSError as e:
127 return "OS error({0}): {1}".format(e.errno, e.strerror)
128 except:
129 return "Unexpected error:", sys.exc_info()[0]
Roger Meier32f39822014-06-18 22:43:17 +0200130 thread = threading.Thread(target=target)
131 thread.start()
132
133 thread.join(10)
134 if thread.is_alive():
135 print 'Terminating process'
136 o[0].terminate()
137 thread.join()
cdwijayarathna11066bd2014-07-26 23:02:13 +0530138 if(len(o)==0):
139 return "Client subprocess failed, args: %s" % (' '.join(cli_args))
Roger Meier32f39822014-06-18 22:43:17 +0200140 ret = o[0].returncode
Roger Meier40cc2322014-06-11 11:09:14 +0200141 if ret != 0:
142 return "Client subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(cli_args))
143 #raise Exception("Client subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(cli_args)))
144 finally:
145 # check that server didn't die
Roger Meier32f39822014-06-18 22:43:17 +0200146 #ensureServerAlive()
Roger Meier40cc2322014-06-11 11:09:14 +0200147 extra_sleep = 0
148 if extra_sleep > 0 and options.verbose > 0:
149 print ('Giving (protocol=%s,zlib=%s,ssl=%s) an extra %d seconds for child'
150 'processes to terminate via alarm'
151 % (protocol, use_zlib, use_ssl, extra_sleep))
152 time.sleep(extra_sleep)
153 os.kill(serverproc.pid, signal.SIGKILL)
154 serverproc.wait()
Roger Meier32f39822014-06-18 22:43:17 +0200155 client_log.flush()
156 server_log.flush()
157 client_log.close()
158 server_log.close()
Roger Meier40cc2322014-06-11 11:09:14 +0200159
160test_count = 0
161failed = 0
162
Roger Meier32f39822014-06-18 22:43:17 +0200163if os.path.exists('log'): shutil.rmtree('log')
164os.makedirs('log')
cdwijayarathna3f679782014-07-09 14:00:33 +0530165if os.path.exists('results.json'): os.remove('results.json')
166results_json = open("results.json","a")
167results_json.write("[\n")
Roger Meier32f39822014-06-18 22:43:17 +0200168
cdwijayarathna3f679782014-07-09 14:00:33 +0530169with open('tests.json') as data_file:
Roger Meier40cc2322014-06-11 11:09:14 +0200170 data = json.load(data_file)
171
Roger Meier32f39822014-06-18 22:43:17 +0200172#subprocess.call("export NODE_PATH=../lib/nodejs/test:../lib/nodejs/lib:${NODE_PATH}")
cdwijayarathna3f679782014-07-09 14:00:33 +0530173count = 0
Roger Meier40cc2322014-06-11 11:09:14 +0200174for server in data["server"]:
175 server_executable = server["executable"]
176 server_extra_args = ""
Roger Meier32f39822014-06-18 22:43:17 +0200177 server_lib = server["lib"]
Roger Meier40cc2322014-06-11 11:09:14 +0200178 if "extra_args" in server:
179 server_extra_args = server["extra_args"]
180 for protocol in server["protocols"]:
181 for transport in server["transports"]:
Roger Meier32f39822014-06-18 22:43:17 +0200182 for sock in server["sockets"]:
183 for client in data["client"]:
184 client_executable = client["executable"]
185 client_extra_args = ""
186 client_lib = client["lib"]
187 if "extra_args" in client:
188 client_extra_args = client["extra_args"]
189 if protocol in client["protocols"]:
190 if transport in client["transports"]:
191 if sock in client["sockets"]:
cdwijayarathna3f679782014-07-09 14:00:33 +0530192 if count != 0:
193 results_json.write(",\n")
194 count = 1
195 results_json.write("\t[\n\t\t\"" + server_lib + "\",\n\t\t\"" + client_lib + "\",\n\t\t\"" + protocol + "\",\n\t\t\"" + transport + "-" + sock + "\",\n" )
Roger Meier32f39822014-06-18 22:43:17 +0200196 test_name = server_lib + "_" + client_lib + "_" + protocol + "_" + transport + "_" + sock
cdwijayarathna3f679782014-07-09 14:00:33 +0530197 ret = runServiceTest(test_name, server_executable, server_extra_args, client_executable, client_extra_args, protocol, protocol, transport, 9090, 0, sock)
Roger Meier32f39822014-06-18 22:43:17 +0200198 if ret != None:
199 failed += 1
200 print "Error: %s" % ret
201 print "Using"
cdwijayarathna3f679782014-07-09 14:00:33 +0530202 print (' Server: %s --protocol=%s --transport=%s %s %s'
203 % (server_executable, protocol, transport, getSocketArgs(sock), ' '.join(server_extra_args)))
204 print (' Client: %s --protocol=%s --transport=%s %s %s'
205 % (client_executable, protocol, transport, getSocketArgs(sock), ''.join(client_extra_args)))
206 results_json.write("\t\t\"failure (<a href=\\\"log/" + test_name + "_client.log\\\">client</a>, <a href=\\\"log/" + test_name + "_server.log\\\">server</a>)\"\n")
207 else:
208 results_json.write("\t\t\"success (<a href=\\\"log/" + test_name + "_client.log\\\">client</a>, <a href=\\\"log/" + test_name + "_server.log\\\">server</a>)\"\n")
209 results_json.write("\t]")
Roger Meier32f39822014-06-18 22:43:17 +0200210 test_count += 1
cdwijayarathna3f679782014-07-09 14:00:33 +0530211 if protocol == 'binary' and 'accel' in client["protocols"]:
212 if transport in client["transports"]:
213 if sock in client["sockets"]:
214 if count != 0:
215 results_json.write(",\n")
216 count = 1
217 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" )
218 test_name = server_lib + "_" + client_lib + "_accel-binary_" + transport + "_" + sock
219 ret = runServiceTest(test_name, server_executable, server_extra_args, client_executable, client_extra_args, protocol, 'accel', transport, 9090, 0, sock)
220 if ret != None:
221 failed += 1
222 print "Error: %s" % ret
223 print "Using"
224 print (' Server: %s --protocol=%s --transport=%s %s %s'
225 % (server_executable, protocol, transport, getSocketArgs(sock), ' '.join(server_extra_args)))
226 print (' Client: %s --protocol=%s --transport=%s %s %s'
227 % (client_executable, protocol, transport , getSocketArgs(sock), ''.join(client_extra_args)))
228 results_json.write("\t\t\"failure (<a href=\\\"log/" + test_name + "_client.log\\\">client</a>, <a href=\\\"log/" + test_name + "_server.log\\\">server</a>)\"\n")
229 else:
230 results_json.write("\t\t\"success (<a href=\\\"log/" + test_name + "_client.log\\\">client</a>, <a href=\\\"log/" + test_name + "_server.log\\\">server</a>)\"\n")
231 results_json.write("\t]")
232 test_count += 1
233 if protocol == 'accel' and 'binary' in client["protocols"]:
234 if transport in client["transports"]:
235 if sock in client["sockets"]:
236 if count != 0:
237 results_json.write(",\n")
238 count = 1
239 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" )
240 test_name = server_lib + "_" + client_lib + "_accel-binary_" + transport + "_" + sock
241 ssl = 0
242 if sock == 'ip-ssl':
243 ssl = 1
244 ret = runServiceTest(test_name, server_executable, server_extra_args, client_executable, client_extra_args, protocol, 'binary', transport, 9090, 0, sock)
245 if ret != None:
246 failed += 1
247 print "Error: %s" % ret
248 print "Using"
249 print (' Server: %s --protocol=%s --transport=%s %s %s'
250 % (server_executable, protocol, transport + sock, getSocketArgs(sock), ' '.join(server_extra_args)))
251 print (' Client: %s --protocol=%s --transport=%s %s %s'
252 % (client_executable, protocol, transport + sock, getSocketArgs(sock), ''.join(client_extra_args)))
253 results_json.write("\t\t\"failure (<a href=\\\"log/" + test_name + "_client.log\\\">client</a>, <a href=\\\"log/" + test_name + "_server.log\\\">server</a>)\"\n")
254 else:
255 results_json.write("\t\t\"success (<a href=\\\"log/" + test_name + "_client.log\\\">client</a>, <a href=\\\"log/" + test_name + "_server.log\\\">server</a>)\"\n")
256 results_json.write("\t]")
257 test_count += 1
258results_json.write("\n]")
259results_json.flush()
260results_json.close()
261print '%s failed of %s tests in total' % (failed, test_count)