1#!/usr/bin/env ruby 2# encoding: utf-8 3 4# 5# Licensed to the Apache Software Foundation (ASF) under one 6# or more contributor license agreements. See the NOTICE file 7# distributed with this work for additional information 8# regarding copyright ownership. The ASF licenses this file 9# to you under the Apache License, Version 2.0 (the 10# "License"); you may not use this file except in compliance 11# with the License. You may obtain a copy of the License at 12# 13# http://www.apache.org/licenses/LICENSE-2.0 14# 15# Unless required by applicable law or agreed to in writing, 16# software distributed under the License is distributed on an 17# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18# KIND, either express or implied. See the License for the 19# specific language governing permissions and limitations 20# under the License. 21# 22 23$:.push File.dirname(__FILE__) + '/..' 24 25require 'test_helper' 26require 'thrift' 27require 'thrift_test' 28 29$domain_socket = nil 30$host = "localhost" 31$port = 9090 32$protocolType = "binary" 33$ssl = false 34$transport = "buffered" 35 36ARGV.each do|a| 37 if a == "--help" 38 puts "Allowed options:" 39 puts "\t -h [ --help ] \t produce help message" 40 puts "\t--domain-socket arg (=) \t Unix domain socket path" 41 puts "\t--host arg (=localhost) \t Host to connect \t not valid with domain-socket" 42 puts "\t--port arg (=9090) \t Port number to listen \t not valid with domain-socket" 43 puts "\t--protocol arg (=binary) \t protocol: accel, binary, compact, json" 44 puts "\t--ssl \t use ssl \t not valid with domain-socket" 45 puts "\t--transport arg (=buffered) transport: buffered, framed, http" 46 exit 47 elsif a.start_with?("--domain-socket") 48 $domain_socket = a.split("=")[1] 49 elsif a.start_with?("--host") 50 $host = a.split("=")[1] 51 elsif a.start_with?("--protocol") 52 $protocolType = a.split("=")[1] 53 elsif a == "--ssl" 54 $ssl = true 55 elsif a.start_with?("--transport") 56 $transport = a.split("=")[1] 57 elsif a.start_with?("--port") 58 $port = a.split("=")[1].to_i 59 end 60end 61 62class SimpleClientTest < Test::Unit::TestCase 63 def setup 64 unless @socket 65 if $domain_socket.to_s.strip.empty? 66 if $ssl 67 # the working directory for ruby crosstest is test/rb/gen-rb 68 keysDir = File.join(File.dirname(File.dirname(Dir.pwd)), "keys") 69 ctx = OpenSSL::SSL::SSLContext.new 70 ctx.ca_file = File.join(keysDir, "CA.pem") 71 ctx.cert = OpenSSL::X509::Certificate.new(File.open(File.join(keysDir, "client.crt"))) 72 ctx.cert_store = OpenSSL::X509::Store.new 73 ctx.cert_store.add_file(File.join(keysDir, 'server.pem')) 74 ctx.key = OpenSSL::PKey::RSA.new(File.open(File.join(keysDir, "client.key"))) 75 ctx.options = OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 76 ctx.ssl_version = :SSLv23 77 ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER 78 @socket = Thrift::SSLSocket.new($host, $port, nil, ctx) 79 else 80 @socket = Thrift::Socket.new($host, $port) 81 end 82 else 83 @socket = Thrift::UNIXSocket.new($domain_socket) 84 end 85 86 if $transport == "buffered" 87 transportFactory = Thrift::BufferedTransport.new(@socket) 88 elsif $transport == "framed" 89 transportFactory = Thrift::FramedTransport.new(@socket) 90 else 91 raise 'Unknown transport type' 92 end 93 94 if $protocolType == "binary" 95 @protocol = Thrift::BinaryProtocol.new(transportFactory) 96 elsif $protocolType == "compact" 97 @protocol = Thrift::CompactProtocol.new(transportFactory) 98 elsif $protocolType == "json" 99 @protocol = Thrift::JsonProtocol.new(transportFactory) 100 elsif $protocolType == "accel" 101 @protocol = Thrift::BinaryProtocolAccelerated.new(transportFactory) 102 else 103 raise 'Unknown protocol type' 104 end 105 @client = Thrift::Test::ThriftTest::Client.new(@protocol) 106 @socket.open 107 end 108 end 109 110 def teardown 111 @socket.close 112 end 113 114 def test_void 115 p 'test_void' 116 @client.testVoid() 117 end 118 119 def test_string 120 p 'test_string' 121 test_string = 122 'quote: \" backslash:' + 123 ' forwardslash-escaped: \/ ' + 124 ' backspace: \b formfeed: \f newline: \n return: \r tab: ' + 125 ' now-all-of-them-together: "\\\/\b\n\r\t' + 126 ' now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><' + 127 ' char-to-test-json-parsing: ]] \"]] \\" }}}{ [[[ ' 128 test_string = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, " + 129 "Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, " + 130 "Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, " + 131 "বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, " + 132 "Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, " + 133 "Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, " + 134 "Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, " + 135 "Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, " + 136 "Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski, " + 137 "Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia, " + 138 "Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa, " + 139 "ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар, " + 140 "Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, " + 141 "Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa " + 142 "Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, مازِرونی, Bahasa " + 143 "Melayu, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, " + 144 "Norsk (nynorsk), Norsk (bokmål), Nouormand, Diné bizaad, " + 145 "Occitan, Иронау, Papiamentu, Deitsch, Polski, پنجابی, پښتو, " + 146 "Norfuk / Pitkern, Português, Runa Simi, Rumantsch, Romani, Română, " + 147 "Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple " + 148 "English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk, " + 149 "Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog, " + 150 "Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, " + 151 "Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, " + 152 "Bân-lâm-gú, 粵語" 153 154 result_string = @client.testString(test_string) 155 assert_equal(test_string, result_string.force_encoding(Encoding::UTF_8)) 156 end 157 158 def test_bool 159 p 'test_bool' 160 assert_equal(@client.testBool(true), true) 161 assert_equal(@client.testBool(false), false) 162 end 163 164 def test_byte 165 p 'test_byte' 166 val = 120 167 assert_equal(@client.testByte(val), val) 168 assert_equal(@client.testByte(-val), -val) 169 end 170 171 def test_i32 172 p 'test_i32' 173 val = 2000000032 174 assert_equal(@client.testI32(val), val) 175 assert_equal(@client.testI32(-val), -val) 176 end 177 178 def test_i64 179 p 'test_i64' 180 val = 9000000000000000064 181 assert_equal(@client.testI64(val), val) 182 assert_equal(@client.testI64(-val), -val) 183 end 184 185 def test_double 186 p 'test_double' 187 val = 3.14159265358979323846 188 assert_equal(@client.testDouble(val), val) 189 assert_equal(@client.testDouble(-val), -val) 190 assert_kind_of(Float, @client.testDouble(val)) 191 end 192 193 def test_binary 194 p 'test_binary' 195 val = (0...256).reverse_each.to_a 196 ret = @client.testBinary(val.pack('C*')) 197 assert_equal(val, ret.bytes.to_a) 198 end 199 200 def test_map 201 p 'test_map' 202 val = {1 => 1, 2 => 2, 3 => 3} 203 assert_equal(@client.testMap(val), val) 204 assert_kind_of(Hash, @client.testMap(val)) 205 end 206 207 def test_string_map 208 p 'test_string_map' 209 val = {'a' => '2', 'b' => 'blah', 'some' => 'thing'} 210 ret = @client.testStringMap(val) 211 assert_equal(val, ret) 212 assert_kind_of(Hash, ret) 213 end 214 215 def test_list 216 p 'test_list' 217 val = [1,2,3,4,5] 218 assert_equal(@client.testList(val), val) 219 assert_kind_of(Array, @client.testList(val)) 220 end 221 222 def test_enum 223 p 'test_enum' 224 val = Thrift::Test::Numberz::SIX 225 ret = @client.testEnum(val) 226 227 assert_equal(ret, 6) 228 assert_kind_of(Fixnum, ret) 229 end 230 231 def test_typedef 232 p 'test_typedef' 233 #UserId testTypedef(1: UserId thing), 234 assert_equal(@client.testTypedef(309858235082523), 309858235082523) 235 assert_kind_of(Fixnum, @client.testTypedef(309858235082523)) 236 true 237 end 238 239 def test_set 240 p 'test_set' 241 val = Set.new([1,2,3]) 242 assert_equal(@client.testSet(val), val) 243 assert_kind_of(Set, @client.testSet(val)) 244 end 245 246 def get_struct 247 Thrift::Test::Xtruct.new({'string_thing' => 'hi!', 'i32_thing' => 4 }) 248 end 249 250 def test_struct 251 p 'test_struct' 252 ret = @client.testStruct(get_struct) 253 254 # TODO: not sure what unspecified "default" requiredness values should be 255 assert(ret.byte_thing == nil || ret.byte_thing == 0) 256 assert(ret.i64_thing == nil || ret.i64_thing == 0) 257 258 assert_equal(ret.string_thing, 'hi!') 259 assert_equal(ret.i32_thing, 4) 260 assert_kind_of(Thrift::Test::Xtruct, ret) 261 end 262 263 def test_nest 264 p 'test_nest' 265 struct2 = Thrift::Test::Xtruct2.new({'struct_thing' => get_struct, 'i32_thing' => 10}) 266 267 ret = @client.testNest(struct2) 268 269 # TODO: not sure what unspecified "default" requiredness values should be 270 assert(ret.struct_thing.byte_thing == nil || ret.struct_thing.byte_thing == 0) 271 assert(ret.struct_thing.i64_thing == nil || ret.struct_thing.i64_thing == 0) 272 273 assert_equal(ret.struct_thing.string_thing, 'hi!') 274 assert_equal(ret.struct_thing.i32_thing, 4) 275 assert_equal(ret.i32_thing, 10) 276 277 assert_kind_of(Thrift::Test::Xtruct, ret.struct_thing) 278 assert_kind_of(Thrift::Test::Xtruct2, ret) 279 end 280 281 def test_insanity 282 p 'test_insanity' 283 insane = Thrift::Test::Insanity.new({ 284 'userMap' => { 285 Thrift::Test::Numberz::FIVE => 5, 286 Thrift::Test::Numberz::EIGHT => 8, 287 }, 288 'xtructs' => [ 289 Thrift::Test::Xtruct.new({ 290 'string_thing' => 'Goodbye4', 291 'byte_thing' => 4, 292 'i32_thing' => 4, 293 'i64_thing' => 4, 294 }), 295 Thrift::Test::Xtruct.new({ 296 'string_thing' => 'Hello2', 297 'byte_thing' => 2, 298 'i32_thing' => 2, 299 'i64_thing' => 2, 300 }) 301 ] 302 }) 303 304 ret = @client.testInsanity(insane) 305 306 assert_equal(insane, ret[1][2]) 307 assert_equal(insane, ret[1][3]) 308 309 assert(ret[2][6].userMap == nil || ret[2][6].userMap.length == 0) 310 assert(ret[2][6].xtructs == nil || ret[2][6].xtructs.length == 0) 311 end 312 313 def test_map_map 314 p 'test_map_map' 315 ret = @client.testMapMap(4) 316 assert_kind_of(Hash, ret) 317 expected = { 318 -4 => { 319 -4 => -4, 320 -3 => -3, 321 -2 => -2, 322 -1 => -1, 323 }, 324 4 => { 325 4 => 4, 326 3 => 3, 327 2 => 2, 328 1 => 1, 329 } 330 } 331 assert_equal(expected, ret) 332 end 333 334 def test_multi 335 p 'test_multi' 336 ret = @client.testMulti(42, 4242, 424242, {1 => 'blah', 2 => 'thing'}, Thrift::Test::Numberz::EIGHT, 24) 337 expected = Thrift::Test::Xtruct.new({ 338 :string_thing => 'Hello2', 339 :byte_thing => 42, 340 :i32_thing => 4242, 341 :i64_thing => 424242 342 }) 343 assert_equal(expected, ret) 344 end 345 346 def test_exception 347 p 'test_exception' 348 assert_raise Thrift::Test::Xception do 349 @client.testException('Xception') 350 end 351 begin 352 @client.testException('TException') 353 rescue => e 354 assert e.class.ancestors.include?(Thrift::Exception) 355 end 356 assert_nothing_raised do 357 @client.testException('test') 358 end 359 end 360 361 def test_multi_exception 362 p 'test_multi_exception' 363 assert_raise Thrift::Test::Xception do 364 @client.testMultiException("Xception", "test 1") 365 end 366 assert_raise Thrift::Test::Xception2 do 367 @client.testMultiException("Xception2", "test 2") 368 end 369 assert_equal( @client.testMultiException("Success", "test 3").string_thing, "test 3") 370 end 371 372 def test_oneway 373 p 'test_oneway' 374 time1 = Time.now.to_f 375 @client.testOneway(1) 376 time2 = Time.now.to_f 377 assert_operator (time2-time1), :<, 0.1 378 end 379 380end 381 382