| #!/usr/bin/env perl |
| |
| # |
| # 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. |
| # |
| |
| use 5.10.0; |
| use strict; |
| use warnings; |
| use Data::Dumper; |
| use Getopt::Long qw(GetOptions); |
| use Time::HiRes qw(gettimeofday); |
| |
| use lib '../../lib/perl/lib'; |
| use lib 'gen-perl'; |
| |
| use Thrift; |
| use Thrift::BinaryProtocol; |
| use Thrift::BufferedTransport; |
| use Thrift::FramedTransport; |
| use Thrift::MultiplexedProtocol; |
| use Thrift::SSLSocket; |
| use Thrift::Socket; |
| use Thrift::UnixSocket; |
| |
| use ThriftTest::SecondService; |
| use ThriftTest::ThriftTest; |
| use ThriftTest::Types; |
| |
| $|++; |
| |
| sub usage { |
| print <<"EOF"; |
| Usage: $0 [OPTIONS] |
| |
| Options: (default) |
| --ca CA to validate server with. |
| --cert Certificate to use. |
| Required if using --ssl. |
| --ciphers Acceptable cipher list. |
| --domain-socket <file> Use a unix domain socket. |
| --help Show usage. |
| --key Certificate key. |
| Required if using --ssl. |
| --port <portnum> 9090 Port to use. |
| --protocol {binary} binary Protocol to use. |
| --ssl If present, use SSL. |
| --transport {buffered|framed} buffered Transport to use. |
| |
| EOF |
| } |
| |
| my %opts = ( |
| 'port' => 9090, |
| 'protocol' => 'binary', |
| 'transport' => 'buffered' |
| ); |
| |
| GetOptions(\%opts, qw ( |
| ca=s |
| cert=s |
| ciphers=s |
| key=s |
| domain-socket=s |
| help |
| host=s |
| port=i |
| protocol=s |
| ssl |
| transport=s |
| )) || exit 1; |
| |
| if ($opts{help}) { |
| usage(); |
| exit 0; |
| } |
| |
| my $socket = undef; |
| if ($opts{'domain-socket'}) { |
| $socket = Thrift::UnixSocket->new($opts{'domain-socket'}); |
| } |
| elsif ($opts{ssl}) { |
| $socket = Thrift::SSLSocket->new(\%opts); |
| } |
| else { |
| $socket = Thrift::Socket->new($opts{host}, $opts{port}); |
| } |
| |
| my $transport; |
| if ($opts{transport} eq 'buffered') { |
| $transport = Thrift::BufferedTransport->new($socket, 1024, 1024); |
| } |
| elsif ($opts{transport} eq 'framed') { |
| $transport = Thrift::FramedTransport->new($socket); |
| } |
| else { |
| usage(); |
| exit 1; |
| } |
| |
| my $protocol; |
| my $protocol2; |
| if ($opts{protocol} eq 'binary' || $opts{protocol} eq 'multi') { |
| $protocol = Thrift::BinaryProtocol->new($transport); |
| } |
| else { |
| usage(); |
| exit 1; |
| } |
| |
| my $secondService = undef; |
| if (index($opts{protocol}, 'multi') == 0) { |
| $protocol2 = Thrift::MultiplexedProtocol->new($protocol, 'SecondService'); |
| $protocol = Thrift::MultiplexedProtocol->new($protocol, 'ThriftTest'); |
| $secondService = ThriftTest::SecondServiceClient->new($protocol2); |
| } |
| |
| my $testClient = ThriftTest::ThriftTestClient->new($protocol); |
| |
| eval { |
| $transport->open(); |
| }; |
| if($@){ |
| die(Dumper($@)); |
| } |
| |
| use constant ERR_BASETYPES => 1; |
| use constant ERR_STRUCTS => 2; |
| use constant ERR_CONTAINERS => 4; |
| use constant ERR_EXCEPTIONS => 8; |
| use constant ERR_PROTOCOL => 16; |
| use constant ERR_UNKNOWN => 64; |
| |
| my $start = gettimeofday(); |
| |
| # |
| # VOID TEST |
| # |
| print('testVoid()'); |
| $testClient->testVoid(); |
| print(" = void\n"); |
| |
| # |
| # STRING TEST |
| # |
| print('testString("Test")'); |
| my $s = $testClient->testString('Test'); |
| print(qq| = "$s"\n|); |
| exit(ERR_BASETYPES) if ($s ne 'Test'); |
| |
| # |
| # MULTIPLEXED TEST |
| # |
| if (index($opts{protocol}, 'multi') == 0) { |
| print('secondtestString("Test2")'); |
| $s = $secondService->secondtestString('Test2'); |
| print(qq| = "$s"\n|); |
| exit(ERR_PROTOCOL) if ($s ne 'testString("Test2")'); |
| } |
| |
| # |
| # BOOL TEST |
| # |
| print('testBool(1)'); |
| my $t = $testClient->testBool(1); |
| print(" = $t\n"); |
| exit(ERR_BASETYPES) if ($t ne 1); |
| print('testBool(0)'); |
| my $f = $testClient->testBool(0); |
| print(" = $f\n"); |
| exit(ERR_BASETYPES) if ($f ne q||); |
| |
| |
| # |
| # BYTE TEST |
| # |
| print('testByte(1)'); |
| my $u8 = $testClient->testByte(1); |
| print(" = $u8\n"); |
| |
| # |
| # I32 TEST |
| # |
| print('testI32(-1)'); |
| my $i32 = $testClient->testI32(-1); |
| print(" = $i32\n"); |
| exit(ERR_BASETYPES) if ($i32 ne -1); |
| |
| # |
| # I64 TEST |
| # |
| print('testI64(-34359738368)'); |
| my $i64 = $testClient->testI64(-34359738368); |
| print(" = $i64\n"); |
| exit(ERR_BASETYPES) if ($i64 ne -34359738368); |
| |
| # |
| # DOUBLE TEST |
| # |
| print('testDouble(-852.234234234)'); |
| my $dub = $testClient->testDouble(-852.234234234); |
| print(" = $dub\n"); |
| exit(ERR_BASETYPES) if ($dub ne -852.234234234); |
| |
| # |
| # BINARY TEST --- TODO |
| # |
| |
| |
| # |
| # STRUCT TEST |
| # |
| print('testStruct({"Zero", 1, -3, -5})'); |
| my $out = ThriftTest::Xtruct->new(); |
| $out->string_thing('Zero'); |
| $out->byte_thing(1); |
| $out->i32_thing(-3); |
| $out->i64_thing(-5); |
| my $in = $testClient->testStruct($out); |
| print(' = {"'.$in->string_thing.'", '. |
| $in->byte_thing.', '. |
| $in->i32_thing.', '. |
| $in->i64_thing."}\n"); |
| |
| # |
| # NESTED STRUCT TEST |
| # |
| print('testNest({1, {"Zero", 1, -3, -5}, 5}'); |
| my $out2 = ThriftTest::Xtruct2->new(); |
| $out2->byte_thing(1); |
| $out2->struct_thing($out); |
| $out2->i32_thing(5); |
| my $in2 = $testClient->testNest($out2); |
| $in = $in2->struct_thing; |
| print(' = {'.$in2->byte_thing.', {"'. |
| $in->string_thing.'", '. |
| $in->byte_thing.', '. |
| $in->i32_thing.', '. |
| $in->i64_thing.'}, '. |
| $in2->i32_thing."}\n"); |
| |
| # |
| # MAP TEST |
| # |
| my $mapout = {}; |
| for (my $i = 0; $i < 5; ++$i) { |
| $mapout->{$i} = $i-10; |
| } |
| print('testMap({'); |
| my $first = 1; |
| while( my($key,$val) = each %$mapout) { |
| if ($first) { |
| $first = 0; |
| } |
| else { |
| print(', '); |
| } |
| print("$key => $val"); |
| } |
| print('})'); |
| |
| |
| my $mapin = $testClient->testMap($mapout); |
| print(' = {'); |
| |
| $first = 1; |
| while( my($key,$val) = each %$mapin){ |
| if ($first) { |
| $first = 0; |
| } |
| else { |
| print(', '); |
| } |
| print("$key => $val"); |
| } |
| print("}\n"); |
| |
| # |
| # SET TEST |
| # |
| my $setout = []; |
| for (my $i = -2; $i < 3; ++$i) { |
| push(@$setout, $i); |
| } |
| |
| print('testSet({'.join(',',@$setout).'})'); |
| |
| my $setin = $testClient->testSet($setout); |
| |
| print(' = {'.join(',',@$setout)."}\n"); |
| |
| # |
| # LIST TEST |
| # |
| my $listout = []; |
| for (my $i = -2; $i < 3; ++$i) { |
| push(@$listout, $i); |
| } |
| |
| print('testList({'.join(',',@$listout).'})'); |
| |
| my $listin = $testClient->testList($listout); |
| |
| print(' = {'.join(',',@$listin)."}\n"); |
| |
| # |
| # ENUM TEST |
| # |
| print('testEnum(ONE)'); |
| my $ret = $testClient->testEnum(ThriftTest::Numberz::ONE); |
| print(" = $ret\n"); |
| |
| print('testEnum(TWO)'); |
| $ret = $testClient->testEnum(ThriftTest::Numberz::TWO); |
| print(" = $ret\n"); |
| |
| print('testEnum(THREE)'); |
| $ret = $testClient->testEnum(ThriftTest::Numberz::THREE); |
| print(" = $ret\n"); |
| |
| print('testEnum(FIVE)'); |
| $ret = $testClient->testEnum(ThriftTest::Numberz::FIVE); |
| print(" = $ret\n"); |
| |
| print('testEnum(EIGHT)'); |
| $ret = $testClient->testEnum(ThriftTest::Numberz::EIGHT); |
| print(" = $ret\n"); |
| |
| # |
| # TYPEDEF TEST |
| # |
| print('testTypedef(309858235082523)'); |
| my $uid = $testClient->testTypedef(309858235082523); |
| print(" = $uid\n"); |
| |
| # |
| # NESTED MAP TEST |
| # |
| print('testMapMap(1)'); |
| my $mm = $testClient->testMapMap(1); |
| print(' = {'); |
| while( my ($key,$val) = each %$mm) { |
| print("$key => {"); |
| while( my($k2,$v2) = each %$val) { |
| print("$k2 => $v2, "); |
| } |
| print('}, '); |
| } |
| print("}\n"); |
| |
| # |
| # INSANITY TEST |
| # |
| my $insane = ThriftTest::Insanity->new(); |
| $insane->{userMap}->{ThriftTest::Numberz::FIVE} = 5000; |
| my $truck = ThriftTest::Xtruct->new(); |
| $truck->string_thing('Hello2'); |
| $truck->byte_thing(2); |
| $truck->i32_thing(2); |
| $truck->i64_thing(2); |
| my $truck2 = ThriftTest::Xtruct->new(); |
| $truck2->string_thing('Goodbye4'); |
| $truck2->byte_thing(4); |
| $truck2->i32_thing(4); |
| $truck2->i64_thing(4); |
| push(@{$insane->{xtructs}}, $truck); |
| push(@{$insane->{xtructs}}, $truck2); |
| |
| print('testInsanity()'); |
| my $whoa = $testClient->testInsanity($insane); |
| print(' = {'); |
| while( my ($key,$val) = each %$whoa) { |
| print("$key => {"); |
| while( my($k2,$v2) = each %$val) { |
| print("$k2 => {"); |
| my $userMap = $v2->{userMap}; |
| print('{'); |
| if (ref($userMap) eq 'HASH') { |
| while( my($k3,$v3) = each %$userMap) { |
| print("$k3 => $v3, "); |
| } |
| } |
| print('}, '); |
| |
| my $xtructs = $v2->{xtructs}; |
| print('{'); |
| if (ref($xtructs) eq 'ARRAY') { |
| foreach my $x (@$xtructs) { |
| print('{"'.$x->{string_thing}.'", '. |
| $x->{byte_thing}.', '.$x->{i32_thing}.', '.$x->{i64_thing}.'}, '); |
| } |
| } |
| print('}'); |
| |
| print('}, '); |
| } |
| print('}, '); |
| } |
| print("}\n"); |
| |
| # |
| # EXCEPTION TEST |
| # |
| print(q|testException('Xception')|); |
| eval { |
| $testClient->testException('Xception'); |
| print(" void\nFAILURE\n"); |
| }; if($@ && $@->UNIVERSAL::isa('ThriftTest::Xception')) { |
| print(' caught xception '.$@->{errorCode}.': '.$@->{message}."\n"); |
| } |
| |
| |
| # |
| # Normal tests done. |
| # |
| my $stop = gettimeofday(); |
| my $elp = sprintf('%d',1000*($stop - $start), 0); |
| print("Total time: $elp ms\n"); |
| |
| # |
| # Extraneous "I don't trust PHP to pack/unpack integer" tests |
| # |
| |
| # Max I32 |
| my $num = 2**30 + 2**30 - 1; |
| my $num2 = $testClient->testI32($num); |
| if ($num != $num2) { |
| print "Missed max32 $num = $num2\n"; |
| } |
| |
| # Min I32 |
| $num = 0 - 2**31; |
| $num2 = $testClient->testI32($num); |
| if ($num != $num2) { |
| print "Missed min32 $num = $num2\n"; |
| } |
| |
| # Max Number I can get out of my perl |
| $num = 2**40; |
| $num2 = $testClient->testI64($num); |
| if ($num != $num2) { |
| print "Missed max64 $num = $num2\n"; |
| } |
| |
| # Max Number I can get out of my perl |
| $num = 0 - 2**40; |
| $num2 = $testClient->testI64($num); |
| if ($num != $num2) { |
| print "Missed min64 $num = $num2\n"; |
| } |
| |
| $transport->close(); |
| |
| |
| |