From 5e71bedc0081ce82ad66e4e2a5669cf63b8521f5 Mon Sep 17 00:00:00 2001 From: Dusan Malusev Date: Sun, 24 Nov 2024 20:16:48 +0100 Subject: [PATCH] feature(development): Better developer experience with Goland and Makefile 1. Create `Debug` target for `Docker`, which allows remote debugging 2. Allow running `gemini` as a `Docker` container from `Makefile`. This replicates the production environment inside SCT 3. Added IDEA run configurations for `gemini` and `gemini-tests` to run inside `Docker` container Signed-off-by: Dusan Malusev --- .run/Cassandra Oracle.run.xml | 13 ++++ .run/Debug Gemini Docker.run.xml | 32 ++++++++ .run/Run Gemini Docker.run.xml | 28 +++++++ .run/Run Gemini Mixed.run.xml | 13 ++++ .run/Run Gemini Read.run.xml | 13 ++++ .run/Run Gemini Write.run.xml | 13 ++++ .run/Scylla Oracle.run.xml | 13 ++++ .run/Tests.run.xml | 14 ++++ Dockerfile | 32 ++++++++ Makefile | 125 +++++++++++++++---------------- 10 files changed, 232 insertions(+), 64 deletions(-) create mode 100644 .run/Cassandra Oracle.run.xml create mode 100644 .run/Debug Gemini Docker.run.xml create mode 100644 .run/Run Gemini Docker.run.xml create mode 100644 .run/Run Gemini Mixed.run.xml create mode 100644 .run/Run Gemini Read.run.xml create mode 100644 .run/Run Gemini Write.run.xml create mode 100644 .run/Scylla Oracle.run.xml create mode 100644 .run/Tests.run.xml diff --git a/.run/Cassandra Oracle.run.xml b/.run/Cassandra Oracle.run.xml new file mode 100644 index 0000000..ec66c6d --- /dev/null +++ b/.run/Cassandra Oracle.run.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/.run/Debug Gemini Docker.run.xml b/.run/Debug Gemini Docker.run.xml new file mode 100644 index 0000000..b390c56 --- /dev/null +++ b/.run/Debug Gemini Docker.run.xml @@ -0,0 +1,32 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.run/Run Gemini Docker.run.xml b/.run/Run Gemini Docker.run.xml new file mode 100644 index 0000000..fea6526 --- /dev/null +++ b/.run/Run Gemini Docker.run.xml @@ -0,0 +1,28 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.run/Run Gemini Mixed.run.xml b/.run/Run Gemini Mixed.run.xml new file mode 100644 index 0000000..c6d7c6c --- /dev/null +++ b/.run/Run Gemini Mixed.run.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.run/Run Gemini Read.run.xml b/.run/Run Gemini Read.run.xml new file mode 100644 index 0000000..2c85116 --- /dev/null +++ b/.run/Run Gemini Read.run.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.run/Run Gemini Write.run.xml b/.run/Run Gemini Write.run.xml new file mode 100644 index 0000000..a2225e6 --- /dev/null +++ b/.run/Run Gemini Write.run.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.run/Scylla Oracle.run.xml b/.run/Scylla Oracle.run.xml new file mode 100644 index 0000000..c9111e1 --- /dev/null +++ b/.run/Scylla Oracle.run.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/.run/Tests.run.xml b/.run/Tests.run.xml new file mode 100644 index 0000000..ed5d241 --- /dev/null +++ b/.run/Tests.run.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 9c11c89..5e8aaf1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,8 @@ ENV GOAMD64=v3 ENV GOARM64=v8.3,crypto ENV CFLAGS="-O3" ENV CXXFLAGS="-O3" +ENV DEBIAN_FRONTEND="noninteractive" +ENV TZ="UTC" WORKDIR /gemini @@ -15,22 +17,52 @@ RUN apt-get update \ && apt-get install -y build-essential ca-certificates libc-dev \ && make build +FROM build AS debug + +ENV GODEBUG="default=go1.23,cgocheck=1,disablethp=0,panicnil=0,http2client=1,http2server=1,asynctimerchan=0,madvdontneed=0" +ENV PATH="/gemini/bin:${PATH}" + +RUN apt-get install -y gdb gcc iputils-ping mlocate vim \ + && make debug-build \ + && go install github.com/go-delve/delve/cmd/dlv@latest \ + && updatedb + +EXPOSE 6060 +EXPOSE 2121 +EXPOSE 2345 + +ENTRYPOINT [ \ + "dlv", "exec", "--log", "--listen=0.0.0.0:2345", "--allow-non-terminal-interactive", \ + "--headless", "--api-version=2", "--accept-multiclient", \ + "/gemini/bin/gemini", "--" \ +] + FROM busybox AS production WORKDIR / +ENV GODEBUG="default=go1.23,cgocheck=0,disablethp=0,panicnil=0,http2client=1,http2server=1,asynctimerchan=0,madvdontneed=0" + COPY --from=build /gemini/bin/gemini /usr/local/bin/gemini ENV PATH="/usr/local/bin:${PATH}" +EXPOSE 6060 +EXPOSE 2121 + ENTRYPOINT ["gemini"] FROM busybox AS production-goreleaser +ENV GODEBUG="default=go1.23,cgocheck=0,disablethp=0,panicnil=0,http2client=1,http2server=1,asynctimerchan=0,madvdontneed=0" + WORKDIR / COPY gemini /usr/local/bin/gemini ENV PATH="/usr/local/bin:${PATH}" +EXPOSE 6060 +EXPOSE 2121 + ENTRYPOINT ["gemini"] diff --git a/Makefile b/Makefile index 1677851..489c78e 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,46 @@ GO111MODULE := on GOOS := $(shell uname | tr '[:upper:]' '[:lower:]') GOARCH := $(shell go env GOARCH) -DOCKER_COMPOSE_TESTING := scylla -DOCKER_VERSION := latest +DOCKER_COMPOSE_TESTING ?= scylla +DOCKER_VERSION ?= latest +GOLANGCI_VERSION ?= 1.62.0 + +CQL_FEATURES ?= normal +CONCURRENCY ?= 1 +DURATION ?= 10m +WARMUP ?= 0 +MODE ?= mixed +DATASET_SIZE ?= large +SEED ?= $(shell date +%s) +GEMINI_BINARY ?= $(PWD)/bin/gemini +GEMINI_TEST_CLUSTER ?= $(shell docker inspect --format='{{ .NetworkSettings.Networks.gemini.IPAddress }}' gemini-test) +GEMINI_ORACLE_CLUSTER ?= $(shell docker inspect --format='{{ .NetworkSettings.Networks.gemini.IPAddress }}' gemini-oracle) +GEMINI_DOCKER_NETWORK ?= gemini +GEMINI_FLAGS ?= --fail-fast \ + --level=info \ + --non-interactive \ + --consistency=LOCAL_QUORUM \ + --test-host-selection-policy=token-aware \ + --oracle-host-selection-policy=token-aware \ + --mode=$(MODE) \ + --non-interactive \ + --request-timeout=5s \ + --connect-timeout=15s \ + --use-server-timestamps=false \ + --async-objects-stabilization-attempts=10 \ + --max-mutation-retries=10 \ + --replication-strategy="{'class': 'NetworkTopologyStrategy', 'replication_factor': '1'}" \ + --oracle-replication-strategy="{'class': 'NetworkTopologyStrategy', 'replication_factor': '1'}" \ + --concurrency=$(CONCURRENCY) \ + --dataset-size=$(DATASET_SIZE) \ + --seed=$(SEED) \ + --schema-seed=$(SEED) \ + --cql-features=$(CQL_FEATURES) \ + --duration=$(DURATION) \ + --warmup=$(WARMUP) \ + --profiling-port=6060 \ + --drop-schema=true + ifndef GOBIN export GOBIN := $(MAKEFILE_PATH)/bin @@ -21,28 +59,29 @@ define dl_tgz fi endef -$(GOBIN)/golangci-lint: GOLANGCI_VERSION = 1.62.0 +$(GOBIN)/golangci-lint: $(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: fmt fmt: - gofumpt -w -extra . + @gofumpt -w -extra . .PHONY: check check: $(GOBIN)/golangci-lint - $(GOBIN)/golangci-lint run + @$(GOBIN)/golangci-lint run .PHONY: fix fix: $(GOBIN)/golangci-lint - $(GOBIN)/golangci-lint run --fix + @$(GOBIN)/golangci-lint run --fix .PHONY: build build: @CGO_ENABLED=0 go build -ldflags="-s -w" -o bin/gemini ./cmd/gemini +.PHONY: debug-build debug-build: - @CGO_ENABLED=0 go build -gcflags "all=-N -l" -o bin/gemini ./cmd/gemini + @CGO_ENABLED=0 go build -gcflags="-N -l" -o bin/gemini ./cmd/gemini .PHONY: build-docker build-docker: @@ -56,80 +95,46 @@ setup: $(GOBIN)/golangci-lint scylla-setup debug-build scylla-setup: @docker compose -f docker/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 + @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 docker/docker-compose-$(DOCKER_COMPOSE_TESTING).yml down --volumes + @docker compose -f docker/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 ?= all -CONCURRENCY ?= 50 -DURATION ?= 10m -WARMUP ?= 1m -DATASET_SIZE ?= large -SEED ?= $(shell date +%s) -GEMINI_BINARY ?= $(PWD)/bin/gemini -GEMINI_TEST_CLUSTER ?= $(shell docker inspect --format='{{ .NetworkSettings.Networks.gemini.IPAddress }}' gemini-test) -GEMINI_ORACLE_CLUSTER ?= $(shell docker inspect --format='{{ .NetworkSettings.Networks.gemini.IPAddress }}' gemini-oracle) -GEMINI_DOCKER_NETWORK ?= gemini -GEMINI_FLAGS = --fail-fast \ - --level=info \ - --non-interactive \ - --materialized-views=false \ - --consistency=LOCAL_QUORUM \ - --test-host-selection-policy=token-aware \ - --oracle-host-selection-policy=token-aware \ - --mode=mixed \ - --non-interactive \ - --request-timeout=5s \ - --connect-timeout=15s \ - --use-server-timestamps=false \ - --async-objects-stabilization-attempts=10 \ - --max-mutation-retries=10 \ - --async-objects-stabilization-backoff=1000ms \ - --max-mutation-retries-backoff=1000ms \ - --replication-strategy="{'class': 'NetworkTopologyStrategy', 'replication_factor': '1'}" \ - --oracle-replication-strategy="{'class': 'NetworkTopologyStrategy', 'replication_factor': '1'}" \ - --concurrency=$(CONCURRENCY) \ - --use-lwt=true \ - --dataset-size=$(DATASET_SIZE) \ - --seed=$(SEED) \ - --schema-seed=$(SEED) \ - --cql-features=$(CQL_FEATURES) \ - --duration=$(DURATION) \ - --warmup=$(WARMUP) \ - --profiling-port=6060 \ - --drop-schema=true - .PHONY: pprof-profile pprof-profile: - go tool pprof -http=:8080 -intel_syntax -call_tree -seconds 60 http://localhost:6060/debug/pprof/profile + @go tool pprof -http=:8080 http://localhost:6060/debug/pprof/profile .PHONY: pprof-heap pprof-heap: - go tool pprof -http=:8080 -intel_syntax -call_tree -seconds 60 http://localhost:6060/debug/pprof/heap + @go tool pprof -http=:8081 http://localhost:6060/debug/pprof/heap .PHONY: pprof-goroutine pprof-goroutine: - go tool pprof -http=:8080 -intel_syntax -call_tree -seconds 60 http://localhost:6060/debug/pprof/goroutine + @go tool pprof -http=:8082 http://localhost:6060/debug/pprof/goroutine .PHONY: pprof-block pprof-block: - go tool pprof -http=:8080 -intel_syntax -call_tree -seconds 60 http://localhost:6060/debug/pprof/block + @go tool pprof -http=:8083 http://localhost:6060/debug/pprof/block + +.PHONY: pprof-mutex +pprof-mutex: + @go tool pprof -http=:8084 http://localhost:6060/debug/pprof/mutex .PHONY: docker-integration-test docker-integration-test: @mkdir -p $(PWD)/results @touch $(PWD)/results/gemini_seed @echo $(GEMINI_SEED) > $(PWD)/results/gemini_seed - docker run \ + @docker run \ -it \ --rm \ + --memory=4G \ -p 6060:6060 \ --name gemini \ --network $(GEMINI_DOCKER_NETWORK) \ @@ -138,10 +143,6 @@ docker-integration-test: scylladb/gemini:$(DOCKER_VERSION) \ --test-cluster=gemini-test \ --oracle-cluster=gemini-oracle \ - --outfile=/results/gemini_result.log \ - --tracing-outfile=/results/gemini_tracing.log \ - --test-statement-log-file=/results/gemini_test_statement.log \ - --oracle-statement-log-file=/results/gemini_oracle_statement.log \ $(GEMINI_FLAGS) .PHONY: integration-test @@ -152,10 +153,6 @@ integration-test: @$(GEMINI_BINARY) \ --test-cluster=$(GEMINI_TEST_CLUSTER) \ --oracle-cluster=$(GEMINI_ORACLE_CLUSTER) \ - --outfile=$(PWD)/results/gemini_result.log \ - --tracing-outfile=$(PWD)/results/gemini_tracing.log \ - --test-statement-log-file=$(PWD)/results/gemini_test_statement.log \ - --oracle-statement-log-file=$(PWD)/results/gemini_oracle_statement.log \ $(GEMINI_FLAGS) .PHONY: clean @@ -167,5 +164,5 @@ clean-bin: .PHONY: clean-results clean-results: - @sudo rm -rf results/*.log - @sudo rm -rf results/gemini_seed + @rm -rf results/*.log + @rm -rf results/gemini_seed