0
# ZooKeeper Mocking
1
2
Complete in-memory ZooKeeper implementation for testing coordination service interactions without requiring an external ZooKeeper cluster. Provides full API compatibility with configurable failure injection and session management.
3
4
## Capabilities
5
6
### MockZooKeeper Operations Enum
7
8
Enumeration of ZooKeeper operations for testing and failure injection.
9
10
```java { .api }
11
enum Op {
12
CREATE, GET, SET, GET_CHILDREN, DELETE, EXISTS, SYNC
13
}
14
```
15
16
### MockZooKeeper
17
18
Main mock ZooKeeper implementation that extends the standard ZooKeeper client with in-memory data storage and testing controls.
19
20
```java { .api }
21
class MockZooKeeper extends ZooKeeper {
22
// Static Factory Methods
23
static MockZooKeeper newInstance();
24
static MockZooKeeper newInstance(int readOpDelayMs);
25
26
// Configuration Methods
27
int getSessionTimeout();
28
void setSessionTimeout(int sessionTimeout);
29
void setSessionId(long id);
30
void overrideSessionId(long sessionId);
31
void removeSessionIdOverride();
32
33
// State and Session Management
34
States getState();
35
void register(Watcher watcher);
36
long getSessionId();
37
38
// Node Operations - Synchronous
39
String create(String path, byte[] data, List<ACL> acl, CreateMode createMode) throws KeeperException, InterruptedException;
40
byte[] getData(String path, Watcher watcher, Stat stat) throws KeeperException, InterruptedException;
41
List<String> getChildren(String path, Watcher watcher) throws KeeperException, InterruptedException;
42
List<String> getChildren(String path, boolean watch) throws KeeperException, InterruptedException;
43
Stat exists(String path, Watcher watcher) throws KeeperException, InterruptedException;
44
Stat exists(String path, boolean watch) throws KeeperException, InterruptedException;
45
Stat setData(String path, byte[] data, int version) throws KeeperException, InterruptedException;
46
void delete(String path, int version) throws KeeperException, InterruptedException;
47
List<OpResult> multi(Iterable<org.apache.zookeeper.Op> ops) throws InterruptedException, KeeperException;
48
49
// Node Operations - Asynchronous
50
void create(String path, byte[] data, List<ACL> acl, CreateMode createMode, StringCallback cb, Object ctx);
51
void getData(String path, Watcher watcher, DataCallback cb, Object ctx);
52
void getData(String path, boolean watch, DataCallback cb, Object ctx);
53
void getChildren(String path, Watcher watcher, ChildrenCallback cb, Object ctx);
54
void getChildren(String path, boolean watcher, Children2Callback cb, Object ctx);
55
void exists(String path, boolean watch, StatCallback cb, Object ctx);
56
void exists(String path, Watcher watcher, StatCallback cb, Object ctx);
57
void sync(String path, VoidCallback cb, Object ctx);
58
void setData(String path, byte[] data, int version, StatCallback cb, Object ctx);
59
void delete(String path, int version, VoidCallback cb, Object ctx);
60
void multi(Iterable<org.apache.zookeeper.Op> ops, AsyncCallback.MultiCallback cb, Object ctx);
61
62
// Watch Management
63
void addWatch(String basePath, Watcher watcher, AddWatchMode mode);
64
void addWatch(String basePath, Watcher watcher, AddWatchMode mode, VoidCallback cb, Object ctx);
65
66
// Testing and Failure Injection
67
void failConditional(KeeperException.Code rc, BiPredicate<Op, String> predicate);
68
void delay(long millis, BiPredicate<Op, String> predicate);
69
void setAlwaysFail(KeeperException.Code rc);
70
void unsetAlwaysFail();
71
void deleteEphemeralNodes(long sessionId);
72
void deleteWatchers(long sessionId);
73
74
// Resource Management
75
synchronized void increaseRefCount();
76
synchronized MockZooKeeper registerCloseable(AutoCloseable closeable);
77
synchronized void close() throws InterruptedException;
78
void shutdown() throws InterruptedException;
79
}
80
```
81
82
### MockZooKeeperSession
83
84
Session-based wrapper that provides isolated ZooKeeper instances for multi-client testing scenarios with automatic session management.
85
86
```java { .api }
87
class MockZooKeeperSession extends ZooKeeper {
88
// Static Factory Methods
89
static MockZooKeeperSession newInstance(MockZooKeeper mockZooKeeper);
90
static MockZooKeeperSession newInstance(MockZooKeeper mockZooKeeper, boolean closeMockZooKeeperOnClose);
91
92
// Configuration Methods
93
int getSessionTimeout();
94
void setSessionTimeout(int sessionTimeout);
95
void setSessionId(long id);
96
long getSessionId();
97
98
// State Management
99
States getState();
100
void register(Watcher watcher);
101
102
// Node Operations - Synchronous (delegates to underlying MockZooKeeper)
103
String create(String path, byte[] data, List<ACL> acl, CreateMode createMode) throws KeeperException, InterruptedException;
104
byte[] getData(String path, Watcher watcher, Stat stat) throws KeeperException, InterruptedException;
105
List<String> getChildren(String path, Watcher watcher) throws KeeperException, InterruptedException;
106
List<String> getChildren(String path, boolean watch) throws KeeperException, InterruptedException;
107
Stat exists(String path, boolean watch) throws KeeperException, InterruptedException;
108
Stat exists(String path, Watcher watcher) throws KeeperException, InterruptedException;
109
Stat setData(String path, byte[] data, int version) throws KeeperException, InterruptedException;
110
void delete(String path, int version) throws InterruptedException, KeeperException;
111
List<OpResult> multi(Iterable<org.apache.zookeeper.Op> ops) throws InterruptedException, KeeperException;
112
113
// Node Operations - Asynchronous (delegates to underlying MockZooKeeper)
114
void create(String path, byte[] data, List<ACL> acl, CreateMode createMode, AsyncCallback.StringCallback cb, Object ctx);
115
void getData(String path, boolean watch, DataCallback cb, Object ctx);
116
void getData(String path, Watcher watcher, DataCallback cb, Object ctx);
117
void getChildren(String path, Watcher watcher, ChildrenCallback cb, Object ctx);
118
void getChildren(String path, boolean watcher, Children2Callback cb, Object ctx);
119
void exists(String path, boolean watch, StatCallback cb, Object ctx);
120
void exists(String path, Watcher watcher, StatCallback cb, Object ctx);
121
void sync(String path, VoidCallback cb, Object ctx);
122
void setData(String path, byte[] data, int version, StatCallback cb, Object ctx);
123
void delete(String path, int version, VoidCallback cb, Object ctx);
124
void multi(Iterable<org.apache.zookeeper.Op> ops, AsyncCallback.MultiCallback cb, Object ctx);
125
126
// Watch Management
127
void addWatch(String basePath, Watcher watcher, AddWatchMode mode, VoidCallback cb, Object ctx);
128
void addWatch(String basePath, Watcher watcher, AddWatchMode mode) throws KeeperException, InterruptedException;
129
void addWatch(String basePath, AddWatchMode mode) throws KeeperException, InterruptedException;
130
void addWatch(String basePath, AddWatchMode mode, VoidCallback cb, Object ctx);
131
132
// Testing Methods
133
void failConditional(KeeperException.Code rc, BiPredicate<MockZooKeeper.Op, String> predicate);
134
void setAlwaysFail(KeeperException.Code rc);
135
void unsetAlwaysFail();
136
137
// Resource Management
138
void close() throws InterruptedException;
139
void shutdown() throws InterruptedException;
140
}
141
```
142
143
## Types
144
145
### ZooKeeper Callback Interfaces
146
147
```java { .api }
148
interface StringCallback {
149
void processResult(int rc, String path, Object ctx, String name);
150
}
151
152
interface DataCallback {
153
void processResult(int rc, String path, Object ctx, byte[] data, Stat stat);
154
}
155
156
interface ChildrenCallback {
157
void processResult(int rc, String path, Object ctx, List<String> children);
158
}
159
160
interface Children2Callback {
161
void processResult(int rc, String path, Object ctx, List<String> children, Stat stat);
162
}
163
164
interface StatCallback {
165
void processResult(int rc, String path, Object ctx, Stat stat);
166
}
167
168
interface VoidCallback {
169
void processResult(int rc, String path, Object ctx);
170
}
171
```
172
173
### ZooKeeper Enums
174
175
```java { .api }
176
enum CreateMode {
177
PERSISTENT, PERSISTENT_SEQUENTIAL, EPHEMERAL, EPHEMERAL_SEQUENTIAL,
178
CONTAINER, PERSISTENT_WITH_TTL, PERSISTENT_SEQUENTIAL_WITH_TTL
179
}
180
181
enum AddWatchMode {
182
PERSISTENT, PERSISTENT_RECURSIVE
183
}
184
```
185
186
### ZooKeeper Exception Types
187
188
```java { .api }
189
class KeeperException extends Exception {
190
enum Code {
191
OK, SYSTEMERROR, RUNTIMEINCONSISTENCY, DATAINCONSISTENCY, CONNECTIONLOSS,
192
MARSHALLINGERROR, UNIMPLEMENTED, OPERATIONTIMEOUT, BADARGUMENTS,
193
APIERROR, NONODE, NOAUTH, BADVERSION, NOCHILDRENFOREPHEMERALS,
194
NODEEXISTS, NOTEMPTY, SESSIONEXPIRED, INVALIDCALLBACK, INVALIDACL,
195
AUTHFAILED, CLOSING, NOTHING, SESSIONMOVED, NOTREADONLY, EPHEMERALONLOCALSESSION,
196
NOWATCHER, RECONFIGDISABLED, REQUESTTIMEOUT, QUOTAEXCEEDED, THROTTLEDOP
197
}
198
}
199
```
200
201
## Usage Examples
202
203
### Basic Operations
204
205
```java
206
import org.apache.zookeeper.MockZooKeeper;
207
import org.apache.zookeeper.CreateMode;
208
import org.apache.zookeeper.ZooDefs.Ids;
209
210
// Create mock instance
211
MockZooKeeper mockZk = MockZooKeeper.newInstance();
212
213
// Create persistent node
214
String path = mockZk.create("/config", "initial".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
215
216
// Read data
217
byte[] data = mockZk.getData("/config", null, null);
218
219
// Update data
220
mockZk.setData("/config", "updated".getBytes(), -1);
221
222
// List children
223
List<String> children = mockZk.getChildren("/", null);
224
225
// Clean up
226
mockZk.close();
227
```
228
229
### Asynchronous Operations
230
231
```java
232
import org.apache.zookeeper.AsyncCallback;
233
234
MockZooKeeper mockZk = MockZooKeeper.newInstance();
235
236
// Async create with callback
237
mockZk.create("/async", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT,
238
(rc, path, ctx, name) -> {
239
if (rc == KeeperException.Code.OK.intValue()) {
240
System.out.println("Created: " + name);
241
}
242
}, null);
243
244
// Async read with callback
245
mockZk.getData("/async", null, (rc, path, ctx, data, stat) -> {
246
if (rc == KeeperException.Code.OK.intValue()) {
247
System.out.println("Data: " + new String(data));
248
}
249
}, null);
250
```
251
252
### Session-Based Testing
253
254
```java
255
import org.apache.zookeeper.MockZooKeeperSession;
256
257
// Create shared mock ZooKeeper instance
258
MockZooKeeper sharedMock = MockZooKeeper.newInstance();
259
260
// Create isolated session clients
261
MockZooKeeperSession client1 = MockZooKeeperSession.newInstance(sharedMock);
262
MockZooKeeperSession client2 = MockZooKeeperSession.newInstance(sharedMock);
263
264
// Each client has its own session but shares the same data
265
client1.create("/shared", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
266
byte[] data = client2.getData("/shared", null, null); // Can read data created by client1
267
268
// Clean up - closes session but not shared mock
269
client1.close();
270
client2.close();
271
sharedMock.close();
272
```
273
274
### Failure Injection Testing
275
276
```java
277
MockZooKeeper mockZk = MockZooKeeper.newInstance();
278
279
// Always fail create operations
280
mockZk.setAlwaysFail(KeeperException.Code.CONNECTIONLOSS);
281
282
try {
283
mockZk.create("/test", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
284
} catch (KeeperException e) {
285
// Will throw CONNECTIONLOSS exception
286
}
287
288
// Remove failure injection
289
mockZk.unsetAlwaysFail();
290
291
// Conditional failure - fail only GET operations on specific paths
292
mockZk.failConditional(KeeperException.Code.NONODE,
293
(op, path) -> op == MockZooKeeper.Op.GET && path.startsWith("/test"));
294
295
// Add delays to operations
296
mockZk.delay(1000, (op, path) -> path.startsWith("/slow"));
297
```
298
299
### Watcher Testing
300
301
```java
302
import org.apache.zookeeper.Watcher;
303
import org.apache.zookeeper.WatchedEvent;
304
305
MockZooKeeper mockZk = MockZooKeeper.newInstance();
306
307
// Set up watcher
308
Watcher watcher = new Watcher() {
309
public void process(WatchedEvent event) {
310
System.out.println("Event: " + event.getType() + " on " + event.getPath());
311
}
312
};
313
314
// Watch for node changes
315
mockZk.exists("/watched", watcher);
316
317
// Create node - triggers watcher
318
mockZk.create("/watched", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
319
320
// Add persistent watcher
321
mockZk.addWatch("/persistent", watcher, AddWatchMode.PERSISTENT);
322
```