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

Commit 9d358a6

Browse files
committed
Adds headless login workaround
1 parent f4fe567 commit 9d358a6

File tree

5 files changed

+131
-6
lines changed

5 files changed

+131
-6
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
ci/bin
33
cmd/coder/coder
44
ci/integration/bin
5+
ci/integration/env.sh

Diff for: ci/integration/integration_test.go

+36-3
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,12 @@ func TestHostRunner(t *testing.T) {
114114
}
115115

116116
func TestCoderCLI(t *testing.T) {
117-
ctx := context.Background()
117+
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5)
118+
defer cancel()
118119

119120
c, err := tcli.NewContainerRunner(ctx, &tcli.ContainerConfig{
120-
Image: "ubuntu:latest",
121-
Name: "test-container",
121+
Image: "codercom/enterprise-dev",
122+
Name: "coder-cli-tests",
122123
BindMounts: map[string]string{
123124
binpath: "/bin/coder",
124125
},
@@ -138,4 +139,36 @@ func TestCoderCLI(t *testing.T) {
138139
tcli.StderrMatches("Usage: coder"),
139140
tcli.StdoutEmpty(),
140141
)
142+
143+
creds := login(ctx, t)
144+
c.Run(ctx, fmt.Sprintf("mkdir -p ~/.config/coder && echo -ne %s > ~/.config/coder/session", creds.token)).Assert(t,
145+
tcli.Success(),
146+
)
147+
c.Run(ctx, fmt.Sprintf("echo -ne %s > ~/.config/coder/url", creds.url)).Assert(t,
148+
tcli.Success(),
149+
)
150+
151+
c.Run(ctx, "coder envs").Assert(t,
152+
tcli.Success(),
153+
)
154+
155+
c.Run(ctx, "coder urls").Assert(t,
156+
tcli.Error(),
157+
)
158+
159+
c.Run(ctx, "coder sync").Assert(t,
160+
tcli.Error(),
161+
)
162+
163+
c.Run(ctx, "coder sh").Assert(t,
164+
tcli.Error(),
165+
)
166+
167+
c.Run(ctx, "coder logout").Assert(t,
168+
tcli.Success(),
169+
)
170+
171+
c.Run(ctx, "coder envs").Assert(t,
172+
tcli.Error(),
173+
)
141174
}

Diff for: ci/integration/login_test.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package integration
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"encoding/json"
7+
"fmt"
8+
"net/http"
9+
"net/url"
10+
"os"
11+
"testing"
12+
13+
"cdr.dev/slog/sloggers/slogtest/assert"
14+
)
15+
16+
type credentials struct {
17+
url, token string
18+
}
19+
20+
func login(ctx context.Context, t *testing.T) credentials {
21+
var (
22+
email = requireEnv(t, "CODER_EMAIL")
23+
password = requireEnv(t, "CODER_PASSWORD")
24+
rawURL = requireEnv(t, "CODER_URL")
25+
)
26+
sessionToken := getSessionToken(ctx, t, email, password, rawURL)
27+
28+
return credentials{
29+
url: rawURL,
30+
token: sessionToken,
31+
}
32+
}
33+
34+
func requireEnv(t *testing.T, key string) string {
35+
value := os.Getenv(key)
36+
assert.True(t, fmt.Sprintf("%q is nonempty", key), value != "")
37+
return value
38+
}
39+
40+
type loginBuiltInAuthReq struct {
41+
Email string `json:"email"`
42+
Password string `json:"password"`
43+
}
44+
45+
type loginBuiltInAuthResp struct {
46+
SessionToken string `json:"session_token"`
47+
}
48+
49+
func getSessionToken(ctx context.Context, t *testing.T, email, password, rawURL string) string {
50+
reqbody := loginBuiltInAuthReq{
51+
Email: email,
52+
Password: password,
53+
}
54+
body, err := json.Marshal(reqbody)
55+
assert.Success(t, "marshal login req body", err)
56+
57+
u, err := url.Parse(rawURL)
58+
assert.Success(t, "parse raw url", err)
59+
u.Path = "/auth/basic/login"
60+
61+
req, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), bytes.NewReader(body))
62+
assert.Success(t, "new request", err)
63+
64+
resp, err := http.DefaultClient.Do(req)
65+
assert.Success(t, "do request", err)
66+
assert.Equal(t, "request status 201", http.StatusCreated, resp.StatusCode)
67+
68+
var tokenResp loginBuiltInAuthResp
69+
err = json.NewDecoder(resp.Body).Decode(&tokenResp)
70+
assert.Success(t, "decode response", err)
71+
72+
defer resp.Body.Close()
73+
74+
return tokenResp.SessionToken
75+
}

Diff for: ci/tcli/doc.go

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Package tcli provides a framework for CLI integration testing.
2+
// Execute commands on the raw host of inside docker container.
3+
// Define custom Assertion types to extend test functionality.
4+
package tcli

Diff for: ci/tcli/tcli.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ func (a Assertable) Assert(t *testing.T, option ...Assertion) {
203203
name = named.Name()
204204
}
205205
t.Run(name, func(t *testing.T) {
206-
t.Parallel()
207206
err := o.Valid(&cmdResult)
208207
assert.Success(t, name, err)
209208
})
@@ -248,12 +247,25 @@ func Success() Assertion {
248247
return ExitCodeIs(0)
249248
}
250249

250+
// Error asserts that the command exited with a nonzero exit code
251+
func Error() Assertion {
252+
return simpleFuncAssert{
253+
valid: func(r *CommandResult) error {
254+
if r.ExitCode == 0 {
255+
return xerrors.Errorf("expected nonzero exit code, got %v", r.ExitCode)
256+
}
257+
return nil
258+
},
259+
name: fmt.Sprintf("error"),
260+
}
261+
}
262+
251263
// ExitCodeIs asserts that the command exited with the given code
252264
func ExitCodeIs(code int) Assertion {
253265
return simpleFuncAssert{
254266
valid: func(r *CommandResult) error {
255267
if r.ExitCode != code {
256-
return xerrors.Errorf("exit code of %v expected, got %v", code, r.ExitCode)
268+
return xerrors.Errorf("exit code of %v expected, got %v, (%s)", code, r.ExitCode, string(r.Stderr))
257269
}
258270
return nil
259271
},
@@ -279,7 +291,7 @@ func GetResult(result **CommandResult) Assertion {
279291
*result = r
280292
return nil
281293
},
282-
name: "get-stdout",
294+
name: "get-result",
283295
}
284296
}
285297

0 commit comments

Comments
 (0)