@@ -6,7 +6,6 @@ package e2e
66import (
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.
233235func 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\n Output: %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