Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Commit 11cd031

Browse files
authored
Add basic env create|edit integration tests (#160)
1 parent a171882 commit 11cd031

File tree

9 files changed

+125
-34
lines changed

9 files changed

+125
-34
lines changed

.github/workflows/integration.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ jobs:
2222
- uses: actions/setup-go@v2
2323
with:
2424
go-version: '^1.14'
25-
- name: go test
26-
run: go test -v ./ci/integration/...
25+
- name: integration tests
26+
run: ./ci/steps/integration.sh

ci/integration/Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM ubuntu:20.04
2+
3+
RUN apt-get update && apt-get install -y jq curl

ci/integration/devurls_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ func TestDevURLCLI(t *testing.T) {
1212
run(t, "coder-cli-devurl-tests", func(t *testing.T, ctx context.Context, c *tcli.ContainerRunner) {
1313
c.Run(ctx, "which coder").Assert(t,
1414
tcli.Success(),
15-
tcli.StdoutMatches("/usr/sbin/coder"),
1615
tcli.StderrEmpty(),
1716
)
1817

ci/integration/envs_test.go

Lines changed: 97 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,46 @@ package integration
22

33
import (
44
"context"
5+
"fmt"
6+
"math"
7+
"net/url"
58
"regexp"
69
"testing"
10+
"time"
711

812
"cdr.dev/coder-cli/ci/tcli"
13+
"cdr.dev/coder-cli/coder-sdk"
14+
"cdr.dev/slog"
15+
"cdr.dev/slog/sloggers/slogtest"
16+
"cdr.dev/slog/sloggers/slogtest/assert"
17+
"github.com/google/go-cmp/cmp"
918
)
1019

11-
// From Coder organization images
12-
// const ubuntuImgID = "5f443b16-30652892427b955601330fa5"
20+
func cleanupClient(t *testing.T, ctx context.Context) *coder.Client {
21+
creds := login(ctx, t)
22+
23+
u, err := url.Parse(creds.url)
24+
assert.Success(t, "parse base url", err)
25+
26+
return &coder.Client{BaseURL: u, Token: creds.token}
27+
}
28+
29+
func cleanupEnv(t *testing.T, client *coder.Client, envID string) func() {
30+
return func() {
31+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
32+
defer cancel()
33+
34+
slogtest.Info(t, "cleanuping up environment", slog.F("env_id", envID))
35+
_ = client.DeleteEnvironment(ctx, envID)
36+
}
37+
}
1338

1439
func TestEnvsCLI(t *testing.T) {
1540
t.Parallel()
1641

1742
run(t, "coder-cli-env-tests", func(t *testing.T, ctx context.Context, c *tcli.ContainerRunner) {
1843
headlessLogin(ctx, t, c)
19-
20-
// Ensure binary is present.
21-
c.Run(ctx, "which coder").Assert(t,
22-
tcli.Success(),
23-
tcli.StdoutMatches("/usr/sbin/coder"),
24-
tcli.StderrEmpty(),
25-
)
44+
client := cleanupClient(t, ctx)
2645

2746
// Minimum args not received.
2847
c.Run(ctx, "coder envs create").Assert(t,
@@ -49,21 +68,74 @@ func TestEnvsCLI(t *testing.T) {
4968
tcli.Error(),
5069
)
5170

52-
// TODO(Faris) : uncomment this when we can safely purge the environments
53-
// the integrations tests would create in the sidecar
54-
// Successfully create environment.
55-
// c.Run(ctx, "coder envs create --image "+ubuntuImgID+" test-ubuntu").Assert(t,
56-
// tcli.Success(),
57-
// // why does flog.Success write to stderr?
58-
// tcli.StderrMatches(regexp.QuoteMeta("Successfully created environment \"test-ubuntu\"")),
59-
// )
60-
61-
// TODO(Faris) : uncomment this when we can safely purge the environments
62-
// the integrations tests would create in the sidecar
63-
// Successfully provision environment with fractional resource amounts
64-
// c.Run(ctx, fmt.Sprintf(`coder envs create -i %s -c 1.2 -m 1.4 non-whole-resource-amounts`, ubuntuImgID)).Assert(t,
65-
// tcli.Success(),
66-
// tcli.StderrMatches(regexp.QuoteMeta("Successfully created environment \"non-whole-resource-amounts\"")),
67-
// )
71+
name := randString(10)
72+
cpu := 2.3
73+
c.Run(ctx, fmt.Sprintf("coder envs create %s --image ubuntu --cpu %f", name, cpu)).Assert(t,
74+
tcli.Success(),
75+
)
76+
77+
c.Run(ctx, "coder envs ls").Assert(t,
78+
tcli.Success(),
79+
tcli.StdoutMatches(regexp.QuoteMeta(name)),
80+
)
81+
82+
var env coder.Environment
83+
c.Run(ctx, fmt.Sprintf(`coder envs ls -o json | jq '.[] | select(.name == "%s")'`, name)).Assert(t,
84+
tcli.Success(),
85+
tcli.StdoutJSONUnmarshal(&env),
86+
)
87+
88+
// attempt to cleanup the environment even if tests fail
89+
t.Cleanup(cleanupEnv(t, client, env.ID))
90+
91+
assert.Equal(t, "environment cpu was correctly set", cpu, float64(env.CPUCores), floatComparer)
92+
93+
c.Run(ctx, fmt.Sprintf("coder envs watch-build %s", name)).Assert(t,
94+
tcli.Success(),
95+
)
96+
97+
c.Run(ctx, fmt.Sprintf("coder envs rm %s --force", name)).Assert(t,
98+
tcli.Success(),
99+
)
100+
})
101+
102+
run(t, "coder-cli-env-edit-tests", func(t *testing.T, ctx context.Context, c *tcli.ContainerRunner) {
103+
headlessLogin(ctx, t, c)
104+
client := cleanupClient(t, ctx)
105+
106+
name := randString(10)
107+
c.Run(ctx, fmt.Sprintf("coder envs create %s --image ubuntu --follow", name)).Assert(t,
108+
tcli.Success(),
109+
)
110+
111+
var env coder.Environment
112+
c.Run(ctx, fmt.Sprintf(`coder envs ls -o json | jq '.[] | select(.name == "%s")'`, name)).Assert(t,
113+
tcli.Success(),
114+
tcli.StdoutJSONUnmarshal(&env),
115+
)
116+
117+
// attempt to cleanup the environment even if tests fail
118+
t.Cleanup(cleanupEnv(t, client, env.ID))
119+
120+
cpu := 2.1
121+
c.Run(ctx, fmt.Sprintf(`coder envs edit %s --cpu %f --follow`, name, cpu)).Assert(t,
122+
tcli.Success(),
123+
)
124+
125+
c.Run(ctx, fmt.Sprintf(`coder envs ls -o json | jq '.[] | select(.name == "%s")'`, name)).Assert(t,
126+
tcli.Success(),
127+
tcli.StdoutJSONUnmarshal(&env),
128+
)
129+
assert.Equal(t, "cpu cores were updated", cpu, float64(env.CPUCores), floatComparer)
130+
131+
c.Run(ctx, fmt.Sprintf("coder envs rm %s --force", name)).Assert(t,
132+
tcli.Success(),
133+
)
68134
})
69135
}
136+
137+
var floatComparer = cmp.Comparer(func(x, y float64) bool {
138+
delta := math.Abs(x - y)
139+
mean := math.Abs(x+y) / 2.0
140+
return delta/mean < 0.001
141+
})

ci/integration/integration_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func run(t *testing.T, container string, execute func(t *testing.T, ctx context.
1818
defer cancel()
1919

2020
c, err := tcli.NewContainerRunner(ctx, &tcli.ContainerConfig{
21-
Image: "codercom/enterprise-dev",
21+
Image: "coder-cli-integration:latest",
2222
Name: container,
2323
BindMounts: map[string]string{
2424
binpath: "/bin/coder",
@@ -36,7 +36,6 @@ func TestCoderCLI(t *testing.T) {
3636
run(t, "test-coder-cli", func(t *testing.T, ctx context.Context, c *tcli.ContainerRunner) {
3737
c.Run(ctx, "which coder").Assert(t,
3838
tcli.Success(),
39-
tcli.StdoutMatches("/usr/sbin/coder"),
4039
tcli.StderrEmpty(),
4140
)
4241

@@ -87,7 +86,7 @@ func TestCoderCLI(t *testing.T) {
8786
var seededRand = rand.New(rand.NewSource(time.Now().UnixNano()))
8887

8988
func randString(length int) string {
90-
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
89+
const charset = "abcdefghijklmnopqrstuvwxyz"
9190
b := make([]byte, length)
9291
for i := range b {
9392
b[i] = charset[seededRand.Intn(len(charset))]

ci/integration/setup_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,17 @@ func build(path string) error {
5151
// write session tokens to the given container runner
5252
func headlessLogin(ctx context.Context, t *testing.T, runner *tcli.ContainerRunner) {
5353
creds := login(ctx, t)
54-
cmd := exec.CommandContext(ctx, "sh", "-c", "mkdir -p ~/.config/coder && cat > ~/.config/coder/session")
54+
cmd := exec.CommandContext(ctx, "sh", "-c", "mkdir -p $HOME/.config/coder && cat > $HOME/.config/coder/session")
5555

5656
// !IMPORTANT: be careful that this does not appear in logs
5757
cmd.Stdin = strings.NewReader(creds.token)
5858
runner.RunCmd(cmd).Assert(t,
5959
tcli.Success(),
6060
)
61-
runner.Run(ctx, fmt.Sprintf("echo -ne %s > ~/.config/coder/url", creds.url)).Assert(t,
61+
62+
cmd = exec.CommandContext(ctx, "sh", "-c", "cat > $HOME/.config/coder/url")
63+
cmd.Stdin = strings.NewReader(creds.url)
64+
runner.RunCmd(cmd).Assert(t,
6265
tcli.Success(),
6366
)
6467
}

ci/integration/users_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ func TestUsers(t *testing.T) {
1414
run(t, "users-cli-tests", func(t *testing.T, ctx context.Context, c *tcli.ContainerRunner) {
1515
c.Run(ctx, "which coder").Assert(t,
1616
tcli.Success(),
17-
tcli.StdoutMatches("/usr/sbin/coder"),
1817
tcli.StderrEmpty(),
1918
)
2019

ci/steps/integration.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
3+
set -eo pipefail
4+
5+
log() {
6+
echo "--- $@"
7+
}
8+
9+
cd "$(git rev-parse --show-toplevel)"
10+
11+
log "building integration test image"
12+
docker build -f ./ci/integration/Dockerfile -t coder-cli-integration:latest .
13+
14+
log "starting integration tests"
15+
go test ./ci/integration -count=1

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ require (
77
cdr.dev/wsep v0.0.0-20200728013649-82316a09813f
88
github.com/briandowns/spinner v1.11.1
99
github.com/fatih/color v1.9.0
10+
github.com/google/go-cmp v0.4.0
1011
github.com/gorilla/websocket v1.4.2
1112
github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f
1213
github.com/klauspost/compress v1.10.8 // indirect

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy