Skip to content

Commit 042b36d

Browse files
feeblefakieKodaiD
andauthored
Backport to branch(3.16) : Add more waits for cache expiry (#3066)
Co-authored-by: Kodai Doki <52027276+KodaiD@users.noreply.github.com>
1 parent b9ad0b1 commit 042b36d

File tree

4 files changed

+197
-89
lines changed

4 files changed

+197
-89
lines changed

core/src/integration-test/java/com/scalar/db/transaction/jdbc/JdbcTransactionAdminIntegrationTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
package com.scalar.db.transaction.jdbc;
22

3+
import com.google.common.util.concurrent.Uninterruptibles;
4+
import com.scalar.db.api.DistributedTransaction;
35
import com.scalar.db.api.DistributedTransactionAdminIntegrationTestBase;
6+
import com.scalar.db.api.DistributedTransactionManager;
7+
import com.scalar.db.api.Insert;
8+
import com.scalar.db.api.Result;
9+
import com.scalar.db.api.Scan;
410
import com.scalar.db.config.DatabaseConfig;
511
import com.scalar.db.exception.storage.ExecutionException;
12+
import com.scalar.db.exception.transaction.TransactionException;
613
import com.scalar.db.storage.jdbc.JdbcConfig;
714
import com.scalar.db.storage.jdbc.JdbcEnv;
815
import com.scalar.db.storage.jdbc.JdbcTestUtils;
916
import com.scalar.db.storage.jdbc.RdbEngineFactory;
1017
import com.scalar.db.storage.jdbc.RdbEngineStrategy;
18+
import java.util.List;
1119
import java.util.Properties;
20+
import java.util.concurrent.TimeUnit;
1221
import org.junit.jupiter.api.Disabled;
1322
import org.junit.jupiter.api.Test;
1423
import org.junit.jupiter.api.condition.DisabledIf;
@@ -174,4 +183,29 @@ protected boolean isCreateIndexOnTextAndBlobColumnsEnabled() {
174183
// So we disable these tests until the issue with the Db2 community edition is resolved.
175184
return !JdbcTestUtils.isDb2(rdbEngine);
176185
}
186+
187+
@Override
188+
protected void transactionalInsert(Insert insert) throws TransactionException {
189+
// Wait for cache expiry
190+
Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
191+
192+
try (DistributedTransactionManager manager = transactionFactory.getTransactionManager()) {
193+
DistributedTransaction transaction = manager.start();
194+
transaction.insert(insert);
195+
transaction.commit();
196+
}
197+
}
198+
199+
@Override
200+
protected List<Result> transactionalScan(Scan scan) throws TransactionException {
201+
// Wait for cache expiry
202+
Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
203+
204+
try (DistributedTransactionManager manager = transactionFactory.getTransactionManager()) {
205+
DistributedTransaction transaction = manager.start();
206+
List<Result> results = transaction.scan(scan);
207+
transaction.commit();
208+
return results;
209+
}
210+
}
177211
}

integration-test/src/main/java/com/scalar/db/api/DistributedTransactionAdminIntegrationTestBase.java

Lines changed: 101 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -425,35 +425,45 @@ public void dropTable_IfExists_ForNonExistingTable_ShouldNotThrowAnyException()
425425
@Test
426426
public void truncateTable_ShouldTruncateProperly()
427427
throws ExecutionException, TransactionException {
428-
DistributedTransactionManager manager = null;
428+
// Use a separate table name to avoid hitting the stale cache, which can cause test failure when
429+
// executing DMLs
430+
String table = "table_for_truncate";
431+
429432
try {
430433
// Arrange
431-
Key partitionKey = new Key(COL_NAME2, "aaa", COL_NAME1, 1);
432-
Key clusteringKey = new Key(COL_NAME4, 2, COL_NAME3, "bbb");
433-
manager = transactionFactory.getTransactionManager();
434-
manager.put(
435-
new Put(partitionKey, clusteringKey)
436-
.withValue(COL_NAME5, 3)
437-
.withValue(COL_NAME6, "ccc")
438-
.withValue(COL_NAME7, 4L)
439-
.withValue(COL_NAME8, 1.0f)
440-
.withValue(COL_NAME9, 1.0d)
441-
.withValue(COL_NAME10, true)
442-
.withValue(COL_NAME11, "ddd".getBytes(StandardCharsets.UTF_8))
443-
.forNamespace(namespace1)
444-
.forTable(TABLE1));
434+
Map<String, String> options = getCreationOptions();
435+
admin.createTable(namespace1, table, TABLE_METADATA, true, options);
436+
Key partitionKey = Key.of(COL_NAME2, "aaa", COL_NAME1, 1);
437+
Key clusteringKey = Key.of(COL_NAME4, 2, COL_NAME3, "bbb");
438+
transactionalInsert(
439+
Insert.newBuilder()
440+
.namespace(namespace1)
441+
.table(table)
442+
.partitionKey(partitionKey)
443+
.clusteringKey(clusteringKey)
444+
.intValue(COL_NAME5, 3)
445+
.textValue(COL_NAME6, "ccc")
446+
.bigIntValue(COL_NAME7, 4L)
447+
.floatValue(COL_NAME8, 1.0f)
448+
.doubleValue(COL_NAME9, 1.0d)
449+
.booleanValue(COL_NAME10, true)
450+
.blobValue(COL_NAME11, "ddd".getBytes(StandardCharsets.UTF_8))
451+
.build());
445452

446453
// Act
447-
admin.truncateTable(namespace1, TABLE1);
454+
admin.truncateTable(namespace1, table);
448455

449456
// Assert
450457
List<Result> results =
451-
manager.scan(new Scan(partitionKey).forNamespace(namespace1).forTable(TABLE1));
458+
transactionalScan(
459+
Scan.newBuilder()
460+
.namespace(namespace1)
461+
.table(table)
462+
.partitionKey(partitionKey)
463+
.build());
452464
assertThat(results).isEmpty();
453465
} finally {
454-
if (manager != null) {
455-
manager.close();
456-
}
466+
admin.dropTable(namespace1, table, true);
457467
}
458468
}
459469

@@ -501,7 +511,10 @@ public void tableExists_ShouldReturnCorrectResults() throws ExecutionException {
501511
@Test
502512
public void createIndex_ForAllDataTypesWithExistingData_ShouldCreateIndexesCorrectly()
503513
throws Exception {
504-
DistributedTransactionManager transactionManager = null;
514+
// Use a separate table name to avoid hitting the stale cache, which can cause test failure when
515+
// executing DMLs
516+
String table = "table_for_create_index";
517+
505518
try {
506519
// Arrange
507520
Map<String, String> options = getCreationOptions();
@@ -525,12 +538,11 @@ public void createIndex_ForAllDataTypesWithExistingData_ShouldCreateIndexesCorre
525538
metadataBuilder = metadataBuilder.addColumn(COL_NAME13, DataType.TIMESTAMP);
526539
}
527540
TableMetadata metadata = metadataBuilder.build();
528-
admin.createTable(namespace1, TABLE4, metadata, options);
529-
transactionManager = transactionFactory.getTransactionManager();
541+
admin.createTable(namespace1, table, metadata, options);
530542
InsertBuilder.Buildable insert =
531543
Insert.newBuilder()
532544
.namespace(namespace1)
533-
.table(TABLE4)
545+
.table(table)
534546
.partitionKey(Key.ofInt(COL_NAME1, 1))
535547
.intValue(COL_NAME2, 2)
536548
.textValue(COL_NAME3, "3")
@@ -551,49 +563,49 @@ public void createIndex_ForAllDataTypesWithExistingData_ShouldCreateIndexesCorre
551563
COL_NAME13,
552564
LocalDateTime.of(LocalDate.of(2020, 6, 2), LocalTime.of(12, 2, 6, 123_000_000)));
553565
}
554-
transactionManager.insert(insert.build());
566+
transactionalInsert(insert.build());
555567

556568
// Act
557-
admin.createIndex(namespace1, TABLE4, COL_NAME2, options);
558-
admin.createIndex(namespace1, TABLE4, COL_NAME4, options);
559-
admin.createIndex(namespace1, TABLE4, COL_NAME5, options);
560-
admin.createIndex(namespace1, TABLE4, COL_NAME6, options);
569+
admin.createIndex(namespace1, table, COL_NAME2, options);
570+
admin.createIndex(namespace1, table, COL_NAME4, options);
571+
admin.createIndex(namespace1, table, COL_NAME5, options);
572+
admin.createIndex(namespace1, table, COL_NAME6, options);
561573
if (isIndexOnBooleanColumnSupported()) {
562-
admin.createIndex(namespace1, TABLE4, COL_NAME7, options);
574+
admin.createIndex(namespace1, table, COL_NAME7, options);
563575
}
564-
admin.createIndex(namespace1, TABLE4, COL_NAME10, options);
565-
admin.createIndex(namespace1, TABLE4, COL_NAME11, options);
566-
admin.createIndex(namespace1, TABLE4, COL_NAME12, options);
576+
admin.createIndex(namespace1, table, COL_NAME10, options);
577+
admin.createIndex(namespace1, table, COL_NAME11, options);
578+
admin.createIndex(namespace1, table, COL_NAME12, options);
567579
if (isTimestampTypeSupported()) {
568-
admin.createIndex(namespace1, TABLE4, COL_NAME13, options);
580+
admin.createIndex(namespace1, table, COL_NAME13, options);
569581
}
570582
if (isCreateIndexOnTextAndBlobColumnsEnabled()) {
571-
admin.createIndex(namespace1, TABLE4, COL_NAME3, options);
572-
admin.createIndex(namespace1, TABLE4, COL_NAME8, options);
583+
admin.createIndex(namespace1, table, COL_NAME3, options);
584+
admin.createIndex(namespace1, table, COL_NAME8, options);
573585
}
574586

575587
// Assert
576-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME2)).isTrue();
577-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME4)).isTrue();
578-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME5)).isTrue();
579-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME6)).isTrue();
588+
assertThat(admin.indexExists(namespace1, table, COL_NAME2)).isTrue();
589+
assertThat(admin.indexExists(namespace1, table, COL_NAME4)).isTrue();
590+
assertThat(admin.indexExists(namespace1, table, COL_NAME5)).isTrue();
591+
assertThat(admin.indexExists(namespace1, table, COL_NAME6)).isTrue();
580592
if (isIndexOnBooleanColumnSupported()) {
581-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME7)).isTrue();
593+
assertThat(admin.indexExists(namespace1, table, COL_NAME7)).isTrue();
582594
}
583-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME9)).isTrue();
584-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME10)).isTrue();
585-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME11)).isTrue();
586-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME12)).isTrue();
595+
assertThat(admin.indexExists(namespace1, table, COL_NAME9)).isTrue();
596+
assertThat(admin.indexExists(namespace1, table, COL_NAME10)).isTrue();
597+
assertThat(admin.indexExists(namespace1, table, COL_NAME11)).isTrue();
598+
assertThat(admin.indexExists(namespace1, table, COL_NAME12)).isTrue();
587599
if (isTimestampTypeSupported()) {
588-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME13)).isTrue();
600+
assertThat(admin.indexExists(namespace1, table, COL_NAME13)).isTrue();
589601
}
590602
if (isCreateIndexOnTextAndBlobColumnsEnabled()) {
591-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME3)).isTrue();
592-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME8)).isTrue();
603+
assertThat(admin.indexExists(namespace1, table, COL_NAME3)).isTrue();
604+
assertThat(admin.indexExists(namespace1, table, COL_NAME8)).isTrue();
593605
}
594606

595607
Set<String> actualSecondaryIndexNames =
596-
admin.getTableMetadata(namespace1, TABLE4).getSecondaryIndexNames();
608+
admin.getTableMetadata(namespace1, table).getSecondaryIndexNames();
597609
assertThat(actualSecondaryIndexNames)
598610
.contains(COL_NAME2, COL_NAME4, COL_NAME5, COL_NAME9, COL_NAME10, COL_NAME11, COL_NAME12);
599611
int indexCount = 8;
@@ -610,12 +622,8 @@ public void createIndex_ForAllDataTypesWithExistingData_ShouldCreateIndexesCorre
610622
indexCount += 2;
611623
}
612624
assertThat(actualSecondaryIndexNames).hasSize(indexCount);
613-
614625
} finally {
615-
admin.dropTable(namespace1, TABLE4, true);
616-
if (transactionManager != null) {
617-
transactionManager.close();
618-
}
626+
admin.dropTable(namespace1, table, true);
619627
}
620628
}
621629

@@ -690,7 +698,10 @@ public void createIndex_IfNotExists_ForAlreadyExistingIndex_ShouldNotThrowAnyExc
690698
@Test
691699
public void dropIndex_ForAllDataTypesWithExistingData_ShouldDropIndexCorrectly()
692700
throws Exception {
693-
DistributedTransactionManager transactionManager = null;
701+
// Use a separate table name to avoid hitting the stale cache, which can cause test failure when
702+
// executing DMLs
703+
String table = "table_for_drop_index";
704+
694705
try {
695706
// Arrange
696707
Map<String, String> options = getCreationOptions();
@@ -727,12 +738,12 @@ public void dropIndex_ForAllDataTypesWithExistingData_ShouldDropIndexCorrectly()
727738
metadataBuilder.addColumn(COL_NAME13, DataType.TIMESTAMP);
728739
metadataBuilder.addSecondaryIndex(COL_NAME13);
729740
}
730-
admin.createTable(namespace1, TABLE4, metadataBuilder.build(), options);
731-
transactionManager = transactionFactory.getTransactionManager();
732-
PutBuilder.Buildable put =
733-
Put.newBuilder()
741+
admin.createTable(namespace1, table, metadataBuilder.build(), options);
742+
743+
InsertBuilder.Buildable insert =
744+
Insert.newBuilder()
734745
.namespace(namespace1)
735-
.table(TABLE4)
746+
.table(table)
736747
.partitionKey(Key.ofInt(COL_NAME1, 1))
737748
.intValue(COL_NAME2, 2)
738749
.textValue(COL_NAME3, "3")
@@ -748,50 +759,47 @@ public void dropIndex_ForAllDataTypesWithExistingData_ShouldDropIndexCorrectly()
748759
LocalDateTime.of(LocalDate.of(2020, 6, 2), LocalTime.of(12, 2, 6, 123_000_000))
749760
.toInstant(ZoneOffset.UTC));
750761
if (isTimestampTypeSupported()) {
751-
put.timestampValue(
762+
insert.timestampValue(
752763
COL_NAME13,
753764
LocalDateTime.of(LocalDate.of(2020, 6, 2), LocalTime.of(12, 2, 6, 123_000_000)));
754765
}
755-
transactionManager.put(put.build());
766+
transactionalInsert(insert.build());
756767

757768
// Act
758-
admin.dropIndex(namespace1, TABLE4, COL_NAME2);
759-
admin.dropIndex(namespace1, TABLE4, COL_NAME3);
760-
admin.dropIndex(namespace1, TABLE4, COL_NAME4);
761-
admin.dropIndex(namespace1, TABLE4, COL_NAME5);
762-
admin.dropIndex(namespace1, TABLE4, COL_NAME6);
769+
admin.dropIndex(namespace1, table, COL_NAME2);
770+
admin.dropIndex(namespace1, table, COL_NAME3);
771+
admin.dropIndex(namespace1, table, COL_NAME4);
772+
admin.dropIndex(namespace1, table, COL_NAME5);
773+
admin.dropIndex(namespace1, table, COL_NAME6);
763774
if (isIndexOnBooleanColumnSupported()) {
764-
admin.dropIndex(namespace1, TABLE4, COL_NAME7);
775+
admin.dropIndex(namespace1, table, COL_NAME7);
765776
}
766-
admin.dropIndex(namespace1, TABLE4, COL_NAME8);
767-
admin.dropIndex(namespace1, TABLE4, COL_NAME10);
768-
admin.dropIndex(namespace1, TABLE4, COL_NAME11);
769-
admin.dropIndex(namespace1, TABLE4, COL_NAME12);
777+
admin.dropIndex(namespace1, table, COL_NAME8);
778+
admin.dropIndex(namespace1, table, COL_NAME10);
779+
admin.dropIndex(namespace1, table, COL_NAME11);
780+
admin.dropIndex(namespace1, table, COL_NAME12);
770781
if (isTimestampTypeSupported()) {
771-
admin.dropIndex(namespace1, TABLE4, COL_NAME13);
782+
admin.dropIndex(namespace1, table, COL_NAME13);
772783
}
773784

774785
// Assert
775-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME2)).isFalse();
776-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME3)).isFalse();
777-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME4)).isFalse();
778-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME5)).isFalse();
779-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME6)).isFalse();
780-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME7)).isFalse();
781-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME8)).isFalse();
782-
assertThat(admin.getTableMetadata(namespace1, TABLE4).getSecondaryIndexNames())
786+
assertThat(admin.indexExists(namespace1, table, COL_NAME2)).isFalse();
787+
assertThat(admin.indexExists(namespace1, table, COL_NAME3)).isFalse();
788+
assertThat(admin.indexExists(namespace1, table, COL_NAME4)).isFalse();
789+
assertThat(admin.indexExists(namespace1, table, COL_NAME5)).isFalse();
790+
assertThat(admin.indexExists(namespace1, table, COL_NAME6)).isFalse();
791+
assertThat(admin.indexExists(namespace1, table, COL_NAME7)).isFalse();
792+
assertThat(admin.indexExists(namespace1, table, COL_NAME8)).isFalse();
793+
assertThat(admin.getTableMetadata(namespace1, table).getSecondaryIndexNames())
783794
.containsOnly(COL_NAME9);
784-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME10)).isFalse();
785-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME11)).isFalse();
786-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME12)).isFalse();
795+
assertThat(admin.indexExists(namespace1, table, COL_NAME10)).isFalse();
796+
assertThat(admin.indexExists(namespace1, table, COL_NAME11)).isFalse();
797+
assertThat(admin.indexExists(namespace1, table, COL_NAME12)).isFalse();
787798
if (isTimestampTypeSupported()) {
788-
assertThat(admin.indexExists(namespace1, TABLE4, COL_NAME13)).isFalse();
799+
assertThat(admin.indexExists(namespace1, table, COL_NAME13)).isFalse();
789800
}
790801
} finally {
791-
admin.dropTable(namespace1, TABLE4, true);
792-
if (transactionManager != null) {
793-
transactionManager.close();
794-
}
802+
admin.dropTable(namespace1, table, true);
795803
}
796804
}
797805

@@ -1002,4 +1010,8 @@ protected boolean isTimestampTypeSupported() {
10021010
protected boolean isCreateIndexOnTextAndBlobColumnsEnabled() {
10031011
return true;
10041012
}
1013+
1014+
protected abstract void transactionalInsert(Insert insert) throws TransactionException;
1015+
1016+
protected abstract List<Result> transactionalScan(Scan scan) throws TransactionException;
10051017
}

integration-test/src/main/java/com/scalar/db/transaction/consensuscommit/ConsensusCommitAdminIntegrationTestBase.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
package com.scalar.db.transaction.consensuscommit;
22

3+
import com.google.common.util.concurrent.Uninterruptibles;
4+
import com.scalar.db.api.DistributedTransaction;
35
import com.scalar.db.api.DistributedTransactionAdminIntegrationTestBase;
6+
import com.scalar.db.api.DistributedTransactionManager;
7+
import com.scalar.db.api.Insert;
8+
import com.scalar.db.api.Result;
9+
import com.scalar.db.api.Scan;
10+
import com.scalar.db.exception.transaction.TransactionException;
11+
import java.util.List;
412
import java.util.Properties;
13+
import java.util.concurrent.TimeUnit;
514

615
public abstract class ConsensusCommitAdminIntegrationTestBase
716
extends DistributedTransactionAdminIntegrationTestBase {
@@ -23,4 +32,29 @@ protected final Properties getProperties(String testName) {
2332
}
2433

2534
protected abstract Properties getProps(String testName);
35+
36+
@Override
37+
protected void transactionalInsert(Insert insert) throws TransactionException {
38+
// Wait for cache expiry
39+
Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
40+
41+
try (DistributedTransactionManager manager = transactionFactory.getTransactionManager()) {
42+
DistributedTransaction transaction = manager.start();
43+
transaction.insert(insert);
44+
transaction.commit();
45+
}
46+
}
47+
48+
@Override
49+
protected List<Result> transactionalScan(Scan scan) throws TransactionException {
50+
// Wait for cache expiry
51+
Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
52+
53+
try (DistributedTransactionManager manager = transactionFactory.getTransactionManager()) {
54+
DistributedTransaction transaction = manager.start();
55+
List<Result> results = transaction.scan(scan);
56+
transaction.commit();
57+
return results;
58+
}
59+
}
2660
}

0 commit comments

Comments
 (0)