diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index b91c19505..012e3a9c3 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -131,12 +131,22 @@ jobs: uses: actions/checkout@v7 - uses: actions/setup-go@v6 + id: setup-go with: go-version-file: go.mod - name: Download dependencies run: go mod download + # Without this, the plugins suite recompiles every test plugin WASM module, + # which dominates the job runtime under -race. + - name: Cache the plugins test suite WASM compilation cache + uses: actions/cache@v6 + with: + path: plugins/testdata/.wazero-cache + key: wazero-${{ runner.os }}-go${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('plugins/testdata/*/*.go', 'plugins/testdata/*/go.*', 'plugins/pdk/go/**/*.go', 'plugins/pdk/go/go.*') }} + restore-keys: wazero-${{ runner.os }}- + - name: Test run: go test -shuffle=on -tags netgo,sqlite_fts5 -race ./... -v diff --git a/.gitignore b/.gitignore index 6459ded9b..810074e72 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,7 @@ go.work* .playwright-mcp/ # Temp benchmark files -zz_*_test.go \ No newline at end of file +zz_*_test.go + +# wazero compilation cache for the plugins test suite +/plugins/testdata/.wazero-cache/ diff --git a/plugins/plugins_suite_test.go b/plugins/plugins_suite_test.go index 77956e2f9..c8585f2c1 100644 --- a/plugins/plugins_suite_test.go +++ b/plugins/plugins_suite_test.go @@ -25,7 +25,10 @@ import ( . "github.com/onsi/gomega" ) -const testDataDir = "plugins/testdata" +const ( + testDataDir = "plugins/testdata" + wazeroCacheDir = ".wazero-cache" +) // Shared test state initialized in BeforeSuite var ( @@ -38,18 +41,10 @@ func TestPlugins(t *testing.T) { tests.Init(t, false) buildTestPlugins(t, testDataDir) - // Create a shared wazero compilation cache directory. - // All test managers will point CacheFolder here so that WASM compilation - // is done once per binary and then reused from disk cache. - sharedCacheDir, err := os.MkdirTemp("", "plugins-shared-cache-*") - if err != nil { - t.Fatalf("Failed to create shared cache dir: %v", err) - } - t.Cleanup(func() { os.RemoveAll(sharedCacheDir) }) - - // Set CacheFolder globally so all tests (including those using - // configtest.SetupConfig) inherit it without needing to set it manually. - conf.Server.CacheFolder = conf.NewDir(sharedCacheDir) + // Set globally so tests using configtest.SetupConfig inherit it. The cache + // persists between runs; entries are content-addressed, so a stale one only misses. + conf.Server.CacheFolder = conf.NewDir(filepath.Join(testDataDir, wazeroCacheDir)) + conf.Server.Plugins.CacheSize = "1GB" // the default evicts the cache mid-run log.SetLevel(log.LevelFatal) RegisterFailHandler(Fail) diff --git a/plugins/testdata/Makefile b/plugins/testdata/Makefile index d53f2aaee..758497095 100644 --- a/plugins/testdata/Makefile +++ b/plugins/testdata/Makefile @@ -10,6 +10,7 @@ all: $(PLUGINS:%=%.ndp) clean: rm -f $(PLUGINS:%=%.ndp) $(PLUGINS:%=%.wasm) + rm -rf .wazero-cache # PDK source files that trigger rebuild when changed (recursive) PDK_SOURCES := $(shell find ../pdk/go -name '*.go' 2>/dev/null) @@ -22,10 +23,11 @@ PDK_SOURCES := $(shell find ../pdk/go -name '*.go' 2>/dev/null) @rm -f plugin.wasm @mv $< $<.tmp && mv $<.tmp $< # Touch wasm to ensure it's older than ndp -# Build the wasm binary +# Build the wasm binary. -buildvcs=false keeps the bytes stable across commits, so +# the test suite's wazero compilation cache still hits after a rebuild. %.wasm: %/*.go %/go.mod $(PDK_SOURCES) ifdef TINYGO cd $* && tinygo build -target wasip1 -buildmode=c-shared -o ../$@ . else - cd $* && GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o ../$@ . + cd $* && GOOS=wasip1 GOARCH=wasm go build -buildvcs=false -buildmode=c-shared -o ../$@ . endif \ No newline at end of file