test(plugins): make the suite safe to run in parallel processes

Two things broke when the suite ran across several Ginkgo processes.

buildTestPlugins ran in every process, so N copies of make raced in the same
directory. The packaging rule made that worse by staging every plugin through
one shared plugin.wasm, so concurrent targets clobbered each other and left
orphaned temp files behind. That also ruled out make -j.

Stage each package under its own per-target directory, and move the build into
SynchronizedBeforeSuite so process 1 does it once while the others wait.
This commit is contained in:
Deluan 2026-08-30 16:26:44 -04:00
parent 46041bb908
commit 2a35d65d21
3 changed files with 16 additions and 15 deletions

1
.gitignore vendored
View File

@ -47,3 +47,4 @@ zz_*_test.go
# wazero compilation cache for the plugins test suite
/plugins/testdata/.wazero-cache/
/plugins/testdata/*.stage/

View File

@ -7,6 +7,7 @@ import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"net/http"
"os"
"os/exec"
@ -39,7 +40,6 @@ var (
func TestPlugins(t *testing.T) {
tests.Init(t, false)
buildTestPlugins(t, testDataDir)
// Set globally so tests using configtest.SetupConfig inherit it. The cache
// persists between runs; entries are content-addressed, so a stale one only misses.
@ -51,16 +51,11 @@ func TestPlugins(t *testing.T) {
RunSpecs(t, "Plugins Suite")
}
func buildTestPlugins(t *testing.T, path string) {
t.Helper()
func buildTestPlugins(path string) {
start := time.Now()
t.Logf("[BeforeSuite] Current working directory: %s", path)
cmd := exec.Command("make", "-C", path)
out, err := cmd.CombinedOutput()
t.Logf("[BeforeSuite] Make output: %s elapsed: %s", string(out), time.Since(start))
if err != nil {
t.Fatalf("Failed to build test plugins: %v", err)
}
out, err := exec.Command("make", "-C", path).CombinedOutput()
fmt.Fprintf(GinkgoWriter, "[BeforeSuite] built test plugins in %s:\n%s", time.Since(start), out)
Expect(err).ToNot(HaveOccurred(), "failed to build test plugins")
}
// createTestManager creates a new plugin Manager with the given plugin config.
@ -146,7 +141,10 @@ func createTestManagerWithPluginsAndMetrics(pluginConfig map[string]map[string]s
return manager, tmpDir
}
var _ = BeforeSuite(func() {
var _ = SynchronizedBeforeSuite(func() {
// Build once: the testdata Makefile is not safe to run concurrently.
buildTestPlugins(testDataDir)
}, func() {
// Get testdata directory (where test plugin .ndp packages live)
_, currentFile, _, ok := runtime.Caller(0)
Expect(ok).To(BeTrue())

View File

@ -10,17 +10,19 @@ all: $(PLUGINS:%=%.ndp)
clean:
rm -f $(PLUGINS:%=%.ndp) $(PLUGINS:%=%.wasm)
rm -rf .wazero-cache
rm -rf .wazero-cache $(PLUGINS:%=%.stage)
# PDK source files that trigger rebuild when changed (recursive)
PDK_SOURCES := $(shell find ../pdk/go -name '*.go' 2>/dev/null)
# Build the .ndp package (zip containing manifest.json + plugin.wasm)
# Stage under a per-target name: a shared plugin.wasm breaks concurrent builds.
%.ndp: %.wasm %/manifest.json
@rm -f $@
@cp $< plugin.wasm
zip -j $@ $*/manifest.json plugin.wasm
@rm -f plugin.wasm
@rm -rf $*.stage && mkdir -p $*.stage
@cp $< $*.stage/plugin.wasm
zip -j $@ $*/manifest.json $*.stage/plugin.wasm
@rm -rf $*.stage
@mv $< $<.tmp && mv $<.tmp $< # Touch wasm to ensure it's older than ndp
# Build the wasm binary. -buildvcs=false keeps the bytes stable across commits, so