Skip to content
This repository was archived by the owner on Apr 28, 2020. It is now read-only.

Commit bc0801f

Browse files
author
Nathan Potter
authored
Merge pull request #37 from codercom/tests
Tests
2 parents 9a5464d + adfe2e5 commit bc0801f

File tree

8 files changed

+491
-13
lines changed

8 files changed

+491
-13
lines changed

codeserver.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"net/http"
77
"os"
88
"path/filepath"
9-
"strings"
109
"time"
1110

1211
"go.coder.com/flog"
@@ -19,17 +18,21 @@ import (
1918
func loadCodeServer(ctx context.Context) (string, error) {
2019
start := time.Now()
2120

21+
const cachePath = "/tmp/sail-code-server-cache/code-server"
22+
23+
// Only check for a new codeserver if it's over an hour old.
24+
info, err := os.Stat(cachePath)
25+
if err == nil {
26+
if info.ModTime().Add(time.Hour).After(time.Now()) {
27+
return cachePath, nil
28+
}
29+
}
30+
2231
u, err := codeserver.DownloadURL(ctx)
2332
if err != nil {
2433
return "", err
2534
}
2635

27-
cachePath := filepath.Join(
28-
"/tmp/sail-code-server-cache",
29-
u[strings.LastIndex(u, "/"):],
30-
"code-server",
31-
)
32-
3336
err = os.MkdirAll(filepath.Dir(cachePath), 0750)
3437
if err != nil {
3538
return "", err

globalflags.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ func requireRepo(fl *flag.FlagSet) repo {
5353
// project reads the project as the first parameter.
5454
func (gf *globalFlags) project(fl *flag.FlagSet) *project {
5555
return &project{
56-
gf: gf,
5756
conf: gf.config(),
5857
repo: requireRepo(fl),
5958
}

hat_builder_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func Test_hatBuilder(t *testing.T) {
10+
t.Parallel()
11+
12+
var tests = []struct {
13+
name string
14+
baseImage string
15+
hatPath string
16+
expectErr bool
17+
}{
18+
{
19+
"BaseImageNotExist",
20+
"codercom/do-not-exist:my-tag",
21+
"./hat-examples/fish",
22+
true,
23+
},
24+
{
25+
"HatNotExist",
26+
"codercom/ubuntu-dev",
27+
"./hat-examples/no-hat",
28+
true,
29+
},
30+
{
31+
"GithubHatNotExist",
32+
"codercom/ubuntu-dev",
33+
"github:codercom/no-hat",
34+
true,
35+
},
36+
{
37+
"OK",
38+
"codercom/ubuntu-dev",
39+
"./hat-examples/fish",
40+
false,
41+
},
42+
}
43+
44+
for _, test := range tests {
45+
test := test
46+
t.Run(test.name, func(t *testing.T) {
47+
t.Parallel()
48+
bldr := &hatBuilder{
49+
baseImage: test.baseImage,
50+
hatPath: test.hatPath,
51+
}
52+
53+
image, err := bldr.applyHat()
54+
if test.expectErr {
55+
require.Error(t, err)
56+
return
57+
}
58+
59+
require.NoError(t, err)
60+
61+
t.Run("ImageLabels", func(t *testing.T) {
62+
labels := requireGetImageLabels(t, image)
63+
64+
assertLabel(t, labels, hatLabel, test.hatPath)
65+
assertLabel(t, labels, baseImageLabel, test.baseImage)
66+
})
67+
68+
t.Run("RemoveImage", func(t *testing.T) {
69+
requireImageRemove(t, image)
70+
})
71+
})
72+
}
73+
}

project.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ const (
2929

3030
// project represents a sail project.
3131
type project struct {
32-
gf *globalFlags
3332
conf config
3433
repo repo
3534
}
@@ -61,9 +60,9 @@ func clone(repo repo, dir string) error {
6160
cmd := xexec.Fmt("git clone %v %v", uri, dir)
6261
xexec.Attach(cmd)
6362

64-
out, err := cmd.CombinedOutput()
63+
err := cmd.Run()
6564
if err != nil {
66-
xerrors.Errorf("failed to clone '%s' to '%s': %s, %w", uri, dir, out, err)
65+
return xerrors.Errorf("failed to clone '%s' to '%s': %w", uri, dir, err)
6766
}
6867
return nil
6968
}
@@ -145,7 +144,6 @@ func (p *project) buildImage() (string, bool, error) {
145144
if err != nil {
146145
return "", false, xerrors.Errorf("failed to pull default image %v: %w", p.conf.DefaultImage, err)
147146
}
148-
149147
return "", false, nil
150148
}
151149

project_test.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package main
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func Test_project(t *testing.T) {
13+
t.Parallel()
14+
15+
homeDir, err := os.UserHomeDir()
16+
require.NoError(t, err)
17+
18+
conf := mustReadConfig(filepath.Join(metaRoot(), ".sail.toml"))
19+
20+
var tests = []struct {
21+
name string
22+
repo string
23+
expCntName string
24+
expEnsureDirErr bool
25+
expCustomBldImg bool
26+
}{
27+
{
28+
"OK",
29+
"codercom/bigdur",
30+
"codercom_bigdur",
31+
false,
32+
true,
33+
},
34+
{
35+
"RepoNotExist",
36+
"codercom/do-not-exist",
37+
"codercom_do-not-exist",
38+
true,
39+
false,
40+
},
41+
}
42+
43+
for _, test := range tests {
44+
test := test
45+
t.Run(test.name, func(t *testing.T) {
46+
t.Parallel()
47+
48+
rb := newRollback()
49+
defer rb.run()
50+
51+
repo, err := ParseRepo(test.repo)
52+
require.NoError(t, err)
53+
54+
p := &project{
55+
conf: conf,
56+
repo: repo,
57+
}
58+
59+
name := p.cntName()
60+
require.Equal(t, test.expCntName, name)
61+
62+
expLocalDir := filepath.Join(homeDir, "Projects", test.repo)
63+
64+
require.Equal(t, expLocalDir, p.localDir())
65+
require.Equal(t,
66+
filepath.Join(expLocalDir, ".sail", "Dockerfile"),
67+
p.dockerfilePath(),
68+
)
69+
70+
t.Run("EnsureDir", func(t *testing.T) {
71+
err = p.ensureDir()
72+
if test.expEnsureDirErr {
73+
require.Error(t, err)
74+
return
75+
}
76+
77+
require.NoError(t, err)
78+
rb.add(func() {
79+
err := os.RemoveAll(p.localDir())
80+
require.NoError(t, err)
81+
})
82+
})
83+
84+
t.Run("BuildImage", func(t *testing.T) {
85+
image, isCustom, err := p.buildImage()
86+
require.NoError(t, err)
87+
if !test.expCustomBldImg {
88+
assert.False(t, isCustom)
89+
assert.Empty(t, image)
90+
return
91+
}
92+
93+
assert.True(t, isCustom)
94+
95+
labels := requireGetImageLabels(t, image)
96+
assertLabel(t, labels, baseImageLabel, p.repo.DockerName())
97+
98+
rb.add(func() {
99+
requireImageRemove(t, p.repo.DockerName())
100+
})
101+
})
102+
})
103+
}
104+
}

runner_test.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func Test_runner(t *testing.T) {
11+
requireNoRunningSailContainers(t)
12+
13+
// labelChecker asserts that all of the correct labels
14+
// are present on the image and container.
15+
labelChecker := func(t *testing.T, p *params) {
16+
t.Run("Labels", func(t *testing.T) {
17+
insp := requireContainerInspect(t, p.proj.cntName())
18+
19+
imgLabels := requireGetImageLabels(t, insp.Image)
20+
21+
assertLabel(t, imgLabels, baseImageLabel, p.bldr.baseImage)
22+
if p.bldr.hatPath != "" {
23+
assertLabel(t, imgLabels, hatLabel, p.bldr.hatPath)
24+
}
25+
26+
labels := insp.Config.Labels
27+
require.NotNil(t, labels)
28+
29+
assertLabel(t, labels, baseImageLabel, p.bldr.baseImage)
30+
if p.bldr.hatPath != "" {
31+
assertLabel(t, labels, hatLabel, p.bldr.hatPath)
32+
}
33+
assertLabel(t, labels, projectLocalDirLabel, p.proj.localDir())
34+
35+
cntDir, err := p.proj.containerDir()
36+
require.NoError(t, err)
37+
assertLabel(t, labels, projectDirLabel, cntDir)
38+
assertLabel(t, labels, projectNameLabel, p.proj.repo.BaseName())
39+
})
40+
}
41+
42+
// loadFromContainer ensures that our state is properly stored
43+
// on the container and can rebuild our in memory structures
44+
// correctly.
45+
loadFromContainer := func(t *testing.T, p *params) {
46+
t.Run("FromContainer", func(t *testing.T) {
47+
bldr, err := hatBuilderFromContainer(p.proj.cntName())
48+
require.NoError(t, err)
49+
50+
assert.Equal(t, p.bldr.hatPath, bldr.hatPath)
51+
assert.Equal(t, p.bldr.baseImage, bldr.baseImage)
52+
53+
runner, err := runnerFromContainer(p.proj.cntName())
54+
require.NoError(t, err)
55+
56+
assert.Equal(t, p.runner.cntName, runner.cntName)
57+
assert.Equal(t, p.runner.hostUser+":user", runner.hostUser)
58+
assert.Equal(t, p.runner.hostname, runner.hostname)
59+
assert.Equal(t, p.runner.port, runner.port)
60+
assert.Equal(t, p.runner.projectLocalDir, runner.projectLocalDir)
61+
assert.Equal(t, p.runner.projectName, runner.projectName)
62+
assert.Equal(t, p.runner.testCmd, runner.testCmd)
63+
})
64+
}
65+
66+
// codeServerStarts ensures that the code server process
67+
// starts up inside the container.
68+
codeServerStarts := func(t *testing.T, p *params) {
69+
t.Run("CodeServerStarts", func(t *testing.T) {
70+
err := p.proj.waitOnline()
71+
require.NoError(t, err)
72+
})
73+
}
74+
75+
run(t, "BaseImageNoHat", "codercom/retry", "",
76+
labelChecker,
77+
loadFromContainer,
78+
codeServerStarts,
79+
)
80+
81+
run(t, "BaseImageHat", "codercom/docs", "./hat-examples/fish",
82+
labelChecker,
83+
loadFromContainer,
84+
codeServerStarts,
85+
)
86+
87+
run(t, "ProjImageNoHat", "codercom/bigdur", "",
88+
labelChecker,
89+
loadFromContainer,
90+
codeServerStarts,
91+
)
92+
93+
run(t, "ProjImageHat", "codercom/extip", "./hat-examples/net",
94+
labelChecker,
95+
loadFromContainer,
96+
codeServerStarts,
97+
)
98+
}

0 commit comments

Comments
 (0)