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