diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 00000000..1b068c96 --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,66 @@ +name: Gemini Integrations Tests + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: + uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.23" + - name: Build + run: make build + - uses: actions/upload-artifact@v4 + with: + name: bin + path: "./bin/gemini" + if-no-files-found: error + retention-days: 1 + test: + needs: [build] + runs-on: ubuntu-latest + strategy: + max-parallel: 1 + matrix: + gemini-features: ["basic", "normal", "all"] + gemini-concurrency: [16] + oracle-scylla-version: ["6.1.1"] + test-scylla-version: ["6.1.1"] + fail-fast: false + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + - name: Start ScyllaDB + id: scylla + run: | + chmod +x ./bin/gemini + make scylla-setup \ + SCYLLA_TEST_VERSION=${{ matrix.test-scylla-version }} \ + SCYLLA_ORACLE_VERSION=${{ matrix.oracle-scylla-version }} + - name: Test + shell: bash + run: | + make integration-test \ + CONCURRENCY=${{ matrix.gemini-concurrency }} \ + CQL_FEATURES=${{ matrix.gemini-features }} \ + DURATION=5m + - name: Shutdown ScyllaDB + run: | + make scylla-shutdown \ + SCYLLA_TEST_VERSION=${{ matrix.test-scylla-version }} \ + SCYLLA_ORACLE_VERSION=${{ matrix.oracle-scylla-version }} + + - uses: actions/upload-artifact@v4 + with: + name: results-${{ matrix.gemini-features }}-${{ matrix.gemini-concurrency }} + path: ./results + if-no-files-found: error + retention-days: 30 diff --git a/Makefile b/Makefile index e56f1c6e..018f8fd4 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,14 @@ MAKEFILE_PATH := $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) GO111MODULE := on -# GO_UPGRADE - do not remove this comment, used by scripts/go-upgrade.sh GOOS := $(shell uname | tr '[:upper:]' '[:lower:]') GOARCH := $(shell go env GOARCH) +DOCKER_COMPOSE_TESTING := scylla +DOCKER_VERSION := latest + ifndef GOBIN -export GOBIN := $(MAKEFILE_PATH)/bin + export GOBIN := $(MAKEFILE_PATH)/bin endif define dl_tgz @@ -23,26 +25,13 @@ $(GOBIN)/golangci-lint: GOLANGCI_VERSION = 1.60.3 $(GOBIN)/golangci-lint: Makefile $(call dl_tgz,golangci-lint,https://github.com/golangci/golangci-lint/releases/download/v$(GOLANGCI_VERSION)/golangci-lint-$(GOLANGCI_VERSION)-$(GOOS)-amd64.tar.gz) -.PHONY: check-golangci -check-golangci: $(GOBIN)/golangci-lint - $(GOBIN)/golangci-lint run - -# fix-golangci Automated fix for golangci-lint errors. -.PHONY: fix-golangci -fix-golangci: $(GOBIN)/golangci-lint - $(GOBIN)/golangci-lint run --fix - -# check Run all static code analysis. (use make fix to attempt automatic fix) .PHONY: check -check: check-golangci +check: $(GOBIN)/golangci-lint + $(GOBIN)/golangci-lint run -# fix make all static code analysis tools to fix the issues .PHONY: fix -fix: fix-golangci - -.PHONY: test -test: - go test -covermode=atomic -race -coverprofile=coverage.txt -timeout 5m -json -v ./... 2>&1 | gotestfmt -showteststatus +fix: $(GOBIN)/golangci-lint + $(GOBIN)/golangci-lint run --fix .PHONY: build build: @@ -53,4 +42,50 @@ debug-build: .PHONY: build-docker build-docker: - docker build --target production -t scylladb/gemini:latest --compress . + docker build --target production -t scylladb/gemini:$(DOCKER_VERSION) --compress . + +.PHONY: scylla-setup +scylla-setup: + @docker compose -f scripts/docker-compose-$(DOCKER_COMPOSE_TESTING).yml up -d + + until docker logs gemini-oracle 2>&1 | grep "Starting listening for CQL clients" > /dev/null; do sleep 0.2; done + until docker logs gemini-test 2>&1 | grep "Starting listening for CQL clients" > /dev/null; do sleep 0.2; done + +.PHONY: scylla-shutdown +scylla-shutdown: + docker compose -f scripts/docker-compose-$(DOCKER_COMPOSE_TESTING).yml down --volumes + +.PHONY: test +test: + go test -covermode=atomic -race -coverprofile=coverage.txt -timeout 5m -json -v ./... 2>&1 | gotestfmt -showteststatus + +CQL_FEATURES := normal +CONCURRENCY := 1 +DURATION := 10m +WARMUP := 1m + +.PHONY: integration-test +integration-test: + mkdir -p ./results + touch ./results/gemini_seed + ./bin/gemini \ + --fail-fast \ + --dataset-size=small \ + --seed=$(shell date +%s | tee ./results/gemini_seed) \ + --test-cluster=$(shell docker inspect --format='{{ .NetworkSettings.Networks.gemini.IPAddress }}' gemini-test) \ + --oracle-cluster=$(shell docker inspect --format='{{ .NetworkSettings.Networks.gemini.IPAddress }}' gemini-oracle) \ + --outfile ./results/gemini_result.log \ + --duration $(DURATION) \ + --warmup $(WARMUP) \ + -m mixed \ + --non-interactive \ + --cql-features $(CQL_FEATURES) \ + --request-timeout 180s \ + --connect-timeout 120s \ + --async-objects-stabilization-attempts 5 \ + --async-objects-stabilization-backoff 500ms \ + --replication-strategy "{'class': 'NetworkTopologyStrategy', 'replication_factor': '1'}" \ + --oracle-replication-strategy "{'class': 'NetworkTopologyStrategy', 'replication_factor': '1'}" \ + --max-mutation-retries 10 \ + --max-mutation-retries-backoff 500ms \ + -c $(CONCURRENCY) diff --git a/results/gemini_result.log b/results/gemini_result.log new file mode 100644 index 00000000..932608f6 --- /dev/null +++ b/results/gemini_result.log @@ -0,0 +1,226 @@ +{ + "gemini_version": "v1.8.7", + "result": { + "errors": [], + "write_ops": 8261, + "write_errors": 0, + "read_ops": 0, + "read_errors": 0 + }, + "schema": { + "keyspace": { + "replication": { + "class": "NetworkTopologyStrategy", + "replication_factor": "1" + }, + "oracle_replication": { + "class": "NetworkTopologyStrategy", + "replication_factor": "1" + }, + "name": "ks1" + }, + "tables": [ + { + "name": "table1", + "partition_keys": [ + { + "type": "bigint", + "name": "pk0" + }, + { + "type": "smallint", + "name": "pk1" + }, + { + "type": "double", + "name": "pk2" + }, + { + "type": "varchar", + "name": "pk3" + }, + { + "type": "varchar", + "name": "pk4" + } + ], + "clustering_keys": [ + { + "type": "smallint", + "name": "ck0" + }, + { + "type": "double", + "name": "ck1" + }, + { + "type": "varchar", + "name": "ck2" + } + ], + "columns": [ + { + "type": "double", + "name": "col0" + }, + { + "type": "date", + "name": "col1" + }, + { + "type": { + "complex_type": "udt", + "value_types": { + "udt_3288840351_0": "smallint", + "udt_3288840351_1": "decimal" + }, + "type_name": "udt_3288840351", + "frozen": true + }, + "name": "col2" + }, + { + "type": "duration", + "name": "col3" + }, + { + "type": "float", + "name": "col4" + }, + { + "type": { + "complex_type": "set", + "value_type": "timeuuid", + "frozen": false + }, + "name": "col5" + }, + { + "type": "double", + "name": "col6" + }, + { + "type": "int", + "name": "col7" + }, + { + "type": "int", + "name": "col8" + }, + { + "type": { + "complex_type": "map", + "key_type": "int", + "value_type": "tinyint", + "frozen": true + }, + "name": "col9" + }, + { + "type": { + "complex_type": "set", + "value_type": "time", + "frozen": true + }, + "name": "col10" + } + ], + "indexes": [ + { + "Column": { + "type": "double", + "name": "col0" + }, + "index_name": "table1_col0_idx", + "column_name": "col0" + }, + { + "Column": { + "type": "float", + "name": "col4" + }, + "index_name": "table1_col4_idx", + "column_name": "col4" + }, + { + "Column": { + "type": "double", + "name": "col6" + }, + "index_name": "table1_col6_idx", + "column_name": "col6" + }, + { + "Column": { + "type": "int", + "name": "col7" + }, + "index_name": "table1_col7_idx", + "column_name": "col7" + }, + { + "Column": { + "type": "int", + "name": "col8" + }, + "index_name": "table1_col8_idx", + "column_name": "col8" + } + ], + "materialized_views": [ + { + "NonPrimaryKey": { + "type": "int", + "name": "col8" + }, + "name": "table1_mv_0", + "partition_keys": [ + { + "type": "int", + "name": "col8" + }, + { + "type": "bigint", + "name": "pk0" + }, + { + "type": "smallint", + "name": "pk1" + }, + { + "type": "double", + "name": "pk2" + }, + { + "type": "varchar", + "name": "pk3" + }, + { + "type": "varchar", + "name": "pk4" + } + ], + "clustering_keys": [ + { + "type": "smallint", + "name": "ck0" + }, + { + "type": "double", + "name": "ck1" + }, + { + "type": "varchar", + "name": "ck2" + } + ] + } + ], + "known_issues": { + "https://github.com/scylladb/scylla/issues/3708": true + } + } + ] + }, + "schemaHash": "785a75a33a8e5bb" + } diff --git a/scripts/docker-compose-cassandra.yml b/scripts/docker-compose-cassandra.yml index 8fa6e1f3..956b8052 100644 --- a/scripts/docker-compose-cassandra.yml +++ b/scripts/docker-compose-cassandra.yml @@ -1,5 +1,3 @@ -version: '3.5' - networks: gemini: name: gemini @@ -17,8 +15,8 @@ services: gemini: gemini-test: - image: scylladb/scylla:5.2.2 + image: scylladb/scylla:${SCYLLA_TEST_VERSION:-6.1.1} container_name: gemini-test - command: --smp 2 --memory 1024M --api-address 0.0.0.0 + command: --smp 1 --memory 512M --api-address 0.0.0.0 networks: gemini: diff --git a/scripts/docker-compose-scylla.yml b/scripts/docker-compose-scylla.yml index 1ce5fe94..34d8e451 100644 --- a/scripts/docker-compose-scylla.yml +++ b/scripts/docker-compose-scylla.yml @@ -1,5 +1,3 @@ -version: '3.5' - networks: gemini: name: gemini @@ -11,15 +9,15 @@ networks: services: gemini-oracle: - image: scylladb/scylla:5.2.2 + image: scylladb/scylla:${SCYLLA_ORACLE_VERSION:-6.1.1} container_name: gemini-oracle - command: --smp 2 --memory 512M --api-address 0.0.0.0 + command: --smp 1 --memory 512M --api-address 0.0.0.0 networks: gemini: gemini-test: - image: scylladb/scylla:5.2.2 + image: scylladb/scylla:${SCYLLA_TEST_VERSION:-6.1.1} container_name: gemini-test - command: --smp 2 --memory 512M --api-address 0.0.0.0 + command: --smp 1 --memory 512M --api-address 0.0.0.0 networks: gemini: diff --git a/scripts/prepare-environment.sh b/scripts/prepare-environment.sh deleted file mode 100755 index 5163059f..00000000 --- a/scripts/prepare-environment.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -docker-compose --log-level WARNING -f scripts/docker-compose-$1.yml up -d - -ORACLE_NAME=gemini-oracle -TEST_NAME=gemini-test - -echo "Waiting for ${ORACLE_NAME} to start" -until docker logs ${ORACLE_NAME} 2>&1 | grep "Starting listening for CQL clients" > /dev/null; do sleep 2; done -echo "Waiting for ${TEST_NAME} to start" -until docker logs ${TEST_NAME} 2>&1 | grep "Starting listening for CQL clients" > /dev/null; do sleep 2; done