In Jenkins parallelise (matrix) dtest-upgrade runs
patch by Mick Semb Wever; reviewed by Eduard Tudenhöfner
diff --git a/build-scripts/cassandra-dtest-pytest.sh b/build-scripts/cassandra-dtest-pytest.sh
index cad2e62..e099ba4 100755
--- a/build-scripts/cassandra-dtest-pytest.sh
+++ b/build-scripts/cassandra-dtest-pytest.sh
@@ -8,6 +8,8 @@
# Pass in target to run, default to base dtest
DTEST_TARGET="${1:-dtest}"
+# Optional: pass in chunk to test, formatted as "K/N" for the Kth chunk of N chunks
+DTEST_SPLIT_CHUNK="$2"
export PYTHONIOENCODING="utf-8"
export PYTHONUNBUFFERED=true
@@ -37,6 +39,7 @@
break
fi
done
+
# Exit, if we didn't build successfully
if [ "${RETURN}" -ne "0" ]; then
echo "Build failed with exit code: ${RETURN}"
@@ -65,21 +68,31 @@
mkdir -p ${TMPDIR}
set +e # disable immediate exit from this point
if [ "${DTEST_TARGET}" = "dtest" ]; then
- pytest -vv --log-level="INFO" --use-vnodes --num-tokens=32 --junit-xml=nosetests.xml --junit-prefix=${DTEST_TARGET} -s --cassandra-dir=$CASSANDRA_DIR --skip-resource-intensive-tests 2>&1 | tee -a ${WORKSPACE}/test_stdout.txt
+ DTEST_ARGS="--use-vnodes --num-tokens=${NUM_TOKENS} --skip-resource-intensive-tests"
elif [ "${DTEST_TARGET}" = "dtest-novnode" ]; then
- pytest -vv --log-level="INFO" --junit-xml=nosetests.xml --junit-prefix=${DTEST_TARGET} -s --cassandra-dir=$CASSANDRA_DIR --skip-resource-intensive-tests 2>&1 | tee -a ${WORKSPACE}/test_stdout.txt
+ DTEST_ARGS="--skip-resource-intensive-tests"
elif [ "${DTEST_TARGET}" = "dtest-offheap" ]; then
- pytest -vv --log-level="INFO" --use-vnodes --num-tokens=32 --use-off-heap-memtables --junit-xml=nosetests.xml --junit-prefix=${DTEST_TARGET} -s --cassandra-dir=$CASSANDRA_DIR --skip-resource-intensive-tests 2>&1 | tee -a ${WORKSPACE}/test_stdout.txt
+ DTEST_ARGS="--use-vnodes --num-tokens=${NUM_TOKENS} --use-off-heap-memtables --skip-resource-intensive-tests"
elif [ "${DTEST_TARGET}" = "dtest-large" ]; then
- pytest -vv --log-level="INFO" --use-vnodes --num-tokens=32 --junit-xml=nosetests.xml --junit-prefix=${DTEST_TARGET} -s --cassandra-dir=$CASSANDRA_DIR --only-resource-intensive-tests 2>&1 | tee -a ${WORKSPACE}/test_stdout.txt
+ DTEST_ARGS="--use-vnodes --num-tokens=${NUM_TOKENS} --only-resource-intensive-tests"
elif [ "${DTEST_TARGET}" = "dtest-upgrade" ]; then
+ DTEST_ARGS="--execute-upgrade-tests-only "
export RUN_STATIC_UPGRADE_MATRIX=true
- pytest -vv --log-level="INFO" --execute-upgrade-tests-only --junit-xml=nosetests.xml --junit-prefix=${DTEST_TARGET} -s --cassandra-dir=$CASSANDRA_DIR 2>&1 | tee -a ${WORKSPACE}/test_stdout.txt
else
echo "Unknown dtest target: ${DTEST_TARGET}"
exit 1
fi
+SPLIT_TESTS=""
+if [ "x${DTEST_SPLIT_CHUNK}" != "x" ] ; then
+ ./run_dtests.py --cassandra-dir=$CASSANDRA_DIR ${DTEST_ARGS} --dtest-print-tests-only --dtest-print-tests-output=${WORKSPACE}/test_list.txt 2>&1 | tee -a ${WORKSPACE}/test_stdout.txt
+ SPLIT_TESTS=$(split -n l/${DTEST_SPLIT_CHUNK} ${WORKSPACE}/test_list.txt)
+fi
+
+PYTEST_OPTS="-vv --log-level="INFO" --junit-xml=nosetests.xml --junit-prefix=${DTEST_TARGET} -s"
+
+pytest ${PYTEST_OPTS} --cassandra-dir=$CASSANDRA_DIR ${DTEST_ARGS} ${SPLIT_TESTS} 2>&1 | tee -a ${WORKSPACE}/test_stdout.txt
+
# tar up any ccm logs for easy retrieval
tar -cJf ccm_logs.tar.xz ${TMPDIR}/*/test/*/logs/*
diff --git a/docker/jenkins/dtest.sh b/docker/jenkins/dtest.sh
index 47ec642..417a36b 100644
--- a/docker/jenkins/dtest.sh
+++ b/docker/jenkins/dtest.sh
@@ -9,4 +9,4 @@
cd cassandra
echo git clone --depth 1 --single-branch --branch=$DTEST_BRANCH $DTEST_REPO
git clone --depth 1 --single-branch --branch=$DTEST_BRANCH $DTEST_REPO
-../cassandra-builds/build-scripts/cassandra-dtest-pytest.sh $1
+../cassandra-builds/build-scripts/cassandra-dtest-pytest.sh "$@"
diff --git a/docker/jenkins/jenkinscommand.sh b/docker/jenkins/jenkinscommand.sh
index bc2b835..7ce3c65 100644
--- a/docker/jenkins/jenkinscommand.sh
+++ b/docker/jenkins/jenkinscommand.sh
@@ -7,6 +7,7 @@
BUILDSBRANCH=$6
DOCKER_IMAGE=$7
TARGET=$8
+SPLIT_CHUNK=$9
cat > env.list <<EOF
REPO=$1
BRANCH=$2
@@ -14,8 +15,8 @@
DTEST_BRANCH=$4
EOF
-echo "jenkinscommand.sh: running: git clone --single-branch --depth 1 --branch $BUILDSBRANCH $BUILDSREPO; sh ./cassandra-builds/docker/jenkins/dtest.sh $TARGET"
-ID=$(docker run --env-file env.list -dt $DOCKER_IMAGE dumb-init bash -ilc "git clone --single-branch --depth 1 --branch $BUILDSBRANCH $BUILDSREPO; sh ./cassandra-builds/docker/jenkins/dtest.sh $TARGET")
+echo "jenkinscommand.sh: running: git clone --single-branch --depth 1 --branch $BUILDSBRANCH $BUILDSREPO; sh ./cassandra-builds/docker/jenkins/dtest.sh $TARGET $SPLIT_CHUNK"
+ID=$(docker run --env-file env.list -dt $DOCKER_IMAGE dumb-init bash -ilc "git clone --single-branch --depth 1 --branch $BUILDSBRANCH $BUILDSREPO; sh ./cassandra-builds/docker/jenkins/dtest.sh $TARGET $SPLIT_CHUNK")
# use docker attach instead of docker wait to get output
docker attach --no-stdin $ID
diff --git a/jenkins-dsl/cassandra_job_dsl_seed.groovy b/jenkins-dsl/cassandra_job_dsl_seed.groovy
index 39bc2b1..7976d73 100644
--- a/jenkins-dsl/cassandra_job_dsl_seed.groovy
+++ b/jenkins-dsl/cassandra_job_dsl_seed.groovy
@@ -275,6 +275,64 @@
}
}
+// wip – parallelise dtests, starting with just upgrade dtests
+matrixJob('Cassandra-template-dtest-matrix') {
+ disabled(true)
+ description(jobDescription)
+ concurrentBuild()
+ compressBuildLog()
+ logRotator {
+ numToKeep(10)
+ artifactNumToKeep(10)
+ }
+ wrappers {
+ timeout {
+ noActivity(1200)
+ }
+ timestamps()
+ }
+ properties {
+ githubProjectUrl(githubRepo)
+ }
+ scm {
+ git {
+ remote {
+ url(mainRepo)
+ }
+ branch('*/null')
+ extensions {
+ cleanAfterCheckout()
+ }
+ }
+ }
+ steps {
+ buildDescription('', buildDescStr)
+ shell("git clean -xdff ; git clone --depth 1 --single-branch -b ${buildsBranch} ${buildsRepo} ; git clone --depth 1 --single-branch ${dtestRepo}")
+ }
+ publishers {
+ archiveArtifacts {
+ pattern('**/test_stdout.txt,**/nosetests.xml,**/ccm_logs.tar.xz')
+ allowEmpty()
+ fingerprint()
+ }
+ archiveJunit('nosetests.xml') {
+ testDataPublishers {
+ publishTestStabilityData()
+ }
+ }
+ postBuildTask {
+ task('.', '''
+ echo "Cleaning project…"; git clean -xdff ;
+ echo "Pruning docker…" ; if pgrep -af jenkinscommand.sh; then docker system prune -f --filter 'until=48h'; else docker system prune -f --volumes ; fi;
+ echo "Reporting disk usage…"; df -h ; du -hs ../* ;
+ echo "Cleaning tmp…";
+ find . -type d -name tmp -delete 2>/dev/null ;
+ find /tmp -type f -atime +2 -user jenkins -and -not -exec fuser -s {} ';' -and -delete 2>/dev/null
+ ''')
+ }
+ }
+}
+
/**
* cqlsh template
*/
@@ -418,6 +476,25 @@
// Skip dtest-offheap on cassandra-3.0 branch
if ((targetName == 'dtest-offheap') && (branchName == 'cassandra-3.0')) {
println("Skipping ${targetName} on branch ${branchName}")
+ } else if (targetName == 'dtest-upgrade') {
+ // wip – parallelise dtests, starting with just upgrade dtests
+ matrixJob("${jobNamePrefix}-${targetName}") {
+ disabled(false)
+ using('Cassandra-template-dtest-matrix')
+ axes {
+ splits = 64
+ List<String> values = new ArrayList<String>()
+ (1..splits).each { values << it.toString() }
+ text('split', values)
+ label('label', slaveLabel)
+ }
+ configure { node ->
+ node / scm / branches / 'hudson.plugins.git.BranchSpec' / name(branchName)
+ }
+ steps {
+ shell("sh ./cassandra-builds/docker/jenkins/jenkinscommand.sh apache ${branchName} https://github.com/apache/cassandra-dtest.git master ${buildsRepo} ${buildsBranch} ${dtestDockerImage} ${targetName} \${split}/${splits}")
+ }
+ }
} else {
job("${jobNamePrefix}-${targetName}") {
disabled(false)