@@ -0,0 +1,83 @@
1+package shell
2+
3+import (
4+ "context"
5+ "os"
6+ "runtime"
7+ "testing"
8+ "time"
9+
10+ "github.com/stretchr/testify/assert"
11+ "github.com/stretchr/testify/require"
12+)
13+
14+func TestShellPerformanceComparison(t *testing.T) {
15+ tmpDir, err := os.MkdirTemp("", "shell-test")
16+ require.NoError(t, err)
17+ defer os.RemoveAll(tmpDir)
18+
19+ shell := GetPersistentShell(tmpDir)
20+ defer shell.Close()
21+
22+ // Test quick command
23+ start := time.Now()
24+ stdout, stderr, exitCode, _, err := shell.Exec(context.Background(), "echo 'hello'", 0)
25+ duration := time.Since(start)
26+
27+ require.NoError(t, err)
28+ assert.Equal(t, 0, exitCode)
29+ assert.Contains(t, stdout, "hello")
30+ assert.Empty(t, stderr)
31+
32+ t.Logf("Quick command took: %v", duration)
33+}
34+
35+func TestShellCPUUsageComparison(t *testing.T) {
36+ tmpDir, err := os.MkdirTemp("", "shell-test")
37+ require.NoError(t, err)
38+ defer os.RemoveAll(tmpDir)
39+
40+ shell := GetPersistentShell(tmpDir)
41+ defer shell.Close()
42+
43+ // Measure CPU and memory usage during a longer command
44+ var m1, m2 runtime.MemStats
45+ runtime.GC()
46+ runtime.ReadMemStats(&m1)
47+
48+ start := time.Now()
49+ _, stderr, exitCode, _, err := shell.Exec(context.Background(), "sleep 0.1", 1000)
50+ duration := time.Since(start)
51+
52+ runtime.ReadMemStats(&m2)
53+
54+ require.NoError(t, err)
55+ assert.Equal(t, 0, exitCode)
56+ assert.Empty(t, stderr)
57+
58+ memGrowth := m2.Alloc - m1.Alloc
59+ t.Logf("Sleep 0.1s command took: %v", duration)
60+ t.Logf("Memory growth during polling: %d bytes", memGrowth)
61+ t.Logf("GC cycles during test: %d", m2.NumGC-m1.NumGC)
62+}
63+
64+// Benchmark CPU usage during polling
65+func BenchmarkShellPolling(b *testing.B) {
66+ tmpDir, err := os.MkdirTemp("", "shell-bench")
67+ require.NoError(b, err)
68+ defer os.RemoveAll(tmpDir)
69+
70+ shell := GetPersistentShell(tmpDir)
71+ defer shell.Close()
72+
73+ b.ResetTimer()
74+ b.ReportAllocs()
75+
76+ for i := 0; i < b.N; i++ {
77+ // Use a short sleep to measure polling overhead
78+ _, _, exitCode, _, err := shell.Exec(context.Background(), "sleep 0.02", 500)
79+ if err != nil || exitCode != 0 {
80+ b.Fatalf("Command failed: %v, exit code: %d", err, exitCode)
81+ }
82+ }
83+}