slyphon-zookeeper 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/CHANGELOG +23 -0
- data/LICENSE +23 -0
- data/Manifest +33 -0
- data/README +42 -0
- data/Rakefile +19 -0
- data/examples/cloud_config.rb +125 -0
- data/ext/.gitignore +5 -0
- data/ext/extconf.rb +56 -0
- data/ext/zkc-3.3.2.tar.gz +0 -0
- data/ext/zookeeper_base.rb +117 -0
- data/ext/zookeeper_c.c +571 -0
- data/ext/zookeeper_lib.c +604 -0
- data/ext/zookeeper_lib.h +165 -0
- data/java/zookeeper_base.rb +426 -0
- data/lib/zookeeper.rb +180 -0
- data/lib/zookeeper/acls.rb +40 -0
- data/lib/zookeeper/callbacks.rb +89 -0
- data/lib/zookeeper/common.rb +97 -0
- data/lib/zookeeper/constants.rb +54 -0
- data/lib/zookeeper/exceptions.rb +92 -0
- data/lib/zookeeper/stat.rb +17 -0
- data/notes.txt +14 -0
- data/slyphon-zookeeper.gemspec +31 -0
- data/spec/default_watcher_spec.rb +41 -0
- data/spec/log4j.properties +17 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/zookeeper_spec.rb +924 -0
- data/test/test_basic.rb +37 -0
- data/test/test_callback1.rb +36 -0
- data/test/test_close.rb +16 -0
- data/test/test_esoteric.rb +7 -0
- data/test/test_watcher1.rb +56 -0
- data/test/test_watcher2.rb +52 -0
- metadata +146 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
module ZookeeperExceptions
|
2
|
+
# exceptions/errors
|
3
|
+
ZOK = 0
|
4
|
+
ZSYSTEMERROR = -1
|
5
|
+
ZRUNTIMEINCONSISTENCY = -2
|
6
|
+
ZDATAINCONSISTENCY = -3
|
7
|
+
ZCONNECTIONLOSS = -4
|
8
|
+
ZMARSHALLINGERROR = -5
|
9
|
+
ZUNIMPLEMENTED = -6
|
10
|
+
ZOPERATIONTIMEOUT = -7
|
11
|
+
ZBADARGUMENTS = -8
|
12
|
+
ZINVALIDSTATE = -9
|
13
|
+
|
14
|
+
# api errors
|
15
|
+
ZAPIERROR = -100
|
16
|
+
ZNONODE = -101
|
17
|
+
ZNOAUTH = -102
|
18
|
+
ZBADVERSION = -103
|
19
|
+
ZNOCHILDRENFOREPHEMERALS = -108
|
20
|
+
ZNODEEXISTS = -110
|
21
|
+
ZNOTEMPTY = -111
|
22
|
+
ZSESSIONEXPIRED = -112
|
23
|
+
ZINVALIDCALLBACK = -113
|
24
|
+
ZINVALIDACL = -114
|
25
|
+
ZAUTHFAILED = -115
|
26
|
+
ZCLOSING = -116
|
27
|
+
ZNOTHING = -117
|
28
|
+
ZSESSIONMOVED = -118
|
29
|
+
|
30
|
+
class ZookeeperException < Exception
|
31
|
+
class EverythingOk < ZookeeperException; end
|
32
|
+
class SystemError < ZookeeperException; end
|
33
|
+
class RunTimeInconsistency < ZookeeperException; end
|
34
|
+
class DataInconsistency < ZookeeperException; end
|
35
|
+
class ConnectionLoss < ZookeeperException; end
|
36
|
+
class MarshallingError < ZookeeperException; end
|
37
|
+
class Unimplemented < ZookeeperException; end
|
38
|
+
class OperationTimeOut < ZookeeperException; end
|
39
|
+
class BadArguments < ZookeeperException; end
|
40
|
+
class InvalidState < ZookeeperException; end
|
41
|
+
class ApiError < ZookeeperException; end
|
42
|
+
class NoNode < ZookeeperException; end
|
43
|
+
class NoAuth < ZookeeperException; end
|
44
|
+
class BadVersion < ZookeeperException; end
|
45
|
+
class NoChildrenForEphemerals < ZookeeperException; end
|
46
|
+
class NodeExists < ZookeeperException; end
|
47
|
+
class NotEmpty < ZookeeperException; end
|
48
|
+
class SessionExpired < ZookeeperException; end
|
49
|
+
class InvalidCallback < ZookeeperException; end
|
50
|
+
class InvalidACL < ZookeeperException; end
|
51
|
+
class AuthFailed < ZookeeperException; end
|
52
|
+
class Closing < ZookeeperException; end
|
53
|
+
class Nothing < ZookeeperException; end
|
54
|
+
class SessionMoved < ZookeeperException; end
|
55
|
+
class ConnectionClosed < ZookeeperException; end # this is a Ruby client exception
|
56
|
+
|
57
|
+
def self.by_code(code)
|
58
|
+
case code
|
59
|
+
when ZOK then EverythingOk
|
60
|
+
when ZSYSTEMERROR then SystemError
|
61
|
+
when ZRUNTIMEINCONSISTENCY then RunTimeInconsistency
|
62
|
+
when ZDATAINCONSISTENCY then DataInconsistency
|
63
|
+
when ZCONNECTIONLOSS then ConnectionLoss
|
64
|
+
when ZMARSHALLINGERROR then MarshallingError
|
65
|
+
when ZUNIMPLEMENTED then Unimplemented
|
66
|
+
when ZOPERATIONTIMEOUT then OperationTimeOut
|
67
|
+
when ZBADARGUMENTS then BadArguments
|
68
|
+
when ZINVALIDSTATE then InvalidState
|
69
|
+
when ZAPIERROR then ApiError
|
70
|
+
when ZNONODE then NoNode
|
71
|
+
when ZNOAUTH then NoAuth
|
72
|
+
when ZBADVERSION then BadVersion
|
73
|
+
when ZNOCHILDRENFOREPHEMERALS then NoChildrenForEphemerals
|
74
|
+
when ZNODEEXISTS then NodeExists
|
75
|
+
when ZNOTEMPTY then NotEmpty
|
76
|
+
when ZSESSIONEXPIRED then SessionExpired
|
77
|
+
when ZINVALIDCALLBACK then InvalidCallback
|
78
|
+
when ZINVALIDACL then InvalidACL
|
79
|
+
when ZAUTHFAILED then AuthFailed
|
80
|
+
when ZCLOSING then Closing
|
81
|
+
when ZNOTHING then Nothing
|
82
|
+
when ZSESSIONMOVED then SessionMoved
|
83
|
+
else Exception.new("no exception defined for code #{code}")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.raise_on_error(code)
|
88
|
+
exc = self.by_code(code)
|
89
|
+
raise exc unless exc == EverythingOk
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ZookeeperStat
|
2
|
+
class Stat
|
3
|
+
attr_reader :version, :exists, :czxid, :mzxid, :ctime, :mtime, :cversion, :aversion, :ephemeralOwner, :dataLength, :numChildren, :pzxid
|
4
|
+
|
5
|
+
alias :ephemeral_owner :ephemeralOwner
|
6
|
+
alias :num_children :numChildren
|
7
|
+
alias :data_length :dataLength
|
8
|
+
|
9
|
+
def initialize(val)
|
10
|
+
@exists = !!val
|
11
|
+
@czxid, @mzxid, @ctime, @mtime, @version, @cversion, @aversion,
|
12
|
+
@ephemeralOwner, @dataLength, @numChildren, @pzxid = val if val.is_a?(Array)
|
13
|
+
val.each { |k,v| instance_variable_set "@#{k}", v } if val.is_a?(Hash)
|
14
|
+
raise ArgumentError unless (val.is_a?(Hash) or val.is_a?(Array) or val == nil)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/notes.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Notes on this fork of http://github.com/twitter/zookeeper
|
2
|
+
|
3
|
+
The main purpose of this fork is to provide JRuby compatibility with the MRI driver of the original. We have been using an early fork with an incomplete binding to the C client, and had recently bumped up against a fairly serious bug with handling events. The twitter/zookeeper driver solved this problem but was lacking JRuby support (which is a core piece of our environment).
|
4
|
+
|
5
|
+
I've packaged the Java client (and its dependency on log4j) as gems that are installed separately from this codebase to cut down on the size of the zookeeper gem. If this poses a problem (for instance, if the original goal was to have an all-in-one install with no external dependencies), it would be trivial to package those jars along with this code.
|
6
|
+
|
7
|
+
In the course of writing the wrapper for JRuby, I've written nearly-complete specs for all of the public API methods: get, set, get_children, stat, create, delete, get_acl, and set_acl. The reason I say they're "nearly" complete is that I have no use for set_acl, and quite honestly, couldn't figure out how to make it work.
|
8
|
+
|
9
|
+
I'm planning on writing a companion gem, 'ZK', that would take some of the higher-level constructs that we'd written around the lower-level driver to implement features like locking and queues, and also to provide a more ruby-like interface.
|
10
|
+
|
11
|
+
I'd like to reorganize this codebase in a number of ways, most of all to move all of the various classes and modules under a common "Zookeeper" namespace, however I thought that would be a radical enough change where I'd want to discuss/coordinate with you on how exactly to do it.
|
12
|
+
|
13
|
+
|
14
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "slyphon-zookeeper"
|
6
|
+
s.version = '0.1.0'
|
7
|
+
|
8
|
+
s.authors = ["Phillip Pearson", "Eric Maland", "Evan Weaver", "Brian Wickman", "Jonathan D. Simms"]
|
9
|
+
s.email = ["slyphon@gmail.com"]
|
10
|
+
s.summary = %q{twitter's zookeeper client}
|
11
|
+
s.description = s.summary
|
12
|
+
|
13
|
+
s.add_development_dependency "rspec", ">= 2.0.0"
|
14
|
+
s.add_development_dependency 'flexmock', '~> 0.8.11'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
if ENV['JAVA_GEM']
|
20
|
+
s.platform = 'java'
|
21
|
+
s.add_runtime_dependency('slyphon-log4j', '= 1.2.15')
|
22
|
+
s.add_runtime_dependency('slyphon-zookeeper_jar', '= 3.3.1')
|
23
|
+
s.require_paths += %w[java]
|
24
|
+
else
|
25
|
+
s.require_paths += %w[ext]
|
26
|
+
s.extensions = 'ext/extconf.rb'
|
27
|
+
end
|
28
|
+
|
29
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
30
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Zookeeper do
|
4
|
+
describe :initialize, 'with watcher block' do
|
5
|
+
before do
|
6
|
+
@events = []
|
7
|
+
@watch_block = lambda do |hash|
|
8
|
+
$stderr.puts "watch_block: #{hash.inspect}"
|
9
|
+
@events << hash
|
10
|
+
end
|
11
|
+
|
12
|
+
@zk = Zookeeper.new('localhost:2181', 10, @watch_block)
|
13
|
+
|
14
|
+
wait_until(2) { @zk.connected? }
|
15
|
+
@zk.should be_connected
|
16
|
+
$stderr.puts "connected!"
|
17
|
+
|
18
|
+
wait_until(2) { !@events.empty? }
|
19
|
+
$stderr.puts "got events!"
|
20
|
+
end
|
21
|
+
|
22
|
+
after do
|
23
|
+
@zk.close if @zk.connected?
|
24
|
+
end
|
25
|
+
|
26
|
+
it %[should receive initial connection state events] do
|
27
|
+
@events.should_not be_empty
|
28
|
+
@events.length.should == 1
|
29
|
+
@events.first[:state].should == Zookeeper::ZOO_CONNECTED_STATE
|
30
|
+
end
|
31
|
+
|
32
|
+
it %[should receive disconnection events] do
|
33
|
+
pending "the C driver doesn't appear to deliver disconnection events (?)"
|
34
|
+
@events.clear
|
35
|
+
@zk.close
|
36
|
+
wait_until(2) { !@events.empty? }
|
37
|
+
@events.should_not be_empty
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -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
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.expand_path('../../ext', __FILE__))
|
3
|
+
$LOAD_PATH.uniq!
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
|
7
|
+
gem 'flexmock', '~> 0.8.11'
|
8
|
+
|
9
|
+
require 'flexmock'
|
10
|
+
require 'zookeeper'
|
11
|
+
|
12
|
+
Zookeeper.logger = Logger.new(File.expand_path('../../test.log', __FILE__)).tap do |log|
|
13
|
+
log.level = Logger::DEBUG
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.mock_with :flexmock
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
# method to wait until block passed returns true or timeout (default is 10 seconds) is reached
|
23
|
+
def wait_until(timeout=10, &block)
|
24
|
+
time_to_stop = Time.now + timeout
|
25
|
+
until yield do
|
26
|
+
break if Time.now > time_to_stop
|
27
|
+
sleep 0.3
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
@@ -0,0 +1,924 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
shared_examples_for "all success return values" do
|
4
|
+
it %[should have a return code of Zookeeper::ZOK] do
|
5
|
+
@rv[:rc].should == Zookeeper::ZOK
|
6
|
+
end
|
7
|
+
|
8
|
+
it %[should have a req_id integer] do
|
9
|
+
@rv[:req_id].should be_kind_of(Integer)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Zookeeper do
|
14
|
+
before do
|
15
|
+
@path = "/_zktest_"
|
16
|
+
@data = "underpants"
|
17
|
+
|
18
|
+
@zk = Zookeeper.new('localhost:2181')
|
19
|
+
|
20
|
+
# uncomment for driver debugging output
|
21
|
+
#@zk.set_debug_level(Zookeeper::ZOO_LOG_LEVEL_DEBUG) unless defined?(::JRUBY_VERSION)
|
22
|
+
|
23
|
+
@zk.create(:path => @path, :data => @data)
|
24
|
+
end
|
25
|
+
|
26
|
+
after do
|
27
|
+
@zk.delete(:path => @path)
|
28
|
+
@zk.close
|
29
|
+
|
30
|
+
wait_until do
|
31
|
+
begin
|
32
|
+
!@zk.connected?
|
33
|
+
rescue RuntimeError
|
34
|
+
true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# unfortunately, we can't test w/o exercising other parts of the driver, so
|
40
|
+
# if "set" is broken, this test will fail as well (but whaddyagonnado?)
|
41
|
+
describe :get do
|
42
|
+
describe :sync do
|
43
|
+
it_should_behave_like "all success return values"
|
44
|
+
|
45
|
+
before do
|
46
|
+
@rv = @zk.get(:path => @path)
|
47
|
+
end
|
48
|
+
|
49
|
+
it %[should return the data] do
|
50
|
+
@rv[:data].should == @data
|
51
|
+
end
|
52
|
+
|
53
|
+
it %[should return a stat] do
|
54
|
+
@rv[:stat].should_not be_nil
|
55
|
+
@rv[:stat].should be_kind_of(ZookeeperStat::Stat)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe :sync_watch do
|
60
|
+
it_should_behave_like "all success return values"
|
61
|
+
|
62
|
+
before do
|
63
|
+
@event = nil
|
64
|
+
@watcher = Zookeeper::WatcherCallback.new
|
65
|
+
|
66
|
+
@rv = @zk.get(:path => @path, :watcher => @watcher, :watcher_context => @path)
|
67
|
+
end
|
68
|
+
|
69
|
+
it %[should return the data] do
|
70
|
+
@rv[:data].should == @data
|
71
|
+
end
|
72
|
+
|
73
|
+
it %[should set a watcher on the node] do
|
74
|
+
# test the watcher by changing node data
|
75
|
+
@zk.set(:path => @path, :data => 'blah')[:rc].should be_zero
|
76
|
+
|
77
|
+
wait_until(1.0) { @watcher.completed? }
|
78
|
+
|
79
|
+
@watcher.path.should == @path
|
80
|
+
@watcher.context.should == @path
|
81
|
+
@watcher.should be_completed
|
82
|
+
@watcher.type.should == Zookeeper::ZOO_CHANGED_EVENT
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe :async do
|
87
|
+
it_should_behave_like "all success return values"
|
88
|
+
|
89
|
+
before do
|
90
|
+
@cb = Zookeeper::DataCallback.new
|
91
|
+
|
92
|
+
@rv = @zk.get(:path => @path, :callback => @cb, :callback_context => @path)
|
93
|
+
wait_until(1.0) { @cb.completed? }
|
94
|
+
@cb.should be_completed
|
95
|
+
end
|
96
|
+
|
97
|
+
it %[should have a return code of ZOK] do
|
98
|
+
@cb.return_code.should == Zookeeper::ZOK
|
99
|
+
end
|
100
|
+
|
101
|
+
it %[should have the stat object in the callback] do
|
102
|
+
@cb.stat.should_not be_nil
|
103
|
+
@cb.stat.should be_kind_of(ZookeeperStat::Stat)
|
104
|
+
end
|
105
|
+
|
106
|
+
it %[should have the data] do
|
107
|
+
@cb.data.should == @data
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe :async_watch do
|
112
|
+
it_should_behave_like "all success return values"
|
113
|
+
|
114
|
+
before do
|
115
|
+
@cb = Zookeeper::DataCallback.new
|
116
|
+
@watcher = Zookeeper::WatcherCallback.new
|
117
|
+
|
118
|
+
@rv = @zk.get(:path => @path, :callback => @cb, :callback_context => @path, :watcher => @watcher, :watcher_context => @path)
|
119
|
+
wait_until(1.0) { @cb.completed? }
|
120
|
+
@cb.should be_completed
|
121
|
+
end
|
122
|
+
|
123
|
+
it %[should have the stat object in the callback] do
|
124
|
+
@cb.stat.should_not be_nil
|
125
|
+
@cb.stat.should be_kind_of(ZookeeperStat::Stat)
|
126
|
+
end
|
127
|
+
|
128
|
+
it %[should have the data] do
|
129
|
+
@cb.data.should == @data
|
130
|
+
end
|
131
|
+
|
132
|
+
it %[should have a return code of ZOK] do
|
133
|
+
@cb.return_code.should == Zookeeper::ZOK
|
134
|
+
end
|
135
|
+
|
136
|
+
it %[should set a watcher on the node] do
|
137
|
+
@zk.set(:path => @path, :data => 'blah')[:rc].should be_zero
|
138
|
+
|
139
|
+
wait_until(2) { @watcher.completed? }
|
140
|
+
|
141
|
+
@watcher.should be_completed
|
142
|
+
|
143
|
+
@watcher.path.should == @path
|
144
|
+
@watcher.context.should == @path
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe 'bad arguments' do
|
149
|
+
it %[should barf with a BadArguments error] do
|
150
|
+
lambda { @zk.get(:bad_arg => 'what!?') }.should raise_error(ZookeeperExceptions::ZookeeperException::BadArguments)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end # get
|
154
|
+
|
155
|
+
describe :set do
|
156
|
+
before do
|
157
|
+
@new_data = "Four score and \007 years ago"
|
158
|
+
@stat = @zk.stat(:path => @path)[:stat]
|
159
|
+
end
|
160
|
+
|
161
|
+
describe :sync do
|
162
|
+
describe 'without version' do
|
163
|
+
it_should_behave_like "all success return values"
|
164
|
+
|
165
|
+
before do
|
166
|
+
@rv = @zk.set(:path => @path, :data => @new_data)
|
167
|
+
end
|
168
|
+
|
169
|
+
it %[should return the new stat] do
|
170
|
+
@rv[:stat].should_not be_nil
|
171
|
+
@rv[:stat].should be_kind_of(ZookeeperStat::Stat)
|
172
|
+
@rv[:stat].version.should > @stat.version
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'with current version' do
|
177
|
+
it_should_behave_like "all success return values"
|
178
|
+
|
179
|
+
before do
|
180
|
+
@rv = @zk.set(:path => @path, :data => @new_data, :version => @stat.version)
|
181
|
+
end
|
182
|
+
|
183
|
+
it %[should return the new stat] do
|
184
|
+
@rv[:stat].should_not be_nil
|
185
|
+
@rv[:stat].should be_kind_of(ZookeeperStat::Stat)
|
186
|
+
@rv[:stat].version.should > @stat.version
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe 'with outdated version' do
|
191
|
+
before do
|
192
|
+
# need to do a couple of sets to ramp up the version
|
193
|
+
3.times { |n| @stat = @zk.set(:path => @path, :data => "#{@new_data}#{n}")[:stat] }
|
194
|
+
|
195
|
+
@rv = @zk.set(:path => @path, :data => @new_data, :version => 0)
|
196
|
+
end
|
197
|
+
|
198
|
+
it %[should have a return code of ZBADVERSION] do
|
199
|
+
@rv[:rc].should == Zookeeper::ZBADVERSION
|
200
|
+
end
|
201
|
+
|
202
|
+
it %[should return a stat with !exists] do
|
203
|
+
@rv[:stat].exists.should be_false
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end # sync
|
207
|
+
|
208
|
+
describe :async do
|
209
|
+
before do
|
210
|
+
@cb = Zookeeper::StatCallback.new
|
211
|
+
end
|
212
|
+
|
213
|
+
describe 'without version' do
|
214
|
+
it_should_behave_like "all success return values"
|
215
|
+
|
216
|
+
before do
|
217
|
+
@rv = @zk.set(:path => @path, :data => @new_data, :callback => @cb, :callback_context => @path)
|
218
|
+
|
219
|
+
wait_until(2) { @cb.completed? }
|
220
|
+
@cb.should be_completed
|
221
|
+
end
|
222
|
+
|
223
|
+
it %[should have the stat in the callback] do
|
224
|
+
@cb.stat.should_not be_nil
|
225
|
+
@cb.stat.version.should > @stat.version
|
226
|
+
end
|
227
|
+
|
228
|
+
it %[should have a return code of ZOK] do
|
229
|
+
@cb.return_code.should == Zookeeper::ZOK
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe 'with current version' do
|
234
|
+
it_should_behave_like "all success return values"
|
235
|
+
|
236
|
+
before do
|
237
|
+
@rv = @zk.set(:path => @path, :data => @new_data, :callback => @cb, :callback_context => @path, :version => @stat.version)
|
238
|
+
|
239
|
+
wait_until(2) { @cb.completed? }
|
240
|
+
@cb.should be_completed
|
241
|
+
end
|
242
|
+
|
243
|
+
it %[should have the stat in the callback] do
|
244
|
+
@cb.stat.should_not be_nil
|
245
|
+
@cb.stat.version.should > @stat.version
|
246
|
+
end
|
247
|
+
|
248
|
+
it %[should have a return code of ZOK] do
|
249
|
+
@cb.return_code.should == Zookeeper::ZOK
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
describe 'with outdated version' do
|
254
|
+
before do
|
255
|
+
# need to do a couple of sets to ramp up the version
|
256
|
+
3.times { |n| @stat = @zk.set(:path => @path, :data => "#{@new_data}#{n}")[:stat] }
|
257
|
+
|
258
|
+
@rv = @zk.set(:path => @path, :data => @new_data, :callback => @cb, :callback_context => @path, :version => 0)
|
259
|
+
|
260
|
+
wait_until(2) { @cb.completed? }
|
261
|
+
@cb.should be_completed
|
262
|
+
end
|
263
|
+
|
264
|
+
it %[should have a return code of ZBADVERSION] do
|
265
|
+
@cb.return_code.should == Zookeeper::ZBADVERSION
|
266
|
+
end
|
267
|
+
|
268
|
+
it %[should return a stat with !exists] do
|
269
|
+
@cb.stat.exists.should be_false
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe :get_children do
|
276
|
+
before do
|
277
|
+
@children = %w[child0 child1 child2]
|
278
|
+
|
279
|
+
@children.each do |name|
|
280
|
+
@zk.create(:path => "#{@path}/#{name}", :data => name)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
after do
|
285
|
+
@children.each do |name|
|
286
|
+
@zk.delete(:path => "#{@path}/#{name}")
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
describe :sync do
|
291
|
+
it_should_behave_like "all success return values"
|
292
|
+
|
293
|
+
before do
|
294
|
+
@rv = @zk.get_children(:path => @path)
|
295
|
+
end
|
296
|
+
|
297
|
+
it %[should have an array of names of the children] do
|
298
|
+
@rv[:children].should be_kind_of(Array)
|
299
|
+
@rv[:children].length.should == 3
|
300
|
+
@rv[:children].sort.should == @children.sort
|
301
|
+
end
|
302
|
+
|
303
|
+
# "Three shall be the number of the counting, and the number of the counting shall be 3"
|
304
|
+
|
305
|
+
it %[should have a stat object whose num_children is 3] do
|
306
|
+
@rv[:stat].should_not be_nil
|
307
|
+
@rv[:stat].should be_kind_of(ZookeeperStat::Stat)
|
308
|
+
@rv[:stat].num_children.should == 3
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
describe :sync_watch do
|
313
|
+
it_should_behave_like "all success return values"
|
314
|
+
|
315
|
+
before do
|
316
|
+
@addtl_child = 'child3'
|
317
|
+
|
318
|
+
@watcher = Zookeeper::WatcherCallback.new
|
319
|
+
|
320
|
+
@rv = @zk.get_children(:path => @path, :watcher => @watcher, :watcher_context => @path)
|
321
|
+
end
|
322
|
+
|
323
|
+
after do
|
324
|
+
@zk.delete(:path => "#{@path}/#{@addtl_child}")
|
325
|
+
end
|
326
|
+
|
327
|
+
it %[should have an array of names of the children] do
|
328
|
+
@rv[:children].should be_kind_of(Array)
|
329
|
+
@rv[:children].length.should == 3
|
330
|
+
@rv[:children].sort.should == @children.sort
|
331
|
+
end
|
332
|
+
|
333
|
+
it %[should have a stat object whose num_children is 3] do
|
334
|
+
@rv[:stat].should_not be_nil
|
335
|
+
@rv[:stat].should be_kind_of(ZookeeperStat::Stat)
|
336
|
+
@rv[:stat].num_children.should == 3
|
337
|
+
end
|
338
|
+
|
339
|
+
it %[should set a watcher for children on the node] do
|
340
|
+
@watcher.should_not be_completed
|
341
|
+
|
342
|
+
@zk.create(:path => "#{@path}/#{@addtl_child}", :data => '')[:rc].should == Zookeeper::ZOK
|
343
|
+
|
344
|
+
wait_until { @watcher.completed? }
|
345
|
+
@watcher.should be_completed
|
346
|
+
|
347
|
+
@watcher.path.should == @path
|
348
|
+
@watcher.context.should == @path
|
349
|
+
@watcher.type.should == Zookeeper::ZOO_CHILD_EVENT
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
describe :async do
|
354
|
+
it_should_behave_like "all success return values"
|
355
|
+
|
356
|
+
before do
|
357
|
+
@cb = ZookeeperCallbacks::StringsCallback.new
|
358
|
+
@rv = @zk.get_children(:path => @path, :callback => @cb, :callback_context => @path)
|
359
|
+
|
360
|
+
wait_until { @cb.completed? }
|
361
|
+
@cb.should be_completed
|
362
|
+
end
|
363
|
+
|
364
|
+
it %[should succeed] do
|
365
|
+
@cb.return_code.should == Zookeeper::ZOK
|
366
|
+
end
|
367
|
+
|
368
|
+
it %[should return an array of children] do
|
369
|
+
@cb.children.should be_kind_of(Array)
|
370
|
+
@cb.children.length.should == 3
|
371
|
+
@cb.children.sort.should == @children.sort
|
372
|
+
end
|
373
|
+
|
374
|
+
it %[should have a stat object whose num_children is 3] do
|
375
|
+
@cb.stat.should_not be_nil
|
376
|
+
@cb.stat.should be_kind_of(ZookeeperStat::Stat)
|
377
|
+
@cb.stat.num_children.should == 3
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
describe :async_watch do
|
382
|
+
it_should_behave_like "all success return values"
|
383
|
+
|
384
|
+
before do
|
385
|
+
@addtl_child = 'child3'
|
386
|
+
|
387
|
+
@watcher = Zookeeper::WatcherCallback.new
|
388
|
+
@cb = ZookeeperCallbacks::StringsCallback.new
|
389
|
+
|
390
|
+
@rv = @zk.get_children(:path => @path, :watcher => @watcher, :watcher_context => @path, :callback => @cb, :callback_context => @path)
|
391
|
+
wait_until { @cb.completed? }
|
392
|
+
@cb.should be_completed
|
393
|
+
end
|
394
|
+
|
395
|
+
after do
|
396
|
+
@zk.delete(:path => "#{@path}/#{@addtl_child}")
|
397
|
+
end
|
398
|
+
|
399
|
+
it %[should succeed] do
|
400
|
+
@cb.return_code.should == Zookeeper::ZOK
|
401
|
+
end
|
402
|
+
|
403
|
+
it %[should return an array of children] do
|
404
|
+
@cb.children.should be_kind_of(Array)
|
405
|
+
@cb.children.length.should == 3
|
406
|
+
@cb.children.sort.should == @children.sort
|
407
|
+
end
|
408
|
+
|
409
|
+
it %[should have a stat object whose num_children is 3] do
|
410
|
+
@cb.stat.should_not be_nil
|
411
|
+
@cb.stat.should be_kind_of(ZookeeperStat::Stat)
|
412
|
+
@cb.stat.num_children.should == 3
|
413
|
+
end
|
414
|
+
|
415
|
+
it %[should set a watcher for children on the node] do
|
416
|
+
@watcher.should_not be_completed
|
417
|
+
|
418
|
+
@zk.create(:path => "#{@path}/#{@addtl_child}", :data => '')[:rc].should == Zookeeper::ZOK
|
419
|
+
|
420
|
+
wait_until { @watcher.completed? }
|
421
|
+
@watcher.should be_completed
|
422
|
+
|
423
|
+
@watcher.path.should == @path
|
424
|
+
@watcher.context.should == @path
|
425
|
+
@watcher.type.should == Zookeeper::ZOO_CHILD_EVENT
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
# NOTE: the jruby version of stat on non-existent node will have a
|
431
|
+
# return_code of 0, but the C version will have a return_code of -101
|
432
|
+
describe :stat do
|
433
|
+
describe :sync do
|
434
|
+
it_should_behave_like "all success return values"
|
435
|
+
|
436
|
+
before do
|
437
|
+
@rv = @zk.stat(:path => @path)
|
438
|
+
end
|
439
|
+
|
440
|
+
it %[should have a stat object] do
|
441
|
+
@rv[:stat].should be_kind_of(Zookeeper::Stat)
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
describe :sync_watch do
|
446
|
+
it_should_behave_like "all success return values"
|
447
|
+
|
448
|
+
before do
|
449
|
+
@watcher = Zookeeper::WatcherCallback.new
|
450
|
+
|
451
|
+
@rv = @zk.stat(:path => @path, :watcher => @watcher, :watcher_context => @path)
|
452
|
+
end
|
453
|
+
|
454
|
+
it %[should have a stat object] do
|
455
|
+
@rv[:stat].should be_kind_of(Zookeeper::Stat)
|
456
|
+
end
|
457
|
+
|
458
|
+
it %[should set a watcher for data changes on the node] do
|
459
|
+
@watcher.should_not be_completed
|
460
|
+
|
461
|
+
@zk.set(:path => @path, :data => 'skunk')[:rc].should == Zookeeper::ZOK
|
462
|
+
|
463
|
+
wait_until { @watcher.completed? }
|
464
|
+
@watcher.should be_completed
|
465
|
+
|
466
|
+
@watcher.path.should == @path
|
467
|
+
@watcher.context.should == @path
|
468
|
+
@watcher.type.should == Zookeeper::ZOO_CHANGED_EVENT
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
describe :async do
|
473
|
+
it_should_behave_like "all success return values"
|
474
|
+
|
475
|
+
before do
|
476
|
+
@cb = ZookeeperCallbacks::StatCallback.new
|
477
|
+
@rv = @zk.stat(:path => @path, :callback => @cb, :callback_context => @path)
|
478
|
+
|
479
|
+
wait_until { @cb.completed? }
|
480
|
+
@cb.should be_completed
|
481
|
+
end
|
482
|
+
|
483
|
+
it %[should succeed] do
|
484
|
+
@cb.return_code.should == Zookeeper::ZOK
|
485
|
+
end
|
486
|
+
|
487
|
+
it %[should have a stat object] do
|
488
|
+
@cb.stat.should be_kind_of(Zookeeper::Stat)
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
describe :async_watch do
|
493
|
+
it_should_behave_like "all success return values"
|
494
|
+
|
495
|
+
before do
|
496
|
+
@addtl_child = 'child3'
|
497
|
+
|
498
|
+
@watcher = Zookeeper::WatcherCallback.new
|
499
|
+
|
500
|
+
@cb = ZookeeperCallbacks::StatCallback.new
|
501
|
+
@rv = @zk.stat(:path => @path, :callback => @cb, :callback_context => @path, :watcher => @watcher, :watcher_context => @path)
|
502
|
+
|
503
|
+
wait_until { @cb.completed? }
|
504
|
+
@cb.should be_completed
|
505
|
+
end
|
506
|
+
|
507
|
+
after do
|
508
|
+
@zk.delete(:path => "#{@path}/#{@addtl_child}")
|
509
|
+
end
|
510
|
+
|
511
|
+
it %[should succeed] do
|
512
|
+
@cb.return_code.should == Zookeeper::ZOK
|
513
|
+
end
|
514
|
+
|
515
|
+
it %[should have a stat object] do
|
516
|
+
@cb.stat.should be_kind_of(Zookeeper::Stat)
|
517
|
+
end
|
518
|
+
|
519
|
+
it %[should set a watcher for data changes on the node] do
|
520
|
+
@watcher.should_not be_completed
|
521
|
+
|
522
|
+
@zk.set(:path => @path, :data => 'skunk')[:rc].should == Zookeeper::ZOK
|
523
|
+
|
524
|
+
wait_until { @watcher.completed? }
|
525
|
+
@watcher.should be_completed
|
526
|
+
|
527
|
+
@watcher.path.should == @path
|
528
|
+
@watcher.context.should == @path
|
529
|
+
@watcher.type.should == Zookeeper::ZOO_CHANGED_EVENT
|
530
|
+
end
|
531
|
+
end
|
532
|
+
end # stat
|
533
|
+
|
534
|
+
describe :create do
|
535
|
+
before do
|
536
|
+
# remove the path set up by the global 'before' block
|
537
|
+
@zk.delete(:path => @path)
|
538
|
+
end
|
539
|
+
|
540
|
+
describe :sync do
|
541
|
+
describe :default_flags do
|
542
|
+
it_should_behave_like "all success return values"
|
543
|
+
|
544
|
+
before do
|
545
|
+
@rv = @zk.create(:path => @path)
|
546
|
+
end
|
547
|
+
|
548
|
+
it %[should return the path that was set] do
|
549
|
+
@rv[:path].should == @path
|
550
|
+
end
|
551
|
+
|
552
|
+
it %[should have created a permanent node] do
|
553
|
+
st = @zk.stat(:path => @path)
|
554
|
+
st[:rc].should == Zookeeper::ZOK
|
555
|
+
|
556
|
+
st[:stat].ephemeral_owner.should == 0
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
describe :ephemeral do
|
561
|
+
it_should_behave_like "all success return values"
|
562
|
+
|
563
|
+
before do
|
564
|
+
@rv = @zk.create(:path => @path, :ephemeral => true)
|
565
|
+
end
|
566
|
+
|
567
|
+
it %[should return the path that was set] do
|
568
|
+
@rv[:path].should == @path
|
569
|
+
end
|
570
|
+
|
571
|
+
it %[should have created a ephemeral node] do
|
572
|
+
st = @zk.stat(:path => @path)
|
573
|
+
st[:rc].should == Zookeeper::ZOK
|
574
|
+
|
575
|
+
st[:stat].ephemeral_owner.should_not be_zero
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
describe :sequence do
|
580
|
+
it_should_behave_like "all success return values"
|
581
|
+
|
582
|
+
before do
|
583
|
+
@orig_path = @path
|
584
|
+
@rv = @zk.create(:path => @path, :sequence => true)
|
585
|
+
@path = @rv[:path] # make sure this gets cleaned up
|
586
|
+
end
|
587
|
+
|
588
|
+
it %[should return the path that was set] do
|
589
|
+
@rv[:path].should_not == @orig_path
|
590
|
+
end
|
591
|
+
|
592
|
+
it %[should have created a permanent node] do
|
593
|
+
st = @zk.stat(:path => @path)
|
594
|
+
st[:rc].should == Zookeeper::ZOK
|
595
|
+
|
596
|
+
st[:stat].ephemeral_owner.should be_zero
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
describe :ephemeral_sequence do
|
601
|
+
it_should_behave_like "all success return values"
|
602
|
+
|
603
|
+
before do
|
604
|
+
@orig_path = @path
|
605
|
+
@rv = @zk.create(:path => @path, :sequence => true, :ephemeral => true)
|
606
|
+
@path = @rv[:path] # make sure this gets cleaned up
|
607
|
+
end
|
608
|
+
|
609
|
+
it %[should return the path that was set] do
|
610
|
+
@rv[:path].should_not == @orig_path
|
611
|
+
end
|
612
|
+
|
613
|
+
it %[should have created an ephemeral node] do
|
614
|
+
st = @zk.stat(:path => @path)
|
615
|
+
st[:rc].should == Zookeeper::ZOK
|
616
|
+
|
617
|
+
st[:stat].ephemeral_owner.should_not be_zero
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
describe :acl do
|
622
|
+
it %[should work] do
|
623
|
+
pending "need to write acl tests"
|
624
|
+
end
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
describe :async do
|
629
|
+
before do
|
630
|
+
@cb = ZookeeperCallbacks::StringCallback.new
|
631
|
+
end
|
632
|
+
|
633
|
+
describe :default_flags do
|
634
|
+
it_should_behave_like "all success return values"
|
635
|
+
|
636
|
+
before do
|
637
|
+
@rv = @zk.create(:path => @path, :callback => @cb, :callback_context => @path)
|
638
|
+
wait_until(2) { @cb.completed? }
|
639
|
+
@cb.should be_completed
|
640
|
+
end
|
641
|
+
|
642
|
+
it %[should have a path] do
|
643
|
+
@cb.path.should_not be_nil
|
644
|
+
end
|
645
|
+
|
646
|
+
it %[should return the path that was set] do
|
647
|
+
@cb.path.should == @path
|
648
|
+
end
|
649
|
+
|
650
|
+
it %[should have created a permanent node] do
|
651
|
+
st = @zk.stat(:path => @path)
|
652
|
+
st[:rc].should == Zookeeper::ZOK
|
653
|
+
|
654
|
+
st[:stat].ephemeral_owner.should == 0
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
describe :ephemeral do
|
659
|
+
it_should_behave_like "all success return values"
|
660
|
+
|
661
|
+
before do
|
662
|
+
@rv = @zk.create(:path => @path, :ephemeral => true, :callback => @cb, :callback_context => @path)
|
663
|
+
wait_until(2) { @cb.completed? }
|
664
|
+
@cb.should be_completed
|
665
|
+
end
|
666
|
+
|
667
|
+
it %[should have a path] do
|
668
|
+
@cb.path.should_not be_nil
|
669
|
+
end
|
670
|
+
|
671
|
+
it %[should return the path that was set] do
|
672
|
+
@cb.path.should == @path
|
673
|
+
end
|
674
|
+
|
675
|
+
it %[should have created a ephemeral node] do
|
676
|
+
st = @zk.stat(:path => @path)
|
677
|
+
st[:rc].should == Zookeeper::ZOK
|
678
|
+
|
679
|
+
st[:stat].ephemeral_owner.should_not be_zero
|
680
|
+
end
|
681
|
+
end
|
682
|
+
|
683
|
+
describe :sequence do
|
684
|
+
it_should_behave_like "all success return values"
|
685
|
+
|
686
|
+
before do
|
687
|
+
@orig_path = @path
|
688
|
+
@rv = @zk.create(:path => @path, :sequence => true, :callback => @cb, :callback_context => @path)
|
689
|
+
|
690
|
+
wait_until(2) { @cb.completed? }
|
691
|
+
@cb.should be_completed
|
692
|
+
|
693
|
+
@path = @cb.path
|
694
|
+
end
|
695
|
+
|
696
|
+
it %[should have a path] do
|
697
|
+
@cb.path.should_not be_nil
|
698
|
+
end
|
699
|
+
|
700
|
+
it %[should return the path that was set] do
|
701
|
+
@cb.path.should_not == @orig_path
|
702
|
+
end
|
703
|
+
|
704
|
+
it %[should have created a permanent node] do
|
705
|
+
st = @zk.stat(:path => @path)
|
706
|
+
st[:rc].should == Zookeeper::ZOK
|
707
|
+
|
708
|
+
st[:stat].ephemeral_owner.should be_zero
|
709
|
+
end
|
710
|
+
end
|
711
|
+
|
712
|
+
describe :ephemeral_sequence do
|
713
|
+
it_should_behave_like "all success return values"
|
714
|
+
|
715
|
+
before do
|
716
|
+
@orig_path = @path
|
717
|
+
@rv = @zk.create(:path => @path, :sequence => true, :ephemeral => true, :callback => @cb, :callback_context => @path)
|
718
|
+
@path = @rv[:path] # make sure this gets cleaned up
|
719
|
+
|
720
|
+
wait_until(2) { @cb.completed? }
|
721
|
+
@cb.should be_completed
|
722
|
+
@path = @cb.path
|
723
|
+
end
|
724
|
+
|
725
|
+
it %[should have a path] do
|
726
|
+
@cb.path.should_not be_nil
|
727
|
+
end
|
728
|
+
|
729
|
+
it %[should return the path that was set] do
|
730
|
+
@path.should_not == @orig_path
|
731
|
+
end
|
732
|
+
|
733
|
+
it %[should have created an ephemeral node] do
|
734
|
+
st = @zk.stat(:path => @path)
|
735
|
+
st[:rc].should == Zookeeper::ZOK
|
736
|
+
|
737
|
+
st[:stat].ephemeral_owner.should_not be_zero
|
738
|
+
end
|
739
|
+
end
|
740
|
+
|
741
|
+
describe :acl do
|
742
|
+
it %[should work] do
|
743
|
+
pending "need to write acl tests"
|
744
|
+
end
|
745
|
+
end
|
746
|
+
end
|
747
|
+
end
|
748
|
+
|
749
|
+
describe :delete do
|
750
|
+
describe :sync do
|
751
|
+
describe 'without version' do
|
752
|
+
it_should_behave_like "all success return values"
|
753
|
+
|
754
|
+
before do
|
755
|
+
@zk.create(:path => @path)
|
756
|
+
@rv = @zk.delete(:path => @path)
|
757
|
+
end
|
758
|
+
|
759
|
+
it %[should have deleted the node] do
|
760
|
+
@zk.stat(:path => @path)[:stat].exists.should be_false
|
761
|
+
end
|
762
|
+
end
|
763
|
+
|
764
|
+
describe 'with current version' do
|
765
|
+
it_should_behave_like "all success return values"
|
766
|
+
|
767
|
+
before do
|
768
|
+
@zk.create(:path => @path)
|
769
|
+
|
770
|
+
@stat = @zk.stat(:path => @path)[:stat]
|
771
|
+
@stat.exists.should be_true
|
772
|
+
|
773
|
+
@rv = @zk.delete(:path => @path, :version => @stat.version)
|
774
|
+
end
|
775
|
+
|
776
|
+
it %[should have deleted the node] do
|
777
|
+
@zk.stat(:path => @path)[:stat].exists.should be_false
|
778
|
+
end
|
779
|
+
end
|
780
|
+
|
781
|
+
describe 'with old version' do
|
782
|
+
before do
|
783
|
+
3.times { |n| @stat = @zk.set(:path => @path, :data => n.to_s)[:stat] }
|
784
|
+
|
785
|
+
@rv = @zk.delete(:path => @path, :version => 0)
|
786
|
+
end
|
787
|
+
|
788
|
+
it %[should have a return code of ZBADVERSION] do
|
789
|
+
@rv[:rc].should == Zookeeper::ZBADVERSION
|
790
|
+
end
|
791
|
+
end
|
792
|
+
end # sync
|
793
|
+
|
794
|
+
describe :async do
|
795
|
+
before do
|
796
|
+
@cb = ZookeeperCallbacks::VoidCallback.new
|
797
|
+
end
|
798
|
+
|
799
|
+
describe 'without version' do
|
800
|
+
it_should_behave_like "all success return values"
|
801
|
+
|
802
|
+
before do
|
803
|
+
@rv = @zk.delete(:path => @path, :callback => @cb, :callback_context => @path)
|
804
|
+
wait_until { @cb.completed? }
|
805
|
+
@cb.should be_completed
|
806
|
+
end
|
807
|
+
|
808
|
+
it %[should have a success return_code] do
|
809
|
+
@cb.return_code.should == Zookeeper::ZOK
|
810
|
+
end
|
811
|
+
|
812
|
+
it %[should have deleted the node] do
|
813
|
+
@zk.stat(:path => @path)[:stat].exists.should be_false
|
814
|
+
end
|
815
|
+
end
|
816
|
+
|
817
|
+
describe 'with current version' do
|
818
|
+
it_should_behave_like "all success return values"
|
819
|
+
|
820
|
+
before do
|
821
|
+
@stat = @zk.stat(:path => @path)[:stat]
|
822
|
+
@rv = @zk.delete(:path => @path, :version => @stat.version, :callback => @cb, :callback_context => @path)
|
823
|
+
wait_until { @cb.completed? }
|
824
|
+
@cb.should be_completed
|
825
|
+
end
|
826
|
+
|
827
|
+
it %[should have a success return_code] do
|
828
|
+
@cb.return_code.should == Zookeeper::ZOK
|
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 old version' do
|
837
|
+
before do
|
838
|
+
3.times { |n| @stat = @zk.set(:path => @path, :data => n.to_s)[:stat] }
|
839
|
+
|
840
|
+
@rv = @zk.delete(:path => @path, :version => 0, :callback => @cb, :callback_context => @path)
|
841
|
+
wait_until { @cb.completed? }
|
842
|
+
@cb.should be_completed
|
843
|
+
end
|
844
|
+
|
845
|
+
it %[should have a return code of ZBADVERSION] do
|
846
|
+
@cb.return_code.should == Zookeeper::ZBADVERSION
|
847
|
+
end
|
848
|
+
end
|
849
|
+
end
|
850
|
+
end # delete
|
851
|
+
|
852
|
+
describe :get_acl do
|
853
|
+
describe :sync do
|
854
|
+
it_should_behave_like "all success return values"
|
855
|
+
|
856
|
+
before do
|
857
|
+
@rv = @zk.get_acl(:path => @path)
|
858
|
+
end
|
859
|
+
|
860
|
+
it %[should return a stat for the path] do
|
861
|
+
@rv[:stat].should be_kind_of(ZookeeperStat::Stat)
|
862
|
+
end
|
863
|
+
|
864
|
+
it %[should return the acls] do
|
865
|
+
acls = @rv[:acl]
|
866
|
+
acls.should be_kind_of(Array)
|
867
|
+
h = acls.first
|
868
|
+
|
869
|
+
h.should be_kind_of(Hash)
|
870
|
+
|
871
|
+
h[:perms].should == Zookeeper::ZOO_PERM_ALL
|
872
|
+
h[:id][:scheme].should == 'world'
|
873
|
+
h[:id][:id].should == 'anyone'
|
874
|
+
end
|
875
|
+
end
|
876
|
+
|
877
|
+
describe :async do
|
878
|
+
it_should_behave_like "all success return values"
|
879
|
+
|
880
|
+
before do
|
881
|
+
@cb = Zookeeper::ACLCallback.new
|
882
|
+
@rv = @zk.get_acl(:path => @path, :callback => @cb, :callback_context => @path)
|
883
|
+
|
884
|
+
wait_until(2) { @cb.completed? }
|
885
|
+
@cb.should be_completed
|
886
|
+
end
|
887
|
+
|
888
|
+
it %[should return a stat for the path] do
|
889
|
+
@cb.stat.should be_kind_of(ZookeeperStat::Stat)
|
890
|
+
end
|
891
|
+
|
892
|
+
it %[should return the acls] do
|
893
|
+
acls = @cb.acl
|
894
|
+
acls.should be_kind_of(Array)
|
895
|
+
|
896
|
+
acl = acls.first
|
897
|
+
acl.should be_kind_of(ZookeeperACLs::ACL)
|
898
|
+
|
899
|
+
acl.perms.should == Zookeeper::ZOO_PERM_ALL
|
900
|
+
|
901
|
+
acl.id.scheme.should == 'world'
|
902
|
+
acl.id.id.should == 'anyone'
|
903
|
+
end
|
904
|
+
end
|
905
|
+
end
|
906
|
+
|
907
|
+
describe :set_acl do
|
908
|
+
|
909
|
+
before do
|
910
|
+
@perms = 5
|
911
|
+
@new_acl = [ZookeeperACLs::ACL.new(:perms => @perms, :id => ZookeeperACLs::ZOO_ANYONE_ID_UNSAFE)]
|
912
|
+
pending("No idea how to set ACLs")
|
913
|
+
end
|
914
|
+
|
915
|
+
describe :sync do
|
916
|
+
it_should_behave_like "all success return values"
|
917
|
+
|
918
|
+
before do
|
919
|
+
@rv = @zk.set_acl(:path => @path, :acl => @new_acl)
|
920
|
+
end
|
921
|
+
|
922
|
+
end
|
923
|
+
end
|
924
|
+
end
|