Skip to content

Commit 92659e6

Browse files
authored
test(e2e): improve test reliability and fix silent failures (#730)
- Add 30s timeout to agent URL wait loop to prevent infinite hangs - Propagate errors in SetupGPG instead of silently returning nil - Use dedicated http.ServeMux in ServeAgent to avoid global state conflicts - Add explicit timeouts/polling to all Eventually assertions missing them - Replace bare defer cleanup with ginkgo.DeferCleanup for timeout safety - Remove 3s sleep in SSH port forwarding test - Consolidate duplicate setupDockerProvider into framework.SetupDockerProvider - Delete commented-out GPG forwarding test code - Fix "nachine" typos and apt-get install spacing in error messages
1 parent 2613a0f commit 92659e6

26 files changed

Lines changed: 815 additions & 768 deletions

e2e/e2e_suite_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,14 @@ func TestRunE2ETests(t *testing.T) {
3333
if runtime.GOOS != "linux" {
3434
go framework.ServeAgent()
3535

36-
// wait for http server to be up and running
36+
// wait for http server to be up and running (max 30s)
37+
deadline := time.After(30 * time.Second)
3738
for {
39+
select {
40+
case <-deadline:
41+
t.Fatal("timeout waiting for DEVPOD_AGENT_URL to be set after 30s")
42+
default:
43+
}
3844
time.Sleep(time.Second)
3945
if os.Getenv("DEVPOD_AGENT_URL") != "" {
4046
break

e2e/framework/command.go

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -286,22 +286,22 @@ func (f *Framework) DevPodProviderUpdate(ctx context.Context, args ...string) er
286286
return nil
287287
}
288288

289-
func (f *Framework) DevPodMachineCreate(args []string) error {
289+
func (f *Framework) DevPodMachineCreate(ctx context.Context, args []string) error {
290290
baseArgs := []string{"machine", "create"}
291291
baseArgs = append(baseArgs, args...)
292-
err := f.ExecCommand(context.Background(), false, false, "", baseArgs)
292+
err := f.ExecCommand(ctx, false, false, "", baseArgs)
293293
if err != nil {
294-
return fmt.Errorf("devpod nachine create failed: %s", err.Error())
294+
return fmt.Errorf("devpod machine create failed: %s", err.Error())
295295
}
296296
return nil
297297
}
298298

299-
func (f *Framework) DevPodMachineDelete(args []string) error {
299+
func (f *Framework) DevPodMachineDelete(ctx context.Context, args []string) error {
300300
baseArgs := []string{"machine", "delete"}
301301
baseArgs = append(baseArgs, args...)
302-
err := f.ExecCommand(context.Background(), false, false, "", baseArgs)
302+
err := f.ExecCommand(ctx, false, false, "", baseArgs)
303303
if err != nil {
304-
return fmt.Errorf("devpod nachine delete failed: %s", err.Error())
304+
return fmt.Errorf("devpod machine delete failed: %s", err.Error())
305305
}
306306
return nil
307307
}
@@ -325,31 +325,31 @@ func (f *Framework) DevPodWorkspaceDelete(
325325

326326
func (f *Framework) SetupGPG(tmpDir string) error {
327327
if _, err := exec.LookPath("gpg"); err != nil {
328-
err := exec.Command("sudo", "apt-get", " install", "gnupg2", "-y").Run()
329-
if err != nil {
330-
return nil
328+
if installErr := exec.Command("sudo", "apt-get", "install", "gnupg2", "-y").
329+
Run(); installErr != nil {
330+
return fmt.Errorf("gpg not found and failed to install gnupg2: %w", installErr)
331331
}
332332
}
333333

334-
err := exec.Command("gpg", "--import", filepath.Join(tmpDir, "gpg-public.key")).Run()
335-
if err != nil {
336-
return nil
334+
// #nosec G204 -- gpg with fixed arguments for test GPG key setup
335+
if err := exec.Command("gpg", "--import", filepath.Join(tmpDir, "gpg-public.key")).
336+
Run(); err != nil {
337+
return fmt.Errorf("failed to import gpg public key: %w", err)
337338
}
338339

339-
err = exec.Command("gpg", "--import", filepath.Join(tmpDir, "gpg-private.key")).Run()
340-
if err != nil {
341-
return nil
340+
// #nosec G204 -- gpg with fixed arguments for test GPG key setup
341+
if err := exec.Command("gpg", "--import", filepath.Join(tmpDir, "gpg-private.key")).
342+
Run(); err != nil {
343+
return fmt.Errorf("failed to import gpg private key: %w", err)
342344
}
343345

344-
err = exec.Command("gpgconf", "--kill", "gpg-agent").Run()
345-
if err != nil {
346-
return nil
346+
if err := exec.Command("gpgconf", "--kill", "gpg-agent").Run(); err != nil {
347+
return fmt.Errorf("failed to kill gpg-agent: %w", err)
347348
}
348349

349-
err = exec.Command("gpg-agent", "--homedir", "$HOME/.gnupg", "--use-standard-socket", "--daemon").
350-
Run()
351-
if err != nil {
352-
return nil
350+
if err := exec.Command("gpg-agent", "--homedir", "$HOME/.gnupg", "--use-standard-socket", "--daemon").
351+
Run(); err != nil {
352+
return fmt.Errorf("failed to start gpg-agent: %w", err)
353353
}
354354

355355
return exec.Command("gpg", "-k").Run()
@@ -456,3 +456,19 @@ func (f *Framework) DevPodIDEList(ctx context.Context, extraArgs ...string) (str
456456
baseArgs := []string{"ide", "list"}
457457
return f.ExecCommandOutput(ctx, append(baseArgs, extraArgs...))
458458
}
459+
460+
// SetupDockerProvider creates a new framework, removes any existing docker provider,
461+
// adds a fresh one with the given docker path, and sets it as the active provider.
462+
func SetupDockerProvider(binDir, dockerPath string) (*Framework, error) {
463+
f := NewDefaultFramework(binDir)
464+
_ = f.DevPodProviderDelete(context.Background(), "docker")
465+
if err := f.DevPodProviderAdd(
466+
context.Background(),
467+
"docker",
468+
"-o",
469+
"DOCKER_PATH="+dockerPath,
470+
); err != nil {
471+
return nil, fmt.Errorf("failed to add docker provider: %w", err)
472+
}
473+
return f, f.DevPodProviderUse(context.Background(), "docker")
474+
}

e2e/framework/server_utils.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ func ServeAgent() {
2424
// Create a file server handler for the specified directory
2525
fileServer := http.FileServer(http.Dir(dir))
2626

27-
// Register the file server handler to serve files under the /files route
28-
http.Handle("/files/", http.StripPrefix("/files", fileServer))
27+
// Use a dedicated ServeMux to avoid conflicts with http.DefaultServeMux
28+
mux := http.NewServeMux()
29+
mux.Handle("/files/", http.StripPrefix("/files", fileServer))
2930

3031
ip := getIP()
3132

@@ -40,10 +41,10 @@ func ServeAgent() {
4041
log.Fatal(err)
4142
}
4243

43-
// Start the HTTP server on port 8080
4444
log.Printf("Server started on %s", addr)
4545

46-
err = http.Serve(listener, nil)
46+
// #nosec G114 -- test-only agent file server, no timeout needed
47+
err = http.Serve(listener, mux)
4748
if err != nil {
4849
log.Fatal(err)
4950
}

0 commit comments

Comments
 (0)