Skip to content

Commit 67571c3

Browse files
committed
fix(e2e): use absolute bin path instead of per-test copy — same ETXTBSY fix as testscript
1 parent 4492c33 commit 67571c3

1 file changed

Lines changed: 17 additions & 40 deletions

File tree

tests/e2e/main_test.go

Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package e2e
66
import (
77
"context"
88
"fmt"
9-
"io"
109
"os"
1110
"os/exec"
1211
"path/filepath"
@@ -229,61 +228,39 @@ func cleanupE2EEnvironment(t *testing.T, env *E2EEnvironment) {
229228
t.Log("E2E environment cleanup complete")
230229
}
231230

232-
// setupAPXBinary builds or copies the apx binary into the testscript workspace
231+
// setupAPXBinary adds the pre-built apx binary to the testscript PATH.
232+
// It uses the absolute path to the repo's bin/ directory directly rather than
233+
// copying the binary per-test, which avoids ETXTBSY (text file busy) errors
234+
// on Linux when parallel tests copy and execute the binary simultaneously.
233235
func setupAPXBinary(env *testscript.Env) error {
234-
// Create bin directory in the test workspace
235-
binDir := filepath.Join(env.WorkDir, "bin")
236-
if err := os.MkdirAll(binDir, 0755); err != nil {
237-
return err
238-
}
239-
240236
binaryName := "apx"
241237
if runtime.GOOS == "windows" {
242238
binaryName = "apx.exe"
243239
}
244240

245-
// Check if the binary already exists in ./bin/ (built by CI or make)
246-
apxBinaryPath := filepath.Join("..", "..", "bin", binaryName)
247-
destPath := filepath.Join(binDir, binaryName)
241+
// Resolve the absolute path to the pre-built binary directory
242+
absDir, err := filepath.Abs(filepath.Join("..", "..", "bin"))
243+
if err != nil {
244+
return fmt.Errorf("failed to resolve bin directory: %w", err)
245+
}
246+
247+
binaryPath := filepath.Join(absDir, binaryName)
248248

249-
if _, err := os.Stat(apxBinaryPath); err == nil {
250-
// Copy the pre-built binary to the test workspace
251-
if err := copyBinaryFile(apxBinaryPath, destPath); err != nil {
249+
// Build if binary doesn't exist (local dev without CI pre-build)
250+
if _, err := os.Stat(binaryPath); os.IsNotExist(err) {
251+
if err := os.MkdirAll(absDir, 0755); err != nil {
252252
return err
253253
}
254-
} else {
255-
// Build the binary fresh
256-
cmd := exec.Command("go", "build", "-o", destPath, "../../cmd/apx")
254+
cmd := exec.Command("go", "build", "-o", binaryPath, "../../cmd/apx")
257255
cmd.Env = os.Environ()
258256
if output, err := cmd.CombinedOutput(); err != nil {
259257
return fmt.Errorf("failed to build apx binary: %w\nOutput: %s", err, output)
260258
}
261259
}
262260

263-
if err := os.Chmod(destPath, 0755); err != nil {
264-
return err
265-
}
266-
267-
// Add the bin directory to PATH
268-
newPath := binDir + string(os.PathListSeparator) + env.Getenv("PATH")
261+
// Add the absolute bin directory to PATH
262+
newPath := absDir + string(os.PathListSeparator) + env.Getenv("PATH")
269263
env.Setenv("PATH", newPath)
270264

271265
return nil
272266
}
273-
274-
// copyBinaryFile copies a file from src to dst
275-
func copyBinaryFile(src, dst string) error {
276-
srcFile, err := os.Open(src)
277-
if err != nil {
278-
return err
279-
}
280-
defer srcFile.Close()
281-
282-
data, err := io.ReadAll(srcFile)
283-
if err != nil {
284-
return err
285-
}
286-
srcFile.Close()
287-
288-
return os.WriteFile(dst, data, 0755)
289-
}

0 commit comments

Comments
 (0)