Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ jobs:
- uses: actions/setup-go@v2
with:
go-version: '^1.14'
- name: go test
run: go test -v ./ci/integration/...
- name: integration tests
run: ./ci/steps/integration.sh
3 changes: 3 additions & 0 deletions ci/integration/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM ubuntu:20.04

RUN apt-get update && apt-get install -y jq curl
1 change: 0 additions & 1 deletion ci/integration/devurls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ func TestDevURLCLI(t *testing.T) {
run(t, "coder-cli-devurl-tests", func(t *testing.T, ctx context.Context, c *tcli.ContainerRunner) {
c.Run(ctx, "which coder").Assert(t,
tcli.Success(),
tcli.StdoutMatches("/usr/sbin/coder"),
tcli.StderrEmpty(),
)

Expand Down
122 changes: 97 additions & 25 deletions ci/integration/envs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,46 @@ package integration

import (
"context"
"fmt"
"math"
"net/url"
"regexp"
"testing"
"time"

"cdr.dev/coder-cli/ci/tcli"
"cdr.dev/coder-cli/coder-sdk"
"cdr.dev/slog"
"cdr.dev/slog/sloggers/slogtest"
"cdr.dev/slog/sloggers/slogtest/assert"
"github.com/google/go-cmp/cmp"
)

// From Coder organization images
// const ubuntuImgID = "5f443b16-30652892427b955601330fa5"
func cleanupClient(t *testing.T, ctx context.Context) *coder.Client {
creds := login(ctx, t)

u, err := url.Parse(creds.url)
assert.Success(t, "parse base url", err)

return &coder.Client{BaseURL: u, Token: creds.token}
}

func cleanupEnv(t *testing.T, client *coder.Client, envID string) func() {
return func() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

slogtest.Info(t, "cleanuping up environment", slog.F("env_id", envID))
_ = client.DeleteEnvironment(ctx, envID)
}
}

func TestEnvsCLI(t *testing.T) {
t.Parallel()

run(t, "coder-cli-env-tests", func(t *testing.T, ctx context.Context, c *tcli.ContainerRunner) {
headlessLogin(ctx, t, c)

// Ensure binary is present.
c.Run(ctx, "which coder").Assert(t,
tcli.Success(),
tcli.StdoutMatches("/usr/sbin/coder"),
tcli.StderrEmpty(),
)
client := cleanupClient(t, ctx)

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

// TODO(Faris) : uncomment this when we can safely purge the environments
// the integrations tests would create in the sidecar
// Successfully create environment.
// c.Run(ctx, "coder envs create --image "+ubuntuImgID+" test-ubuntu").Assert(t,
// tcli.Success(),
// // why does flog.Success write to stderr?
// tcli.StderrMatches(regexp.QuoteMeta("Successfully created environment \"test-ubuntu\"")),
// )

// TODO(Faris) : uncomment this when we can safely purge the environments
// the integrations tests would create in the sidecar
// Successfully provision environment with fractional resource amounts
// c.Run(ctx, fmt.Sprintf(`coder envs create -i %s -c 1.2 -m 1.4 non-whole-resource-amounts`, ubuntuImgID)).Assert(t,
// tcli.Success(),
// tcli.StderrMatches(regexp.QuoteMeta("Successfully created environment \"non-whole-resource-amounts\"")),
// )
name := randString(10)
cpu := 2.3
c.Run(ctx, fmt.Sprintf("coder envs create %s --image ubuntu --cpu %f", name, cpu)).Assert(t,
tcli.Success(),
)

c.Run(ctx, "coder envs ls").Assert(t,
tcli.Success(),
tcli.StdoutMatches(regexp.QuoteMeta(name)),
)

var env coder.Environment
c.Run(ctx, fmt.Sprintf(`coder envs ls -o json | jq '.[] | select(.name == "%s")'`, name)).Assert(t,
tcli.Success(),
tcli.StdoutJSONUnmarshal(&env),
)

// attempt to cleanup the environment even if tests fail
t.Cleanup(cleanupEnv(t, client, env.ID))

assert.Equal(t, "environment cpu was correctly set", cpu, float64(env.CPUCores), floatComparer)

c.Run(ctx, fmt.Sprintf("coder envs watch-build %s", name)).Assert(t,
tcli.Success(),
)

c.Run(ctx, fmt.Sprintf("coder envs rm %s --force", name)).Assert(t,
tcli.Success(),
)
})

run(t, "coder-cli-env-edit-tests", func(t *testing.T, ctx context.Context, c *tcli.ContainerRunner) {
headlessLogin(ctx, t, c)
client := cleanupClient(t, ctx)

name := randString(10)
c.Run(ctx, fmt.Sprintf("coder envs create %s --image ubuntu --follow", name)).Assert(t,
tcli.Success(),
)

var env coder.Environment
c.Run(ctx, fmt.Sprintf(`coder envs ls -o json | jq '.[] | select(.name == "%s")'`, name)).Assert(t,
tcli.Success(),
tcli.StdoutJSONUnmarshal(&env),
)

// attempt to cleanup the environment even if tests fail
t.Cleanup(cleanupEnv(t, client, env.ID))

cpu := 2.1
c.Run(ctx, fmt.Sprintf(`coder envs edit %s --cpu %f --follow`, name, cpu)).Assert(t,
tcli.Success(),
)

c.Run(ctx, fmt.Sprintf(`coder envs ls -o json | jq '.[] | select(.name == "%s")'`, name)).Assert(t,
tcli.Success(),
tcli.StdoutJSONUnmarshal(&env),
)
assert.Equal(t, "cpu cores were updated", cpu, float64(env.CPUCores), floatComparer)

c.Run(ctx, fmt.Sprintf("coder envs rm %s --force", name)).Assert(t,
tcli.Success(),
)
})
}

var floatComparer = cmp.Comparer(func(x, y float64) bool {
delta := math.Abs(x - y)
mean := math.Abs(x+y) / 2.0
return delta/mean < 0.001
})
5 changes: 2 additions & 3 deletions ci/integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func run(t *testing.T, container string, execute func(t *testing.T, ctx context.
defer cancel()

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

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

func randString(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const charset = "abcdefghijklmnopqrstuvwxyz"
b := make([]byte, length)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
Expand Down
7 changes: 5 additions & 2 deletions ci/integration/setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,17 @@ func build(path string) error {
// write session tokens to the given container runner
func headlessLogin(ctx context.Context, t *testing.T, runner *tcli.ContainerRunner) {
creds := login(ctx, t)
cmd := exec.CommandContext(ctx, "sh", "-c", "mkdir -p ~/.config/coder && cat > ~/.config/coder/session")
cmd := exec.CommandContext(ctx, "sh", "-c", "mkdir -p $HOME/.config/coder && cat > $HOME/.config/coder/session")

// !IMPORTANT: be careful that this does not appear in logs
cmd.Stdin = strings.NewReader(creds.token)
runner.RunCmd(cmd).Assert(t,
tcli.Success(),
)
runner.Run(ctx, fmt.Sprintf("echo -ne %s > ~/.config/coder/url", creds.url)).Assert(t,

cmd = exec.CommandContext(ctx, "sh", "-c", "cat > $HOME/.config/coder/url")
cmd.Stdin = strings.NewReader(creds.url)
runner.RunCmd(cmd).Assert(t,
tcli.Success(),
)
}
1 change: 0 additions & 1 deletion ci/integration/users_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ func TestUsers(t *testing.T) {
run(t, "users-cli-tests", func(t *testing.T, ctx context.Context, c *tcli.ContainerRunner) {
c.Run(ctx, "which coder").Assert(t,
tcli.Success(),
tcli.StdoutMatches("/usr/sbin/coder"),
tcli.StderrEmpty(),
)

Expand Down
15 changes: 15 additions & 0 deletions ci/steps/integration.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

set -eo pipefail

log() {
echo "--- $@"
}

cd "$(git rev-parse --show-toplevel)"

log "building integration test image"
docker build -f ./ci/integration/Dockerfile -t coder-cli-integration:latest .

log "starting integration tests"
go test ./ci/integration -count=1
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
cdr.dev/wsep v0.0.0-20200728013649-82316a09813f
github.com/briandowns/spinner v1.11.1
github.com/fatih/color v1.9.0
github.com/google/go-cmp v0.4.0
github.com/gorilla/websocket v1.4.2
github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f
github.com/klauspost/compress v1.10.8 // indirect
Expand Down
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