blob: fcbe599b1b611c7fe4b473c383bf8369a00a148f [file] [log] [blame]
Jonathan Hart6df90172014-04-03 10:13:11 -07001package net.onrc.onos.core.datastore.hazelcast;
Yuta HIGUCHI6a643132014-03-18 22:39:27 -07002
Jonathan Harta88fd242014-04-03 11:24:54 -07003import static org.junit.Assert.assertArrayEquals;
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertNotEquals;
6import static org.junit.Assert.assertNotNull;
7import static org.junit.Assert.assertNull;
8import static org.junit.Assert.assertTrue;
9import static org.junit.Assert.fail;
Yuta HIGUCHI6a643132014-03-18 22:39:27 -070010
11import java.nio.charset.StandardCharsets;
12import java.util.Map;
13import java.util.TreeMap;
14
Jonathan Harta88fd242014-04-03 11:24:54 -070015import net.onrc.onos.core.datastore.IKVTable.IKVEntry;
Jonathan Hart6df90172014-04-03 10:13:11 -070016import net.onrc.onos.core.datastore.ObjectDoesntExistException;
17import net.onrc.onos.core.datastore.ObjectExistsException;
18import net.onrc.onos.core.datastore.WrongVersionException;
Jonathan Hart6df90172014-04-03 10:13:11 -070019import net.onrc.onos.core.datastore.hazelcast.HZTable.VersionedValue;
20import net.onrc.onos.core.datastore.utils.ByteArrayComparator;
Yuta HIGUCHI6a643132014-03-18 22:39:27 -070021
22import org.junit.After;
23import org.junit.Before;
24import org.junit.Ignore;
25import org.junit.Rule;
26import org.junit.Test;
27import org.junit.rules.TestName;
28
29public class HZTableTest {
30 @Rule
31 public TestName name= new TestName();
32
33 static final String TEST_TABLE_NAME = "TableForUnitTest";
34 HZTable table;
35
36 @Before
37 public void setUp() throws Exception {
38 table = (HZTable) HZClient.getClient().getTable(TEST_TABLE_NAME);
39 }
40
41 @After
42 public void tearDown() throws Exception {
43 HZClient.getClient().dropTable(table);
44 }
45
46 public void assertEntryInTable(final byte[] key, final byte[] value, final long version) {
47 VersionedValue valueblob = table.getBackendMap().get(key);
48 assertNotNull(valueblob);
49 assertArrayEquals(value, valueblob.getValue());
50 assertEquals(version, valueblob.getVersion());
51 }
52
53 public void assertKeyNotInTable(final byte[] key) {
54 VersionedValue valueblob = table.getBackendMap().get(key);
55 assertNull(valueblob);
56 }
57
58 @Test
59 public void testGetInitialVersion() {
60 final long version1 = HZTable.getInitialVersion();
61 assertNotEquals(HZClient.VERSION_NONEXISTENT,version1);
62
63 final long version2 = HZTable.getInitialVersion();
64 assertNotEquals(HZClient.VERSION_NONEXISTENT, version2);
65 assertNotEquals(version1, version2);
66 }
67
68 @Test
69 public void testGetNextVersion() {
70 final long nextVersion = HZTable.getNextVersion(1);
71 assertNotEquals(nextVersion, HZClient.VERSION_NONEXISTENT);
72 assertNotEquals(nextVersion, 1);
73
74 final long nextVersion1 = HZTable.getNextVersion(Long.MAX_VALUE);
75 assertNotEquals(nextVersion1, HZClient.VERSION_NONEXISTENT);
76 assertNotEquals(nextVersion1, Long.MAX_VALUE);
77
78 final long nextVersion11 = HZTable.getNextVersion(HZClient.VERSION_NONEXISTENT-1);
79 assertNotEquals(nextVersion11, HZClient.VERSION_NONEXISTENT);
80 assertNotEquals(nextVersion11, HZClient.VERSION_NONEXISTENT-1);
81 }
82
83 @Ignore // nothing to test for now
84 @Test
85 public void testHZTable() {
86 fail("Not yet implemented");
87 }
88
89 @Test
90 public void testGetTableName() {
91 assertEquals(TEST_TABLE_NAME, table.getTableName());
92 }
93
94 @Test
95 public void testVERSION_NONEXISTENT() {
96 assertEquals(HZClient.VERSION_NONEXISTENT, table.VERSION_NONEXISTENT());
97 }
98
99 @Test
100 public void testGetTableId() {
101 // for Hazelcast implementation IKVTableID is table itself
102 assertEquals(table, table.getTableId());
103 }
104
105 @Test
106 public void testCreate() throws ObjectExistsException {
107 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
108 final byte[] value = "SomeValue".getBytes(StandardCharsets.UTF_8);
109
110 final long version = table.create(key, value);
111 assertNotEquals(HZClient.VERSION_NONEXISTENT,version);
112
113 assertEntryInTable(key, value, version);
114 }
115
116 @Test(expected = ObjectExistsException.class)
117 public void testCreateConflict() throws ObjectExistsException {
118 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
119 final byte[] value = "SomeValue".getBytes(StandardCharsets.UTF_8);
120
121 final long version = table.create(key, value);
122 assertNotEquals(HZClient.VERSION_NONEXISTENT,version);
123
124 assertEntryInTable(key, value, version);
125
126 table.create(key, value);
127 fail("Should have thrown exception");
128 }
129
130 @Test
131 public void testForceCreate() {
132 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
133 final byte[] value = "SomeValue".getBytes(StandardCharsets.UTF_8);
134
135 final long version = table.forceCreate(key, value);
136 assertNotEquals(HZClient.VERSION_NONEXISTENT,version);
137 assertEntryInTable(key, value, version);
138
139
140 final long version1 = table.forceCreate(key, value);
141 assertNotEquals(HZClient.VERSION_NONEXISTENT,version1);
142 assertNotEquals(version, version1);
143 assertEntryInTable(key, value, version1);
144 }
145
146 @Test
147 public void testRead() throws ObjectDoesntExistException {
148 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
149 final byte[] value = "SomeValue".getBytes(StandardCharsets.UTF_8);
150
151 // put data to read
152 final long version = table.forceCreate(key, value);
153 assertNotEquals(HZClient.VERSION_NONEXISTENT,version);
154 assertEntryInTable(key, value, version);
155
156 // test body
157 final IKVEntry readValue = table.read(key);
158 assertArrayEquals(key, readValue.getKey());
159 assertArrayEquals(value, readValue.getValue());
160 assertEquals(version, readValue.getVersion());
161 }
162
163
164 @Test(expected = ObjectDoesntExistException.class)
165 public void testReadNotExist() throws ObjectDoesntExistException {
166 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
167
168 table.read(key);
169 fail("Should have thrown exception");
170 }
171
172 @Test
173 public void testUpdateByteArrayByteArrayLongSuccess() throws ObjectDoesntExistException, WrongVersionException {
174 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
175 final byte[] oldValue = "OldValue".getBytes(StandardCharsets.UTF_8);
176 final byte[] value = "SomeValue".getBytes(StandardCharsets.UTF_8);
177
178 // put data to update
179 final long oldVersion = table.forceCreate(key, oldValue);
180 assertNotEquals(HZClient.VERSION_NONEXISTENT,oldVersion);
181 assertEntryInTable(key, oldValue, oldVersion);
182
183 final long version = table.update(key, value, oldVersion);
184 assertNotEquals(HZClient.VERSION_NONEXISTENT,version);
185 assertEntryInTable(key, value, version);
186 }
187
188 @Test(expected = ObjectDoesntExistException.class)
189 public void testUpdateByteArrayByteArrayLongFailNoOldValue() throws ObjectDoesntExistException, WrongVersionException {
190 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
191 final byte[] value = "SomeValue".getBytes(StandardCharsets.UTF_8);
192
193 final long oldVersion = 0xDEAD;
194
195 final long version = table.update(key, value, oldVersion);
196 assertNotEquals(HZClient.VERSION_NONEXISTENT,version);
197 assertEntryInTable(key, value, version);
198 }
199
200 @Test(expected = WrongVersionException.class)
201 public void testUpdateByteArrayByteArrayLongFailWrongVersion() throws ObjectDoesntExistException, WrongVersionException {
202 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
203 final byte[] oldValue = "OldValue".getBytes(StandardCharsets.UTF_8);
204 final byte[] value = "SomeValue".getBytes(StandardCharsets.UTF_8);
205
206 // put data to update
207 final long oldVersion = table.forceCreate(key, oldValue);
208 assertNotEquals(HZClient.VERSION_NONEXISTENT,oldVersion);
209 assertEntryInTable(key, oldValue, oldVersion);
210 // some one updates (from different thread/process in reality)
211 table.forceCreate(key, oldValue);
212 assertNotEquals(HZClient.VERSION_NONEXISTENT,oldVersion);
213
214
215 table.update(key, value, oldVersion);
216 fail("Should have thrown exception");
217 }
218
219 @Test
220 public void testUpdateByteArrayByteArraySuccess() throws ObjectDoesntExistException {
221 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
222 final byte[] oldValue = "OldValue".getBytes(StandardCharsets.UTF_8);
223 final byte[] value = "SomeValue".getBytes(StandardCharsets.UTF_8);
224
225 // put data to update
226 final long oldVersion = table.forceCreate(key, oldValue);
227 assertNotEquals(HZClient.VERSION_NONEXISTENT,oldVersion);
228 assertEntryInTable(key, oldValue, oldVersion);
229
230 final long version = table.update(key, value);
231 assertNotEquals(HZClient.VERSION_NONEXISTENT,version);
232 assertEntryInTable(key, value, version);
233 }
234
235 @Test(expected = ObjectDoesntExistException.class)
236 public void testUpdateByteArrayByteArrayFailNoOldValue() throws ObjectDoesntExistException, WrongVersionException {
237 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
238 final byte[] value = "SomeValue".getBytes(StandardCharsets.UTF_8);
239
240 final long version = table.update(key, value);
241 assertNotEquals(HZClient.VERSION_NONEXISTENT,version);
242 assertEntryInTable(key, value, version);
243 fail("Should have thrown exception");
244 }
245
246 @Test
247 public void testUpdateByteArrayByteArraySuccessIgnoreVersion() throws ObjectDoesntExistException, WrongVersionException {
248 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
249 final byte[] oldValue = "OldValue".getBytes(StandardCharsets.UTF_8);
250 final byte[] value = "SomeValue".getBytes(StandardCharsets.UTF_8);
251
252 // put data to update
253 final long oldVersion = table.forceCreate(key, oldValue);
254 assertNotEquals(HZClient.VERSION_NONEXISTENT,oldVersion);
255 assertEntryInTable(key, oldValue, oldVersion);
256 // someone updates (from different thread/process in reality)
257 table.forceCreate(key, oldValue);
258 assertNotEquals(HZClient.VERSION_NONEXISTENT,oldVersion);
259
260
261 final long version = table.update(key, value);
262 assertNotEquals(HZClient.VERSION_NONEXISTENT,version);
263 assertEntryInTable(key, value, version);
264 }
265
266 @Test
267 public void testDelete() throws ObjectDoesntExistException, WrongVersionException {
268 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
269 final byte[] oldValue = "OldValue".getBytes(StandardCharsets.UTF_8);
270
271 // put data to delete
272 final long oldVersion = table.forceCreate(key, oldValue);
273 assertNotEquals(HZClient.VERSION_NONEXISTENT,oldVersion);
274 assertEntryInTable(key, oldValue, oldVersion);
275
276 long version = table.delete(key, oldVersion);
277 assertNotEquals(HZClient.VERSION_NONEXISTENT,oldVersion);
278 assertEquals(oldVersion, version);
279 assertKeyNotInTable(key);
280 }
281
282 @Test(expected = ObjectDoesntExistException.class)
283 public void testDeleteFailNoEntry() throws ObjectDoesntExistException, WrongVersionException {
284 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
285
286 final long oldVersion = 0xDEAD;
287
288 try {
289 table.delete(key, oldVersion);
290 } catch (ObjectDoesntExistException | WrongVersionException e) {
291 assertKeyNotInTable(key);
292 throw e;
293 }
294 fail("Should have thrown exception");
295 }
296
297 @Test(expected = WrongVersionException.class)
298 public void testDeleteFailWrongVersion() throws ObjectDoesntExistException, WrongVersionException {
299 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
300 final byte[] oldValue = "OldValue".getBytes(StandardCharsets.UTF_8);
301
302 // put data to delete
303 final long oldVersion = table.forceCreate(key, oldValue);
304 assertNotEquals(HZClient.VERSION_NONEXISTENT,oldVersion);
305 assertEntryInTable(key, oldValue, oldVersion);
306 // someone updates (from different thread/process in reality)
307 final long latestVersion = table.forceCreate(key, oldValue);
308 assertNotEquals(HZClient.VERSION_NONEXISTENT,latestVersion);
309
310 try {
311 table.delete(key, oldVersion);
312 } catch (ObjectDoesntExistException | WrongVersionException e) {
313 assertEntryInTable(key, oldValue, latestVersion);
314 throw e;
315 }
316 fail("Should have thrown exception");
317 }
318
319
320
321 @Test
322 public void testForceDelete() {
323 final byte[] key = name.getMethodName().getBytes(StandardCharsets.UTF_8);
324 final byte[] oldValue = "OldValue".getBytes(StandardCharsets.UTF_8);
325
326 // put data to delete
327 final long oldVersion = table.forceCreate(key, oldValue);
328 assertNotEquals(HZClient.VERSION_NONEXISTENT,oldVersion);
329 assertEntryInTable(key, oldValue, oldVersion);
330
331 long version = table.forceDelete(key);
332 assertNotEquals(HZClient.VERSION_NONEXISTENT,oldVersion);
333 assertEquals(oldVersion, version);
334 assertKeyNotInTable(key);
335 }
336
337 @Test
338 public void testGetAllEntries() {
339 final int DATASETSIZE = 100;
340 final Map<byte[], VersionedValue> testdata = new TreeMap<>(ByteArrayComparator.BYTEARRAY_COMPARATOR);
341 for(int i = 0 ; i < DATASETSIZE ; ++i) {
342 final byte[] key = (name.getMethodName()+i).getBytes(StandardCharsets.UTF_8);
343 final byte[] value = ("Value"+i).getBytes(StandardCharsets.UTF_8);
344
345 // put data to delete
346 final long version = table.forceCreate(key, value);
347 assertNotEquals(HZClient.VERSION_NONEXISTENT, version);
348 assertEntryInTable(key, value, version);
349
350 testdata.put(key, new VersionedValue(value, version));
351 }
352
353 Iterable<IKVEntry> datastore = table.getAllEntries();
354 for( IKVEntry entry : datastore ) {
355 VersionedValue expectedValue = testdata.get(entry.getKey());
356 assertNotNull(expectedValue);
357 assertArrayEquals(expectedValue.getValue(), entry.getValue());
358 assertEquals(expectedValue.getVersion(), entry.getVersion());
359
360 testdata.remove(entry.getKey());
361 }
362
363 assertTrue(testdata.isEmpty());
364 }
365
366 @Test
367 public void testToString() {
368 assertEquals("[HZTable " + TEST_TABLE_NAME + "]", table.toString());
369 }
370
371}