You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2021/11/02 15:37:25 UTC
[ignite-3] 02/02: Add KV test.
This is an automated email from the ASF dual-hosted git repository.
amashenkov pushed a commit to branch ignite-15783
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit 651f06ed518bd522248a988a106ea9fded8af79a
Author: Andrew Mashenkov <an...@gmail.com>
AuthorDate: Tue Nov 2 18:36:59 2021 +0300
Add KV test.
---
.../internal/table/KeyValueViewOperationsTest.java | 572 +++++++++++++++++++++
1 file changed, 572 insertions(+)
diff --git a/modules/table/src/test/java/org/apache/ignite/internal/table/KeyValueViewOperationsTest.java b/modules/table/src/test/java/org/apache/ignite/internal/table/KeyValueViewOperationsTest.java
new file mode 100644
index 0000000..ad7fdbf
--- /dev/null
+++ b/modules/table/src/test/java/org/apache/ignite/internal/table/KeyValueViewOperationsTest.java
@@ -0,0 +1,572 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.table;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Random;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import org.apache.ignite.internal.schema.Column;
+import org.apache.ignite.internal.schema.NativeTypeSpec;
+import org.apache.ignite.internal.schema.NativeTypes;
+import org.apache.ignite.internal.schema.SchemaDescriptor;
+import org.apache.ignite.internal.schema.SchemaTestUtils;
+import org.apache.ignite.internal.table.impl.DummyInternalTableImpl;
+import org.apache.ignite.internal.table.impl.DummySchemaManagerImpl;
+import org.apache.ignite.internal.testframework.IgniteTestUtils;
+import org.apache.ignite.table.KeyValueView;
+import org.apache.ignite.table.mapper.Mapper;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.ignite.internal.schema.NativeTypes.BYTES;
+import static org.apache.ignite.internal.schema.NativeTypes.DATE;
+import static org.apache.ignite.internal.schema.NativeTypes.DOUBLE;
+import static org.apache.ignite.internal.schema.NativeTypes.FLOAT;
+import static org.apache.ignite.internal.schema.NativeTypes.INT16;
+import static org.apache.ignite.internal.schema.NativeTypes.INT32;
+import static org.apache.ignite.internal.schema.NativeTypes.INT64;
+import static org.apache.ignite.internal.schema.NativeTypes.INT8;
+import static org.apache.ignite.internal.schema.NativeTypes.STRING;
+import static org.apache.ignite.internal.schema.NativeTypes.datetime;
+import static org.apache.ignite.internal.schema.NativeTypes.time;
+import static org.apache.ignite.internal.schema.NativeTypes.timestamp;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Basic table operations test.
+ * <p>
+ * TODO: IGNITE-14487 Add bulk operations tests.
+ * TODO: IGNITE-14487 Add async operations tests.
+ */
+public class KeyValueViewOperationsTest {
+
+ private final Random rnd = new Random();
+
+ /**
+ *
+ */
+ @Test
+ public void put() {
+ TestKeyObject key = TestKeyObject.randomObject(rnd);
+ TestValueObject obj = TestValueObject.randomObject(rnd);
+ TestValueObject obj2 = TestValueObject.randomObject(rnd);
+ TestValueObject obj3 = TestValueObject.randomObject(rnd);
+
+ KeyValueView<TestKeyObject, TestValueObject> tbl = kvView();
+
+ assertNull(tbl.get(key));
+
+ // Put KV pair.
+ tbl.put(key, obj);
+
+ assertEquals(obj, tbl.get(key));
+ assertEquals(obj, tbl.get(key));
+
+ // Update KV pair.
+ tbl.put(key, obj2);
+
+ assertEquals(obj2, tbl.get(key));
+ assertEquals(obj2, tbl.get(key));
+
+ // Remove KV pair.
+ tbl.put(key, null);
+
+ assertNull(tbl.get(key));
+
+ // Put KV pair.
+ tbl.put(key, obj3);
+ assertEquals(obj3, tbl.get(key));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void putIfAbsent() {
+ TestKeyObject key = TestKeyObject.randomObject(rnd);
+ TestValueObject obj = TestValueObject.randomObject(rnd);
+ TestValueObject obj2 = TestValueObject.randomObject(rnd);
+
+ KeyValueView<TestKeyObject, TestValueObject> tbl = kvView();
+
+ assertNull(tbl.get(key));
+
+ // Insert new KV pair.
+ assertTrue(tbl.putIfAbsent(key, obj));
+
+ assertEquals(obj, tbl.get(key));
+
+ // Update KV pair.
+ assertFalse(tbl.putIfAbsent(key, obj2));
+
+ assertEquals(obj, tbl.get(key));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void getAndPut() {
+ TestKeyObject key = TestKeyObject.randomObject(rnd);
+ TestValueObject obj = TestValueObject.randomObject(rnd);
+ TestValueObject obj2 = TestValueObject.randomObject(rnd);
+ TestValueObject obj3 = TestValueObject.randomObject(rnd);
+
+ KeyValueView<TestKeyObject, TestValueObject> tbl = kvView();
+
+ assertNull(tbl.get(key));
+
+ // Insert new tuple.
+ assertNull(tbl.getAndPut(key, obj));
+
+ assertEquals(obj, tbl.get(key));
+
+ assertEquals(obj, tbl.getAndPut(key, obj2));
+ assertEquals(obj2, tbl.getAndPut(key, obj3));
+
+ assertEquals(obj3, tbl.get(key));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void contains() {
+ TestKeyObject key = TestKeyObject.randomObject(rnd);
+ TestKeyObject key2 = TestKeyObject.randomObject(rnd);
+ TestValueObject obj = TestValueObject.randomObject(rnd);
+ TestValueObject obj2 = TestValueObject.randomObject(rnd);
+
+ KeyValueView<TestKeyObject, TestValueObject> tbl = kvView();
+
+ // Not-existed value.
+ assertFalse(tbl.contains(key));
+
+ // Put KV pair.
+ tbl.put(key, obj);
+ assertTrue(tbl.contains(key));
+
+ // Delete key.
+ assertTrue(tbl.remove(key));
+ assertFalse(tbl.contains(key));
+
+ // Put KV pair.
+ tbl.put(key, obj2);
+ assertTrue(tbl.contains(key));
+
+ // Delete key.
+ tbl.remove(key2);
+ assertFalse(tbl.contains(key2));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void remove() {
+ TestKeyObject key = TestKeyObject.randomObject(rnd);
+ TestKeyObject key2 = TestKeyObject.randomObject(rnd);
+ TestValueObject obj = TestValueObject.randomObject(rnd);
+ TestValueObject obj2 = TestValueObject.randomObject(rnd);
+
+ KeyValueView<TestKeyObject, TestValueObject> tbl = kvView();
+
+ // Put KV pair.
+ tbl.put(key, obj);
+
+ // Delete existed key.
+ assertEquals(obj, tbl.get(key));
+ assertTrue(tbl.remove(key));
+ assertNull(tbl.get(key));
+
+ // Delete already deleted key.
+ assertFalse(tbl.remove(key));
+
+ // Put KV pair.
+ tbl.put(key, obj2);
+ assertEquals(obj2, tbl.get(key));
+
+ // Delete existed key.
+ assertTrue(tbl.remove(key));
+ assertNull(tbl.get(key));
+
+ // Delete not existed key.
+ assertNull(tbl.get(key2));
+ assertFalse(tbl.remove(key2));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void removeExact() {
+ TestKeyObject key = TestKeyObject.randomObject(rnd);
+ TestKeyObject key2 = TestKeyObject.randomObject(rnd);
+ TestValueObject obj = TestValueObject.randomObject(rnd);
+ TestValueObject obj2 = TestValueObject.randomObject(rnd);
+
+ KeyValueView<TestKeyObject, TestValueObject> tbl = kvView();
+
+ // Put KV pair.
+ tbl.put(key, obj);
+ assertEquals(obj, tbl.get(key));
+
+ // Fails to delete KV pair with unexpected value.
+ assertFalse(tbl.remove(key, obj2));
+ assertEquals(obj, tbl.get(key));
+
+ // Delete KV pair with expected value.
+ assertTrue(tbl.remove(key, obj));
+ assertNull(tbl.get(key));
+
+ // Once again.
+ assertFalse(tbl.remove(key, obj));
+ assertNull(tbl.get(key));
+
+ // Try to remove non-existed key.
+ assertFalse(tbl.remove(key, obj));
+ assertNull(tbl.get(key));
+
+ // Put KV pair.
+ tbl.put(key, obj2);
+ assertEquals(obj2, tbl.get(key));
+
+ // Check null value ignored.
+ assertThrows(Throwable.class, () -> tbl.remove(key, null));
+ assertEquals(obj2, tbl.get(key));
+
+ // Delete KV pair with expected value.
+ assertTrue(tbl.remove(key, obj2));
+ assertNull(tbl.get(key));
+
+ assertFalse(tbl.remove(key2, obj2));
+ assertNull(tbl.get(key2));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void replace() {
+ TestKeyObject key = TestKeyObject.randomObject(rnd);
+ TestKeyObject key2 = TestKeyObject.randomObject(rnd);
+ TestValueObject obj = TestValueObject.randomObject(rnd);
+ TestValueObject obj2 = TestValueObject.randomObject(rnd);
+ TestValueObject obj3 = TestValueObject.randomObject(rnd);
+
+ KeyValueView<TestKeyObject, TestValueObject> tbl = kvView();
+
+ // Ignore replace operation for non-existed KV pair.
+ assertFalse(tbl.replace(key, obj));
+ assertNull(tbl.get(key));
+
+ tbl.put(key, obj);
+
+ // Replace existed KV pair.
+ assertTrue(tbl.replace(key, obj2));
+ assertEquals(obj2, tbl.get(key));
+
+ // Remove existed KV pair.
+ assertTrue(tbl.replace(key, null));
+ assertNull(tbl.get(key));
+
+ // Ignore replace operation for non-existed KV pair.
+ assertFalse(tbl.replace(key, obj3));
+ assertNull(tbl.get(key));
+
+ tbl.put(key, obj3);
+ assertEquals(obj3, tbl.get(key));
+
+ // Remove non-existed KV pair.
+ assertFalse(tbl.replace(key2, null));
+ assertNull(tbl.get(key2));
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void replaceExact() {
+ TestKeyObject key = TestKeyObject.randomObject(rnd);
+ TestKeyObject key2 = TestKeyObject.randomObject(rnd);
+ TestValueObject obj = TestValueObject.randomObject(rnd);
+ TestValueObject obj2 = TestValueObject.randomObject(rnd);
+ TestValueObject obj3 = TestValueObject.randomObject(rnd);
+
+ KeyValueView<TestKeyObject, TestValueObject> tbl = kvView();
+
+ // Insert KV pair.
+ assertTrue(tbl.replace(key, null, obj));
+ assertEquals(obj, tbl.get(key));
+ assertNull(tbl.get(key2));
+
+ // Ignore replace operation for non-existed KV pair.
+ assertFalse(tbl.replace(key2, obj, obj2));
+ assertNull(tbl.get(key2));
+
+ // Replace existed KV pair.
+ assertTrue(tbl.replace(key, obj, obj2));
+ assertEquals(obj2, tbl.get(key));
+
+ // Remove existed KV pair.
+ assertTrue(tbl.replace(key, obj2, null));
+ assertNull(tbl.get(key));
+
+ // Insert KV pair.
+ assertTrue(tbl.replace(key, null, obj3));
+ assertEquals(obj3, tbl.get(key));
+
+ // Remove non-existed KV pair.
+ assertTrue(tbl.replace(key2, null, null));
+ }
+
+ /**
+ * @return Key-value view.
+ */
+ private KeyValueViewImpl<TestKeyObject, TestValueObject> kvView() {
+ Mapper<TestKeyObject> keyMapper = () -> TestKeyObject.class;
+ Mapper<TestValueObject> valMapper = () -> TestValueObject.class;
+
+ Column[] valCols = {
+ new Column("pByteCol", INT8, false),
+ new Column("pShortCol", INT16, false),
+ new Column("pIntCol", INT32, false),
+ new Column("pLongCol", INT64, false),
+ new Column("pFloatCol", FLOAT, false),
+ new Column("pDoubleCol", DOUBLE, false),
+
+ new Column("byteCol", INT8, true),
+ new Column("shortCol", INT16, true),
+ new Column("intCol", INT32, true),
+ new Column("longCol", INT64, true),
+ new Column("nullLongCol", INT64, true),
+ new Column("floatCol", FLOAT, true),
+ new Column("doubleCol", DOUBLE, true),
+
+ new Column("dateCol", DATE, true),
+ new Column("timeCol", time(), true),
+ new Column("dateTimeCol", datetime(), true),
+ new Column("timestampCol", timestamp(), true),
+
+ new Column("uuidCol", NativeTypes.UUID, true),
+ new Column("bitmaskCol", NativeTypes.bitmaskOf(42), true),
+ new Column("stringCol", STRING, true),
+ new Column("nullBytesCol", BYTES, true),
+ new Column("bytesCol", BYTES, true),
+ new Column("numberCol", NativeTypes.numberOf(12), true),
+ new Column("decimalCol", NativeTypes.decimalOf(19, 3), true),
+ };
+
+ SchemaDescriptor schema = new SchemaDescriptor(
+ 1,
+ new Column[] {new Column("id", NativeTypes.INT64, false)},
+ valCols
+ );
+
+ Set<NativeTypeSpec> testedTypes = Arrays.stream(valCols).map(c -> c.type().spec()).collect(Collectors.toSet());
+ Set<NativeTypeSpec> missedTypes = Arrays.stream(NativeTypeSpec.values()).filter(t -> !testedTypes.contains(t)).collect(Collectors.toSet());
+
+ assertEquals(Collections.emptySet(), missedTypes);
+
+ return new KeyValueViewImpl<>(
+ new DummyInternalTableImpl(),
+ new DummySchemaManagerImpl(schema),
+ keyMapper,
+ valMapper,
+ null
+ );
+ }
+
+ /**
+ * Test object.
+ */
+ @SuppressWarnings("InstanceVariableMayNotBeInitialized")
+ public static class TestKeyObject {
+ public static TestKeyObject randomObject(Random rnd) {
+ return new TestKeyObject(rnd.nextLong());
+ }
+
+ private long id;
+
+ private TestKeyObject() {
+ }
+
+ public TestKeyObject(long id) {
+ this.id = id;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TestKeyObject that = (TestKeyObject)o;
+ return id == that.id;
+ }
+
+ @Override public int hashCode() {
+ return Objects.hash(id);
+ }
+ }
+
+ /**
+ * Test object.
+ */
+ @SuppressWarnings("InstanceVariableMayNotBeInitialized")
+ public static class TestValueObject {
+ /**
+ * @return Random TestObject.
+ */
+ public static TestValueObject randomObject(Random rnd) {
+ final TestValueObject obj = new TestValueObject();
+
+ obj.pByteCol = (byte)rnd.nextInt(255);
+ obj.pShortCol = (short)rnd.nextInt(65535);
+ obj.pIntCol = rnd.nextInt();
+ obj.pLongCol = rnd.nextLong();
+ obj.pFloatCol = rnd.nextFloat();
+ obj.pDoubleCol = rnd.nextDouble();
+
+ obj.byteCol = (byte)rnd.nextInt(255);
+ obj.shortCol = (short)rnd.nextInt(65535);
+ obj.intCol = rnd.nextInt();
+ obj.longCol = rnd.nextLong();
+ obj.floatCol = rnd.nextFloat();
+ obj.doubleCol = rnd.nextDouble();
+ obj.nullLongCol = null;
+
+ obj.nullBytesCol = null;
+ obj.uuidCol = new UUID(rnd.nextLong(), rnd.nextLong());
+ obj.bitmaskCol = IgniteTestUtils.randomBitSet(rnd, 42);
+
+ obj.dateCol = (LocalDate)SchemaTestUtils.generateRandomValue(rnd, DATE);
+ obj.timeCol = (LocalTime)SchemaTestUtils.generateRandomValue(rnd, NativeTypes.time());
+ obj.dateTimeCol = (LocalDateTime)SchemaTestUtils.generateRandomValue(rnd, NativeTypes.datetime());
+ obj.timestampCol = (Instant)SchemaTestUtils.generateRandomValue(rnd, NativeTypes.timestamp());
+
+ obj.stringCol = IgniteTestUtils.randomString(rnd, rnd.nextInt(255));
+ obj.bytesCol = IgniteTestUtils.randomBytes(rnd, rnd.nextInt(255));
+ obj.numberCol = (BigInteger)SchemaTestUtils.generateRandomValue(rnd, NativeTypes.numberOf(12));
+ obj.decimalCol = (BigDecimal)SchemaTestUtils.generateRandomValue(rnd, NativeTypes.decimalOf(19, 3));
+
+ return obj;
+ }
+
+ // Primitive typed
+ private byte pByteCol;
+
+ private short pShortCol;
+
+ private int pIntCol;
+
+ private long pLongCol;
+
+ private float pFloatCol;
+
+ private double pDoubleCol;
+
+ // Reference typed
+ private Byte byteCol;
+
+ private Short shortCol;
+
+ private Integer intCol;
+
+ private Long longCol;
+
+ private Long nullLongCol;
+
+ private Float floatCol;
+
+ private Double doubleCol;
+
+ private UUID uuidCol;
+
+ private LocalTime timeCol;
+
+ private LocalDate dateCol;
+
+ private LocalDateTime dateTimeCol;
+
+ private Instant timestampCol;
+
+ private BitSet bitmaskCol;
+
+ private String stringCol;
+
+ private byte[] bytesCol;
+
+ private byte[] nullBytesCol;
+
+ private BigInteger numberCol;
+
+ private BigDecimal decimalCol;
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ TestValueObject object = (TestValueObject)o;
+
+ return pByteCol == object.pByteCol &&
+ pShortCol == object.pShortCol &&
+ pIntCol == object.pIntCol &&
+ pLongCol == object.pLongCol &&
+ Float.compare(object.pFloatCol, pFloatCol) == 0 &&
+ Double.compare(object.pDoubleCol, pDoubleCol) == 0 &&
+ Objects.equals(byteCol, object.byteCol) &&
+ Objects.equals(shortCol, object.shortCol) &&
+ Objects.equals(intCol, object.intCol) &&
+ Objects.equals(longCol, object.longCol) &&
+ Objects.equals(nullLongCol, object.nullLongCol) &&
+ Objects.equals(floatCol, object.floatCol) &&
+ Objects.equals(doubleCol, object.doubleCol) &&
+ Objects.equals(dateCol, object.dateCol) &&
+ Objects.equals(timeCol, object.timeCol) &&
+ Objects.equals(timestampCol, object.timestampCol) &&
+ Objects.equals(dateTimeCol, object.dateTimeCol) &&
+ Objects.equals(uuidCol, object.uuidCol) &&
+ Objects.equals(bitmaskCol, object.bitmaskCol) &&
+ Objects.equals(stringCol, object.stringCol) &&
+ Arrays.equals(bytesCol, object.bytesCol) &&
+ Objects.equals(numberCol, object.numberCol) &&
+ Objects.equals(decimalCol, object.decimalCol);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return 73;
+ }
+ }
+}