zookeeper-ng 1.5.2.1-java

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.
Files changed (86) 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/.github/workflows/build.yml +57 -0
  7. data/.gitignore +19 -0
  8. data/.gitmodules +3 -0
  9. data/CHANGELOG +408 -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 +62 -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-buffer-overflow.patch +11 -0
  29. data/ext/patches/zkc-3.4.5-config.patch +5454 -0
  30. data/ext/patches/zkc-3.4.5-fetch-and-add.patch +16 -0
  31. data/ext/patches/zkc-3.4.5-logging.patch +41 -0
  32. data/ext/patches/zkc-3.4.5-out-of-order-ping.patch +163 -0
  33. data/ext/patches/zkc-3.4.5-yosemite-htonl-fix.patch +102 -0
  34. data/ext/zkc-3.4.5.tar.gz +0 -0
  35. data/ext/zkrb.c +1080 -0
  36. data/ext/zkrb_wrapper.c +775 -0
  37. data/ext/zkrb_wrapper.h +350 -0
  38. data/ext/zkrb_wrapper_compat.c +15 -0
  39. data/ext/zkrb_wrapper_compat.h +11 -0
  40. data/ext/zookeeper_base.rb +256 -0
  41. data/java/java_base.rb +501 -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/queue_with_pipe.rb +110 -0
  47. data/lib/zookeeper/common.rb +122 -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/forwarding_logger.rb +84 -0
  57. data/lib/zookeeper/logger.rb +39 -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/lib/zookeeper.rb +115 -0
  64. data/notes.txt +14 -0
  65. data/scripts/upgrade-1.0-sed-alike.rb +46 -0
  66. data/spec/c_zookeeper_spec.rb +51 -0
  67. data/spec/chrooted_connection_spec.rb +83 -0
  68. data/spec/compatibilty_spec.rb +8 -0
  69. data/spec/default_watcher_spec.rb +41 -0
  70. data/spec/em_spec.rb +51 -0
  71. data/spec/ext/zookeeper_base_spec.rb +19 -0
  72. data/spec/forked_connection_spec.rb +122 -0
  73. data/spec/latch_spec.rb +24 -0
  74. data/spec/log4j.properties +17 -0
  75. data/spec/shared/all_success_return_values.rb +10 -0
  76. data/spec/shared/connection_examples.rb +1081 -0
  77. data/spec/spec_helper.rb +61 -0
  78. data/spec/support/00_logging.rb +38 -0
  79. data/spec/support/10_spawn_zookeeper.rb +20 -0
  80. data/spec/support/progress_formatter.rb +15 -0
  81. data/spec/support/zookeeper_spec_helpers.rb +96 -0
  82. data/spec/zookeeper_spec.rb +24 -0
  83. data/zookeeper.gemspec +46 -0
  84. data/zoomonkey/duplicates +3 -0
  85. data/zoomonkey/zoomonkey.rb +194 -0
  86. metadata +185 -0
@@ -0,0 +1,1081 @@
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
+ begin
1055
+ zk.stat(:path => path, :callback => evil_cb)
1056
+ rescue IOError
1057
+ # captures flaky IOError: stream closed in another thread
1058
+ end
1059
+
1060
+ wait_until { zk.closed? }
1061
+ zk.should be_closed
1062
+ end
1063
+ end
1064
+ end
1065
+
1066
+ unless defined?(::JRUBY_VERSION)
1067
+ describe 'fork protection' do
1068
+ it %[should raise an InheritedConnectionError if the current Process.pid is different from the one that created the client] do
1069
+ pid = Process.pid
1070
+ begin
1071
+ Process.stub(:pid => -1)
1072
+ lambda { zk.stat(:path => path) }.should raise_error(Zookeeper::Exceptions::InheritedConnectionError)
1073
+ ensure
1074
+ # ensure we reset this, only want it to fail during the test
1075
+ Process.stub(:pid => pid)
1076
+ end
1077
+ end
1078
+ end
1079
+ end
1080
+ end
1081
+