Enhance Exec Method with Context-Aware Output Handling and Timeout Verification
- Updated the Exec method to read output with context awareness, allowing for better error handling during command execution. - Modified the TestExecWithTimeout to ensure it correctly verifies timeout behavior and measures execution duration, improving test reliability. - Added logic to create parent directories in WriteFile method, ensuring proper file handling within containers.
This commit is contained in:
parent
d4bed4f277
commit
55e43a7edd
2 changed files with 51 additions and 18 deletions
|
|
@ -319,21 +319,35 @@ func (m *Manager) Exec(ctx context.Context, name string, cmd []string, opts *Exe
|
|||
}
|
||||
defer reader.Close()
|
||||
|
||||
// Read all output
|
||||
output, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
// Read output with context awareness
|
||||
outputCh := make(chan []byte, 1)
|
||||
errCh := make(chan error, 1)
|
||||
|
||||
go func() {
|
||||
output, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
outputCh <- output
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case err := <-errCh:
|
||||
return nil, fmt.Errorf("failed to read output: %w", err)
|
||||
case output := <-outputCh:
|
||||
// Parse Docker multiplexed stream
|
||||
// TODO: Properly demux stdout/stderr from Docker stream
|
||||
stdout := string(output)
|
||||
|
||||
return &ExecResult{
|
||||
ExitCode: 0,
|
||||
Stdout: stdout,
|
||||
Stderr: "",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Parse Docker multiplexed stream
|
||||
// TODO: Properly demux stdout/stderr from Docker stream
|
||||
stdout := string(output)
|
||||
|
||||
return &ExecResult{
|
||||
ExitCode: 0,
|
||||
Stdout: stdout,
|
||||
Stderr: "",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Start starts a stopped container
|
||||
|
|
@ -454,6 +468,14 @@ func (m *Manager) WriteFile(ctx context.Context, name, path string, content []by
|
|||
}
|
||||
cont := c.(*Container)
|
||||
|
||||
// Ensure parent directory exists
|
||||
dir := filepath.Dir(path)
|
||||
if dir != "/" && dir != "." {
|
||||
if _, err := m.Exec(ctx, name, []string{"mkdir", "-p", dir}, nil); err != nil {
|
||||
return fmt.Errorf("failed to create parent directory: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a tar archive with the file
|
||||
var buf bytes.Buffer
|
||||
tw := tar.NewWriter(&buf)
|
||||
|
|
@ -474,7 +496,7 @@ func (m *Manager) WriteFile(ctx context.Context, name, path string, content []by
|
|||
}
|
||||
|
||||
// Copy to container
|
||||
return m.dockerClient.CopyToContainer(ctx, cont.ID, filepath.Dir(path), &buf, container.CopyToContainerOptions{})
|
||||
return m.dockerClient.CopyToContainer(ctx, cont.ID, dir, &buf, container.CopyToContainerOptions{})
|
||||
}
|
||||
|
||||
// ReadFile reads content from a file in container
|
||||
|
|
|
|||
|
|
@ -271,15 +271,26 @@ func TestExecWithTimeout(t *testing.T) {
|
|||
}
|
||||
defer m.Remove(ctx, container.Name)
|
||||
|
||||
// Execute command with very short timeout
|
||||
// Execute command with short timeout (sleep 10s but timeout after 500ms)
|
||||
start := time.Now()
|
||||
_, err = m.Exec(ctx, container.Name, []string{"sleep", "10"}, &ExecOptions{
|
||||
Timeout: 100 * time.Millisecond,
|
||||
Timeout: 500 * time.Millisecond,
|
||||
})
|
||||
elapsed := time.Since(start)
|
||||
|
||||
// Should timeout
|
||||
// Should timeout with context deadline exceeded
|
||||
if err == nil {
|
||||
t.Log("Expected timeout error, but command completed (may be fast system)")
|
||||
t.Error("Expected timeout error, but command completed without error")
|
||||
} else if err != context.DeadlineExceeded {
|
||||
t.Logf("Got error (expected context.DeadlineExceeded): %v", err)
|
||||
}
|
||||
|
||||
// Verify it didn't wait the full 10 seconds
|
||||
if elapsed > 5*time.Second {
|
||||
t.Errorf("Timeout took too long: %v (expected < 5s)", elapsed)
|
||||
}
|
||||
|
||||
t.Logf("Timeout completed in %v", elapsed)
|
||||
}
|
||||
|
||||
// TestFileOperations tests filesystem operations
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue