fl-thrift_client 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,137 @@
1
+
2
+ require "#{File.dirname(__FILE__)}/test_helper"
3
+
4
+ class SimpleTest < Test::Unit::TestCase
5
+
6
+ S = ThriftClient::Simple
7
+ S.make_struct("Example", S::Field.new(:name, S::STRING, 1))
8
+ S.make_struct("Args")
9
+ S.make_struct("Retval", S::Field.new(:rv, S::I32, 0))
10
+
11
+ def test_definition
12
+ assert Struct::ST_Example
13
+ assert Struct::ST_Args
14
+ assert Struct::ST_Retval
15
+ end
16
+
17
+ ## Encoding
18
+
19
+ def test_boolean_encoding
20
+ assert_equal "\001", S.pack_value(S::BOOL, true)
21
+ assert_equal "\000", S.pack_value(S::BOOL, false)
22
+ end
23
+
24
+ def test_byte_encoding
25
+ assert_equal "\xc7", S.pack_value(S::BYTE, 199)
26
+ end
27
+
28
+ def test_i16_encoding
29
+ assert_equal "\x00\x96", S.pack_value(S::I16, 150)
30
+ end
31
+
32
+ def test_i32_encoding
33
+ assert_equal "\x00\x96\xb4\x3f", S.pack_value(S::I32, 9876543)
34
+ end
35
+
36
+ def test_i64_encoding
37
+ assert_equal "\x00\x00\x00\x1c\xbb\xf3\x09\x04", S.pack_value(S::I64, 123412351236)
38
+ end
39
+
40
+ def test_double_encoding
41
+ assert_equal "\x40\x23\x00\x00\x00\x00\x00\x00", S.pack_value(S::DOUBLE, 9.5)
42
+ end
43
+
44
+ def test_string_encoding
45
+ assert_equal "\x00\x00\x00\x05hello", S.pack_value(S::STRING, "hello")
46
+ end
47
+
48
+ def test_list_encoding
49
+ assert_equal "\x08\x00\x00\x00\x03\x00\x00\x00\x17\x00\x00\x00\x16\x00\x00\x00\x15",
50
+ S.pack_value(S::ListType.new(S::I32), [ 23, 22, 21 ])
51
+ end
52
+
53
+ def test_map_encoding
54
+ assert_equal "\x0b\x08\x00\x00\x00\x01\x00\x00\x00\x03cat\x00\x00\x00\x05",
55
+ S.pack_value(S::MapType.new(S::STRING, S::I32), "cat" => 5)
56
+ end
57
+
58
+ def test_set_encoding
59
+ assert_equal "\x08\x00\x00\x00\x01\x00\x00\x00\x04",
60
+ S.pack_value(S::SetType.new(S::I32), [ 4 ])
61
+ end
62
+
63
+ def test_struct_encoding
64
+ assert_equal "\x0b\x00\x01\x00\x00\x00\x06Commie\x00",
65
+ S.pack_value(S::StructType.new(Struct::ST_Example), Struct::ST_Example.new("Commie"))
66
+ end
67
+
68
+ def test_request_encoding
69
+ assert_equal "\x80\x01\x00\x01\x00\x00\x00\x09getHeight\x00\x00\x00\x17\x00",
70
+ S.pack_request("getHeight", Struct::ST_Args.new, 23)
71
+ end
72
+
73
+ ## Decoding
74
+
75
+ def test_boolean_decoding
76
+ assert_equal true, S.read_value(StringIO.new("\x01"), S::BOOL)
77
+ assert_equal false, S.read_value(StringIO.new("\x00"), S::BOOL)
78
+ end
79
+
80
+ def test_byte_decoding
81
+ assert_equal -57, S.read_value(StringIO.new("\xc7"), S::BYTE)
82
+ end
83
+
84
+ def test_i16_decoding
85
+ assert_equal 150, S.read_value(StringIO.new("\x00\x96"), S::I16)
86
+ end
87
+
88
+ def test_i32_decoding
89
+ assert_equal 9876543, S.read_value(StringIO.new("\x00\x96\xb4\x3f"), S::I32)
90
+ end
91
+
92
+ def test_i64_decoding
93
+ assert_equal 123412351236,
94
+ S.read_value(StringIO.new("\x00\x00\x00\x1c\xbb\xf3\x09\x04"), S::I64)
95
+ end
96
+
97
+ def test_double_decoding
98
+ assert_equal 9.5,
99
+ S.read_value(StringIO.new("\x40\x23\x00\x00\x00\x00\x00\x00"), S::DOUBLE)
100
+ end
101
+
102
+ def test_string_decoding
103
+ assert_equal "hello", S.read_value(StringIO.new("\x00\x00\x00\x05hello"), S::STRING)
104
+ end
105
+
106
+ def test_list_decoding
107
+ assert_equal [ 23, 22, 21 ],
108
+ S.read_value(StringIO.new("\x08\x00\x00\x00\x03\x00\x00\x00\x17\x00\x00\x00\x16\x00\x00\x00\x15"),
109
+ S::ListType.new(S::I32))
110
+ end
111
+
112
+ def test_map_decoding
113
+ assert_equal({ "cat" => 5 },
114
+ S.read_value(StringIO.new("\x0b\x08\x00\x00\x00\x01\x00\x00\x00\x03cat\x00\x00\x00\x05"),
115
+ S::MapType.new(S::STRING, S::I32)))
116
+ end
117
+
118
+ def test_set_decoding
119
+ assert_equal [ 4 ],
120
+ S.read_value(StringIO.new("\x08\x00\x00\x00\x01\x00\x00\x00\x04"),
121
+ S::ListType.new(S::I32))
122
+ end
123
+
124
+ def test_struct_decoding
125
+ assert_equal Struct::ST_Example.new("Commie"),
126
+ S.read_value(StringIO.new("\x0b\x00\x01\x00\x00\x00\x06Commie\x00"),
127
+ S::StructType.new(Struct::ST_Example))
128
+ end
129
+
130
+ def test_response_decoding
131
+ assert_equal [ "getHeight", 255, 1 ],
132
+ S.read_response(
133
+ StringIO.new("\x80\x01\x00\x02\x00\x00\x00\x09getHeight\x00\x00\x00\xff\x08\x00\x00\x00\x00\x00\x01\x00"),
134
+ Struct::ST_Retval)
135
+ end
136
+
137
+ end
@@ -0,0 +1,12 @@
1
+
2
+ require 'test/unit'
3
+ require 'benchmark'
4
+ $LOAD_PATH << "#{File.expand_path(File.dirname(__FILE__))}/../lib"
5
+ require 'thrift_client'
6
+ require 'thrift_client/simple'
7
+
8
+ $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
9
+ require 'greeter/greeter'
10
+ require 'greeter/server'
11
+
12
+ begin; require 'ruby-debug'; rescue LoadError; end
@@ -0,0 +1,54 @@
1
+ require "#{File.dirname(__FILE__)}/test_helper"
2
+ require "thrift/server/mongrel_http_server"
3
+
4
+ class ThriftClientHTTPTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @servers = ["http://127.0.0.1:1461/greeter", "http://127.0.0.1:1462/greeter", "http://127.0.0.1:1463/greeter"]
8
+ @socket = 1461
9
+ @timeout = 0.2
10
+ @options = {:protocol_extra_params => [false]}
11
+ @pid = Process.fork do
12
+ Signal.trap("INT") { exit }
13
+ Greeter::HTTPServer.new(@servers.last).serve
14
+ end
15
+ # Need to give the child process a moment to open the listening socket or
16
+ # we get occasional "could not connect" errors in tests.
17
+ sleep 0.05
18
+ end
19
+
20
+ def teardown
21
+ Process.kill("INT", @pid)
22
+ Process.wait
23
+ end
24
+
25
+ def test_bad_uri
26
+ assert_raises URI::InvalidURIError do
27
+ @options.merge!({ :protocol => Thrift::BinaryProtocol, :transport => Thrift::HTTPClientTransport })
28
+ ThriftClient.new(Greeter::Client, "127.0.0.1:1463", @options).greeting("someone")
29
+ end
30
+ end
31
+
32
+ def test_bad_uri_no_http
33
+ assert_raises ArgumentError do
34
+ @options.merge!({ :protocol => Thrift::BinaryProtocol, :transport => Thrift::HTTPClientTransport })
35
+ ThriftClient.new(Greeter::Client, "//127.0.0.1:1463", @options).greeting("someone")
36
+ end
37
+ end
38
+
39
+ def test_valid_server
40
+ assert_nothing_raised do
41
+ @options.merge!({ :protocol => Thrift::BinaryProtocol, :transport => Thrift::HTTPClientTransport })
42
+ ThriftClient.new(Greeter::Client, "http://127.0.0.1:1463/greeter", @options).greeting("someone")
43
+ end
44
+ end
45
+
46
+ def test_non_random_fall_through
47
+ @servers = ["http://127.0.0.1:1463/greeter", "http://127.0.0.1:1461/greeter", "http://127.0.0.1:1462/greeter"]
48
+ assert_nothing_raised do
49
+ @options.merge!({ :protocol => Thrift::BinaryProtocol, :transport => Thrift::HTTPClientTransport })
50
+ ThriftClient.new(Greeter::Client, @servers, @options.merge(:randomize_server_list => false)).greeting("someone")
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,166 @@
1
+ require "#{File.dirname(__FILE__)}/test_helper"
2
+
3
+ class ThriftClientTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @servers = ["127.0.0.1:1461", "127.0.0.1:1462", "127.0.0.1:1463"]
7
+ @socket = 1461
8
+ @timeout = 0.2
9
+ @options = {:protocol_extra_params => [false]}
10
+ @pid = Process.fork do
11
+ Signal.trap("INT") { exit }
12
+ Greeter::Server.new("1463").serve
13
+ end
14
+ # Need to give the child process a moment to open the listening socket or
15
+ # we get occasional "could not connect" errors in tests.
16
+ sleep 0.05
17
+ end
18
+
19
+ def teardown
20
+ Process.kill("INT", @pid)
21
+ Process.wait
22
+ end
23
+
24
+ def test_inspect
25
+ client = ThriftClient.new(Greeter::Client, @servers.last, @options)
26
+ assert_equal "<ThriftClient(Greeter::Client) @current_server=127.0.0.1:1463>", client.inspect
27
+ end
28
+
29
+ def test_live_server
30
+ assert_nothing_raised do
31
+ ThriftClient.new(Greeter::Client, @servers.last, @options).greeting("someone")
32
+ end
33
+ end
34
+
35
+ def test_non_random_fall_through
36
+ assert_nothing_raised do
37
+ ThriftClient.new(Greeter::Client, @servers, @options.merge(:randomize_server_list => false)).greeting("someone")
38
+ end
39
+ end
40
+
41
+ def test_dont_raise
42
+ assert_nothing_raised do
43
+ ThriftClient.new(Greeter::Client, @servers.first, @options.merge(:raise => false)).greeting("someone")
44
+ end
45
+ end
46
+
47
+ def test_dont_raise_with_defaults
48
+ client = ThriftClient.new(Greeter::Client, @servers.first, @options.merge(:raise => false, :defaults => {:greeting => 1}))
49
+ assert_equal 1, client.greeting
50
+ end
51
+
52
+ def test_defaults_dont_override_no_method_error
53
+ client = ThriftClient.new(Greeter::Client, @servers, @options.merge(:raise => false, :defaults => {:Missing => 2}))
54
+ assert_raises(NoMethodError) { client.Missing }
55
+ end
56
+
57
+ def test_random_fall_through
58
+ assert_nothing_raised do
59
+ 10.times do
60
+ client = ThriftClient.new(Greeter::Client, @servers, @options)
61
+ client.greeting("someone")
62
+ client.disconnect!
63
+ end
64
+ end
65
+ end
66
+
67
+ def test_lazy_connection
68
+ assert_nothing_raised do
69
+ ThriftClient.new(Greeter::Client, @servers[0,2])
70
+ end
71
+ end
72
+
73
+ def test_no_servers_eventually_raise
74
+ client = ThriftClient.new(Greeter::Client, @servers[0,2], @options)
75
+ assert_raises(ThriftClient::NoServersAvailable) do
76
+ client.greeting("someone")
77
+ client.disconnect!
78
+ end
79
+ end
80
+
81
+ def test_framed_transport_timeout
82
+ stub_server(@socket) do |socket|
83
+ measurement = Benchmark.measure do
84
+ assert_raises(Thrift::TransportException) do
85
+ ThriftClient.new(Greeter::Client, "127.0.0.1:#{@socket}",
86
+ @options.merge(:timeout => @timeout)
87
+ ).greeting("someone")
88
+ end
89
+ end
90
+ assert((measurement.real > @timeout), "#{measurement.real} < #{@timeout}")
91
+ end
92
+ end
93
+
94
+ def test_buffered_transport_timeout
95
+ stub_server(@socket) do |socket|
96
+ measurement = Benchmark.measure do
97
+ assert_raises(Thrift::TransportException) do
98
+ ThriftClient.new(Greeter::Client, "127.0.0.1:#{@socket}",
99
+ @options.merge(:timeout => @timeout, :transport_wrapper => Thrift::BufferedTransport)
100
+ ).greeting("someone")
101
+ end
102
+ end
103
+ assert((measurement.real > @timeout), "#{measurement.real} < #{@timeout}")
104
+ end
105
+ end
106
+
107
+ def test_buffered_transport_timeout_override
108
+ # FIXME Large timeout values always are applied twice for some bizarre reason
109
+ log_timeout = @timeout * 4
110
+ stub_server(@socket) do |socket|
111
+ measurement = Benchmark.measure do
112
+ assert_raises(Thrift::TransportException) do
113
+ ThriftClient.new(Greeter::Client, "127.0.0.1:#{@socket}",
114
+ @options.merge(:timeout => @timeout, :timeout_overrides => {:greeting => log_timeout}, :transport_wrapper => Thrift::BufferedTransport)
115
+ ).greeting("someone")
116
+ end
117
+ end
118
+ assert((measurement.real > log_timeout), "#{measurement.real} < #{log_timeout}")
119
+ end
120
+ end
121
+
122
+ def test_retry_period
123
+ client = ThriftClient.new(Greeter::Client, @servers[0,2], @options.merge(:server_retry_period => 1))
124
+ assert_raises(ThriftClient::NoServersAvailable) { client.greeting("someone") }
125
+ sleep 1.1
126
+ assert_raises(ThriftClient::NoServersAvailable) { client.greeting("someone") }
127
+ end
128
+
129
+ def test_client_with_retry_period_drops_servers
130
+ client = ThriftClient.new(Greeter::Client, @servers[0,2], @options.merge(:server_retry_period => 1))
131
+ assert_raises(ThriftClient::NoServersAvailable) { client.greeting("someone") }
132
+ sleep 1.1
133
+ assert_raises(ThriftClient::NoServersAvailable) { client.greeting("someone") }
134
+ end
135
+
136
+ def test_server_max_requests_with_downed_servers
137
+ client = ThriftClient.new(Greeter::Client, @servers, @options.merge(:server_max_requests => 2))
138
+ client.greeting("someone")
139
+ internal_client = client.client
140
+ client.greeting("someone")
141
+ assert_equal internal_client, client.client
142
+
143
+ # This next call maxes out the requests for that "client" object
144
+ # and moves on to the next.
145
+ client.greeting("someone")
146
+ assert_not_equal internal_client, new_client = client.client
147
+
148
+ # And here we should still have the same client as the last one...
149
+ client.greeting("someone")
150
+ assert_equal new_client, client.client
151
+
152
+ # Until we max it out, too.
153
+ client.greeting("someone")
154
+ assert_not_equal internal_client, client.client
155
+ end
156
+
157
+ private
158
+
159
+ def stub_server(port)
160
+ socket = TCPServer.new('127.0.0.1', port)
161
+ Thread.new { socket.accept }
162
+ yield socket
163
+ ensure
164
+ socket.close
165
+ end
166
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{fl-thrift_client}
5
+ s.version = "0.4.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0.8") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Evan Weaver"]
9
+ s.date = %q{2010-04-08}
10
+ s.description = %q{A Thrift client wrapper that encapsulates some common failover behavior.}
11
+ s.email = %q{}
12
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.rdoc", "lib/thrift_client.rb", "lib/thrift_client/abstract_thrift_client.rb", "lib/thrift_client/connection.rb", "lib/thrift_client/connection/base.rb", "lib/thrift_client/connection/factory.rb", "lib/thrift_client/connection/http.rb", "lib/thrift_client/connection/socket.rb", "lib/thrift_client/event_machine.rb", "lib/thrift_client/simple.rb", "lib/thrift_client/thrift.rb"]
13
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.rdoc", "Rakefile", "lib/thrift_client.rb", "lib/thrift_client/abstract_thrift_client.rb", "lib/thrift_client/connection.rb", "lib/thrift_client/connection/base.rb", "lib/thrift_client/connection/factory.rb", "lib/thrift_client/connection/http.rb", "lib/thrift_client/connection/socket.rb", "lib/thrift_client/event_machine.rb", "lib/thrift_client/simple.rb", "lib/thrift_client/thrift.rb", "test/greeter/greeter.rb", "test/greeter/greeter.thrift", "test/greeter/server.rb", "test/multiple_working_servers_test.rb", "test/simple_test.rb", "test/test_helper.rb", "test/thrift_client_http_test.rb", "test/thrift_client_test.rb", "thrift_client.gemspec"]
14
+ s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/thrift_client/}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Thrift_client", "--main", "README.rdoc"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{fauna}
18
+ s.rubygems_version = %q{1.3.5}
19
+ s.summary = %q{A Thrift client wrapper that encapsulates some common failover behavior.}
20
+ s.test_files = ["test/multiple_working_servers_test.rb", "test/simple_test.rb", "test/test_helper.rb", "test/thrift_client_http_test.rb", "test/thrift_client_test.rb"]
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 3
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fl-thrift_client
3
+ version: !ruby/object:Gem::Version
4
+ hash: 11
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 4
9
+ - 2
10
+ version: 0.4.2
11
+ platform: ruby
12
+ authors:
13
+ - Evan Weaver
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-04-08 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: A Thrift client wrapper that encapsulates some common failover behavior.
23
+ email: ""
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - CHANGELOG
30
+ - LICENSE
31
+ - README.rdoc
32
+ - lib/thrift_client.rb
33
+ - lib/thrift_client/abstract_thrift_client.rb
34
+ - lib/thrift_client/connection.rb
35
+ - lib/thrift_client/connection/base.rb
36
+ - lib/thrift_client/connection/factory.rb
37
+ - lib/thrift_client/connection/http.rb
38
+ - lib/thrift_client/connection/socket.rb
39
+ - lib/thrift_client/event_machine.rb
40
+ - lib/thrift_client/simple.rb
41
+ - lib/thrift_client/thrift.rb
42
+ files:
43
+ - CHANGELOG
44
+ - LICENSE
45
+ - Manifest
46
+ - README.rdoc
47
+ - Rakefile
48
+ - lib/thrift_client.rb
49
+ - lib/thrift_client/abstract_thrift_client.rb
50
+ - lib/thrift_client/connection.rb
51
+ - lib/thrift_client/connection/base.rb
52
+ - lib/thrift_client/connection/factory.rb
53
+ - lib/thrift_client/connection/http.rb
54
+ - lib/thrift_client/connection/socket.rb
55
+ - lib/thrift_client/event_machine.rb
56
+ - lib/thrift_client/simple.rb
57
+ - lib/thrift_client/thrift.rb
58
+ - test/greeter/greeter.rb
59
+ - test/greeter/greeter.thrift
60
+ - test/greeter/server.rb
61
+ - test/multiple_working_servers_test.rb
62
+ - test/simple_test.rb
63
+ - test/test_helper.rb
64
+ - test/thrift_client_http_test.rb
65
+ - test/thrift_client_test.rb
66
+ - thrift_client.gemspec
67
+ has_rdoc: true
68
+ homepage: http://blog.evanweaver.com/files/doc/fauna/thrift_client/
69
+ licenses: []
70
+
71
+ post_install_message:
72
+ rdoc_options:
73
+ - --line-numbers
74
+ - --inline-source
75
+ - --title
76
+ - Thrift_client
77
+ - --main
78
+ - README.rdoc
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ hash: 27
96
+ segments:
97
+ - 0
98
+ - 8
99
+ version: "0.8"
100
+ requirements: []
101
+
102
+ rubyforge_project: fauna
103
+ rubygems_version: 1.3.9.3
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: A Thrift client wrapper that encapsulates some common failover behavior.
107
+ test_files:
108
+ - test/multiple_working_servers_test.rb
109
+ - test/simple_test.rb
110
+ - test/test_helper.rb
111
+ - test/thrift_client_http_test.rb
112
+ - test/thrift_client_test.rb