Search in sources :

Example 1 with BadKeyVersionException

use of io.pravega.client.tables.BadKeyVersionException in project pravega by pravega.

the class KeyValueTableTestBase method testNoSecondaryKeys.

/**
 * Tests functionality without secondary keys. Only single-key operations are tested because we cannot do multi-key
 * operations using different primary keys.
 * @throws Exception If an error occurred.
 */
@Test
public void testNoSecondaryKeys() throws Exception {
    val entryCount = getPrimaryKeyCount();
    val config = KeyValueTableConfiguration.builder().partitionCount(DEFAULT_SEGMENT_COUNT).primaryKeyLength(16).secondaryKeyLength(// No Secondary Keys.
    0).build();
    val rnd = new Random(0);
    @Cleanup val kvt = createKeyValueTable(new KeyValueTableInfo("Scope", "KVTNoSecondaryKeys"), config);
    List<ByteBuffer> keys = IntStream.range(0, entryCount).mapToObj(i -> {
        val keyData = new byte[config.getPrimaryKeyLength()];
        rnd.nextBytes(keyData);
        return ByteBuffer.wrap(keyData).asReadOnlyBuffer();
    }).collect(Collectors.toList());
    // Insertions.
    val iteration = new AtomicInteger(0);
    val versions = new HashMap<ByteBuffer, Version>();
    for (ByteBuffer k : keys) {
        Version v = kvt.update(new Insert(new TableKey(k), getValue(k, iteration.get()))).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
        versions.put(k, v);
        AssertExtensions.assertSuppliedFutureThrows("Conditional insert did not fail for existing key.", () -> kvt.update(new Insert(new TableKey(k), getValue(k, iteration.get()))), ex -> ex instanceof BadKeyVersionException);
    }
    checkValues(iteration.get(), versions, kvt);
    // Updates.
    iteration.incrementAndGet();
    for (ByteBuffer k : keys) {
        Version v = versions.get(k);
        long pkValue = Math.abs(PK_SERIALIZER.deserialize(k));
        Put p = pkValue % 2 == 0 ? new Put(new TableKey(k), getValue(k, iteration.get()), v) : new Put(new TableKey(k), getValue(k, iteration.get()));
        v = kvt.update(p).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
        versions.put(k, v);
    }
    checkValues(iteration.get(), versions, kvt);
    // Removals.
    iteration.incrementAndGet();
    for (ByteBuffer k : keys) {
        Version v = versions.get(k);
        long pkValue = Math.abs(PK_SERIALIZER.deserialize(k));
        Remove r = pkValue % 2 == 0 ? new Remove(new TableKey(k), v) : new Remove(new TableKey(k));
        kvt.update(r).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
        versions.put(k, null);
    }
    checkValues(iteration.get(), versions, kvt);
}
Also used : lombok.val(lombok.val) Insert(io.pravega.client.tables.Insert) IntStream(java.util.stream.IntStream) Put(io.pravega.client.tables.Put) Getter(lombok.Getter) AssertExtensions(io.pravega.test.common.AssertExtensions) Cleanup(lombok.Cleanup) HashMap(java.util.HashMap) Random(java.util.Random) KeyValueTableConfiguration(io.pravega.client.tables.KeyValueTableConfiguration) BitConverter(io.pravega.common.util.BitConverter) Function(java.util.function.Function) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) AccessLevel(lombok.AccessLevel) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) KeyValueTableInfo(io.pravega.client.admin.KeyValueTableInfo) Duration(java.time.Duration) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) Timeout(org.junit.rules.Timeout) Nullable(javax.annotation.Nullable) Before(org.junit.Before) Serializer(io.pravega.client.stream.Serializer) LeakDetectorTestSuite(io.pravega.test.common.LeakDetectorTestSuite) TableEntry(io.pravega.client.tables.TableEntry) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) lombok.val(lombok.val) Test(org.junit.Test) Collectors(java.util.stream.Collectors) Version(io.pravega.client.tables.Version) TimeUnit(java.util.concurrent.TimeUnit) TableModification(io.pravega.client.tables.TableModification) List(java.util.List) Rule(org.junit.Rule) KeyValueTable(io.pravega.client.tables.KeyValueTable) TableKey(io.pravega.client.tables.TableKey) Assert(org.junit.Assert) BadKeyVersionException(io.pravega.client.tables.BadKeyVersionException) Remove(io.pravega.client.tables.Remove) BadKeyVersionException(io.pravega.client.tables.BadKeyVersionException) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) TableKey(io.pravega.client.tables.TableKey) Remove(io.pravega.client.tables.Remove) Insert(io.pravega.client.tables.Insert) Cleanup(lombok.Cleanup) ByteBuffer(java.nio.ByteBuffer) KeyValueTableInfo(io.pravega.client.admin.KeyValueTableInfo) Put(io.pravega.client.tables.Put) Random(java.util.Random) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Version(io.pravega.client.tables.Version) Test(org.junit.Test)

Example 2 with BadKeyVersionException

use of io.pravega.client.tables.BadKeyVersionException in project pravega by pravega.

the class KeyValueTableTestBase method testSingleKeyUnconditionalRemovals.

/**
 * Tests the ability to perform single-key updates and removals (conditional and unconditional). These methods are exercised:
 * - {@link KeyValueTable#update} with {@link Put} instances and with {@link Remove} instances.
 * - {@link KeyValueTable#get} and {@link KeyValueTable#getAll}
 */
@Test
public void testSingleKeyUnconditionalRemovals() {
    val versions = new Versions();
    @Cleanup val kvt = createKeyValueTable();
    // Put (unconditional update).
    val iteration = new AtomicInteger(0);
    forEveryKey((pk, sk) -> {
        val value = getValue(pk, sk, iteration.get());
        Version kv = kvt.update(new Put(new TableKey(pk, sk), value)).join();
        versions.add(getUniqueKeyId(pk, sk), kv);
    });
    // Remove (both conditional and unconditional)
    iteration.incrementAndGet();
    forEveryKey((pk, sk) -> {
        val keyId = getUniqueKeyId(pk, sk);
        val existingVersion = versions.get(keyId);
        // Verify that conditions are checked both for segment names and their versions.
        val pkValue = Math.abs(PK_SERIALIZER.deserialize(pk));
        boolean conditional = pkValue % 2 == 0;
        if (conditional) {
            // First check that a bad version will be checked.
            Version badVersion = alterVersion(existingVersion, pkValue % 4 == 0, pkValue % 4 != 0);
            AssertExtensions.assertSuppliedFutureThrows("update(Remove) did not throw for bad version.", () -> kvt.update(new Remove(new TableKey(pk, sk), badVersion)), ex -> ex instanceof BadKeyVersionException);
            // Remove it.
            kvt.update(new Remove(new TableKey(pk, sk), existingVersion)).join();
        } else {
            kvt.update(new Remove(new TableKey(pk, sk))).join();
        }
        versions.remove(keyId);
    });
    Assert.assertTrue("Expected all keys to have been removed.", versions.isEmpty());
    checkValues(iteration.get(), versions, kvt);
    // Re-insert (conditionally).
    iteration.incrementAndGet();
    forEveryKey((pk, sk) -> {
        val value = getValue(pk, sk, iteration.get());
        // First one should work.
        Version kv = kvt.update(new Insert(new TableKey(pk, sk), value)).join();
        versions.add(getUniqueKeyId(pk, sk), kv);
    });
    checkValues(iteration.get(), versions, kvt);
}
Also used : lombok.val(lombok.val) BadKeyVersionException(io.pravega.client.tables.BadKeyVersionException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Version(io.pravega.client.tables.Version) TableKey(io.pravega.client.tables.TableKey) Remove(io.pravega.client.tables.Remove) Insert(io.pravega.client.tables.Insert) Cleanup(lombok.Cleanup) Put(io.pravega.client.tables.Put) Test(org.junit.Test)

Example 3 with BadKeyVersionException

use of io.pravega.client.tables.BadKeyVersionException in project pravega by pravega.

the class KeyValueTableTestBase method testMultiKeyOperations.

/**
 * Tests the ability to perform multi-key updates, replacements and removals. These methods should be exercised:
 * - {@link KeyValueTable#update(Iterable)} with {@link Insert} and {@link Put} instances.
 * - {@link KeyValueTable#update(Iterable)} with {@link Remove}.
 * - {@link KeyValueTable#getAll}
 */
@Test
public void testMultiKeyOperations() {
    val versions = new Versions();
    @Cleanup val kvt = createKeyValueTable();
    // Conditional Insert.
    val iteration = new AtomicInteger(0);
    forEveryPrimaryKey((pk, secondaryKeys) -> {
        List<TableModification> inserts = secondaryKeys.stream().map(sk -> new Insert(new TableKey(pk, sk), getValue(pk, sk, iteration.get()))).collect(Collectors.toList());
        val keyVersions = kvt.update(inserts).join();
        val hint = getUniqueKeyId(pk);
        Assert.assertEquals("Unexpected result size" + hint, inserts.size(), keyVersions.size());
        for (int i = 0; i < inserts.size(); i++) {
            versions.add(getUniqueKeyId(pk, inserts.get(i).getKey().getSecondaryKey()), keyVersions.get(i));
        }
    });
    checkValues(iteration.get(), versions, kvt);
    // Unconditional update.
    iteration.incrementAndGet();
    forEveryPrimaryKey((pk, secondaryKeys) -> {
        List<TableModification> puts = secondaryKeys.stream().map(sk -> new Put(new TableKey(pk, sk), getValue(pk, sk, iteration.get()))).collect(Collectors.toList());
        val keyVersions = kvt.update(puts).join();
        val hint = getUniqueKeyId(pk);
        Assert.assertEquals("Unexpected result size" + hint, puts.size(), keyVersions.size());
        for (int i = 0; i < puts.size(); i++) {
            versions.add(getUniqueKeyId(pk, puts.get(i).getKey().getSecondaryKey()), keyVersions.get(i));
        }
    });
    checkValues(iteration.get(), versions, kvt);
    // Conditional replace.
    iteration.incrementAndGet();
    forEveryPrimaryKey((pk, secondaryKeys) -> {
        // Failed update (bad version).
        val pkValue = Math.abs(PK_SERIALIZER.deserialize(pk));
        List<TableModification> badPuts = secondaryKeys.stream().map(sk -> new Put(new TableKey(pk, sk), getValue(pk, sk, iteration.get()), alterVersion(versions.get(getUniqueKeyId(pk, sk)), pkValue % 2 == 0, pkValue % 2 == 1))).collect(Collectors.toList());
        AssertExtensions.assertSuppliedFutureThrows("update(Put) did not throw for bad version.", () -> kvt.update(badPuts), ex -> ex instanceof BadKeyVersionException);
        // Correct update.
        List<TableModification> puts = secondaryKeys.stream().map(sk -> new Put(new TableKey(pk, sk), getValue(pk, sk, iteration.get()), versions.get(getUniqueKeyId(pk, sk)))).collect(Collectors.toList());
        val keyVersions = kvt.update(puts).join();
        val hint = getUniqueKeyId(pk);
        Assert.assertEquals("Unexpected result size" + hint, puts.size(), keyVersions.size());
        for (int i = 0; i < puts.size(); i++) {
            versions.add(getUniqueKeyId(pk, puts.get(i).getKey().getSecondaryKey()), keyVersions.get(i));
        }
    });
    checkValues(iteration.get(), versions, kvt);
    // Conditional removal.
    iteration.incrementAndGet();
    forEveryPrimaryKey((pk, secondaryKeys) -> {
        val hint = getUniqueKeyId(pk);
        // Failed update (bad version).
        val pkValue = Math.abs(PK_SERIALIZER.deserialize(pk));
        List<TableModification> badRemovals = secondaryKeys.stream().map(sk -> new Remove(new TableKey(pk, sk), alterVersion(versions.get(getUniqueKeyId(pk, sk)), pkValue % 2 == 0, pkValue % 2 == 1))).collect(Collectors.toList());
        AssertExtensions.assertSuppliedFutureThrows("update(Remove) did not throw for bad version." + hint, () -> kvt.update(badRemovals), ex -> ex instanceof BadKeyVersionException);
        // Correct update.
        List<TableModification> removals = secondaryKeys.stream().map(sk -> new Remove(new TableKey(pk, sk), versions.get(getUniqueKeyId(pk, sk)))).collect(Collectors.toList());
        kvt.update(removals).join();
        for (val sk : secondaryKeys) {
            versions.remove(getUniqueKeyId(pk, sk));
        }
    });
    Assert.assertTrue("Expected all keys to have been removed.", versions.isEmpty());
    checkValues(iteration.get(), versions, kvt);
    // Reinsert (conditionally)
    iteration.incrementAndGet();
    forEveryPrimaryKey((pk, secondaryKeys) -> {
        val hint = getUniqueKeyId(pk);
        List<TableModification> entries = secondaryKeys.stream().map(sk -> new Insert(new TableKey(pk, sk), getValue(pk, sk, iteration.get()))).collect(Collectors.toList());
        val keyVersions = kvt.update(entries).join();
        Assert.assertEquals("Unexpected result size" + hint, entries.size(), keyVersions.size());
        for (int i = 0; i < entries.size(); i++) {
            versions.add(getUniqueKeyId(pk, entries.get(i).getKey().getSecondaryKey()), keyVersions.get(i));
        }
    });
    checkValues(iteration.get(), versions, kvt);
}
Also used : lombok.val(lombok.val) Insert(io.pravega.client.tables.Insert) IntStream(java.util.stream.IntStream) Put(io.pravega.client.tables.Put) Getter(lombok.Getter) AssertExtensions(io.pravega.test.common.AssertExtensions) Cleanup(lombok.Cleanup) HashMap(java.util.HashMap) Random(java.util.Random) KeyValueTableConfiguration(io.pravega.client.tables.KeyValueTableConfiguration) BitConverter(io.pravega.common.util.BitConverter) Function(java.util.function.Function) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) AccessLevel(lombok.AccessLevel) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) KeyValueTableInfo(io.pravega.client.admin.KeyValueTableInfo) Duration(java.time.Duration) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) Timeout(org.junit.rules.Timeout) Nullable(javax.annotation.Nullable) Before(org.junit.Before) Serializer(io.pravega.client.stream.Serializer) LeakDetectorTestSuite(io.pravega.test.common.LeakDetectorTestSuite) TableEntry(io.pravega.client.tables.TableEntry) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) lombok.val(lombok.val) Test(org.junit.Test) Collectors(java.util.stream.Collectors) Version(io.pravega.client.tables.Version) TimeUnit(java.util.concurrent.TimeUnit) TableModification(io.pravega.client.tables.TableModification) List(java.util.List) Rule(org.junit.Rule) KeyValueTable(io.pravega.client.tables.KeyValueTable) TableKey(io.pravega.client.tables.TableKey) Assert(org.junit.Assert) BadKeyVersionException(io.pravega.client.tables.BadKeyVersionException) Remove(io.pravega.client.tables.Remove) BadKeyVersionException(io.pravega.client.tables.BadKeyVersionException) TableModification(io.pravega.client.tables.TableModification) TableKey(io.pravega.client.tables.TableKey) Remove(io.pravega.client.tables.Remove) Insert(io.pravega.client.tables.Insert) Cleanup(lombok.Cleanup) Put(io.pravega.client.tables.Put) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Test(org.junit.Test)

Example 4 with BadKeyVersionException

use of io.pravega.client.tables.BadKeyVersionException in project pravega by pravega.

the class KeyValueTableTestBase method testSingleKeyConditionalInserts.

/**
 * Tests the ability to perform single-key conditional insertions. These methods are exercised:
 * - {@link KeyValueTable#update} with {@link Insert} instances.
 * - {@link KeyValueTable#get} and {@link KeyValueTable#getAll}.
 */
@Test
public void testSingleKeyConditionalInserts() {
    val versions = new Versions();
    @Cleanup val kvt = createKeyValueTable();
    // Put (conditional insert)
    val iteration = new AtomicInteger(0);
    forEveryKey((pk, sk) -> {
        val value = getValue(pk, sk, iteration.get());
        // First one should work.
        val insert = new Insert(new TableKey(pk, sk), value);
        Version kv = kvt.update(insert).join();
        versions.add(getUniqueKeyId(pk, sk), kv);
        // Second one should throw.
        AssertExtensions.assertSuppliedFutureThrows("insert() did not throw for already existing key.", () -> kvt.update(insert), ex -> ex instanceof BadKeyVersionException);
    });
    checkValues(iteration.get(), versions, kvt);
}
Also used : lombok.val(lombok.val) BadKeyVersionException(io.pravega.client.tables.BadKeyVersionException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Version(io.pravega.client.tables.Version) TableKey(io.pravega.client.tables.TableKey) Insert(io.pravega.client.tables.Insert) Cleanup(lombok.Cleanup) Test(org.junit.Test)

Example 5 with BadKeyVersionException

use of io.pravega.client.tables.BadKeyVersionException in project pravega by pravega.

the class KeyValueTableTestBase method testSingleKeyUpdates.

/**
 * Tests the ability to perform single-key updates and replacements. These methods are exercised:
 * - {@link KeyValueTable#update} with {@link Put} instances.
 * - {@link KeyValueTable#get} and {@link KeyValueTable#getAll}.
 */
@Test
public void testSingleKeyUpdates() {
    val versions = new Versions();
    @Cleanup val kvt = createKeyValueTable();
    // Put (unconditional update).
    val iteration = new AtomicInteger(0);
    forEveryKey((pk, sk) -> {
        val value = getValue(pk, sk, iteration.get());
        Version kv = kvt.update(new Put(new TableKey(pk, sk), value)).join();
        versions.add(getUniqueKeyId(pk, sk), kv);
    });
    checkValues(iteration.get(), versions, kvt);
    // Put (conditional update (not insertion)).
    iteration.incrementAndGet();
    forEveryKey((pk, sk) -> {
        val value = getValue(pk, sk, iteration.get());
        val keyId = getUniqueKeyId(pk, sk);
        val existingVersion = versions.get(keyId);
        // Verify that conditions are checked both for segment names and their versions.
        val pkValue = Math.abs(PK_SERIALIZER.deserialize(pk));
        Version badVersion = alterVersion(existingVersion, pkValue % 2 == 0, pkValue % 2 == 1);
        AssertExtensions.assertSuppliedFutureThrows("update(Put-Conditional) did not throw for bad version.", () -> kvt.update(new Put(new TableKey(pk, sk), value, badVersion)), ex -> ex instanceof BadKeyVersionException);
        Version kv = kvt.update(new Put(new TableKey(pk, sk), value, existingVersion)).join();
        versions.add(keyId, kv);
    });
    checkValues(iteration.get(), versions, kvt);
}
Also used : lombok.val(lombok.val) BadKeyVersionException(io.pravega.client.tables.BadKeyVersionException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Version(io.pravega.client.tables.Version) TableKey(io.pravega.client.tables.TableKey) Cleanup(lombok.Cleanup) Put(io.pravega.client.tables.Put) Test(org.junit.Test)

Aggregations

BadKeyVersionException (io.pravega.client.tables.BadKeyVersionException)5 TableKey (io.pravega.client.tables.TableKey)5 Version (io.pravega.client.tables.Version)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 Cleanup (lombok.Cleanup)5 lombok.val (lombok.val)5 Test (org.junit.Test)5 Insert (io.pravega.client.tables.Insert)4 Put (io.pravega.client.tables.Put)4 Remove (io.pravega.client.tables.Remove)3 KeyValueTableInfo (io.pravega.client.admin.KeyValueTableInfo)2 Serializer (io.pravega.client.stream.Serializer)2 KeyValueTable (io.pravega.client.tables.KeyValueTable)2 KeyValueTableConfiguration (io.pravega.client.tables.KeyValueTableConfiguration)2 TableEntry (io.pravega.client.tables.TableEntry)2 TableModification (io.pravega.client.tables.TableModification)2 BitConverter (io.pravega.common.util.BitConverter)2 AssertExtensions (io.pravega.test.common.AssertExtensions)2 LeakDetectorTestSuite (io.pravega.test.common.LeakDetectorTestSuite)2 ByteBuffer (java.nio.ByteBuffer)2