stark 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,187 @@
1
+ require 'test/unit'
2
+
3
+ require 'stark'
4
+ require 'thrift'
5
+
6
+ require 'test/test_helper'
7
+
8
+ class TestCoerceStrings1 < Test::Unit::TestCase
9
+ IDL = "test/ThriftSpec.thrift"
10
+ SERVICE = "SpecNamespace::NonblockingService"
11
+ include TestHelper
12
+
13
+ class Handler
14
+ def sleep_value
15
+ @sleep
16
+ end
17
+
18
+ def sleep(sec)
19
+ @sleep = sec
20
+ end
21
+ end
22
+
23
+ def setup
24
+ @handler = Handler.new
25
+ setup_server @handler
26
+ end
27
+
28
+ def test_coerce_string_to_double
29
+
30
+ send_to_server do
31
+ name = "sleep"
32
+ @client_p.write_message_begin name, Thrift::MessageTypes::CALL, 0
33
+ @client_p.write_struct_begin "#{name}_args"
34
+ @client_p.write_field_begin "seconds", Thrift::Types::STRING, 1
35
+ @client_p.write_string "1.5"
36
+ @client_p.write_field_end
37
+ @client_p.write_field_stop
38
+ @client_p.write_struct_end
39
+ @client_p.write_message_end
40
+ @client_p.trans.flush
41
+
42
+ @client_p.read_message_begin
43
+ @client_p.skip Thrift::Types::STRUCT
44
+ @client_p.read_message_end
45
+ end
46
+
47
+ assert_equal 1.5, @handler.sleep_value
48
+ end
49
+ end
50
+
51
+ class TestCoerceStrings2 < Test::Unit::TestCase
52
+ IDL = "test/profile.thrift"
53
+ SERVICE = "UserStorage"
54
+ include TestHelper
55
+
56
+ def setup
57
+ setup_server
58
+ end
59
+
60
+ def test_coerce_string_to_int
61
+
62
+ send_to_server do
63
+ name = "add"
64
+ @client_p.write_message_begin name, Thrift::MessageTypes::CALL, 0
65
+ @client_p.write_struct_begin "#{name}_args"
66
+ @client_p.write_field_begin "a", Thrift::Types::STRING, 1
67
+ @client_p.write_string "1"
68
+ @client_p.write_field_end
69
+ @client_p.write_field_begin "b", Thrift::Types::STRING, 2
70
+ @client_p.write_string "1"
71
+ @client_p.write_field_end
72
+ @client_p.write_field_stop
73
+ @client_p.write_struct_end
74
+ @client_p.write_message_end
75
+ @client_p.trans.flush
76
+
77
+ @client_p.read_message_begin
78
+ @client_p.read_struct_begin
79
+ _, _, fid = @client_p.read_field_begin
80
+ assert_equal 0, fid
81
+ assert_equal 2, @client_p.read_i32
82
+ @client_p.read_field_end
83
+ _, type, _ = @client_p.read_field_begin
84
+ assert_equal type, Thrift::Types::STOP
85
+ @client_p.read_struct_end
86
+ @client_p.read_message_end
87
+ end
88
+ end
89
+
90
+ def test_coerce_number_list_to_string_list
91
+ send_to_server do
92
+ name = "set_list"
93
+ @client_p.write_message_begin name, Thrift::MessageTypes::CALL, 0
94
+ @client_p.write_struct_begin "#{name}_args"
95
+ @client_p.write_field_begin "l", Thrift::Types::LIST, 1
96
+ @client_p.write_list_begin ::Thrift::Types::I32, 3
97
+ @client_p.write_i32 1
98
+ @client_p.write_i32 2
99
+ @client_p.write_i32 3
100
+ @client_p.write_list_end
101
+ @client_p.write_field_end
102
+ @client_p.write_field_stop
103
+ @client_p.write_struct_end
104
+ @client_p.write_message_end
105
+ @client_p.trans.flush
106
+ end
107
+
108
+ assert_equal ["1", "2", "3"], @handler.last_list
109
+ end
110
+
111
+ def test_coerce_strings_on_write_parameter
112
+ @handler.store @n::UserProfile.new(:uid => 123, :name => "Gob")
113
+
114
+ profile = send_to_server do
115
+ @client.retrieve "123"
116
+ end
117
+
118
+ assert profile
119
+ assert_equal "Gob", profile.name
120
+ end
121
+
122
+ def test_coerce_strings_on_write_struct_field
123
+ send_to_server do
124
+ @client.set_user_friends @n::UserFriends.new(:user => "123")
125
+ end
126
+
127
+ assert @handler.user_friends
128
+ assert_equal 123, @handler.user_friends.user
129
+ end
130
+
131
+ def test_coercion_fails_on_write_with_incompatible_types
132
+ assert_raises TypeError do
133
+ @client.store "user_profile"
134
+ end
135
+ end
136
+
137
+ class BadTypesHandler
138
+ def initialize(n)
139
+ @n = n
140
+ end
141
+
142
+ def retrieve(uid)
143
+ @n::UserProfile.new(:uid => "123", :name => 123)
144
+ end
145
+
146
+ def volume_up
147
+ "11"
148
+ end
149
+ end
150
+
151
+ def test_coerce_strings_on_processor_write_struct_field
152
+ set_handler BadTypesHandler.new(@n)
153
+
154
+ profile = send_to_server do
155
+ @client.retrieve 123
156
+ end
157
+
158
+ assert profile
159
+ assert_equal "123", profile.name
160
+ end
161
+
162
+ def test_coerce_strings_on_processor_write_return_value
163
+ set_handler BadTypesHandler.new(@n)
164
+
165
+ vol = send_to_server do
166
+ @client.volume_up
167
+ end
168
+
169
+ assert vol
170
+ assert_equal 11, vol
171
+ end
172
+
173
+ def test_coercion_fails_on_processor_write_with_incompatible_types
174
+ set_handler Object.new.tap {|h|
175
+ def h.retrieve(uid)
176
+ "user_profile"
177
+ end
178
+ }
179
+
180
+ assert_raises Thrift::ApplicationException do
181
+ send_to_server do
182
+ @client.retrieve 123
183
+ end
184
+ end
185
+ end
186
+
187
+ end
@@ -0,0 +1,113 @@
1
+ module TestHelper
2
+ def setup_shared
3
+ @client_t, @server_t = Stark.pipe_transport
4
+ @client_p = Thrift::BinaryProtocol.new @client_t
5
+ @server_p = Thrift::BinaryProtocol.new @server_t
6
+
7
+ @n = Module.new
8
+ Stark.materialize self.class::IDL, @n
9
+ @s = @n.module_eval self.class::SERVICE
10
+ @prev_logger = Stark.logger
11
+ @log_stream = StringIO.new
12
+ Stark.logger = Logger.new @log_stream
13
+ end
14
+
15
+ def setup_client
16
+ setup_shared
17
+ @client = @n::UserStorage::Client.new @client_p, @client_p
18
+ @handler = Handler.new(Object)
19
+ @server = UserStorage::Processor.new @handler
20
+ end
21
+
22
+ def setup_server(handler = nil)
23
+ setup_shared
24
+ @client = @s::Client.new @client_p, @client_p
25
+ set_handler handler
26
+ end
27
+
28
+ def set_handler(handler = nil)
29
+ @handler = handler || Handler.new(@n)
30
+ @server = @s::Processor.new @handler
31
+ end
32
+
33
+ def teardown
34
+ print @log_stream.string unless passed?
35
+ Stark.logger = @prev_logger
36
+ @client_t.close
37
+ @server_t.close
38
+ end
39
+
40
+ class Handler
41
+ def initialize(n)
42
+ @users = {}
43
+ @last_map = nil
44
+ @last_list = nil
45
+ @last_status = nil
46
+ @n = n
47
+ @user_status = nil
48
+ @user_relationship = nil
49
+ @user_friends = nil
50
+ end
51
+
52
+ attr_accessor :last_map, :last_list, :last_status, :user_status
53
+
54
+ def store(obj)
55
+ @users[obj.uid] = obj
56
+ end
57
+
58
+ def retrieve(id)
59
+ @users[id]
60
+ end
61
+
62
+ def set_map(m)
63
+ @last_map = m
64
+ end
65
+
66
+ def set_list(l)
67
+ @last_list = l
68
+ end
69
+
70
+ def set_status(s)
71
+ @last_status = s
72
+ end
73
+
74
+ def volume_up
75
+ raise @n::RockTooHard.new(:volume => 11)
76
+ end
77
+
78
+ def make_bitcoins
79
+ sleep 2
80
+ end
81
+
82
+ def add(a,b)
83
+ a + b
84
+ end
85
+
86
+ def set_user_status(s)
87
+ @user_status = s
88
+ end
89
+
90
+ attr_accessor :user_relationship
91
+ def set_user_relationship(rel)
92
+ @user_relationship = rel
93
+ end
94
+
95
+ attr_accessor :user_friends
96
+ def set_user_friends(fr)
97
+ @user_friends = fr
98
+ end
99
+ end
100
+
101
+ def send_to_server
102
+ st = Thread.new do
103
+ @server.process @server_p, @server_p
104
+ end
105
+ yield
106
+ rescue => e
107
+ st = nil
108
+ raise e
109
+ ensure
110
+ st.value if st
111
+ end
112
+
113
+ end
@@ -0,0 +1,131 @@
1
+ require 'test/unit'
2
+
3
+ require 'stark'
4
+ require 'thrift'
5
+
6
+ require 'test/test_helper'
7
+
8
+ class TestMarshal < Test::Unit::TestCase
9
+ IDL = "test/types.thrift"
10
+ SERVICE = "Types"
11
+ include TestHelper
12
+
13
+ class Handler
14
+ def initialize(n, at = nil, err = nil)
15
+ @n = n
16
+ @at = at || @n::AllTypes.new
17
+ @err = err
18
+ end
19
+
20
+ def get_all_types
21
+ @at
22
+ end
23
+
24
+ def set_all_types(at)
25
+ @at = at
26
+ end
27
+
28
+ def raise_error
29
+ raise @err if @err
30
+ end
31
+
32
+ def set_error(err)
33
+ @err = err
34
+ end
35
+ end
36
+
37
+ def create_all_types(fields)
38
+ @n::AllTypes.new(fields).tap do |af|
39
+ enum = fields.keys.first.to_s.sub(/^an?_/, '')
40
+ af.field = enum.to_sym
41
+ end
42
+ end
43
+
44
+ def setup
45
+ setup_server
46
+ set_handler Handler.new(@n)
47
+ end
48
+
49
+ def test_returning_struct
50
+ send_to_server do
51
+ assert @client.get_all_types.field.nil?
52
+ end
53
+ end
54
+
55
+ def test_returning_a_list_of_structs
56
+ l = [@n::Element.new(:id => 1, :name => "one"), @n::Element.new(:id => 2, :name => "two")]
57
+ @handler.set_all_types create_all_types(:a_list_of_structs => l)
58
+
59
+ at = send_to_server do
60
+ @client.get_all_types
61
+ end
62
+
63
+ assert_equal :list_of_structs, at.field
64
+ assert_equal 2, at.a_list_of_structs.size
65
+ el = at.a_list_of_structs[0]
66
+ assert_equal 1, el.id
67
+ assert_equal "one", el.name
68
+ el = at.a_list_of_structs[1]
69
+ assert_equal 2, el.id
70
+ assert_equal "two", el.name
71
+ end
72
+
73
+ def test_returning_a_map
74
+ ascii = Hash[*(0...128).map{|n| [n, n.chr]}.flatten]
75
+ @handler.set_all_types create_all_types(:a_map => ascii)
76
+
77
+ at = send_to_server do
78
+ @client.get_all_types
79
+ end
80
+
81
+ assert_equal :map, at.field
82
+ assert_equal ascii, at.a_map
83
+ end
84
+
85
+ def test_returning_a_set
86
+ primes = begin
87
+ require 'prime'
88
+ Prime::instance.each(256).to_a
89
+ rescue LoadError
90
+ require 'mathn'
91
+ p = Prime.new
92
+ [].tap {|arr| 256.times { arr << p.next } }
93
+ end
94
+ @handler.set_all_types create_all_types(:a_set => primes + primes)
95
+
96
+ at = send_to_server do
97
+ @client.get_all_types
98
+ end
99
+
100
+ assert_equal :set, at.field
101
+ assert_equal Set.new(primes), at.a_set
102
+ end
103
+
104
+ def test_raise_no_error
105
+ send_to_server do
106
+ assert @client.raise_error.nil?
107
+ end
108
+ end
109
+
110
+ def test_raise_first_error
111
+ err = @n::AnException.new :message => "An error occurred", :backtrace => caller
112
+ @handler.set_error err
113
+ exception = send_to_server do
114
+ assert_raises @n::AnException do
115
+ @client.raise_error
116
+ end
117
+ end
118
+
119
+ assert_equal err.message, exception.message
120
+ assert_equal err.backtrace, exception.backtrace
121
+ end
122
+
123
+ def test_raise_second_error
124
+ @handler.set_error @n::AnotherException.new
125
+ send_to_server do
126
+ assert_raises @n::AnotherException do
127
+ @client.raise_error
128
+ end
129
+ end
130
+ end
131
+ end
@@ -56,6 +56,17 @@ struct Foo {
56
56
  EOM
57
57
  end
58
58
 
59
+ def test_list_with_struct
60
+ parse <<-EOM
61
+ struct Foo {
62
+ 1: i32 uid
63
+ }
64
+ struct Bar {
65
+ 1: list<Foo> foos
66
+ }
67
+ EOM
68
+ end
69
+
59
70
  include Stark::Parser::AST
60
71
 
61
72
  def comment(text)
@@ -355,5 +366,55 @@ namespace rb Blah
355
366
  assert_field fs[0], 1, "My_union", "fun_union"
356
367
  assert_field fs[1], 2, "i32", "integer32"
357
368
  assert_field fs[2], 3, "string", "some_characters"
369
+
370
+ s = ary.shift
371
+ assert_equal "StructWithEnumMap", s.name
372
+
373
+ s = ary.shift
374
+ # comment
375
+
376
+ s = ary.shift
377
+ assert_equal "NestedListInList", s.name
378
+
379
+ s = ary.shift
380
+ assert_equal "NestedListInSet", s.name
381
+
382
+ s = ary.shift
383
+ assert_equal "NestedListInMapKey", s.name
384
+
385
+ s = ary.shift
386
+ assert_equal "NestedListInMapValue", s.name
387
+
388
+ s = ary.shift # comment
389
+ s = ary.shift
390
+ assert_equal "NestedSetInList", s.name
391
+
392
+ s = ary.shift
393
+ assert_equal "NestedSetInSet", s.name
394
+
395
+ s = ary.shift
396
+ assert_equal "NestedSetInMapKey", s.name
397
+
398
+ s = ary.shift
399
+ assert_equal "NestedSetInMapValue", s.name
400
+
401
+ s = ary.shift # comment
402
+ s = ary.shift
403
+ assert_equal "NestedMapInList", s.name
404
+
405
+ s = ary.shift
406
+ assert_equal "NestedMapInSet", s.name
407
+
408
+ s = ary.shift
409
+ assert_equal "NestedMapInMapKey", s.name
410
+
411
+ s = ary.shift
412
+ assert_equal "NestedMapInMapValue", s.name
413
+
414
+ s = ary.shift
415
+ assert_equal "HelloService", s.name
416
+ fs = s.functions
417
+
418
+ assert_func fs[0], list("Hello"), "all", nil
358
419
  end
359
420
  end