From faf1d813c28aad0575fcc69ce1d89426d569d8b2 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 28 Nov 2023 09:25:20 -0800 Subject: [PATCH 01/13] Un-Disable 3 tests that pass with recent `JsonTerm` fix --- .../service/operation/model/impl/FindOperationTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/FindOperationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/FindOperationTest.java index 5eee846483..bfdc2b22f1 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/FindOperationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/FindOperationTest.java @@ -869,7 +869,6 @@ public void findWithAllFilter() throws Exception { assertThat(result.errors()).isNullOrEmpty(); } - @Disabled // fails on binding Collection value @Test public void findWithSizeFilter() throws Exception { String collectionReadCql = @@ -934,7 +933,6 @@ public void findWithSizeFilter() throws Exception { assertThat(result.errors()).isNullOrEmpty(); } - @Disabled // fails on binding Map key @Test public void findWithArrayEqualFilter() throws Exception { // Due to trimming of indexes, former "array_equals" moved under "query_text_values": @@ -1030,7 +1028,6 @@ public void findWithArrayEqualFilter() throws Exception { assertThat(result.errors()).isNullOrEmpty(); } - @Disabled // fails on binding Map key @Test public void findWithSubDocEqualFilter() throws Exception { String collectionReadCql = From aebefdc214256b442d44d75b24df72f5134eb1ef Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 28 Nov 2023 09:28:15 -0800 Subject: [PATCH 02/13] mvn fmt:format --- .../jsonapi/service/operation/model/impl/FindOperationTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/FindOperationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/FindOperationTest.java index bfdc2b22f1..540d7e5a26 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/FindOperationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/FindOperationTest.java @@ -43,7 +43,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import java.util.stream.Stream; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; From 27f4d09a35e47227de6753d34e891ed69910b5cf Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 28 Nov 2023 15:39:06 -0800 Subject: [PATCH 03/13] Convert `InsertOperationTest` to use native CQL access --- .../cqldriver/serializer/CQLBindValues.java | 10 +- .../model/impl/InsertOperationTest.java | 128 +++++++++++------- .../model/impl/OperationTestBase.java | 11 +- 3 files changed, 94 insertions(+), 55 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java b/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java index 70acb47410..37d76d107b 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java @@ -30,18 +30,18 @@ public static Set getSetValue(Set from) { return from.stream().map(val -> val.toString()).collect(Collectors.toSet()); } - public static Set getStringSetValue(Set from) { + public static Set getStringSetValue(Set from) { return from.stream().map(val -> val.toString()).collect(Collectors.toSet()); } - public static List getListValue(List from) { + public static List getListValue(List from) { return from.stream().map(val -> val.toString()).collect(Collectors.toList()); } - public static Map getStringMapValues(Map from) { + public static Map getStringMapValues(Map from) { final Map to = new HashMap<>(from.size()); - for (Map.Entry entry : from.entrySet()) { - to.put(entry.getKey().toString(), entry.getValue()); + for (Map.Entry entry : from.entrySet()) { + to.put(entry.getKey().toString(), entry.getValue().toString()); } return to; } diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java index f82237fea7..255e65ed44 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java @@ -2,17 +2,24 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; - +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.datastax.oss.driver.api.core.cql.AsyncResultSet; +import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; +import com.datastax.oss.driver.api.core.cql.Row; +import com.datastax.oss.driver.api.core.cql.SimpleStatement; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.TestProfile; +import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.helpers.test.UniAssertSubscriber; import io.stargate.bridge.grpc.TypeSpecs; import io.stargate.bridge.grpc.Values; import io.stargate.bridge.proto.QueryOuterClass; import io.stargate.sgv2.api.common.config.QueriesConfig; -import io.stargate.sgv2.common.bridge.AbstractValidatingStargateBridgeTest; import io.stargate.sgv2.common.bridge.ValidatingStargateBridge; import io.stargate.sgv2.common.testprofiles.NoGlobalResourcesTestProfile; import io.stargate.sgv2.jsonapi.api.model.command.CommandContext; @@ -22,34 +29,35 @@ import io.stargate.sgv2.jsonapi.exception.JsonApiException; import io.stargate.sgv2.jsonapi.service.cqldriver.executor.CollectionSettings; import io.stargate.sgv2.jsonapi.service.cqldriver.executor.QueryExecutor; +import io.stargate.sgv2.jsonapi.service.cqldriver.serializer.CQLBindValues; import io.stargate.sgv2.jsonapi.service.cqldriver.serializer.CustomValueSerializers; import io.stargate.sgv2.jsonapi.service.shredding.Shredder; import io.stargate.sgv2.jsonapi.service.shredding.model.DocumentId; import io.stargate.sgv2.jsonapi.service.shredding.model.WritableShreddedDocument; +import io.stargate.sgv2.jsonapi.service.testutil.MockAsyncResultSet; +import io.stargate.sgv2.jsonapi.service.testutil.MockRow; import jakarta.inject.Inject; +import java.nio.ByteBuffer; +import java.util.Arrays; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; -import org.apache.commons.lang3.RandomStringUtils; +import java.util.stream.Stream; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @QuarkusTest -@Disabled @TestProfile(NoGlobalResourcesTestProfile.Impl.class) -public class InsertOperationTest extends AbstractValidatingStargateBridgeTest { - private static final String KEYSPACE_NAME = RandomStringUtils.randomAlphanumeric(16); - private static final String COLLECTION_NAME = RandomStringUtils.randomAlphanumeric(16); - private static final CommandContext COMMAND_CONTEXT = - new CommandContext(KEYSPACE_NAME, COLLECTION_NAME); +public class InsertOperationTest extends OperationTestBase { + private final CommandContext COMMAND_CONTEXT = new CommandContext(KEYSPACE_NAME, COLLECTION_NAME); - private static final CommandContext COMMAND_CONTEXT_VECTOR = + private final CommandContext COMMAND_CONTEXT_VECTOR = new CommandContext( KEYSPACE_NAME, COLLECTION_NAME, true, CollectionSettings.SimilarityFunction.COSINE, null); @Inject Shredder shredder; @Inject ObjectMapper objectMapper; - @Inject QueryExecutor queryExecutor; @Inject QueriesConfig queriesConfig; @Nested @@ -87,34 +95,32 @@ public void insertOne() throws Exception { WritableShreddedDocument shredDocument = shredder.shred(jsonNode); String insertCql = INSERT_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); - ValidatingStargateBridge.QueryAssert insertAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument.id())), - Values.of(shredDocument.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues(shredDocument.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returning(List.of(List.of(Values.of(true)))); + SimpleStatement stmt = + SimpleStatement.newInstance( + insertCql, + CQLBindValues.getDocumentIdValue(DocumentId.fromString("doc1")), + shredDocument.docJson(), + CQLBindValues.getStringSetValue(shredDocument.existKeys()), + CQLBindValues.getIntegerMapValues(shredDocument.arraySize()), + shredDocument.arrayContains(), // already Set + CQLBindValues.getBooleanMapValues(shredDocument.queryBoolValues()), + CQLBindValues.getDoubleMapValues(shredDocument.queryNumberValues()), + CQLBindValues.getStringMapValues(shredDocument.queryTextValues()), + CQLBindValues.getSetValue(shredDocument.queryNullValues()), + CQLBindValues.getTimestampMapValues(shredDocument.queryTimestampValues())); + ColumnDefinitions columnDefs = buildColumnDefs(TestColumn.ofBoolean("applied")); + List rows = Arrays.asList(resultRow(columnDefs, 0, Boolean.TRUE)); + AsyncResultSet results = new MockAsyncResultSet(columnDefs, rows, null); + final AtomicInteger callCount = new AtomicInteger(); + QueryExecutor queryExecutor = mock(QueryExecutor.class); + + when(queryExecutor.executeWrite(eq(stmt))) + .then( + invocation -> { + callCount.incrementAndGet(); + return Uni.createFrom().item(results); + }); InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, shredDocument); Supplier execute = operation @@ -125,7 +131,7 @@ public void insertOne() throws Exception { .getItem(); // assert query execution - insertAssert.assertExecuteCount().isOne(); + assertThat(callCount.get()).isEqualTo(1); // then result CommandResult result = execute.get(); @@ -135,6 +141,7 @@ public void insertOne() throws Exception { assertThat(result.errors()).isNull(); } + @Disabled @Test public void insertDuplicate() throws Exception { String doc1 = @@ -185,7 +192,7 @@ public void insertDuplicate() throws Exception { InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, shredDocument); Supplier execute = operation - .execute(queryExecutor) + .execute(queryExecutor0) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() @@ -210,6 +217,7 @@ public void insertDuplicate() throws Exception { }); } + @Disabled @Test public void insertManyOrdered() throws Exception { String document1 = @@ -305,7 +313,7 @@ public void insertManyOrdered() throws Exception { new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), true); Supplier execute = operation - .execute(queryExecutor) + .execute(queryExecutor0) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() @@ -325,6 +333,7 @@ public void insertManyOrdered() throws Exception { assertThat(result.errors()).isNull(); } + @Disabled @Test public void insertManyUnordered() throws Exception { String document1 = @@ -420,7 +429,7 @@ public void insertManyUnordered() throws Exception { new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), false); Supplier execute = operation - .execute(queryExecutor) + .execute(queryExecutor0) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() @@ -442,6 +451,7 @@ public void insertManyUnordered() throws Exception { // failure modes + @Disabled @Test public void failureOrdered() throws Exception { // unordered first query fail @@ -510,7 +520,7 @@ public void failureOrdered() throws Exception { new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), true); Supplier execute = operation - .execute(queryExecutor) + .execute(queryExecutor0) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() @@ -533,6 +543,7 @@ public void failureOrdered() throws Exception { }); } + @Disabled @Test public void failureOrderedLastFails() throws Exception { // unordered first query OK, second fail @@ -629,7 +640,7 @@ public void failureOrderedLastFails() throws Exception { new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), true); Supplier execute = operation - .execute(queryExecutor) + .execute(queryExecutor0) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() @@ -656,6 +667,7 @@ public void failureOrderedLastFails() throws Exception { }); } + @Disabled @Test public void failureUnorderedPartial() throws Exception { // unordered one query fail @@ -752,7 +764,7 @@ public void failureUnorderedPartial() throws Exception { new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), false); Supplier execute = operation - .execute(queryExecutor) + .execute(queryExecutor0) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() @@ -778,6 +790,7 @@ public void failureUnorderedPartial() throws Exception { }); } + @Disabled @Test public void failureUnorderedAll() throws Exception { // unordered both queries fail @@ -874,7 +887,7 @@ public void failureUnorderedAll() throws Exception { new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), false); Supplier execute = operation - .execute(queryExecutor) + .execute(queryExecutor0) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() @@ -896,6 +909,7 @@ public void failureUnorderedAll() throws Exception { "Failed to insert document with _id 'doc2': Ivan really breaks the test."); } + @Disabled @Test public void insertOneVectorSearch() throws Exception { String document = @@ -949,7 +963,7 @@ public void insertOneVectorSearch() throws Exception { InsertOperation operation = new InsertOperation(COMMAND_CONTEXT_VECTOR, shredDocument); Supplier execute = operation - .execute(queryExecutor) + .execute(queryExecutor0) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() @@ -966,6 +980,7 @@ public void insertOneVectorSearch() throws Exception { assertThat(result.errors()).isNull(); } + @Disabled @Test public void insertOneVectorEnabledNoVectorData() throws Exception { String document = @@ -1018,7 +1033,7 @@ public void insertOneVectorEnabledNoVectorData() throws Exception { InsertOperation operation = new InsertOperation(COMMAND_CONTEXT_VECTOR, shredDocument); Supplier execute = operation - .execute(queryExecutor) + .execute(queryExecutor0) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() @@ -1035,6 +1050,7 @@ public void insertOneVectorEnabledNoVectorData() throws Exception { assertThat(result.errors()).isNull(); } + @Disabled @Test public void insertOneVectorDisabledWithVectorData() throws Exception { String document = @@ -1055,10 +1071,24 @@ public void insertOneVectorDisabledWithVectorData() throws Exception { JsonNode jsonNode = objectMapper.readTree(document); WritableShreddedDocument shredDocument = shredder.shred(jsonNode); InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, shredDocument); - Throwable failure = catchThrowable(() -> operation.execute(queryExecutor)); + Throwable failure = catchThrowable(() -> operation.execute(queryExecutor0)); assertThat(failure) .isInstanceOf(JsonApiException.class) .hasFieldOrPropertyWithValue("errorCode", ErrorCode.VECTOR_SEARCH_NOT_SUPPORTED); } } + + private MockRow resultRow(ColumnDefinitions columnDefs, int index, Object... values) { + List buffers = Stream.of(values).map(value -> byteBufferFromAny(value)).toList(); + return new MockRow(columnDefs, index, buffers); + } + + // TEMPORARY ADDITIONS TO COMPILE DURING CONVERSION + + QueryExecutor queryExecutor0 = mock(QueryExecutor.class); + + protected ValidatingStargateBridge.QueryExpectation withQuery( + String cql, QueryOuterClass.Value... values) { + throw new IllegalStateException("No longer supported without Bridge"); + } } diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/OperationTestBase.java b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/OperationTestBase.java index 9cf40ab63a..d65b89ea5e 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/OperationTestBase.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/OperationTestBase.java @@ -16,6 +16,8 @@ import com.datastax.oss.protocol.internal.response.result.RawType; import io.stargate.sgv2.jsonapi.api.model.command.CommandContext; import io.stargate.sgv2.jsonapi.config.constants.DocumentConstants; +import io.stargate.sgv2.jsonapi.service.cqldriver.serializer.CQLBindValues; +import io.stargate.sgv2.jsonapi.service.shredding.model.DocumentId; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; @@ -52,6 +54,10 @@ protected ColumnDefinitions buildColumnDefs( return DefaultColumnDefinitions.valueOf(columnDefs); } + protected ByteBuffer byteBufferFrom(boolean value) { + return TypeCodecs.BOOLEAN.encode(value, ProtocolVersion.DEFAULT); + } + protected ByteBuffer byteBufferFrom(long value) { return TypeCodecs.BIGINT.encode(value, ProtocolVersion.DEFAULT); } @@ -71,6 +77,9 @@ protected ByteBuffer byteBufferFromAny(Object value) { if (value instanceof ByteBuffer) { return (ByteBuffer) value; } + if (value instanceof Boolean) { + return byteBufferFrom((Boolean) value); + } if (value instanceof UUID) { return byteBufferFrom((UUID) value); } @@ -103,7 +112,7 @@ protected ByteBuffer byteBufferForNull() { * @return Bound value to use with {@code SimpleStatement} */ protected TupleValue boundKeyForStatement(String key) { - return DOC_KEY_TYPE.newValue((byte) DocumentConstants.KeyTypeId.TYPE_ID_STRING, key); + return CQLBindValues.getDocumentIdValue(DocumentId.fromString(key)); } protected CqlVector vectorForStatement(Float... value) { From b4380948cf90894795175d4771087017739025e7 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 28 Nov 2023 16:25:00 -0800 Subject: [PATCH 04/13] Convert second test --- .../model/impl/InsertOperationTest.java | 114 ++++++++---------- .../service/testutil/MockAsyncResultSet.java | 2 +- 2 files changed, 52 insertions(+), 64 deletions(-) diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java index 255e65ed44..fc3d41c51a 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java @@ -56,25 +56,27 @@ public class InsertOperationTest extends OperationTestBase { new CommandContext( KEYSPACE_NAME, COLLECTION_NAME, true, CollectionSettings.SimilarityFunction.COSINE, null); + private final ColumnDefinitions COLUMNS_APPLIED = + buildColumnDefs(TestColumn.ofBoolean("[applied]")); + @Inject Shredder shredder; @Inject ObjectMapper objectMapper; @Inject QueriesConfig queriesConfig; - @Nested - class Execute { - - static final String INSERT_CQL = - "INSERT INTO \"%s\".\"%s\"" - + " (key, tx_id, doc_json, exist_keys, array_size, array_contains, query_bool_values, query_dbl_values , query_text_values, query_null_values, query_timestamp_values)" - + " VALUES" - + " (?, now(), ?, ?, ?, ?, ?, ?, ?, ?, ?) IF NOT EXISTS"; + static final String INSERT_CQL = + "INSERT INTO \"%s\".\"%s\"" + + " (key, tx_id, doc_json, exist_keys, array_size, array_contains, query_bool_values, query_dbl_values , query_text_values, query_null_values, query_timestamp_values)" + + " VALUES" + + " (?, now(), ?, ?, ?, ?, ?, ?, ?, ?, ?) IF NOT EXISTS"; - static final String INSERT_VECTOR_CQL = - "INSERT INTO \"%s\".\"%s\"" - + " (key, tx_id, doc_json, exist_keys, array_size, array_contains, query_bool_values, query_dbl_values , query_text_values, query_null_values, query_timestamp_values, query_vector_value)" - + " VALUES" - + " (?, now(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) IF NOT EXISTS"; + static final String INSERT_VECTOR_CQL = + "INSERT INTO \"%s\".\"%s\"" + + " (key, tx_id, doc_json, exist_keys, array_size, array_contains, query_bool_values, query_dbl_values , query_text_values, query_null_values, query_timestamp_values, query_vector_value)" + + " VALUES" + + " (?, now(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) IF NOT EXISTS"; + @Nested + class Execute { @Test public void insertOne() throws Exception { String document = @@ -94,33 +96,19 @@ public void insertOne() throws Exception { JsonNode jsonNode = objectMapper.readTree(document); WritableShreddedDocument shredDocument = shredder.shred(jsonNode); - String insertCql = INSERT_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); - - SimpleStatement stmt = - SimpleStatement.newInstance( - insertCql, - CQLBindValues.getDocumentIdValue(DocumentId.fromString("doc1")), - shredDocument.docJson(), - CQLBindValues.getStringSetValue(shredDocument.existKeys()), - CQLBindValues.getIntegerMapValues(shredDocument.arraySize()), - shredDocument.arrayContains(), // already Set - CQLBindValues.getBooleanMapValues(shredDocument.queryBoolValues()), - CQLBindValues.getDoubleMapValues(shredDocument.queryNumberValues()), - CQLBindValues.getStringMapValues(shredDocument.queryTextValues()), - CQLBindValues.getSetValue(shredDocument.queryNullValues()), - CQLBindValues.getTimestampMapValues(shredDocument.queryTimestampValues())); - ColumnDefinitions columnDefs = buildColumnDefs(TestColumn.ofBoolean("applied")); - List rows = Arrays.asList(resultRow(columnDefs, 0, Boolean.TRUE)); - AsyncResultSet results = new MockAsyncResultSet(columnDefs, rows, null); + SimpleStatement insertStmt = nonVectorInsertStatement(shredDocument); + List rows = Arrays.asList(resultRow(COLUMNS_APPLIED, 0, Boolean.TRUE)); + AsyncResultSet results = new MockAsyncResultSet(COLUMNS_APPLIED, rows, null); final AtomicInteger callCount = new AtomicInteger(); QueryExecutor queryExecutor = mock(QueryExecutor.class); - when(queryExecutor.executeWrite(eq(stmt))) + when(queryExecutor.executeWrite(eq(insertStmt))) .then( invocation -> { callCount.incrementAndGet(); return Uni.createFrom().item(results); }); + InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, shredDocument); Supplier execute = operation @@ -141,7 +129,6 @@ public void insertOne() throws Exception { assertThat(result.errors()).isNull(); } - @Disabled @Test public void insertDuplicate() throws Exception { String doc1 = @@ -160,46 +147,31 @@ public void insertDuplicate() throws Exception { final JsonNode jsonNode = objectMapper.readTree(doc1); final WritableShreddedDocument shredDocument = shredder.shred(jsonNode); - String insertCql = INSERT_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); - ValidatingStargateBridge.QueryAssert insertAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument.id())), - Values.of(shredDocument.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues(shredDocument.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returning(List.of(List.of(Values.of(false)))); + SimpleStatement insertStmt = nonVectorInsertStatement(shredDocument); + // Note: FALSE is needed to "fail" insertion, producing failure message + List rows = Arrays.asList(resultRow(COLUMNS_APPLIED, 0, Boolean.FALSE)); + AsyncResultSet results = new MockAsyncResultSet(COLUMNS_APPLIED, rows, null); + final AtomicInteger callCount = new AtomicInteger(); + QueryExecutor queryExecutor = mock(QueryExecutor.class); + + when(queryExecutor.executeWrite(eq(insertStmt))) + .then( + invocation -> { + callCount.incrementAndGet(); + return Uni.createFrom().item(results); + }); InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, shredDocument); Supplier execute = operation - .execute(queryExecutor0) + .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() .getItem(); // assert query execution - insertAssert.assertExecuteCount().isOne(); + assertThat(callCount.get()).isEqualTo(1); // then result CommandResult result = execute.get(); @@ -1083,6 +1055,22 @@ private MockRow resultRow(ColumnDefinitions columnDefs, int index, Object... val return new MockRow(columnDefs, index, buffers); } + private SimpleStatement nonVectorInsertStatement(WritableShreddedDocument shredDocument) { + String insertCql = INSERT_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); + return SimpleStatement.newInstance( + insertCql, + CQLBindValues.getDocumentIdValue(shredDocument.id()), + shredDocument.docJson(), + CQLBindValues.getSetValue(shredDocument.existKeys()), + CQLBindValues.getIntegerMapValues(shredDocument.arraySize()), + CQLBindValues.getStringSetValue(shredDocument.arrayContains()), + CQLBindValues.getBooleanMapValues(shredDocument.queryBoolValues()), + CQLBindValues.getDoubleMapValues(shredDocument.queryNumberValues()), + CQLBindValues.getStringMapValues(shredDocument.queryTextValues()), + CQLBindValues.getSetValue(shredDocument.queryNullValues()), + CQLBindValues.getTimestampMapValues(shredDocument.queryTimestampValues())); + } + // TEMPORARY ADDITIONS TO COMPILE DURING CONVERSION QueryExecutor queryExecutor0 = mock(QueryExecutor.class); diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/testutil/MockAsyncResultSet.java b/src/test/java/io/stargate/sgv2/jsonapi/service/testutil/MockAsyncResultSet.java index 0fa7ec49c2..91e542869c 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/testutil/MockAsyncResultSet.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/testutil/MockAsyncResultSet.java @@ -85,6 +85,6 @@ public ExecutionInfo getExecutionInfo() { @Override public boolean wasApplied() { - return true; + return rows.get(0).getBoolean("[applied]"); } } From 1948c4e5519788a3c174a165741e0c51c9d2e225 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 28 Nov 2023 16:34:36 -0800 Subject: [PATCH 05/13] Convert 3rd test --- .../model/impl/InsertOperationTest.java | 85 ++++++------------- 1 file changed, 24 insertions(+), 61 deletions(-) diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java index fc3d41c51a..5dec998834 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java @@ -38,6 +38,7 @@ import io.stargate.sgv2.jsonapi.service.testutil.MockRow; import jakarta.inject.Inject; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -189,7 +190,6 @@ public void insertDuplicate() throws Exception { }); } - @Disabled @Test public void insertManyOrdered() throws Exception { String document1 = @@ -223,77 +223,40 @@ public void insertManyOrdered() throws Exception { JsonNode jsonNode2 = objectMapper.readTree(document2); WritableShreddedDocument shredDocument2 = shredder.shred(jsonNode2); - String insertCql = INSERT_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); - ValidatingStargateBridge.QueryAssert insertFirstAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument1.id())), - Values.of(shredDocument1.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument1.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument1.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument1.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues( - shredDocument1.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument1.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument1.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returning(List.of(List.of(Values.of(true)))); - ValidatingStargateBridge.QueryAssert insertSecondAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument2.id())), - Values.of(shredDocument2.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument2.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument2.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument2.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument2.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues( - shredDocument2.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument2.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument2.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument2.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returning(List.of(List.of(Values.of(true)))); + SimpleStatement insertStmt1 = nonVectorInsertStatement(shredDocument1); + SimpleStatement insertStmt2 = nonVectorInsertStatement(shredDocument2); + + List rows = Arrays.asList(resultRow(COLUMNS_APPLIED, 0, Boolean.TRUE)); + AsyncResultSet results1 = new MockAsyncResultSet(COLUMNS_APPLIED, rows, null); + AsyncResultSet results2 = new MockAsyncResultSet(COLUMNS_APPLIED, rows, null); + final List calls = new ArrayList<>(); + QueryExecutor queryExecutor = mock(QueryExecutor.class); + + when(queryExecutor.executeWrite(eq(insertStmt1))) + .then( + invocation -> { + calls.add(1); + return Uni.createFrom().item(results1); + }); + when(queryExecutor.executeWrite(eq(insertStmt2))) + .then( + invocation -> { + calls.add(2); + return Uni.createFrom().item(results2); + }); InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), true); Supplier execute = operation - .execute(queryExecutor0) + .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() .getItem(); // assert query execution - insertFirstAssert.assertExecuteCount().isOne(); - insertSecondAssert.assertExecuteCount().isOne(); + assertThat(calls).isEqualTo(Arrays.asList(1, 2)); // then result CommandResult result = execute.get(); From 63b15c95966e9a946b49fa51428f4e5b34b150d7 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 28 Nov 2023 16:46:44 -0800 Subject: [PATCH 06/13] Some more conversions --- .../model/impl/InsertOperationTest.java | 136 ++++++------------ 1 file changed, 43 insertions(+), 93 deletions(-) diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java index 5dec998834..d69c5a9ed2 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java @@ -268,7 +268,6 @@ public void insertManyOrdered() throws Exception { assertThat(result.errors()).isNull(); } - @Disabled @Test public void insertManyUnordered() throws Exception { String document1 = @@ -302,77 +301,40 @@ public void insertManyUnordered() throws Exception { JsonNode jsonNode2 = objectMapper.readTree(document2); WritableShreddedDocument shredDocument2 = shredder.shred(jsonNode2); - String insertCql = INSERT_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); - ValidatingStargateBridge.QueryAssert insertFirstAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument1.id())), - Values.of(shredDocument1.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument1.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument1.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument1.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues( - shredDocument1.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument1.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument1.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returning(List.of(List.of(Values.of(true)))); - ValidatingStargateBridge.QueryAssert insertSecondAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument2.id())), - Values.of(shredDocument2.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument2.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument2.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument2.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument2.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues( - shredDocument2.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument2.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument2.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument2.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returning(List.of(List.of(Values.of(true)))); + SimpleStatement insertStmt1 = nonVectorInsertStatement(shredDocument1); + SimpleStatement insertStmt2 = nonVectorInsertStatement(shredDocument2); + + List rows = Arrays.asList(resultRow(COLUMNS_APPLIED, 0, Boolean.TRUE)); + AsyncResultSet results1 = new MockAsyncResultSet(COLUMNS_APPLIED, rows, null); + AsyncResultSet results2 = new MockAsyncResultSet(COLUMNS_APPLIED, rows, null); + final AtomicInteger callCount = new AtomicInteger(); + QueryExecutor queryExecutor = mock(QueryExecutor.class); + + when(queryExecutor.executeWrite(eq(insertStmt1))) + .then( + invocation -> { + callCount.addAndGet(1); + return Uni.createFrom().item(results1); + }); + when(queryExecutor.executeWrite(eq(insertStmt2))) + .then( + invocation -> { + callCount.addAndGet(1); + return Uni.createFrom().item(results2); + }); InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), false); Supplier execute = operation - .execute(queryExecutor0) + .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() .getItem(); // assert query execution - insertFirstAssert.assertExecuteCount().isOne(); - insertSecondAssert.assertExecuteCount().isOne(); + assertThat(callCount.get()).isEqualTo(2); // then result CommandResult result = execute.get(); @@ -386,7 +348,6 @@ public void insertManyUnordered() throws Exception { // failure modes - @Disabled @Test public void failureOrdered() throws Exception { // unordered first query fail @@ -421,41 +382,30 @@ public void failureOrdered() throws Exception { JsonNode jsonNode2 = objectMapper.readTree(document2); WritableShreddedDocument shredDocument2 = shredder.shred(jsonNode2); - String insertCql = INSERT_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); - ValidatingStargateBridge.QueryAssert insertFirstAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument1.id())), - Values.of(shredDocument1.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument1.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument1.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument1.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues( - shredDocument1.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument1.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument1.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returningFailure(new RuntimeException("Ivan breaks the test.")); + SimpleStatement insertStmt1 = nonVectorInsertStatement(shredDocument1); + SimpleStatement insertStmt2 = nonVectorInsertStatement(shredDocument2); + + final AtomicInteger callCount = new AtomicInteger(); + QueryExecutor queryExecutor = mock(QueryExecutor.class); + + when(queryExecutor.executeWrite(eq(insertStmt1))) + .then( + invocation -> { + callCount.addAndGet(1); + return Uni.createFrom().failure(new RuntimeException("Ivan breaks the test.")); + }); + when(queryExecutor.executeWrite(eq(insertStmt2))) + .then( + invocation -> { + callCount.addAndGet(1); + return Uni.createFrom().item(Arrays.asList()); + }); InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), true); Supplier execute = operation - .execute(queryExecutor0) + .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() @@ -463,7 +413,7 @@ public void failureOrdered() throws Exception { // assert query execution // second query never executed - insertFirstAssert.assertExecuteCount().isOne(); + assertThat(callCount.get()).isEqualTo(1); // then result CommandResult result = execute.get(); From c6e64ef2d060619e2c529042fe5a27e20dea2313 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 28 Nov 2023 16:52:02 -0800 Subject: [PATCH 07/13] One more conversion --- .../model/impl/InsertOperationTest.java | 92 ++++++------------- 1 file changed, 27 insertions(+), 65 deletions(-) diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java index d69c5a9ed2..42b3713c05 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java @@ -350,7 +350,7 @@ public void insertManyUnordered() throws Exception { @Test public void failureOrdered() throws Exception { - // unordered first query fail + // ordered first insert fails String document1 = """ { @@ -428,10 +428,9 @@ public void failureOrdered() throws Exception { }); } - @Disabled @Test public void failureOrderedLastFails() throws Exception { - // unordered first query OK, second fail + // ordered first insert OK, second fail String document1 = """ { @@ -463,78 +462,41 @@ public void failureOrderedLastFails() throws Exception { JsonNode jsonNode2 = objectMapper.readTree(document2); WritableShreddedDocument shredDocument2 = shredder.shred(jsonNode2); - String insertCql = INSERT_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); - ValidatingStargateBridge.QueryAssert insertFirstAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument1.id())), - Values.of(shredDocument1.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument1.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument1.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument1.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues( - shredDocument1.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument1.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument1.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returning(List.of(List.of(Values.of(true)))); - ValidatingStargateBridge.QueryAssert insertSecondAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument2.id())), - Values.of(shredDocument2.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument2.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument2.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument2.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument2.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues( - shredDocument2.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument2.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument2.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument2.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returningFailure(new RuntimeException("Ivan really breaks the test.")); + SimpleStatement insertStmt1 = nonVectorInsertStatement(shredDocument1); + SimpleStatement insertStmt2 = nonVectorInsertStatement(shredDocument2); + + List rows = Arrays.asList(resultRow(COLUMNS_APPLIED, 0, Boolean.TRUE)); + AsyncResultSet resultOk = new MockAsyncResultSet(COLUMNS_APPLIED, rows, null); + + final AtomicInteger callCount = new AtomicInteger(); + QueryExecutor queryExecutor = mock(QueryExecutor.class); + + when(queryExecutor.executeWrite(eq(insertStmt1))) + .then( + invocation -> { + callCount.addAndGet(1); + return Uni.createFrom().item(resultOk); + }); + when(queryExecutor.executeWrite(eq(insertStmt2))) + .then( + invocation -> { + callCount.addAndGet(1); + return Uni.createFrom() + .failure(new RuntimeException("Ivan really breaks the test.")); + }); InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), true); Supplier execute = operation - .execute(queryExecutor0) + .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() .getItem(); - // assert query execution - // second query never executed - insertFirstAssert.assertExecuteCount().isOne(); - insertSecondAssert.assertExecuteCount().isOne(); + // assert query execution: both executed (second failed) + assertThat(callCount.get()).isEqualTo(2); // then result contains both insert and error CommandResult result = execute.get(); From c29e6f92e95d57db73ab888b5b58f8e6a2af1bd8 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 29 Nov 2023 09:51:36 -0800 Subject: [PATCH 08/13] ... --- .../service/operation/model/impl/OperationTestBase.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/OperationTestBase.java b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/OperationTestBase.java index 216447ac09..5abb0c53f5 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/OperationTestBase.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/OperationTestBase.java @@ -62,10 +62,6 @@ protected ByteBuffer byteBufferFrom(long value) { return TypeCodecs.BIGINT.encode(value, ProtocolVersion.DEFAULT); } - protected ByteBuffer byteBufferFrom(boolean value) { - return TypeCodecs.BOOLEAN.encode(value, ProtocolVersion.DEFAULT); - } - protected ByteBuffer byteBufferFrom(TupleValue value) { return TypeCodecs.tupleOf(DOC_KEY_TYPE).encode(value, ProtocolVersion.DEFAULT); } From 1a4bbbde3d3c4f033487991c292e89e60ebadb46 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 29 Nov 2023 11:37:53 -0800 Subject: [PATCH 09/13] Convert last tests --- .../model/impl/InsertOperationTest.java | 650 ++++++++---------- 1 file changed, 268 insertions(+), 382 deletions(-) diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java index 42b3713c05..37ee451b38 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java @@ -16,11 +16,7 @@ import io.quarkus.test.junit.TestProfile; import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.helpers.test.UniAssertSubscriber; -import io.stargate.bridge.grpc.TypeSpecs; -import io.stargate.bridge.grpc.Values; -import io.stargate.bridge.proto.QueryOuterClass; import io.stargate.sgv2.api.common.config.QueriesConfig; -import io.stargate.sgv2.common.bridge.ValidatingStargateBridge; import io.stargate.sgv2.common.testprofiles.NoGlobalResourcesTestProfile; import io.stargate.sgv2.jsonapi.api.model.command.CommandContext; import io.stargate.sgv2.jsonapi.api.model.command.CommandResult; @@ -30,7 +26,6 @@ import io.stargate.sgv2.jsonapi.service.cqldriver.executor.CollectionSettings; import io.stargate.sgv2.jsonapi.service.cqldriver.executor.QueryExecutor; import io.stargate.sgv2.jsonapi.service.cqldriver.serializer.CQLBindValues; -import io.stargate.sgv2.jsonapi.service.cqldriver.serializer.CustomValueSerializers; import io.stargate.sgv2.jsonapi.service.shredding.Shredder; import io.stargate.sgv2.jsonapi.service.shredding.model.DocumentId; import io.stargate.sgv2.jsonapi.service.shredding.model.WritableShreddedDocument; @@ -44,14 +39,14 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import java.util.stream.Stream; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @QuarkusTest @TestProfile(NoGlobalResourcesTestProfile.Impl.class) public class InsertOperationTest extends OperationTestBase { - private final CommandContext COMMAND_CONTEXT = new CommandContext(KEYSPACE_NAME, COLLECTION_NAME); + private final CommandContext COMMAND_CONTEXT_NON_VECTOR = + new CommandContext(KEYSPACE_NAME, COLLECTION_NAME); private final CommandContext COMMAND_CONTEXT_VECTOR = new CommandContext( @@ -77,22 +72,22 @@ public class InsertOperationTest extends OperationTestBase { + " (?, now(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) IF NOT EXISTS"; @Nested - class Execute { + class InsertNonVector { @Test public void insertOne() throws Exception { String document = """ - { - "_id": "doc1", - "text": "user1", - "number" : 10, - "boolean": true, - "nullval" : null, - "array" : ["a", "b"], - "sub_doc" : {"col": "val"}, - "date_val" : {"$date": 1672531200000 } - } - """; + { + "_id": "doc1", + "text": "user1", + "number" : 10, + "boolean": true, + "nullval" : null, + "array" : ["a", "b"], + "sub_doc" : {"col": "val"}, + "date_val" : {"$date": 1672531200000 } + } + """; JsonNode jsonNode = objectMapper.readTree(document); WritableShreddedDocument shredDocument = shredder.shred(jsonNode); @@ -110,9 +105,8 @@ public void insertOne() throws Exception { return Uni.createFrom().item(results); }); - InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, shredDocument); Supplier execute = - operation + new InsertOperation(COMMAND_CONTEXT_NON_VECTOR, shredDocument) .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) @@ -134,16 +128,16 @@ public void insertOne() throws Exception { public void insertDuplicate() throws Exception { String doc1 = """ - { - "_id": "doc1", - "text": "user1", - "number" : 10, - "boolean": true, - "nullval" : null, - "array" : ["a", "b"], - "sub_doc" : {"col": "val"} - } - """; + { + "_id": "doc1", + "text": "user1", + "number" : 10, + "boolean": true, + "nullval" : null, + "array" : ["a", "b"], + "sub_doc" : {"col": "val"} + } + """; final JsonNode jsonNode = objectMapper.readTree(doc1); final WritableShreddedDocument shredDocument = shredder.shred(jsonNode); @@ -162,9 +156,8 @@ public void insertDuplicate() throws Exception { return Uni.createFrom().item(results); }); - InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, shredDocument); Supplier execute = - operation + new InsertOperation(COMMAND_CONTEXT_NON_VECTOR, shredDocument) .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) @@ -194,28 +187,28 @@ public void insertDuplicate() throws Exception { public void insertManyOrdered() throws Exception { String document1 = """ - { - "_id": "doc1", - "text": "user1", - "number" : 10, - "boolean": true, - "nullval" : null, - "array" : ["a", "b"], - "sub_doc" : {"col": "val"} - } - """; + { + "_id": "doc1", + "text": "user1", + "number" : 10, + "boolean": true, + "nullval" : null, + "array" : ["a", "b"], + "sub_doc" : {"col": "val"} + } + """; String document2 = """ - { - "_id": "doc2", - "text": "user2", - "number" : 11, - "boolean": false, - "nullval" : null, - "array" : ["c", "d"], - "sub_doc" : {"col": "lav"} - } - """; + { + "_id": "doc2", + "text": "user2", + "number" : 11, + "boolean": false, + "nullval" : null, + "array" : ["c", "d"], + "sub_doc" : {"col": "lav"} + } + """; JsonNode jsonNode1 = objectMapper.readTree(document1); WritableShreddedDocument shredDocument1 = shredder.shred(jsonNode1); @@ -245,10 +238,9 @@ public void insertManyOrdered() throws Exception { return Uni.createFrom().item(results2); }); - InsertOperation operation = - new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), true); Supplier execute = - operation + new InsertOperation( + COMMAND_CONTEXT_NON_VECTOR, List.of(shredDocument1, shredDocument2), true) .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) @@ -272,28 +264,28 @@ public void insertManyOrdered() throws Exception { public void insertManyUnordered() throws Exception { String document1 = """ - { - "_id": "doc1", - "text": "user1", - "number" : 10, - "boolean": true, - "nullval" : null, - "array" : ["a", "b"], - "sub_doc" : {"col": "val"} - } - """; + { + "_id": "doc1", + "text": "user1", + "number" : 10, + "boolean": true, + "nullval" : null, + "array" : ["a", "b"], + "sub_doc" : {"col": "val"} + } + """; String document2 = """ - { - "_id": "doc2", - "text": "user2", - "number" : 11, - "boolean": false, - "nullval" : null, - "array" : ["c", "d"], - "sub_doc" : {"col": "lav"} - } - """; + { + "_id": "doc2", + "text": "user2", + "number" : 11, + "boolean": false, + "nullval" : null, + "array" : ["c", "d"], + "sub_doc" : {"col": "lav"} + } + """; JsonNode jsonNode1 = objectMapper.readTree(document1); WritableShreddedDocument shredDocument1 = shredder.shred(jsonNode1); @@ -323,10 +315,9 @@ public void insertManyUnordered() throws Exception { return Uni.createFrom().item(results2); }); - InsertOperation operation = - new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), false); Supplier execute = - operation + new InsertOperation( + COMMAND_CONTEXT_NON_VECTOR, List.of(shredDocument1, shredDocument2), false) .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) @@ -353,28 +344,28 @@ public void failureOrdered() throws Exception { // ordered first insert fails String document1 = """ - { - "_id": "doc1", - "text": "user1", - "number" : 10, - "boolean": true, - "nullval" : null, - "array" : ["a", "b"], - "sub_doc" : {"col": "val"} - } - """; + { + "_id": "doc1", + "text": "user1", + "number" : 10, + "boolean": true, + "nullval" : null, + "array" : ["a", "b"], + "sub_doc" : {"col": "val"} + } + """; String document2 = """ - { - "_id": "doc2", - "text": "user2", - "number" : 11, - "boolean": false, - "nullval" : null, - "array" : ["c", "d"], - "sub_doc" : {"col": "lav"} - } - """; + { + "_id": "doc2", + "text": "user2", + "number" : 11, + "boolean": false, + "nullval" : null, + "array" : ["c", "d"], + "sub_doc" : {"col": "lav"} + } + """; JsonNode jsonNode1 = objectMapper.readTree(document1); WritableShreddedDocument shredDocument1 = shredder.shred(jsonNode1); @@ -401,10 +392,9 @@ public void failureOrdered() throws Exception { return Uni.createFrom().item(Arrays.asList()); }); - InsertOperation operation = - new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), true); Supplier execute = - operation + new InsertOperation( + COMMAND_CONTEXT_NON_VECTOR, List.of(shredDocument1, shredDocument2), true) .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) @@ -433,28 +423,28 @@ public void failureOrderedLastFails() throws Exception { // ordered first insert OK, second fail String document1 = """ - { - "_id": "doc1", - "text": "user1", - "number" : 10, - "boolean": true, - "nullval" : null, - "array" : ["a", "b"], - "sub_doc" : {"col": "val"} - } - """; + { + "_id": "doc1", + "text": "user1", + "number" : 10, + "boolean": true, + "nullval" : null, + "array" : ["a", "b"], + "sub_doc" : {"col": "val"} + } + """; String document2 = """ - { - "_id": "doc2", - "text": "user2", - "number" : 11, - "boolean": false, - "nullval" : null, - "array" : ["c", "d"], - "sub_doc" : {"col": "lav"} - } - """; + { + "_id": "doc2", + "text": "user2", + "number" : 11, + "boolean": false, + "nullval" : null, + "array" : ["c", "d"], + "sub_doc" : {"col": "lav"} + } + """; JsonNode jsonNode1 = objectMapper.readTree(document1); WritableShreddedDocument shredDocument1 = shredder.shred(jsonNode1); @@ -485,10 +475,9 @@ public void failureOrderedLastFails() throws Exception { .failure(new RuntimeException("Ivan really breaks the test.")); }); - InsertOperation operation = - new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), true); Supplier execute = - operation + new InsertOperation( + COMMAND_CONTEXT_NON_VECTOR, List.of(shredDocument1, shredDocument2), true) .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) @@ -514,113 +503,74 @@ public void failureOrderedLastFails() throws Exception { }); } - @Disabled @Test public void failureUnorderedPartial() throws Exception { // unordered one query fail String document1 = """ - { - "_id": "doc1", - "text": "user1", - "number" : 10, - "boolean": true, - "nullval" : null, - "array" : ["a", "b"], - "sub_doc" : {"col": "val"} - } - """; + { + "_id": "doc1", + "text": "user1", + "number" : 10, + "boolean": true, + "nullval" : null, + "array" : ["a", "b"], + "sub_doc" : {"col": "val"} + } + """; String document2 = """ - { - "_id": "doc2", - "text": "user2", - "number" : 11, - "boolean": false, - "nullval" : null, - "array" : ["c", "d"], - "sub_doc" : {"col": "lav"} - } - """; + { + "_id": "doc2", + "text": "user2", + "number" : 11, + "boolean": false, + "nullval" : null, + "array" : ["c", "d"], + "sub_doc" : {"col": "lav"} + } + """; JsonNode jsonNode1 = objectMapper.readTree(document1); WritableShreddedDocument shredDocument1 = shredder.shred(jsonNode1); - JsonNode jsonNode2 = objectMapper.readTree(document2); WritableShreddedDocument shredDocument2 = shredder.shred(jsonNode2); - String insertCql = INSERT_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); - ValidatingStargateBridge.QueryAssert insertFirstAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument1.id())), - Values.of(shredDocument1.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument1.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument1.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument1.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues( - shredDocument1.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument1.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument1.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returningFailure(new RuntimeException("Ivan breaks the test.")); - ValidatingStargateBridge.QueryAssert insertSecondAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument2.id())), - Values.of(shredDocument2.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument2.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument2.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument2.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument2.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues( - shredDocument2.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument2.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument2.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument2.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returning(List.of(List.of(Values.of(true)))); - - InsertOperation operation = - new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), false); + SimpleStatement insertStmt1 = nonVectorInsertStatement(shredDocument1); + SimpleStatement insertStmt2 = nonVectorInsertStatement(shredDocument2); + + List rows = Arrays.asList(resultRow(COLUMNS_APPLIED, 0, Boolean.TRUE)); + AsyncResultSet resultOk = new MockAsyncResultSet(COLUMNS_APPLIED, rows, null); + + final AtomicInteger callCount1 = new AtomicInteger(); + final AtomicInteger callCount2 = new AtomicInteger(); + QueryExecutor queryExecutor = mock(QueryExecutor.class); + + when(queryExecutor.executeWrite(eq(insertStmt1))) + .then( + invocation -> { + callCount1.addAndGet(1); + return Uni.createFrom().failure(new RuntimeException("Ivan breaks the test.")); + }); + when(queryExecutor.executeWrite(eq(insertStmt2))) + .then( + invocation -> { + callCount2.addAndGet(1); + return Uni.createFrom().item(resultOk); + }); + Supplier execute = - operation - .execute(queryExecutor0) + new InsertOperation( + COMMAND_CONTEXT_NON_VECTOR, List.of(shredDocument1, shredDocument2), false) + .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() .getItem(); - // assert query execution - // second query never executed - insertFirstAssert.assertExecuteCount().isOne(); - insertSecondAssert.assertExecuteCount().isOne(); + // assert query execution: both called + assertThat(callCount1.get()).isEqualTo(1); + assertThat(callCount1.get()).isEqualTo(1); // then result has both insert id and errors CommandResult result = execute.get(); @@ -637,34 +587,33 @@ public void failureUnorderedPartial() throws Exception { }); } - @Disabled @Test public void failureUnorderedAll() throws Exception { // unordered both queries fail String document1 = """ - { - "_id": "doc1", - "text": "user1", - "number" : 10, - "boolean": true, - "nullval" : null, - "array" : ["a", "b"], - "sub_doc" : {"col": "val"} - } - """; + { + "_id": "doc1", + "text": "user1", + "number" : 10, + "boolean": true, + "nullval" : null, + "array" : ["a", "b"], + "sub_doc" : {"col": "val"} + } + """; String document2 = """ - { - "_id": "doc2", - "text": "user2", - "number" : 11, - "boolean": false, - "nullval" : null, - "array" : ["c", "d"], - "sub_doc" : {"col": "lav"} - } - """; + { + "_id": "doc2", + "text": "user2", + "number" : 11, + "boolean": false, + "nullval" : null, + "array" : ["c", "d"], + "sub_doc" : {"col": "lav"} + } + """; JsonNode jsonNode1 = objectMapper.readTree(document1); WritableShreddedDocument shredDocument1 = shredder.shred(jsonNode1); @@ -672,78 +621,41 @@ public void failureUnorderedAll() throws Exception { JsonNode jsonNode2 = objectMapper.readTree(document2); WritableShreddedDocument shredDocument2 = shredder.shred(jsonNode2); - String insertCql = INSERT_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); - ValidatingStargateBridge.QueryAssert insertFirstAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument1.id())), - Values.of(shredDocument1.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument1.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument1.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument1.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues( - shredDocument1.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument1.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument1.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument1.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returningFailure(new RuntimeException("Ivan breaks the test.")); - ValidatingStargateBridge.QueryAssert insertSecondAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument2.id())), - Values.of(shredDocument2.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument2.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument2.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument2.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument2.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues( - shredDocument2.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument2.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument2.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument2.queryTimestampValues()))) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returningFailure(new RuntimeException("Ivan really breaks the test.")); - - InsertOperation operation = - new InsertOperation(COMMAND_CONTEXT, List.of(shredDocument1, shredDocument2), false); + SimpleStatement insertStmt1 = nonVectorInsertStatement(shredDocument1); + SimpleStatement insertStmt2 = nonVectorInsertStatement(shredDocument2); + + List rows = Arrays.asList(resultRow(COLUMNS_APPLIED, 0, Boolean.TRUE)); + AsyncResultSet resultOk = new MockAsyncResultSet(COLUMNS_APPLIED, rows, null); + + final AtomicInteger callCount1 = new AtomicInteger(); + final AtomicInteger callCount2 = new AtomicInteger(); + QueryExecutor queryExecutor = mock(QueryExecutor.class); + + when(queryExecutor.executeWrite(eq(insertStmt1))) + .then( + invocation -> { + callCount1.addAndGet(1); + return Uni.createFrom().failure(new RuntimeException("Insert 1 failed")); + }); + when(queryExecutor.executeWrite(eq(insertStmt2))) + .then( + invocation -> { + callCount2.addAndGet(1); + return Uni.createFrom().failure(new RuntimeException("Insert 2 failed")); + }); + Supplier execute = - operation - .execute(queryExecutor0) + new InsertOperation( + COMMAND_CONTEXT_NON_VECTOR, List.of(shredDocument1, shredDocument2), false) + .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() .getItem(); - // assert query execution - // second query never executed - insertFirstAssert.assertExecuteCount().isOne(); - insertSecondAssert.assertExecuteCount().isOne(); + // assert query execution: both called + assertThat(callCount1.get()).isEqualTo(1); + assertThat(callCount1.get()).isEqualTo(1); // then result has 2 errors CommandResult result = execute.get(); @@ -752,11 +664,13 @@ public void failureUnorderedAll() throws Exception { .hasSize(2) .extracting(CommandResult.Error::message) .containsExactlyInAnyOrder( - "Failed to insert document with _id 'doc1': Ivan breaks the test.", - "Failed to insert document with _id 'doc2': Ivan really breaks the test."); + "Failed to insert document with _id 'doc1': Insert 1 failed", + "Failed to insert document with _id 'doc2': Insert 2 failed"); } + } - @Disabled + @Nested + class InsertVector { @Test public void insertOneVectorSearch() throws Exception { String document = @@ -777,47 +691,29 @@ public void insertOneVectorSearch() throws Exception { JsonNode jsonNode = objectMapper.readTree(document); WritableShreddedDocument shredDocument = shredder.shred(jsonNode); - String insertCql = INSERT_VECTOR_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); - ValidatingStargateBridge.QueryAssert insertAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument.id())), - Values.of(shredDocument.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues(shredDocument.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument.queryTimestampValues())), - CustomValueSerializers.getVectorValue(shredDocument.queryVectorValues())) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returning(List.of(List.of(Values.of(true)))); - - InsertOperation operation = new InsertOperation(COMMAND_CONTEXT_VECTOR, shredDocument); + SimpleStatement insertStmt = vectorInsertStatement(shredDocument); + List rows = Arrays.asList(resultRow(COLUMNS_APPLIED, 0, Boolean.TRUE)); + AsyncResultSet results = new MockAsyncResultSet(COLUMNS_APPLIED, rows, null); + final AtomicInteger callCount = new AtomicInteger(); + QueryExecutor queryExecutor = mock(QueryExecutor.class); + + when(queryExecutor.executeWrite(eq(insertStmt))) + .then( + invocation -> { + callCount.incrementAndGet(); + return Uni.createFrom().item(results); + }); + Supplier execute = - operation - .execute(queryExecutor0) + new InsertOperation(COMMAND_CONTEXT_VECTOR, shredDocument) + .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() .getItem(); // assert query execution - insertAssert.assertExecuteCount().isOne(); + assertThat(callCount.get()).isEqualTo(1); // then result CommandResult result = execute.get(); @@ -827,7 +723,6 @@ public void insertOneVectorSearch() throws Exception { assertThat(result.errors()).isNull(); } - @Disabled @Test public void insertOneVectorEnabledNoVectorData() throws Exception { String document = @@ -847,47 +742,29 @@ public void insertOneVectorEnabledNoVectorData() throws Exception { JsonNode jsonNode = objectMapper.readTree(document); WritableShreddedDocument shredDocument = shredder.shred(jsonNode); - String insertCql = INSERT_VECTOR_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); - ValidatingStargateBridge.QueryAssert insertAssert = - withQuery( - insertCql, - Values.of(CustomValueSerializers.getDocumentIdValue(shredDocument.id())), - Values.of(shredDocument.docJson()), - Values.of(CustomValueSerializers.getSetValue(shredDocument.existKeys())), - Values.of(CustomValueSerializers.getIntegerMapValues(shredDocument.arraySize())), - Values.of( - CustomValueSerializers.getStringSetValue(shredDocument.arrayContains())), - Values.of( - CustomValueSerializers.getBooleanMapValues(shredDocument.queryBoolValues())), - Values.of( - CustomValueSerializers.getDoubleMapValues(shredDocument.queryNumberValues())), - Values.of( - CustomValueSerializers.getStringMapValues(shredDocument.queryTextValues())), - Values.of(CustomValueSerializers.getSetValue(shredDocument.queryNullValues())), - Values.of( - CustomValueSerializers.getTimestampMapValues( - shredDocument.queryTimestampValues())), - CustomValueSerializers.getVectorValue(shredDocument.queryVectorValues())) - .withColumnSpec( - List.of( - QueryOuterClass.ColumnSpec.newBuilder() - .setName("applied") - .setType(TypeSpecs.BOOLEAN) - .build())) - .withSerialConsistency(queriesConfig.serialConsistency()) - .returning(List.of(List.of(Values.of(true)))); - - InsertOperation operation = new InsertOperation(COMMAND_CONTEXT_VECTOR, shredDocument); + SimpleStatement insertStmt = vectorInsertStatement(shredDocument); + List rows = Arrays.asList(resultRow(COLUMNS_APPLIED, 0, Boolean.TRUE)); + AsyncResultSet results = new MockAsyncResultSet(COLUMNS_APPLIED, rows, null); + final AtomicInteger callCount = new AtomicInteger(); + QueryExecutor queryExecutor = mock(QueryExecutor.class); + + when(queryExecutor.executeWrite(eq(insertStmt))) + .then( + invocation -> { + callCount.incrementAndGet(); + return Uni.createFrom().item(results); + }); + Supplier execute = - operation - .execute(queryExecutor0) + new InsertOperation(COMMAND_CONTEXT_VECTOR, shredDocument) + .execute(queryExecutor) .subscribe() .withSubscriber(UniAssertSubscriber.create()) .awaitItem() .getItem(); // assert query execution - insertAssert.assertExecuteCount().isOne(); + assertThat(callCount.get()).isEqualTo(1); // then result CommandResult result = execute.get(); @@ -897,7 +774,6 @@ public void insertOneVectorEnabledNoVectorData() throws Exception { assertThat(result.errors()).isNull(); } - @Disabled @Test public void insertOneVectorDisabledWithVectorData() throws Exception { String document = @@ -917,8 +793,10 @@ public void insertOneVectorDisabledWithVectorData() throws Exception { JsonNode jsonNode = objectMapper.readTree(document); WritableShreddedDocument shredDocument = shredder.shred(jsonNode); - InsertOperation operation = new InsertOperation(COMMAND_CONTEXT, shredDocument); - Throwable failure = catchThrowable(() -> operation.execute(queryExecutor0)); + InsertOperation operation = new InsertOperation(COMMAND_CONTEXT_NON_VECTOR, shredDocument); + QueryExecutor queryExecutor = mock(QueryExecutor.class); + + Throwable failure = catchThrowable(() -> operation.execute(queryExecutor)); assertThat(failure) .isInstanceOf(JsonApiException.class) .hasFieldOrPropertyWithValue("errorCode", ErrorCode.VECTOR_SEARCH_NOT_SUPPORTED); @@ -946,12 +824,20 @@ private SimpleStatement nonVectorInsertStatement(WritableShreddedDocument shredD CQLBindValues.getTimestampMapValues(shredDocument.queryTimestampValues())); } - // TEMPORARY ADDITIONS TO COMPILE DURING CONVERSION - - QueryExecutor queryExecutor0 = mock(QueryExecutor.class); - - protected ValidatingStargateBridge.QueryExpectation withQuery( - String cql, QueryOuterClass.Value... values) { - throw new IllegalStateException("No longer supported without Bridge"); + private SimpleStatement vectorInsertStatement(WritableShreddedDocument shredDocument) { + String insertCql = INSERT_VECTOR_CQL.formatted(KEYSPACE_NAME, COLLECTION_NAME); + return SimpleStatement.newInstance( + insertCql, + CQLBindValues.getDocumentIdValue(shredDocument.id()), + shredDocument.docJson(), + CQLBindValues.getSetValue(shredDocument.existKeys()), + CQLBindValues.getIntegerMapValues(shredDocument.arraySize()), + CQLBindValues.getStringSetValue(shredDocument.arrayContains()), + CQLBindValues.getBooleanMapValues(shredDocument.queryBoolValues()), + CQLBindValues.getDoubleMapValues(shredDocument.queryNumberValues()), + CQLBindValues.getStringMapValues(shredDocument.queryTextValues()), + CQLBindValues.getSetValue(shredDocument.queryNullValues()), + CQLBindValues.getTimestampMapValues(shredDocument.queryTimestampValues()), + CQLBindValues.getVectorValue(shredDocument.queryVectorValues())); } } From 70b927ce434a317139dd0811e0c96d2e952ad8ed Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 29 Nov 2023 11:43:18 -0800 Subject: [PATCH 10/13] Undo one signature change --- .../jsonapi/service/cqldriver/serializer/CQLBindValues.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java b/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java index 37d76d107b..3180e60f6c 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java @@ -38,10 +38,10 @@ public static List getListValue(List from) { return from.stream().map(val -> val.toString()).collect(Collectors.toList()); } - public static Map getStringMapValues(Map from) { + public static Map getStringMapValues(Map from) { final Map to = new HashMap<>(from.size()); - for (Map.Entry entry : from.entrySet()) { - to.put(entry.getKey().toString(), entry.getValue().toString()); + for (Map.Entry entry : from.entrySet()) { + to.put(entry.getKey().toString(), entry.getValue()); } return to; } From 30ea154621ad7fc430ee2a0da05ca7695c0ce01b Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 30 Nov 2023 10:00:13 -0800 Subject: [PATCH 11/13] Changes suggested by code review --- .../cqldriver/serializer/CQLBindValues.java | 5 +++-- .../model/impl/InsertOperationTest.java | 18 ++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java b/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java index 3180e60f6c..d2422babbc 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -30,8 +31,8 @@ public static Set getSetValue(Set from) { return from.stream().map(val -> val.toString()).collect(Collectors.toSet()); } - public static Set getStringSetValue(Set from) { - return from.stream().map(val -> val.toString()).collect(Collectors.toSet()); + public static Set getStringSetValue(Set from) { + return new LinkedHashSet<>(from); } public static List getListValue(List from) { diff --git a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java index 37ee451b38..920f8f991d 100644 --- a/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java +++ b/src/test/java/io/stargate/sgv2/jsonapi/service/operation/model/impl/InsertOperationTest.java @@ -383,7 +383,7 @@ public void failureOrdered() throws Exception { .then( invocation -> { callCount.addAndGet(1); - return Uni.createFrom().failure(new RuntimeException("Ivan breaks the test.")); + return Uni.createFrom().failure(new RuntimeException("Test break #1")); }); when(queryExecutor.executeWrite(eq(insertStmt2))) .then( @@ -413,7 +413,7 @@ public void failureOrdered() throws Exception { .satisfies( error -> { assertThat(error.message()) - .isEqualTo("Failed to insert document with _id 'doc1': Ivan breaks the test."); + .isEqualTo("Failed to insert document with _id 'doc1': Test break #1"); assertThat(error.fields()).containsEntry("exceptionClass", "RuntimeException"); }); } @@ -471,8 +471,7 @@ public void failureOrderedLastFails() throws Exception { .then( invocation -> { callCount.addAndGet(1); - return Uni.createFrom() - .failure(new RuntimeException("Ivan really breaks the test.")); + return Uni.createFrom().failure(new RuntimeException("Test break #2")); }); Supplier execute = @@ -497,8 +496,7 @@ public void failureOrderedLastFails() throws Exception { .satisfies( error -> { assertThat(error.message()) - .isEqualTo( - "Failed to insert document with _id 'doc2': Ivan really breaks the test."); + .isEqualTo("Failed to insert document with _id 'doc2': Test break #2"); assertThat(error.fields()).containsEntry("exceptionClass", "RuntimeException"); }); } @@ -550,7 +548,7 @@ public void failureUnorderedPartial() throws Exception { .then( invocation -> { callCount1.addAndGet(1); - return Uni.createFrom().failure(new RuntimeException("Ivan breaks the test.")); + return Uni.createFrom().failure(new RuntimeException("Test break #1")); }); when(queryExecutor.executeWrite(eq(insertStmt2))) .then( @@ -582,7 +580,7 @@ public void failureUnorderedPartial() throws Exception { .satisfies( error -> { assertThat(error.message()) - .isEqualTo("Failed to insert document with _id 'doc1': Ivan breaks the test."); + .isEqualTo("Failed to insert document with _id 'doc1': Test break #1"); assertThat(error.fields()).containsEntry("exceptionClass", "RuntimeException"); }); } @@ -816,7 +814,7 @@ private SimpleStatement nonVectorInsertStatement(WritableShreddedDocument shredD shredDocument.docJson(), CQLBindValues.getSetValue(shredDocument.existKeys()), CQLBindValues.getIntegerMapValues(shredDocument.arraySize()), - CQLBindValues.getStringSetValue(shredDocument.arrayContains()), + shredDocument.arrayContains(), CQLBindValues.getBooleanMapValues(shredDocument.queryBoolValues()), CQLBindValues.getDoubleMapValues(shredDocument.queryNumberValues()), CQLBindValues.getStringMapValues(shredDocument.queryTextValues()), @@ -832,7 +830,7 @@ private SimpleStatement vectorInsertStatement(WritableShreddedDocument shredDocu shredDocument.docJson(), CQLBindValues.getSetValue(shredDocument.existKeys()), CQLBindValues.getIntegerMapValues(shredDocument.arraySize()), - CQLBindValues.getStringSetValue(shredDocument.arrayContains()), + shredDocument.arrayContains(), CQLBindValues.getBooleanMapValues(shredDocument.queryBoolValues()), CQLBindValues.getDoubleMapValues(shredDocument.queryNumberValues()), CQLBindValues.getStringMapValues(shredDocument.queryTextValues()), From 1af7afd836aaa4e550c68d18c60f8a0c7675bbdf Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 30 Nov 2023 10:02:13 -0800 Subject: [PATCH 12/13] Minor Javadoc addition --- .../jsonapi/service/cqldriver/serializer/CQLBindValues.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java b/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java index d2422babbc..de2937f570 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java @@ -17,6 +17,10 @@ import java.util.Set; import java.util.stream.Collectors; +/** + * Utility class for methods used to convert from Java types to CQL types, + * for use in CQL bind values. + */ public class CQLBindValues { public static Map getIntegerMapValues(Map from) { From 232dba49a1db4754d90e6499734585e868a1ee93 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 30 Nov 2023 10:38:28 -0800 Subject: [PATCH 13/13] mvn fmt:format --- .../jsonapi/service/cqldriver/serializer/CQLBindValues.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java b/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java index de2937f570..fc89b0c12a 100644 --- a/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java +++ b/src/main/java/io/stargate/sgv2/jsonapi/service/cqldriver/serializer/CQLBindValues.java @@ -18,8 +18,8 @@ import java.util.stream.Collectors; /** - * Utility class for methods used to convert from Java types to CQL types, - * for use in CQL bind values. + * Utility class for methods used to convert from Java types to CQL types, for use in CQL bind + * values. */ public class CQLBindValues {