|
9 | 9 | "testing" |
10 | 10 | "time" |
11 | 11 |
|
| 12 | + "github.com/onkernel/hypeman/lib/exec" |
12 | 13 | "github.com/onkernel/hypeman/lib/images" |
13 | 14 | "github.com/onkernel/hypeman/lib/paths" |
14 | 15 | "github.com/onkernel/hypeman/lib/system" |
@@ -214,4 +215,43 @@ func TestExecConcurrent(t *testing.T) { |
214 | 215 | "streams appear serialized - took %v, expected < %v", streamElapsed, maxExpected) |
215 | 216 |
|
216 | 217 | t.Logf("Long-running streams completed in %v (concurrent OK)", streamElapsed) |
| 218 | + |
| 219 | + // Phase 3: Test command not found returns quickly (no hang) |
| 220 | + // Regression test for a hang that occurred when the command wasn't found. |
| 221 | + t.Log("Phase 3: Testing exec with non-existent command...") |
| 222 | + |
| 223 | + // Test without TTY |
| 224 | + start := time.Now() |
| 225 | + var stdout, stderr strings.Builder |
| 226 | + _, err = exec.ExecIntoInstance(ctx, inst.VsockSocket, exec.ExecOptions{ |
| 227 | + Command: []string{"nonexistent_command_asdfasdf"}, |
| 228 | + Stdout: &stdout, |
| 229 | + Stderr: &stderr, |
| 230 | + TTY: false, |
| 231 | + }) |
| 232 | + elapsed := time.Since(start) |
| 233 | + t.Logf("Exec (no TTY) completed in %v (error: %v)", elapsed, err) |
| 234 | + |
| 235 | + require.Error(t, err, "exec should fail for non-existent command") |
| 236 | + require.Contains(t, err.Error(), "executable file not found", "error should mention command not found") |
| 237 | + require.Less(t, elapsed, 5*time.Second, "exec should not hang, took %v", elapsed) |
| 238 | + |
| 239 | + // Test with TTY |
| 240 | + start = time.Now() |
| 241 | + stdout.Reset() |
| 242 | + stderr.Reset() |
| 243 | + _, err = exec.ExecIntoInstance(ctx, inst.VsockSocket, exec.ExecOptions{ |
| 244 | + Command: []string{"nonexistent_command_xyz123"}, |
| 245 | + Stdout: &stdout, |
| 246 | + Stderr: &stderr, |
| 247 | + TTY: true, |
| 248 | + }) |
| 249 | + elapsed = time.Since(start) |
| 250 | + t.Logf("Exec (with TTY) completed in %v (error: %v)", elapsed, err) |
| 251 | + |
| 252 | + require.Error(t, err, "exec with TTY should fail for non-existent command") |
| 253 | + require.Contains(t, err.Error(), "executable file not found", "error should mention command not found") |
| 254 | + require.Less(t, elapsed, 5*time.Second, "exec with TTY should not hang, took %v", elapsed) |
| 255 | + |
| 256 | + t.Log("Command not found tests passed - exec does not hang") |
217 | 257 | } |
0 commit comments