This is an automated email from the ASF dual-hosted git repository.
ycai pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra-sidecar.git
The following commit(s) were added to refs/heads/trunk by this push:
new 385ab54 CASSANDRASC-130: Improve integration test speed (#121)
385ab54 is described below
commit 385ab5444884db09e7e018e24416a13198ea5139
Author: Yifan Cai <[email protected]>
AuthorDate: Fri May 10 13:23:44 2024 -0700
CASSANDRASC-130: Improve integration test speed (#121)
Patch by Yifan Cai; Reviewed by Francisco Guerrero for CASSANDRASC-130
---
.circleci/config.yml | 141 ++++++++++++---------
build.gradle | 11 ++
scripts/build-dtest-jars.sh | 5 +
.../sidecar/db/schema/AbstractSchema.java | 8 --
.../sidecar/db/schema/RestoreJobsSchema.java | 2 +-
.../sidecar/db/schema/RestoreSlicesSchema.java | 2 +-
.../cassandra/sidecar/db/schema/TableSchema.java | 27 ++++
.../sidecar/common/CQLSessionProviderTest.java | 6 +
.../sidecar/common/DelegateIntegrationTest.java | 3 +
.../db/RestoreJobsDatabaseAccessorIntTest.java | 3 +-
.../tokenrange/BaseTokenRangeIntegrationTest.java | 3 +-
.../sidecar/routes/tokenrange/JoiningBaseTest.java | 3 +-
.../tokenrange/JoiningTestDoubleCluster.java | 43 ++-----
.../routes/tokenrange/JoiningTestMultiDC.java | 43 ++-----
.../JoiningTestMultiDCSingleReplicated.java | 43 ++-----
.../tokenrange/JoiningTestMultipleNodes.java | 43 ++-----
.../routes/tokenrange/JoiningTestSingleNode.java | 43 ++-----
.../sidecar/routes/tokenrange/LeavingBaseTest.java | 4 +-
.../sidecar/routes/tokenrange/LeavingTest.java | 9 +-
.../routes/tokenrange/LeavingTestMultiDC.java | 6 +-
.../tokenrange/LeavingTestMultiDCHalveCluster.java | 6 +-
.../sidecar/routes/tokenrange/MovingBaseTest.java | 3 +-
.../routes/tokenrange/MovingMultiDCTest.java | 6 +-
.../sidecar/routes/tokenrange/MovingTest.java | 6 +-
.../routes/tokenrange/ReplacementBaseTest.java | 47 +++++--
.../routes/tokenrange/ReplacementMultiDCTest.java | 45 ++-----
.../sidecar/routes/tokenrange/ReplacementTest.java | 45 ++-----
.../sidecar/testing/BootstrapBBUtils.java | 53 ++++++++
.../testing/CassandraSidecarTestContext.java | 77 +++++++----
.../sidecar/testing/IntegrationTestBase.java | 13 +-
.../sidecar/testing/IntegrationTestModule.java | 32 +++--
.../cassandra/testing/CassandraTestTemplate.java | 6 +
.../testing/ConfigurableCassandraTestContext.java | 1 +
33 files changed, 415 insertions(+), 373 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 2f0acb1..8f263a9 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -38,94 +38,104 @@ aliases:
TERM: dumb
TZ: "America/Los_Angeles"
-# we might modify this in the future to accept a parameter for the java
package to install
commands:
- install_java:
- description: "Installs Java using AdoptOpenJDK"
- parameters:
- version:
- type: string
- steps:
- - run: wget -qO -
https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | sudo apt-key
add -
- - run: sudo add-apt-repository --yes
https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/
- - run: sudo apt-get update
- - run: sudo apt-get install -y << parameters.version>>
-
install_common:
- description: "Installs common software and certificates"
steps:
- run: sudo apt-get update
- - run: sudo apt-get install apt-transport-https ca-certificates curl
gnupg-agent software-properties-common
+ # Somehow, the certs already installed in the java 11 image are
installed strangely
+ # in that there's a directory called `cacerts` with a symlink in it
named `cacerts`
+ # (/etc/ssl/certs/java/cacerts/cacerts) rather than just a symlink to
+ # `cacerts` in the /etc/ssl/certs/java directory - if this is the
case, fix it by
+ # moving it down a directory and then ant should install cleanly
+ - run: |
+ if [ -f /etc/ssl/certs/java/cacerts/cacerts ]; then
+ sudo mv /etc/ssl/certs/java/cacerts/
/etc/ssl/certs/java/cacerts-old
+ sudo mv /etc/ssl/certs/java/cacerts-old/cacerts
/etc/ssl/certs/java/
+ sudo rmdir /etc/ssl/certs/java/cacerts-old
+ fi
+ # The image already has java installed, but `apt-get install ant`
reinstalls it.
+ # Therefore, we download just the deb package for ant and install it
with dpkg.
+ - run: |
+ apt-get download ant ant-optional
+ sudo dpkg --force-all -i ant*.deb
+ rm ant*.deb
+ # We need aliases for localhost2,localhost3, ..., localhost20 in hosts
+ - run: |
+ sudo bash -c 'for i in {2..20}; do echo 127.0.0.${i} localhost${i}
>> /etc/hosts; done'
+ cat /etc/hosts
jobs:
# Runs java 8 tests on a docker image
unit_java8:
docker:
- - image: cimg/openjdk:8.0
+ - image: cimg/openjdk:8.0
environment:
skipIntegrationTest: true
steps:
- - setup_remote_docker
- - checkout
- - run: ./gradlew --info check -x integrationTest --stacktrace
+ - install_common
+ - setup_remote_docker
+ - checkout
+ - run: ./gradlew check -x integrationTest --stacktrace
- - store_artifacts:
- path: build/reports
- destination: test-reports
+ - store_artifacts:
+ path: build/reports
+ destination: test-reports
- - store_artifacts:
- path: build/test-results/
- destination: test-results
+ - store_artifacts:
+ path: build/test-results/
+ destination: test-results
- - store_test_results:
- path: build/test-results/
+ - store_test_results:
+ path: build/test-results/
integration_cassandra_40_java8:
docker:
- - image: circleci/openjdk:8-jdk-stretch
+ - image: cimg/openjdk:8.0
environment:
INTEGRATION_MAX_PARALLEL_FORKS: 2
INTEGRATION_MAX_HEAP_SIZE: "3500M"
resource_class: large
steps:
- - checkout
- # Cassandra 4.0 jar seems to be missing some dependencies, so we use 4.1
here (this is what we currently do)
- - run: BRANCHES="cassandra-4.0 cassandra-4.1" scripts/build-dtest-jars.sh
- - run: ./gradlew --no-daemon -PdtestVersion=4.1.4
-Dcassandra.sidecar.versions_to_test="4.0" --info checkstyleIntegrationTest
spotbugsIntegrationTest integrationTest --stacktrace
+ - install_common
+ - checkout
+ # Cassandra 4.0 jar seems to be missing some dependencies, so we use 4.1
here (this is what we currently do)
+ - run: BRANCHES="cassandra-4.0 cassandra-4.1" scripts/build-dtest-jars.sh
+ - run: ./gradlew --no-daemon -PdtestVersion=4.1.4
-Dcassandra.sidecar.versions_to_test="4.0" checkstyleIntegrationTest
spotbugsIntegrationTest integrationTest --stacktrace
- - store_artifacts:
- path: build/reports
- destination: test-reports
+ - store_artifacts:
+ path: build/reports
+ destination: test-reports
- - store_artifacts:
- path: build/test-results/
- destination: test-results
+ - store_artifacts:
+ path: build/test-results/
+ destination: test-results
- - store_test_results:
- path: build/test-results/
+ - store_test_results:
+ path: build/test-results/
integration_cassandra_41_java8:
docker:
- - image: circleci/openjdk:8-jdk-stretch
+ - image: cimg/openjdk:8.0
environment:
INTEGRATION_MAX_PARALLEL_FORKS: 2
INTEGRATION_MAX_HEAP_SIZE: "3500M"
resource_class: large
steps:
- - checkout
- - run: BRANCHES="cassandra-4.1" scripts/build-dtest-jars.sh
- - run: ./gradlew --no-daemon -PdtestVersion=4.1.4
-Dcassandra.sidecar.versions_to_test="4.1" --info checkstyleIntegrationTest
spotbugsIntegrationTest integrationTest --stacktrace
+ - install_common
+ - checkout
+ - run: BRANCHES="cassandra-4.1" scripts/build-dtest-jars.sh
+ - run: ./gradlew --no-daemon -PdtestVersion=4.1.4
-Dcassandra.sidecar.versions_to_test="4.1" checkstyleIntegrationTest
spotbugsIntegrationTest integrationTest --stacktrace
- - store_artifacts:
- path: build/reports
- destination: test-reports
+ - store_artifacts:
+ path: build/reports
+ destination: test-reports
- - store_artifacts:
- path: build/test-results/
- destination: test-results
+ - store_artifacts:
+ path: build/test-results/
+ destination: test-results
- - store_test_results:
- path: build/test-results/
+ - store_test_results:
+ path: build/test-results/
# Runs java 11 tests on a docker image
unit_java11:
@@ -135,8 +145,9 @@ jobs:
skipIntegrationTest: true
steps:
- setup_remote_docker
+ - install_common
- checkout
- - run: ./gradlew --info check -x integrationTest --stacktrace
+ - run: ./gradlew check -x integrationTest --stacktrace
- store_artifacts:
path: build/reports
@@ -147,16 +158,17 @@ jobs:
integration_cassandra_40_java11:
docker:
- - image: circleci/openjdk:11-jdk-stretch
+ - image: cimg/openjdk:11.0
environment:
INTEGRATION_MAX_PARALLEL_FORKS: 2
INTEGRATION_MAX_HEAP_SIZE: "3500M"
resource_class: large
steps:
+ - install_common
- checkout
# Cassandra 4.0 jar seems to be missing some dependencies, so we use 4.1
here (this is what we currently do)
- run: BRANCHES="cassandra-4.0 cassandra-4.1" CASSANDRA_USE_JDK11=true
scripts/build-dtest-jars.sh
- - run: ./gradlew --no-daemon -PdtestVersion=4.1.4
-Dcassandra.sidecar.versions_to_test="4.0" --info checkstyleIntegrationTest
spotbugsIntegrationTest integrationTest --stacktrace
+ - run: ./gradlew --no-daemon -PdtestVersion=4.1.4
-Dcassandra.sidecar.versions_to_test="4.0" checkstyleIntegrationTest
spotbugsIntegrationTest integrationTest --stacktrace
- store_artifacts:
path: build/reports
@@ -171,15 +183,16 @@ jobs:
integration_cassandra_50_java11:
docker:
- - image: circleci/openjdk:11-jdk-stretch
+ - image: cimg/openjdk:11.0
environment:
INTEGRATION_MAX_PARALLEL_FORKS: 2
INTEGRATION_MAX_HEAP_SIZE: "3500M"
resource_class: large
steps:
+ - install_common
- checkout
- run: BRANCHES="cassandra-5.0" scripts/build-dtest-jars.sh
- - run: ./gradlew --no-daemon -PdtestVersion=5.0-alpha2
-Dcassandra.sidecar.versions_to_test="5.0" --info checkstyleIntegrationTest
spotbugsIntegrationTest integrationTest --stacktrace
+ - run: ./gradlew --no-daemon -PdtestVersion=5.0-alpha2
-Dcassandra.sidecar.versions_to_test="5.0" checkstyleIntegrationTest
spotbugsIntegrationTest integrationTest --stacktrace
- store_artifacts:
path: build/reports
@@ -194,15 +207,16 @@ jobs:
integration_cassandra_trunk_java11:
docker:
- - image: circleci/openjdk:11-jdk-stretch
+ - image: cimg/openjdk:11.0
environment:
INTEGRATION_MAX_PARALLEL_FORKS: 2
INTEGRATION_MAX_HEAP_SIZE: "3500M"
resource_class: large
steps:
+ - install_common
- checkout
- run: BRANCHES="trunk" scripts/build-dtest-jars.sh
- - run: ./gradlew --no-daemon -PdtestVersion=5.1
-Dcassandra.sidecar.versions_to_test="5.1" --info checkstyleIntegrationTest
spotbugsIntegrationTest integrationTest --stacktrace
+ - run: ./gradlew --no-daemon -PdtestVersion=5.1
-Dcassandra.sidecar.versions_to_test="5.1" checkstyleIntegrationTest
spotbugsIntegrationTest integrationTest --stacktrace
- store_artifacts:
path: build/reports
@@ -218,10 +232,12 @@ jobs:
# ensures we can build and install deb packages
deb_build_install:
docker:
- - image: circleci/openjdk:11-jdk-stretch
+ - image: cimg/openjdk:11.0
steps:
+ - install_common
- checkout
- - run: ./gradlew -i clean buildDeb
+ - run: sudo apt --fix-broken install
+ - run: ./gradlew --info clean buildDeb
- run: DEBIAN_FRONTEND=noninteractive sudo apt install -y
./build/distributions/cassandra-sidecar*.deb
- run: test -f /opt/cassandra-sidecar/bin/cassandra-sidecar
@@ -242,12 +258,13 @@ jobs:
<<: *base_job
steps:
- checkout
- - run: ./gradlew -i clean jibDockerBuild
+ - run: ./gradlew --info clean jibDockerBuild
docs_build:
docker:
- - image: circleci/openjdk:11-jdk-stretch
+ - image: cimg/openjdk:11.0
steps:
+ - install_common
- checkout
- run: ./gradlew docs:asciidoctor
- run: test -f docs/build/user.html
diff --git a/build.gradle b/build.gradle
index d791cbb..6f048d5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -378,6 +378,17 @@ tasks.register("integrationTest", Test) {
forkEvery = 1 // DTest framework tends to have issues without forkEvery
test class
maxHeapSize = integrationMaxHeapSize
maxParallelForks = integrationMaxParallelForks
+
+ afterTest { descriptor, result ->
+ def totalTime = (result.endTime - result.startTime) / 1000.0
+ logger.lifecycle("--")
+ if (totalTime >= 60) { // log the tests that take 1 minute and more
+ logger.warn("$descriptor.displayName took $totalTime s")
+ }
+ else {
+ logger.info("$descriptor.displayName took $totalTime s")
+ }
+ }
}
tasks.register("containerTest", Test) {
diff --git a/scripts/build-dtest-jars.sh b/scripts/build-dtest-jars.sh
index e8492b2..112c8f4 100755
--- a/scripts/build-dtest-jars.sh
+++ b/scripts/build-dtest-jars.sh
@@ -22,6 +22,7 @@ CANDIDATE_BRANCHES=(
"cassandra-4.0:1f79c8492528f01bcc5f88951a1cc9e0d7265c54"
"cassandra-4.1:725655dda2776fef35567496a6e331102eb7610d"
"cassandra-5.0:f19dd0bb1309c35535876e8f0f996ad2b76adda5"
+ # note the trunk hash cannot be advanced beyond
ae0842372ff6dd1437d026f82968a3749f555ff4 (TCM), which breaks integration test
"trunk:2a5e1b77c9f8a205dbec1afdea3f4ed1eaf6a4eb"
)
BRANCHES=( ${BRANCHES:-cassandra-4.0 cassandra-4.1 cassandra-5.0 trunk} )
@@ -99,3 +100,7 @@ for index in "${!CANDIDATE_BRANCHES[@]}"; do
exit ${RETURN}
fi
done
+
+# Remove the build directory enclosing all Cassandra branches just cloned,
+# in order to not confuse IDE's indexing
+rm -rf ${BUILD_DIR}
diff --git
a/src/main/java/org/apache/cassandra/sidecar/db/schema/AbstractSchema.java
b/src/main/java/org/apache/cassandra/sidecar/db/schema/AbstractSchema.java
index ae72c28..05d27ec 100644
--- a/src/main/java/org/apache/cassandra/sidecar/db/schema/AbstractSchema.java
+++ b/src/main/java/org/apache/cassandra/sidecar/db/schema/AbstractSchema.java
@@ -73,12 +73,4 @@ abstract class AbstractSchema
protected abstract boolean exists(@NotNull Metadata metadata);
protected abstract String createSchemaStatement();
-
- /**
- * Abstract base schema class for table schema
- */
- public abstract static class TableSchema extends AbstractSchema
- {
-
- }
}
diff --git
a/src/main/java/org/apache/cassandra/sidecar/db/schema/RestoreJobsSchema.java
b/src/main/java/org/apache/cassandra/sidecar/db/schema/RestoreJobsSchema.java
index 8df27bf..348f95d 100644
---
a/src/main/java/org/apache/cassandra/sidecar/db/schema/RestoreJobsSchema.java
+++
b/src/main/java/org/apache/cassandra/sidecar/db/schema/RestoreJobsSchema.java
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.NotNull;
* to {@link org.apache.cassandra.sidecar.db.RestoreJob} like inserting a
restore job, updating a restore job,
* finding restore jobs and more
*/
-public class RestoreJobsSchema extends AbstractSchema.TableSchema
+public class RestoreJobsSchema extends TableSchema
{
private static final String RESTORE_JOB_TABLE_NAME = "restore_job_v2";
diff --git
a/src/main/java/org/apache/cassandra/sidecar/db/schema/RestoreSlicesSchema.java
b/src/main/java/org/apache/cassandra/sidecar/db/schema/RestoreSlicesSchema.java
index 3c9e2f1..0221f01 100644
---
a/src/main/java/org/apache/cassandra/sidecar/db/schema/RestoreSlicesSchema.java
+++
b/src/main/java/org/apache/cassandra/sidecar/db/schema/RestoreSlicesSchema.java
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.NotNull;
* related to {@link org.apache.cassandra.sidecar.db.RestoreSlice} like
inserting a new restore slice,
* updating status of a slice, finding restore slices and more
*/
-public class RestoreSlicesSchema extends AbstractSchema.TableSchema
+public class RestoreSlicesSchema extends TableSchema
{
private static final String RESTORE_SLICE_TABLE_NAME = "restore_slice_v2";
diff --git
a/src/main/java/org/apache/cassandra/sidecar/db/schema/TableSchema.java
b/src/main/java/org/apache/cassandra/sidecar/db/schema/TableSchema.java
new file mode 100644
index 0000000..6792f71
--- /dev/null
+++ b/src/main/java/org/apache/cassandra/sidecar/db/schema/TableSchema.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.sidecar.db.schema;
+
+/**
+ * Abstract base schema class for table schema
+ */
+public abstract class TableSchema extends AbstractSchema
+{
+
+}
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/common/CQLSessionProviderTest.java
b/src/test/integration/org/apache/cassandra/sidecar/common/CQLSessionProviderTest.java
index d77f5f8..cf361d6 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/common/CQLSessionProviderTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/common/CQLSessionProviderTest.java
@@ -49,6 +49,12 @@ public class CQLSessionProviderTest extends
IntegrationTestBase
public static final String OK_KEYSPACE_RESPONSE_START =
"{\"schema\":\"CREATE KEYSPACE ";
public static final String KEYSPACE_FAILED_RESPONSE_START =
"{\"status\":\"Service Unavailable\",";
+ @Override
+ protected int getNumInstancesToManage(int clusterSize)
+ {
+ return 2;
+ }
+
@CassandraIntegrationTest(nodesPerDc = 2, startCluster = false)
void testCqlSessionProviderWorksAsExpected(VertxTestContext context,
CassandraTestContext cassandraTestContext)
throws Exception
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/common/DelegateIntegrationTest.java
b/src/test/integration/org/apache/cassandra/sidecar/common/DelegateIntegrationTest.java
index 9bc1c82..d367901 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/common/DelegateIntegrationTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/common/DelegateIntegrationTest.java
@@ -186,6 +186,9 @@ class DelegateIntegrationTest extends IntegrationTestBase
@CassandraIntegrationTest(nodesPerDc = 2, newNodesPerDc = 1, startCluster
= false)
public void testChangingClusterSize(VertxTestContext context) throws
InterruptedException
{
+ // assume the sidecar has 3 managed instances, even though the cluster
only starts with 2 instances initially
+ sidecarTestContext.setNumInstancesToManage(3);
+
EventBus eventBus = vertx.eventBus();
Checkpoint jmxConnected = context.checkpoint(3);
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/db/RestoreJobsDatabaseAccessorIntTest.java
b/src/test/integration/org/apache/cassandra/sidecar/db/RestoreJobsDatabaseAccessorIntTest.java
index def98cf..9fdb149 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/db/RestoreJobsDatabaseAccessorIntTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/db/RestoreJobsDatabaseAccessorIntTest.java
@@ -23,7 +23,6 @@ import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import com.datastax.driver.core.utils.UUIDs;
@@ -51,7 +50,7 @@ class RestoreJobsDatabaseAccessorIntTest extends
IntegrationTestBase
vertx.eventBus()
.localConsumer(SidecarServerEvents.ON_SIDECAR_SCHEMA_INITIALIZED.address(), msg
-> latch.countDown());
- Uninterruptibles.awaitUninterruptibly(latch, 10, TimeUnit.SECONDS);
+ awaitLatchOrTimeout(latch, 10, TimeUnit.SECONDS);
assertThat(accessor.findAllRecent(3)).isEmpty();
QualifiedTableName qualifiedTableName = new QualifiedTableName("ks",
"tbl");
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/BaseTokenRangeIntegrationTest.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/BaseTokenRangeIntegrationTest.java
index 93269e9..08422d3 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/BaseTokenRangeIntegrationTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/BaseTokenRangeIntegrationTest.java
@@ -138,8 +138,7 @@ public class BaseTokenRangeIntegrationTest extends
IntegrationTestBase
1);
int totalNodeCount = (annotation.nodesPerDc() +
annotation.newNodesPerDc()) * annotation.numDcs();
- return cassandraTestContext.configureAndStartCluster(
- builder -> {
+ return cassandraTestContext.configureAndStartCluster(builder -> {
builder.withInstanceInitializer(initializer);
builder.withTokenSupplier(mdcTokenSupplier);
builder.withNodeIdTopology(networkTopology(totalNodeCount,
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningBaseTest.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningBaseTest.java
index ac1862c..0dea56c 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningBaseTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningBaseTest.java
@@ -35,7 +35,6 @@ import java.util.stream.Collectors;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.Uninterruptibles;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.vertx.junit5.VertxTestContext;
@@ -103,7 +102,7 @@ class JoiningBaseTest extends BaseTokenRangeIntegrationTest
}
}
- Uninterruptibles.awaitUninterruptibly(transientStateStart, 2,
TimeUnit.MINUTES);
+ awaitLatchOrTimeout(transientStateStart, 2, TimeUnit.MINUTES);
for (IUpgradeableInstance newInstance : newInstances)
{
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestDoubleCluster.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestDoubleCluster.java
index 322c5ad..3b1065a 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestDoubleCluster.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestDoubleCluster.java
@@ -20,33 +20,23 @@ package org.apache.cassandra.sidecar.routes.tokenrange;
import java.math.BigInteger;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
import io.vertx.junit5.VertxTestContext;
-import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.description.type.TypeDescription;
-import net.bytebuddy.dynamic.ClassFileLocator;
-import net.bytebuddy.dynamic.TypeResolutionStrategy;
-import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
-import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
-import net.bytebuddy.pool.TypePool;
+import org.apache.cassandra.db.SystemKeyspace;
+import org.apache.cassandra.sidecar.testing.BootstrapBBUtils;
import org.apache.cassandra.testing.CassandraIntegrationTest;
import org.apache.cassandra.testing.ConfigurableCassandraTestContext;
-import org.apache.cassandra.utils.Shared;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
/**
* Cluster expansion scenarios integration tests for token range replica
mapping endpoint with the in-jvm
@@ -173,7 +163,6 @@ public class JoiningTestDoubleCluster extends
JoiningBaseTest
/**
* ByteBuddy helper for doubling cluster size
*/
- @Shared
public static class BBHelperDoubleClusterSize
{
static CountDownLatch transientStateStart = new CountDownLatch(5);
@@ -185,27 +174,19 @@ public class JoiningTestDoubleCluster extends
JoiningBaseTest
// We intercept the bootstrap of the new nodes (6-10) to validate
token ranges
if (nodeNumber > 5)
{
- TypePool typePool = TypePool.Default.of(cl);
- TypeDescription description =
typePool.describe("org.apache.cassandra.service.StorageService")
- .resolve();
- new ByteBuddy().rebase(description,
ClassFileLocator.ForClassLoader.of(cl))
-
.method(named("bootstrap").and(takesArguments(2)))
-
.intercept(MethodDelegation.to(BBHelperDoubleClusterSize.class))
- // Defer class loading until all dependencies
are loaded
- .make(TypeResolutionStrategy.Lazy.INSTANCE,
typePool)
- .load(cl,
ClassLoadingStrategy.Default.INJECTION);
+ BootstrapBBUtils.installSetBoostrapStateIntercepter(cl,
BBHelperDoubleClusterSize.class);
}
}
- public static boolean bootstrap(Collection<?> tokens,
- long bootstrapTimeoutMillis,
- @SuperCall Callable<Boolean> orig)
throws Exception
+ public static void setBootstrapState(SystemKeyspace.BootstrapState
state, @SuperCall Callable<Void> orig) throws Exception
{
- boolean result = orig.call();
- // trigger bootstrap start and wait until bootstrap is ready from
test
- transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
- return result;
+ if (state == SystemKeyspace.BootstrapState.COMPLETED)
+ {
+ // trigger bootstrap start and wait until bootstrap is ready
from test
+ transientStateStart.countDown();
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
+ }
+ orig.call();
}
public static void reset()
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultiDC.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultiDC.java
index 0f56390..16eb43f 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultiDC.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultiDC.java
@@ -20,34 +20,24 @@ package org.apache.cassandra.sidecar.routes.tokenrange;
import java.math.BigInteger;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
import io.vertx.junit5.VertxTestContext;
-import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.description.type.TypeDescription;
-import net.bytebuddy.dynamic.ClassFileLocator;
-import net.bytebuddy.dynamic.TypeResolutionStrategy;
-import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
-import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
-import net.bytebuddy.pool.TypePool;
+import org.apache.cassandra.db.SystemKeyspace;
import org.apache.cassandra.distributed.UpgradeableCluster;
+import org.apache.cassandra.sidecar.testing.BootstrapBBUtils;
import org.apache.cassandra.testing.CassandraIntegrationTest;
import org.apache.cassandra.testing.ConfigurableCassandraTestContext;
-import org.apache.cassandra.utils.Shared;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
/**
* Multi-DC Cluster expansion scenarios integration tests for token range
replica mapping endpoint with the in-jvm
@@ -229,7 +219,6 @@ public class JoiningTestMultiDC extends JoiningBaseTest
/**
* ByteBuddy helper for multiple joining nodes
*/
- @Shared
public static class BBHelperDoubleClusterMultiDC
{
static CountDownLatch transientStateStart = new CountDownLatch(6);
@@ -241,27 +230,19 @@ public class JoiningTestMultiDC extends JoiningBaseTest
// We intercept the bootstrap of nodes (7-12) to validate token
ranges
if (nodeNumber > 6)
{
- TypePool typePool = TypePool.Default.of(cl);
- TypeDescription description =
typePool.describe("org.apache.cassandra.service.StorageService")
- .resolve();
- new ByteBuddy().rebase(description,
ClassFileLocator.ForClassLoader.of(cl))
-
.method(named("bootstrap").and(takesArguments(2)))
-
.intercept(MethodDelegation.to(BBHelperDoubleClusterMultiDC.class))
- // Defer class loading until all dependencies
are loaded
- .make(TypeResolutionStrategy.Lazy.INSTANCE,
typePool)
- .load(cl,
ClassLoadingStrategy.Default.INJECTION);
+ BootstrapBBUtils.installSetBoostrapStateIntercepter(cl,
BBHelperDoubleClusterMultiDC.class);
}
}
- public static boolean bootstrap(Collection<?> tokens,
- long bootstrapTimeoutMillis,
- @SuperCall Callable<Boolean> orig)
throws Exception
+ public static void setBootstrapState(SystemKeyspace.BootstrapState
state, @SuperCall Callable<Void> orig) throws Exception
{
- boolean result = orig.call();
- // trigger bootstrap start and wait until bootstrap is ready from
test
- transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
- return result;
+ if (state == SystemKeyspace.BootstrapState.COMPLETED)
+ {
+ // trigger bootstrap start and wait until bootstrap is ready
from test
+ transientStateStart.countDown();
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
+ }
+ orig.call();
}
public static void reset()
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultiDCSingleReplicated.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultiDCSingleReplicated.java
index 3db934d..170f8c6 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultiDCSingleReplicated.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultiDCSingleReplicated.java
@@ -20,34 +20,24 @@ package org.apache.cassandra.sidecar.routes.tokenrange;
import java.math.BigInteger;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
import io.vertx.junit5.VertxTestContext;
-import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.description.type.TypeDescription;
-import net.bytebuddy.dynamic.ClassFileLocator;
-import net.bytebuddy.dynamic.TypeResolutionStrategy;
-import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
-import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
-import net.bytebuddy.pool.TypePool;
+import org.apache.cassandra.db.SystemKeyspace;
import org.apache.cassandra.distributed.UpgradeableCluster;
+import org.apache.cassandra.sidecar.testing.BootstrapBBUtils;
import org.apache.cassandra.testing.CassandraIntegrationTest;
import org.apache.cassandra.testing.ConfigurableCassandraTestContext;
-import org.apache.cassandra.utils.Shared;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
/**
* Multi-DC Cluster expansion scenarios integration tests for token range
replica mapping endpoint with the in-jvm
@@ -158,7 +148,6 @@ public class JoiningTestMultiDCSingleReplicated extends
JoiningBaseTest
/**
* ByteBuddy helper for multiple joining nodes
*/
- @Shared
public static class BBHelperMultiDC
{
static CountDownLatch transientStateStart = new CountDownLatch(2);
@@ -170,27 +159,19 @@ public class JoiningTestMultiDCSingleReplicated extends
JoiningBaseTest
// We intercept the bootstrap of nodes (11,12) to validate token
ranges
if (nodeNumber > 10)
{
- TypePool typePool = TypePool.Default.of(cl);
- TypeDescription description =
typePool.describe("org.apache.cassandra.service.StorageService")
- .resolve();
- new ByteBuddy().rebase(description,
ClassFileLocator.ForClassLoader.of(cl))
-
.method(named("bootstrap").and(takesArguments(2)))
-
.intercept(MethodDelegation.to(BBHelperMultiDC.class))
- // Defer class loading until all dependencies
are loaded
- .make(TypeResolutionStrategy.Lazy.INSTANCE,
typePool)
- .load(cl,
ClassLoadingStrategy.Default.INJECTION);
+ BootstrapBBUtils.installSetBoostrapStateIntercepter(cl,
BBHelperMultiDC.class);
}
}
- public static boolean bootstrap(Collection<?> tokens,
- long bootstrapTimeoutMillis,
- @SuperCall Callable<Boolean> orig)
throws Exception
+ public static void setBootstrapState(SystemKeyspace.BootstrapState
state, @SuperCall Callable<Void> orig) throws Exception
{
- boolean result = orig.call();
- // trigger bootstrap start and wait until bootstrap is ready from
test
- transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
- return result;
+ if (state == SystemKeyspace.BootstrapState.COMPLETED)
+ {
+ // trigger bootstrap start and wait until bootstrap is ready
from test
+ transientStateStart.countDown();
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
+ }
+ orig.call();
}
public static void reset()
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultipleNodes.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultipleNodes.java
index 1eec7e2..6f2fda6 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultipleNodes.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestMultipleNodes.java
@@ -20,33 +20,23 @@ package org.apache.cassandra.sidecar.routes.tokenrange;
import java.math.BigInteger;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
import io.vertx.junit5.VertxTestContext;
-import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.description.type.TypeDescription;
-import net.bytebuddy.dynamic.ClassFileLocator;
-import net.bytebuddy.dynamic.TypeResolutionStrategy;
-import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
-import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
-import net.bytebuddy.pool.TypePool;
+import org.apache.cassandra.db.SystemKeyspace;
+import org.apache.cassandra.sidecar.testing.BootstrapBBUtils;
import org.apache.cassandra.testing.CassandraIntegrationTest;
import org.apache.cassandra.testing.ConfigurableCassandraTestContext;
-import org.apache.cassandra.utils.Shared;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
/**
* Cluster expansion scenarios integration tests for token range replica
mapping endpoint with the in-jvm
@@ -145,7 +135,6 @@ public class JoiningTestMultipleNodes extends
JoiningBaseTest
/**
* ByteBuddy helper for multiple joining nodes
*/
- @Shared
public static class BBHelperMultipleJoiningNodes
{
static CountDownLatch transientStateStart = new CountDownLatch(2);
@@ -157,27 +146,19 @@ public class JoiningTestMultipleNodes extends
JoiningBaseTest
// We intercept the joining of nodes (4, 5) to validate token
ranges
if (nodeNumber > 3)
{
- TypePool typePool = TypePool.Default.of(cl);
- TypeDescription description =
typePool.describe("org.apache.cassandra.service.StorageService")
- .resolve();
- new ByteBuddy().rebase(description,
ClassFileLocator.ForClassLoader.of(cl))
-
.method(named("bootstrap").and(takesArguments(2)))
-
.intercept(MethodDelegation.to(BBHelperMultipleJoiningNodes.class))
- // Defer class loading until all dependencies
are loaded
- .make(TypeResolutionStrategy.Lazy.INSTANCE,
typePool)
- .load(cl,
ClassLoadingStrategy.Default.INJECTION);
+ BootstrapBBUtils.installSetBoostrapStateIntercepter(cl,
BBHelperMultipleJoiningNodes.class);
}
}
- public static boolean bootstrap(Collection<?> tokens,
- long bootstrapTimeoutMillis,
- @SuperCall Callable<Boolean> orig)
throws Exception
+ public static void setBootstrapState(SystemKeyspace.BootstrapState
state, @SuperCall Callable<Void> orig) throws Exception
{
- boolean result = orig.call();
- // trigger bootstrap start and wait until bootstrap is ready from
test
- transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
- return result;
+ if (state == SystemKeyspace.BootstrapState.COMPLETED)
+ {
+ // trigger bootstrap start and wait until bootstrap is ready
from test
+ transientStateStart.countDown();
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
+ }
+ orig.call();
}
public static void reset()
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestSingleNode.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestSingleNode.java
index ac36244..0f3916e 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestSingleNode.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/JoiningTestSingleNode.java
@@ -20,33 +20,23 @@ package org.apache.cassandra.sidecar.routes.tokenrange;
import java.math.BigInteger;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
import io.vertx.junit5.VertxTestContext;
-import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.description.type.TypeDescription;
-import net.bytebuddy.dynamic.ClassFileLocator;
-import net.bytebuddy.dynamic.TypeResolutionStrategy;
-import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
-import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
-import net.bytebuddy.pool.TypePool;
+import org.apache.cassandra.db.SystemKeyspace;
+import org.apache.cassandra.sidecar.testing.BootstrapBBUtils;
import org.apache.cassandra.testing.CassandraIntegrationTest;
import org.apache.cassandra.testing.ConfigurableCassandraTestContext;
-import org.apache.cassandra.utils.Shared;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
/**
* Cluster expansion scenarios integration tests for token range replica
mapping endpoint with the in-jvm
@@ -112,7 +102,6 @@ public class JoiningTestSingleNode extends JoiningBaseTest
/**
* ByteBuddy helper for a single joining node
*/
- @Shared
public static class BBHelperSingleJoiningNode
{
static CountDownLatch transientStateStart = new CountDownLatch(1);
@@ -124,27 +113,19 @@ public class JoiningTestSingleNode extends JoiningBaseTest
// We intercept the bootstrap of the leaving node (4) to validate
token ranges
if (nodeNumber == 6)
{
- TypePool typePool = TypePool.Default.of(cl);
- TypeDescription description =
typePool.describe("org.apache.cassandra.service.StorageService")
- .resolve();
- new ByteBuddy().rebase(description,
ClassFileLocator.ForClassLoader.of(cl))
-
.method(named("bootstrap").and(takesArguments(2)))
-
.intercept(MethodDelegation.to(BBHelperSingleJoiningNode.class))
- // Defer class loading until all dependencies
are loaded
- .make(TypeResolutionStrategy.Lazy.INSTANCE,
typePool)
- .load(cl,
ClassLoadingStrategy.Default.INJECTION);
+ BootstrapBBUtils.installSetBoostrapStateIntercepter(cl,
BBHelperSingleJoiningNode.class);
}
}
- public static boolean bootstrap(Collection<?> tokens,
- long bootstrapTimeoutMillis,
- @SuperCall Callable<Boolean> orig)
throws Exception
+ public static void setBootstrapState(SystemKeyspace.BootstrapState
state, @SuperCall Callable<Void> orig) throws Exception
{
- boolean result = orig.call();
- // trigger bootstrap start and wait until bootstrap is ready from
test
- transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
- return result;
+ if (state == SystemKeyspace.BootstrapState.COMPLETED)
+ {
+ // trigger bootstrap start and wait until bootstrap is ready
from test
+ transientStateStart.countDown();
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
+ }
+ orig.call();
}
public static void reset()
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingBaseTest.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingBaseTest.java
index ac661a4..287d9e9 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingBaseTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingBaseTest.java
@@ -27,12 +27,12 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.Uninterruptibles;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.vertx.junit5.VertxTestContext;
@@ -84,7 +84,7 @@ class LeavingBaseTest extends BaseTokenRangeIntegrationTest
}
// Wait until nodes have reached expected state
- Uninterruptibles.awaitUninterruptibly(transientStateStart);
+ awaitLatchOrTimeout(transientStateStart, 2, TimeUnit.MINUTES);
for (IUpgradeableInstance node : leavingNodes)
{
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTest.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTest.java
index d4e6a8a..dde164b 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTest.java
@@ -25,10 +25,10 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
@@ -260,7 +260,6 @@ class LeavingTest extends LeavingBaseTest
/**
* ByteBuddy Helper for a single leaving node
*/
- @Shared
public static class BBHelperSingleLeavingNode
{
static CountDownLatch transientStateStart = new CountDownLatch(1);
@@ -288,7 +287,7 @@ class LeavingTest extends LeavingBaseTest
public static void unbootstrap(@SuperCall Callable<?> orig) throws
Exception
{
transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
orig.call();
}
@@ -330,7 +329,7 @@ class LeavingTest extends LeavingBaseTest
public static void unbootstrap(@SuperCall Callable<?> orig) throws
Exception
{
transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
orig.call();
}
@@ -372,7 +371,7 @@ class LeavingTest extends LeavingBaseTest
public static void unbootstrap(@SuperCall Callable<?> orig) throws
Exception
{
transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
orig.call();
}
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTestMultiDC.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTestMultiDC.java
index 0e28836..eb82353 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTestMultiDC.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTestMultiDC.java
@@ -25,9 +25,9 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
@@ -43,7 +43,6 @@ import net.bytebuddy.pool.TypePool;
import org.apache.cassandra.distributed.UpgradeableCluster;
import org.apache.cassandra.testing.CassandraIntegrationTest;
import org.apache.cassandra.testing.ConfigurableCassandraTestContext;
-import org.apache.cassandra.utils.Shared;
import static net.bytebuddy.matcher.ElementMatchers.named;
@@ -156,7 +155,6 @@ class LeavingTestMultiDC extends LeavingBaseTest
/**
* ByteBuddy helper for multiple leaving nodes multi-DC
*/
- @Shared
public static class BBHelperLeavingNodesMultiDC
{
static CountDownLatch transientStateStart = new CountDownLatch(2);
@@ -184,7 +182,7 @@ class LeavingTestMultiDC extends LeavingBaseTest
public static void unbootstrap(@SuperCall Callable<?> orig) throws
Exception
{
transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
orig.call();
}
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTestMultiDCHalveCluster.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTestMultiDCHalveCluster.java
index 6684f9e..d193613 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTestMultiDCHalveCluster.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/LeavingTestMultiDCHalveCluster.java
@@ -25,9 +25,9 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
@@ -43,7 +43,6 @@ import net.bytebuddy.pool.TypePool;
import org.apache.cassandra.distributed.UpgradeableCluster;
import org.apache.cassandra.testing.CassandraIntegrationTest;
import org.apache.cassandra.testing.ConfigurableCassandraTestContext;
-import org.apache.cassandra.utils.Shared;
import static net.bytebuddy.matcher.ElementMatchers.named;
@@ -189,7 +188,6 @@ class LeavingTestMultiDCHalveCluster extends LeavingBaseTest
/**
* ByteBuddy helper for halve cluster size with multi-DC
*/
- @Shared
public static class BBHelperHalveClusterMultiDC
{
static CountDownLatch transientStateStart = new CountDownLatch(6);
@@ -217,7 +215,7 @@ class LeavingTestMultiDCHalveCluster extends LeavingBaseTest
public static void unbootstrap(@SuperCall Callable<?> orig) throws
Exception
{
transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
orig.call();
}
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingBaseTest.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingBaseTest.java
index bf07215..52a7d6c 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingBaseTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingBaseTest.java
@@ -35,7 +35,6 @@ import java.util.stream.Collectors;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.Uninterruptibles;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.vertx.junit5.VertxTestContext;
@@ -88,7 +87,7 @@ class MovingBaseTest extends BaseTokenRangeIntegrationTest
.success()).start();
// Wait until nodes have reached expected state
- Uninterruptibles.awaitUninterruptibly(transientStateStart, 2,
TimeUnit.MINUTES);
+ awaitLatchOrTimeout(transientStateStart, 2, TimeUnit.MINUTES);
ClusterUtils.awaitRingState(seed, movingNode, "Moving");
retrieveMappingWithKeyspace(context, TEST_KEYSPACE, response -> {
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingMultiDCTest.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingMultiDCTest.java
index 64bf535..98c596a 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingMultiDCTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingMultiDCTest.java
@@ -26,9 +26,9 @@ import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
@@ -44,7 +44,6 @@ import net.bytebuddy.pool.TypePool;
import org.apache.cassandra.distributed.UpgradeableCluster;
import org.apache.cassandra.testing.CassandraIntegrationTest;
import org.apache.cassandra.testing.ConfigurableCassandraTestContext;
-import org.apache.cassandra.utils.Shared;
import static net.bytebuddy.matcher.ElementMatchers.named;
@@ -173,7 +172,6 @@ class MovingMultiDCTest extends MovingBaseTest
/**
* ByteBuddy Helper for a multiDC moving node
*/
- @Shared
public static class BBHelperMovingNodeMultiDC
{
static CountDownLatch transientStateStart = new CountDownLatch(1);
@@ -201,7 +199,7 @@ class MovingMultiDCTest extends MovingBaseTest
{
Future<?> res = orig.call();
transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
return res;
}
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingTest.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingTest.java
index 3e89b8e..f40322e 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/MovingTest.java
@@ -26,9 +26,9 @@ import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
@@ -45,7 +45,6 @@ import org.apache.cassandra.distributed.UpgradeableCluster;
import org.apache.cassandra.distributed.api.TokenSupplier;
import org.apache.cassandra.testing.CassandraIntegrationTest;
import org.apache.cassandra.testing.ConfigurableCassandraTestContext;
-import org.apache.cassandra.utils.Shared;
import static net.bytebuddy.matcher.ElementMatchers.named;
@@ -133,7 +132,6 @@ class MovingTest extends MovingBaseTest
/**
* ByteBuddy Helper for a single moving node
*/
- @Shared
public static class BBHelperMovingNode
{
static CountDownLatch transientStateStart = new CountDownLatch(1);
@@ -161,7 +159,7 @@ class MovingTest extends MovingBaseTest
{
Future<?> res = orig.call();
transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
return res;
}
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementBaseTest.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementBaseTest.java
index 17232d2..ca588eb 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementBaseTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementBaseTest.java
@@ -25,25 +25,29 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.Uninterruptibles;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.vertx.junit5.VertxTestContext;
import org.apache.cassandra.config.CassandraRelevantProperties;
import org.apache.cassandra.distributed.UpgradeableCluster;
import org.apache.cassandra.distributed.api.Feature;
+import org.apache.cassandra.distributed.api.IInstance;
import org.apache.cassandra.distributed.api.IInstanceConfig;
import org.apache.cassandra.distributed.api.IUpgradeableInstance;
+import org.apache.cassandra.distributed.impl.AbstractCluster;
import org.apache.cassandra.distributed.shared.ClusterUtils;
+import org.apache.cassandra.distributed.shared.NetworkTopology;
import org.apache.cassandra.sidecar.common.response.TokenRangeReplicasResponse;
import org.apache.cassandra.testing.CassandraIntegrationTest;
@@ -95,9 +99,9 @@ class ReplacementBaseTest extends
BaseTokenRangeIntegrationTest
stopNodes(seed, nodesToRemove);
List<IUpgradeableInstance> newNodes =
startReplacementNodes(nodeStart, cluster, nodesToRemove);
-
+ sidecarTestContext.refreshInstancesConfig();
// Wait until replacement nodes are in JOINING state
- Uninterruptibles.awaitUninterruptibly(transientStateStart, 2,
TimeUnit.MINUTES);
+ awaitLatchOrTimeout(transientStateStart, 2, TimeUnit.MINUTES);
// Verify state of replacement nodes
for (IUpgradeableInstance newInstance : newNodes)
@@ -158,16 +162,17 @@ class ReplacementBaseTest extends
BaseTokenRangeIntegrationTest
String remAddress =
removedConfig.broadcastAddress().getAddress().getHostAddress();
int remPort = removedConfig.getInt("storage_port");
IUpgradeableInstance replacement =
- ClusterUtils.addInstance(cluster, removedConfig,
- c -> {
- c.set("auto_bootstrap", true);
- // explicitly DOES NOT set instances
that failed startup as "shutdown"
- // so subsequent attempts to shut
down the instance are honored
-
c.set("dtest.api.startup.failure_as_shutdown", false);
- c.with(Feature.GOSSIP,
- Feature.JMX,
- Feature.NATIVE_PROTOCOL);
- });
+ addInstanceLocal(cluster, removedConfig.localDatacenter(),
removedConfig.localRack(),
+ c -> {
+ c.set("auto_bootstrap", true);
+ // explicitly DOES NOT set instances that
failed startup as "shutdown"
+ // so subsequent attempts to shut down the
instance are honored
+
c.set("dtest.api.startup.failure_as_shutdown", false);
+ c.with(Feature.GOSSIP,
+ Feature.JMX,
+ Feature.NATIVE_PROTOCOL);
+ c.set("storage_port", remPort);
+ });
new Thread(() -> ClusterUtils.start(replacement, (properties) -> {
properties.set(CassandraRelevantProperties.BOOTSTRAP_SKIP_SCHEMA_CHECK, true);
@@ -182,12 +187,25 @@ class ReplacementBaseTest extends
BaseTokenRangeIntegrationTest
properties.with("cassandra.replace_address_first_boot",
remAddress + ":" + remPort);
})).start();
- Uninterruptibles.awaitUninterruptibly(nodeStart, 2,
TimeUnit.MINUTES);
+ awaitLatchOrTimeout(nodeStart, 2, TimeUnit.MINUTES);
newNodes.add(replacement);
}
return newNodes;
}
+ public static <I extends IInstance> I addInstanceLocal(AbstractCluster<I>
cluster,
+ String dc,
+ String rack,
+
Consumer<IInstanceConfig> fn)
+ {
+ Objects.requireNonNull(dc, "dc");
+ Objects.requireNonNull(rack, "rack");
+ IInstanceConfig config = cluster.newInstanceConfig();
+ fn.accept(config);
+ config.networkTopology().put(config.broadcastAddress(),
NetworkTopology.dcAndRack(dc, rack));
+ return cluster.bootstrap(config);
+ }
+
private void stopNodes(IUpgradeableInstance seed,
List<IUpgradeableInstance> removedNodes)
{
for (IUpgradeableInstance nodeToRemove : removedNodes)
@@ -195,6 +213,7 @@ class ReplacementBaseTest extends
BaseTokenRangeIntegrationTest
ClusterUtils.stopUnchecked(nodeToRemove);
ClusterUtils.awaitRingStatus(seed, nodeToRemove, "Down");
}
+ sidecarTestContext.refreshInstancesConfig();
}
private void validateReplicaMapping(TokenRangeReplicasResponse
mappingResponse,
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementMultiDCTest.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementMultiDCTest.java
index d94dcb9..104e8e6 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementMultiDCTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementMultiDCTest.java
@@ -20,35 +20,25 @@ package org.apache.cassandra.sidecar.routes.tokenrange;
import java.math.BigInteger;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
import io.vertx.junit5.VertxTestContext;
-import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.description.type.TypeDescription;
-import net.bytebuddy.dynamic.ClassFileLocator;
-import net.bytebuddy.dynamic.TypeResolutionStrategy;
-import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
-import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
-import net.bytebuddy.pool.TypePool;
+import org.apache.cassandra.db.SystemKeyspace;
import org.apache.cassandra.distributed.UpgradeableCluster;
import org.apache.cassandra.distributed.api.IUpgradeableInstance;
+import org.apache.cassandra.sidecar.testing.BootstrapBBUtils;
import org.apache.cassandra.testing.CassandraIntegrationTest;
import org.apache.cassandra.testing.ConfigurableCassandraTestContext;
-import org.apache.cassandra.utils.Shared;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
/**
* Multi-DC Host replacement scenario integration tests for token range
replica mapping endpoint with the in-jvm
@@ -164,7 +154,6 @@ class ReplacementMultiDCTest extends ReplacementBaseTest
/**
* ByteBuddy helper for multi-DC node replacement
*/
- @Shared
public static class BBHelperReplacementsMultiDC
{
// Additional latch used here to sequentially start the 2 new nodes to
isolate the loading
@@ -179,28 +168,20 @@ class ReplacementMultiDCTest extends ReplacementBaseTest
// We intercept the bootstrap of the replacement nodes to validate
token ranges
if (nodeNumber > 10)
{
- TypePool typePool = TypePool.Default.of(cl);
- TypeDescription description =
typePool.describe("org.apache.cassandra.service.StorageService")
- .resolve();
- new ByteBuddy().rebase(description,
ClassFileLocator.ForClassLoader.of(cl))
-
.method(named("bootstrap").and(takesArguments(2)))
-
.intercept(MethodDelegation.to(BBHelperReplacementsMultiDC.class))
- // Defer class loading until all dependencies
are loaded
- .make(TypeResolutionStrategy.Lazy.INSTANCE,
typePool)
- .load(cl,
ClassLoadingStrategy.Default.INJECTION);
+ BootstrapBBUtils.installSetBoostrapStateIntercepter(cl,
BBHelperReplacementsMultiDC.class);
}
}
- public static boolean bootstrap(Collection<?> tokens,
- long bootstrapTimeoutMillis,
- @SuperCall Callable<Boolean> orig)
throws Exception
+ public static void setBootstrapState(SystemKeyspace.BootstrapState
state, @SuperCall Callable<Void> orig) throws Exception
{
- boolean result = orig.call();
- nodeStart.countDown();
- // trigger bootstrap start and wait until bootstrap is ready from
test
- transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
- return result;
+ if (state == SystemKeyspace.BootstrapState.COMPLETED)
+ {
+ nodeStart.countDown();
+ // trigger bootstrap start and wait until bootstrap is ready
from test
+ transientStateStart.countDown();
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
+ }
+ orig.call();
}
public static void reset()
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementTest.java
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementTest.java
index c5d0e2b..5206353 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementTest.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/routes/tokenrange/ReplacementTest.java
@@ -20,38 +20,28 @@ package org.apache.cassandra.sidecar.routes.tokenrange;
import java.math.BigInteger;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import com.google.common.collect.Range;
-import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.jupiter.api.extension.ExtendWith;
import io.vertx.junit5.VertxExtension;
import io.vertx.junit5.VertxTestContext;
-import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.description.type.TypeDescription;
-import net.bytebuddy.dynamic.ClassFileLocator;
-import net.bytebuddy.dynamic.TypeResolutionStrategy;
-import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
-import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
-import net.bytebuddy.pool.TypePool;
+import org.apache.cassandra.db.SystemKeyspace;
import org.apache.cassandra.distributed.UpgradeableCluster;
import org.apache.cassandra.distributed.api.IUpgradeableInstance;
import org.apache.cassandra.distributed.api.TokenSupplier;
+import org.apache.cassandra.sidecar.testing.BootstrapBBUtils;
import org.apache.cassandra.testing.CassandraIntegrationTest;
import org.apache.cassandra.testing.ConfigurableCassandraTestContext;
-import org.apache.cassandra.utils.Shared;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
/**
* Host replacement scenario integration tests for token range replica mapping
endpoint with the in-jvm dtest framework.
@@ -146,7 +136,6 @@ class ReplacementTest extends ReplacementBaseTest
/**
* ByteBuddy helper for a single node replacement
*/
- @Shared
public static class BBHelperReplacementsNode
{
// Additional latch used here to sequentially start the 2 new nodes to
isolate the loading
@@ -161,28 +150,20 @@ class ReplacementTest extends ReplacementBaseTest
// We intercept the bootstrap of the replacement (6th) node to
validate token ranges
if (nodeNumber == 6)
{
- TypePool typePool = TypePool.Default.of(cl);
- TypeDescription description =
typePool.describe("org.apache.cassandra.service.StorageService")
- .resolve();
- new ByteBuddy().rebase(description,
ClassFileLocator.ForClassLoader.of(cl))
-
.method(named("bootstrap").and(takesArguments(2)))
-
.intercept(MethodDelegation.to(BBHelperReplacementsNode.class))
- // Defer class loading until all dependencies
are loaded
- .make(TypeResolutionStrategy.Lazy.INSTANCE,
typePool)
- .load(cl,
ClassLoadingStrategy.Default.INJECTION);
+ BootstrapBBUtils.installSetBoostrapStateIntercepter(cl,
BBHelperReplacementsNode.class);
}
}
- public static boolean bootstrap(Collection<?> tokens,
- long bootstrapTimeoutMillis,
- @SuperCall Callable<Boolean> orig)
throws Exception
+ public static void setBootstrapState(SystemKeyspace.BootstrapState
state, @SuperCall Callable<Void> orig) throws Exception
{
- boolean result = orig.call();
- nodeStart.countDown();
- // trigger bootstrap start and wait until bootstrap is ready from
test
- transientStateStart.countDown();
- Uninterruptibles.awaitUninterruptibly(transientStateEnd);
- return result;
+ if (state == SystemKeyspace.BootstrapState.COMPLETED)
+ {
+ nodeStart.countDown();
+ // trigger bootstrap start and wait until bootstrap is ready
from test
+ transientStateStart.countDown();
+ awaitLatchOrTimeout(transientStateEnd, 2, TimeUnit.MINUTES);
+ }
+ orig.call();
}
public static void reset()
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/testing/BootstrapBBUtils.java
b/src/test/integration/org/apache/cassandra/sidecar/testing/BootstrapBBUtils.java
new file mode 100644
index 0000000..ab5ec78
--- /dev/null
+++
b/src/test/integration/org/apache/cassandra/sidecar/testing/BootstrapBBUtils.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.sidecar.testing;
+
+import net.bytebuddy.ByteBuddy;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.dynamic.ClassFileLocator;
+import net.bytebuddy.dynamic.TypeResolutionStrategy;
+import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
+import net.bytebuddy.implementation.MethodDelegation;
+import net.bytebuddy.pool.TypePool;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
+
+/**
+ * Utils to install the ByteBuddy method interceptor for bootstrap
+ */
+public class BootstrapBBUtils
+{
+ /**
+ * Note that the test class _must_ define the `setBootstrapState` method
in order for the installed intercepter to be effective.
+ * See {@code ReplacementTest.BBHelperReplacementsNode} for example
+ */
+ public static void installSetBoostrapStateIntercepter(ClassLoader cl,
Class<?> interceptor)
+ {
+ TypePool typePool = TypePool.Default.of(cl);
+ TypeDescription description =
typePool.describe("org.apache.cassandra.db.SystemKeyspace")
+ .resolve();
+ new ByteBuddy().rebase(description,
ClassFileLocator.ForClassLoader.of(cl))
+
.method(named("setBootstrapState").and(takesArguments(1)))
+ .intercept(MethodDelegation.to(interceptor))
+ // Defer class loading until all dependencies are loaded
+ .make(TypeResolutionStrategy.Lazy.INSTANCE, typePool)
+ .load(cl, ClassLoadingStrategy.Default.INJECTION);
+ }
+}
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/testing/CassandraSidecarTestContext.java
b/src/test/integration/org/apache/cassandra/sidecar/testing/CassandraSidecarTestContext.java
index 73e8ed5..bb3db58 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/testing/CassandraSidecarTestContext.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/testing/CassandraSidecarTestContext.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -70,8 +71,8 @@ public class CassandraSidecarTestContext implements
AutoCloseable
private final DnsResolver dnsResolver;
private final AbstractCassandraTestContext abstractCassandraTestContext;
private final Vertx vertx;
- private final int numInstancesToManage;
private final List<InstanceConfigListener> instanceConfigListeners;
+ private int numInstancesToManage;
public InstancesConfig instancesConfig;
private List<JmxClient> jmxClients;
private CQLSessionProvider sessionProvider;
@@ -156,22 +157,42 @@ public class CassandraSidecarTestContext implements
AutoCloseable
return cluster;
}
+ public void setNumInstancesToManage(int numInstancesToManage)
+ {
+ this.numInstancesToManage = numInstancesToManage;
+ refreshInstancesConfig();
+ }
+
public InstancesConfig instancesConfig()
{
- // rebuild instances config if cluster changed
- if (instancesConfig == null
- || instancesConfig.instances().size() != numInstancesToManage)
+ if (instancesConfig == null)
{
- // clean-up any open sessions or client resources
- close();
- setInstancesConfig();
+ refreshInstancesConfig();
}
return this.instancesConfig;
}
+ public InstancesConfig refreshInstancesConfig()
+ {
+ // clean-up any open sessions or client resources
+ close();
+ setInstancesConfig();
+ return this.instancesConfig;
+ }
+
public Session session()
{
- return sessionProvider.get();
+ return sessionProvider == null ? null : sessionProvider.get();
+ }
+
+ public void closeSessionProvider()
+ {
+ if (sessionProvider == null)
+ {
+ return;
+ }
+
+ sessionProvider.close();
}
@Override
@@ -192,20 +213,6 @@ public class CassandraSidecarTestContext implements
AutoCloseable
}
}
- public JmxClient jmxClient()
- {
- return jmxClient(0);
- }
-
- private JmxClient jmxClient(int instance)
- {
- if (jmxClients == null)
- {
- setInstancesConfig();
- }
- return jmxClients.get(instance);
- }
-
private void setInstancesConfig()
{
this.instancesConfig = buildInstancesConfig(versionProvider,
dnsResolver);
@@ -227,6 +234,10 @@ public class CassandraSidecarTestContext implements
AutoCloseable
0,
SharedExecutorNettyOptions.INSTANCE);
for (int i = 0; i < configs.size(); i++)
{
+ if (configs.get(i) == null)
+ {
+ continue;
+ }
IInstanceConfig config = configs.get(i);
String hostName = JMXUtil.getJmxHost(config);
int nativeTransportPort = tryGetIntConfig(config,
"native_transport_port", 9042);
@@ -277,6 +288,7 @@ public class CassandraSidecarTestContext implements
AutoCloseable
// Always return the complete list of addresses even if the cluster
isn't yet that large
// this way, we populate the entire local instance list
return configs.stream()
+ .filter(Objects::nonNull)
.map(config -> new
InetSocketAddress(config.broadcastAddress().getAddress(),
tryGetIntConfig(config, "native_transport_port", 9042)))
.collect(Collectors.toList());
@@ -285,12 +297,27 @@ public class CassandraSidecarTestContext implements
AutoCloseable
@NotNull
private List<InstanceConfig> buildInstanceConfigs(UpgradeableCluster
cluster)
{
- return IntStream.range(1, numInstancesToManage + 1)
- .mapToObj(nodeNum ->
-
AbstractClusterUtils.createInstanceConfig(cluster, nodeNum))
+ int nodes = numInstancesToManage == -1 ? cluster.size() :
numInstancesToManage;
+ return IntStream.range(1, nodes + 1)
+ .mapToObj(nodeNum -> {
+ // check whether the instances are managed by the
test framework first. Because the nodeNum might be greater than the cluster size
+ if (manageInstanceByTestFramework() &&
cluster.get(nodeNum).isShutdown())
+ {
+ return null;
+ }
+ else
+ {
+ return
AbstractClusterUtils.createInstanceConfig(cluster, nodeNum);
+ }
+ })
.collect(Collectors.toList());
}
+ private boolean manageInstanceByTestFramework()
+ {
+ return numInstancesToManage == -1;
+ }
+
/**
* A listener for {@link InstancesConfig} state changes
*/
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestBase.java
b/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestBase.java
index 593414c..2755aec 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestBase.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestBase.java
@@ -133,11 +133,11 @@ public abstract class IntegrationTestBase
* Defaults to the entire cluster.
*
* @param clusterSize the size of the cluster as defined by the
integration test
- * @return the number of instances to manage
+ * @return the number of instances to manage; or -1 to let test framework
to determine the cluster size at the runtime
*/
protected int getNumInstancesToManage(int clusterSize)
{
- return clusterSize;
+ return -1;
}
@AfterEach
@@ -199,6 +199,8 @@ public abstract class IntegrationTestBase
{
try
{
+ sidecarTestContext.refreshInstancesConfig();
+
Session session = maybeGetSession();
session.execute("CREATE KEYSPACE IF NOT EXISTS " +
TEST_KEYSPACE +
@@ -238,6 +240,13 @@ public abstract class IntegrationTestBase
return tableName;
}
+ protected static void awaitLatchOrTimeout(CountDownLatch latch, long
duration, TimeUnit timeUnit)
+ {
+ assertThat(Uninterruptibles.awaitUninterruptibly(latch, duration,
timeUnit))
+ .describedAs("Latch times out after " + duration + ' ' +
timeUnit.name())
+ .isTrue();
+ }
+
protected Session maybeGetSession()
{
Session session = sidecarTestContext.session();
diff --git
a/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestModule.java
b/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestModule.java
index 3009155..5030261 100644
---
a/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestModule.java
+++
b/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestModule.java
@@ -18,16 +18,14 @@
package org.apache.cassandra.sidecar.testing;
-import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.List;
-import java.util.stream.Collectors;
+import com.datastax.driver.core.Session;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import io.vertx.core.Vertx;
-import org.apache.cassandra.sidecar.cluster.CQLSessionProviderImpl;
import org.apache.cassandra.sidecar.cluster.InstancesConfig;
import org.apache.cassandra.sidecar.cluster.instance.InstanceMetadata;
import org.apache.cassandra.sidecar.common.server.CQLSessionProvider;
@@ -40,6 +38,7 @@ import
org.apache.cassandra.sidecar.config.yaml.SidecarConfigurationImpl;
import org.apache.cassandra.sidecar.config.yaml.TestServiceConfiguration;
import org.apache.cassandra.sidecar.exceptions.NoSuchSidecarInstanceException;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import static
org.apache.cassandra.sidecar.server.SidecarServerEvents.ON_SERVER_STOP;
@@ -84,13 +83,26 @@ public class IntegrationTestModule extends AbstractModule
@Singleton
public CQLSessionProvider cqlSessionProvider(Vertx vertx, InstancesConfig
instancesConfig)
{
- // cql session provider uses local instances as contacts
- List<InetSocketAddress> addresses = instancesConfig.instances()
- .stream()
- .map(i -> new
InetSocketAddress(i.host(), i.port()))
-
.collect(Collectors.toList());
- CQLSessionProviderImpl cqlSessionProvider = new
CQLSessionProviderImpl(addresses, addresses, 500, null,
-
0, SharedExecutorNettyOptions.INSTANCE);
+ CQLSessionProvider cqlSessionProvider = new CQLSessionProvider()
+ {
+ @Override
+ public @Nullable Session get()
+ {
+ return cassandraTestContext.session();
+ }
+
+ @Override
+ public void close()
+ {
+ cassandraTestContext.closeSessionProvider();
+ }
+
+ @Override
+ public @Nullable Session getIfConnected()
+ {
+ return get();
+ }
+ };
vertx.eventBus().localConsumer(ON_SERVER_STOP.address(), message ->
cqlSessionProvider.close());
return cqlSessionProvider;
}
diff --git
a/src/test/integration/org/apache/cassandra/testing/CassandraTestTemplate.java
b/src/test/integration/org/apache/cassandra/testing/CassandraTestTemplate.java
index 899f729..fba4f6a 100644
---
a/src/test/integration/org/apache/cassandra/testing/CassandraTestTemplate.java
+++
b/src/test/integration/org/apache/cassandra/testing/CassandraTestTemplate.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
+import java.util.function.Predicate;
import java.util.stream.Stream;
import org.junit.jupiter.api.extension.AfterEachCallback;
@@ -40,6 +41,7 @@ import com.vdurmont.semver4j.Semver;
import org.apache.cassandra.distributed.UpgradeableCluster;
import org.apache.cassandra.distributed.api.Feature;
import org.apache.cassandra.distributed.api.TokenSupplier;
+import org.apache.cassandra.distributed.impl.AbstractCluster;
import org.apache.cassandra.distributed.shared.Versions;
import org.apache.cassandra.sidecar.common.utils.Preconditions;
@@ -142,6 +144,9 @@ public class CassandraTestTemplate implements
TestTemplateInvocationContextProvi
private BeforeEachCallback beforeEach()
{
+ Predicate<String> extra = c -> {
+ return c.contains("BBHelper") || c.contains("BootstrapState");
+ };
return beforeEachCtx -> {
CassandraIntegrationTest annotation =
getCassandraIntegrationTestAnnotation(context, true);
// spin up a C* cluster using the in-jvm dtest
@@ -162,6 +167,7 @@ public class CassandraTestTemplate implements
TestTemplateInvocationContextProvi
.withDynamicPortAllocation(true) // to allow
parallel test runs
.withVersion(requestedVersion)
.withDCs(dcCount)
+
.withSharedClasses(extra.or(AbstractCluster.SHARED_PREDICATE))
.withDataDirCount(annotation.numDataDirsPerInstance())
.withConfig(config ->
annotationToFeatureList(annotation).forEach(config::with));
TokenSupplier tokenSupplier =
TokenSupplier.evenlyDistributedTokens(finalNodeCount,
diff --git
a/src/test/integration/org/apache/cassandra/testing/ConfigurableCassandraTestContext.java
b/src/test/integration/org/apache/cassandra/testing/ConfigurableCassandraTestContext.java
index c1c0187..b43f3ac 100644
---
a/src/test/integration/org/apache/cassandra/testing/ConfigurableCassandraTestContext.java
+++
b/src/test/integration/org/apache/cassandra/testing/ConfigurableCassandraTestContext.java
@@ -71,6 +71,7 @@ public class ConfigurableCassandraTestContext extends
AbstractCassandraTestConte
{
try
{
+ cluster = null; // make sure cluster is null
cluster = configureCluster(configurator);
cluster.startup();
return cluster;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]