zookeeper-ng 1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/.ctags_paths +1 -0
  3. data/.dotfiles/ruby-gemset +1 -0
  4. data/.dotfiles/ruby-version +1 -0
  5. data/.dotfiles/rvmrc +2 -0
  6. data/.gitignore +19 -0
  7. data/.gitmodules +3 -0
  8. data/.travis.yml +25 -0
  9. data/CHANGELOG +395 -0
  10. data/Gemfile +30 -0
  11. data/Guardfile +8 -0
  12. data/LICENSE +23 -0
  13. data/Manifest +29 -0
  14. data/README.markdown +85 -0
  15. data/Rakefile +121 -0
  16. data/cause-abort.rb +117 -0
  17. data/ext/.gitignore +6 -0
  18. data/ext/Rakefile +41 -0
  19. data/ext/c_zookeeper.rb +398 -0
  20. data/ext/common.h +17 -0
  21. data/ext/dbg.h +53 -0
  22. data/ext/depend +5 -0
  23. data/ext/event_lib.c +740 -0
  24. data/ext/event_lib.h +175 -0
  25. data/ext/extconf.rb +103 -0
  26. data/ext/generate_gvl_code.rb +321 -0
  27. data/ext/patches/zkc-3.3.5-network.patch +24 -0
  28. data/ext/patches/zkc-3.4.5-fetch-and-add.patch +16 -0
  29. data/ext/patches/zkc-3.4.5-logging.patch +41 -0
  30. data/ext/patches/zkc-3.4.5-out-of-order-ping.patch +163 -0
  31. data/ext/patches/zkc-3.4.5-overflow.patch +11 -0
  32. data/ext/patches/zkc-3.4.5-yosemite-htonl-fix.patch +102 -0
  33. data/ext/zkc-3.4.5.tar.gz +0 -0
  34. data/ext/zkrb.c +1075 -0
  35. data/ext/zkrb_wrapper.c +775 -0
  36. data/ext/zkrb_wrapper.h +350 -0
  37. data/ext/zkrb_wrapper_compat.c +15 -0
  38. data/ext/zkrb_wrapper_compat.h +11 -0
  39. data/ext/zookeeper_base.rb +256 -0
  40. data/java/java_base.rb +503 -0
  41. data/lib/zookeeper.rb +115 -0
  42. data/lib/zookeeper/acls.rb +44 -0
  43. data/lib/zookeeper/callbacks.rb +108 -0
  44. data/lib/zookeeper/client.rb +30 -0
  45. data/lib/zookeeper/client_methods.rb +282 -0
  46. data/lib/zookeeper/common.rb +122 -0
  47. data/lib/zookeeper/common/queue_with_pipe.rb +110 -0
  48. data/lib/zookeeper/compatibility.rb +138 -0
  49. data/lib/zookeeper/constants.rb +97 -0
  50. data/lib/zookeeper/continuation.rb +223 -0
  51. data/lib/zookeeper/core_ext.rb +58 -0
  52. data/lib/zookeeper/em_client.rb +55 -0
  53. data/lib/zookeeper/exceptions.rb +135 -0
  54. data/lib/zookeeper/forked.rb +19 -0
  55. data/lib/zookeeper/latch.rb +34 -0
  56. data/lib/zookeeper/logger.rb +39 -0
  57. data/lib/zookeeper/logger/forwarding_logger.rb +84 -0
  58. data/lib/zookeeper/monitor.rb +19 -0
  59. data/lib/zookeeper/rake_tasks.rb +165 -0
  60. data/lib/zookeeper/request_registry.rb +153 -0
  61. data/lib/zookeeper/stat.rb +21 -0
  62. data/lib/zookeeper/version.rb +4 -0
  63. data/notes.txt +14 -0
  64. data/scripts/upgrade-1.0-sed-alike.rb +46 -0
  65. data/spec/c_zookeeper_spec.rb +51 -0
  66. data/spec/chrooted_connection_spec.rb +83 -0
  67. data/spec/compatibilty_spec.rb +8 -0
  68. data/spec/default_watcher_spec.rb +41 -0
  69. data/spec/em_spec.rb +51 -0
  70. data/spec/ext/zookeeper_base_spec.rb +19 -0
  71. data/spec/forked_connection_spec.rb +124 -0
  72. data/spec/latch_spec.rb +24 -0
  73. data/spec/log4j.properties +17 -0
  74. data/spec/shared/all_success_return_values.rb +10 -0
  75. data/spec/shared/connection_examples.rb +1077 -0
  76. data/spec/spec_helper.rb +61 -0
  77. data/spec/support/00_logging.rb +38 -0
  78. data/spec/support/10_spawn_zookeeper.rb +24 -0
  79. data/spec/support/progress_formatter.rb +15 -0
  80. data/spec/support/zookeeper_spec_helpers.rb +96 -0
  81. data/spec/zookeeper_spec.rb +24 -0
  82. data/zookeeper.gemspec +38 -0
  83. data/zoomonkey/duplicates +3 -0
  84. data/zoomonkey/zoomonkey.rb +194 -0
  85. metadata +157 -0
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ # this is a simple sanity check of my timeout addition
4
+
5
+ describe Zookeeper::Latch do
6
+ subject { described_class.new }
7
+
8
+ describe %[await] do
9
+ describe %[with timeout] do
10
+ it %[should return after waiting until timeout if not released] do
11
+ other_latch = described_class.new
12
+
13
+ th = Thread.new do
14
+ subject.await(0.01)
15
+ other_latch.release
16
+ end
17
+
18
+ other_latch.await
19
+ th.join(1).should == th
20
+ end
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,17 @@
1
+ log4j.rootLogger = DEBUG,S
2
+
3
+ log4j.appender.S = org.apache.log4j.FileAppender
4
+ log4j.appender.S.File = /tmp/zk-test.log
5
+
6
+ log4j.appender.S.layout = org.apache.log4j.PatternLayout
7
+ log4j.appender.S.layout.ConversionPattern = %5p [%t] (%c:%F:%L) - %m%n
8
+
9
+ log4j.appender.C = org.apache.log4j.FileAppender
10
+ log4j.appender.C.File = /tmp/zk-test-client.log
11
+
12
+ log4j.appender.C.layout = org.apache.log4j.PatternLayout
13
+ log4j.appender.C.layout.ConversionPattern = %5p [%t] (%c:%F:%L) - %m%n
14
+
15
+ log4j.org.apache.zookeeper.ZooKeeper = DEBUG,C
16
+ log4j.org.apache.zookeeper.server = DEBUG,S
17
+
@@ -0,0 +1,10 @@
1
+ shared_examples_for "all success return values" do
2
+ it %[should have a return code of Zookeeper::ZOK] do
3
+ @rv[:rc].should == Zookeeper::ZOK
4
+ end
5
+
6
+ it %[should have a req_id integer] do
7
+ @rv[:req_id].should be_kind_of(Integer)
8
+ end
9
+ end
10
+
@@ -0,0 +1,1077 @@
1
+ require 'shared/all_success_return_values'
2
+
3
+ shared_examples_for "connection" do
4
+
5
+ before :each do
6
+ ensure_node(zk, path, data)
7
+ end
8
+
9
+ after :each do
10
+ ensure_node(zk, path, data)
11
+ end
12
+
13
+ after :all do
14
+ logger.warn "running shared examples after :all"
15
+
16
+ with_open_zk(connection_string) do |z|
17
+ rm_rf(z, path)
18
+ end
19
+ end
20
+
21
+ # unfortunately, we can't test w/o exercising other parts of the driver, so
22
+ # if "set" is broken, this test will fail as well (but whaddyagonnado?)
23
+ describe :get do
24
+ describe :sync, :sync => true do
25
+ it_should_behave_like "all success return values"
26
+
27
+ before do
28
+ @rv = zk.get(:path => path)
29
+ end
30
+
31
+ it %[should return the data] do
32
+ @rv[:data].should == data
33
+ end
34
+
35
+ it %[should return a stat] do
36
+ @rv[:stat].should_not be_nil
37
+ @rv[:stat].should be_kind_of(Zookeeper::Stat)
38
+ end
39
+ end
40
+
41
+ describe :sync_watch, :sync => true do
42
+ it_should_behave_like "all success return values"
43
+
44
+ before do
45
+ @event = nil
46
+ @watcher = Zookeeper::Callbacks::WatcherCallback.new
47
+
48
+ @rv = zk.get(:path => path, :watcher => @watcher, :watcher_context => path)
49
+ end
50
+
51
+ it %[should return the data] do
52
+ @rv[:data].should == data
53
+ end
54
+
55
+ it %[should set a watcher on the node] do
56
+ # test the watcher by changing node data
57
+ zk.set(:path => path, :data => 'blah')[:rc].should be_zero
58
+
59
+ wait_until(1.0) { @watcher.completed? }
60
+
61
+ @watcher.path.should == path
62
+ @watcher.context.should == path
63
+ @watcher.should be_completed
64
+ @watcher.type.should == Zookeeper::ZOO_CHANGED_EVENT
65
+ end
66
+ end
67
+
68
+ describe :async, :async => true do
69
+ before do
70
+ @cb = Zookeeper::Callbacks::DataCallback.new
71
+
72
+ @rv = zk.get(:path => path, :callback => @cb, :callback_context => path)
73
+ wait_until(1.0) { @cb.completed? }
74
+ @cb.should be_completed
75
+ end
76
+
77
+ it_should_behave_like "all success return values"
78
+
79
+ it %[should have a return code of ZOK] do
80
+ @cb.return_code.should == Zookeeper::ZOK
81
+ end
82
+
83
+ it %[should have the stat object in the callback] do
84
+ @cb.stat.should_not be_nil
85
+ @cb.stat.should be_kind_of(Zookeeper::Stat)
86
+ end
87
+
88
+ it %[should have the data] do
89
+ @cb.data.should == data
90
+ end
91
+ end
92
+
93
+ describe :async_watch, :async => true, :method => :get, :watch => true do
94
+ it_should_behave_like "all success return values"
95
+
96
+ before do
97
+ logger.debug { "-----------------> MAKING ASYNC GET REQUEST WITH WATCH <--------------------" }
98
+ @cb = Zookeeper::Callbacks::DataCallback.new
99
+ @watcher = Zookeeper::Callbacks::WatcherCallback.new
100
+
101
+ @rv = zk.get(:path => path, :callback => @cb, :callback_context => path, :watcher => @watcher, :watcher_context => path)
102
+ wait_until(1.0) { @cb.completed? }
103
+ @cb.should be_completed
104
+ logger.debug { "-----------------> ASYNC GET REQUEST WITH WATCH COMPLETE <--------------------" }
105
+ end
106
+
107
+ it %[should have the stat object in the callback] do
108
+ @cb.stat.should_not be_nil
109
+ @cb.stat.should be_kind_of(Zookeeper::Stat)
110
+ end
111
+
112
+ it %[should have the data] do
113
+ @cb.data.should == data
114
+ end
115
+
116
+ it %[should have a return code of ZOK] do
117
+ @cb.return_code.should == Zookeeper::ZOK
118
+ end
119
+
120
+ it %[should set a watcher on the node] do
121
+ zk.set(:path => path, :data => 'blah')[:rc].should be_zero
122
+
123
+ wait_until(2) { @watcher.completed? }
124
+
125
+ @watcher.should be_completed
126
+
127
+ @watcher.path.should == path
128
+ @watcher.context.should == path
129
+ end
130
+ end
131
+
132
+ describe 'bad arguments' do
133
+ it %[should barf with a BadArguments error] do
134
+ lambda { zk.get(:bad_arg => 'what!?') }.should raise_error(Zookeeper::Exceptions::BadArguments)
135
+ end
136
+ end
137
+ end # get
138
+
139
+ describe :set do
140
+ before do
141
+ @new_data = "Four score and \007 years ago"
142
+ @stat = zk.stat(:path => path)[:stat]
143
+ end
144
+
145
+ describe :sync, :sync => true do
146
+ describe 'without version' do
147
+ it_should_behave_like "all success return values"
148
+
149
+ before do
150
+ @rv = zk.set(:path => path, :data => @new_data)
151
+ end
152
+
153
+ it %[should return the new stat] do
154
+ @rv[:stat].should_not be_nil
155
+ @rv[:stat].should be_kind_of(Zookeeper::Stat)
156
+ @rv[:stat].version.should > @stat.version
157
+ end
158
+ end
159
+
160
+ describe 'with current version' do
161
+ it_should_behave_like "all success return values"
162
+
163
+ before do
164
+ @rv = zk.set(:path => path, :data => @new_data, :version => @stat.version)
165
+ end
166
+
167
+ it %[should return the new stat] do
168
+ @rv[:stat].should_not be_nil
169
+ @rv[:stat].should be_kind_of(Zookeeper::Stat)
170
+ @rv[:stat].version.should > @stat.version
171
+ end
172
+ end
173
+
174
+ describe 'with outdated version' do
175
+ before do
176
+ # need to do a couple of sets to ramp up the version
177
+ 3.times { |n| @stat = zk.set(:path => path, :data => "#{@new_data}#{n}")[:stat] }
178
+
179
+ @rv = zk.set(:path => path, :data => @new_data, :version => 0)
180
+ end
181
+
182
+ it %[should have a return code of ZBADVERSION] do
183
+ @rv[:rc].should == Zookeeper::ZBADVERSION
184
+ end
185
+
186
+ it %[should return a stat with !exists] do
187
+ @rv[:stat].exists.should be_false
188
+ end
189
+ end
190
+
191
+ describe 'error' do
192
+ it %[should barf if the data size is too large], :input_size => true do
193
+ large_data = '0' * (1024 ** 2)
194
+
195
+ lambda { zk.set(:path => path, :data => large_data) }.should raise_error(Zookeeper::Exceptions::DataTooLargeException)
196
+ end
197
+ end
198
+ end # sync
199
+
200
+ describe :async, :async => true do
201
+ before do
202
+ @cb = Zookeeper::Callbacks::StatCallback.new
203
+ end
204
+
205
+ describe 'without version' do
206
+ it_should_behave_like "all success return values"
207
+
208
+ before do
209
+ @rv = zk.set(:path => path, :data => @new_data, :callback => @cb, :callback_context => path)
210
+
211
+ wait_until(2) { @cb.completed? }
212
+ @cb.should be_completed
213
+ end
214
+
215
+ it %[should have the stat in the callback] do
216
+ @cb.stat.should_not be_nil
217
+ @cb.stat.version.should > @stat.version
218
+ end
219
+
220
+ it %[should have a return code of ZOK] do
221
+ @cb.return_code.should == Zookeeper::ZOK
222
+ end
223
+ end
224
+
225
+ describe 'with current version' do
226
+ it_should_behave_like "all success return values"
227
+
228
+ before do
229
+ @rv = zk.set(:path => path, :data => @new_data, :callback => @cb, :callback_context => path, :version => @stat.version)
230
+
231
+ wait_until(2) { @cb.completed? }
232
+ @cb.should be_completed
233
+ end
234
+
235
+ it %[should have the stat in the callback] do
236
+ @cb.stat.should_not be_nil
237
+ @cb.stat.version.should > @stat.version
238
+ end
239
+
240
+ it %[should have a return code of ZOK] do
241
+ @cb.return_code.should == Zookeeper::ZOK
242
+ end
243
+ end
244
+
245
+ describe 'with outdated version' do
246
+ before do
247
+ # need to do a couple of sets to ramp up the version
248
+ 3.times { |n| @stat = zk.set(:path => path, :data => "#{@new_data}#{n}")[:stat] }
249
+
250
+ @rv = zk.set(:path => path, :data => @new_data, :callback => @cb, :callback_context => path, :version => 0)
251
+
252
+ wait_until(2) { @cb.completed? }
253
+ @cb.should be_completed
254
+ end
255
+
256
+ it %[should have a return code of ZBADVERSION] do
257
+ @cb.return_code.should == Zookeeper::ZBADVERSION
258
+ end
259
+
260
+ it %[should return a stat with !exists] do
261
+ @cb.stat.exists.should be_false
262
+ end
263
+ end
264
+
265
+ describe 'error' do
266
+ it %[should barf if the data size is too large], :input_size => true do
267
+ large_data = '0' * (1024 ** 2)
268
+
269
+ lambda { zk.set(:path => path, :data => large_data, :callback => @cb, :callback_context => path) }.should raise_error(Zookeeper::Exceptions::DataTooLargeException)
270
+ end
271
+ end
272
+
273
+ end # async
274
+ end # set
275
+
276
+ describe :add_auth do
277
+ it %[should return ZOK if everything goes swimingly] do
278
+ result = zk.add_auth(:scheme => 'digest', :cert => 'test_user:test_password')
279
+
280
+ rv = result[:rc]
281
+
282
+ # gahhh, this shouldn't be like this.... :P
283
+ rv = rv.respond_to?(:intValue) ? rv.intValue : rv
284
+
285
+ rv.should == Zookeeper::ZOK
286
+ end
287
+ end
288
+
289
+ describe :get_children do
290
+ before do
291
+ @children = %w[child0 child1 child2]
292
+
293
+ @children.each do |name|
294
+ zk.create(:path => "#{path}/#{name}", :data => name)
295
+ end
296
+ end
297
+
298
+ after do
299
+ @children.each do |name|
300
+ zk.delete(:path => "#{path}/#{name}")
301
+ end
302
+ end
303
+
304
+ describe :sync, :sync => true do
305
+ it_should_behave_like "all success return values"
306
+
307
+ before do
308
+ @rv = zk.get_children(:path => path)
309
+ end
310
+
311
+ it %[should have an array of names of the children] do
312
+ @rv[:children].should be_kind_of(Array)
313
+ @rv[:children].length.should == 3
314
+ @rv[:children].sort.should == @children.sort
315
+ end
316
+
317
+ # "Three shall be the number of the counting, and the number of the counting shall be 3"
318
+
319
+ it %[should have a stat object whose num_children is 3] do
320
+ @rv[:stat].should_not be_nil
321
+ @rv[:stat].should be_kind_of(Zookeeper::Stat)
322
+ @rv[:stat].num_children.should == 3
323
+ end
324
+ end
325
+
326
+ describe :sync_watch, :sync => true do
327
+ it_should_behave_like "all success return values"
328
+
329
+ before do
330
+ @addtl_child = 'child3'
331
+
332
+ @watcher = Zookeeper::Callbacks::WatcherCallback.new
333
+
334
+ @rv = zk.get_children(:path => path, :watcher => @watcher, :watcher_context => path)
335
+ end
336
+
337
+ after do
338
+ zk.delete(:path => "#{path}/#{@addtl_child}")
339
+ end
340
+
341
+ it %[should have an array of names of the children] do
342
+ @rv[:children].should be_kind_of(Array)
343
+ @rv[:children].length.should == 3
344
+ @rv[:children].sort.should == @children.sort
345
+ end
346
+
347
+ it %[should have a stat object whose num_children is 3] do
348
+ @rv[:stat].should_not be_nil
349
+ @rv[:stat].should be_kind_of(Zookeeper::Stat)
350
+ @rv[:stat].num_children.should == 3
351
+ end
352
+
353
+ it %[should set a watcher for children on the node] do
354
+ @watcher.should_not be_completed
355
+
356
+ zk.create(:path => "#{path}/#{@addtl_child}", :data => '')[:rc].should == Zookeeper::ZOK
357
+
358
+ wait_until { @watcher.completed? }
359
+ @watcher.should be_completed
360
+
361
+ @watcher.path.should == path
362
+ @watcher.context.should == path
363
+ @watcher.type.should == Zookeeper::ZOO_CHILD_EVENT
364
+ end
365
+ end
366
+
367
+ describe :async, :async => true do
368
+ it_should_behave_like "all success return values"
369
+
370
+ before do
371
+ @cb = Zookeeper::Callbacks::StringsCallback.new
372
+ @rv = zk.get_children(:path => path, :callback => @cb, :callback_context => path)
373
+
374
+ wait_until { @cb.completed? }
375
+ @cb.should be_completed
376
+ end
377
+
378
+ it %[should succeed] do
379
+ @cb.return_code.should == Zookeeper::ZOK
380
+ end
381
+
382
+ it %[should return an array of children] do
383
+ @cb.children.should be_kind_of(Array)
384
+ @cb.children.length.should == 3
385
+ @cb.children.sort.should == @children.sort
386
+ end
387
+
388
+ it %[should have a stat object whose num_children is 3] do
389
+ @cb.stat.should_not be_nil
390
+ @cb.stat.should be_kind_of(Zookeeper::Stat)
391
+ @cb.stat.num_children.should == 3
392
+ end
393
+ end
394
+
395
+ describe :async_watch, :async => true do
396
+ it_should_behave_like "all success return values"
397
+
398
+ before do
399
+ @addtl_child = 'child3'
400
+
401
+ @watcher = Zookeeper::Callbacks::WatcherCallback.new
402
+ @cb = Zookeeper::Callbacks::StringsCallback.new
403
+
404
+ @rv = zk.get_children(:path => path, :watcher => @watcher, :watcher_context => path, :callback => @cb, :callback_context => path)
405
+ wait_until { @cb.completed? }
406
+ @cb.should be_completed
407
+ end
408
+
409
+ after do
410
+ zk.delete(:path => "#{path}/#{@addtl_child}")
411
+ end
412
+
413
+ it %[should succeed] do
414
+ @cb.return_code.should == Zookeeper::ZOK
415
+ end
416
+
417
+ it %[should return an array of children] do
418
+ @cb.children.should be_kind_of(Array)
419
+ @cb.children.length.should == 3
420
+ @cb.children.sort.should == @children.sort
421
+ end
422
+
423
+ it %[should have a stat object whose num_children is 3] do
424
+ @cb.stat.should_not be_nil
425
+ @cb.stat.should be_kind_of(Zookeeper::Stat)
426
+ @cb.stat.num_children.should == 3
427
+ end
428
+
429
+ it %[should set a watcher for children on the node] do
430
+ @watcher.should_not be_completed
431
+
432
+ zk.create(:path => "#{path}/#{@addtl_child}", :data => '')[:rc].should == Zookeeper::ZOK
433
+
434
+ wait_until { @watcher.completed? }
435
+ @watcher.should be_completed
436
+
437
+ @watcher.path.should == path
438
+ @watcher.context.should == path
439
+ @watcher.type.should == Zookeeper::ZOO_CHILD_EVENT
440
+ end
441
+ end
442
+ end
443
+
444
+ describe :child_watcher_behavior do
445
+ describe :async_watch, :async => true do
446
+ it_should_behave_like "all success return values"
447
+
448
+ before do
449
+ @watcher = Zookeeper::Callbacks::WatcherCallback.new
450
+ @cb = Zookeeper::Callbacks::StringsCallback.new
451
+
452
+ @rv = zk.get_children(:path => path, :watcher => @watcher, :watcher_context => path, :callback => @cb, :callback_context => path)
453
+ wait_until { @cb.completed? }
454
+ @cb.should be_completed
455
+ end
456
+
457
+ it %[should fire the watcher when the node has been deleted] do
458
+ @watcher.should_not be_completed
459
+
460
+ zk.delete(:path => path)[:rc].should == Zookeeper::ZOK
461
+
462
+ wait_until { @watcher.completed? }
463
+ @watcher.should be_completed
464
+
465
+ @watcher.path.should == path
466
+ @watcher.context.should == path
467
+ @watcher.type.should == Zookeeper::ZOO_DELETED_EVENT
468
+ end
469
+ end
470
+ end
471
+
472
+
473
+ # NOTE: the jruby version of stat on non-existent node will have a
474
+ # return_code of 0, but the C version will have a return_code of -101
475
+ describe :stat do
476
+ describe :sync, :sync => true do
477
+ it_should_behave_like "all success return values"
478
+
479
+ before do
480
+ @rv = zk.stat(:path => path)
481
+ end
482
+
483
+ it %[should have a stat object] do
484
+ @rv[:stat].should be_kind_of(Zookeeper::Stat)
485
+ end
486
+ end
487
+
488
+ describe :sync_watch, :sync => true do
489
+ it_should_behave_like "all success return values"
490
+
491
+ before do
492
+ @watcher = Zookeeper::Callbacks::WatcherCallback.new
493
+
494
+ @rv = zk.stat(:path => path, :watcher => @watcher, :watcher_context => path)
495
+ end
496
+
497
+ it %[should have a stat object] do
498
+ @rv[:stat].should be_kind_of(Zookeeper::Stat)
499
+ end
500
+
501
+ it %[should set a watcher for data changes on the node] do
502
+ @watcher.should_not be_completed
503
+
504
+ zk.set(:path => path, :data => 'skunk')[:rc].should == Zookeeper::ZOK
505
+
506
+ wait_until { @watcher.completed? }
507
+ @watcher.should be_completed
508
+
509
+ @watcher.path.should == path
510
+ @watcher.context.should == path
511
+ @watcher.type.should == Zookeeper::ZOO_CHANGED_EVENT
512
+ end
513
+ end
514
+
515
+ describe :async, :async => true do
516
+ it_should_behave_like "all success return values"
517
+
518
+ before do
519
+ @cb = Zookeeper::Callbacks::StatCallback.new
520
+ @rv = zk.stat(:path => path, :callback => @cb, :callback_context => path)
521
+
522
+ wait_until { @cb.completed? }
523
+ @cb.should be_completed
524
+ end
525
+
526
+ it %[should succeed] do
527
+ @cb.return_code.should == Zookeeper::ZOK
528
+ end
529
+
530
+ it %[should have a stat object] do
531
+ @cb.stat.should be_kind_of(Zookeeper::Stat)
532
+ end
533
+ end
534
+
535
+ describe :async_watch, :async => true do
536
+ it_should_behave_like "all success return values"
537
+
538
+ before do
539
+ @addtl_child = 'child3'
540
+
541
+ @watcher = Zookeeper::Callbacks::WatcherCallback.new
542
+
543
+ @cb = Zookeeper::Callbacks::StatCallback.new
544
+ @rv = zk.stat(:path => path, :callback => @cb, :callback_context => path, :watcher => @watcher, :watcher_context => path)
545
+
546
+ wait_until { @cb.completed? }
547
+ @cb.should be_completed
548
+ end
549
+
550
+ after do
551
+ zk.delete(:path => "#{path}/#{@addtl_child}")
552
+ end
553
+
554
+ it %[should succeed] do
555
+ @cb.return_code.should == Zookeeper::ZOK
556
+ end
557
+
558
+ it %[should have a stat object] do
559
+ @cb.stat.should be_kind_of(Zookeeper::Stat)
560
+ end
561
+
562
+ it %[should set a watcher for data changes on the node] do
563
+ @watcher.should_not be_completed
564
+
565
+ zk.set(:path => path, :data => 'skunk')[:rc].should == Zookeeper::ZOK
566
+
567
+ wait_until { @watcher.completed? }
568
+ @watcher.should be_completed
569
+
570
+ @watcher.path.should == path
571
+ @watcher.context.should == path
572
+ @watcher.type.should == Zookeeper::ZOO_CHANGED_EVENT
573
+ end
574
+ end
575
+ end # stat
576
+
577
+ describe :create do
578
+ before do
579
+ # remove the path set up by the global 'before' block
580
+ zk.delete(:path => path)
581
+ end
582
+
583
+ describe :sync, :sync => true do
584
+ describe 'error' do
585
+ it %[should barf if the data size is too large], :input_size => true do
586
+ large_data = '0' * (1024 ** 2)
587
+
588
+ lambda { zk.create(:path => path, :data => large_data) }.should raise_error(Zookeeper::Exceptions::DataTooLargeException)
589
+ end
590
+ end
591
+
592
+ describe :default_flags do
593
+ it_should_behave_like "all success return values"
594
+
595
+ before do
596
+ @rv = zk.create(:path => path)
597
+ end
598
+
599
+ it %[should return the path that was set] do
600
+ @rv[:path].should == path
601
+ end
602
+
603
+ it %[should have created a permanent node] do
604
+ st = zk.stat(:path => path)
605
+ st[:rc].should == Zookeeper::ZOK
606
+
607
+ st[:stat].ephemeral_owner.should == 0
608
+ end
609
+ end
610
+
611
+ describe :ephemeral do
612
+ it_should_behave_like "all success return values"
613
+
614
+ before do
615
+ @rv = zk.create(:path => path, :ephemeral => true)
616
+ end
617
+
618
+ it %[should return the path that was set] do
619
+ @rv[:path].should == path
620
+ end
621
+
622
+ it %[should have created a ephemeral node] do
623
+ st = zk.stat(:path => path)
624
+ st[:rc].should == Zookeeper::ZOK
625
+
626
+ st[:stat].ephemeral_owner.should_not be_zero
627
+ end
628
+ end
629
+
630
+ describe :sequence do
631
+ it_should_behave_like "all success return values"
632
+
633
+ before do
634
+ @orig_path = path
635
+ @rv = zk.create(:path => path, :sequence => true)
636
+ @s_path = @rv[:path] # make sure this gets cleaned up
637
+ end
638
+
639
+ after do
640
+ zk.delete(:path => @s_path)
641
+ end
642
+
643
+ it %[should return the path that was set] do
644
+ @rv[:path].should_not == @orig_path
645
+ end
646
+
647
+ it %[should have created a permanent node] do
648
+ st = zk.stat(:path => @s_path)
649
+ st[:rc].should == Zookeeper::ZOK
650
+
651
+ st[:stat].ephemeral_owner.should be_zero
652
+ end
653
+ end
654
+
655
+ describe :ephemeral_sequence do
656
+ it_should_behave_like "all success return values"
657
+
658
+ before do
659
+ @orig_path = path
660
+ @rv = zk.create(:path => path, :sequence => true, :ephemeral => true)
661
+ @s_path = @rv[:path] # make sure this gets cleaned up
662
+ end
663
+
664
+ after do
665
+ zk.delete(:path => @s_path)
666
+ end
667
+
668
+ it %[should return the path that was set] do
669
+ @rv[:path].should_not == @orig_path
670
+ end
671
+
672
+ it %[should have created an ephemeral node] do
673
+ st = zk.stat(:path => @s_path)
674
+ st[:rc].should == Zookeeper::ZOK
675
+
676
+ st[:stat].ephemeral_owner.should_not be_zero
677
+ end
678
+ end
679
+
680
+ describe :acl do
681
+ it %[should work] do
682
+ pending "need to write acl tests"
683
+ end
684
+ end
685
+ end
686
+
687
+ describe :async, :async => true do
688
+ before do
689
+ @cb = Zookeeper::Callbacks::StringCallback.new
690
+ end
691
+
692
+ describe :default_flags do
693
+ it_should_behave_like "all success return values"
694
+
695
+ before do
696
+ @rv = zk.create(:path => path, :callback => @cb, :callback_context => path)
697
+ wait_until(2) { @cb.completed? }
698
+ @cb.should be_completed
699
+ end
700
+
701
+ it %[should have a path] do
702
+ @cb.path.should_not be_nil
703
+ end
704
+
705
+ it %[should return the path that was set] do
706
+ @cb.path.should == path
707
+ end
708
+
709
+ it %[should have created a permanent node] do
710
+ st = zk.stat(:path => path)
711
+ st[:rc].should == Zookeeper::ZOK
712
+
713
+ st[:stat].ephemeral_owner.should == 0
714
+ end
715
+ end
716
+
717
+ describe 'error' do
718
+ it %[should barf if the data size is too large], :input_size => true do
719
+ large_data = '0' * (1024 ** 2)
720
+
721
+ lambda do
722
+ zk.create(:path => path, :data => large_data, :callback => @cb, :callback_context => path)
723
+ end.should raise_error(Zookeeper::Exceptions::DataTooLargeException)
724
+ end
725
+ end
726
+
727
+
728
+ describe :ephemeral do
729
+ it_should_behave_like "all success return values"
730
+
731
+ before do
732
+ @rv = zk.create(:path => path, :ephemeral => true, :callback => @cb, :callback_context => path)
733
+ wait_until(2) { @cb.completed? }
734
+ @cb.should be_completed
735
+ end
736
+
737
+ it %[should have a path] do
738
+ @cb.path.should_not be_nil
739
+ end
740
+
741
+ it %[should return the path that was set] do
742
+ @cb.path.should == path
743
+ end
744
+
745
+ it %[should have created a ephemeral node] do
746
+ st = zk.stat(:path => path)
747
+ st[:rc].should == Zookeeper::ZOK
748
+
749
+ st[:stat].ephemeral_owner.should_not be_zero
750
+ end
751
+ end
752
+
753
+ describe :sequence do
754
+ it_should_behave_like "all success return values"
755
+
756
+ before do
757
+ @orig_path = path
758
+ @rv = zk.create(:path => path, :sequence => true, :callback => @cb, :callback_context => path)
759
+
760
+ wait_until(2) { @cb.completed? }
761
+ @cb.should be_completed
762
+
763
+ @s_path = @cb.path
764
+ end
765
+
766
+ after do
767
+ zk.delete(:path => @s_path)
768
+ end
769
+
770
+ it %[should have a path] do
771
+ @cb.path.should_not be_nil
772
+ end
773
+
774
+ it %[should return the path that was set] do
775
+ @cb.path.should_not == @orig_path
776
+ end
777
+
778
+ it %[should have created a permanent node] do
779
+ st = zk.stat(:path => @s_path)
780
+ st[:rc].should == Zookeeper::ZOK
781
+
782
+ st[:stat].ephemeral_owner.should be_zero
783
+ end
784
+ end
785
+
786
+ describe :ephemeral_sequence do
787
+ it_should_behave_like "all success return values"
788
+
789
+ before do
790
+ @orig_path = path
791
+ @rv = zk.create(:path => path, :sequence => true, :ephemeral => true, :callback => @cb, :callback_context => path)
792
+ path = @rv[:path] # make sure this gets cleaned up
793
+
794
+ wait_until(2) { @cb.completed? }
795
+ @cb.should be_completed
796
+ @s_path = @cb.path
797
+ end
798
+
799
+ after do
800
+ zk.delete(:path => @s_path)
801
+ end
802
+
803
+ it %[should have a path] do
804
+ @cb.path.should_not be_nil
805
+ end
806
+
807
+ it %[should return the path that was set] do
808
+ @s_path.should_not == @orig_path
809
+ end
810
+
811
+ it %[should have created an ephemeral node] do
812
+ st = zk.stat(:path => @s_path)
813
+ st[:rc].should == Zookeeper::ZOK
814
+
815
+ st[:stat].ephemeral_owner.should_not be_zero
816
+ end
817
+ end # ephemeral_sequence
818
+ end # async
819
+ end # create
820
+
821
+ describe :delete do
822
+ describe :sync, :sync => true do
823
+ describe 'without version' do
824
+ it_should_behave_like "all success return values"
825
+
826
+ before do
827
+ zk.create(:path => path)
828
+ @rv = zk.delete(:path => path)
829
+ end
830
+
831
+ it %[should have deleted the node] do
832
+ zk.stat(:path => path)[:stat].exists.should be_false
833
+ end
834
+ end
835
+
836
+ describe 'with current version' do
837
+ it_should_behave_like "all success return values"
838
+
839
+ before do
840
+ zk.create(:path => path)
841
+
842
+ @stat = zk.stat(:path => path)[:stat]
843
+ @stat.exists.should be_true
844
+
845
+ @rv = zk.delete(:path => path, :version => @stat.version)
846
+ end
847
+
848
+ it %[should have deleted the node] do
849
+ zk.stat(:path => path)[:stat].exists.should be_false
850
+ end
851
+ end
852
+
853
+ describe 'with old version' do
854
+ before do
855
+ 3.times { |n| @stat = zk.set(:path => path, :data => n.to_s)[:stat] }
856
+
857
+ @rv = zk.delete(:path => path, :version => 0)
858
+ end
859
+
860
+ it %[should have a return code of ZBADVERSION] do
861
+ @rv[:rc].should == Zookeeper::ZBADVERSION
862
+ end
863
+ end
864
+ end # sync
865
+
866
+ describe :async, :async => true do
867
+ before do
868
+ @cb = Zookeeper::Callbacks::VoidCallback.new
869
+ end
870
+
871
+ describe 'without version' do
872
+ it_should_behave_like "all success return values"
873
+
874
+ before do
875
+ @rv = zk.delete(:path => path, :callback => @cb, :callback_context => path)
876
+ wait_until { @cb.completed? }
877
+ @cb.should be_completed
878
+ end
879
+
880
+ it %[should have a success return_code] do
881
+ @cb.return_code.should == Zookeeper::ZOK
882
+ end
883
+
884
+ it %[should have deleted the node] do
885
+ zk.stat(:path => path)[:stat].exists.should be_false
886
+ end
887
+ end
888
+
889
+ describe 'with current version' do
890
+ it_should_behave_like "all success return values"
891
+
892
+ before do
893
+ @stat = zk.stat(:path => path)[:stat]
894
+ @rv = zk.delete(:path => path, :version => @stat.version, :callback => @cb, :callback_context => path)
895
+ wait_until { @cb.completed? }
896
+ @cb.should be_completed
897
+ end
898
+
899
+ it %[should have a success return_code] do
900
+ @cb.return_code.should == Zookeeper::ZOK
901
+ end
902
+
903
+ it %[should have deleted the node] do
904
+ zk.stat(:path => path)[:stat].exists.should be_false
905
+ end
906
+ end
907
+
908
+ describe 'with old version' do
909
+ before do
910
+ 3.times { |n| @stat = zk.set(:path => path, :data => n.to_s)[:stat] }
911
+
912
+ @rv = zk.delete(:path => path, :version => 0, :callback => @cb, :callback_context => path)
913
+ wait_until { @cb.completed? }
914
+ @cb.should be_completed
915
+ end
916
+
917
+ it %[should have a return code of ZBADVERSION] do
918
+ @cb.return_code.should == Zookeeper::ZBADVERSION
919
+ end
920
+ end
921
+ end # async
922
+ end # delete
923
+
924
+ describe :get_acl do
925
+ describe :sync, :sync => true do
926
+ it_should_behave_like "all success return values"
927
+
928
+ before do
929
+ @rv = zk.get_acl(:path => path)
930
+ end
931
+
932
+ it %[should return a stat for the path] do
933
+ @rv[:stat].should be_kind_of(Zookeeper::Stat)
934
+ end
935
+
936
+ it %[should return the acls] do
937
+ acls = @rv[:acl]
938
+ acls.should be_kind_of(Array)
939
+ h = acls.first
940
+
941
+ h.should be_kind_of(Hash)
942
+
943
+ h[:perms].should == Zookeeper::ZOO_PERM_ALL
944
+ h[:id][:scheme].should == 'world'
945
+ h[:id][:id].should == 'anyone'
946
+ end
947
+ end
948
+
949
+ describe :async, :async => true do
950
+ it_should_behave_like "all success return values"
951
+
952
+ before do
953
+ @cb = Zookeeper::Callbacks::ACLCallback.new
954
+ @rv = zk.get_acl(:path => path, :callback => @cb, :callback_context => path)
955
+
956
+ wait_until(2) { @cb.completed? }
957
+ @cb.should be_completed
958
+ end
959
+
960
+ it %[should return a stat for the path] do
961
+ @cb.stat.should be_kind_of(Zookeeper::Stat)
962
+ end
963
+
964
+ it %[should return the acls] do
965
+ acls = @cb.acl
966
+ acls.should be_kind_of(Array)
967
+
968
+ acl = acls.first
969
+ acl.should be_kind_of(Zookeeper::ACLs::ACL)
970
+
971
+ acl.perms.should == Zookeeper::ZOO_PERM_ALL
972
+
973
+ acl.id.scheme.should == 'world'
974
+ acl.id.id.should == 'anyone'
975
+ end
976
+ end
977
+ end
978
+
979
+ describe :set_acl do
980
+ before do
981
+ @perms = 5
982
+ @new_acl = [Zookeeper::ACLs::ACL.new(:perms => @perms, :id => Zookeeper::Constants::ZOO_ANYONE_ID_UNSAFE)]
983
+ pending("No idea how to set ACLs")
984
+ end
985
+
986
+ describe :sync, :sync => true do
987
+ it_should_behave_like "all success return values"
988
+
989
+ before do
990
+ @rv = zk.set_acl(:path => path, :acl => @new_acl)
991
+ end
992
+ end
993
+ end
994
+
995
+ describe :session_id do
996
+ it %[should return the session_id as a Fixnum] do
997
+ zk.session_id.should be_kind_of(Integer)
998
+ end
999
+ end
1000
+
1001
+ describe :session_passwd do
1002
+ it %[should return the session passwd as a String] do
1003
+ zk.session_passwd.should be_kind_of(String)
1004
+ end
1005
+ end
1006
+
1007
+ describe :sync, :sync => true do
1008
+ describe :success do
1009
+ it_should_behave_like "all success return values"
1010
+
1011
+ before do
1012
+ @cb = Zookeeper::Callbacks::StringCallback.new
1013
+ @rv = zk.sync(:path => path, :callback => @cb)
1014
+
1015
+ wait_until(2) { @cb.completed }
1016
+ @cb.should be_completed
1017
+ end
1018
+ end
1019
+
1020
+ describe :errors do
1021
+ it %[should barf with BadArguments if :callback is not given] do
1022
+ lambda { zk.sync(:path => path) }.should raise_error(Zookeeper::Exceptions::BadArguments)
1023
+ end
1024
+ end
1025
+ end
1026
+
1027
+ describe :event_dispatch_thread? do
1028
+ it %[should return true when called on the event dispatching thread] do
1029
+ @result = nil
1030
+
1031
+ cb = lambda do |hash|
1032
+ @result = zk.event_dispatch_thread?
1033
+ end
1034
+
1035
+ @rv = zk.sync(:path => path, :callback => cb)
1036
+
1037
+ wait_until(2) { @result == true }.should be_true
1038
+ end
1039
+
1040
+ it %[should return false when not on the event dispatching thread] do
1041
+ zk.event_dispatch_thread?.should_not be_true
1042
+ end
1043
+ end
1044
+
1045
+ describe :close do
1046
+ describe 'from the event dispatch thread' do
1047
+ it %[should not deadlock] do
1048
+
1049
+ evil_cb = lambda do |*|
1050
+ logger.debug { "calling close event_dispatch_thread? #{zk.event_dispatch_thread?}" }
1051
+ zk.close
1052
+ end
1053
+
1054
+ zk.stat(:path => path, :callback => evil_cb)
1055
+
1056
+ wait_until { zk.closed? }
1057
+ zk.should be_closed
1058
+ end
1059
+ end
1060
+ end
1061
+
1062
+ unless defined?(::JRUBY_VERSION)
1063
+ describe 'fork protection' do
1064
+ it %[should raise an InheritedConnectionError if the current Process.pid is different from the one that created the client] do
1065
+ pid = Process.pid
1066
+ begin
1067
+ Process.stub(:pid => -1)
1068
+ lambda { zk.stat(:path => path) }.should raise_error(Zookeeper::Exceptions::InheritedConnectionError)
1069
+ ensure
1070
+ # ensure we reset this, only want it to fail during the test
1071
+ Process.stub(:pid => pid)
1072
+ end
1073
+ end
1074
+ end
1075
+ end
1076
+ end
1077
+