Skip to content

Commit 00c9cd7

Browse files
committed
add basic test
1 parent 538c6c3 commit 00c9cd7

File tree

4 files changed

+119
-4
lines changed

4 files changed

+119
-4
lines changed

agent/agentexec/cli.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package agentexec
22

33
import (
4-
"context"
54
"fmt"
65
"os"
76
"os/exec"
@@ -20,7 +19,7 @@ const (
2019
)
2120

2221
// CLI runs the agent-exec command. It should only be called by the cli package.
23-
func CLI(ctx context.Context, args []string, environ []string) error {
22+
func CLI(args []string, environ []string) error {
2423
if runtime.GOOS != "linux" {
2524
return xerrors.Errorf("agent-exec is only supported on Linux")
2625
}

agent/agentexec/cli_test.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package agentexec_test
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"fmt"
7+
"os"
8+
"os/exec"
9+
"strconv"
10+
"strings"
11+
"syscall"
12+
"testing"
13+
14+
"github.com/stretchr/testify/require"
15+
"golang.org/x/sys/unix"
16+
17+
"github.com/coder/coder/v2/testutil"
18+
)
19+
20+
func TestCLI(t *testing.T) {
21+
t.Parallel()
22+
t.Run("OK", func(t *testing.T) {
23+
t.Parallel()
24+
25+
ctx := testutil.Context(t, testutil.WaitMedium)
26+
cmd, dir := cmd(t, ctx)
27+
cmd.Env = append(cmd.Env, "CODER_PROC_NICE_SCORE=10")
28+
cmd.Env = append(cmd.Env, "CODER_PROC_OOM_SCORE=123")
29+
err := cmd.Start()
30+
require.NoError(t, err)
31+
32+
waitForSentinel(t, ctx, cmd, dir)
33+
requireOOMScore(t, cmd.Process.Pid, 123)
34+
requireNiceScore(t, cmd.Process.Pid, 10)
35+
})
36+
}
37+
38+
func requireNiceScore(t *testing.T, pid int, score int) {
39+
t.Helper()
40+
41+
nice, err := unix.Getpriority(0, pid)
42+
require.NoError(t, err)
43+
require.Equal(t, score, nice)
44+
}
45+
46+
func requireOOMScore(t *testing.T, pid int, expected int) {
47+
t.Helper()
48+
49+
actual, err := os.ReadFile(fmt.Sprintf("/proc/%d/oom_score_adj", pid))
50+
require.NoError(t, err)
51+
score := strings.TrimSpace(string(actual))
52+
require.Equal(t, strconv.Itoa(expected), score)
53+
}
54+
55+
func waitForSentinel(t *testing.T, ctx context.Context, cmd *exec.Cmd, dir string) {
56+
t.Helper()
57+
58+
require.Eventually(t, func() bool {
59+
// Check if the process is still running.
60+
err := cmd.Process.Signal(syscall.Signal(0))
61+
require.NoError(t, err)
62+
63+
_, err = os.Stat(dir)
64+
return err == nil && ctx.Err() == nil
65+
}, testutil.WaitLong, testutil.IntervalFast)
66+
}
67+
68+
func cmd(t *testing.T, ctx context.Context, args ...string) (*exec.Cmd, string) {
69+
dir := ""
70+
cmd := exec.Command(TestBin, args...)
71+
if len(args) == 0 {
72+
dir = t.TempDir()
73+
//nolint:gosec
74+
cmd = exec.CommandContext(ctx, TestBin, "sh", "-c", fmt.Sprintf("touch %s && sleep 10m", dir))
75+
}
76+
var buf bytes.Buffer
77+
cmd.Stdout = &buf
78+
cmd.Stderr = &buf
79+
t.Cleanup(func() {
80+
// Print output of a command if the test fails.
81+
if t.Failed() {
82+
t.Logf("cmd %q output: %s", cmd.Args, buf.String())
83+
}
84+
85+
if cmd.Process != nil {
86+
_ = cmd.Process.Kill()
87+
}
88+
})
89+
return cmd, dir
90+
}

agent/agentexec/cmdtest/main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
package main
22

33
import (
4-
"context"
54
"fmt"
65
"os"
76

87
"github.com/coder/coder/v2/agent/agentexec"
98
)
109

1110
func main() {
12-
err := agentexec.CLI(context.Background(), os.Args, os.Environ())
11+
err := agentexec.CLI(os.Args, os.Environ())
1312
if err != nil {
1413
_, _ = fmt.Fprintln(os.Stderr, err)
1514
os.Exit(1)

agent/agentexec/main_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package agentexec_test
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"os/exec"
7+
"testing"
8+
)
9+
10+
const TestBin = "/tmp/agent-test"
11+
12+
func TestMain(m *testing.M) {
13+
buildBinary()
14+
15+
os.Exit(m.Run())
16+
}
17+
18+
func buildBinary() {
19+
out, err := exec.Command("go", "build", "-o", TestBin, "./cmdtest").CombinedOutput()
20+
mustf(err, "build binary: %s", out)
21+
}
22+
23+
func mustf(err error, msg string, args ...any) {
24+
if err != nil {
25+
panic(fmt.Sprintf(msg, args...))
26+
}
27+
}

0 commit comments

Comments
 (0)