stark 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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