fraggle-spanx 4.0.1.1

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,60 @@
1
+ ## Generated from msg.proto for server
2
+ require "beefcake"
3
+
4
+ module Fraggle
5
+
6
+ class Request
7
+ include Beefcake::Message
8
+
9
+ module Verb
10
+ GET = 1
11
+ SET = 2
12
+ DEL = 3
13
+ REV = 5
14
+ WAIT = 6
15
+ NOP = 7
16
+ WALK = 9
17
+ GETDIR = 14
18
+ STAT = 16
19
+ ACCESS = 99
20
+ end
21
+
22
+ optional :tag, :int32, 1
23
+ optional :verb, Request::Verb, 2
24
+ optional :path, :string, 4
25
+ optional :value, :bytes, 5
26
+ optional :other_tag, :int32, 6
27
+ optional :offset, :int32, 7
28
+ optional :rev, :int64, 9
29
+
30
+ end
31
+
32
+ class Response
33
+ include Beefcake::Message
34
+
35
+ module Err
36
+ OTHER = 127
37
+ TAG_IN_USE = 1
38
+ UNKNOWN_VERB = 2
39
+ READONLY = 3
40
+ TOO_LATE = 4
41
+ REV_MISMATCH = 5
42
+ BAD_PATH = 6
43
+ MISSING_ARG = 7
44
+ RANGE = 8
45
+ NOTDIR = 20
46
+ ISDIR = 21
47
+ NOENT = 22
48
+ end
49
+
50
+ optional :tag, :int32, 1
51
+ optional :flags, :int32, 2
52
+ optional :rev, :int64, 3
53
+ optional :path, :string, 5
54
+ optional :value, :bytes, 6
55
+ optional :len, :int32, 8
56
+ optional :err_code, Response::Err, 100
57
+ optional :err_detail, :string, 101
58
+
59
+ end
60
+ end
@@ -0,0 +1,28 @@
1
+ require 'fraggle/msg.pb'
2
+
3
+ module Fraggle
4
+ class Response
5
+
6
+ SET = 4
7
+ DEL = 8
8
+
9
+ def set?
10
+ return false if !flags
11
+ (flags & SET) > 0
12
+ end
13
+
14
+ def del?
15
+ return false if !flags
16
+ (flags & DEL) > 0
17
+ end
18
+
19
+ def missing?
20
+ rev == 0
21
+ end
22
+
23
+ def ok?
24
+ err_code.nil?
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module Fraggle
2
+ VERSION = "4.0.1.1"
3
+ end
@@ -0,0 +1,238 @@
1
+ require File.expand_path(File.dirname(__FILE__)+"/helper")
2
+ require 'fraggle/client'
3
+
4
+ class FraggleClientTest < Test::Unit::TestCase
5
+
6
+ attr_reader :c
7
+
8
+ def setup
9
+ addr = "127.0.0.1:0"
10
+ cn = TestConn.new(addr)
11
+
12
+ @addrs = ["1.1.1.1:1", "2.2.2.2:2", "3.3.3.3:3"]
13
+ @c = Fraggle::Client.allocate
14
+
15
+ def @c.reconnect(addr)
16
+ @cn = TestConn.new(addr)
17
+ end
18
+
19
+ def @c.monitor_addrs
20
+ # do nothing
21
+ end
22
+
23
+ @c.__send__(:initialize, cn, @addrs)
24
+ end
25
+
26
+ def test_response_error
27
+ req, log = request(V::REV)
28
+
29
+ c.send(req, &log)
30
+
31
+ res = reply(req.tag, :err_code => E::OTHER)
32
+ c.cn.receive_response(res)
33
+
34
+ assert_equal [[nil, C::ResponseError.new(res)]], log
35
+ end
36
+
37
+ def test_reconnect_without_pending_requests
38
+ exp = @addrs.dup
39
+
40
+ # Disconnect from 127.0.0.1:0
41
+ c.cn.close_connection
42
+
43
+ # Send a request to invoke reconnect
44
+ req, log = request(V::REV)
45
+ c.send(req, &log)
46
+
47
+ # Fake reactor turn (only available in tests)
48
+ c.cn.tick!
49
+
50
+ assert exp.include?(c.cn.addr), "#{c.cn.addr.inspect} not in #{exp.inspect}"
51
+
52
+ # If the client can handle an error, it should not mention it to the user.
53
+ assert_equal [[nil, C::DisconnectedError.new("127.0.0.1:0")]], log
54
+ end
55
+
56
+ def test_reconnect_with_pending_request
57
+ exp = @addrs.dup
58
+
59
+ # Send a request to invoke reconnect
60
+ req, log = request(V::REV)
61
+ c.send(req, &log)
62
+
63
+ # Disconnect from 127.0.0.1:0
64
+ c.cn.close_connection
65
+
66
+ # Fake reactor turn (only available in tests)
67
+ c.cn.tick!
68
+
69
+ assert exp.include?(c.cn.addr), "#{c.cn.addr.inspect} not in #{exp.inspect}"
70
+
71
+ assert_equal [[nil, C::DisconnectedError.new("127.0.0.1:0")]], log
72
+ end
73
+
74
+ def test_reconnect_with_multiple_pending_requests
75
+ exp = @addrs.dup
76
+
77
+ # Send a request to invoke reconnect
78
+ req, loga = request(V::REV)
79
+ c.send(req, &loga)
80
+
81
+ req, logb = request(V::REV)
82
+ c.send(req, &logb)
83
+
84
+ # Disconnect from 127.0.0.1:0
85
+ c.cn.close_connection
86
+
87
+ # Fake reactor turn (only available in tests)
88
+ c.cn.tick!
89
+
90
+ assert exp.include?(c.cn.addr), "#{c.cn.addr.inspect} not in #{exp.inspect}"
91
+
92
+ # If the client can handle an error, it should not mention it to the user.
93
+ assert_equal [[nil, C::DisconnectedError.new("127.0.0.1:0")]], loga
94
+ assert_equal [[nil, C::DisconnectedError.new("127.0.0.1:0")]], logb
95
+ end
96
+
97
+ def test_resend_pending_requests
98
+ req, log = request(V::GET, :path => "/foo")
99
+ c.resend(req, &log)
100
+
101
+ c.cn.close_connection
102
+
103
+ assert_equal [req], c.cn.sent
104
+ end
105
+
106
+ def test_idemp_pending_requests
107
+ one, olog = request(V::SET, :rev => 1, :path => "/foo", :value => "bar")
108
+ c.idemp(one, &olog)
109
+
110
+ zero, zlog = request(V::SET, :rev => 0, :path => "/foo", :value => "bar")
111
+ c.idemp(zero, &zlog)
112
+
113
+ c.cn.close_connection
114
+
115
+ assert_equal [one], c.cn.sent
116
+
117
+ assert_equal [[nil, C::DisconnectedError.new("127.0.0.1:0")]], zlog
118
+ end
119
+
120
+ def test_idemp_unhandled_error
121
+ req, log = request(V::SET, :path => "/foo", :value => "bar", :rev => Fraggle::Client::MaxInt64)
122
+ c.idemp(req, &log)
123
+
124
+ res = reply(req.tag, :err_code => E::OTHER)
125
+ c.cn.receive_response(res)
126
+
127
+ assert_equal [[nil, C::ResponseError.new(res)]], log
128
+ end
129
+
130
+ ###
131
+ # Sugar
132
+
133
+ def last_sent
134
+ c.cn.sent.last
135
+ end
136
+
137
+ def assert_verb(exp, name, *args)
138
+ called = false
139
+ blk = Proc.new { called = true }
140
+ req = c.__send__(name, *args, &blk)
141
+ exp[:tag] = req.tag
142
+ assert_equal exp, last_sent.to_hash
143
+
144
+ c.cn.receive_response(reply(req.tag))
145
+ assert called
146
+ end
147
+
148
+ def test_set
149
+ exp = {
150
+ :verb => V::SET,
151
+ :rev => 0,
152
+ :path => "/foo",
153
+ :value => "bar"
154
+ }
155
+
156
+ assert_verb exp, :set, 0, "/foo", "bar"
157
+ end
158
+
159
+ def test_get
160
+ exp = {
161
+ :verb => V::GET,
162
+ :rev => 0,
163
+ :path => "/foo"
164
+ }
165
+
166
+ assert_verb exp, :get, 0, "/foo"
167
+ end
168
+
169
+ def test_del
170
+ exp = {
171
+ :verb => V::DEL,
172
+ :rev => 0,
173
+ :path => "/foo"
174
+ }
175
+
176
+ assert_verb exp, :del, 0, "/foo"
177
+ end
178
+
179
+ def test_getdir
180
+ exp = {
181
+ :verb => V::GETDIR,
182
+ :rev => 0,
183
+ :path => "/foo",
184
+ :offset => 0
185
+ }
186
+
187
+ assert_verb exp, :_getdir, 0, "/foo", 0
188
+ end
189
+
190
+ def test_rev
191
+ exp = {
192
+ :verb => V::REV
193
+ }
194
+
195
+ assert_verb exp, :rev
196
+ end
197
+
198
+ def test_stat
199
+ exp = {
200
+ :rev => 0,
201
+ :verb => V::STAT,
202
+ :path => "/foo"
203
+ }
204
+
205
+ assert_verb exp, :stat, 0, "/foo"
206
+ end
207
+
208
+ def test_walk
209
+ exp = {
210
+ :verb => V::WALK,
211
+ :rev => 0,
212
+ :path => "/foo/*",
213
+ :offset => 0
214
+ }
215
+
216
+ assert_verb exp, :_walk, 0, "/foo/*", 0
217
+ end
218
+
219
+ def test_wait
220
+ exp = {
221
+ :verb => V::WAIT,
222
+ :rev => 0,
223
+ :path => "/foo/*"
224
+ }
225
+
226
+ assert_verb exp, :wait, 0, "/foo/*"
227
+ end
228
+
229
+ def test_wait
230
+ exp = {
231
+ :verb => V::ACCESS,
232
+ :value => "abc"
233
+ }
234
+
235
+ assert_verb exp, :access, "abc"
236
+ end
237
+
238
+ end
@@ -0,0 +1,88 @@
1
+ require File.expand_path(File.dirname(__FILE__)+"/helper")
2
+ require 'fraggle/connection'
3
+
4
+ class FraggleProtocolTest < Test::Unit::TestCase
5
+
6
+ attr_reader :cn
7
+
8
+ def setup
9
+ @cn = TestConn.new("127.0.0.1:0")
10
+ end
11
+
12
+ def encode(req)
13
+ data = req.encode
14
+ [data.length].pack("N") + data
15
+ end
16
+
17
+ def test_simple
18
+ req = Fraggle::Response.new :tag => 0, :verb => V::NOP
19
+ cn.receive_data(encode(req))
20
+
21
+ assert_equal [req], cn.received
22
+ end
23
+
24
+ def test_multiple_single
25
+ a = Fraggle::Response.new :tag => 0, :verb => V::NOP
26
+ b = Fraggle::Response.new :tag => 1, :verb => V::NOP
27
+ cn.receive_data(encode(a) + encode(b))
28
+
29
+ assert_equal [a, b], cn.received
30
+ end
31
+
32
+ def test_multiple_double
33
+ a = Fraggle::Response.new :tag => 0, :verb => V::NOP
34
+ b = Fraggle::Response.new :tag => 1, :verb => V::NOP
35
+ cn.receive_data(encode(a))
36
+ cn.receive_data(encode(b))
37
+
38
+ assert_equal [a, b], cn.received
39
+ end
40
+
41
+ def test_small_chunks
42
+ req = Fraggle::Response.new :tag => 0, :verb => V::NOP
43
+
44
+ bytes = encode(req) * 3
45
+ len = bytes.length
46
+
47
+ 0.step(len, 1) do |i|
48
+ data = bytes.slice!(0, i)
49
+ cn.receive_data(data)
50
+ end
51
+
52
+ assert_equal [req, req, req], cn.received
53
+ end
54
+
55
+ def test_big_chunks
56
+ req = Fraggle::Response.new :tag => 0, :verb => V::NOP
57
+
58
+ bytes = encode(req) * 3
59
+ len = bytes.length
60
+
61
+ 0.step(len, len/2) do |i|
62
+ data = bytes.slice!(0, i)
63
+ cn.receive_data(data)
64
+ end
65
+
66
+ assert_equal [req, req, req], cn.received
67
+ end
68
+
69
+ def test_send_request
70
+ req = Fraggle::Request.new :tag => 0, :verb => V::NOP
71
+ bytes = req.encode
72
+ head = [bytes.length].pack("N")
73
+ exp = head+bytes
74
+
75
+ got = ""
76
+ (class << cn ; self ; end).instance_eval do
77
+ define_method(:send_data) do |data|
78
+ got << data
79
+ end
80
+ end
81
+
82
+ nop = Fraggle::Request.new :verb => V::NOP
83
+ cn.send_request(nop, nil)
84
+
85
+ assert_equal head+bytes, got
86
+ end
87
+
88
+ end
@@ -0,0 +1,12 @@
1
+ require 'fraggle'
2
+
3
+ class FraggleTest < Test::Unit::TestCase
4
+
5
+ def test_uri
6
+ uri = "doozer:?ca=1:1&ca=2:2&ca=3:3&ignore=this&sk=foo"
7
+ addrs, sk = Fraggle.uri(uri)
8
+ assert_equal ["1:1", "2:2", "3:3"], addrs
9
+ assert_equal "foo", sk
10
+ end
11
+
12
+ end
@@ -0,0 +1,116 @@
1
+ require File.expand_path(File.dirname(__FILE__)+"/helper")
2
+ require 'fraggle/connection'
3
+
4
+ class FraggleTransactionTest < Test::Unit::TestCase
5
+
6
+ attr_reader :cn
7
+
8
+ def setup
9
+ @cn = TestConn.new("127.0.0.1:0")
10
+ end
11
+
12
+ def test_tagging
13
+ req, _ = request(V::REV)
14
+ assert_equal 0, cn.send_request(req, _).tag
15
+ req, _ = request(V::REV)
16
+ assert_equal 1, cn.send_request(req, _).tag
17
+ req, _ = request(V::REV)
18
+ assert_equal 2, cn.send_request(req, _).tag
19
+ end
20
+
21
+ def test
22
+ req, log = request(V::REV)
23
+
24
+ cn.send_request(req, log)
25
+
26
+ res = reply(req.tag)
27
+ cn.receive_response(res)
28
+
29
+ assert_equal [[res, nil]], log
30
+ end
31
+
32
+ def test_error
33
+ req, log = request(V::REV)
34
+
35
+ cn.send_request(req, log)
36
+
37
+ res = reply(req.tag, :err_code => E::OTHER)
38
+ cn.receive_response(res)
39
+
40
+ err = C::ResponseError.new(res)
41
+ assert_equal [[nil, err]], log
42
+ end
43
+
44
+ def test_i_tag
45
+ res = reply(0, :err_code => E::OTHER)
46
+
47
+ assert_nothing_raised do
48
+ cn.receive_response(res)
49
+ end
50
+ end
51
+
52
+ def test_deletes_callback
53
+ req, log = request(V::REV)
54
+
55
+ cn.send_request(req, log)
56
+
57
+ res = reply(req.tag)
58
+ cn.receive_response(res)
59
+
60
+ # This should be ignored
61
+ cn.receive_response(res)
62
+
63
+ assert_equal [[res, nil]], log
64
+ end
65
+
66
+ def test_error_deletes_callback
67
+ req, log = request(V::REV)
68
+
69
+ cn.send_request(req, log)
70
+
71
+ res = reply(req.tag, :err_code => E::OTHER)
72
+ cn.receive_response(res)
73
+
74
+ # This should be ignored
75
+ cn.receive_response(res)
76
+
77
+ assert_equal [[nil, C::ResponseError.new(res)]], log
78
+ end
79
+
80
+ def test_cannot_reuse_sent_request
81
+ req, _ = request(V::REV)
82
+ cn.send_request(req, _)
83
+
84
+ assert_raises C::SendError do
85
+ cn.send_request(req, _)
86
+ end
87
+ end
88
+
89
+ def test_disconnect_with_pending_requests
90
+ a, al = request(V::REV)
91
+ a = cn.send_request(a, al)
92
+ b, bl = request(V::REV)
93
+ b = cn.send_request(b, bl)
94
+ c, cl = request(V::REV)
95
+ c = cn.send_request(c, cl)
96
+
97
+ cn.unbind
98
+
99
+ assert_equal [[nil, C::DisconnectedError.new("127.0.0.1:0")]], al
100
+ assert_equal [[nil, C::DisconnectedError.new("127.0.0.1:0")]], bl
101
+ assert_equal [[nil, C::DisconnectedError.new("127.0.0.1:0")]], cl
102
+ end
103
+
104
+ def test_send_when_disconnected
105
+ cn.unbind
106
+
107
+ req, log = request(V::REV)
108
+ ret = cn.send_request(req, log)
109
+
110
+ assert_equal req, ret
111
+
112
+ cn.tick!
113
+
114
+ assert_equal [[nil, C::DisconnectedError.new("127.0.0.1:0")]], log
115
+ end
116
+ end