THRIFT-3400 Add Erlang to cross test Client: Test, Erlang Patch: Nobuaki Sukegawa
Project: http://git-wip-us.apache.org/repos/asf/thrift/repo Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/826ea998 Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/826ea998 Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/826ea998 Branch: refs/heads/master Commit: 826ea998d5590247a00a3aea09026a9d7518d1f7 Parents: a6509f7 Author: Nobuaki Sukegawa <[email protected]> Authored: Wed Oct 28 22:19:45 2015 +0900 Committer: Nobuaki Sukegawa <[email protected]> Committed: Sat Oct 31 14:54:12 2015 +0900 ---------------------------------------------------------------------- .gitignore | 2 +- .travis.yml | 2 +- Makefile.am | 2 +- build/docker/centos/Dockerfile | 2 +- build/docker/ubuntu/Dockerfile | 2 +- configure.ac | 2 + lib/erl/Makefile.am | 21 +- lib/erl/test/Thrift3214.thrift | 23 - lib/erl/test/flags/LegacyNames.thrift | 33 ++ lib/erl/test/flags/Thrift3214.thrift | 23 + lib/erl/test/legacy_names_test.erl | 69 +++ lib/erl/test/name_conflict_test.erl | 299 +++++++++++++ lib/erl/test/test_client.erl | 133 ------ lib/erl/test/test_thrift_server.erl | 208 --------- lib/erl/test/thrift_test_test.erl | 655 +++++++++++++++++++++++++++++ test/Makefile.am | 1 + test/erl/LegacyNames.thrift | 33 -- test/erl/Makefile.am | 16 +- test/erl/rebar.config | 5 +- test/erl/src/legacy_names_test.erl | 69 --- test/erl/src/name_conflict_test.erl | 299 ------------- test/erl/src/test_client.erl | 139 ++++++ test/erl/src/test_thrift_server.erl | 223 ++++++++++ test/erl/src/thrift_test.app.src | 7 +- test/erl/src/thrift_test_test.erl | 655 ----------------------------- test/known_failures_Linux.json | 5 + test/tests.json | 47 +++ tutorial/erl/json_client.erl | 4 +- 28 files changed, 1534 insertions(+), 1445 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/.gitignore ---------------------------------------------------------------------- diff --git a/.gitignore b/.gitignore index 44e630a..c1cc1a9 100644 --- a/.gitignore +++ b/.gitignore @@ -245,8 +245,8 @@ test-driver /test/dart/**/pubspec.lock /test/log/ /test/test.log -/test/erl/.eunit/ /test/erl/.generated +/test/erl/ebin /test/go/bin/ /test/go/ThriftTest.thrift /test/go/gopath http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/.travis.yml ---------------------------------------------------------------------- diff --git a/.travis.yml b/.travis.yml index 5be7c34..4d2ecdb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -67,7 +67,7 @@ env: # Put it here because it's most time consuming - TEST_NAME="make cross (automake)" THRIFT_CROSSTEST_CONCURRENCY=6 - CONFIG="--enable-tutorial=no --without-erlang --without-lua --without-haxe --without-d" + CONFIG="--enable-tutorial=no --without-lua --without-haxe --without-d" ALL_DEPS="yes" MAKE_TARGET="cross" ERROR_LOG="test/log/unexpected_failures.log" http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/Makefile.am ---------------------------------------------------------------------- diff --git a/Makefile.am b/Makefile.am index eeeb4f2..73bc48f 100755 --- a/Makefile.am +++ b/Makefile.am @@ -49,7 +49,7 @@ empty := space := $(empty) $(empty) comma := , -CROSS_LANGS = @MAYBE_CPP@ @MAYBE_C_GLIB@ @MAYBE_JAVA@ @MAYBE_CSHARP@ @MAYBE_PYTHON@ @MAYBE_RUBY@ @MAYBE_HASKELL@ @MAYBE_PERL@ @MAYBE_PHP@ @MAYBE_GO@ @MAYBE_NODEJS@ @MAYBE_DART@ +CROSS_LANGS = @MAYBE_CPP@ @MAYBE_C_GLIB@ @MAYBE_JAVA@ @MAYBE_CSHARP@ @MAYBE_PYTHON@ @MAYBE_RUBY@ @MAYBE_HASKELL@ @MAYBE_PERL@ @MAYBE_PHP@ @MAYBE_GO@ @MAYBE_NODEJS@ @MAYBE_DART@ @MAYBE_ERLANG@ CROSS_LANGS_COMMA_SEPARATED = $(subst $(space),$(comma),$(CROSS_LANGS)) cross: precross http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/build/docker/centos/Dockerfile ---------------------------------------------------------------------- diff --git a/build/docker/centos/Dockerfile b/build/docker/centos/Dockerfile index c4c273c..8d5596a 100644 --- a/build/docker/centos/Dockerfile +++ b/build/docker/centos/Dockerfile @@ -67,7 +67,7 @@ RUN yum install -y glib2-devel # Erlang Dependencies RUN curl -sSL http://packages.erlang-solutions.com/rpm/centos/erlang_solutions.repo -o /etc/yum.repos.d/erlang_solutions.repo && \ - yum install -y erlang-kernel erlang-erts erlang-stdlib erlang-eunit erlang-rebar + yum install -y erlang-kernel erlang-erts erlang-stdlib erlang-eunit erlang-rebar erlang-tools # Go Dependencies RUN curl -sSL https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz | tar -C /usr/lib/ -xz && \ http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/build/docker/ubuntu/Dockerfile ---------------------------------------------------------------------- diff --git a/build/docker/ubuntu/Dockerfile b/build/docker/ubuntu/Dockerfile index 0148006..4ad94e1 100644 --- a/build/docker/ubuntu/Dockerfile +++ b/build/docker/ubuntu/Dockerfile @@ -56,7 +56,7 @@ RUN apt-get install -y libglib2.0-dev RUN echo 'deb http://packages.erlang-solutions.com/debian trusty contrib' > /etc/apt/sources.list.d/erlang_solutions.list && \ curl -sSL http://packages.erlang-solutions.com/debian/erlang_solutions.asc | sudo apt-key add - && \ apt-get update && \ - apt-get install -y erlang-base erlang-eunit erlang-dev + apt-get install -y erlang-base erlang-eunit erlang-dev erlang-tools # GO dependencies RUN curl -sSL https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz | tar -C /usr/lib/ -xz && \ http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/configure.ac ---------------------------------------------------------------------- diff --git a/configure.ac b/configure.ac index 701fdc9..3d1b15f 100755 --- a/configure.ac +++ b/configure.ac @@ -796,6 +796,8 @@ if test "$have_go" = "yes" ; then MAYBE_GO="go" ; else MAYBE_GO="" ; fi AC_SUBST([MAYBE_GO]) if test "$have_nodejs" = "yes" ; then MAYBE_NODEJS="nodejs" ; else MAYBE_NODEJS="" ; fi AC_SUBST([MAYBE_NODEJS]) +if test "$have_erlang" = "yes" ; then MAYBE_ERLANG="erl" ; else MAYBE_ERLANG="" ; fi +AC_SUBST([MAYBE_ERLANG]) AC_OUTPUT http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/lib/erl/Makefile.am ---------------------------------------------------------------------- diff --git a/lib/erl/Makefile.am b/lib/erl/Makefile.am index f577a63..21d21bf 100644 --- a/lib/erl/Makefile.am +++ b/lib/erl/Makefile.am @@ -19,21 +19,26 @@ THRIFT = ../../compiler/cpp/thrift THRIFT_FILES = $(wildcard test/*.thrift) \ + ../../test/NameConflictTest.thrift \ ../../test/ThriftTest.thrift if ERLANG_OTP16 -.generated: $(THRIFT) $(THRIFT_FILES) - for f in $(THRIFT_FILES) ; do \ - $(THRIFT) --gen erl:otp16 -o test $$f ; \ - done ; +ERL_FLAG = erl:otp16 +ERL_FLAG_LEGACY = erl:otp16,legacynames +# otp16 + maps does not make sense. We need to generate it anyway to avoid include error. +ERL_FLAG_MAPS = erl:otp16 else +ERL_FLAG = erl +ERL_FLAG_LEGACY = erl:legacynames +ERL_FLAG_MAPS = erl:maps +endif .generated: $(THRIFT) $(THRIFT_FILES) for f in $(THRIFT_FILES) ; do \ - $(THRIFT) --gen erl -o test $$f ; \ - done ; \ - $(THRIFT) --gen erl:maps -o test test/Thrift3214.thrift ; \ + $(THRIFT) --gen $(ERL_FLAG) -o test $$f ; \ + done + $(THRIFT) --gen $(ERL_FLAG_LEGACY) -o test test/flags/LegacyNames.thrift + $(THRIFT) --gen $(ERL_FLAG_MAPS) -o test test/flags/Thrift3214.thrift touch .generated -endif all: .generated ./rebar get-deps http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/lib/erl/test/Thrift3214.thrift ---------------------------------------------------------------------- diff --git a/lib/erl/test/Thrift3214.thrift b/lib/erl/test/Thrift3214.thrift deleted file mode 100644 index a9110ce..0000000 --- a/lib/erl/test/Thrift3214.thrift +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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. - */ - -struct StringMap -{ - 1: map<i32, string> data = {1: "a", 2: "b"}; -} http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/lib/erl/test/flags/LegacyNames.thrift ---------------------------------------------------------------------- diff --git a/lib/erl/test/flags/LegacyNames.thrift b/lib/erl/test/flags/LegacyNames.thrift new file mode 100644 index 0000000..38f2729 --- /dev/null +++ b/lib/erl/test/flags/LegacyNames.thrift @@ -0,0 +1,33 @@ +enum Numberz +{ + ONE = 1, + TWO, + THREE, + FIVE = 5, + SIX, + EIGHT = 8 +} + +const Numberz myNumberz = Numberz.ONE; + +struct CapitalizedStruct +{ + 1: i32 Id, + 2: binary message +} + +struct ListCapitalizedStructs +{ + 1: list<CapitalizedStruct> structs +} + +exception Xception { + 1: i32 errorCode, + 2: binary message +} + +service LegacyNames +{ + ListCapitalizedStructs Names(1: CapitalizedStruct foo, 2: CapitalizedStruct bar) + throws(1: Xception err) +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/lib/erl/test/flags/Thrift3214.thrift ---------------------------------------------------------------------- diff --git a/lib/erl/test/flags/Thrift3214.thrift b/lib/erl/test/flags/Thrift3214.thrift new file mode 100644 index 0000000..a9110ce --- /dev/null +++ b/lib/erl/test/flags/Thrift3214.thrift @@ -0,0 +1,23 @@ +/* + * 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. + */ + +struct StringMap +{ + 1: map<i32, string> data = {1: "a", 2: "b"}; +} http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/lib/erl/test/legacy_names_test.erl ---------------------------------------------------------------------- diff --git a/lib/erl/test/legacy_names_test.erl b/lib/erl/test/legacy_names_test.erl new file mode 100644 index 0000000..c16aa3e --- /dev/null +++ b/lib/erl/test/legacy_names_test.erl @@ -0,0 +1,69 @@ +%% +%% 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. +%% + +-module(legacy_names_test). +-compile(export_all). + +-include_lib("eunit/include/eunit.hrl"). + +-include("gen-erl/legacyNames_constants.hrl"). + +record_generation_test_() -> + [ + {"capitalizedStruct record", ?_assertMatch( + {capitalizedStruct, _, _}, + #capitalizedStruct{id=null,message=null} + )} + ]. + +struct_info_test_() -> + [ + {"capitalizedStruct extended definition", ?_assertEqual( + {struct, [ + {1, undefined, i32, 'id', undefined}, + {2, undefined, string, 'message', undefined} + ]}, + legacyNames_types:struct_info_ext(capitalizedStruct) + )}, + {"listCapitalizedStructs extended definition", ?_assertEqual( + {struct, [ + {1, undefined, {list, {struct, {'legacyNames_types', 'capitalizedStruct'}}}, 'structs', []} + ]}, + legacyNames_types:struct_info_ext(listCapitalizedStructs) + )} + ]. + +service_info_test_() -> + [ + {"names params", ?_assertEqual( + {struct, [ + {1, {struct, {'legacyNames_types', 'capitalizedStruct'}}}, + {2, {struct, {'legacyNames_types', 'capitalizedStruct'}}} + ]}, + legacyNames_thrift:function_info(names, params_type) + )}, + {"names reply", ?_assertEqual( + {struct, {'legacyNames_types', 'listCapitalizedStructs'}}, + legacyNames_thrift:function_info(names, reply_type) + )}, + {"names exceptions", ?_assertEqual( + {struct, [{1, {struct, {'legacyNames_types', 'xception'}}}]}, + legacyNames_thrift:function_info(names, exceptions) + )} + ]. http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/lib/erl/test/name_conflict_test.erl ---------------------------------------------------------------------- diff --git a/lib/erl/test/name_conflict_test.erl b/lib/erl/test/name_conflict_test.erl new file mode 100644 index 0000000..b01df57 --- /dev/null +++ b/lib/erl/test/name_conflict_test.erl @@ -0,0 +1,299 @@ +%% +%% 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. +%% + +-module(name_conflict_test). +-compile(export_all). + +-include_lib("eunit/include/eunit.hrl"). + +-include("gen-erl/name_conflict_test_constants.hrl"). + +record_generation_test_() -> + [ + {"using record", ?_assertMatch( + {using, _, _}, + #using{single=null,integer=null} + )}, + {"delegate record", ?_assertMatch( + {delegate, _, _}, + #delegate{partial=null,delegate=null} + )}, + {"get record", ?_assertMatch( + {get, _}, + #get{sbyte=null} + )}, + {"partial record", ?_assertMatch( + {partial, _, _, _}, + #partial{using=null} + )}, + {"ClassAndProp record", ?_assertMatch( + {'ClassAndProp', _, _, _, _}, + #'ClassAndProp'{ + 'ClassAndProp'=null, + 'ClassAndProp_'=null, + 'ClassAndProp__'=null, + 'ClassAndProper'=null + } + )}, + {"second_chance record", ?_assertMatch( + {second_chance, _, _, _, _}, + #second_chance{ + 'SECOND_CHANCE'=null, + 'SECOND_CHANCE_'=null, + 'SECOND_CHANCE__'=null, + 'SECOND_CHANCES'=null + } + )}, + {"NOW_EAT_THIS record", ?_assertMatch( + {'NOW_EAT_THIS', _, _, _, _}, + #'NOW_EAT_THIS'{ + now_eat_this=null, + now_eat_this_=null, + now_eat_this__=null, + now_eat_this_and_this=null + } + )}, + {"TheEdgeCase record", ?_assertMatch( + {'TheEdgeCase', _, _, _, _, _, _}, + #'TheEdgeCase'{ + theEdgeCase=null, + theEdgeCase_=null, + theEdgeCase__=null, + 'TheEdgeCase'=null, + 'TheEdgeCase_'=null, + 'TheEdgeCase__'=null + } + )}, + {"Tricky_ record", ?_assertMatch( + {'Tricky_', _, _}, + #'Tricky_'{tricky=null,'Tricky'=null} + )}, + {"Nested record", ?_assertMatch( + {'Nested', _, _, _, _, _, _}, + #'Nested'{ + 'ClassAndProp'=null, + second_chance=null, + 'NOW_EAT_THIS'=null, + 'TheEdgeCase'=null, + 'Tricky_'=null, + 'Nested'=null + } + )}, + {"Problem_ record", ?_assertMatch( + {'Problem_', _, _}, + #'Problem_'{problem=null,'Problem'=null} + )} + ]. + +struct_info_test_() -> + [ + {"using definition", ?_assertEqual( + {struct, [{1, double},{2, double}]}, + name_conflict_test_types:struct_info(using) + )}, + {"delegate definition", ?_assertEqual( + {struct, [ + {1, string}, + {2, {struct, {name_conflict_test_types, delegate}}} + ]}, + name_conflict_test_types:struct_info(delegate) + )}, + {"get definition", ?_assertEqual( + {struct, [{1, bool}]}, + name_conflict_test_types:struct_info(get) + )}, + {"partial definition", ?_assertEqual( + {struct, [ + {1, {struct, {name_conflict_test_types, using}}}, + {2, bool}, + {3, bool} + ]}, + name_conflict_test_types:struct_info(partial) + )}, + {"ClassAndProp definition", ?_assertEqual( + {struct, [{1, bool},{2, bool},{3, bool},{4, bool}]}, + name_conflict_test_types:struct_info('ClassAndProp') + )}, + {"second_chance definition", ?_assertEqual( + {struct, [{1, bool},{2, bool},{3, bool},{4, bool}]}, + name_conflict_test_types:struct_info(second_chance) + )}, + {"NOW_EAT_THIS definition", ?_assertEqual( + {struct, [{1, bool},{2, bool},{3, bool},{4, bool}]}, + name_conflict_test_types:struct_info('NOW_EAT_THIS') + )}, + {"TheEdgeCase definition", ?_assertEqual( + {struct, [{1, bool},{2, bool},{3, bool},{4, bool},{5, bool},{6, bool}]}, + name_conflict_test_types:struct_info('TheEdgeCase') + )}, + {"Tricky_ definition", ?_assertEqual( + {struct, [{1, bool},{2, bool}]}, + name_conflict_test_types:struct_info('Tricky_') + )}, + {"Nested definition", ?_assertEqual( + {struct, [ + {1, {struct, {name_conflict_test_types, 'ClassAndProp'}}}, + {2, {struct, {name_conflict_test_types, second_chance}}}, + {3, {struct, {name_conflict_test_types, 'NOW_EAT_THIS'}}}, + {4, {struct, {name_conflict_test_types, 'TheEdgeCase'}}}, + {5, {struct, {name_conflict_test_types, 'Tricky_'}}}, + {6, {struct, {name_conflict_test_types, 'Nested'}}} + ]}, + name_conflict_test_types:struct_info('Nested') + )}, + {"Problem_ definition", ?_assertEqual( + {struct, [{1, bool},{2, bool}]}, + name_conflict_test_types:struct_info('Problem_') + )}, + {"using extended definition", ?_assertEqual( + {struct, [ + {1, undefined, double, single, undefined}, + {2, undefined, double, integer, undefined} + ]}, + name_conflict_test_types:struct_info_ext(using) + )}, + {"delegate extended definition", ?_assertEqual( + {struct, [ + {1, undefined, string, partial, undefined}, + {2, undefined, {struct, {name_conflict_test_types, delegate}}, delegate, undefined} + ]}, + name_conflict_test_types:struct_info_ext(delegate) + )}, + {"get extended definition", ?_assertEqual( + {struct, [{1, undefined, bool, sbyte, undefined}]}, + name_conflict_test_types:struct_info_ext(get) + )}, + {"partial extended definition", ?_assertEqual( + {struct, [ + {1, undefined, {struct, {name_conflict_test_types, using}}, using, #using{}}, + {2, undefined, bool, read, undefined}, + {3, undefined, bool, write, undefined} + ]}, + name_conflict_test_types:struct_info_ext(partial) + )}, + {"ClassAndProp extended definition", ?_assertEqual( + {struct, [ + {1, undefined, bool, 'ClassAndProp', undefined}, + {2, undefined, bool, 'ClassAndProp_', undefined}, + {3, undefined, bool, 'ClassAndProp__', undefined}, + {4, undefined, bool, 'ClassAndProper', undefined} + ]}, + name_conflict_test_types:struct_info_ext('ClassAndProp') + )}, + {"second_chance extended definition", ?_assertEqual( + {struct, [ + {1, undefined, bool, 'SECOND_CHANCE', undefined}, + {2, undefined, bool, 'SECOND_CHANCE_', undefined}, + {3, undefined, bool, 'SECOND_CHANCE__', undefined}, + {4, undefined, bool, 'SECOND_CHANCES', undefined} + ]}, + name_conflict_test_types:struct_info_ext(second_chance) + )}, + {"NOW_EAT_THIS extended definition", ?_assertEqual( + {struct, [ + {1, undefined, bool, now_eat_this, undefined}, + {2, undefined, bool, now_eat_this_, undefined}, + {3, undefined, bool, now_eat_this__, undefined}, + {4, undefined, bool, now_eat_this_and_this, undefined} + ]}, + name_conflict_test_types:struct_info_ext('NOW_EAT_THIS') + )}, + {"TheEdgeCase extended definition", ?_assertEqual( + {struct, [ + {1, undefined, bool, theEdgeCase, undefined}, + {2, undefined, bool, theEdgeCase_, undefined}, + {3, undefined, bool, theEdgeCase__, undefined}, + {4, undefined, bool, 'TheEdgeCase', undefined}, + {5, undefined, bool, 'TheEdgeCase_', undefined}, + {6, undefined, bool, 'TheEdgeCase__', undefined} + ]}, + name_conflict_test_types:struct_info_ext('TheEdgeCase') + )}, + {"Tricky_ extended definition", ?_assertEqual( + {struct, [ + {1, undefined, bool, tricky, undefined}, + {2, undefined, bool, 'Tricky', undefined} + ]}, + name_conflict_test_types:struct_info_ext('Tricky_') + )}, + {"Nested extended definition", ?_assertEqual( + {struct, [ + {1, undefined, {struct, { + name_conflict_test_types, + 'ClassAndProp' + }}, 'ClassAndProp', #'ClassAndProp'{}}, + {2, undefined, {struct, { + name_conflict_test_types, + second_chance + }}, second_chance, #second_chance{}}, + {3, undefined, {struct, { + name_conflict_test_types, + 'NOW_EAT_THIS' + }}, 'NOW_EAT_THIS', #'NOW_EAT_THIS'{}}, + {4, undefined, {struct, { + name_conflict_test_types, + 'TheEdgeCase' + }}, 'TheEdgeCase', #'TheEdgeCase'{}}, + {5, undefined, {struct, { + name_conflict_test_types, + 'Tricky_' + }}, 'Tricky_', #'Tricky_'{}}, + {6, undefined, {struct, { + name_conflict_test_types, + 'Nested' + }}, 'Nested', undefined} + ]}, + name_conflict_test_types:struct_info_ext('Nested') + )}, + {"Problem_ extended definition", ?_assertEqual( + {struct, [ + {1, undefined, bool, problem, undefined}, + {2, undefined, bool, 'Problem', undefined} + ]}, + name_conflict_test_types:struct_info_ext('Problem_') + )} + ]. + +service_info_test_() -> + [ + {"event params", ?_assertEqual( + {struct, [{1, {struct, {name_conflict_test_types, partial}}}]}, + extern_thrift:function_info(event, params_type) + )}, + {"event reply", ?_assertEqual( + {struct, {name_conflict_test_types, delegate}}, + extern_thrift:function_info(event, reply_type) + )}, + {"event exceptions", ?_assertEqual( + {struct, []}, + extern_thrift:function_info(event, exceptions) + )}, + {"Foo params", ?_assertEqual( + {struct, [{1, {struct, {name_conflict_test_types, 'Nested'}}}]}, + extern_thrift:function_info('Foo', params_type) + )}, + {"Foo reply", ?_assertEqual( + {struct, []}, + extern_thrift:function_info('Foo', reply_type) + )}, + {"Foo exceptions", ?_assertEqual( + {struct, [{1, {struct, {name_conflict_test_types, 'Problem_'}}}]}, + extern_thrift:function_info('Foo', exceptions) + )} + ]. http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/lib/erl/test/test_client.erl ---------------------------------------------------------------------- diff --git a/lib/erl/test/test_client.erl b/lib/erl/test/test_client.erl deleted file mode 100644 index 4e85c47..0000000 --- a/lib/erl/test/test_client.erl +++ /dev/null @@ -1,133 +0,0 @@ -%% -%% 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. -%% - --module(test_client). - --export([start/0, start/1]). - --include("gen-erl/thrift_test_types.hrl"). - --record(options, {port = 9090, - client_opts = []}). - -parse_args(Args) -> parse_args(Args, #options{}). -parse_args([], Opts) -> Opts; -parse_args([Head | Rest], Opts) -> - NewOpts = - case catch list_to_integer(Head) of - Port when is_integer(Port) -> - Opts#options{port = Port}; - _Else -> - case Head of - "framed" -> - Opts#options{client_opts = [{framed, true} | Opts#options.client_opts]}; - "" -> - Opts; - _Else -> - erlang:error({bad_arg, Head}) - end - end, - parse_args(Rest, NewOpts). - - -start() -> start([]). -start(Args) -> - #options{port = Port, client_opts = ClientOpts} = parse_args(Args), - {ok, Client0} = thrift_client_util:new( - "127.0.0.1", Port, thrift_test_thrift, ClientOpts), - - DemoXtruct = #'Xtruct'{ - string_thing = <<"Zero">>, - byte_thing = 1, - i32_thing = 9128361, - i64_thing = 9223372036854775807}, - - DemoNest = #'Xtruct2'{ - byte_thing = 7, - struct_thing = DemoXtruct, - % Note that we don't set i32_thing, it will come back as undefined - % from the Python server, but 0 from the C++ server, since it is not - % optional - i32_thing = 2}, - - % Is it safe to match these things? - DemoDict = dict:from_list([ {Key, Key-10} || Key <- lists:seq(0,10) ]), - DemoSet = sets:from_list([ Key || Key <- lists:seq(-3,3) ]), - - %DemoInsane = #insanity{ - % userMap = dict:from_list([{?thriftTest_FIVE, 5000}]), - % xtructs = [#xtruct{ string_thing = <<"Truck">>, byte_thing = 8, i32_thing = 8, i64_thing = 8}]}, - - {Client01, {ok, ok}} = thrift_client:call(Client0, testVoid, []), - - {Client02, {ok, <<"Test">>}} = thrift_client:call(Client01, testString, ["Test"]), - {Client03, {ok, <<"Test">>}} = thrift_client:call(Client02, testString, [<<"Test">>]), - {Client04, {ok, 63}} = thrift_client:call(Client03, testByte, [63]), - {Client05, {ok, -1}} = thrift_client:call(Client04, testI32, [-1]), - {Client06, {ok, 0}} = thrift_client:call(Client05, testI32, [0]), - {Client07, {ok, -34359738368}} = thrift_client:call(Client06, testI64, [-34359738368]), - {Client08, {ok, -5.2098523}} = thrift_client:call(Client07, testDouble, [-5.2098523]), - %% TODO: add testBinary() call - {Client09, {ok, DemoXtruct}} = thrift_client:call(Client08, testStruct, [DemoXtruct]), - {Client10, {ok, DemoNest}} = thrift_client:call(Client09, testNest, [DemoNest]), - {Client11, {ok, DemoDict}} = thrift_client:call(Client10, testMap, [DemoDict]), - {Client12, {ok, DemoSet}} = thrift_client:call(Client11, testSet, [DemoSet]), - {Client13, {ok, [-1,2,3]}} = thrift_client:call(Client12, testList, [[-1,2,3]]), - {Client14, {ok, 1}} = thrift_client:call(Client13, testEnum, [?THRIFT_TEST_NUMBERZ_ONE]), - {Client15, {ok, 309858235082523}} = thrift_client:call(Client14, testTypedef, [309858235082523]), - - % No python implementation, but works with C++ and Erlang. - %{Client16, {ok, InsaneResult}} = thrift_client:call(Client15, testInsanity, [DemoInsane]), - %io:format("~p~n", [InsaneResult]), - Client16 = Client15, - - {Client17, {ok, #'Xtruct'{string_thing = <<"Message">>}}} = - thrift_client:call(Client16, testMultiException, ["Safe", "Message"]), - - Client18 = - try - {ClientS1, Result1} = thrift_client:call(Client17, testMultiException, ["Xception", "Message"]), - io:format("Unexpected return! ~p~n", [Result1]), - ClientS1 - catch - throw:{ClientS2, {exception, ExnS1 = #'Xception'{}}} -> - #'Xception'{errorCode = 1001, message = <<"This is an Xception">>} = ExnS1, - ClientS2; - throw:{ClientS2, {exception, _ExnS1 = #'Xception2'{}}} -> - io:format("Wrong exception type!~n", []), - ClientS2 - end, - - Client19 = - try - {ClientS3, Result2} = thrift_client:call(Client18, testMultiException, ["Xception2", "Message"]), - io:format("Unexpected return! ~p~n", [Result2]), - ClientS3 - catch - throw:{ClientS4, {exception, _ExnS2 = #'Xception'{}}} -> - io:format("Wrong exception type!~n", []), - ClientS4; - throw:{ClientS4, {exception, ExnS2 = #'Xception2'{}}} -> - #'Xception2'{errorCode = 2002, - struct_thing = #'Xtruct'{ - string_thing = <<"This is an Xception2">>}} = ExnS2, - ClientS4 - end, - - thrift_client:close(Client19). http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/lib/erl/test/test_thrift_server.erl ---------------------------------------------------------------------- diff --git a/lib/erl/test/test_thrift_server.erl b/lib/erl/test/test_thrift_server.erl deleted file mode 100644 index 1f43b72..0000000 --- a/lib/erl/test/test_thrift_server.erl +++ /dev/null @@ -1,208 +0,0 @@ -%% -%% 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. -%% - --module(test_thrift_server). - --export([go/0, go/1, start_link/2, handle_function/2]). - --include("gen-erl/thrift_test_types.hrl"). - --record(options, {port = 9090, - server_opts = []}). - -parse_args(Args) -> parse_args(Args, #options{}). -parse_args([], Opts) -> Opts; -parse_args([Head | Rest], Opts) -> - NewOpts = - case catch list_to_integer(Head) of - Port when is_integer(Port) -> - Opts#options{port = Port}; - _Else -> - case Head of - "framed" -> - Opts#options{server_opts = [{framed, true} | Opts#options.server_opts]}; - "" -> - Opts; - _Else -> - erlang:error({bad_arg, Head}) - end - end, - parse_args(Rest, NewOpts). - -go() -> go([]). -go(Args) -> - #options{port = Port, server_opts = ServerOpts} = parse_args(Args), - spawn(fun() -> start_link(Port, ServerOpts), receive after infinity -> ok end end). - -start_link(Port, ServerOpts) -> - thrift_socket_server:start([{handler, ?MODULE}, - {service, thrift_test_thrift}, - {port, Port}] ++ - ServerOpts). - - -handle_function(testVoid, {}) -> - io:format("testVoid~n"), - ok; - -handle_function(testString, {S}) when is_binary(S) -> - io:format("testString: ~p~n", [S]), - {reply, S}; - -handle_function(testByte, {I8}) when is_integer(I8) -> - io:format("testByte: ~p~n", [I8]), - {reply, I8}; - -handle_function(testI32, {I32}) when is_integer(I32) -> - io:format("testI32: ~p~n", [I32]), - {reply, I32}; - -handle_function(testI64, {I64}) when is_integer(I64) -> - io:format("testI64: ~p~n", [I64]), - {reply, I64}; - -handle_function(testDouble, {Double}) when is_float(Double) -> - io:format("testDouble: ~p~n", [Double]), - {reply, Double}; - -handle_function(testBinary, {S}) when is_binary(S) -> - io:format("testBinary: ~p~n", [S]), - {reply, S}; - -handle_function(testStruct, - {Struct = #'Xtruct'{string_thing = String, - byte_thing = Byte, - i32_thing = I32, - i64_thing = I64}}) -when is_binary(String), - is_integer(Byte), - is_integer(I32), - is_integer(I64) -> - io:format("testStruct: ~p~n", [Struct]), - {reply, Struct}; - -handle_function(testNest, - {Nest}) when is_record(Nest, 'Xtruct2'), - is_record(Nest#'Xtruct2'.struct_thing, 'Xtruct') -> - io:format("testNest: ~p~n", [Nest]), - {reply, Nest}; - -handle_function(testMap, {Map}) -> - io:format("testMap: ~p~n", [dict:to_list(Map)]), - {reply, Map}; - -handle_function(testSet, {Set}) -> - true = sets:is_set(Set), - io:format("testSet: ~p~n", [sets:to_list(Set)]), - {reply, Set}; - -handle_function(testList, {List}) when is_list(List) -> - io:format("testList: ~p~n", [List]), - {reply, List}; - -handle_function(testEnum, {Enum}) when is_integer(Enum) -> - io:format("testEnum: ~p~n", [Enum]), - {reply, Enum}; - -handle_function(testTypedef, {UserID}) when is_integer(UserID) -> - io:format("testTypedef: ~p~n", [UserID]), - {reply, UserID}; - -handle_function(testMapMap, {Hello}) -> - io:format("testMapMap: ~p~n", [Hello]), - - PosList = [{I, I} || I <- lists:seq(1, 5)], - NegList = [{-I, -I} || I <- lists:seq(1, 5)], - - MapMap = dict:from_list([{4, dict:from_list(PosList)}, - {-4, dict:from_list(NegList)}]), - {reply, MapMap}; - -handle_function(testInsanity, {Insanity}) when is_record(Insanity, 'Insanity') -> - Hello = #'Xtruct'{string_thing = <<"Hello2">>, - byte_thing = 2, - i32_thing = 2, - i64_thing = 2}, - - Goodbye = #'Xtruct'{string_thing = <<"Goodbye4">>, - byte_thing = 4, - i32_thing = 4, - i64_thing = 4}, - Crazy = #'Insanity'{ - userMap = dict:from_list([{?THRIFT_TEST_NUMBERZ_EIGHT, 8}]), - xtructs = [Goodbye] - }, - - Looney = #'Insanity'{ - userMap = dict:from_list([{?THRIFT_TEST_NUMBERZ_FIVE, 5}]), - xtructs = [Hello] - }, - - FirstMap = dict:from_list([{?THRIFT_TEST_NUMBERZ_TWO, Crazy}, - {?THRIFT_TEST_NUMBERZ_THREE, Crazy}]), - - SecondMap = dict:from_list([{?THRIFT_TEST_NUMBERZ_SIX, Looney}]), - - Insane = dict:from_list([{1, FirstMap}, - {2, SecondMap}]), - - io:format("Return = ~p~n", [Insane]), - - {reply, Insane}; - -handle_function(testMulti, Args = {Arg0, Arg1, Arg2, _Arg3, Arg4, Arg5}) - when is_integer(Arg0), - is_integer(Arg1), - is_integer(Arg2), - is_integer(Arg4), - is_integer(Arg5) -> - - io:format("testMulti(~p)~n", [Args]), - {reply, #'Xtruct'{string_thing = <<"Hello2">>, - byte_thing = Arg0, - i32_thing = Arg1, - i64_thing = Arg2}}; - -handle_function(testException, {String}) when is_binary(String) -> - io:format("testException(~p)~n", [String]), - case String of - <<"Xception">> -> - throw(#'Xception'{errorCode = 1001, - message = String}); - _ -> - ok - end; - -handle_function(testMultiException, {Arg0, Arg1}) -> - io:format("testMultiException(~p, ~p)~n", [Arg0, Arg1]), - case Arg0 of - <<"Xception">> -> - throw(#'Xception'{errorCode = 1001, - message = <<"This is an Xception">>}); - <<"Xception2">> -> - throw(#'Xception2'{errorCode = 2002, - struct_thing = - #'Xtruct'{string_thing = <<"This is an Xception2">>}}); - _ -> - {reply, #'Xtruct'{string_thing = Arg1}} - end; - -handle_function(testOneway, {Seconds}) -> - timer:sleep(1000 * Seconds), - ok. http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/lib/erl/test/thrift_test_test.erl ---------------------------------------------------------------------- diff --git a/lib/erl/test/thrift_test_test.erl b/lib/erl/test/thrift_test_test.erl new file mode 100644 index 0000000..e506437 --- /dev/null +++ b/lib/erl/test/thrift_test_test.erl @@ -0,0 +1,655 @@ +%% +%% 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. +%% + +% don't rename this thrift_test, it clobbers generated files +-module(thrift_test_test). +-compile(export_all). + +-include_lib("eunit/include/eunit.hrl"). + +-include("gen-erl/thrift_test_constants.hrl"). + +constant_test_() -> + [ + {"myNumberz equals 1", ?_assertEqual(1, ?THRIFT_TEST_MYNUMBERZ)} + ]. + +record_generation_test_() -> + [ + {"Bonk record", ?_assertMatch( + {'Bonk', _, _}, + #'Bonk'{message=null,type=null} + )}, + {"Bools record", ?_assertMatch( + {'Bools', _, _}, + #'Bools'{im_true=null,im_false=null} + )}, + {"Xtruct record", ?_assertMatch( + {'Xtruct', _, _, _, _}, + #'Xtruct'{string_thing=null,byte_thing=null,i32_thing=null,i64_thing=null} + )}, + {"Xtruct2 record", ?_assertMatch( + {'Xtruct2', _, _, _}, + #'Xtruct2'{byte_thing=null,struct_thing=null,i32_thing=null} + )}, + {"Xtruct3 record", ?_assertMatch( + {'Xtruct3', _, _, _, _}, + #'Xtruct3'{string_thing=null,changed=null,i32_thing=null,i64_thing=null} + )}, + {"Insanity record", ?_assertMatch( + {'Insanity', _, _}, + #'Insanity'{userMap=null,xtructs=null} + )}, + {"CrazyNesting record", ?_assertMatch( + {'CrazyNesting', _, _, _, _}, + #'CrazyNesting'{ + string_field=null, + set_field=null, + list_field=null, + binary_field=null + } + )}, + {"Xception record", ?_assertMatch( + {'Xception', _, _}, + #'Xception'{errorCode=null,message=null} + )}, + {"Xception2 record", ?_assertMatch( + {'Xception2', _, _}, + #'Xception2'{errorCode=null,struct_thing=null} + )}, + {"EmptyStruct record", ?_assertMatch({'EmptyStruct'}, #'EmptyStruct'{})}, + {"OneField record", ?_assertMatch({'OneField', _}, #'OneField'{field=null})}, + {"VersioningTestV1 record", ?_assertMatch( + {'VersioningTestV1', _, _, _}, + #'VersioningTestV1'{begin_in_both=null,old_string=null,end_in_both=null} + )}, + {"VersioningTestV2 record", ?_assertMatch( + {'VersioningTestV2', _, _, _, _, _, _, _, _, _, _, _, _}, + #'VersioningTestV2'{ + begin_in_both=null, + newint=null, + newbyte=null, + newshort=null, + newlong=null, + newdouble=null, + newstruct=null, + newlist=null, + newset=null, + newmap=null, + newstring=null, + end_in_both=null + } + )}, + {"ListTypeVersioningV1 record", ?_assertMatch( + {'ListTypeVersioningV1', _, _}, + #'ListTypeVersioningV1'{myints=null,hello=null} + )}, + {"ListTypeVersioningV2 record", ?_assertMatch( + {'ListTypeVersioningV2', _, _}, + #'ListTypeVersioningV2'{strings=null,hello=null} + )}, + {"GuessProtocolStruct record", ?_assertMatch( + {'GuessProtocolStruct', _}, + #'GuessProtocolStruct'{map_field=null} + )}, + {"LargeDeltas record", ?_assertMatch( + {'LargeDeltas', _, _, _, _, _, _, _, _, _, _}, + #'LargeDeltas'{ + b1=null, + b10=null, + b100=null, + check_true=null, + b1000=null, + check_false=null, + vertwo2000=null, + a_set2500=null, + vertwo3000=null, + big_numbers=null + } + )}, + {"NestedListsI32x2 record", ?_assertMatch( + {'NestedListsI32x2', _}, + #'NestedListsI32x2'{integerlist=null} + )}, + {"NestedListsI32x3 record", ?_assertMatch( + {'NestedListsI32x3', _}, + #'NestedListsI32x3'{integerlist=null} + )}, + {"NestedMixedx2 record", ?_assertMatch( + {'NestedMixedx2', _, _, _}, + #'NestedMixedx2'{ + int_set_list=null, + map_int_strset=null, + map_int_strset_list=null + } + )}, + {"ListBonks record", ?_assertMatch({'ListBonks', _}, #'ListBonks'{bonk=null})}, + {"NestedListsBonk record", ?_assertMatch( + {'NestedListsBonk', _}, + #'NestedListsBonk'{bonk=null} + )}, + {"BoolTest record", ?_assertMatch( + {'BoolTest', _, _}, + #'BoolTest'{b=null,s=null} + )}, + {"StructA record", ?_assertMatch({'StructA', _}, #'StructA'{s=null})}, + {"StructB record", ?_assertMatch( + {'StructB', _, _}, + #'StructB'{aa=null,ab=null} + )} + ]. + +struct_info_test_() -> + [ + {"Bonk definition (short version)", ?_assertEqual( + {struct, [{1, string}, {2, i32}]}, + thrift_test_types:struct_info('Bonk') + )}, + {"Bonk definition", ?_assertEqual( + {struct, [ + {1, undefined, string, message, undefined}, + {2, undefined, i32, type, undefined} + ]}, + thrift_test_types:struct_info_ext('Bonk') + )}, + {"Bools definition", ?_assertEqual( + {struct, [ + {1, undefined, bool, im_true, undefined}, + {2, undefined, bool, im_false, undefined} + ]}, + thrift_test_types:struct_info_ext('Bools') + )}, + {"Xtruct definition", ?_assertEqual( + {struct, [ + {1, undefined, string, string_thing, undefined}, + {4, undefined, byte, byte_thing, undefined}, + {9, undefined, i32, i32_thing, undefined}, + {11, undefined, i64, i64_thing, undefined} + ]}, + thrift_test_types:struct_info_ext('Xtruct') + )}, + {"Xtruct2 definition", ?_assertEqual( + {struct, [ + {1, undefined, byte, byte_thing, undefined}, + {2, undefined, {struct, {'thrift_test_types', 'Xtruct'}}, struct_thing, #'Xtruct'{}}, + {3, undefined, i32, i32_thing, undefined} + ]}, + thrift_test_types:struct_info_ext('Xtruct2') + )}, + {"Xtruct3 definition", ?_assertEqual( + {struct, [ + {1, undefined, string, string_thing, undefined}, + {4, undefined, i32, changed, undefined}, + {9, undefined, i32, i32_thing, undefined}, + {11, undefined, i64, i64_thing, undefined} + ]}, + thrift_test_types:struct_info_ext('Xtruct3') + )}, + {"Insanity definition", ?_assertEqual( + {struct, [ + {1, undefined, {map, i32, i64}, userMap, dict:new()}, + {2, undefined, {list, {struct, {'thrift_test_types', 'Xtruct'}}}, xtructs, []} + ]}, + thrift_test_types:struct_info_ext('Insanity') + )}, + {"CrazyNesting definition", ?_assertEqual( + {struct, [ + {1, undefined, string, string_field, undefined}, + {2, optional, {set, {struct, {'thrift_test_types', 'Insanity'}}}, set_field, sets:new()}, + {3, required, {list, {map, + {set, i32}, + {map, i32, {set, {list, {map, {struct, {'thrift_test_types', 'Insanity'}}, string}}}} + }}, list_field, []}, + {4, undefined, string, binary_field, undefined} + ]}, + thrift_test_types:struct_info_ext('CrazyNesting') + )}, + {"Xception definition", ?_assertEqual( + {struct, [ + {1, undefined, i32, errorCode, undefined}, + {2, undefined, string, message, undefined} + ]}, + thrift_test_types:struct_info_ext('Xception') + )}, + {"Xception2 definition", ?_assertEqual( + {struct, [ + {1, undefined, i32, errorCode, undefined}, + {2, undefined, {struct, {'thrift_test_types', 'Xtruct'}}, struct_thing, #'Xtruct'{}} + ]}, + thrift_test_types:struct_info_ext('Xception2') + )}, + {"EmptyStruct definition", ?_assertEqual( + {struct, []}, + thrift_test_types:struct_info_ext('EmptyStruct') + )}, + {"OneField definition", ?_assertEqual( + {struct, [ + {1, undefined, {struct, {'thrift_test_types', 'EmptyStruct'}}, field, #'EmptyStruct'{}} + ]}, + thrift_test_types:struct_info_ext('OneField') + )}, + {"VersioningTestV1 definition", ?_assertEqual( + {struct, [ + {1, undefined, i32, begin_in_both, undefined}, + {3, undefined, string, old_string, undefined}, + {12, undefined, i32, end_in_both, undefined} + ]}, + thrift_test_types:struct_info_ext('VersioningTestV1') + )}, + {"VersioningTestV2 definition", ?_assertEqual( + {struct, [ + {1, undefined, i32, begin_in_both, undefined}, + {2, undefined, i32, newint, undefined}, + {3, undefined, byte, newbyte, undefined}, + {4, undefined, i16, newshort, undefined}, + {5, undefined, i64, newlong, undefined}, + {6, undefined, double, newdouble, undefined}, + {7, undefined, {struct, {thrift_test_types, 'Bonk'}}, newstruct, #'Bonk'{}}, + {8, undefined, {list, i32}, newlist, []}, + {9, undefined, {set, i32}, newset, sets:new()}, + {10, undefined, {map, i32, i32}, newmap, dict:new()}, + {11, undefined, string, newstring, undefined}, + {12, undefined, i32, end_in_both, undefined} + ]}, + thrift_test_types:struct_info_ext('VersioningTestV2') + )}, + {"ListTypeVersioningV1 definition", ?_assertEqual( + {struct, [ + {1, undefined, {list, i32}, myints, []}, + {2, undefined, string, hello, undefined} + ]}, + thrift_test_types:struct_info_ext('ListTypeVersioningV1') + )}, + {"ListTypeVersioningV2 definition", ?_assertEqual( + {struct, [ + {1, undefined, {list, string}, strings, []}, + {2, undefined, string, hello, undefined} + ]}, + thrift_test_types:struct_info_ext('ListTypeVersioningV2') + )}, + {"GuessProtocolStruct definition", ?_assertEqual( + {struct, [ + {7, undefined, {map, string, string}, map_field, dict:new()} + ]}, + thrift_test_types:struct_info_ext('GuessProtocolStruct') + )}, + {"LargeDeltas definition", ?_assertEqual( + {struct, [ + {1, undefined, {struct, {thrift_test_types, 'Bools'}}, b1, #'Bools'{}}, + {10, undefined, {struct, {thrift_test_types, 'Bools'}}, b10, #'Bools'{}}, + {100, undefined, {struct, {thrift_test_types, 'Bools'}}, b100, #'Bools'{}}, + {500, undefined, bool, check_true, undefined}, + {1000, undefined, {struct, {thrift_test_types, 'Bools'}}, b1000, #'Bools'{}}, + {1500, undefined, bool, check_false, undefined}, + {2000, undefined, {struct, {thrift_test_types, 'VersioningTestV2'}}, vertwo2000, #'VersioningTestV2'{}}, + {2500, undefined, {set, string}, a_set2500, sets:new()}, + {3000, undefined, {struct, {thrift_test_types, 'VersioningTestV2'}}, vertwo3000, #'VersioningTestV2'{}}, + {4000, undefined, {list, i32}, big_numbers, []} + ]}, + thrift_test_types:struct_info_ext('LargeDeltas') + )}, + {"NestedListsI32x2 definition", ?_assertEqual( + {struct, [ + {1, undefined, {list, {list, i32}}, integerlist, []} + ]}, + thrift_test_types:struct_info_ext('NestedListsI32x2') + )}, + {"NestedListsI32x3 definition", ?_assertEqual( + {struct, [ + {1, undefined, {list, {list, {list, i32}}}, integerlist, []} + ]}, + thrift_test_types:struct_info_ext('NestedListsI32x3') + )}, + {"NestedMixedx2 definition", ?_assertEqual( + {struct, [ + {1, undefined, {list, {set, i32}}, int_set_list, []}, + {2, undefined, {map, i32, {set, string}}, map_int_strset, dict:new()}, + {3, undefined, {list, {map, i32, {set, string}}}, map_int_strset_list, []} + ]}, + thrift_test_types:struct_info_ext('NestedMixedx2') + )}, + {"ListBonks definition", ?_assertEqual( + {struct, [ + {1, undefined, {list, {struct, {thrift_test_types, 'Bonk'}}}, bonk, []} + ]}, + thrift_test_types:struct_info_ext('ListBonks') + )}, + {"NestedListsBonk definition", ?_assertEqual( + {struct, [ + {1, undefined, {list, {list, {list, {struct, {thrift_test_types, 'Bonk'}}}}}, bonk, []} + ]}, + thrift_test_types:struct_info_ext('NestedListsBonk') + )}, + {"BoolTest definition", ?_assertEqual( + {struct, [ + {1, optional, bool, b, true}, + {2, optional, string, s, "true"} + ]}, + thrift_test_types:struct_info_ext('BoolTest') + )}, + {"StructA definition", ?_assertEqual( + {struct, [{1, required, string, s, undefined}]}, + thrift_test_types:struct_info_ext('StructA') + )}, + {"StructB definition", ?_assertEqual( + {struct, [ + {1, optional, {struct, {thrift_test_types, 'StructA'}}, aa, #'StructA'{}}, + {2, required, {struct, {thrift_test_types, 'StructA'}}, ab, #'StructA'{}} + ]}, + thrift_test_types:struct_info_ext('StructB') + )} + ]. + +service_info_test_() -> + [ + {"testVoid params", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testVoid, params_type) + )}, + {"testVoid reply", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testVoid, reply_type) + )}, + {"testVoid exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testVoid, exceptions) + )}, + {"testString params", ?_assertEqual( + {struct, [{1, string}]}, + thrift_test_thrift:function_info(testString, params_type) + )}, + {"testString reply", ?_assertEqual( + string, + thrift_test_thrift:function_info(testString, reply_type) + )}, + {"testString exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testString, exceptions) + )}, + {"testByte params", ?_assertEqual( + {struct, [{1, byte}]}, + thrift_test_thrift:function_info(testByte, params_type) + )}, + {"testByte reply", ?_assertEqual( + byte, + thrift_test_thrift:function_info(testByte, reply_type) + )}, + {"testByte exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testByte, exceptions) + )}, + {"testI32 params", ?_assertEqual( + {struct, [{1, i32}]}, + thrift_test_thrift:function_info(testI32, params_type) + )}, + {"testI32 reply", ?_assertEqual( + i32, + thrift_test_thrift:function_info(testI32, reply_type) + )}, + {"testI32 exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testI32, exceptions) + )}, + {"testI64 params", ?_assertEqual( + {struct, [{1, i64}]}, + thrift_test_thrift:function_info(testI64, params_type) + )}, + {"testI64 reply", ?_assertEqual( + i64, + thrift_test_thrift:function_info(testI64, reply_type) + )}, + {"testI64 exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testI64, exceptions) + )}, + {"testDouble params", ?_assertEqual( + {struct, [{1, double}]}, + thrift_test_thrift:function_info(testDouble, params_type) + )}, + {"testDouble reply", ?_assertEqual( + double, + thrift_test_thrift:function_info(testDouble, reply_type) + )}, + {"testDouble exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testDouble, exceptions) + )}, + {"testStruct params", ?_assertEqual( + {struct, [ + {1, {struct, {thrift_test_types, 'Xtruct'}}} + ]}, + thrift_test_thrift:function_info(testStruct, params_type) + )}, + {"testStruct reply", ?_assertEqual( + {struct, {thrift_test_types, 'Xtruct'}}, + thrift_test_thrift:function_info(testStruct, reply_type) + )}, + {"testStruct exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testStruct, exceptions) + )}, + {"testNest params", ?_assertEqual( + {struct, [ + {1, {struct, {thrift_test_types, 'Xtruct2'}}} + ]}, + thrift_test_thrift:function_info(testNest, params_type) + )}, + {"testNest reply", ?_assertEqual( + {struct, {thrift_test_types, 'Xtruct2'}}, + thrift_test_thrift:function_info(testNest, reply_type) + )}, + {"testNest exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testNest, exceptions) + )}, + {"testMap params", ?_assertEqual( + {struct, [ + {1, {map, i32, i32}} + ]}, + thrift_test_thrift:function_info(testMap, params_type) + )}, + {"testMap reply", ?_assertEqual( + {map, i32, i32}, + thrift_test_thrift:function_info(testMap, reply_type) + )}, + {"testMap exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testMap, exceptions) + )}, + {"testStringMap params", ?_assertEqual( + {struct, [ + {1, {map, string, string}} + ]}, + thrift_test_thrift:function_info(testStringMap, params_type) + )}, + {"testStringMap reply", ?_assertEqual( + {map, string, string}, + thrift_test_thrift:function_info(testStringMap, reply_type) + )}, + {"testStringMap exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testStringMap, exceptions) + )}, + {"testSet params", ?_assertEqual( + {struct, [ + {1, {set, i32}} + ]}, + thrift_test_thrift:function_info(testSet, params_type) + )}, + {"testSet reply", ?_assertEqual( + {set, i32}, + thrift_test_thrift:function_info(testSet, reply_type) + )}, + {"testSet exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testSet, exceptions) + )}, + {"testList params", ?_assertEqual( + {struct, [ + {1, {list, i32}} + ]}, + thrift_test_thrift:function_info(testList, params_type) + )}, + {"testList reply", ?_assertEqual( + {list, i32}, + thrift_test_thrift:function_info(testList, reply_type) + )}, + {"testList exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testList, exceptions) + )}, + {"testEnum params", ?_assertEqual( + {struct, [ + {1, i32} + ]}, + thrift_test_thrift:function_info(testEnum, params_type) + )}, + {"testEnum reply", ?_assertEqual( + i32, + thrift_test_thrift:function_info(testEnum, reply_type) + )}, + {"testEnum exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testEnum, exceptions) + )}, + {"testTypedef params", ?_assertEqual( + {struct, [{1, i64}]}, + thrift_test_thrift:function_info(testTypedef, params_type) + )}, + {"testTypedef reply", ?_assertEqual( + i64, + thrift_test_thrift:function_info(testTypedef, reply_type) + )}, + {"testTypedef exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testTypedef, exceptions) + )}, + {"testMapMap params", ?_assertEqual( + {struct, [ + {1, i32} + ]}, + thrift_test_thrift:function_info(testMapMap, params_type) + )}, + {"testMapMap reply", ?_assertEqual( + {map, i32, {map, i32,i32}}, + thrift_test_thrift:function_info(testMapMap, reply_type) + )}, + {"testMapMap exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testMapMap, exceptions) + )}, + {"testInsanity params", ?_assertEqual( + {struct, [ + {1, {struct, {thrift_test_types, 'Insanity'}}} + ]}, + thrift_test_thrift:function_info(testInsanity, params_type) + )}, + {"testInsanity reply", ?_assertEqual( + {map, i64, {map, i32, {struct, {'thrift_test_types', 'Insanity'}}}}, + thrift_test_thrift:function_info(testInsanity, reply_type) + )}, + {"testInsanity exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testInsanity, exceptions) + )}, + {"testMulti params", ?_assertEqual( + {struct, [ + {1, byte}, + {2, i32}, + {3, i64}, + {4, {map, i16, string}}, + {5, i32}, + {6, i64} + ]}, + thrift_test_thrift:function_info(testMulti, params_type) + )}, + {"testMulti reply", ?_assertEqual( + {struct, {thrift_test_types, 'Xtruct'}}, + thrift_test_thrift:function_info(testMulti, reply_type) + )}, + {"testMulti exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testMulti, exceptions) + )}, + {"testException params", ?_assertEqual( + {struct, [{1, string}]}, + thrift_test_thrift:function_info(testException, params_type) + )}, + {"testException reply", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testException, reply_type) + )}, + {"testException exceptions", ?_assertEqual( + {struct, [ + {1, {struct, {thrift_test_types, 'Xception'}}} + ]}, + thrift_test_thrift:function_info(testException, exceptions) + )}, + {"testMultiException params", ?_assertEqual( + {struct, [{1, string}, {2, string}]}, + thrift_test_thrift:function_info(testMultiException, params_type) + )}, + {"testMultiException reply", ?_assertEqual( + {struct, {thrift_test_types, 'Xtruct'}}, + thrift_test_thrift:function_info(testMultiException, reply_type) + )}, + {"testMultiException exceptions", ?_assertEqual( + {struct, [ + {1, {struct, {thrift_test_types, 'Xception'}}}, + {2, {struct, {thrift_test_types, 'Xception2'}}} + ]}, + thrift_test_thrift:function_info(testMultiException, exceptions) + )}, + {"testOneway params", ?_assertEqual( + {struct, [{1, i32}]}, + thrift_test_thrift:function_info(testOneway, params_type) + )}, + {"testOneway reply", ?_assertEqual( + oneway_void, + thrift_test_thrift:function_info(testOneway, reply_type) + )}, + {"testOneway exceptions", ?_assertEqual( + {struct, []}, + thrift_test_thrift:function_info(testOneway, exceptions) + )}, + {"blahBlah params", ?_assertEqual( + {struct, []}, + second_service_thrift:function_info(blahBlah, params_type) + )}, + {"blahBlah reply", ?_assertEqual( + {struct, []}, + second_service_thrift:function_info(blahBlah, reply_type) + )}, + {"blahBlah exceptions", ?_assertEqual( + {struct, []}, + second_service_thrift:function_info(blahBlah, exceptions) + )}, + {"secondtestString params", ?_assertEqual( + {struct, [{1, string}]}, + second_service_thrift:function_info(secondtestString, params_type) + )}, + {"secondtestString reply", ?_assertEqual( + string, + second_service_thrift:function_info(secondtestString, reply_type) + )}, + {"secondtestString exceptions", ?_assertEqual( + {struct, []}, + second_service_thrift:function_info(secondtestString, exceptions) + )} + ]. http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/test/Makefile.am ---------------------------------------------------------------------- diff --git a/test/Makefile.am b/test/Makefile.am index 7590921..593b1c4 100755 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -72,6 +72,7 @@ endif if WITH_ERLANG SUBDIRS += erl +PRECROSS_TARGET += precross-erl endif # http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/test/erl/LegacyNames.thrift ---------------------------------------------------------------------- diff --git a/test/erl/LegacyNames.thrift b/test/erl/LegacyNames.thrift deleted file mode 100644 index 38f2729..0000000 --- a/test/erl/LegacyNames.thrift +++ /dev/null @@ -1,33 +0,0 @@ -enum Numberz -{ - ONE = 1, - TWO, - THREE, - FIVE = 5, - SIX, - EIGHT = 8 -} - -const Numberz myNumberz = Numberz.ONE; - -struct CapitalizedStruct -{ - 1: i32 Id, - 2: binary message -} - -struct ListCapitalizedStructs -{ - 1: list<CapitalizedStruct> structs -} - -exception Xception { - 1: i32 errorCode, - 2: binary message -} - -service LegacyNames -{ - ListCapitalizedStructs Names(1: CapitalizedStruct foo, 2: CapitalizedStruct bar) - throws(1: Xception err) -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/test/erl/Makefile.am ---------------------------------------------------------------------- diff --git a/test/erl/Makefile.am b/test/erl/Makefile.am index 1940ce3..b489d8e 100644 --- a/test/erl/Makefile.am +++ b/test/erl/Makefile.am @@ -22,19 +22,23 @@ REBAR = $(top_srcdir)/lib/erl/rebar THRIFT_FILES = $(wildcard ../*.thrift) +if ERLANG_OTP16 +ERL_FLAG = erl:otp16 +else +ERL_FLAG = erl +endif # make sure ThriftTest.thrift is generated last to prevent conflicts with other *.thrift files .generated: $(THRIFT_FILES) for f in $(THRIFT_FILES) ; do \ - $(THRIFT) --gen erl $$f ; \ + $(THRIFT) --gen $(ERL_FLAG) -o src $$f ; \ done ; \ - $(THRIFT) --gen erl:legacynames LegacyNames.thrift - $(THRIFT) --gen erl ../ThriftTest.thrift + $(THRIFT) --gen $(ERL_FLAG) -o src ../ThriftTest.thrift touch .generated -check: .generated - $(REBAR) eunit +precross: .generated + $(REBAR) compile clean: rm -f .generated - rm -rf gen-erl + rm -rf src/gen-erl $(REBAR) clean http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/test/erl/rebar.config ---------------------------------------------------------------------- diff --git a/test/erl/rebar.config b/test/erl/rebar.config index 6035849..59a0788 100644 --- a/test/erl/rebar.config +++ b/test/erl/rebar.config @@ -1,5 +1,6 @@ +{sub_dirs, ["../../lib/erl"]}. + {erl_opts, [ debug_info, - {i, ["gen-erl"]}, - {src_dirs, ["gen-erl"]} + {i, "../../lib/erl/include"} ]}. http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/test/erl/src/legacy_names_test.erl ---------------------------------------------------------------------- diff --git a/test/erl/src/legacy_names_test.erl b/test/erl/src/legacy_names_test.erl deleted file mode 100644 index 2ace7d0..0000000 --- a/test/erl/src/legacy_names_test.erl +++ /dev/null @@ -1,69 +0,0 @@ -%% -%% 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. -%% - --module(legacy_names_test). --compile(export_all). - --include_lib("eunit/include/eunit.hrl"). - --include("legacyNames_constants.hrl"). - -record_generation_test_() -> - [ - {"capitalizedStruct record", ?_assertMatch( - {capitalizedStruct, _, _}, - #capitalizedStruct{id=null,message=null} - )} - ]. - -struct_info_test_() -> - [ - {"capitalizedStruct extended definition", ?_assertEqual( - {struct, [ - {1, undefined, i32, 'id', undefined}, - {2, undefined, string, 'message', undefined} - ]}, - legacyNames_types:struct_info_ext(capitalizedStruct) - )}, - {"listCapitalizedStructs extended definition", ?_assertEqual( - {struct, [ - {1, undefined, {list, {struct, {'legacyNames_types', 'capitalizedStruct'}}}, 'structs', []} - ]}, - legacyNames_types:struct_info_ext(listCapitalizedStructs) - )} - ]. - -service_info_test_() -> - [ - {"names params", ?_assertEqual( - {struct, [ - {1, {struct, {'legacyNames_types', 'capitalizedStruct'}}}, - {2, {struct, {'legacyNames_types', 'capitalizedStruct'}}} - ]}, - legacyNames_thrift:function_info(names, params_type) - )}, - {"names reply", ?_assertEqual( - {struct, {'legacyNames_types', 'listCapitalizedStructs'}}, - legacyNames_thrift:function_info(names, reply_type) - )}, - {"names exceptions", ?_assertEqual( - {struct, [{1, {struct, {'legacyNames_types', 'xception'}}}]}, - legacyNames_thrift:function_info(names, exceptions) - )} - ]. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/test/erl/src/name_conflict_test.erl ---------------------------------------------------------------------- diff --git a/test/erl/src/name_conflict_test.erl b/test/erl/src/name_conflict_test.erl deleted file mode 100644 index 5576ffa..0000000 --- a/test/erl/src/name_conflict_test.erl +++ /dev/null @@ -1,299 +0,0 @@ -%% -%% 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. -%% - --module(name_conflict_test). --compile(export_all). - --include_lib("eunit/include/eunit.hrl"). - --include("name_conflict_test_constants.hrl"). - -record_generation_test_() -> - [ - {"using record", ?_assertMatch( - {using, _, _}, - #using{single=null,integer=null} - )}, - {"delegate record", ?_assertMatch( - {delegate, _, _}, - #delegate{partial=null,delegate=null} - )}, - {"get record", ?_assertMatch( - {get, _}, - #get{sbyte=null} - )}, - {"partial record", ?_assertMatch( - {partial, _, _, _}, - #partial{using=null} - )}, - {"ClassAndProp record", ?_assertMatch( - {'ClassAndProp', _, _, _, _}, - #'ClassAndProp'{ - 'ClassAndProp'=null, - 'ClassAndProp_'=null, - 'ClassAndProp__'=null, - 'ClassAndProper'=null - } - )}, - {"second_chance record", ?_assertMatch( - {second_chance, _, _, _, _}, - #second_chance{ - 'SECOND_CHANCE'=null, - 'SECOND_CHANCE_'=null, - 'SECOND_CHANCE__'=null, - 'SECOND_CHANCES'=null - } - )}, - {"NOW_EAT_THIS record", ?_assertMatch( - {'NOW_EAT_THIS', _, _, _, _}, - #'NOW_EAT_THIS'{ - now_eat_this=null, - now_eat_this_=null, - now_eat_this__=null, - now_eat_this_and_this=null - } - )}, - {"TheEdgeCase record", ?_assertMatch( - {'TheEdgeCase', _, _, _, _, _, _}, - #'TheEdgeCase'{ - theEdgeCase=null, - theEdgeCase_=null, - theEdgeCase__=null, - 'TheEdgeCase'=null, - 'TheEdgeCase_'=null, - 'TheEdgeCase__'=null - } - )}, - {"Tricky_ record", ?_assertMatch( - {'Tricky_', _, _}, - #'Tricky_'{tricky=null,'Tricky'=null} - )}, - {"Nested record", ?_assertMatch( - {'Nested', _, _, _, _, _, _}, - #'Nested'{ - 'ClassAndProp'=null, - second_chance=null, - 'NOW_EAT_THIS'=null, - 'TheEdgeCase'=null, - 'Tricky_'=null, - 'Nested'=null - } - )}, - {"Problem_ record", ?_assertMatch( - {'Problem_', _, _}, - #'Problem_'{problem=null,'Problem'=null} - )} - ]. - -struct_info_test_() -> - [ - {"using definition", ?_assertEqual( - {struct, [{1, double},{2, double}]}, - name_conflict_test_types:struct_info(using) - )}, - {"delegate definition", ?_assertEqual( - {struct, [ - {1, string}, - {2, {struct, {name_conflict_test_types, delegate}}} - ]}, - name_conflict_test_types:struct_info(delegate) - )}, - {"get definition", ?_assertEqual( - {struct, [{1, bool}]}, - name_conflict_test_types:struct_info(get) - )}, - {"partial definition", ?_assertEqual( - {struct, [ - {1, {struct, {name_conflict_test_types, using}}}, - {2, bool}, - {3, bool} - ]}, - name_conflict_test_types:struct_info(partial) - )}, - {"ClassAndProp definition", ?_assertEqual( - {struct, [{1, bool},{2, bool},{3, bool},{4, bool}]}, - name_conflict_test_types:struct_info('ClassAndProp') - )}, - {"second_chance definition", ?_assertEqual( - {struct, [{1, bool},{2, bool},{3, bool},{4, bool}]}, - name_conflict_test_types:struct_info(second_chance) - )}, - {"NOW_EAT_THIS definition", ?_assertEqual( - {struct, [{1, bool},{2, bool},{3, bool},{4, bool}]}, - name_conflict_test_types:struct_info('NOW_EAT_THIS') - )}, - {"TheEdgeCase definition", ?_assertEqual( - {struct, [{1, bool},{2, bool},{3, bool},{4, bool},{5, bool},{6, bool}]}, - name_conflict_test_types:struct_info('TheEdgeCase') - )}, - {"Tricky_ definition", ?_assertEqual( - {struct, [{1, bool},{2, bool}]}, - name_conflict_test_types:struct_info('Tricky_') - )}, - {"Nested definition", ?_assertEqual( - {struct, [ - {1, {struct, {name_conflict_test_types, 'ClassAndProp'}}}, - {2, {struct, {name_conflict_test_types, second_chance}}}, - {3, {struct, {name_conflict_test_types, 'NOW_EAT_THIS'}}}, - {4, {struct, {name_conflict_test_types, 'TheEdgeCase'}}}, - {5, {struct, {name_conflict_test_types, 'Tricky_'}}}, - {6, {struct, {name_conflict_test_types, 'Nested'}}} - ]}, - name_conflict_test_types:struct_info('Nested') - )}, - {"Problem_ definition", ?_assertEqual( - {struct, [{1, bool},{2, bool}]}, - name_conflict_test_types:struct_info('Problem_') - )}, - {"using extended definition", ?_assertEqual( - {struct, [ - {1, undefined, double, single, undefined}, - {2, undefined, double, integer, undefined} - ]}, - name_conflict_test_types:struct_info_ext(using) - )}, - {"delegate extended definition", ?_assertEqual( - {struct, [ - {1, undefined, string, partial, undefined}, - {2, undefined, {struct, {name_conflict_test_types, delegate}}, delegate, undefined} - ]}, - name_conflict_test_types:struct_info_ext(delegate) - )}, - {"get extended definition", ?_assertEqual( - {struct, [{1, undefined, bool, sbyte, undefined}]}, - name_conflict_test_types:struct_info_ext(get) - )}, - {"partial extended definition", ?_assertEqual( - {struct, [ - {1, undefined, {struct, {name_conflict_test_types, using}}, using, #using{}}, - {2, undefined, bool, read, undefined}, - {3, undefined, bool, write, undefined} - ]}, - name_conflict_test_types:struct_info_ext(partial) - )}, - {"ClassAndProp extended definition", ?_assertEqual( - {struct, [ - {1, undefined, bool, 'ClassAndProp', undefined}, - {2, undefined, bool, 'ClassAndProp_', undefined}, - {3, undefined, bool, 'ClassAndProp__', undefined}, - {4, undefined, bool, 'ClassAndProper', undefined} - ]}, - name_conflict_test_types:struct_info_ext('ClassAndProp') - )}, - {"second_chance extended definition", ?_assertEqual( - {struct, [ - {1, undefined, bool, 'SECOND_CHANCE', undefined}, - {2, undefined, bool, 'SECOND_CHANCE_', undefined}, - {3, undefined, bool, 'SECOND_CHANCE__', undefined}, - {4, undefined, bool, 'SECOND_CHANCES', undefined} - ]}, - name_conflict_test_types:struct_info_ext(second_chance) - )}, - {"NOW_EAT_THIS extended definition", ?_assertEqual( - {struct, [ - {1, undefined, bool, now_eat_this, undefined}, - {2, undefined, bool, now_eat_this_, undefined}, - {3, undefined, bool, now_eat_this__, undefined}, - {4, undefined, bool, now_eat_this_and_this, undefined} - ]}, - name_conflict_test_types:struct_info_ext('NOW_EAT_THIS') - )}, - {"TheEdgeCase extended definition", ?_assertEqual( - {struct, [ - {1, undefined, bool, theEdgeCase, undefined}, - {2, undefined, bool, theEdgeCase_, undefined}, - {3, undefined, bool, theEdgeCase__, undefined}, - {4, undefined, bool, 'TheEdgeCase', undefined}, - {5, undefined, bool, 'TheEdgeCase_', undefined}, - {6, undefined, bool, 'TheEdgeCase__', undefined} - ]}, - name_conflict_test_types:struct_info_ext('TheEdgeCase') - )}, - {"Tricky_ extended definition", ?_assertEqual( - {struct, [ - {1, undefined, bool, tricky, undefined}, - {2, undefined, bool, 'Tricky', undefined} - ]}, - name_conflict_test_types:struct_info_ext('Tricky_') - )}, - {"Nested extended definition", ?_assertEqual( - {struct, [ - {1, undefined, {struct, { - name_conflict_test_types, - 'ClassAndProp' - }}, 'ClassAndProp', #'ClassAndProp'{}}, - {2, undefined, {struct, { - name_conflict_test_types, - second_chance - }}, second_chance, #second_chance{}}, - {3, undefined, {struct, { - name_conflict_test_types, - 'NOW_EAT_THIS' - }}, 'NOW_EAT_THIS', #'NOW_EAT_THIS'{}}, - {4, undefined, {struct, { - name_conflict_test_types, - 'TheEdgeCase' - }}, 'TheEdgeCase', #'TheEdgeCase'{}}, - {5, undefined, {struct, { - name_conflict_test_types, - 'Tricky_' - }}, 'Tricky_', #'Tricky_'{}}, - {6, undefined, {struct, { - name_conflict_test_types, - 'Nested' - }}, 'Nested', undefined} - ]}, - name_conflict_test_types:struct_info_ext('Nested') - )}, - {"Problem_ extended definition", ?_assertEqual( - {struct, [ - {1, undefined, bool, problem, undefined}, - {2, undefined, bool, 'Problem', undefined} - ]}, - name_conflict_test_types:struct_info_ext('Problem_') - )} - ]. - -service_info_test_() -> - [ - {"event params", ?_assertEqual( - {struct, [{1, {struct, {name_conflict_test_types, partial}}}]}, - extern_thrift:function_info(event, params_type) - )}, - {"event reply", ?_assertEqual( - {struct, {name_conflict_test_types, delegate}}, - extern_thrift:function_info(event, reply_type) - )}, - {"event exceptions", ?_assertEqual( - {struct, []}, - extern_thrift:function_info(event, exceptions) - )}, - {"Foo params", ?_assertEqual( - {struct, [{1, {struct, {name_conflict_test_types, 'Nested'}}}]}, - extern_thrift:function_info('Foo', params_type) - )}, - {"Foo reply", ?_assertEqual( - {struct, []}, - extern_thrift:function_info('Foo', reply_type) - )}, - {"Foo exceptions", ?_assertEqual( - {struct, [{1, {struct, {name_conflict_test_types, 'Problem_'}}}]}, - extern_thrift:function_info('Foo', exceptions) - )} - ]. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/thrift/blob/826ea998/test/erl/src/test_client.erl ---------------------------------------------------------------------- diff --git a/test/erl/src/test_client.erl b/test/erl/src/test_client.erl new file mode 100644 index 0000000..fad0988 --- /dev/null +++ b/test/erl/src/test_client.erl @@ -0,0 +1,139 @@ +%% +%% 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. +%% + +-module(test_client). + +-export([start/0, start/1]). + +-include("gen-erl/thrift_test_types.hrl"). + +-record(options, {port = 9090, + client_opts = []}). + +parse_args(Args) -> parse_args(Args, #options{}). +parse_args([], Opts) -> + Opts; +parse_args([Head | Rest], Opts) -> + NewOpts = + case Head of + "--port=" ++ Port -> + case string:to_integer(Port) of + {IntPort,_} when is_integer(IntPort) -> + Opts#options{port = IntPort}; + _Else -> + erlang:error({bad_arg, Head}) + end; + "--transport=" ++ Trans -> + % TODO: Enable Buffered and HTTP transport + case Trans of + "framed" -> + Opts#options{client_opts = [{framed, true} | Opts#options.client_opts]}; + _Else -> + Opts + end; + "--protocol=binary" -> + % TODO: Enable JSON protocol + Opts; + _Else -> + erlang:error({bad_arg, Head}) + end, + parse_args(Rest, NewOpts). + +start() -> start(init:get_plain_arguments()). +start(Args) -> + #options{port = Port, client_opts = ClientOpts} = parse_args(Args), + {ok, Client0} = thrift_client_util:new( + "127.0.0.1", Port, thrift_test_thrift, ClientOpts), + + DemoXtruct = #'Xtruct'{ + string_thing = <<"Zero">>, + byte_thing = 1, + i32_thing = 9128361, + i64_thing = 9223372036854775807}, + + DemoNest = #'Xtruct2'{ + byte_thing = 7, + struct_thing = DemoXtruct, + % Note that we don't set i32_thing, it will come back as undefined + % from the Python server, but 0 from the C++ server, since it is not + % optional + i32_thing = 2}, + + % Is it safe to match these things? + DemoDict = dict:from_list([ {Key, Key-10} || Key <- lists:seq(0,10) ]), + DemoSet = sets:from_list([ Key || Key <- lists:seq(-3,3) ]), + + DemoInsane = #'Insanity'{ + userMap = dict:from_list([{?THRIFT_TEST_NUMBERZ_FIVE, 5000}]), + xtructs = [#'Xtruct'{ string_thing = <<"Truck">>, byte_thing = 8, i32_thing = 8, i64_thing = 8}]}, + + {Client01, {ok, ok}} = thrift_client:call(Client0, testVoid, []), + + {Client02, {ok, <<"Test">>}} = thrift_client:call(Client01, testString, ["Test"]), + {Client03, {ok, <<"Test">>}} = thrift_client:call(Client02, testString, [<<"Test">>]), + {Client04, {ok, 63}} = thrift_client:call(Client03, testByte, [63]), + {Client05, {ok, -1}} = thrift_client:call(Client04, testI32, [-1]), + {Client06, {ok, 0}} = thrift_client:call(Client05, testI32, [0]), + {Client07, {ok, -34359738368}} = thrift_client:call(Client06, testI64, [-34359738368]), + {Client08, {ok, -5.2098523}} = thrift_client:call(Client07, testDouble, [-5.2098523]), + %% TODO: add testBinary() call + {Client09, {ok, DemoXtruct}} = thrift_client:call(Client08, testStruct, [DemoXtruct]), + {Client10, {ok, DemoNest}} = thrift_client:call(Client09, testNest, [DemoNest]), + {Client11, {ok, DemoDict}} = thrift_client:call(Client10, testMap, [DemoDict]), + {Client12, {ok, DemoSet}} = thrift_client:call(Client11, testSet, [DemoSet]), + {Client13, {ok, [-1,2,3]}} = thrift_client:call(Client12, testList, [[-1,2,3]]), + {Client14, {ok, 1}} = thrift_client:call(Client13, testEnum, [?THRIFT_TEST_NUMBERZ_ONE]), + {Client15, {ok, 309858235082523}} = thrift_client:call(Client14, testTypedef, [309858235082523]), + {Client16, {ok, InsaneResult}} = thrift_client:call(Client15, testInsanity, [DemoInsane]), + io:format("~p~n", [InsaneResult]), + + {Client17, {ok, #'Xtruct'{string_thing = <<"Message">>}}} = + thrift_client:call(Client16, testMultiException, ["Safe", "Message"]), + + Client18 = + try + {ClientS1, Result1} = thrift_client:call(Client17, testMultiException, ["Xception", "Message"]), + io:format("Unexpected return! ~p~n", [Result1]), + ClientS1 + catch + throw:{ClientS2, {exception, ExnS1 = #'Xception'{}}} -> + #'Xception'{errorCode = 1001, message = <<"This is an Xception">>} = ExnS1, + ClientS2; + throw:{ClientS2, {exception, _ExnS1 = #'Xception2'{}}} -> + io:format("Wrong exception type!~n", []), + ClientS2 + end, + + Client19 = + try + {ClientS3, Result2} = thrift_client:call(Client18, testMultiException, ["Xception2", "Message"]), + io:format("Unexpected return! ~p~n", [Result2]), + ClientS3 + catch + throw:{ClientS4, {exception, _ExnS2 = #'Xception'{}}} -> + io:format("Wrong exception type!~n", []), + ClientS4; + throw:{ClientS4, {exception, ExnS2 = #'Xception2'{}}} -> + #'Xception2'{errorCode = 2002, + struct_thing = #'Xtruct'{ + string_thing = <<"This is an Xception2">>}} = ExnS2, + ClientS4 + end, + + thrift_client:close(Client19).
