diff --git a/Makefile b/Makefile index b023cebf99a..0905537cf08 100644 --- a/Makefile +++ b/Makefile @@ -84,16 +84,16 @@ uninstall: ## Uninstall dgraph binary dgraph-installed: $(MAKE) install -.PHONY: deps -deps: ## Check test dependencies (pass AUTO_INSTALL=true to auto-install missing ones) - $(MAKE) -C t deps +.PHONY: check-deps +check-deps: ## Check test dependencies (pass AUTO_INSTALL=true to auto-install missing ones) + $(MAKE) -C t check-deps .PHONY: setup setup: ## Install all test dependencies automatically - $(MAKE) deps AUTO_INSTALL=true + $(MAKE) check-deps AUTO_INSTALL=true .PHONY: test -test: dgraph-installed local-image ## Run tests (default: integration + integration2) +test: check-deps dgraph-installed local-image ## Run tests (default: integration + integration2) ifdef TAGS @echo "Running tests with tags: $(TAGS)" go test -v --tags="$(TAGS)" \ @@ -177,7 +177,7 @@ test-all: ## Every test: all t/ suites + integration2 + upgrade + fuzz $(MAKE) test-fuzz .PHONY: test-benchmark -test-benchmark: ## Go benchmarks (i.e. 'go test -bench') +test-benchmark: check-deps ## Go benchmarks (i.e. 'go test -bench') go test -bench=. -benchmem $(if $(PKG),./$(PKG)/...,./...) .PHONY: local-image diff --git a/TESTING.md b/TESTING.md index a25a2d6d12f..e0118f47b9b 100644 --- a/TESTING.md +++ b/TESTING.md @@ -142,24 +142,28 @@ auto-install them: make setup # Check dependencies without installing (reports what's missing) -make deps +make check-deps -# Same as 'make deps' but auto-installs anything missing -make deps AUTO_INSTALL=true +# Same as 'make check-deps' but auto-installs anything missing +make check-deps AUTO_INSTALL=true ``` The check scripts validate: -- Go version (1.21+) -- Docker and Docker Compose versions and memory allocation +- Go version (matches go.mod requirement) +- Docker and Docker Compose versions +- Docker available memory (warns if < 8GB, with auto-fix on macOS) - gotestsum installation - ack installation +- Cross-compiler for non-Linux hosts (macOS) +- protoc installation (Linux only) - Dgraph binary existence and correct architecture ### Required Tools -> **Note:** You don't need to install these manually. Running `make setup` from the repo root -> automatically installs missing dependencies. The commands below are listed for reference. +> **Note:** You do **not** need to install these manually. Running `make setup` or +> `make check-deps AUTO_INSTALL=true` from the repo root automatically checks and installs all +> missing dependencies. The commands below are listed only as reference for what gets installed. #### 1. Go (1.21+) @@ -273,6 +277,9 @@ Use `go test` to run one easy test on types package: ```bash go test -v ./types/... -run TestConvert + +# Or with make (runs all unit tests, not just one) +make test-unit ``` **Expected output:** @@ -294,6 +301,9 @@ ok github.com/dgraph-io/dgraph/v25/types (cached) ```bash cd t && go build . && ./t --test=TestGQLSchema + +# Or with make +make test TEST=TestGQLSchema ``` If both pass, you're ready to run all test types! @@ -304,28 +314,27 @@ If both pass, you're ready to run all test types! ### Using Make Targets -The simplest way to run tests: - -```bash -# Run default tests (~30 min): integration suite + integration2 -make test - -# Run every test in the repo (all suites + all tag-based tests + fuzz) -make test-all - -# Common shortcuts (run 'make help' for full list) -make test-unit # True unit tests only — no Docker, no build tags -make test-integration # Integration tests via t/ runner with Docker (SUITE=integration) -make test-integration-heavy # All heavy tests: systest-heavy + ldbc + load -make test-core # Core tests (i.e. 'make test SUITE=core') -make test-systest # All systest packages: systest-baseline + systest-heavy -make test-vector # Vector search tests (i.e. 'make test SUITE=vector') -make test-integration2 # Integration2 tests via dgraphtest (i.e. 'make test TAGS=integration2') -make test-upgrade # Upgrade tests (i.e. 'make test TAGS=upgrade') -make test-fuzz # Fuzz tests (i.e. 'make test FUZZ=1') -make test-all # Every test: all t/ suites + integration2 + upgrade + fuzz -make test-benchmark # Go benchmarks (i.e. 'go test -bench') -``` +The simplest way to run tests is `make test` (default: `integration` suite + `integration2`). Each +`test-*` target is a shortcut for `make test` with specific arguments. The table below shows all +three ways to run each test type. + +| Target | `make test` equivalent | Without make | +| ----------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------- | +| `make test` | _(default)_ | `cd t && ./t --suite=integration` then `go test -v --tags=integration2 ./...` | +| `make test-unit` | `make test SUITE=unit` | `cd t && ./t --suite=unit` | +| `make test-integration` | `make test SUITE=integration` | `cd t && ./t --suite=integration` | +| `make test-core` | `make test SUITE=core` | `cd t && ./t --suite=core` | +| `make test-systest` | `make test SUITE=systest` | `cd t && ./t --suite=systest` | +| `make test-vector` | `make test SUITE=vector` | `cd t && ./t --suite=vector` | +| `make test-integration-heavy` | `make test SUITE=systest-heavy,ldbc,load` | `cd t && ./t --suite=systest-heavy,ldbc,load` | +| `make test-integration2` | `make test TAGS=integration2` | `go test -v --tags=integration2 ./...` | +| `make test-upgrade` | `make test TAGS=upgrade` | `go test -v --tags=upgrade ./...` | +| `make test-fuzz` | `make test FUZZ=1` | `go test -v -fuzz=Fuzz -fuzztime=300s ./dql/...` | +| `make test-benchmark` | _(no equivalent)_ | `go test -bench=. -benchmem ./...` | +| `make test-all` | _(no equivalent)_ | Runs `SUITE=all` + `integration2` + `upgrade` + fuzz sequentially | + +> **Tip:** All targets accept `PKG=`, `TEST=`, and `TIMEOUT=` variables. For example: +> `make test-systest PKG=systest/plugin TEST=TestPasswordReturn TIMEOUT=60m` Run `make help` to see all available targets, variables, and dynamically discovered SUITE/TAGS values. @@ -501,6 +510,19 @@ go test ./types/... go test -v ./types/... -run TestConvert ``` +**With make:** + +```bash +# Run all unit tests (no Docker, no build tags) +make test-unit + +# Run unit tests for a specific package +make test-unit PKG=types + +# Run a specific unit test +make test-unit PKG=types TEST=TestConvert +``` + ### Identifying a unit test - No `//go:build` tag at the top of the file = unit test @@ -586,6 +608,19 @@ cd t && go build . ./t -r ``` +**With make:** + +```bash +# Run a suite +make test SUITE=core + +# Run specific package +make test SUITE=integration PKG=systest/export + +# Run single test +make test TEST=TestExportAndLoadJson +``` + ### Key Flags | Flag | Description | @@ -621,6 +656,16 @@ cd t && go build . ./t --pkg=systest/export --keep ``` +**With make:** + +```bash +# Run all tests in a package (make builds the runner automatically) +make test SUITE=integration PKG=systest/export + +# Run single test +make test TEST=TestExportAndLoadJson +``` + ### Method 2: Manual Cluster + go test For fine-grained control, manually start a cluster and run tests against it. @@ -693,6 +738,19 @@ Using `t/` runner: ./t --suite=systest ``` +**With make:** + +```bash +# Run all systest packages +make test-systest + +# Run specific systest package +make test SUITE=systest PKG=systest/export + +# Run specific test by name +make test TEST=TestExportAndLoadJson +``` + ### Key Environment Variables | Variable | Purpose | Set by | @@ -738,6 +796,19 @@ go test -v --tags=integration2 ./systest/integration2/ go test -v --tags=integration2 --run '^TestName$' ./pkg/ ``` +**With make:** + +```bash +# Run all integration2 tests +make test-integration2 + +# Run integration2 tests for a specific package +make test TAGS=integration2 PKG=systest/vector + +# Run a specific integration2 test +make test TAGS=integration2 PKG=systest/vector TEST=TestVectorSearch +``` + ### Version & Binary Management **Automatic version handling:** @@ -948,6 +1019,19 @@ go test -v --tags=upgrade ./worker/ go test -v --tags=upgrade -run '^TestUpgradeName$' ./pkg/ ``` +**With make:** + +```bash +# Run all upgrade tests +make test-upgrade + +# Run upgrade tests for a specific package +make test TAGS=upgrade PKG=acl + +# Run a specific upgrade test +make test TAGS=upgrade PKG=acl TEST=TestACL +``` + ### Where Upgrade Tests Live | Package | Tests | @@ -1222,6 +1306,19 @@ go test -v --tags=integration --run 'TestPluginTestSuite/TestPasswordReturn/subt go test -v --tags=upgrade --run 'TestPluginTestSuite/TestPasswordReturn' ./systest/plugin/ ``` +**With make:** + +```bash +# Run the plugin systest package via t/ runner +make test SUITE=systest PKG=systest/plugin + +# Run a specific test +make test SUITE=systest PKG=systest/plugin TEST=TestPluginTestSuite/TestPasswordReturn + +# Run in upgrade mode +make test TAGS=upgrade PKG=systest/plugin TEST=TestPluginTestSuite/TestPasswordReturn +``` + **When NOT to use:** - Simple one-off tests → use regular `func TestX(t *testing.T)` @@ -1258,6 +1355,16 @@ go test -v ./dql -fuzz=Fuzz -fuzztime=5m go test -v ./dql -fuzz=Fuzz -fuzztime=300s -fuzzminimizetime=120s ``` +**With make:** + +```bash +# Run all fuzz tests (default 300s per package) +make test-fuzz + +# Fuzz a specific package with custom duration +make test FUZZ=1 PKG=dql FUZZTIME=5m +``` + ### CI Workflow - `ci-dgraph-fuzz.yml` (runs on PRs) @@ -1276,41 +1383,6 @@ go test -v ./dql -fuzz=Fuzz -fuzztime=300s -fuzzminimizetime=120s ## Future Improvement Ideas -### ✅ Completed Improvements - -The following items from the original wishlist have been implemented: - -- **✅ OS detection and automatic binary handling:** The Makefile now detects the host OS at runtime - and automatically builds the correct binaries. On macOS, `make install` builds both native and - Linux binaries without manual intervention. - -- **✅ Automatic binary path management:** The `LINUX_GOBIN` environment variable is automatically - set based on OS. Docker Compose files use `${LINUX_GOBIN:-$GOPATH/bin}` to mount the correct - binary. - -- **✅ No manual setup scripts required:** The `make test` target now depends on `dgraph-installed` - which automatically builds binaries if missing. Dependency checking scripts in `t/scripts/` can - auto-install missing tools with `AUTO_INSTALL=true`. - -- **✅ Prerequisites handled automatically:** Running `make test` validates dependencies and builds - required binaries before running tests. - -- **✅ Unified test interface:** A single `make test` entry point that accepts arguments to run any - test type (unit, integration, integration2, upgrade, fuzz) with environment variables for control. - The default (`make test` with no args) runs `integration` suite plus `integration2` for a fast - feedback loop (~30 min). Use `make test-all` to run every test. - -- **✅ Example commands that "just work":** The following now work as expected: - - ```bash - make test SUITE=systest - make test FUZZ=1 PKG=dql - make test TAGS=upgrade PKG=acl - make test SUITE=systest PKG=systest/plugin - ``` - -### Remaining Ideas - The following improvements could still enhance the developer experience: - **Extend t/ runner:** Have the `t/` runner also handle unit and integration2 tests, providing a diff --git a/t/Makefile b/t/Makefile index b6e35a851f5..ed1a7cd1110 100644 --- a/t/Makefile +++ b/t/Makefile @@ -3,6 +3,9 @@ # SPDX-License-Identifier: Apache-2.0 # +# OS detection (lowercase: linux, darwin) +OS := $(shell uname -s | tr '[:upper:]' '[:lower:]') + # linux || darwin GOOS ?= $(shell go env GOOS) export GOPATH ?= $(shell go env GOPATH) @@ -18,15 +21,16 @@ endif all: test -.PHONY: deps -deps: check-go check-docker check-gotestsum check-ack check-cross-compiler - @if [ "$(GOOS)" = "linux" ]; then \ - which protoc > /dev/null 2>&1 || (echo "Error: protoc is not installed or not in PATH" && exit 1); \ - fi +# =========================================================================== +# Dependency checking +# =========================================================================== + +.PHONY: check-deps +check-deps: check-deps-go check-deps-docker check-deps-gotestsum check-deps-ack check-deps-cross-compiler check-deps-protoc check-docker-available-memory @echo "All dependencies are installed" .PHONY: check -check: deps +check: check-deps @echo "LINUX_GOBIN=$(LINUX_GOBIN)" @if [ -f "$(LINUX_GOBIN)/dgraph" ]; then \ file $(LINUX_GOBIN)/dgraph | grep -q "ELF.*executable" || (echo "Error: dgraph binary at $(LINUX_GOBIN)/dgraph is not a Linux executable" && exit 1); \ @@ -35,33 +39,208 @@ check: deps fi @echo "The dgraph binary is a Linux executable (as required)" -.PHONY: check-docker -check-docker: - @./scripts/check-docker.sh +# ---- check-deps-{tool} targets ---- +# +# Flow for each tool: +# 1. Silent check → pass → done +# 2. Silent check → fail + AUTO_INSTALL=true → install via OS target → re-check +# 3. Silent check → fail + no AUTO_INSTALL → re-run with output → exit 1 + +.PHONY: check-deps-go +check-deps-go: + @if AUTO_INSTALL= ./scripts/check-deps-go.sh >/dev/null 2>&1; then \ + :; \ + elif [ "$(AUTO_INSTALL)" = "true" ]; then \ + $(MAKE) install-deps-go-$(OS) && \ + AUTO_INSTALL= ./scripts/check-deps-go.sh; \ + else \ + AUTO_INSTALL= ./scripts/check-deps-go.sh || exit 1; \ + fi + +.PHONY: check-deps-docker +check-deps-docker: + @if AUTO_INSTALL= ./scripts/check-deps-docker.sh >/dev/null 2>&1; then \ + :; \ + elif [ "$(AUTO_INSTALL)" = "true" ]; then \ + $(MAKE) install-deps-docker-$(OS) && \ + AUTO_INSTALL= ./scripts/check-deps-docker.sh; \ + else \ + AUTO_INSTALL= ./scripts/check-deps-docker.sh || exit 1; \ + fi + +.PHONY: check-deps-gotestsum +check-deps-gotestsum: + @if AUTO_INSTALL= ./scripts/check-deps-gotestsum.sh >/dev/null 2>&1; then \ + :; \ + elif [ "$(AUTO_INSTALL)" = "true" ]; then \ + $(MAKE) install-deps-gotestsum-$(OS) && \ + AUTO_INSTALL= ./scripts/check-deps-gotestsum.sh; \ + else \ + AUTO_INSTALL= ./scripts/check-deps-gotestsum.sh || exit 1; \ + fi + +.PHONY: check-deps-ack +check-deps-ack: + @if AUTO_INSTALL= ./scripts/check-deps-ack.sh >/dev/null 2>&1; then \ + :; \ + elif [ "$(AUTO_INSTALL)" = "true" ]; then \ + $(MAKE) install-deps-ack-$(OS) && \ + AUTO_INSTALL= ./scripts/check-deps-ack.sh; \ + else \ + AUTO_INSTALL= ./scripts/check-deps-ack.sh || exit 1; \ + fi + +.PHONY: check-deps-cross-compiler +check-deps-cross-compiler: + @if AUTO_INSTALL= ./scripts/check-deps-cross-compiler.sh >/dev/null 2>&1; then \ + :; \ + elif [ "$(AUTO_INSTALL)" = "true" ]; then \ + $(MAKE) install-deps-cross-compiler-$(OS) && \ + AUTO_INSTALL= ./scripts/check-deps-cross-compiler.sh; \ + else \ + AUTO_INSTALL= ./scripts/check-deps-cross-compiler.sh || exit 1; \ + fi + +.PHONY: check-deps-protoc +check-deps-protoc: + @if [ "$(OS)" = "linux" ]; then \ + if AUTO_INSTALL= ./scripts/check-deps-protoc.sh >/dev/null 2>&1; then :; \ + elif [ "$(AUTO_INSTALL)" = "true" ]; then \ + $(MAKE) install-deps-protoc-$(OS) && \ + AUTO_INSTALL= ./scripts/check-deps-protoc.sh; \ + else \ + AUTO_INSTALL= ./scripts/check-deps-protoc.sh || exit 1; \ + fi; \ + fi + +# ---- Docker memory check ---- + +.PHONY: check-docker-available-memory +check-docker-available-memory: check-deps-docker + @$(MAKE) check-docker-available-memory-$(OS) + +.PHONY: check-docker-available-memory-darwin +check-docker-available-memory-darwin: + @./scripts/check-docker-available-memory.sh + +.PHONY: check-docker-available-memory-linux +check-docker-available-memory-linux: + @./scripts/check-docker-available-memory.sh + +# =========================================================================== +# Install targets — Homebrew prerequisite (darwin) +# =========================================================================== + +.PHONY: check-install-deps-homebrew-darwin +check-install-deps-homebrew-darwin: + @[ "$(OS)" = "darwin" ] || { echo "ERROR: Homebrew is only available on macOS"; exit 1; } + @AUTO_INSTALL=$(AUTO_INSTALL) ./scripts/check-deps-brew.sh + +# =========================================================================== +# Install targets — darwin +# =========================================================================== + +.PHONY: install-deps-go-darwin +install-deps-go-darwin: check-install-deps-homebrew-darwin + @brew upgrade go 2>/dev/null || brew install go + +.PHONY: install-deps-docker-darwin +install-deps-docker-darwin: check-install-deps-homebrew-darwin + @brew install --cask docker + +.PHONY: install-deps-gotestsum-darwin +install-deps-gotestsum-darwin: check-install-deps-homebrew-darwin + @go install gotest.tools/gotestsum@latest + +.PHONY: install-deps-ack-darwin +install-deps-ack-darwin: check-install-deps-homebrew-darwin + @brew install ack + +.PHONY: install-deps-cross-compiler-darwin +install-deps-cross-compiler-darwin: check-install-deps-homebrew-darwin + @brew tap messense/macos-cross-toolchains && \ + brew install messense/macos-cross-toolchains/$$(case $$(uname -m) in arm64|aarch64) echo aarch64-unknown-linux-gnu;; x86_64) echo x86_64-unknown-linux-gnu;; esac) + +.PHONY: install-deps-protoc-darwin +install-deps-protoc-darwin: check-install-deps-homebrew-darwin + @brew install protobuf + +# =========================================================================== +# Install targets — linux +# =========================================================================== + +.PHONY: install-deps-go-linux +install-deps-go-linux: + @echo ""; \ + echo "Go is not installed or is below the required version."; \ + echo ""; \ + VERSION=$$(grep -E '^go [0-9]+\.[0-9]+' ../go.mod | awk '{print $$2}'); \ + echo "Required version: Go $${VERSION} (from go.mod)"; \ + echo ""; \ + echo "Install or upgrade Go using the official instructions:"; \ + echo " https://go.dev/doc/install"; \ + echo ""; \ + ARCH=$$(uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/'); \ + echo "Quick steps for Linux:"; \ + echo " curl -fsSLO https://go.dev/dl/go$${VERSION}.linux-$${ARCH}.tar.gz"; \ + echo " sudo rm -rf /usr/local/go"; \ + echo " sudo tar -C /usr/local -xzf go$${VERSION}.linux-$${ARCH}.tar.gz"; \ + echo " export PATH=\$$PATH:/usr/local/go/bin"; \ + echo ""; \ + exit 1 + +.PHONY: install-deps-docker-linux +install-deps-docker-linux: + @if command -v apt-get >/dev/null 2>&1; then $(MAKE) install-deps-docker-linux-apt; \ + elif command -v dnf >/dev/null 2>&1; then $(MAKE) install-deps-docker-linux-dnf; \ + elif command -v pacman >/dev/null 2>&1; then $(MAKE) install-deps-docker-linux-pacman; \ + else echo "ERROR: No supported package manager found (tried: apt, dnf, pacman)"; exit 1; fi + +.PHONY: install-deps-docker-linux-apt +install-deps-docker-linux-apt: + @sudo apt-get update && sudo apt-get install -y ca-certificates curl gnupg && \ + sudo install -m 0755 -d /etc/apt/keyrings && \ + curl -fsSL https://download.docker.com/linux/$$(. /etc/os-release && echo "$${ID:-ubuntu}")/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \ + sudo chmod a+r /etc/apt/keyrings/docker.gpg && \ + echo "deb [arch=$$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/$$(. /etc/os-release && echo "$${ID:-ubuntu}") $$(. /etc/os-release && echo "$${VERSION_CODENAME}") stable" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null && \ + sudo apt-get update && \ + sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + +.PHONY: install-deps-docker-linux-dnf +install-deps-docker-linux-dnf: + @sudo dnf -y install dnf-plugins-core && \ + sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo && \ + sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -.PHONY: check-gotestsum -check-gotestsum: - @./scripts/check-gotestsum.sh +.PHONY: install-deps-docker-linux-pacman +install-deps-docker-linux-pacman: + @sudo pacman -S --noconfirm docker docker-compose -.PHONY: check-ack -check-ack: - @./scripts/check-ack.sh +.PHONY: install-deps-gotestsum-linux +install-deps-gotestsum-linux: + @go install gotest.tools/gotestsum@latest -.PHONY: check-cross-compiler -check-cross-compiler: - @./scripts/check-cross-compiler.sh +.PHONY: install-deps-ack-linux +install-deps-ack-linux: + @if command -v apt-get >/dev/null 2>&1; then sudo apt-get update && sudo apt-get install -y ack; \ + elif command -v dnf >/dev/null 2>&1; then sudo dnf install -y ack; \ + elif command -v pacman >/dev/null 2>&1; then sudo pacman -S --noconfirm ack; \ + else echo "ERROR: No supported package manager found (tried: apt, dnf, pacman)"; exit 1; fi -.PHONY: check-protoc -check-protoc: - @./scripts/check-protoc.sh +.PHONY: install-deps-cross-compiler-linux +install-deps-cross-compiler-linux: + @: # Cross-compiler not needed on Linux -.PHONY: check-go -check-go: - @./scripts/check-go.sh +.PHONY: install-deps-protoc-linux +install-deps-protoc-linux: + @if command -v apt-get >/dev/null 2>&1; then sudo apt-get update && sudo apt-get install -y protobuf-compiler; \ + elif command -v dnf >/dev/null 2>&1; then sudo dnf install -y protobuf-compiler; \ + elif command -v pacman >/dev/null 2>&1; then sudo pacman -S --noconfirm protobuf; \ + else echo "ERROR: No supported package manager found (tried: apt, dnf, pacman)"; exit 1; fi -.PHONY: check-brew -check-brew: - @./scripts/check-brew.sh +# =========================================================================== +# Build & test +# =========================================================================== .PHONY: dgraph-installed dgraph-installed: diff --git a/t/scripts/check-ack.sh b/t/scripts/check-deps-ack.sh similarity index 100% rename from t/scripts/check-ack.sh rename to t/scripts/check-deps-ack.sh diff --git a/t/scripts/check-brew.sh b/t/scripts/check-deps-brew.sh similarity index 100% rename from t/scripts/check-brew.sh rename to t/scripts/check-deps-brew.sh diff --git a/t/scripts/check-cross-compiler.sh b/t/scripts/check-deps-cross-compiler.sh similarity index 100% rename from t/scripts/check-cross-compiler.sh rename to t/scripts/check-deps-cross-compiler.sh diff --git a/t/scripts/check-docker.sh b/t/scripts/check-deps-docker.sh similarity index 100% rename from t/scripts/check-docker.sh rename to t/scripts/check-deps-docker.sh diff --git a/t/scripts/check-go.sh b/t/scripts/check-deps-go.sh similarity index 100% rename from t/scripts/check-go.sh rename to t/scripts/check-deps-go.sh diff --git a/t/scripts/check-gotestsum.sh b/t/scripts/check-deps-gotestsum.sh similarity index 100% rename from t/scripts/check-gotestsum.sh rename to t/scripts/check-deps-gotestsum.sh diff --git a/t/scripts/check-protoc.sh b/t/scripts/check-deps-protoc.sh similarity index 100% rename from t/scripts/check-protoc.sh rename to t/scripts/check-deps-protoc.sh diff --git a/t/scripts/check-docker-available-memory.sh b/t/scripts/check-docker-available-memory.sh new file mode 100755 index 00000000000..65017b82126 --- /dev/null +++ b/t/scripts/check-docker-available-memory.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# shellcheck disable=SC2310 +set -euo pipefail + +# shellcheck source=checkhelper.sh +source "$(dirname "${BASH_SOURCE[0]}")/checkhelper.sh" + +# Minimum recommended Docker memory in MB +REC_MEM_MB=8192 + +main() { + # Query Docker memory (Docker must be running — guaranteed by Make prereq on check-deps-docker) + local mem_bytes + mem_bytes="$(docker info --format '{{.MemTotal}}' 2>/dev/null)" || { + warn "could not query Docker memory (is Docker running?)" + exit 0 + } + + if [[ -z ${mem_bytes} || ! ${mem_bytes} =~ ^[0-9]+$ ]]; then + warn "could not parse Docker memory info" + exit 0 + fi + + local mem_mb=$((mem_bytes / 1024 / 1024)) + + if ((mem_mb >= REC_MEM_MB)); then + exit 0 + fi + + # Memory is below recommended + warn "Docker memory ${mem_mb}MB is below recommended ${REC_MEM_MB}MB" + warn "Some tests may fail with OOM errors" + + local os + os="$(uname -s)" + + if [[ ${os} == "Darwin" ]]; then + local settings_file="${HOME}/Library/Group Containers/group.com.docker/settings-store.json" + + if [[ ${AUTO_INSTALL-} == "true" ]]; then + if [[ -f ${settings_file} ]] && command -v jq &>/dev/null; then + local tmp + tmp="$(mktemp)" + if jq '.memoryMiB = 8192' "${settings_file}" >"${tmp}" 2>/dev/null; then + cp "${tmp}" "${settings_file}" + rm "${tmp}" + warn "Updated Docker Desktop memory setting to 8192MB" + warn "Please restart Docker Desktop for the change to take effect" + else + rm -f "${tmp}" + warn "Could not update Docker Desktop settings automatically" + warn "Please increase memory via: Docker Desktop → Settings → Resources → Memory" + fi + else + warn "Please increase memory via: Docker Desktop → Settings → Resources → Memory" + fi + else + warn "Please increase memory via: Docker Desktop → Settings → Resources → Memory" + fi + else + # Linux — Docker uses host memory directly + warn "Consider adding more RAM to this machine or reducing test parallelism" + fi + + # Always exit 0 — this is a warning, not a blocker + exit 0 +} + +main "$@" diff --git a/t/t.go b/t/t.go index 59ed9f3a687..168b6d364c7 100644 --- a/t/t.go +++ b/t/t.go @@ -428,7 +428,7 @@ func sanitizeFilename(pkg string) string { // gotestsumBin returns the absolute path to gotestsum inside $GOPATH/bin. // This avoids relying on $PATH, which may not include $GOPATH/bin on all machines -// (the check-gotestsum.sh script validates at this same path). +// (the check-deps-gotestsum.sh script validates at this same path). func gotestsumBin() string { gopath := os.Getenv("GOPATH") if gopath == "" {