Skip to content

Commit e3dec86

Browse files
committed
Add Cassandra permission test
1 parent 54ab4e6 commit e3dec86

File tree

9 files changed

+1197
-0
lines changed

9 files changed

+1197
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
name: Test Permissions
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
7+
env:
8+
TERM: dumb
9+
JAVA_VERSION: '8'
10+
JAVA_VENDOR: 'temurin'
11+
12+
jobs:
13+
integration-test-permission-cassandra-3-0:
14+
name: Cassandra 3.0 Permission Integration Test
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Set up JDK ${{ env.JAVA_VERSION }} (${{ env.JAVA_VENDOR }})
21+
uses: actions/setup-java@v4
22+
with:
23+
java-version: ${{ env.JAVA_VERSION }}
24+
distribution: ${{ env.JAVA_VENDOR }}
25+
26+
- name: Setup Gradle
27+
uses: gradle/actions/setup-gradle@v4
28+
29+
- name: Start Cassandra with authentication enabled
30+
run: |
31+
docker run -d --name cassandra \
32+
-p 9042:9042 \
33+
-e CASSANDRA_PASSWORD_SEEDER=yes \
34+
-e CASSANDRA_PASSWORD=cassandra \
35+
-e CASSANDRA_AUTHENTICATOR=PasswordAuthenticator \
36+
-e CASSANDRA_AUTHORIZER=CassandraAuthorizer \
37+
bitnami/cassandra:3.0
38+
39+
- name: Wait for Cassandra to be ready
40+
run: sleep 30
41+
42+
- name: Execute Gradle 'integrationTestCassandraPermission' task
43+
run: ./gradlew integrationTestCassandraPermission
44+
45+
- name: Upload Gradle test reports
46+
if: always()
47+
uses: actions/upload-artifact@v4
48+
with:
49+
name: cassandra_3.0_permission_integration_test_reports
50+
path: core/build/reports/tests/integrationTestCassandraPermission
51+
52+
integration-test-permission-cassandra-3-11:
53+
name: Cassandra 3.11 Permission Integration Test
54+
runs-on: ubuntu-latest
55+
56+
steps:
57+
- uses: actions/checkout@v4
58+
59+
- name: Set up JDK ${{ env.JAVA_VERSION }} (${{ env.JAVA_VENDOR }})
60+
uses: actions/setup-java@v4
61+
with:
62+
java-version: ${{ env.JAVA_VERSION }}
63+
distribution: ${{ env.JAVA_VENDOR }}
64+
65+
- name: Setup Gradle
66+
uses: gradle/actions/setup-gradle@v4
67+
68+
- name: Start Cassandra with authentication enabled
69+
run: |
70+
docker run -d --name cassandra \
71+
-p 9042:9042 \
72+
-e CASSANDRA_PASSWORD_SEEDER=yes \
73+
-e CASSANDRA_PASSWORD=cassandra \
74+
-e CASSANDRA_AUTHENTICATOR=PasswordAuthenticator \
75+
-e CASSANDRA_AUTHORIZER=CassandraAuthorizer \
76+
bitnami/cassandra:3.11
77+
78+
- name: Wait for Cassandra to be ready
79+
run: sleep 30
80+
81+
- name: Execute Gradle 'integrationTestCassandraPermission' task
82+
run: ./gradlew integrationTestCassandraPermission
83+
84+
- name: Upload Gradle test reports
85+
if: always()
86+
uses: actions/upload-artifact@v4
87+
with:
88+
name: cassandra_3.11_permission_integration_test_reports
89+
path: core/build/reports/tests/integrationTestCassandraPermission

core/build.gradle

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ sourceSets {
2222
srcDir file('src/integration-test/java')
2323
include '**/com/scalar/db/common/*.java'
2424
include '**/com/scalar/db/storage/cassandra/*.java'
25+
exclude '**/com/scalar/db/storage/cassandra/CassandraPermissionTestUtils.java'
26+
exclude '**/com/scalar/db/storage/cassandra/CassandraPermissionIntegrationTest.java'
27+
exclude '**/com/scalar/db/storage/cassandra/CassandraAdminPermissionIntegrationTest.java'
2528
}
2629
resources.srcDir file('src/integration-test/resources')
2730
}
@@ -67,6 +70,20 @@ sourceSets {
6770
}
6871
resources.srcDir file('src/integration-test/resources')
6972
}
73+
integrationTestCassandraPermission {
74+
java {
75+
compileClasspath += main.output + test.output
76+
runtimeClasspath += main.output + test.output
77+
srcDir file('src/integration-test/java')
78+
include '**/com/scalar/db/common/*.java'
79+
include '**/com/scalar/db/storage/cassandra/CassandraPermissionTestUtils.java'
80+
include '**/com/scalar/db/storage/cassandra/CassandraAdminTestUtils.java'
81+
include '**/com/scalar/db/storage/cassandra/CassandraEnv.java'
82+
include '**/com/scalar/db/storage/cassandra/CassandraPermissionIntegrationTest.java'
83+
include '**/com/scalar/db/storage/cassandra/CassandraAdminPermissionIntegrationTest.java'
84+
}
85+
resources.srcDir file('src/integration-test/resources')
86+
}
7087
}
7188

7289
configurations {
@@ -88,6 +105,9 @@ configurations {
88105
integrationTestMultiStorageImplementation.extendsFrom testImplementation
89106
integrationTestMultiStorageRuntimeOnly.extendsFrom testRuntimeOnly
90107
integrationTestMultiStorageCompileOnly.extendsFrom testCompileOnly
108+
integrationTestCassandraPermissionImplementation.extendsFrom testImplementation
109+
integrationTestCassandraPermissionRuntimeOnly.extendsFrom testRuntimeOnly
110+
integrationTestCassandraPermissionCompileOnly.extendsFrom testCompileOnly
91111
}
92112

93113
dependencies {
@@ -200,6 +220,17 @@ task integrationTestMultiStorage(type: Test) {
200220
}
201221
}
202222

223+
task integrationTestCassandraPermission(type: Test) {
224+
description = 'Runs the integration tests for Cassandra permissions.'
225+
group = 'verification'
226+
testClassesDirs = sourceSets.integrationTestCassandraPermission.output.classesDirs
227+
classpath = sourceSets.integrationTestCassandraPermission.runtimeClasspath
228+
outputs.upToDateWhen { false } // ensures integration tests are run every time when called
229+
options {
230+
systemProperties(System.getProperties().findAll { it.key.toString().startsWith("scalardb") })
231+
}
232+
}
233+
203234
spotless {
204235
java {
205236
target 'src/*/java/**/*.java'
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package com.scalar.db.storage.cassandra;
2+
3+
import com.google.common.util.concurrent.Uninterruptibles;
4+
import com.scalar.db.api.DistributedStorageAdminPermissionIntegrationTestBase;
5+
import com.scalar.db.util.AdminTestUtils;
6+
import com.scalar.db.util.PermissionTestUtils;
7+
import java.util.Collections;
8+
import java.util.Map;
9+
import java.util.Properties;
10+
import org.junit.jupiter.api.Disabled;
11+
import org.junit.jupiter.api.Test;
12+
13+
public class CassandraAdminPermissionIntegrationTest
14+
extends DistributedStorageAdminPermissionIntegrationTestBase {
15+
private static final int SLEEP_BETWEEN_RETRIES_SECONDS = 3;
16+
private static final int MAX_RETRY_COUNT = 10;
17+
18+
@Override
19+
protected Properties getProperties(String testName) {
20+
return CassandraEnv.getProperties(testName);
21+
}
22+
23+
@Override
24+
protected Properties getPropertiesForNormalUser(String testName) {
25+
return CassandraEnv.getPropertiesForNormalUser(testName);
26+
}
27+
28+
@Override
29+
protected AdminTestUtils getAdminTestUtils(String testName) {
30+
return new CassandraAdminTestUtils(getProperties(testName));
31+
}
32+
33+
@Override
34+
protected PermissionTestUtils getPermissionTestUtils(String testName) {
35+
return new CassandraPermissionTestUtils(getProperties(testName));
36+
}
37+
38+
@Override
39+
protected Map<String, String> getCreationOptions() {
40+
return Collections.singletonMap(CassandraAdmin.REPLICATION_FACTOR, "1");
41+
}
42+
43+
@Override
44+
protected void waitForNamespaceCreation() {
45+
try {
46+
AdminTestUtils utils = getAdminTestUtils(TEST_NAME);
47+
int retryCount = 0;
48+
while (retryCount < MAX_RETRY_COUNT) {
49+
if (utils.namespaceExists(NAMESPACE)) {
50+
utils.close();
51+
return;
52+
}
53+
Uninterruptibles.sleepUninterruptibly(
54+
SLEEP_BETWEEN_RETRIES_SECONDS, java.util.concurrent.TimeUnit.SECONDS);
55+
retryCount++;
56+
}
57+
utils.close();
58+
throw new RuntimeException("Namespace was not created after " + MAX_RETRY_COUNT + " retries");
59+
} catch (Exception e) {
60+
throw new RuntimeException("Failed to wait for namespace creation", e);
61+
}
62+
}
63+
64+
@Override
65+
protected void waitForTableCreation() {
66+
try {
67+
AdminTestUtils utils = getAdminTestUtils(TEST_NAME);
68+
int retryCount = 0;
69+
while (retryCount < MAX_RETRY_COUNT) {
70+
if (utils.tableExists(NAMESPACE, TABLE)) {
71+
utils.close();
72+
return;
73+
}
74+
Uninterruptibles.sleepUninterruptibly(
75+
SLEEP_BETWEEN_RETRIES_SECONDS, java.util.concurrent.TimeUnit.SECONDS);
76+
retryCount++;
77+
}
78+
utils.close();
79+
throw new RuntimeException("Table was not created after " + MAX_RETRY_COUNT + " retries");
80+
} catch (Exception e) {
81+
throw new RuntimeException("Failed to wait for table creation", e);
82+
}
83+
}
84+
85+
@Override
86+
protected void waitForNamespaceDeletion() {
87+
try {
88+
AdminTestUtils utils = getAdminTestUtils(TEST_NAME);
89+
int retryCount = 0;
90+
while (retryCount < MAX_RETRY_COUNT) {
91+
if (!utils.namespaceExists(NAMESPACE)) {
92+
utils.close();
93+
return;
94+
}
95+
Uninterruptibles.sleepUninterruptibly(
96+
SLEEP_BETWEEN_RETRIES_SECONDS, java.util.concurrent.TimeUnit.MILLISECONDS);
97+
retryCount++;
98+
}
99+
utils.close();
100+
throw new RuntimeException("Namespace was not deleted after " + MAX_RETRY_COUNT + " retries");
101+
} catch (Exception e) {
102+
throw new RuntimeException("Failed to wait for namespace deletion", e);
103+
}
104+
}
105+
106+
@Override
107+
protected void waitForTableDeletion() {
108+
try {
109+
AdminTestUtils utils = getAdminTestUtils(TEST_NAME);
110+
int retryCount = 0;
111+
while (retryCount < MAX_RETRY_COUNT) {
112+
if (!utils.tableExists(NAMESPACE, TABLE)) {
113+
utils.close();
114+
return;
115+
}
116+
Uninterruptibles.sleepUninterruptibly(
117+
SLEEP_BETWEEN_RETRIES_SECONDS, java.util.concurrent.TimeUnit.SECONDS);
118+
retryCount++;
119+
}
120+
utils.close();
121+
throw new RuntimeException("Table was not deleted after " + MAX_RETRY_COUNT + " retries");
122+
} catch (Exception e) {
123+
throw new RuntimeException("Failed to wait for table deletion", e);
124+
}
125+
}
126+
127+
@Test
128+
@Override
129+
@Disabled("Import-related functionality is not supported in Cassandra")
130+
public void getImportTableMetadata_WithSufficientPermission_ShouldSucceed() {}
131+
132+
@Test
133+
@Override
134+
@Disabled("Import-related functionality is not supported in Cassandra")
135+
public void addRawColumnToTable_WithSufficientPermission_ShouldSucceed() {}
136+
137+
@Test
138+
@Override
139+
@Disabled("Import-related functionality is not supported in Cassandra")
140+
public void importTable_WithSufficientPermission_ShouldSucceed() {}
141+
}

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ public final class CassandraEnv {
77
private static final String PROP_CASSANDRA_CONTACT_POINTS = "scalardb.cassandra.contact_points";
88
private static final String PROP_CASSANDRA_USERNAME = "scalardb.cassandra.username";
99
private static final String PROP_CASSANDRA_PASSWORD = "scalardb.cassandra.password";
10+
private static final String PROP_CASSANDRA_NORMAL_USERNAME = "scalardb.cassandra.normal_username";
11+
private static final String PROP_CASSANDRA_NORMAL_PASSWORD = "scalardb.cassandra.normal_password";
1012

1113
private static final String DEFAULT_CASSANDRA_CONTACT_POINTS = "localhost";
1214
private static final String DEFAULT_CASSANDRA_USERNAME = "cassandra";
1315
private static final String DEFAULT_CASSANDRA_PASSWORD = "cassandra";
16+
private static final String DEFAULT_CASSANDRA_NORMAL_USERNAME = "test";
17+
private static final String DEFAULT_CASSANDRA_NORMAL_PASSWORD = "test";
1418

1519
private CassandraEnv() {}
1620

@@ -35,4 +39,28 @@ public static Properties getProperties(String testName) {
3539

3640
return properties;
3741
}
42+
43+
public static Properties getPropertiesForNormalUser(String testName) {
44+
String contactPoints =
45+
System.getProperty(PROP_CASSANDRA_CONTACT_POINTS, DEFAULT_CASSANDRA_CONTACT_POINTS);
46+
String username =
47+
System.getProperty(PROP_CASSANDRA_NORMAL_USERNAME, DEFAULT_CASSANDRA_NORMAL_USERNAME);
48+
String password =
49+
System.getProperty(PROP_CASSANDRA_NORMAL_PASSWORD, DEFAULT_CASSANDRA_NORMAL_PASSWORD);
50+
51+
Properties properties = new Properties();
52+
properties.setProperty(DatabaseConfig.CONTACT_POINTS, contactPoints);
53+
properties.setProperty(DatabaseConfig.USERNAME, username);
54+
properties.setProperty(DatabaseConfig.PASSWORD, password);
55+
properties.setProperty(DatabaseConfig.CROSS_PARTITION_SCAN, "true");
56+
properties.setProperty(DatabaseConfig.CROSS_PARTITION_SCAN_FILTERING, "true");
57+
properties.setProperty(DatabaseConfig.CROSS_PARTITION_SCAN_ORDERING, "false");
58+
59+
// Add testName as a metadata schema suffix
60+
properties.setProperty(
61+
DatabaseConfig.SYSTEM_NAMESPACE_NAME,
62+
DatabaseConfig.DEFAULT_SYSTEM_NAMESPACE_NAME + "_" + testName);
63+
64+
return properties;
65+
}
3866
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.scalar.db.storage.cassandra;
2+
3+
import com.google.common.util.concurrent.Uninterruptibles;
4+
import com.scalar.db.api.DistributedStoragePermissionIntegrationTestBase;
5+
import com.scalar.db.util.AdminTestUtils;
6+
import com.scalar.db.util.PermissionTestUtils;
7+
import java.util.Collections;
8+
import java.util.Map;
9+
import java.util.Properties;
10+
import java.util.concurrent.TimeUnit;
11+
12+
public class CassandraPermissionIntegrationTest
13+
extends DistributedStoragePermissionIntegrationTestBase {
14+
private static final int SLEEP_BETWEEN_RETRIES_SECONDS = 3;
15+
private static final int MAX_RETRY_COUNT = 10;
16+
17+
@Override
18+
protected Properties getProperties(String testName) {
19+
return CassandraEnv.getProperties(testName);
20+
}
21+
22+
@Override
23+
protected Properties getPropertiesForNormalUser(String testName) {
24+
return CassandraEnv.getPropertiesForNormalUser(testName);
25+
}
26+
27+
@Override
28+
protected PermissionTestUtils getPermissionTestUtils(String testName) {
29+
return new CassandraPermissionTestUtils(getProperties(testName));
30+
}
31+
32+
@Override
33+
protected AdminTestUtils getAdminTestUtils(String testName) {
34+
return new CassandraAdminTestUtils(getProperties(testName));
35+
}
36+
37+
@Override
38+
protected Map<String, String> getCreationOptions() {
39+
return Collections.singletonMap(CassandraAdmin.REPLICATION_FACTOR, "1");
40+
}
41+
42+
@Override
43+
protected void waitForTableCreation() {
44+
try {
45+
AdminTestUtils utils = getAdminTestUtils(TEST_NAME);
46+
int retryCount = 0;
47+
while (retryCount < MAX_RETRY_COUNT) {
48+
if (utils.tableExists(NAMESPACE, TABLE)) {
49+
utils.close();
50+
return;
51+
}
52+
Uninterruptibles.sleepUninterruptibly(SLEEP_BETWEEN_RETRIES_SECONDS, TimeUnit.SECONDS);
53+
retryCount++;
54+
}
55+
utils.close();
56+
throw new RuntimeException("Table was not created after " + MAX_RETRY_COUNT + " retries");
57+
} catch (Exception e) {
58+
throw new RuntimeException("Failed to wait for table creation", e);
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)