diff options
author | Jens Geyer <jensg@apache.org> | 2014-07-28 01:25:30 +0200 |
---|---|---|
committer | Jens Geyer <jensg@apache.org> | 2014-11-09 01:58:25 +0100 |
commit | bd52f1a1dd0a45aa01c551cdb15338ff3ac82a02 (patch) | |
tree | 290ffa559ff9f596ae3561e93bb899b81f5a5fda /test/haxe | |
parent | 4712f8c2e36fabfb00cfc67a6ecf5d6de20e3c18 (diff) | |
download | thrift-bd52f1a1dd0a45aa01c551cdb15338ff3ac82a02.tar.gz |
THRIFT-2644 Haxe support
Client: Haxe
Patch: Jens Geyer
This closes #214
Diffstat (limited to 'test/haxe')
-rw-r--r-- | test/haxe/Makefile.am | 52 | ||||
-rw-r--r-- | test/haxe/cpp.hxml | 41 | ||||
-rw-r--r-- | test/haxe/csharp.hxml | 38 | ||||
-rw-r--r-- | test/haxe/flash.hxml | 41 | ||||
-rw-r--r-- | test/haxe/java.hxml | 38 | ||||
-rw-r--r-- | test/haxe/javascript.hxml | 44 | ||||
-rw-r--r-- | test/haxe/make_all.bat | 68 | ||||
-rw-r--r-- | test/haxe/make_all.sh | 41 | ||||
-rw-r--r-- | test/haxe/neko.hxml | 38 | ||||
-rw-r--r-- | test/haxe/php.hxml | 38 | ||||
-rw-r--r-- | test/haxe/project.hide | 85 | ||||
-rw-r--r-- | test/haxe/python.hxml | 38 | ||||
-rw-r--r-- | test/haxe/src/Arguments.hx | 181 | ||||
-rw-r--r-- | test/haxe/src/Main.hx | 48 | ||||
-rw-r--r-- | test/haxe/src/TestClient.hx | 696 | ||||
-rw-r--r-- | test/haxe/src/TestServer.hx | 106 | ||||
-rw-r--r-- | test/haxe/src/TestServerEventHandler.hx | 53 | ||||
-rw-r--r-- | test/haxe/src/TestServerHandler.hx | 470 |
18 files changed, 2116 insertions, 0 deletions
diff --git a/test/haxe/Makefile.am b/test/haxe/Makefile.am new file mode 100644 index 000000000..08c0369e7 --- /dev/null +++ b/test/haxe/Makefile.am @@ -0,0 +1,52 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +THRIFT = $(top_srcdir)/compiler/cpp/thrift +THRIFTCMD = $(THRIFT) --gen haxe -r +THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift + +BIN_CPP = bin/Main-debug + +gen-haxe/ThriftTest/ThriftTest.hx: $(THRIFTTEST) + $(THRIFTCMD) $(THRIFTTEST) + +all-local: $(BIN_CPP) + +$(BIN_CPP): gen-haxe/ThriftTest/ThriftTest.hx + $(HAXE) --cwd . cpp.hxml + + +#TODO: other haxe targets +# $(HAXE) --cwd . csharp +# $(HAXE) --cwd . flash +# $(HAXE) --cwd . java +# $(HAXE) --cwd . javascript +# $(HAXE) --cwd . neko +# $(HAXE) --cwd . php +# $(HAXE) --cwd . python # needs Haxe 3.1.4 + + +clean-local: + $(RM) -r gen-haxe bin + +check: $(BIN_CPP) + timeout 120 $(BIN_CPP) server & + sleep 1 + $(BIN_CPP) client + diff --git a/test/haxe/cpp.hxml b/test/haxe/cpp.hxml new file mode 100644 index 000000000..6adb52d7e --- /dev/null +++ b/test/haxe/cpp.hxml @@ -0,0 +1,41 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +#integrate files to classpath +-cp src +-cp gen-haxe +-cp ../../lib/haxe/src + +#this class wil be used as entry point for your app. +-main Main + +#CPP target +-cpp bin + +#To produce 64 bit binaries the file should define the HXCPP_M64 compile variable: +#-D HXCPP_M64 + +#Add debug information +-debug + +#dead code elimination : remove unused code +#"-dce no" : do not remove unused code +#"-dce std" : remove unused code in the std lib (default) +#"-dce full" : remove all unused code +-dce full
\ No newline at end of file diff --git a/test/haxe/csharp.hxml b/test/haxe/csharp.hxml new file mode 100644 index 000000000..295c017e7 --- /dev/null +++ b/test/haxe/csharp.hxml @@ -0,0 +1,38 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +#integrate files to classpath +-cp src +-cp gen-haxe +-cp ../../lib/haxe/src + +#this class wil be used as entry point for your app. +-main Main + +#CSHARP target +-cs bin/Tutorial.exe + +#Add debug information +-debug + +#dead code elimination : remove unused code +#"-dce no" : do not remove unused code +#"-dce std" : remove unused code in the std lib (default) +#"-dce full" : remove all unused code +-dce full
\ No newline at end of file diff --git a/test/haxe/flash.hxml b/test/haxe/flash.hxml new file mode 100644 index 000000000..a1f0568ad --- /dev/null +++ b/test/haxe/flash.hxml @@ -0,0 +1,41 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +#integrate files to classpath +-cp src +-cp gen-haxe +-cp ../../lib/haxe/src + +#this class wil be used as entry point for your app. +-main Main + +#Flash target +-swf bin/Tutorial.swf + +#Add debug information +-debug + +# we need some goodies from sys.net +# --macro allowPackage("sys") + +#dead code elimination : remove unused code +#"-dce no" : do not remove unused code +#"-dce std" : remove unused code in the std lib (default) +#"-dce full" : remove all unused code +-dce full
\ No newline at end of file diff --git a/test/haxe/java.hxml b/test/haxe/java.hxml new file mode 100644 index 000000000..c615565a9 --- /dev/null +++ b/test/haxe/java.hxml @@ -0,0 +1,38 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +#integrate files to classpath +-cp src +-cp gen-haxe +-cp ../../lib/haxe/src + +#this class wil be used as entry point for your app. +-main Main + +#Java target +-java bin/Tutorial.jar + +#Add debug information +-debug + +#dead code elimination : remove unused code +#"-dce no" : do not remove unused code +#"-dce std" : remove unused code in the std lib (default) +#"-dce full" : remove all unused code +-dce full
\ No newline at end of file diff --git a/test/haxe/javascript.hxml b/test/haxe/javascript.hxml new file mode 100644 index 000000000..b2b3876cf --- /dev/null +++ b/test/haxe/javascript.hxml @@ -0,0 +1,44 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +#integrate files to classpath +-cp src +-cp gen-haxe +-cp ../../lib/haxe/src + +#this class wil be used as entry point for your app. +-main Main + +#JavaScript target +-js bin/Tutorial.js + +#You can use -D source-map-content (requires Haxe 3.1+) to have the .hx +#files directly embedded into the map file, this way you only have to +#upload it, and it will be always in sync with the compiled .js even if +#you modify your .hx files. +-D source-map-content + +#Generate source map and add debug information +-debug + +#dead code elimination : remove unused code +#"-dce no" : do not remove unused code +#"-dce std" : remove unused code in the std lib (default) +#"-dce full" : remove all unused code +-dce full
\ No newline at end of file diff --git a/test/haxe/make_all.bat b/test/haxe/make_all.bat new file mode 100644 index 000000000..eaeba890d --- /dev/null +++ b/test/haxe/make_all.bat @@ -0,0 +1,68 @@ +@echo off +rem /* +rem * Licensed to the Apache Software Foundation (ASF) under one +rem * or more contributor license agreements. See the NOTICE file +rem * distributed with this work for additional information +rem * regarding copyright ownership. The ASF licenses this file +rem * to you under the Apache License, Version 2.0 (the +rem * "License"); you may not use this file except in compliance +rem * with the License. You may obtain a copy of the License at +rem * +rem * http://www.apache.org/licenses/LICENSE-2.0 +rem * +rem * Unless required by applicable law or agreed to in writing, +rem * software distributed under the License is distributed on an +rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +rem * KIND, either express or implied. See the License for the +rem * specific language governing permissions and limitations +rem * under the License. +rem */ + +setlocal +if "%HOMEDRIVE%"=="" goto MISSINGVARS +if "%HOMEPATH%"=="" goto MISSINGVARS +if "%HAXEPATH%"=="" goto NOTINSTALLED + +set path=%HAXEPATH%;%HAXEPATH%\..\neko;%path% + +rem # invoke Thrift comnpiler +thrift -r -gen haxe ..\ThriftTest.thrift +if errorlevel 1 goto STOP + +rem # invoke Haxe compiler for all targets +for %%a in (*.hxml) do ( + rem * filter Python, as it is not supported by Haxe 3.1.3 (but will be in 3.1.4) + if not "%%a"=="python.hxml" ( + echo -------------------------- + echo Building %%a ... + echo -------------------------- + haxe --cwd . %%a + ) +) + + +echo. +echo done. +pause +goto eof + +:NOTINSTALLED +echo FATAL: Either Haxe is not installed, or the HAXEPATH variable is not set. +pause +goto eof + +:MISSINGVARS +echo FATAL: Unable to locate home folder. +echo. +echo Both HOMEDRIVE and HOMEPATH need to be set to point to your Home folder. +echo The current values are: +echo HOMEDRIVE=%HOMEDRIVE% +echo HOMEPATH=%HOMEPATH% +pause +goto eof + +:STOP +pause +goto eof + +:eof diff --git a/test/haxe/make_all.sh b/test/haxe/make_all.sh new file mode 100644 index 000000000..262125877 --- /dev/null +++ b/test/haxe/make_all.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# invoke Thrift comnpiler +thrift -r -gen haxe ../ThriftTest.thrift + +# output folder +if [ ! -d bin ]; then + mkdir bin +fi + +# invoke Haxe compiler +for target in *.hxml; do + echo -------------------------- + echo Building ${target} ... + echo -------------------------- + if [ ! -d bin/${target} ]; then + mkdir bin/${target} + fi + haxe --cwd . ${target} +done + + +#eof diff --git a/test/haxe/neko.hxml b/test/haxe/neko.hxml new file mode 100644 index 000000000..6161f6977 --- /dev/null +++ b/test/haxe/neko.hxml @@ -0,0 +1,38 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +#integrate files to classpath +-cp src +-cp gen-haxe +-cp ../../lib/haxe/src + +#this class wil be used as entry point for your app. +-main Main + +#neko target +-neko bin/Tutorial.n + +#Add debug information +-debug + +#dead code elimination : remove unused code +#"-dce no" : do not remove unused code +#"-dce std" : remove unused code in the std lib (default) +#"-dce full" : remove all unused code +-dce full
\ No newline at end of file diff --git a/test/haxe/php.hxml b/test/haxe/php.hxml new file mode 100644 index 000000000..1eaac8b2b --- /dev/null +++ b/test/haxe/php.hxml @@ -0,0 +1,38 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +#integrate files to classpath +-cp src +-cp gen-haxe +-cp ../../lib/haxe/src + +#this class wil be used as entry point for your app. +-main Main + +#PHP target +-php bin/Tutorial.php + +#Add debug information +-debug + +#dead code elimination : remove unused code +#"-dce no" : do not remove unused code +#"-dce std" : remove unused code in the std lib (default) +#"-dce full" : remove all unused code +-dce full
\ No newline at end of file diff --git a/test/haxe/project.hide b/test/haxe/project.hide new file mode 100644 index 000000000..f09030b55 --- /dev/null +++ b/test/haxe/project.hide @@ -0,0 +1,85 @@ +{ + "type" : 0 + ,"target" : 4 + ,"name" : "Apache Thrift cross-platform test client/server" + ,"main" : null + ,"projectPackage" : "" + ,"company" : "Apache Software Foundation (ASF)" + ,"license" : "Apache License, Version 2.0" + ,"url" : "http://www.apache.org/licenses/LICENSE-2.0" + ,"targetData" : [ + { + "pathToHxml" : "flash.hxml" + ,"runActionType" : 1 + ,"runActionText" : "bin/Tutorial.swf" + } + ,{ + "pathToHxml" : "javascript.hxml" + ,"runActionType" : 1 + ,"runActionText" : "bin\\index.html" + } + ,{ + "pathToHxml" : "neko.hxml" + ,"runActionType" : 2 + ,"runActionText" : "neko bin/Tutorial.n" + } + ,{ + "pathToHxml" : "php.hxml" + } + ,{ + "pathToHxml" : "cpp.hxml" + ,"runActionType" : 2 + ,"runActionText" : "bin/Main-debug.exe client --json" + } + ,{ + "pathToHxml" : "java.hxml" + } + ,{ + "pathToHxml" : "csharp.hxml" + } + ,{ + "pathToHxml" : "python.hxml" + ,"runActionType" : 2 + ,"runActionText" : "python bin/Tutorial.py" + } + ] + ,"files" : [ + { + "path" : "src\\Arguments.hx" + ,"useTabs" : true + ,"indentSize" : 4 + ,"foldedRegions" : [ + + ] + ,"activeLine" : 159 + } + ,{ + "path" : "..\\..\\lib\\haxe\\src\\org\\apache\\thrift\\protocol\\TJSONProtocol.hx" + ,"useTabs" : true + ,"indentSize" : 4 + ,"foldedRegions" : [ + + ] + ,"activeLine" : 665 + } + ,{ + "path" : "src\\TestClient.hx" + ,"useTabs" : true + ,"indentSize" : 4 + ,"foldedRegions" : [ + + ] + ,"activeLine" : 325 + } + ] + ,"activeFile" : "..\\..\\lib\\haxe\\src\\org\\apache\\thrift\\protocol\\TJSONProtocol.hx" + ,"openFLTarget" : null + ,"openFLBuildMode" : "Debug" + ,"runActionType" : null + ,"runActionText" : null + ,"buildActionCommand" : null + ,"hiddenItems" : [ + + ] + ,"showHiddenItems" : false +}
\ No newline at end of file diff --git a/test/haxe/python.hxml b/test/haxe/python.hxml new file mode 100644 index 000000000..f2c19fa93 --- /dev/null +++ b/test/haxe/python.hxml @@ -0,0 +1,38 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +#integrate files to classpath +-cp src +-cp gen-haxe +-cp ../../lib/haxe/src + +#this class wil be used as entry point for your app. +-main Main + +#Python target +-python bin/Tutorial.py + +#Add debug information +-debug + +#dead code elimination : remove unused code +#"-dce no" : do not remove unused code +#"-dce std" : remove unused code in the std lib (default) +#"-dce full" : remove all unused code +-dce full
\ No newline at end of file diff --git a/test/haxe/src/Arguments.hx b/test/haxe/src/Arguments.hx new file mode 100644 index 000000000..bcf3793cb --- /dev/null +++ b/test/haxe/src/Arguments.hx @@ -0,0 +1,181 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package; + +import org.apache.thrift.*; +import org.apache.thrift.protocol.*; +import org.apache.thrift.transport.*; +import org.apache.thrift.server.*; +import org.apache.thrift.meta_data.*; + +using StringTools; + + +enum Prot { + binary; + json; +} + +enum Trns { + socket; + http; +} + + +class Arguments +{ + public var server(default,null) : Bool = false; + public var framed(default,null) : Bool = false; + public var buffered(default,null) : Bool = false; + public var protocol(default,null) : Prot = binary; + public var transport(default,null) : Trns = socket; + + public var host(default,null) : String = "localhost"; + public var port(default,null) : Int = 9090; + + public var numIterations(default,null) : Int = 1; + public var numThreads(default,null) : Int = 1; + + + public function new() { + #if sys + try { + ParseArgs(); + } catch (e : String) { + trace(GetHelp()); + throw e; + } + #else + trace("WN: Platform does not support program arguments, using defaults."); + #end + } + + #if sys + + private static function GetHelp() : String { + return "\n" + +Sys.executablePath()+" [client|server] [options]\n" + +"Modus: Either client or server, the default is client.\n" + +"\n" + +"Options:\n" + +" -f, --framed framed transport (supersedes buffered)\n" + +" -b, --buffered buffered transport\n" + +" --json JSON protocol\n" + +" --protocol=<prot> Choose protocol: json, binary (default binary).\n" + +" --port=<port> Port number for socket transport, default 9090\n" + +"\n" + +"Client only options:\n" + +" --host=<host> Host name, IP or URL, default localhost\n" + +" -n=<iterations> Number of test iterations\n" + +" -t=<threads> Number of test threads\n" + +" -u=<url> Target Host/URL (same as --host)\n" + +"\n" + +"All arguments are optional.\n"; + } + + + private function ParseArgs() : Void { + var step = 0; + for (arg in Sys.args()) { + + // server|client + switch(step) { + case 0: + ++step; + if ( arg == "client") + server = false; + else if ( arg == "server") + server = true; + else + throw "First argument must be 'server' or 'client'"; + + case 1: + if ( (arg == "-f") || (arg == "--framed")) { + framed = true; + } else if (( arg == "-b") || ( arg == "--buffered")) { + buffered = true; + } else if (( arg == "--json") || (arg == "--protocol=json")){ + protocol = json; + } else if (( arg == "--protocol=binary")){ + protocol = binary; + } else if (arg.startsWith("--host=")) { + ClientOnlyOption(arg); + host = arg.substr(arg.indexOf("=") + 1); + } else if (arg.startsWith("--port=")) { + var tmp = Std.parseInt(arg.substr(arg.indexOf("=")+1)); + if( tmp != null) + port = tmp; + else + throw "Invalid port number "+arg; + } else if (arg == "-n") { + ClientOnlyOption(arg); + step = 2; + } else if (arg == "-t") { + ClientOnlyOption(arg); + step = 3; + } else if (arg == "-u") { + ClientOnlyOption(arg); + step = 4; + } else { + throw "Unexpected argument "+arg; + } + + case 2: // num iterations + step = 1; + var tmp = Std.parseInt(arg); + if( tmp != null) + numIterations = tmp; + else + throw "Invalid numeric value "+arg; + + case 3: // num threads + step = 1; + var tmp = Std.parseInt(arg); + if( tmp != null) + numThreads = tmp; + else + throw "Invalid numeric value "+arg; + + case 4: // url + step = 1; + host = arg; + + default: + throw "Unexpected state"; + } + + + if ( framed && buffered) + { + trace("WN: framed supersedes buffered transport"); + } + + } + } + + #end + + + private function ClientOnlyOption( arg : String) { + if( server) { + throw "Unexpected argument in client mode: "+arg; + } + } +} diff --git a/test/haxe/src/Main.hx b/test/haxe/src/Main.hx new file mode 100644 index 000000000..a8ad147a2 --- /dev/null +++ b/test/haxe/src/Main.hx @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +package; + +import org.apache.thrift.*; +import org.apache.thrift.protocol.*; +import org.apache.thrift.transport.*; +import org.apache.thrift.server.*; +import org.apache.thrift.meta_data.*; + +import thrift.test.*; // generated code + +class Main +{ + static function main() { + try { + var args = new Arguments(); + + if (args.server) + TestServer.Execute(args); + else + TestClient.Execute(args); + + trace("Completed."); + } catch (e : String) { + trace(e); + } + } + +} diff --git a/test/haxe/src/TestClient.hx b/test/haxe/src/TestClient.hx new file mode 100644 index 000000000..8698220aa --- /dev/null +++ b/test/haxe/src/TestClient.hx @@ -0,0 +1,696 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package; + +import haxe.Int32; +import haxe.Int64; +import haxe.Timer; +import haxe.ds.IntMap; +import haxe.ds.StringMap; +import haxe.ds.ObjectMap; + +import org.apache.thrift.*; +import org.apache.thrift.helper.*; +import org.apache.thrift.protocol.*; +import org.apache.thrift.transport.*; +import org.apache.thrift.server.*; +import org.apache.thrift.meta_data.*; + +#if cpp +import cpp.vm.Thread; +#else +// no thread support (yet) +#end + +import thrift.test.*; // generated code + + +class TestResults { + private var successCnt : Int = 0; + private var errorCnt : Int = 0; + private var failedTests : String = ""; + private var print_direct : Bool = false; + + public function new(direct : Bool) { + print_direct = direct; + } + + public function Expect( expr : Bool, msg : String) : Void { + if ( expr) { + ++successCnt; + } else { + ++errorCnt; + failedTests += "\n " + msg; + if( print_direct) { + trace('FAIL: $msg'); + } + } + } + + + public function PrintSummary() : Void { + var total = successCnt + errorCnt; + var sp = (100 * successCnt) / total; + var ep = (100 * errorCnt) / total; + + trace('==========================='); + trace('Tests executed $total'); + trace('Tests succeeded $successCnt ($sp%)'); + trace('Tests failed $errorCnt ($ep%)'); + if ( errorCnt > 0) + { + trace('==========================='); + trace('FAILED TESTS: $failedTests'); + } + trace('==========================='); + } +} + + +class TestClient { + + public static function Execute(args : Arguments) : Void + { + try + { + var difft = Timer.stamp(); + + if( args.numThreads > 1) { + var threads = new List<Thread>(); + for( test in 0 ... args.numThreads) { + threads.add( StartThread( args)); + } + for( thread in threads) { + Thread.readMessage(true); + } + } else { + var rslt = new TestResults(true); + RunClient(args,rslt); + rslt.PrintSummary(); + } + + difft = Timer.stamp() - difft; + trace('total test time: $difft seconds'); + } + catch (e : TException) + { + trace('$e'); + } + catch (e : Dynamic) + { + trace('$e'); + } + } + + + private static function StartThread(args : Arguments) : Thread { + var thread = Thread.create( + function() : Void { + var main : Thread = Thread.readMessage(true); + try + { + var rslt = new TestResults(false); + RunClient(args,rslt); + // TODO: promote rslt values to main thread + } + catch (e : TException) + { + trace('$e'); + } + catch (e : Dynamic) + { + trace('$e'); + } + main.sendMessage("done"); + }); + + thread.sendMessage(Thread.current()); + return thread; + } + + + public static function RunClient(args : Arguments, rslt : TestResults) + { + var transport : TTransport = null; + switch (args.transport) + { + case socket: + transport = new TSocket(args.host, args.port); + case http: + throw "http transport not supported yet"; + //transport = new THttpClient(args.host); + default: + throw "Unhandled transport"; + } + + // optional: layered transport + if ( args.framed) { + trace("- framed transport"); + transport = new TFramedTransport(transport); + } else if ( args.buffered) { + trace("- buffered transport"); + throw "TBufferedTransport not implemented yet"; + //transport = new TBufferedTransport(transport); + } + + // protocol + var protocol : TProtocol = null; + switch( args.protocol) + { + case binary: + trace("- binary protocol"); + protocol = new TBinaryProtocol(transport); + case json: + trace("- json protocol"); + protocol = new TJSONProtocol(transport); + default: + throw "Unhandled protocol"; + } + + + // run the test code + HaxeBasicsTest( rslt); + ClientTest( transport, protocol, rslt); + + } + + + public static function HaxeBasicsTest( rslt : TestResults) : Void + { + // We need to test a few basic things used in the ClientTest + // Anything else beyond this scope should go into /lib/haxe/ instead + + var map32 = new IntMap<Int32>(); + var map64 = new Int64Map<Int32>(); + + rslt.Expect( map32.keys().hasNext() == map64.keys().hasNext(), "Int64Map<Int32> Test #1"); + rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map<Int32> Test #2"); + rslt.Expect( map32.remove( 4711) == map64.remove( Int64.make(47,11)), "Int64Map<Int32> Test #3"); + rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map<Int32> Test #4"); + + map32.set( 42, 815); + map64.set( Int64.make(0,42), 815); + map32.set( -517, 23); + map64.set( Int64.make(-5,17), 23); + map32.set( 0, -123); + map64.set( Int64.make(0,0), -123); + + rslt.Expect( map32.keys().hasNext() == map64.keys().hasNext(), "Int64Map<Int32> Test #10"); + rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map<Int32> Test #11"); + rslt.Expect( map32.exists( -517) == map64.exists( Int64.make(-5,17)), "Int64Map<Int32> Test #12"); + rslt.Expect( map32.exists( 42) == map64.exists( Int64.make(0,42)), "Int64Map<Int32> Test #13"); + rslt.Expect( map32.exists( 0) == map64.exists( Int64.make(0,0)), "Int64Map<Int32> Test #14"); + rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map<Int32> Test #15"); + rslt.Expect( map32.get( -517) == map64.get( Int64.make(-5,17)), "Int64Map<Int32> Test #16"); + rslt.Expect( map32.get( 42) == map64.get( Int64.make(0,42)), "Int64Map<Int32> Test #Int64.make(-5,17)"); + rslt.Expect( map32.get( 0) == map64.get( Int64.make(0,0)), "Int64Map<Int32> Test #18"); + rslt.Expect( map32.remove( 4711) == map64.remove( Int64.make(47,11)), "Int64Map<Int32> Test #19"); + rslt.Expect( map32.remove( -517) == map64.remove( Int64.make(-5,17)), "Int64Map<Int32> Test #20"); + rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map<Int32> Test #21"); + rslt.Expect( map32.exists( -517) == map64.exists( Int64.make(-5,17)), "Int64Map<Int32> Test #22"); + rslt.Expect( map32.exists( 42) == map64.exists( Int64.make(0,42)), "Int64Map<Int32> Test #23"); + rslt.Expect( map32.exists( 0) == map64.exists( Int64.make(0,0)), "Int64Map<Int32> Test #24"); + rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map<Int32> Test #25"); + rslt.Expect( map32.get( -517) == map64.get( Int64.make(-5,17)), "Int64Map<Int32> Test #26"); + rslt.Expect( map32.get( 42) == map64.get( Int64.make(0,42)), "Int64Map<Int32> Test #27"); + rslt.Expect( map32.get( 0) == map64.get( Int64.make(0,0)), "Int64Map<Int32> Test #28"); + + map32.set( 42, 1); + map64.set( Int64.make(0,42), 1); + map32.set( -517, -2); + map64.set( Int64.make(-5,17), -2); + map32.set( 0, 3); + map64.set( Int64.make(0,0), 3); + + var c32 = 0; + for (key in map32.keys()) { + ++c32; + } + var c64 = 0; + for (key in map64.keys()) { + ++c64; + } + rslt.Expect( c32 == c64, "Int64Map<Int32> Test #30"); + + var s32 = map32.toString(); + var s64 = map64.toString(); + trace("Int64Map<Int32>.toString(): " + ' ("$s32" == "$s64")'); + + map32.remove( 42); + map64.remove( Int64.make(0,42)); + map32.remove( -517); + map64.remove( Int64.make(-5,17)); + map32.remove( 0); + map64.remove( Int64.make(0,0)); + + rslt.Expect( map32.keys().hasNext() == map64.keys().hasNext(), "Int64Map<Int32> Test #90"); + rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map<Int32> Test #91"); + rslt.Expect( map32.exists( -517) == map64.exists( Int64.make(-5,17)), "Int64Map<Int32> Test #92"); + rslt.Expect( map32.exists( 42) == map64.exists( Int64.make(0,42)), "Int64Map<Int32> Test #93"); + rslt.Expect( map32.exists( 0) == map64.exists( Int64.make(0,0)), "Int64Map<Int32> Test #94"); + rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map<Int32> Test #95"); + rslt.Expect( map32.get( -517) == map64.get( Int64.make(-5,17)), "Int64Map<Int32> Test #96"); + rslt.Expect( map32.get( 42) == map64.get( Int64.make(0,42)), "Int64Map<Int32> Test #97"); + rslt.Expect( map32.get( 0) == map64.get( Int64.make(0,0)), "Int64Map<Int32> Test #98"); + } + + + public static function ClientTest( transport : TTransport, protocol : TProtocol, rslt : TestResults) : Void + { + var client = new ThriftTestImpl(protocol,protocol); + try + { + if (!transport.isOpen()) + { + transport.open(); + } + } + catch (e : TException) + { + trace('$e'); + return; + } + catch (e : Dynamic) + { + trace('$e'); + return; + } + + var start = Date.now(); + + trace('testVoid()'); + client.testVoid(); + trace(' = void'); + rslt.Expect(true,"testVoid()"); // bump counter + + trace('testString("Test")'); + var s = client.testString("Test"); + trace(' = "$s"'); + rslt.Expect(s == "Test", '$s == "Test"'); + + trace('testByte(1)'); + var i8 = client.testByte(1); + trace(' = $i8'); + rslt.Expect(i8 == 1, '$i8 == 1'); + + trace('testI32(-1)'); + var i32 = client.testI32(-1); + trace(' = $i32'); + rslt.Expect(i32 == -1, '$i32 == -1'); + + trace('testI64(-34359738368)'); + var i64 = client.testI64( Int64.make( 0xFFFFFFF8, 0x00000000)); // -34359738368 + trace(' = $i64'); + rslt.Expect( Int64.compare( i64, Int64.make( 0xFFFFFFF8, 0x00000000)) == 0, + Int64.toStr(i64) +" == "+Int64.toStr(Int64.make( 0xFFFFFFF8, 0x00000000))); + + // edge case: the largest negative Int64 has no positive Int64 equivalent + trace('testI64(-9223372036854775808)'); + i64 = client.testI64( Int64.make( 0x80000000, 0x00000000)); // -9223372036854775808 + trace(' = $i64'); + rslt.Expect( Int64.compare( i64, Int64.make( 0x80000000, 0x00000000)) == 0, + Int64.toStr(i64) +" == "+Int64.toStr(Int64.make( 0x80000000, 0x00000000))); + + trace('testDouble(5.325098235)'); + var dub = client.testDouble(5.325098235); + trace(' = $dub'); + rslt.Expect(dub == 5.325098235, '$dub == 5.325098235'); + + trace('testStruct({"Zero", 1, -3, -5})'); + var o = new Xtruct(); + o.string_thing = "Zero"; + o.byte_thing = 1; + o.i32_thing = -3; + o.i64_thing = Int64.make(0,-5); + var i = client.testStruct(o); + trace(' = {"' + i.string_thing + '", ' + i.byte_thing +', ' + + i.i32_thing +', '+ Int64.toStr(i.i64_thing) + '}'); + rslt.Expect( i.string_thing == o.string_thing, "i.string_thing == o.string_thing"); + rslt.Expect( i.byte_thing == o.byte_thing, "i.byte_thing == o.byte_thing"); + rslt.Expect( i.i32_thing == o.i32_thing, "i.i64_thing == o.i64_thing"); + rslt.Expect( i.i32_thing == o.i32_thing, "i.i64_thing == o.i64_thing"); + + trace('testNest({1, {\"Zero\", 1, -3, -5}, 5})'); + var o2 = new Xtruct2(); + o2.byte_thing = 1; + o2.struct_thing = o; + o2.i32_thing = 5; + var i2 = client.testNest(o2); + i = i2.struct_thing; + trace(" = {" + i2.byte_thing + ", {\"" + i.string_thing + "\", " + + i.byte_thing + ", " + i.i32_thing + ", " + Int64.toStr(i.i64_thing) + "}, " + + i2.i32_thing + "}"); + rslt.Expect( i2.byte_thing == o2.byte_thing, "i2.byte_thing == o2.byte_thing"); + rslt.Expect( i2.i32_thing == o2.i32_thing, "i2.i32_thing == o2.i32_thing"); + rslt.Expect( i.string_thing == o.string_thing, "i.string_thing == o.string_thing"); + rslt.Expect( i.byte_thing == o.byte_thing, "i.byte_thing == o.byte_thing"); + rslt.Expect( i.i32_thing == o.i32_thing, "i.i32_thing == o.i32_thing"); + rslt.Expect( Int64.compare( i.i64_thing, o.i64_thing) == 0, "i.i64_thing == o.i64_thing"); + + var mapout = new IntMap< haxe.Int32>(); + for ( j in 0 ... 5) + { + mapout.set(j, j - 10); + } + trace("testMap({"); + var first : Bool = true; + for( key in mapout.keys()) + { + if (first) + { + first = false; + } + else + { + trace(", "); + } + trace(key + " => " + mapout.get(key)); + } + trace("})"); + + var mapin = client.testMap(mapout); + + trace(" = {"); + first = true; + for( key in mapin.keys()) + { + if (first) + { + first = false; + } + else + { + trace(", "); + } + trace(key + " => " + mapin.get(key)); + rslt.Expect( mapin.get(key) == mapout.get(key), ' mapin.get($key) == mapout.get($key)'); + } + trace("}"); + for( key in mapout.keys()) + { + rslt.Expect(mapin.exists(key), 'mapin.exists($key)'); + } + + var listout = new List<Int>(); + for (j in -2 ... 3) + { + listout.add(j); + } + trace("testList({"); + first = true; + for( j in listout) + { + if (first) + { + first = false; + } + else + { + trace(", "); + } + trace(j); + } + trace("})"); + + var listin = client.testList(listout); + + trace(" = {"); + first = true; + for( j in listin) + { + if (first) + { + first = false; + } + else + { + trace(", "); + } + trace(j); + } + trace("}"); + + rslt.Expect(listin.length == listout.length, "listin.length == listout.length"); + var literout = listout.iterator(); + var literin = listin.iterator(); + while( literin.hasNext()) { + rslt.Expect(literin.next() == literout.next(), "literin[i] == literout[i]"); + } + + //set + var setout = new IntSet(); + for (j in -2 ... 3) + { + setout.add(j); + } + trace("testSet({"); + first = true; + for( j in setout) + { + if (first) + { + first = false; + } + else + { + trace(", "); + } + trace(j); + } + trace("})"); + + var setin = client.testSet(setout); + + trace(" = {"); + first = true; + for( j in setin) + { + if (first) + { + first = false; + } + else + { + trace(", "); + } + trace(j); + rslt.Expect(setout.contains(j), 'setout.contains($j)'); + } + trace("}"); + rslt.Expect(setin.size == setout.size, "setin.length == setout.length"); + + + trace("testEnum(ONE)"); + var ret = client.testEnum(Numberz.ONE); + trace(" = " + ret); + rslt.Expect(ret == Numberz.ONE, '$ret == Numberz.ONE'); + + trace("testEnum(TWO)"); + ret = client.testEnum(Numberz.TWO); + trace(" = " + ret); + rslt.Expect(ret == Numberz.TWO, '$ret == Numberz.TWO'); + + trace("testEnum(THREE)"); + ret = client.testEnum(Numberz.THREE); + trace(" = " + ret); + rslt.Expect(ret == Numberz.THREE, '$ret == Numberz.THREE'); + + trace("testEnum(FIVE)"); + ret = client.testEnum(Numberz.FIVE); + trace(" = " + ret); + rslt.Expect(ret == Numberz.FIVE, '$ret == Numberz.FIVE'); + + trace("testEnum(EIGHT)"); + ret = client.testEnum(Numberz.EIGHT); + trace(" = " + ret); + rslt.Expect(ret == Numberz.EIGHT, '$ret == Numberz.EIGHT'); + + trace("testTypedef(309858235082523)"); + var uid = client.testTypedef( Int64.make( 0x119D0, 0x7E08671B)); // 309858235082523 + trace(" = " + uid); + rslt.Expect( Int64.compare( uid, Int64.make( 0x119D0, 0x7E08671B)) == 0, + Int64.toStr(uid)+" == "+Int64.toStr(Int64.make( 0x119D0, 0x7E08671B))); + + trace("testMapMap(1)"); + var mm = client.testMapMap(1); + trace(" = {"); + for( key in mm.keys()) + { + trace(key + " => {"); + var m2 = mm.get(key); + for( k2 in m2.keys()) + { + trace(k2 + " => " + m2.get(k2) + ", "); + } + trace("}, "); + } + trace("}"); + + var pos = mm.get(4); + var neg = mm.get(-4); + rslt.Expect( (pos != null) && (neg != null), "(pos != null) && (neg != null)"); + for (i in 0 ... 5) { + rslt.Expect( pos.get(i) == i, 'pos.get($i) == $i'); + rslt.Expect( neg.get(-i) == -i, 'neg.get(-$i) == -$i'); + } + + var insane = new Insanity(); + insane.userMap = new IntMap< Int64>(); + insane.userMap.set( Numberz.FIVE, Int64.make(0,5000)); + var truck = new Xtruct(); + truck.string_thing = "Truck"; + truck.byte_thing = 8; + truck.i32_thing = 8; + truck.i64_thing = Int64.make(0,8); + insane.xtructs = new List<Xtruct>(); + insane.xtructs.add(truck); + trace("testInsanity()"); + var whoa = client.testInsanity(insane); + trace(" = {"); + for( key in whoa.keys()) + { + var val = whoa.get(key); + trace(key + " => {"); + + for( k2 in val.keys()) + { + var v2 = val.get(k2); + + trace(k2 + " => {"); + var userMap = v2.userMap; + + trace("{"); + if (userMap != null) + { + for( k3 in userMap.keys()) + { + trace(k3 + " => " + userMap.get(k3) + ", "); + } + } + else + { + trace("null"); + } + trace("}, "); + + var xtructs = v2.xtructs; + + trace("{"); + if (xtructs != null) + { + for( x in xtructs) + { + trace("{\"" + x.string_thing + "\", " + + x.byte_thing + ", " + x.i32_thing + ", " + + x.i32_thing + "}, "); + } + } + else + { + trace("null"); + } + trace("}"); + + trace("}, "); + } + trace("}, "); + } + trace("}"); + + var first_map = whoa.get(Int64.make(0,1)); + var second_map = whoa.get(Int64.make(0,2)); + rslt.Expect( (first_map != null) && (second_map != null), "(first_map != null) && (second_map != null)"); + if ((first_map != null) && (second_map != null)) + { + var crazy2 = first_map.get(Numberz.TWO); + var crazy3 = first_map.get(Numberz.THREE); + var looney = second_map.get(Numberz.SIX); + rslt.Expect( (crazy2 != null) && (crazy3 != null) && (looney != null), + "(crazy2 != null) && (crazy3 != null) && (looney != null)"); + + rslt.Expect( Int64.compare( crazy2.userMap.get(Numberz.EIGHT), Int64.make(0,8)) == 0, + "crazy2.UserMap.get(Numberz.EIGHT) == 8"); + rslt.Expect( Int64.compare( crazy3.userMap.get(Numberz.EIGHT), Int64.make(0,8)) == 0, + "crazy3.UserMap.get(Numberz.EIGHT) == 8"); + rslt.Expect( Int64.compare( crazy2.userMap.get(Numberz.FIVE), Int64.make(0,5)) == 0, + "crazy2.UserMap.get(Numberz.FIVE) == 5"); + rslt.Expect( Int64.compare( crazy3.userMap.get(Numberz.FIVE), Int64.make(0,5)) == 0, + "crazy3.UserMap.get(Numberz.FIVE) == 5"); + + var crz2iter = crazy2.xtructs.iterator(); + var crz3iter = crazy3.xtructs.iterator(); + rslt.Expect( crz2iter.hasNext() && crz3iter.hasNext(), "crz2iter.hasNext() && crz3iter.hasNext()"); + var goodbye2 = crz2iter.next(); + var goodbye3 = crz3iter.next(); + rslt.Expect( crz2iter.hasNext() && crz3iter.hasNext(), "crz2iter.hasNext() && crz3iter.hasNext()"); + var hello2 = crz2iter.next(); + var hello3 = crz3iter.next(); + rslt.Expect( ! (crz2iter.hasNext() || crz3iter.hasNext()), "! (crz2iter.hasNext() || crz3iter.hasNext())"); + + rslt.Expect( hello2.string_thing == "Hello2", 'hello2.String_thing == "Hello2"'); + rslt.Expect( hello2.byte_thing == 2, 'hello2.Byte_thing == 2'); + rslt.Expect( hello2.i32_thing == 2, 'hello2.I32_thing == 2'); + rslt.Expect( Int64.compare( hello2.i64_thing, Int64.make(0,2)) == 0, 'hello2.I64_thing == 2'); + rslt.Expect( hello3.string_thing == "Hello2", 'hello3.String_thing == "Hello2"'); + rslt.Expect( hello3.byte_thing == 2, 'hello3.Byte_thing == 2'); + rslt.Expect( hello3.i32_thing == 2, 'hello3.I32_thing == 2'); + rslt.Expect( Int64.compare( hello3.i64_thing, Int64.make(0,2)) == 0, 'hello3.I64_thing == 2'); + + rslt.Expect( goodbye2.string_thing == "Goodbye4", 'goodbye2.String_thing == "Goodbye4"'); + rslt.Expect( goodbye2.byte_thing == 4, 'goodbye2.Byte_thing == 4'); + rslt.Expect( goodbye2.i32_thing == 4, 'goodbye2.I32_thing == 4'); + rslt.Expect( Int64.compare( goodbye2.i64_thing, Int64.make(0,4)) == 0, 'goodbye2.I64_thing == 4'); + rslt.Expect( goodbye3.string_thing == "Goodbye4", 'goodbye3.String_thing == "Goodbye4"'); + rslt.Expect( goodbye3.byte_thing == 4, 'goodbye3.Byte_thing == 4'); + rslt.Expect( goodbye3.i32_thing == 4, 'goodbye3.I32_thing == 4'); + rslt.Expect( Int64.compare( goodbye3.i64_thing, Int64.make(0,4)) == 0, 'goodbye3.I64_thing == 4'); + } + + var arg0 = 1; + var arg1 = 2; + var arg2 = Int64.make( 0x7FFFFFFF,0xFFFFFFFF); + var multiDict = new IntMap< String>(); + multiDict.set(1, "one"); + var arg4 = Numberz.FIVE; + var arg5 = Int64.make(0,5000000); + trace("Test Multi(" + arg0 + "," + arg1 + "," + arg2 + "," + multiDict + "," + arg4 + "," + arg5 + ")"); + var multiResponse = client.testMulti(arg0, arg1, arg2, multiDict, arg4, arg5); + trace(" = Xtruct(byte_thing:" + multiResponse.byte_thing + ",string_thing:" + multiResponse.string_thing + + ",i32_thing:" + multiResponse.i32_thing + + ",i64_thing:" + Int64.toStr(multiResponse.i64_thing) + ")"); + + rslt.Expect( multiResponse.string_thing == "Hello2", 'multiResponse.String_thing == "Hello2"'); + rslt.Expect( multiResponse.byte_thing == arg0, 'multiResponse.Byte_thing == arg0'); + rslt.Expect( multiResponse.i32_thing == arg1, 'multiResponse.I32_thing == arg1'); + rslt.Expect( Int64.compare( multiResponse.i64_thing, arg2) == 0, 'multiResponse.I64_thing == arg2'); + + + trace("Test Oneway(1)"); + client.testOneway(1); + + trace("Test Calltime()"); + var difft = Timer.stamp(); + for ( k in 0 ... 1000) { + client.testVoid(); + } + difft = Timer.stamp() - difft; + trace('$difft ms per testVoid() call'); + } +} diff --git a/test/haxe/src/TestServer.hx b/test/haxe/src/TestServer.hx new file mode 100644 index 000000000..66b06e009 --- /dev/null +++ b/test/haxe/src/TestServer.hx @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package; + +import org.apache.thrift.*; +import org.apache.thrift.protocol.*; +import org.apache.thrift.transport.*; +import org.apache.thrift.server.*; +import org.apache.thrift.meta_data.*; + +import thrift.test.*; // generated code + + +class TestServer +{ + public static function Execute(args : Arguments) : Void + { + try + { + // Transport + var transport : TServerTransport = null; + switch( args.transport) { + case socket: + trace("- socket port "+args.port); + transport = new TServerSocket( args.port); + case http: + trace("- http"); + throw "HTTP server not implemented yet"; + //transport = new THttpServer( targetHost); + default: + throw "Unhandled transport"; + } + + // optional: layered transport + var transfactory : TTransportFactory = null; + if ( args.framed) { + trace("- framed transport"); + transfactory = new TFramedTransportFactory(); + } else if ( args.buffered) { + trace("- buffered transport"); + throw "TBufferedTransport not implemented yet"; + //transfactory = new TBufferedTransportFactory(); + } + + // protocol + var protfactory : TProtocolFactory = null; + switch( args.protocol) + { + case binary: + trace("- binary protocol"); + protfactory = new TBinaryProtocolFactory(); + case json: + trace("- json protocol"); + protfactory = new TJSONProtocolFactory(); + default: + throw "Unhandled protocol"; + } + + + // Processor + var handler = new TestServerHandler(); + var processor = new ThriftTestProcessor(handler); + + // Simple Server + var server = new TSimpleServer( processor, transport, transfactory, protfactory); + + + /* + // Server event handler + var events = new TestServerEventHandler(); + server.setEventHandler(serverEvents); + handler.server = serverEngine; + */ + + // Run it + server.Serve(); + trace("done."); + + } + catch (x : TException) + { + trace('$x'); + } + catch (x : Dynamic) + { + trace('$x'); + } + } +} diff --git a/test/haxe/src/TestServerEventHandler.hx b/test/haxe/src/TestServerEventHandler.hx new file mode 100644 index 000000000..b52943a22 --- /dev/null +++ b/test/haxe/src/TestServerEventHandler.hx @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package; + +import org.apache.thrift.*; +import org.apache.thrift.protocol.*; +import org.apache.thrift.transport.*; +import org.apache.thrift.server.*; +import org.apache.thrift.meta_data.*; + +import thrift.test.*; // generated code + + +class TestServerEventHandler : TServerEventHandler +{ + public int callCount = 0; + public void preServe() + { + callCount++; + } + public Object createContext(Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output) + { + callCount++; + return null; + } + public void deleteContext(Object serverContext, Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output) + { + callCount++; + } + public void processContext(Object serverContext, Thrift.Transport.TTransport transport) + { + callCount++; + } +} + +
\ No newline at end of file diff --git a/test/haxe/src/TestServerHandler.hx b/test/haxe/src/TestServerHandler.hx new file mode 100644 index 000000000..e988adbeb --- /dev/null +++ b/test/haxe/src/TestServerHandler.hx @@ -0,0 +1,470 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package; + +import org.apache.thrift.*; +import org.apache.thrift.protocol.*; +import org.apache.thrift.transport.*; +import org.apache.thrift.server.*; +import org.apache.thrift.meta_data.*; +import org.apache.thrift.helper.*; + +import haxe.Int32; +import haxe.Int64; +import haxe.io.Bytes; +import haxe.ds.IntMap; +import haxe.ds.StringMap; +import haxe.ds.ObjectMap; + +import thrift.test.*; // generated code + + +class TestServerHandler implements ThriftTest { + + public var server:TServer; + + public function new() { + } + + /** + * Prints "testVoid()" and returns nothing. + */ + public function testVoid():Void + { + trace("testVoid()"); + } + + /** + * Prints 'testString("%s")' with thing as '%s' + * @param string thing - the string to print + * @return string - returns the string 'thing' + * + * @param thing + */ + public function testString(thing:String):String + { + trace("teststring(\"" + thing + "\")"); + return thing; + } + + /** + * Prints 'testByte("%d")' with thing as '%d' + * @param byte thing - the byte to print + * @return byte - returns the byte 'thing' + * + * @param thing + */ + public function testByte(thing:haxe.Int32):haxe.Int32 + { + trace("testByte(" + thing + ")"); + return thing; + } + + /** + * Prints 'testI32("%d")' with thing as '%d' + * @param i32 thing - the i32 to print + * @return i32 - returns the i32 'thing' + * + * @param thing + */ + public function testI32(thing:haxe.Int32):haxe.Int32 + { + trace("testI32(" + thing + ")"); + return thing; + } + + /** + * Prints 'testI64("%d")' with thing as '%d' + * @param i64 thing - the i64 to print + * @return i64 - returns the i64 'thing' + * + * @param thing + */ + public function testI64(thing:haxe.Int64):haxe.Int64 + { + trace("testI64(" + thing + ")"); + return thing; + } + + /** + * Prints 'testDouble("%f")' with thing as '%f' + * @param double thing - the double to print + * @return double - returns the double 'thing' + * + * @param thing + */ + public function testDouble(thing:Float):Float + { + trace("testDouble(" + thing + ")"); + return thing; + } + + /** + * Prints 'testStruct("{%s}")' where thing has been formatted + * into a string of comma seperated values + * @param Xtruct thing - the Xtruct to print + * @return Xtruct - returns the Xtruct 'thing' + * + * @param thing + */ + public function testStruct(thing:Xtruct):Xtruct + { + trace("testStruct({" + + "\"" + thing.string_thing + "\", " + + thing.byte_thing + ", " + + thing.i32_thing + ", " + + Int64.toStr(thing.i64_thing) + "})"); + return thing; + } + + /** + * Prints 'testNest("{%s}")' where thing has been formatted + * into a string of the nested struct + * @param Xtruct2 thing - the Xtruct2 to print + * @return Xtruct2 - returns the Xtruct2 'thing' + * + * @param thing + */ + public function testNest(nest:Xtruct2):Xtruct2 + { + var thing:Xtruct = nest.struct_thing; + trace("testNest({" + + nest.byte_thing + ", {" + + "\"" + thing.string_thing + "\", " + + thing.byte_thing + ", " + + thing.i32_thing + ", " + + Int64.toStr(thing.i64_thing) + "}, " + + nest.i32_thing + "})"); + return nest; + } + + /** + * Prints 'testMap("{%s")' where thing has been formatted + * into a string of 'key => value' pairs + * seperated by commas and new lines + * @param map<i32,i32> thing - the map<i32,i32> to print + * @return map<i32,i32> - returns the map<i32,i32> 'thing' + * + * @param thing + */ + public function testMap(thing:IntMap<haxe.Int32>):IntMap<haxe.Int32> + { + trace("testMap({"); + var first:Bool = true; + for (key in thing.keys()) { + if (first) { + first = false; + } else { + trace(", "); + }; + trace(key + " => " + thing.get(key)); + }; + trace("})"); + return thing; + } + + /** + * Prints 'testStringMap("{%s}")' where thing has been formatted + * into a string of 'key => value' pairs + * seperated by commas and new lines + * @param map<string,string> thing - the map<string,string> to print + * @return map<string,string> - returns the map<string,string> 'thing' + * + * @param thing + */ + public function testStringMap(thing:StringMap<String>):StringMap<String> + { + trace("testStringMap({"); + var first:Bool = true; + for (key in thing.keys()) { + if (first) { + first = false; + } else { + trace(", "); + }; + trace(key + " => " + thing.get(key)); + }; + trace("})"); + return thing; + } + + /** + * Prints 'testSet("{%s}")' where thing has been formatted + * into a string of values + * seperated by commas and new lines + * @param set<i32> thing - the set<i32> to print + * @return set<i32> - returns the set<i32> 'thing' + * + * @param thing + */ + public function testSet(thing:IntSet):IntSet + { + trace("testSet({"); + var first:Bool = true; + for (elem in thing) { + if (first) { + first = false; + } else { + trace(", "); + }; + trace(elem); + }; + trace("})"); + return thing; + } + + /** + * Prints 'testList("{%s}")' where thing has been formatted + * into a string of values + * seperated by commas and new lines + * @param list<i32> thing - the list<i32> to print + * @return list<i32> - returns the list<i32> 'thing' + * + * @param thing + */ + public function testList(thing:List<haxe.Int32>):List<haxe.Int32> + { + trace("testList({"); + var first:Bool = true; + for (elem in thing) { + if (first) { + first = false; + } else { + trace(", "); + }; + trace(elem); + }; + trace("})"); + return thing; + } + + /** + * Prints 'testEnum("%d")' where thing has been formatted into it's numeric value + * @param Numberz thing - the Numberz to print + * @return Numberz - returns the Numberz 'thing' + * + * @param thing + */ + public function testEnum(thing:Int):Int + { + trace("testEnum(" + thing + ")"); + return thing; + } + + /** + * Prints 'testTypedef("%d")' with thing as '%d' + * @param UserId thing - the UserId to print + * @return UserId - returns the UserId 'thing' + * + * @param thing + */ + public function testTypedef(thing:haxe.Int64):haxe.Int64 + { + trace("testTypedef(" + thing + ")"); + return thing; + } + + /** + * Prints 'testMapMap("%d")' with hello as '%d' + * @param i32 hello - the i32 to print + * @return map<i32,map<i32,i32>> - returns a dictionary with these values: + * {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, + * 4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, } + * + * @param hello + */ + public function testMapMap(hello:haxe.Int32):IntMap<IntMap<haxe.Int32>> + { + trace("testMapMap(" + hello + ")"); + var mapmap = new IntMap<IntMap<Int>>(); + var pos = new IntMap<Int>(); + var neg = new IntMap<Int>(); + for (i in 1 ... 5) { + pos.set(i, i); + neg.set(-i, -i); + }; + mapmap.set(4, pos); + mapmap.set(-4, neg); + return mapmap; + } + + /** + * So you think you've got this all worked, out eh? + * + * Creates a the returned map with these values and prints it out: + * { 1 => { 2 => argument, + * 3 => argument, + * }, + * 2 => { 6 => <empty Insanity struct>, }, + * } + * @return map<UserId, map<Numberz,Insanity>> - a map with the above values + * + * @param argument + */ + public function testInsanity(argument : Insanity) : Int64Map< IntMap< Insanity>> + { + trace("testInsanity()"); + + var hello = new Xtruct(); + hello.string_thing = "Hello2"; + hello.byte_thing = 2; + hello.i32_thing = 2; + hello.i64_thing = Int64.make(0, 2); + + var goodbye = new Xtruct(); + goodbye.string_thing = "Goodbye4"; + goodbye.byte_thing = 4; + goodbye.i32_thing = 4; + goodbye.i64_thing = Int64.make(0, 4); + + var crazy = new Insanity(); + crazy.userMap = new IntMap< haxe.Int64>(); + crazy.userMap.set(Numberz.EIGHT, Int64.make(0,8)); + crazy.xtructs = new List<Xtruct>(); + crazy.xtructs.add(goodbye); + + var looney = new Insanity(); + crazy.userMap.set(Numberz.FIVE, Int64.make(0,5)); + crazy.xtructs.add(hello); + + var first_map = new IntMap< Insanity>(); + first_map.set(Numberz.TWO, crazy); + first_map.set(Numberz.THREE, crazy); + + var second_map = new IntMap< Insanity>(); + second_map.set(Numberz.SIX, looney); + + var insane = new Int64Map< IntMap< Insanity>>(); + insane.set( Int64.make(0,1), first_map); + insane.set( Int64.make(0,2), second_map); + + return insane; + } + + /** + * Prints 'testMulti()' + * @param byte arg0 - + * @param i32 arg1 - + * @param i64 arg2 - + * @param map<i16, string> arg3 - + * @param Numberz arg4 - + * @param UserId arg5 - + * @return Xtruct - returns an Xtruct + * with string_thing = "Hello2, byte_thing = arg0, i32_thing = arg1 + * and i64_thing = arg2 + * + * @param arg0 + * @param arg1 + * @param arg2 + * @param arg3 + * @param arg4 + * @param arg5 + */ + public function testMulti(arg0:haxe.Int32, arg1:haxe.Int32, arg2:haxe.Int64, + arg3:IntMap<String>, arg4:Int, arg5:haxe.Int64):Xtruct + { + trace("testMulti()"); + var hello = new Xtruct(); + hello.string_thing = "Hello2"; + hello.byte_thing = arg0; + hello.i32_thing = arg1; + hello.i64_thing = arg2; + return hello; + } + + /** + * Print 'testException(%s)' with arg as '%s' + * @param string arg - a string indication what type of exception to throw + * if arg == "Xception" throw Xception with errorCode = 1001 and message = arg + * elsen if arg == "TException" throw TException + * else do not throw anything + * + * @param arg + */ + public function testException(arg:String):Void + { + trace("testException(" + arg + ")"); + if (arg == "Xception") { + var x = new Xception(); + x.errorCode = 1001; + x.message = arg; + throw x; + }; + if (arg == "TException") { + throw new TException(); + }; + return; + } + + /** + * Print 'testMultiException(%s, %s)' with arg0 as '%s' and arg1 as '%s' + * @param string arg - a string indication what type of exception to throw + * if arg0 == "Xception" + * throw Xception with errorCode = 1001 and message = "This is an Xception" + * else if arg0 == "Xception2" + * throw Xception2 with errorCode = 2002 and message = "This is an Xception2" + * else do not throw anything + * @return Xtruct - an Xtruct with string_thing = arg1 + * + * @param arg0 + * @param arg1 + */ + public function testMultiException(arg0:String, arg1:String):Xtruct + { + trace("testMultiException(" + arg0 + ", " + arg1 + ")"); + if (arg0 == "Xception") { + var x = new Xception(); + x.errorCode = 1001; + x.message = "This is an Xception"; + throw x; + } else if (arg0 == "Xception2") { + var x = new Xception2(); + x.errorCode = 2002; + x.struct_thing = new Xtruct(); + x.struct_thing.string_thing = "This is an Xception2"; + throw x; + }; + var result = new Xtruct(); + result.string_thing = arg1; + return result; + } + + /** + * Print 'testOneway(%d): Sleeping...' with secondsToSleep as '%d' + * sleep 'secondsToSleep' + * Print 'testOneway(%d): done sleeping!' with secondsToSleep as '%d' + * @param i32 secondsToSleep - the number of seconds to sleep + * + * @param secondsToSleep + */ + public function testOneway(secondsToSleep:haxe.Int32):Void + { + trace("testOneway(" + secondsToSleep + "), sleeping..."); + Sys.sleep(secondsToSleep); + trace("testOneway finished"); + } + + public function testStop():Void + { + if (server != null) { + server.Stop(); + }; + } +} |