0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 package org.apache.spark.util.kvstore;
0019
0020 import static java.nio.charset.StandardCharsets.UTF_8;
0021
0022 import org.junit.Test;
0023 import static org.junit.Assert.*;
0024
0025 public class LevelDBTypeInfoSuite {
0026
0027 @Test
0028 public void testIndexAnnotation() throws Exception {
0029 KVTypeInfo ti = new KVTypeInfo(CustomType1.class);
0030 assertEquals(5, ti.indices().count());
0031
0032 CustomType1 t1 = new CustomType1();
0033 t1.key = "key";
0034 t1.id = "id";
0035 t1.name = "name";
0036 t1.num = 42;
0037 t1.child = "child";
0038
0039 assertEquals(t1.key, ti.getIndexValue(KVIndex.NATURAL_INDEX_NAME, t1));
0040 assertEquals(t1.id, ti.getIndexValue("id", t1));
0041 assertEquals(t1.name, ti.getIndexValue("name", t1));
0042 assertEquals(t1.num, ti.getIndexValue("int", t1));
0043 assertEquals(t1.child, ti.getIndexValue("child", t1));
0044 }
0045
0046 @Test(expected = IllegalArgumentException.class)
0047 public void testNoNaturalIndex() throws Exception {
0048 newTypeInfo(NoNaturalIndex.class);
0049 }
0050
0051 @Test(expected = IllegalArgumentException.class)
0052 public void testNoNaturalIndex2() throws Exception {
0053 newTypeInfo(NoNaturalIndex2.class);
0054 }
0055
0056 @Test(expected = IllegalArgumentException.class)
0057 public void testDuplicateIndex() throws Exception {
0058 newTypeInfo(DuplicateIndex.class);
0059 }
0060
0061 @Test(expected = IllegalArgumentException.class)
0062 public void testEmptyIndexName() throws Exception {
0063 newTypeInfo(EmptyIndexName.class);
0064 }
0065
0066 @Test(expected = IllegalArgumentException.class)
0067 public void testIllegalIndexName() throws Exception {
0068 newTypeInfo(IllegalIndexName.class);
0069 }
0070
0071 @Test(expected = IllegalArgumentException.class)
0072 public void testIllegalIndexMethod() throws Exception {
0073 newTypeInfo(IllegalIndexMethod.class);
0074 }
0075
0076 @Test
0077 public void testKeyClashes() throws Exception {
0078 LevelDBTypeInfo ti = newTypeInfo(CustomType1.class);
0079
0080 CustomType1 t1 = new CustomType1();
0081 t1.key = "key1";
0082 t1.name = "a";
0083
0084 CustomType1 t2 = new CustomType1();
0085 t2.key = "key2";
0086 t2.name = "aa";
0087
0088 CustomType1 t3 = new CustomType1();
0089 t3.key = "key3";
0090 t3.name = "aaa";
0091
0092
0093 assertBefore(ti.index("name").entityKey(null, t1), ti.index("name").entityKey(null, t2));
0094 assertBefore(ti.index("name").entityKey(null, t1), ti.index("name").entityKey(null, t3));
0095 assertBefore(ti.index("name").entityKey(null, t2), ti.index("name").entityKey(null, t3));
0096 }
0097
0098 @Test
0099 public void testNumEncoding() throws Exception {
0100 LevelDBTypeInfo.Index idx = newTypeInfo(CustomType1.class).indices().iterator().next();
0101
0102 assertEquals("+=00000001", new String(idx.toKey(1), UTF_8));
0103 assertEquals("+=00000010", new String(idx.toKey(16), UTF_8));
0104 assertEquals("+=7fffffff", new String(idx.toKey(Integer.MAX_VALUE), UTF_8));
0105
0106 assertBefore(idx.toKey(1), idx.toKey(2));
0107 assertBefore(idx.toKey(-1), idx.toKey(2));
0108 assertBefore(idx.toKey(-11), idx.toKey(2));
0109 assertBefore(idx.toKey(-11), idx.toKey(-1));
0110 assertBefore(idx.toKey(1), idx.toKey(11));
0111 assertBefore(idx.toKey(Integer.MIN_VALUE), idx.toKey(Integer.MAX_VALUE));
0112
0113 assertBefore(idx.toKey(1L), idx.toKey(2L));
0114 assertBefore(idx.toKey(-1L), idx.toKey(2L));
0115 assertBefore(idx.toKey(Long.MIN_VALUE), idx.toKey(Long.MAX_VALUE));
0116
0117 assertBefore(idx.toKey((short) 1), idx.toKey((short) 2));
0118 assertBefore(idx.toKey((short) -1), idx.toKey((short) 2));
0119 assertBefore(idx.toKey(Short.MIN_VALUE), idx.toKey(Short.MAX_VALUE));
0120
0121 assertBefore(idx.toKey((byte) 1), idx.toKey((byte) 2));
0122 assertBefore(idx.toKey((byte) -1), idx.toKey((byte) 2));
0123 assertBefore(idx.toKey(Byte.MIN_VALUE), idx.toKey(Byte.MAX_VALUE));
0124
0125 byte prefix = LevelDBTypeInfo.ENTRY_PREFIX;
0126 assertSame(new byte[] { prefix, LevelDBTypeInfo.FALSE }, idx.toKey(false));
0127 assertSame(new byte[] { prefix, LevelDBTypeInfo.TRUE }, idx.toKey(true));
0128 }
0129
0130 @Test
0131 public void testArrayIndices() throws Exception {
0132 LevelDBTypeInfo.Index idx = newTypeInfo(CustomType1.class).indices().iterator().next();
0133
0134 assertBefore(idx.toKey(new String[] { "str1" }), idx.toKey(new String[] { "str2" }));
0135 assertBefore(idx.toKey(new String[] { "str1", "str2" }),
0136 idx.toKey(new String[] { "str1", "str3" }));
0137
0138 assertBefore(idx.toKey(new int[] { 1 }), idx.toKey(new int[] { 2 }));
0139 assertBefore(idx.toKey(new int[] { 1, 2 }), idx.toKey(new int[] { 1, 3 }));
0140 }
0141
0142 private LevelDBTypeInfo newTypeInfo(Class<?> type) throws Exception {
0143 return new LevelDBTypeInfo(null, type, type.getName().getBytes(UTF_8));
0144 }
0145
0146 private void assertBefore(byte[] key1, byte[] key2) {
0147 assertBefore(new String(key1, UTF_8), new String(key2, UTF_8));
0148 }
0149
0150 private void assertBefore(String str1, String str2) {
0151 assertTrue(String.format("%s < %s failed", str1, str2), str1.compareTo(str2) < 0);
0152 }
0153
0154 private void assertSame(byte[] key1, byte[] key2) {
0155 assertEquals(new String(key1, UTF_8), new String(key2, UTF_8));
0156 }
0157
0158 public static class NoNaturalIndex {
0159
0160 public String id;
0161
0162 }
0163
0164 public static class NoNaturalIndex2 {
0165
0166 @KVIndex("id")
0167 public String id;
0168
0169 }
0170
0171 public static class DuplicateIndex {
0172
0173 @KVIndex
0174 public String key;
0175
0176 @KVIndex("id")
0177 public String id;
0178
0179 @KVIndex("id")
0180 public String id2;
0181
0182 }
0183
0184 public static class EmptyIndexName {
0185
0186 @KVIndex("")
0187 public String id;
0188
0189 }
0190
0191 public static class IllegalIndexName {
0192
0193 @KVIndex("__invalid")
0194 public String id;
0195
0196 }
0197
0198 public static class IllegalIndexMethod {
0199
0200 @KVIndex("id")
0201 public String id(boolean illegalParam) {
0202 return null;
0203 }
0204
0205 }
0206
0207 }