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

Commit

Permalink
Add validation tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathan Potter committed Apr 25, 2019
1 parent 9a5464d commit adfe2e5
Show file tree
Hide file tree
Showing 8 changed files with 491 additions and 13 deletions.
17 changes: 10 additions & 7 deletions codeserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"net/http"
"os"
"path/filepath"
"strings"
"time"

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

const cachePath = "/tmp/sail-code-server-cache/code-server"

// Only check for a new codeserver if it's over an hour old.
info, err := os.Stat(cachePath)
if err == nil {
if info.ModTime().Add(time.Hour).After(time.Now()) {
return cachePath, nil
}
}

u, err := codeserver.DownloadURL(ctx)
if err != nil {
return "", err
}

cachePath := filepath.Join(
"/tmp/sail-code-server-cache",
u[strings.LastIndex(u, "/"):],
"code-server",
)

err = os.MkdirAll(filepath.Dir(cachePath), 0750)
if err != nil {
return "", err
Expand Down
1 change: 0 additions & 1 deletion globalflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ func requireRepo(fl *flag.FlagSet) repo {
// project reads the project as the first parameter.
func (gf *globalFlags) project(fl *flag.FlagSet) *project {
return &project{
gf: gf,
conf: gf.config(),
repo: requireRepo(fl),
}
Expand Down
73 changes: 73 additions & 0 deletions hat_builder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package main

import (
"testing"

"github.com/stretchr/testify/require"
)

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

var tests = []struct {
name string
baseImage string
hatPath string
expectErr bool
}{
{
"BaseImageNotExist",
"codercom/do-not-exist:my-tag",
"./hat-examples/fish",
true,
},
{
"HatNotExist",
"codercom/ubuntu-dev",
"./hat-examples/no-hat",
true,
},
{
"GithubHatNotExist",
"codercom/ubuntu-dev",
"github:codercom/no-hat",
true,
},
{
"OK",
"codercom/ubuntu-dev",
"./hat-examples/fish",
false,
},
}

for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
bldr := &hatBuilder{
baseImage: test.baseImage,
hatPath: test.hatPath,
}

image, err := bldr.applyHat()
if test.expectErr {
require.Error(t, err)
return
}

require.NoError(t, err)

t.Run("ImageLabels", func(t *testing.T) {
labels := requireGetImageLabels(t, image)

assertLabel(t, labels, hatLabel, test.hatPath)
assertLabel(t, labels, baseImageLabel, test.baseImage)
})

t.Run("RemoveImage", func(t *testing.T) {
requireImageRemove(t, image)
})
})
}
}
6 changes: 2 additions & 4 deletions project.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ const (

// project represents a sail project.
type project struct {
gf *globalFlags
conf config
repo repo
}
Expand Down Expand Up @@ -61,9 +60,9 @@ func clone(repo repo, dir string) error {
cmd := xexec.Fmt("git clone %v %v", uri, dir)
xexec.Attach(cmd)

out, err := cmd.CombinedOutput()
err := cmd.Run()
if err != nil {
xerrors.Errorf("failed to clone '%s' to '%s': %s, %w", uri, dir, out, err)
return xerrors.Errorf("failed to clone '%s' to '%s': %w", uri, dir, err)
}
return nil
}
Expand Down Expand Up @@ -145,7 +144,6 @@ func (p *project) buildImage() (string, bool, error) {
if err != nil {
return "", false, xerrors.Errorf("failed to pull default image %v: %w", p.conf.DefaultImage, err)
}

return "", false, nil
}

Expand Down
104 changes: 104 additions & 0 deletions project_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package main

import (
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

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

homeDir, err := os.UserHomeDir()
require.NoError(t, err)

conf := mustReadConfig(filepath.Join(metaRoot(), ".sail.toml"))

var tests = []struct {
name string
repo string
expCntName string
expEnsureDirErr bool
expCustomBldImg bool
}{
{
"OK",
"codercom/bigdur",
"codercom_bigdur",
false,
true,
},
{
"RepoNotExist",
"codercom/do-not-exist",
"codercom_do-not-exist",
true,
false,
},
}

for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()

rb := newRollback()
defer rb.run()

repo, err := ParseRepo(test.repo)
require.NoError(t, err)

p := &project{
conf: conf,
repo: repo,
}

name := p.cntName()
require.Equal(t, test.expCntName, name)

expLocalDir := filepath.Join(homeDir, "Projects", test.repo)

require.Equal(t, expLocalDir, p.localDir())
require.Equal(t,
filepath.Join(expLocalDir, ".sail", "Dockerfile"),
p.dockerfilePath(),
)

t.Run("EnsureDir", func(t *testing.T) {
err = p.ensureDir()
if test.expEnsureDirErr {
require.Error(t, err)
return
}

require.NoError(t, err)
rb.add(func() {
err := os.RemoveAll(p.localDir())
require.NoError(t, err)
})
})

t.Run("BuildImage", func(t *testing.T) {
image, isCustom, err := p.buildImage()
require.NoError(t, err)
if !test.expCustomBldImg {
assert.False(t, isCustom)
assert.Empty(t, image)
return
}

assert.True(t, isCustom)

labels := requireGetImageLabels(t, image)
assertLabel(t, labels, baseImageLabel, p.repo.DockerName())

rb.add(func() {
requireImageRemove(t, p.repo.DockerName())
})
})
})
}
}
98 changes: 98 additions & 0 deletions runner_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package main

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func Test_runner(t *testing.T) {
requireNoRunningSailContainers(t)

// labelChecker asserts that all of the correct labels
// are present on the image and container.
labelChecker := func(t *testing.T, p *params) {
t.Run("Labels", func(t *testing.T) {
insp := requireContainerInspect(t, p.proj.cntName())

imgLabels := requireGetImageLabels(t, insp.Image)

assertLabel(t, imgLabels, baseImageLabel, p.bldr.baseImage)
if p.bldr.hatPath != "" {
assertLabel(t, imgLabels, hatLabel, p.bldr.hatPath)
}

labels := insp.Config.Labels
require.NotNil(t, labels)

assertLabel(t, labels, baseImageLabel, p.bldr.baseImage)
if p.bldr.hatPath != "" {
assertLabel(t, labels, hatLabel, p.bldr.hatPath)
}
assertLabel(t, labels, projectLocalDirLabel, p.proj.localDir())

cntDir, err := p.proj.containerDir()
require.NoError(t, err)
assertLabel(t, labels, projectDirLabel, cntDir)
assertLabel(t, labels, projectNameLabel, p.proj.repo.BaseName())
})
}

// loadFromContainer ensures that our state is properly stored
// on the container and can rebuild our in memory structures
// correctly.
loadFromContainer := func(t *testing.T, p *params) {
t.Run("FromContainer", func(t *testing.T) {
bldr, err := hatBuilderFromContainer(p.proj.cntName())
require.NoError(t, err)

assert.Equal(t, p.bldr.hatPath, bldr.hatPath)
assert.Equal(t, p.bldr.baseImage, bldr.baseImage)

runner, err := runnerFromContainer(p.proj.cntName())
require.NoError(t, err)

assert.Equal(t, p.runner.cntName, runner.cntName)
assert.Equal(t, p.runner.hostUser+":user", runner.hostUser)
assert.Equal(t, p.runner.hostname, runner.hostname)
assert.Equal(t, p.runner.port, runner.port)
assert.Equal(t, p.runner.projectLocalDir, runner.projectLocalDir)
assert.Equal(t, p.runner.projectName, runner.projectName)
assert.Equal(t, p.runner.testCmd, runner.testCmd)
})
}

// codeServerStarts ensures that the code server process
// starts up inside the container.
codeServerStarts := func(t *testing.T, p *params) {
t.Run("CodeServerStarts", func(t *testing.T) {
err := p.proj.waitOnline()
require.NoError(t, err)
})
}

run(t, "BaseImageNoHat", "codercom/retry", "",
labelChecker,
loadFromContainer,
codeServerStarts,
)

run(t, "BaseImageHat", "codercom/docs", "./hat-examples/fish",
labelChecker,
loadFromContainer,
codeServerStarts,
)

run(t, "ProjImageNoHat", "codercom/bigdur", "",
labelChecker,
loadFromContainer,
codeServerStarts,
)

run(t, "ProjImageHat", "codercom/extip", "./hat-examples/net",
labelChecker,
loadFromContainer,
codeServerStarts,
)
}
Loading

0 comments on commit adfe2e5

Please sign in to comment.