...
1 package memexec
2
3 import (
4 "bytes"
5 "context"
6 "os"
7 "os/exec"
8 "runtime"
9 "strings"
10 "testing"
11 "time"
12 )
13
14 func TestCommand(t *testing.T) {
15 exe := newEchoExec(t)
16 defer func() {
17 if err := exe.Close(); err != nil {
18 t.Fatalf("close error: %s", err)
19 }
20 }()
21
22 c := exe.Command("test")
23 if have := runCommand(t, c); !strings.HasPrefix(have, "test") {
24 t.Errorf("command output = %q doesn't contain %q", have, "test")
25 }
26 }
27
28 func TestCommand_Shell(t *testing.T) {
29 if runtime.GOOS == "windows" {
30 return
31 }
32
33 exe, err := New([]byte("#!/bin/sh\necho hello"))
34 if err != nil {
35 panic(err)
36 }
37 defer exe.Close()
38
39 b, err := exe.Command().CombinedOutput()
40 if err != nil {
41 t.Fatalf("err = %v, output = %q", err, b)
42 }
43 if !bytes.Equal(b, []byte("hello\n")) {
44 t.Fatalf("output = %q, want %q", string(b), []byte("hello\n"))
45 }
46 }
47
48 func TestCommandContext(t *testing.T) {
49
50
51 if runtime.GOOS == "windows" {
52 return
53 }
54
55 exe := newSleepExec(t)
56 defer func() {
57 if err := exe.Close(); err != nil {
58 t.Fatalf("close error: %s", err)
59 }
60 }()
61
62 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*500)
63 defer cancel()
64
65 c := exe.CommandContext(ctx, "1")
66
67 start := time.Now()
68 if err := c.Start(); err != nil {
69 t.Fatalf("start failed: %s", err)
70 }
71 if err := c.Wait(); err != nil && err.Error() != "signal: killed" {
72 t.Fatalf("command execution failed: %s", err)
73 }
74 stop := time.Now()
75 if delta := stop.Sub(start); delta > time.Millisecond*600 || delta < time.Millisecond*500 {
76 t.Fatalf("unexpected command execution time: delta=%s", delta)
77 }
78 }
79
80 func BenchmarkCommand(b *testing.B) {
81 exe := newEchoExec(b)
82 defer func() {
83 if err := exe.Close(); err != nil {
84 b.Fatalf("close error: %s", err)
85 }
86 }()
87
88 for i := 0; i < b.N; i++ {
89 cmd := exe.Command("test")
90 if _, err := cmd.Output(); err != nil {
91 b.Fatal(err)
92 }
93 }
94 }
95
96 func newExec(t testing.TB, name string) *Exec {
97 path, err := exec.LookPath(name)
98 if err != nil {
99 t.Fatal(err)
100 }
101 b, err := os.ReadFile(path)
102 if err != nil {
103 t.Fatal(err)
104 }
105
106 exe, err := New(b)
107 if err != nil {
108 t.Fatal(err)
109 }
110 return exe
111 }
112
113 func newEchoExec(t testing.TB) *Exec {
114
115
116 return newExec(t, "echo")
117 }
118
119 func newSleepExec(t testing.TB) *Exec {
120 return newExec(t, "sleep")
121 }
122
123 func runCommand(t *testing.T, cmd *exec.Cmd) string {
124 t.Helper()
125 b, err := cmd.CombinedOutput()
126 if err != nil {
127 if b != nil {
128 t.Fatalf("failed to run: %q", string(b))
129 }
130 t.Fatal(err)
131 }
132 return string(b)
133 }
134
View as plain text