blob: 0eb22c3e58d767c3ff3cad582e5a98c5d11e50f2 [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")
44parser.set_defaults(verbose=1)
45options, args = parser.parse_args()
46
47def relfile(fname):
48 return os.path.join(os.path.dirname(__file__), fname)
49
cdwijayarathna3f679782014-07-09 14:00:33 +053050def getSocketArgs(socket_type):
51 if socket_type == 'ip':
52 return ""
53 elif socket_type == 'ip-ssl':
54 return "--ssl"
55 elif socket_type == 'domain':
56 return "--domain-socket=/tmp/ThriftTest.thrift"
57
58def 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 +020059 # Build command line arguments
60 server_args = [relfile(server_executable)]
61 cli_args = [relfile(client_executable)]
cdwijayarathna3f679782014-07-09 14:00:33 +053062 server_args.append('--protocol=%s' % server_protocol)
63 cli_args.append('--protocol=%s' % client_protocol)
64
Roger Meier40cc2322014-06-11 11:09:14 +020065 for which in (server_args, cli_args):
Roger Meier40cc2322014-06-11 11:09:14 +020066 which.append('--transport=%s' % transport)
67 which.append('--port=%d' % port) # default to 9090
68 if use_zlib:
69 which.append('--zlib')
cdwijayarathna3f679782014-07-09 14:00:33 +053070 if socket_type == 'ip-ssl':
Roger Meier40cc2322014-06-11 11:09:14 +020071 which.append('--ssl')
cdwijayarathna3f679782014-07-09 14:00:33 +053072 elif socket_type == 'domain':
73 which.append('--domain-socket=/tmp/ThriftTest.thrift')
Roger Meier40cc2322014-06-11 11:09:14 +020074# if options.verbose == 0:
75# which.append('-q')
76# if options.verbose == 2:
77# which.append('-v')
78
79 server_args.extend(server_extra_args)
80 cli_args.extend(client_extra_args)
Roger Meier32f39822014-06-18 22:43:17 +020081 server_log=open("log/" + test_name + "_server.log","a")
82 client_log=open("log/" + test_name + "_client.log","a")
Roger Meier40cc2322014-06-11 11:09:14 +020083
cdwijayarathna11066bd2014-07-26 23:02:13 +053084 try:
85 if options.verbose > 0:
86 print 'Testing server: %s' % (' '.join(server_args))
87 serverproc = subprocess.Popen(server_args, stdout=server_log, stderr=server_log)
88 else:
89 serverproc = subprocess.Popen(server_args, stdout=server_log, stderr=server_log)
90 except OSError as e:
91 return "OS error({0}): {1}".format(e.errno, e.strerror)
cdwijayarathna3f679782014-07-09 14:00:33 +053092
Roger Meier40cc2322014-06-11 11:09:14 +020093 def ensureServerAlive():
94 if serverproc.poll() is not None:
cdwijayarathna11066bd2014-07-26 23:02:13 +053095 return 'Server subprocess died, args: %s' % (' '.join(server_args))
Roger Meier40cc2322014-06-11 11:09:14 +020096
97 # Wait for the server to start accepting connections on the given port.
98 sock = socket.socket()
99 sleep_time = 0.1 # Seconds
100 max_attempts = 100
101 try:
102 attempt = 0
cdwijayarathna3f679782014-07-09 14:00:33 +0530103
104 if socket_type != 'domain':
105 while sock.connect_ex(('127.0.0.1', port)) != 0:
106 attempt += 1
107 if attempt >= max_attempts:
cdwijayarathna11066bd2014-07-26 23:02:13 +0530108 return "TestServer not ready on port %d after %.2f seconds" % (port, sleep_time * attempt)
cdwijayarathna3f679782014-07-09 14:00:33 +0530109 ensureServerAlive()
110 time.sleep(sleep_time)
Roger Meier40cc2322014-06-11 11:09:14 +0200111 finally:
112 sock.close()
113
114 try:
Roger Meier32f39822014-06-18 22:43:17 +0200115 o = []
116 def target():
cdwijayarathna11066bd2014-07-26 23:02:13 +0530117 try:
118 if options.verbose > 0:
119 print 'Testing client: %s' % (' '.join(cli_args))
120 process = subprocess.Popen(cli_args, stdout=client_log, stderr=client_log)
121 o.append(process)
122 process.communicate()
123 else:
124 process = subprocess.Popen(cli_args, stdout=client_log, stderr=client_log)
125 o.append(process)
126 process.communicate()
127 except OSError as e:
128 return "OS error({0}): {1}".format(e.errno, e.strerror)
129 except:
130 return "Unexpected error:", sys.exc_info()[0]
Roger Meier32f39822014-06-18 22:43:17 +0200131 thread = threading.Thread(target=target)
132 thread.start()
133
134 thread.join(10)
135 if thread.is_alive():
136 print 'Terminating process'
137 o[0].terminate()
138 thread.join()
cdwijayarathna11066bd2014-07-26 23:02:13 +0530139 if(len(o)==0):
140 return "Client subprocess failed, args: %s" % (' '.join(cli_args))
Roger Meier32f39822014-06-18 22:43:17 +0200141 ret = o[0].returncode
Roger Meier40cc2322014-06-11 11:09:14 +0200142 if ret != 0:
143 return "Client subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(cli_args))
144 #raise Exception("Client subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(cli_args)))
145 finally:
146 # check that server didn't die
Roger Meier32f39822014-06-18 22:43:17 +0200147 #ensureServerAlive()
Roger Meier40cc2322014-06-11 11:09:14 +0200148 extra_sleep = 0
149 if extra_sleep > 0 and options.verbose > 0:
150 print ('Giving (protocol=%s,zlib=%s,ssl=%s) an extra %d seconds for child'
151 'processes to terminate via alarm'
152 % (protocol, use_zlib, use_ssl, extra_sleep))
153 time.sleep(extra_sleep)
154 os.kill(serverproc.pid, signal.SIGKILL)
155 serverproc.wait()
Roger Meier32f39822014-06-18 22:43:17 +0200156 client_log.flush()
157 server_log.flush()
158 client_log.close()
159 server_log.close()
Roger Meier40cc2322014-06-11 11:09:14 +0200160
161test_count = 0
162failed = 0
cdwijayarathna75eb2a32014-07-28 21:54:56 +0530163platform = platform.system()
Roger Meier32f39822014-06-18 22:43:17 +0200164if os.path.exists('log'): shutil.rmtree('log')
165os.makedirs('log')
cdwijayarathna3f679782014-07-09 14:00:33 +0530166if os.path.exists('results.json'): os.remove('results.json')
167results_json = open("results.json","a")
168results_json.write("[\n")
Roger Meier32f39822014-06-18 22:43:17 +0200169
cdwijayarathna3f679782014-07-09 14:00:33 +0530170with open('tests.json') as data_file:
Roger Meier40cc2322014-06-11 11:09:14 +0200171 data = json.load(data_file)
172
Roger Meier32f39822014-06-18 22:43:17 +0200173#subprocess.call("export NODE_PATH=../lib/nodejs/test:../lib/nodejs/lib:${NODE_PATH}")
cdwijayarathna3f679782014-07-09 14:00:33 +0530174count = 0
Roger Meier40cc2322014-06-11 11:09:14 +0200175for server in data["server"]:
176 server_executable = server["executable"]
177 server_extra_args = ""
Roger Meier32f39822014-06-18 22:43:17 +0200178 server_lib = server["lib"]
Roger Meier40cc2322014-06-11 11:09:14 +0200179 if "extra_args" in server:
180 server_extra_args = server["extra_args"]
181 for protocol in server["protocols"]:
182 for transport in server["transports"]:
Roger Meier32f39822014-06-18 22:43:17 +0200183 for sock in server["sockets"]:
184 for client in data["client"]:
cdwijayarathna75eb2a32014-07-28 21:54:56 +0530185 if platform in server["platform"] and platform in client["platform"]:
186 client_executable = client["executable"]
187 client_extra_args = ""
188 client_lib = client["lib"]
189 if "extra_args" in client:
190 client_extra_args = client["extra_args"]
191 if protocol in client["protocols"]:
192 if transport in client["transports"]:
193 if sock in client["sockets"]:
194 if count != 0:
195 results_json.write(",\n")
196 count = 1
197 results_json.write("\t[\n\t\t\"" + server_lib + "\",\n\t\t\"" + client_lib + "\",\n\t\t\"" + protocol + "\",\n\t\t\"" + transport + "-" + sock + "\",\n" )
198 test_name = server_lib + "_" + client_lib + "_" + protocol + "_" + transport + "_" + sock
199 ret = runServiceTest(test_name, server_executable, server_extra_args, client_executable, client_extra_args, protocol, protocol, transport, 9090, 0, sock)
200 if ret != None:
201 failed += 1
202 print "Error: %s" % ret
203 print "Using"
204 print (' Server: %s --protocol=%s --transport=%s %s %s'
205 % (server_executable, protocol, transport, getSocketArgs(sock), ' '.join(server_extra_args)))
206 print (' Client: %s --protocol=%s --transport=%s %s %s'
207 % (client_executable, protocol, transport, getSocketArgs(sock), ''.join(client_extra_args)))
208 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")
209 else:
210 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")
211 results_json.write("\t]")
212 test_count += 1
213 if protocol == 'binary' and 'accel' in client["protocols"]:
214 if transport in client["transports"]:
215 if sock in client["sockets"]:
216 if count != 0:
217 results_json.write(",\n")
218 count = 1
219 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" )
220 test_name = server_lib + "_" + client_lib + "_accel-binary_" + transport + "_" + sock
221 ret = runServiceTest(test_name, server_executable, server_extra_args, client_executable, client_extra_args, protocol, 'accel', transport, 9090, 0, sock)
222 if ret != None:
223 failed += 1
224 print "Error: %s" % ret
225 print "Using"
226 print (' Server: %s --protocol=%s --transport=%s %s %s'
227 % (server_executable, protocol, transport, getSocketArgs(sock), ' '.join(server_extra_args)))
228 print (' Client: %s --protocol=%s --transport=%s %s %s'
229 % (client_executable, protocol, transport , getSocketArgs(sock), ''.join(client_extra_args)))
230 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")
231 else:
232 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")
233 results_json.write("\t]")
234 test_count += 1
235 if protocol == 'accel' and 'binary' in client["protocols"]:
236 if transport in client["transports"]:
237 if sock in client["sockets"]:
238 if count != 0:
239 results_json.write(",\n")
240 count = 1
241 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" )
242 test_name = server_lib + "_" + client_lib + "_accel-binary_" + transport + "_" + sock
243 ret = runServiceTest(test_name, server_executable, server_extra_args, client_executable, client_extra_args, protocol, 'binary', transport, 9090, 0, sock)
244 if ret != None:
245 failed += 1
246 print "Error: %s" % ret
247 print "Using"
248 print (' Server: %s --protocol=%s --transport=%s %s %s'
249 % (server_executable, protocol, transport + sock, getSocketArgs(sock), ' '.join(server_extra_args)))
250 print (' Client: %s --protocol=%s --transport=%s %s %s'
251 % (client_executable, protocol, transport + sock, getSocketArgs(sock), ''.join(client_extra_args)))
252 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")
253 else:
254 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")
255 results_json.write("\t]")
256 test_count += 1
cdwijayarathna3f679782014-07-09 14:00:33 +0530257results_json.write("\n]")
258results_json.flush()
259results_json.close()
260print '%s failed of %s tests in total' % (failed, test_count)