Skip to content

Commit 8bd13ec

Browse files
committed
Add case-insensitive test cases for storage and storage admin
1 parent 819ae90 commit 8bd13ec

17 files changed

+1832
-1594
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.scalar.db.storage.cassandra;
2+
3+
import com.scalar.db.api.DistributedStorageAdminCaseSensitivityIntegrationTest;
4+
import com.scalar.db.util.AdminTestUtils;
5+
import java.util.Collections;
6+
import java.util.Map;
7+
import java.util.Properties;
8+
9+
public class CassandraAdminCaseSensitivityIntegrationTest
10+
extends DistributedStorageAdminCaseSensitivityIntegrationTest {
11+
@Override
12+
protected Properties getProperties(String testName) {
13+
return CassandraEnv.getProperties(testName);
14+
}
15+
16+
@Override
17+
protected Map<String, String> getCreationOptions() {
18+
return Collections.singletonMap(CassandraAdmin.REPLICATION_FACTOR, "1");
19+
}
20+
21+
@Override
22+
protected AdminTestUtils getAdminTestUtils(String testName) {
23+
return new CassandraAdminTestUtils(getProperties(testName));
24+
}
25+
26+
@Override
27+
protected boolean isTimestampTypeSupported() {
28+
return false;
29+
}
30+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.scalar.db.storage.cassandra;
2+
3+
import com.scalar.db.api.DistributedStorageCaseSensitivityIntegrationTest;
4+
import java.util.Collections;
5+
import java.util.Map;
6+
import java.util.Properties;
7+
import org.junit.jupiter.api.Disabled;
8+
import org.junit.jupiter.api.Test;
9+
10+
public class CassandraCaseSensitivityIntegrationTest
11+
extends DistributedStorageCaseSensitivityIntegrationTest {
12+
@Override
13+
protected Properties getProperties(String testName) {
14+
return CassandraEnv.getProperties(testName);
15+
}
16+
17+
@Override
18+
protected Map<String, String> getCreationOptions() {
19+
return Collections.singletonMap(CassandraAdmin.REPLICATION_FACTOR, "1");
20+
}
21+
22+
@Disabled(
23+
"In Cassandra, if an IS NULL condition is specified for a column in a non-existing record, "
24+
+ "the condition is considered satisfied. This behavior differs from that of other adapters")
25+
@Override
26+
@Test
27+
public void put_withPutIfIsNullWhenRecordDoesNotExist_shouldThrowNoMutationException() {}
28+
}

core/src/integration-test/java/com/scalar/db/storage/cassandra/CassandraWithReservedKeywordIntegrationTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import java.util.Collections;
55
import java.util.Map;
66
import java.util.Properties;
7+
import org.junit.jupiter.api.Disabled;
8+
import org.junit.jupiter.api.Test;
79

810
public class CassandraWithReservedKeywordIntegrationTest
911
extends DistributedStorageWithReservedKeywordIntegrationTestBase {
@@ -58,4 +60,11 @@ protected String getColumnName5() {
5860
protected Properties getProperties(String testName) {
5961
return CassandraEnv.getProperties(testName);
6062
}
63+
64+
@Disabled(
65+
"In Cassandra, if an IS NULL condition is specified for a column in a non-existing record, "
66+
+ "the condition is considered satisfied. This behavior differs from that of other adapters")
67+
@Override
68+
@Test
69+
public void put_withPutIfIsNullWhenRecordDoesNotExist_shouldThrowNoMutationException() {}
6170
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.scalar.db.storage.cosmos;
2+
3+
import com.scalar.db.api.DistributedStorageAdminCaseSensitivityIntegrationTest;
4+
import com.scalar.db.util.AdminTestUtils;
5+
import java.util.Map;
6+
import java.util.Properties;
7+
8+
public class CosmosAdminCaseSensitivityIntegrationTest
9+
extends DistributedStorageAdminCaseSensitivityIntegrationTest {
10+
11+
@Override
12+
protected Properties getProperties(String testName) {
13+
return CosmosEnv.getProperties(testName);
14+
}
15+
16+
@Override
17+
protected Map<String, String> getCreationOptions() {
18+
return CosmosEnv.getCreationOptions();
19+
}
20+
21+
@Override
22+
protected AdminTestUtils getAdminTestUtils(String testName) {
23+
return new CosmosAdminTestUtils(getProperties(testName));
24+
}
25+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.scalar.db.storage.cosmos;
2+
3+
import com.scalar.db.api.DistributedStorageCaseSensitivityIntegrationTest;
4+
import java.util.Map;
5+
import java.util.Properties;
6+
7+
public class CosmosCaseSensitivityIntegrationTest
8+
extends DistributedStorageCaseSensitivityIntegrationTest {
9+
10+
@Override
11+
protected Properties getProperties(String testName) {
12+
return CosmosEnv.getProperties(testName);
13+
}
14+
15+
@Override
16+
protected Map<String, String> getCreationOptions() {
17+
return CosmosEnv.getCreationOptions();
18+
}
19+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.scalar.db.storage.dynamo;
2+
3+
import com.scalar.db.api.DistributedStorageAdminCaseSensitivityIntegrationTest;
4+
import com.scalar.db.util.AdminTestUtils;
5+
import java.util.Map;
6+
import java.util.Properties;
7+
8+
public class DynamoAdminCaseSensitivityIntegrationTest
9+
extends DistributedStorageAdminCaseSensitivityIntegrationTest {
10+
11+
@Override
12+
protected Properties getProperties(String testName) {
13+
return DynamoEnv.getProperties(testName);
14+
}
15+
16+
@Override
17+
protected Map<String, String> getCreationOptions() {
18+
return DynamoEnv.getCreationOptions();
19+
}
20+
21+
@Override
22+
protected boolean isIndexOnBooleanColumnSupported() {
23+
return false;
24+
}
25+
26+
@Override
27+
protected AdminTestUtils getAdminTestUtils(String testName) {
28+
return new DynamoAdminTestUtils(getProperties(testName));
29+
}
30+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.scalar.db.storage.dynamo;
2+
3+
import com.scalar.db.api.DistributedStorageCaseSensitivityIntegrationTest;
4+
import java.util.Map;
5+
import java.util.Properties;
6+
import org.junit.jupiter.api.Disabled;
7+
8+
public class DynamoCaseSensitivityIntegrationTest
9+
extends DistributedStorageCaseSensitivityIntegrationTest {
10+
11+
@Override
12+
protected Properties getProperties(String testName) {
13+
return DynamoEnv.getProperties(testName);
14+
}
15+
16+
@Override
17+
protected Map<String, String> getCreationOptions() {
18+
return DynamoEnv.getCreationOptions();
19+
}
20+
21+
// DynamoDB doesn't support putting a null value for a secondary index column
22+
@Disabled
23+
@Override
24+
public void put_PutGivenForIndexedColumnWithNullValue_ShouldPut() {}
25+
}

core/src/integration-test/java/com/scalar/db/storage/dynamo/DynamoWithReservedKeywordIntegrationTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.scalar.db.api.DistributedStorageWithReservedKeywordIntegrationTestBase;
44
import java.util.Map;
55
import java.util.Properties;
6+
import org.junit.jupiter.api.Disabled;
67

78
public class DynamoWithReservedKeywordIntegrationTest
89
extends DistributedStorageWithReservedKeywordIntegrationTestBase {
@@ -58,4 +59,9 @@ protected Properties getProperties(String testName) {
5859
protected Map<String, String> getCreationOptions() {
5960
return DynamoEnv.getCreationOptions();
6061
}
62+
63+
// DynamoDB doesn't support putting a null value for a secondary index column
64+
@Disabled
65+
@Override
66+
public void put_PutGivenForIndexedColumnWithNullValue_ShouldPut() {}
6167
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.scalar.db.storage.jdbc;
2+
3+
import com.scalar.db.api.DistributedStorageAdminCaseSensitivityIntegrationTest;
4+
import com.scalar.db.config.DatabaseConfig;
5+
import com.scalar.db.util.AdminTestUtils;
6+
import java.util.Properties;
7+
8+
public class JdbcAdminCaseSensitivityIntegrationTest
9+
extends DistributedStorageAdminCaseSensitivityIntegrationTest {
10+
private RdbEngineStrategy rdbEngine;
11+
12+
@Override
13+
protected Properties getProperties(String testName) {
14+
Properties properties = JdbcEnv.getProperties(testName);
15+
rdbEngine = RdbEngineFactory.create(new JdbcConfig(new DatabaseConfig(properties)));
16+
return properties;
17+
}
18+
19+
@Override
20+
protected AdminTestUtils getAdminTestUtils(String testName) {
21+
return new JdbcAdminTestUtils(getProperties(testName));
22+
}
23+
24+
@Override
25+
protected boolean isCreateIndexOnTextAndBlobColumnsEnabled() {
26+
// "admin.createIndex()" for TEXT and BLOB columns fails (the "create index" query runs
27+
// indefinitely) on Db2 community edition version but works on Db2 hosted on IBM Cloud.
28+
// So we disable these tests until the issue is resolved.
29+
return !JdbcTestUtils.isDb2(rdbEngine);
30+
}
31+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package com.scalar.db.storage.jdbc;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import com.scalar.db.api.DistributedStorage;
6+
import com.scalar.db.api.DistributedStorageCaseSensitivityIntegrationTest;
7+
import com.scalar.db.api.Get;
8+
import com.scalar.db.api.Put;
9+
import com.scalar.db.api.Result;
10+
import com.scalar.db.api.Scan;
11+
import com.scalar.db.api.Scanner;
12+
import com.scalar.db.config.DatabaseConfig;
13+
import com.scalar.db.exception.storage.ExecutionException;
14+
import com.scalar.db.io.Key;
15+
import com.scalar.db.service.StorageFactory;
16+
import java.io.IOException;
17+
import java.util.List;
18+
import java.util.Optional;
19+
import java.util.Properties;
20+
import org.junit.jupiter.api.Test;
21+
22+
public class JdbcDatabaseCaseSensitivityIntegrationTest
23+
extends DistributedStorageCaseSensitivityIntegrationTest {
24+
25+
private RdbEngineStrategy rdbEngine;
26+
27+
@Override
28+
protected Properties getProperties(String testName) {
29+
Properties properties = JdbcEnv.getProperties(testName);
30+
JdbcConfig config = new JdbcConfig(new DatabaseConfig(properties));
31+
rdbEngine = RdbEngineFactory.create(config);
32+
return JdbcEnv.getProperties(testName);
33+
}
34+
35+
@Override
36+
protected int getLargeDataSizeInBytes() {
37+
if (JdbcTestUtils.isOracle(rdbEngine)) {
38+
// For Oracle, the max data size for BLOB is 2000 bytes
39+
return 2000;
40+
} else {
41+
return super.getLargeDataSizeInBytes();
42+
}
43+
}
44+
45+
@Test
46+
public void get_InStreamingMode_ShouldRetrieveSingleResult() throws ExecutionException {
47+
if (!JdbcTestUtils.isMysql(rdbEngine) || JdbcTestUtils.isMariaDB(rdbEngine)) {
48+
// MySQL is the only RDB engine that supports streaming mode
49+
return;
50+
}
51+
52+
try (DistributedStorage storage = getStorageInStreamingMode()) {
53+
// Arrange
54+
int pKey = 0;
55+
int cKey = 1;
56+
int value = 2;
57+
58+
storage.put(
59+
Put.newBuilder()
60+
.namespace(namespace)
61+
.table(getTableName())
62+
.partitionKey(Key.ofInt(getColumnName1(), pKey))
63+
.clusteringKey(Key.ofInt(getColumnName4(), cKey))
64+
.intValue(getColumnName3(), value)
65+
.build());
66+
67+
// Act
68+
Optional<Result> result =
69+
storage.get(
70+
Get.newBuilder()
71+
.namespace(namespace)
72+
.table(getTableName())
73+
.partitionKey(Key.ofInt(getColumnName1(), pKey))
74+
.clusteringKey(Key.ofInt(getColumnName4(), cKey))
75+
.build());
76+
77+
// Assert
78+
assertThat(result.isPresent()).isTrue();
79+
assertThat(result.get().getInt(getColumnName1())).isEqualTo(pKey);
80+
assertThat(result.get().getInt(getColumnName4())).isEqualTo(cKey);
81+
assertThat(result.get().getInt(getColumnName3())).isEqualTo(value);
82+
}
83+
}
84+
85+
@Test
86+
public void scan_InStreamingMode_ShouldRetrieveResults() throws IOException, ExecutionException {
87+
if (!JdbcTestUtils.isMysql(rdbEngine) || JdbcTestUtils.isMariaDB(rdbEngine)) {
88+
// MySQL is the only RDB engine that supports streaming mode
89+
return;
90+
}
91+
92+
try (DistributedStorage storage = getStorageInStreamingMode()) {
93+
// Arrange
94+
int pKey = 0;
95+
96+
storage.put(
97+
Put.newBuilder()
98+
.namespace(namespace)
99+
.table(getTableName())
100+
.partitionKey(Key.ofInt(getColumnName1(), pKey))
101+
.clusteringKey(Key.ofInt(getColumnName4(), 0))
102+
.intValue(getColumnName3(), 1)
103+
.build());
104+
storage.put(
105+
Put.newBuilder()
106+
.namespace(namespace)
107+
.table(getTableName())
108+
.partitionKey(Key.ofInt(getColumnName1(), pKey))
109+
.clusteringKey(Key.ofInt(getColumnName4(), 1))
110+
.intValue(getColumnName3(), 2)
111+
.build());
112+
storage.put(
113+
Put.newBuilder()
114+
.namespace(namespace)
115+
.table(getTableName())
116+
.partitionKey(Key.ofInt(getColumnName1(), pKey))
117+
.clusteringKey(Key.ofInt(getColumnName4(), 2))
118+
.intValue(getColumnName3(), 3)
119+
.build());
120+
121+
// Act
122+
Scanner scanner =
123+
storage.scan(
124+
Scan.newBuilder()
125+
.namespace(namespace)
126+
.table(getTableName())
127+
.partitionKey(Key.ofInt(getColumnName1(), pKey))
128+
.build());
129+
List<Result> results = scanner.all();
130+
scanner.close();
131+
132+
// Assert
133+
assertThat(results).hasSize(3);
134+
assertThat(results.get(0).getInt(getColumnName1())).isEqualTo(pKey);
135+
assertThat(results.get(0).getInt(getColumnName4())).isEqualTo(0);
136+
assertThat(results.get(0).getInt(getColumnName3())).isEqualTo(1);
137+
138+
assertThat(results.get(1).getInt(getColumnName1())).isEqualTo(pKey);
139+
assertThat(results.get(1).getInt(getColumnName4())).isEqualTo(1);
140+
assertThat(results.get(1).getInt(getColumnName3())).isEqualTo(2);
141+
142+
assertThat(results.get(2).getInt(getColumnName1())).isEqualTo(pKey);
143+
assertThat(results.get(2).getInt(getColumnName4())).isEqualTo(2);
144+
assertThat(results.get(2).getInt(getColumnName3())).isEqualTo(3);
145+
}
146+
}
147+
148+
private DistributedStorage getStorageInStreamingMode() {
149+
Properties properties = JdbcEnv.getProperties(getTestName());
150+
properties.setProperty(DatabaseConfig.SCAN_FETCH_SIZE, Integer.toString(Integer.MIN_VALUE));
151+
return StorageFactory.create(properties).getStorage();
152+
}
153+
}

0 commit comments

Comments
 (0)