From 4af9131a6fc3fc900378782bb786082f9e358103 Mon Sep 17 00:00:00 2001 From: Kodai Doki <52027276+KodaiD@users.noreply.github.com> Date: Fri, 17 Oct 2025 07:03:40 +0000 Subject: [PATCH 1/2] Empty commit [skip ci] From e19fc8fb917035d2c4e24f74630b7618783cd7ae Mon Sep 17 00:00:00 2001 From: Kodai Doki <52027276+KodaiD@users.noreply.github.com> Date: Wed, 15 Oct 2025 15:45:42 +0900 Subject: [PATCH 2/2] Add more waits for cache expiry (#3046) --- .../JdbcTransactionAdminIntegrationTest.java | 34 ++++ ...edTransactionAdminIntegrationTestBase.java | 160 ++++++++++-------- ...nsensusCommitAdminIntegrationTestBase.java | 34 ++++ ...onTransactionAdminIntegrationTestBase.java | 28 +++ 4 files changed, 183 insertions(+), 73 deletions(-) diff --git a/core/src/integration-test/java/com/scalar/db/transaction/jdbc/JdbcTransactionAdminIntegrationTest.java b/core/src/integration-test/java/com/scalar/db/transaction/jdbc/JdbcTransactionAdminIntegrationTest.java index 9c114868da..0fcfe7fd9f 100644 --- a/core/src/integration-test/java/com/scalar/db/transaction/jdbc/JdbcTransactionAdminIntegrationTest.java +++ b/core/src/integration-test/java/com/scalar/db/transaction/jdbc/JdbcTransactionAdminIntegrationTest.java @@ -1,11 +1,20 @@ package com.scalar.db.transaction.jdbc; +import com.google.common.util.concurrent.Uninterruptibles; +import com.scalar.db.api.DistributedTransaction; import com.scalar.db.api.DistributedTransactionAdminIntegrationTestBase; +import com.scalar.db.api.DistributedTransactionManager; +import com.scalar.db.api.Insert; +import com.scalar.db.api.Result; +import com.scalar.db.api.Scan; import com.scalar.db.config.DatabaseConfig; import com.scalar.db.exception.storage.ExecutionException; +import com.scalar.db.exception.transaction.TransactionException; import com.scalar.db.storage.jdbc.JdbcConfig; import com.scalar.db.storage.jdbc.JdbcEnv; +import java.util.List; import java.util.Properties; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIf; @@ -160,4 +169,29 @@ public void dropCoordinatorTables_IfExist_CoordinatorTablesDoNotExist_ShouldNotT throws ExecutionException { super.dropCoordinatorTables_IfExist_CoordinatorTablesDoNotExist_ShouldNotThrowAnyException(); } + + @Override + protected void transactionalInsert(Insert insert) throws TransactionException { + // Wait for cache expiry + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); + + try (DistributedTransactionManager manager = transactionFactory.getTransactionManager()) { + DistributedTransaction transaction = manager.start(); + transaction.insert(insert); + transaction.commit(); + } + } + + @Override + protected List transactionalScan(Scan scan) throws TransactionException { + // Wait for cache expiry + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); + + try (DistributedTransactionManager manager = transactionFactory.getTransactionManager()) { + DistributedTransaction transaction = manager.start(); + List results = transaction.scan(scan); + transaction.commit(); + return results; + } + } } diff --git a/integration-test/src/main/java/com/scalar/db/api/DistributedTransactionAdminIntegrationTestBase.java b/integration-test/src/main/java/com/scalar/db/api/DistributedTransactionAdminIntegrationTestBase.java index 8f6d173a6e..a1cfd07788 100644 --- a/integration-test/src/main/java/com/scalar/db/api/DistributedTransactionAdminIntegrationTestBase.java +++ b/integration-test/src/main/java/com/scalar/db/api/DistributedTransactionAdminIntegrationTestBase.java @@ -391,35 +391,45 @@ public void dropTable_IfExists_ForNonExistingTable_ShouldNotThrowAnyException() @Test public void truncateTable_ShouldTruncateProperly() throws ExecutionException, TransactionException { - DistributedTransactionManager manager = null; + // Use a separate table name to avoid hitting the stale cache, which can cause test failure when + // executing DMLs + String table = "table_for_truncate"; + try { // Arrange - Key partitionKey = new Key(COL_NAME2, "aaa", COL_NAME1, 1); - Key clusteringKey = new Key(COL_NAME4, 2, COL_NAME3, "bbb"); - manager = transactionFactory.getTransactionManager(); - manager.put( - new Put(partitionKey, clusteringKey) - .withValue(COL_NAME5, 3) - .withValue(COL_NAME6, "ccc") - .withValue(COL_NAME7, 4L) - .withValue(COL_NAME8, 1.0f) - .withValue(COL_NAME9, 1.0d) - .withValue(COL_NAME10, true) - .withValue(COL_NAME11, "ddd".getBytes(StandardCharsets.UTF_8)) - .forNamespace(namespace1) - .forTable(TABLE1)); + Map options = getCreationOptions(); + admin.createTable(namespace1, table, TABLE_METADATA, true, options); + Key partitionKey = Key.of(COL_NAME2, "aaa", COL_NAME1, 1); + Key clusteringKey = Key.of(COL_NAME4, 2, COL_NAME3, "bbb"); + transactionalInsert( + Insert.newBuilder() + .namespace(namespace1) + .table(table) + .partitionKey(partitionKey) + .clusteringKey(clusteringKey) + .intValue(COL_NAME5, 3) + .textValue(COL_NAME6, "ccc") + .bigIntValue(COL_NAME7, 4L) + .floatValue(COL_NAME8, 1.0f) + .doubleValue(COL_NAME9, 1.0d) + .booleanValue(COL_NAME10, true) + .blobValue(COL_NAME11, "ddd".getBytes(StandardCharsets.UTF_8)) + .build()); // Act - admin.truncateTable(namespace1, TABLE1); + admin.truncateTable(namespace1, table); // Assert List results = - manager.scan(new Scan(partitionKey).forNamespace(namespace1).forTable(TABLE1)); + transactionalScan( + Scan.newBuilder() + .namespace(namespace1) + .table(table) + .partitionKey(partitionKey) + .build()); assertThat(results).isEmpty(); } finally { - if (manager != null) { - manager.close(); - } + admin.dropTable(namespace1, table, true); } } @@ -467,7 +477,10 @@ public void tableExists_ShouldReturnCorrectResults() throws ExecutionException { @Test public void createIndex_ForAllDataTypesWithExistingData_ShouldCreateIndexesCorrectly() throws Exception { - DistributedTransactionManager transactionManager = null; + // Use a separate table name to avoid hitting the stale cache, which can cause test failure when + // executing DMLs + String table = "table_for_create_index"; + try { // Arrange Map options = getCreationOptions(); @@ -485,12 +498,11 @@ public void createIndex_ForAllDataTypesWithExistingData_ShouldCreateIndexesCorre .addPartitionKey(COL_NAME1) .addSecondaryIndex(COL_NAME9) .build(); - admin.createTable(namespace1, TABLE4, metadata, options); - transactionManager = transactionFactory.getTransactionManager(); - transactionManager.put( - Put.newBuilder() + admin.createTable(namespace1, table, metadata, options); + Insert insert = + Insert.newBuilder() .namespace(namespace1) - .table(TABLE4) + .table(table) .partitionKey(Key.ofInt(COL_NAME1, 1)) .intValue(COL_NAME2, 2) .textValue(COL_NAME3, "3") @@ -500,45 +512,43 @@ public void createIndex_ForAllDataTypesWithExistingData_ShouldCreateIndexesCorre .booleanValue(COL_NAME7, true) .blobValue(COL_NAME8, "8".getBytes(StandardCharsets.UTF_8)) .textValue(COL_NAME9, "9") - .build()); + .build(); + transactionalInsert(insert); // Act - admin.createIndex(namespace1, TABLE4, COL_NAME2, options); - admin.createIndex(namespace1, TABLE4, COL_NAME3, options); - admin.createIndex(namespace1, TABLE4, COL_NAME4, options); - admin.createIndex(namespace1, TABLE4, COL_NAME5, options); - admin.createIndex(namespace1, TABLE4, COL_NAME6, options); + admin.createIndex(namespace1, table, COL_NAME2, options); + admin.createIndex(namespace1, table, COL_NAME3, options); + admin.createIndex(namespace1, table, COL_NAME4, options); + admin.createIndex(namespace1, table, COL_NAME5, options); + admin.createIndex(namespace1, table, COL_NAME6, options); if (isIndexOnBooleanColumnSupported()) { - admin.createIndex(namespace1, TABLE4, COL_NAME7, options); + admin.createIndex(namespace1, table, COL_NAME7, options); } - admin.createIndex(namespace1, TABLE4, COL_NAME8, options); + admin.createIndex(namespace1, table, COL_NAME8, options); // Assert - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME2)).isTrue(); - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME3)).isTrue(); - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME4)).isTrue(); - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME5)).isTrue(); - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME6)).isTrue(); + assertThat(admin.indexExists(namespace1, table, COL_NAME2)).isTrue(); + assertThat(admin.indexExists(namespace1, table, COL_NAME3)).isTrue(); + assertThat(admin.indexExists(namespace1, table, COL_NAME4)).isTrue(); + assertThat(admin.indexExists(namespace1, table, COL_NAME5)).isTrue(); + assertThat(admin.indexExists(namespace1, table, COL_NAME6)).isTrue(); if (isIndexOnBooleanColumnSupported()) { - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME7)).isTrue(); + assertThat(admin.indexExists(namespace1, table, COL_NAME7)).isTrue(); } - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME8)).isTrue(); + assertThat(admin.indexExists(namespace1, table, COL_NAME8)).isTrue(); if (isIndexOnBooleanColumnSupported()) { - assertThat(admin.getTableMetadata(namespace1, TABLE4).getSecondaryIndexNames()) + assertThat(admin.getTableMetadata(namespace1, table).getSecondaryIndexNames()) .containsOnly( COL_NAME2, COL_NAME3, COL_NAME4, COL_NAME5, COL_NAME6, COL_NAME7, COL_NAME8, COL_NAME9); } else { - assertThat(admin.getTableMetadata(namespace1, TABLE4).getSecondaryIndexNames()) + assertThat(admin.getTableMetadata(namespace1, table).getSecondaryIndexNames()) .containsOnly( COL_NAME2, COL_NAME3, COL_NAME4, COL_NAME5, COL_NAME6, COL_NAME8, COL_NAME9); } } finally { - admin.dropTable(namespace1, TABLE4, true); - if (transactionManager != null) { - transactionManager.close(); - } + admin.dropTable(namespace1, table, true); } } @@ -613,7 +623,10 @@ public void createIndex_IfNotExists_ForAlreadyExistingIndex_ShouldNotThrowAnyExc @Test public void dropIndex_ForAllDataTypesWithExistingData_ShouldDropIndexCorrectly() throws Exception { - DistributedTransactionManager transactionManager = null; + // Use a separate table name to avoid hitting the stale cache, which can cause test failure when + // executing DMLs + String table = "table_for_drop_index"; + try { // Arrange Map options = getCreationOptions(); @@ -641,12 +654,11 @@ public void dropIndex_ForAllDataTypesWithExistingData_ShouldDropIndexCorrectly() if (isIndexOnBooleanColumnSupported()) { metadata = TableMetadata.newBuilder(metadata).addSecondaryIndex(COL_NAME7).build(); } - admin.createTable(namespace1, TABLE4, metadata, options); - transactionManager = transactionFactory.getTransactionManager(); - transactionManager.put( - Put.newBuilder() + admin.createTable(namespace1, table, metadata, options); + Insert insert = + Insert.newBuilder() .namespace(namespace1) - .table(TABLE4) + .table(table) .partitionKey(Key.ofInt(COL_NAME1, 1)) .intValue(COL_NAME2, 2) .textValue(COL_NAME3, "3") @@ -656,34 +668,32 @@ public void dropIndex_ForAllDataTypesWithExistingData_ShouldDropIndexCorrectly() .booleanValue(COL_NAME7, true) .blobValue(COL_NAME8, "8".getBytes(StandardCharsets.UTF_8)) .textValue(COL_NAME9, "9") - .build()); + .build(); + transactionalInsert(insert); // Act - admin.dropIndex(namespace1, TABLE4, COL_NAME2); - admin.dropIndex(namespace1, TABLE4, COL_NAME3); - admin.dropIndex(namespace1, TABLE4, COL_NAME4); - admin.dropIndex(namespace1, TABLE4, COL_NAME5); - admin.dropIndex(namespace1, TABLE4, COL_NAME6); + admin.dropIndex(namespace1, table, COL_NAME2); + admin.dropIndex(namespace1, table, COL_NAME3); + admin.dropIndex(namespace1, table, COL_NAME4); + admin.dropIndex(namespace1, table, COL_NAME5); + admin.dropIndex(namespace1, table, COL_NAME6); if (isIndexOnBooleanColumnSupported()) { - admin.dropIndex(namespace1, TABLE4, COL_NAME7); + admin.dropIndex(namespace1, table, COL_NAME7); } - admin.dropIndex(namespace1, TABLE4, COL_NAME8); + admin.dropIndex(namespace1, table, COL_NAME8); // Assert - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME2)).isFalse(); - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME3)).isFalse(); - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME4)).isFalse(); - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME5)).isFalse(); - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME6)).isFalse(); - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME7)).isFalse(); - assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME8)).isFalse(); - assertThat(admin.getTableMetadata(namespace1, TABLE4).getSecondaryIndexNames()) + assertThat(admin.indexExists(namespace1, table, COL_NAME2)).isFalse(); + assertThat(admin.indexExists(namespace1, table, COL_NAME3)).isFalse(); + assertThat(admin.indexExists(namespace1, table, COL_NAME4)).isFalse(); + assertThat(admin.indexExists(namespace1, table, COL_NAME5)).isFalse(); + assertThat(admin.indexExists(namespace1, table, COL_NAME6)).isFalse(); + assertThat(admin.indexExists(namespace1, table, COL_NAME7)).isFalse(); + assertThat(admin.indexExists(namespace1, table, COL_NAME8)).isFalse(); + assertThat(admin.getTableMetadata(namespace1, table).getSecondaryIndexNames()) .containsOnly(COL_NAME9); } finally { - admin.dropTable(namespace1, TABLE4, true); - if (transactionManager != null) { - transactionManager.close(); - } + admin.dropTable(namespace1, table, true); } } @@ -886,4 +896,8 @@ public void getNamespaceNames_ShouldReturnCreatedNamespaces() throws ExecutionEx protected boolean isIndexOnBooleanColumnSupported() { return true; } + + protected abstract void transactionalInsert(Insert insert) throws TransactionException; + + protected abstract List transactionalScan(Scan scan) throws TransactionException; } diff --git a/integration-test/src/main/java/com/scalar/db/transaction/consensuscommit/ConsensusCommitAdminIntegrationTestBase.java b/integration-test/src/main/java/com/scalar/db/transaction/consensuscommit/ConsensusCommitAdminIntegrationTestBase.java index e35015b424..1f1094834e 100644 --- a/integration-test/src/main/java/com/scalar/db/transaction/consensuscommit/ConsensusCommitAdminIntegrationTestBase.java +++ b/integration-test/src/main/java/com/scalar/db/transaction/consensuscommit/ConsensusCommitAdminIntegrationTestBase.java @@ -1,7 +1,16 @@ package com.scalar.db.transaction.consensuscommit; +import com.google.common.util.concurrent.Uninterruptibles; +import com.scalar.db.api.DistributedTransaction; import com.scalar.db.api.DistributedTransactionAdminIntegrationTestBase; +import com.scalar.db.api.DistributedTransactionManager; +import com.scalar.db.api.Insert; +import com.scalar.db.api.Result; +import com.scalar.db.api.Scan; +import com.scalar.db.exception.transaction.TransactionException; +import java.util.List; import java.util.Properties; +import java.util.concurrent.TimeUnit; public abstract class ConsensusCommitAdminIntegrationTestBase extends DistributedTransactionAdminIntegrationTestBase { @@ -23,4 +32,29 @@ protected final Properties getProperties(String testName) { } protected abstract Properties getProps(String testName); + + @Override + protected void transactionalInsert(Insert insert) throws TransactionException { + // Wait for cache expiry + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); + + try (DistributedTransactionManager manager = transactionFactory.getTransactionManager()) { + DistributedTransaction transaction = manager.start(); + transaction.insert(insert); + transaction.commit(); + } + } + + @Override + protected List transactionalScan(Scan scan) throws TransactionException { + // Wait for cache expiry + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); + + try (DistributedTransactionManager manager = transactionFactory.getTransactionManager()) { + DistributedTransaction transaction = manager.start(); + List results = transaction.scan(scan); + transaction.commit(); + return results; + } + } } diff --git a/integration-test/src/main/java/com/scalar/db/transaction/singlecrudoperation/SingleCrudOperationTransactionAdminIntegrationTestBase.java b/integration-test/src/main/java/com/scalar/db/transaction/singlecrudoperation/SingleCrudOperationTransactionAdminIntegrationTestBase.java index e9674f7375..c47da4254d 100644 --- a/integration-test/src/main/java/com/scalar/db/transaction/singlecrudoperation/SingleCrudOperationTransactionAdminIntegrationTestBase.java +++ b/integration-test/src/main/java/com/scalar/db/transaction/singlecrudoperation/SingleCrudOperationTransactionAdminIntegrationTestBase.java @@ -1,9 +1,17 @@ package com.scalar.db.transaction.singlecrudoperation; +import com.google.common.util.concurrent.Uninterruptibles; import com.scalar.db.api.DistributedTransactionAdminIntegrationTestBase; +import com.scalar.db.api.DistributedTransactionManager; +import com.scalar.db.api.Insert; +import com.scalar.db.api.Result; +import com.scalar.db.api.Scan; import com.scalar.db.config.DatabaseConfig; import com.scalar.db.exception.storage.ExecutionException; +import com.scalar.db.exception.transaction.TransactionException; +import java.util.List; import java.util.Properties; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -79,4 +87,24 @@ public void dropCoordinatorTables_IfExist_CoordinatorTablesDoNotExist_ShouldNotT throws ExecutionException { super.dropCoordinatorTables_IfExist_CoordinatorTablesDoNotExist_ShouldNotThrowAnyException(); } + + @Override + protected void transactionalInsert(Insert insert) throws TransactionException { + // Wait for cache expiry + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); + + try (DistributedTransactionManager manager = transactionFactory.getTransactionManager()) { + manager.insert(insert); + } + } + + @Override + protected List transactionalScan(Scan scan) throws TransactionException { + // Wait for cache expiry + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); + + try (DistributedTransactionManager manager = transactionFactory.getTransactionManager()) { + return manager.scan(scan); + } + } }