Skip to content

Commit 79046fd

Browse files
feature(cassandra-stress): use ScyllaDB fork of Cassandra Stress instead of downloading Apache Cassandra
Signed-off-by: Dusan Malusev <[email protected]>
1 parent 01ce49a commit 79046fd

10 files changed

+182
-82
lines changed

.dockerignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
cassandra-download/
2+
target/
3+
.github/

.github/workflows/dockerhub-description.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ jobs:
1818
with:
1919
username: ${{ secrets.DOCKERHUB_USERNAME }}
2020
password: ${{ secrets.DOCKERHUB_TOKEN }}
21-
repository: scylladb/latte
21+
repository: scylladb/cql-stress
2222
short-description: ${{ github.event.repository.description }}
2323
enable-url-completion: true

.github/workflows/release.yml

+31-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ on:
55
tags:
66
- "*"
77

8+
env:
9+
RUSTFLAGS: "--cfg fetch_extended_version_info"
10+
CARGO_TERM_COLOR: always
11+
PYTHONUNBUFFERED: "1"
12+
813
jobs:
914
get_tag:
1015
runs-on: ubuntu-latest
@@ -59,35 +64,49 @@ jobs:
5964
uses: actions/checkout@v4
6065
- uses: actions-rust-lang/setup-rust-toolchain@v1
6166

62-
- name: Build Binary
67+
- name: Build CQLStressScyllaBench Binary
6368
uses: actions-rs/cargo@v1
6469
with:
6570
command: build
66-
args: --release
71+
args: --profile dist --all
6772

6873
- name: Set Binary Name
69-
id: set_binary_name
7074
run: |
71-
BIN_NAME="cql-stress-${{ needs.get_tag.outputs.tag }}-${{ matrix.os }}"
72-
echo "BIN_NAME=$BIN_NAME" >> $GITHUB_ENV
73-
echo "BIN_NAME=$BIN_NAME"
75+
BIN_NAME_CS="cql-stress-cassandra-stress-${{ needs.get_tag.outputs.tag }}-${{ matrix.os }}"
76+
BIN_NAME_SB="cql-stress-scylla-bench-${{ needs.get_tag.outputs.tag }}-${{ matrix.os }}"
77+
echo "BIN_NAME_CS=$BIN_NAME_CS" >> $GITHUB_ENV
78+
echo "BIN_NAME_CS=$BIN_NAME_CS"
79+
echo "BIN_NAME_SB=$BIN_NAME_SB" >> $GITHUB_ENV
80+
echo "BIN_NAME_SB=$BIN_NAME_SB"
81+
82+
mv ./target/dist/cql-stress-cassandra-stress ./target/dist/$BIN_NAME_CS
83+
mv ./target/dist/cql-stress-scylla-bench ./target/dist/$BIN_NAME_SB
7484
shell: bash
7585

7686
- name: Get Release Upload URL
77-
id: get_upload_url
7887
run: |
79-
UPLOAD_URL=$(gh release view ${{ inputs.version }} --json uploadUrl -q '.uploadUrl' | sed 's/{.*//')
80-
echo "UPLOAD_URL=${UPLOAD_URL}?name=${{ env.BIN_NAME }}" >> $GITHUB_ENV
88+
UPLOAD_URL=$(gh release view ${{ needs.get_tag.outputs.tag }} --json uploadUrl -q '.uploadUrl' | sed 's/{.*//')
89+
echo "UPLOAD_URL=${UPLOAD_URL}?name=${{ needs.get_tag.outputs.tag }}" >> $GITHUB_ENV
8190
env:
8291
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8392

8493
- name: Upload Release Asset
85-
id: upload-release-asset-unix
94+
id: upload-release-asset-cs
95+
uses: actions/upload-release-asset@v1
96+
env:
97+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
98+
with:
99+
upload_url: ${{ env.UPLOAD_URL }}
100+
asset_path: ./target/dist/${{ env.BIN_NAME_CS }}
101+
asset_name: ${{ env.BIN_NAME_CS }}
102+
asset_content_type: application/octet-stream
103+
- name: Upload Release Asset
104+
id: upload-release-asset-sb
86105
uses: actions/upload-release-asset@v1
87106
env:
88107
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
89108
with:
90109
upload_url: ${{ env.UPLOAD_URL }}
91-
asset_path: ./target/release/cql-stress
92-
asset_name: ${{ env.BIN_NAME }}
110+
asset_path: ./target/dist/${{ env.BIN_NAME_SB }}
111+
asset_name: ${{ env.BIN_NAME_SB }}
93112
asset_content_type: application/octet-stream

.github/workflows/rust.yml

+28-36
Original file line numberDiff line numberDiff line change
@@ -52,75 +52,67 @@ jobs:
5252
uses: actions-rs/cargo@v1
5353
with:
5454
command: build
55-
args: --release --bin cql-stress-cassandra-stress
56-
- name: Build cql-stress-scylla-bench binary
57-
uses: actions-rs/cargo@v1
58-
with:
59-
command: build
60-
args: --release --bin cql-stress-scylla-bench
55+
args: --profile dist --all
6156

6257
- uses: actions/upload-artifact@v4
6358
with:
6459
name: cql-stress-cassandra-stress
65-
path: "./target/release/cql-stress-cassandra-stress"
60+
path: "./target/dist/cql-stress-cassandra-stress"
6661
if-no-files-found: error
6762
retention-days: 1
6863
- uses: actions/upload-artifact@v4
6964
with:
7065
name: cql-stress-scylla-bench
71-
path: "./target/release/cql-stress-scylla-bench"
66+
path: "./target/dist/cql-stress-scylla-bench"
7267
if-no-files-found: error
7368
retention-days: 1
7469
test:
7570
runs-on: ubuntu-24.04
76-
services:
77-
scylladb:
78-
image: scylladb/scylla
79-
ports:
80-
- 9042:9042
81-
options: >-
82-
--name scylla-ci
83-
--health-cmd "cqlsh --debug"
84-
--health-interval 5s
85-
--health-retries 10
86-
volumes:
87-
- ${{ github.workspace }}:/workspace
8871
steps:
8972
- uses: actions/checkout@v4
9073
- uses: actions-rust-lang/setup-rust-toolchain@v1
9174
with:
9275
cache: true
76+
- name: Start ScyllaDB
77+
run: |
78+
docker compose -f ./docker/scylla-test/compose.yml up -d --wait
79+
until docker logs scylla_test 2>&1 | grep "Starting listening for CQL clients" > /dev/null; do sleep 0.2; done
9380
- uses: actions-rs/cargo@v1
9481
with:
9582
command: build
96-
args: --release --tests --features "user-profile"
83+
args: --tests --features "user-profile"
9784
- uses: actions-rs/cargo@v1
9885
with:
9986
command: test
10087
# test threads must be one because else database tests will run in parallel and will result in flaky tests
10188
args: --features "user-profile" -- --test-threads=1
10289

10390
integration-tests:
104-
needs: [build]
91+
needs: [build, test]
92+
cancel-timeout-minutes: 1
93+
timeout-minutes: 20
10594
runs-on: ubuntu-24.04
106-
services:
107-
scylladb:
108-
image: scylladb/scylla
109-
ports:
110-
- 9042:9042
111-
options: >-
112-
--name scylla-ci
113-
--health-cmd "cqlsh --debug"
114-
--health-interval 5s
115-
--health-retries 10
116-
volumes:
117-
- ${{ github.workspace }}:/workspace
95+
concurrency:
96+
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.binary }}
97+
strategy:
98+
max-parallel: 2
99+
matrix:
100+
binary: [cql-stress-cassandra-stress]
118101
steps:
119102
- uses: actions/checkout@v4
120-
- uses: actions/download-artifact@v4
121103
- name: Install python driver
122104
run: pip install scylla-driver
123105
- name: Install pytest
124106
run: pip install -U pytest
107+
- name: Start ScyllaDB
108+
run: |
109+
docker compose -f ./docker/scylla-test/compose.yml up -d --wait
110+
until docker logs scylla_test 2>&1 | grep "Starting listening for CQL clients" > /dev/null; do sleep 0.2; done
111+
- uses: actions/download-artifact@v4
112+
with:
113+
name: ${{ matrix.binary }}
125114
- name: C-S frontend tests
126-
run: pytest -s ./tools/cassandra_stress_ci.py
115+
run: |
116+
mv ${{ matrix.binary }} /usr/local/bin
117+
chmod +x /usr/local/bin/${{ matrix.binary }}
118+
pytest -s ./tools/${{ matrix.binary }}-ci.py

Cargo.toml

+28-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,31 @@ rust-version = "1.85.0"
66

77
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88

9+
[[bin]]
10+
name = "cql-stress-cassandra-stress"
11+
path = "src/bin/cql-stress-cassandra-stress/main.rs"
12+
13+
[[bin]]
14+
name = "cql-stress-scylla-bench"
15+
path = "src/bin/cql-stress-scylla-bench/main.rs"
16+
17+
[profile.release]
18+
codegen-units = 1
19+
lto = true
20+
panic = "abort"
21+
22+
[profile.dist]
23+
inherits = "release"
24+
opt-level = 3
25+
overflow-checks = false
26+
debug = false
27+
strip = true
28+
debug-assertions = false
29+
30+
[profile.dev-opt]
31+
inherits = "dev"
32+
opt-level = 2
33+
934
[dependencies]
1035
anyhow = "1.0.52"
1136
async-trait = "0.1.52"
@@ -62,4 +87,6 @@ scylla = { version = "1.0.0", features = [
6287
] }
6388

6489
[lints.rust]
65-
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fetch_extended_version_info)'] }
90+
unexpected_cfgs = { level = "warn", check-cfg = [
91+
'cfg(fetch_extended_version_info)',
92+
] }

Dockerfile

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
FROM rust:1.85-slim-bookworm AS builder
2+
3+
WORKDIR /app
4+
5+
ENV RUSTFLAGS="--cfg fetch_extended_version_info"
6+
ENV CARGO_TERM_COLOR=always
7+
8+
COPY . .
9+
10+
RUN apt-get update && apt-get install -y \
11+
build-essential \
12+
cmake \
13+
libclang-dev \
14+
git \
15+
libssl-dev \
16+
pkg-config \
17+
&& cargo build --profile dist --all
18+
19+
FROM debian:bookworm-slim AS production
20+
21+
ENV PATH="${PATH}:/usr/local/bin"
22+
23+
LABEL org.opencontainers.image.source="https://github.com/scylladb/cql-stress"
24+
LABEL org.opencontainers.image.title="ScyllaDB cql-stress"
25+
26+
COPY --from=builder /app/target/dist/cql-stress-cassandra-stress /usr/local/bin/cql-stress-cassandra-stress
27+
COPY --from=builder /app/target/dist/cql-stress-scylla-bench /usr/local/bin/cql-stress-scylla-bench
28+
29+
RUN --mount=type=cache,target=/var/cache/apt apt-get update \
30+
&& apt-get upgrade -y \
31+
&& apt-get install -y libssl3 \
32+
&& apt-get autoremove -y \
33+
&& apt-get clean \
34+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
35+
&& chmod +x /usr/local/bin/cql-stress-cassandra-stress /usr/local/bin/cql-stress-scylla-bench \
36+
&& ln -s /usr/local/bin/cql-stress-cassandra-stress /usr/local/bin/cassandra-stress \
37+
&& ln -s /usr/local/bin/cql-stress-scylla-bench /usr/local/bin/scylla-bench
38+
39+
ENTRYPOINT [ "bash" ]

docker/scylla_test/compose.yml renamed to docker/scylla-test/compose.yml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ services:
44
container_name: scylla_test
55
ports:
66
- 9042:9042
7+
- 19042:19042
78
healthcheck:
89
test: [ "CMD", "cqlsh", "-e", "select * from system.local" ]
910
interval: 5s

tools/util/cassandra_stress.py

+50-31
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66
from collections import namedtuple
77

88

9-
# scylla-tools-java is based on 3.* version of Apache Cassandra.
10-
# Notice that Apache c-s changed generation logic in version 4.0.0.
11-
# See: https://github.com/apache/cassandra/commit/f1f5f194620d3f9e11492f0051b6b71018033413
12-
DEFAULT_CASSANDRA_VERSION = "3.11.19"
9+
DEFAULT_CASSANDRA_STRESS_VERSION = "v3.17.3"
1310
ROOT_DIRECTORY = dirname(dirname(dirname(__file__)))
1411
DOWNLOAD_DIRECTORY_NAME = os.path.join(ROOT_DIRECTORY, "cassandra-download")
1512

@@ -79,41 +76,63 @@ def run_user(self, node_ip, profile_name, runtime_args: CSCliRuntimeArguments):
7976

8077

8178
class CassandraStress(CSCliRunner):
82-
def __init__(self, cassandra_version=DEFAULT_CASSANDRA_VERSION):
83-
cassandra_dir = f"apache-cassandra-{cassandra_version}"
84-
cassandra_tar = f"{cassandra_dir}-bin.tar.gz"
79+
def __init__(self, cassandra_stress_version=DEFAULT_CASSANDRA_STRESS_VERSION):
80+
cassandra_stress_dir = "cassandra-stress"
81+
cassandra_stress_tar = "cassandra-stress-bin.tar.gz"
8582

86-
abs_cassandra_dir = os.path.join(
87-
DOWNLOAD_DIRECTORY_NAME, cassandra_dir)
88-
abs_cassandra_tar = os.path.join(
89-
DOWNLOAD_DIRECTORY_NAME, cassandra_tar)
83+
abs_cassandra_dir = os.path.join(DOWNLOAD_DIRECTORY_NAME, cassandra_stress_dir)
84+
abs_cassandra_tar = os.path.join(DOWNLOAD_DIRECTORY_NAME, cassandra_stress_tar)
85+
86+
super().__init__(
87+
stress_cmd=[os.path.join(abs_cassandra_dir, "bin", "cassandra-stress")]
88+
)
9089

9190
if os.path.exists(abs_cassandra_dir):
9291
# Cassandra already fetched.
9392
print(
94-
f"Cassandra {cassandra_version} already installed. Skipping the download phase.")
95-
else:
93+
f"Cassandra {cassandra_stress_version} already installed. Skipping the download phase."
94+
)
95+
return
96+
97+
if not os.path.exists(abs_cassandra_tar):
98+
os.makedirs(DOWNLOAD_DIRECTORY_NAME, exist_ok=True)
9699
# Fetch cassandra.
97100
print(
98-
f"Fetching cassandra {cassandra_version} to {DOWNLOAD_DIRECTORY_NAME}")
99-
# https://dlcdn.apache.org/cassandra/3.11.18/apache-cassandra-3.11.18-bin.tar.gz
100-
cassandra_url = f"https://dlcdn.apache.org/cassandra/{cassandra_version}/{cassandra_tar}"
101-
subprocess.run(args=["wget", "-P", DOWNLOAD_DIRECTORY_NAME,
102-
"-N", "--no-verbose", cassandra_url], check=True)
103-
104-
# Extract cassandra
105-
print(f"Extracting cassandra {cassandra_version}")
106-
subprocess.run(args=["tar", "-xzf", abs_cassandra_tar,
107-
"--directory", DOWNLOAD_DIRECTORY_NAME], check=True)
108-
print(f"Extracted cassandra to {abs_cassandra_dir}")
109-
110-
stress_cmd = [os.path.join(
111-
abs_cassandra_dir, "tools", "bin", "cassandra-stress")]
112-
super().__init__(stress_cmd=stress_cmd)
101+
f"Fetching cassandra {cassandra_stress_version} to {DOWNLOAD_DIRECTORY_NAME}"
102+
)
103+
cassandra_stress_url = f"https://github.com/scylladb/cassandra-stress/releases/download/{cassandra_stress_version}/cassandra-stress-bin.tar.gz"
104+
subprocess.run(
105+
args=[
106+
"wget",
107+
"-c",
108+
"-P",
109+
DOWNLOAD_DIRECTORY_NAME,
110+
"-N",
111+
"--no-verbose",
112+
cassandra_stress_url,
113+
],
114+
check=True,
115+
)
116+
117+
# Extract cassandra
118+
print(f"Extracting cassandra {cassandra_stress_version}")
119+
subprocess.run(
120+
args=[
121+
"tar",
122+
"-xzf",
123+
abs_cassandra_tar,
124+
"--directory",
125+
DOWNLOAD_DIRECTORY_NAME,
126+
],
127+
check=True,
128+
)
129+
print(f"Extracted cassandra to {abs_cassandra_dir}")
113130

114131

115132
class CqlStressCassandraStress(CSCliRunner):
116133
def __init__(self):
117-
stress_cmd = ["cargo", "run", "--features", "user-profile", "--bin",
118-
"cql-stress-cassandra-stress", "--"]
119-
super().__init__(stress_cmd=stress_cmd)
134+
super().__init__(stress_cmd=["cql-stress-cassandra-stress"])
135+
136+
137+
if __name__ == "__main__":
138+
cassandra_stress = CassandraStress()

tools/util/scylla_docker.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88

99
@contextmanager
10-
def scylla_docker(teardown_behavior, compose_yaml="docker/scylla_test/compose.yml"):
10+
def scylla_docker(teardown_behavior, compose_yaml="docker/scylla-test/compose.yml"):
1111
print("Setting up Scylla")
1212
print("Starting the container and waiting for it to be healthy")
1313

0 commit comments

Comments
 (0)