cmdtest: Run/Output/OutputJSON asserts success
* use .ExpectExit(1) to expect it to exit(1) * use .Try/.TryOutput/.TryOutputJSON to use the error return value yourself instead this shortens almost all usage of it since they no longer need to require.NoError Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
This commit is contained in:
parent
b08403e284
commit
2ec21a6f20
|
@ -66,15 +66,11 @@ func testCredentialManagement(
|
|||
}
|
||||
|
||||
t.Run("pipelines", func(t *testing.T) {
|
||||
err := fly.Run("set-pipeline", "-n", "-c", "pipelines/credential-management.yml", "-p", "test")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = fly.Run("unpause-pipeline", "-p", "test")
|
||||
require.NoError(t, err)
|
||||
fly.Run(t, "set-pipeline", "-n", "-c", "pipelines/credential-management.yml", "-p", "test")
|
||||
fly.Run(t, "unpause-pipeline", "-p", "test")
|
||||
|
||||
t.Run("config is not interpolated", func(t *testing.T) {
|
||||
config, err := fly.Output("get-pipeline", "-p", "test")
|
||||
require.NoError(t, err)
|
||||
config := fly.Output(t, "get-pipeline", "-p", "test")
|
||||
|
||||
eachString(pipelineVars, func(val string) {
|
||||
if val != "" {
|
||||
|
@ -91,54 +87,48 @@ func testCredentialManagement(
|
|||
|
||||
t.Run("interpolates resource type checks", func(t *testing.T) {
|
||||
// build will fail if ((check_failure)) doesn't get interpolated to ""
|
||||
err := fly.Run("check-resource-type", "-r", "test/custom-resource-type")
|
||||
require.NoError(t, err)
|
||||
fly.Run(t, "check-resource-type", "-r", "test/custom-resource-type")
|
||||
})
|
||||
|
||||
t.Run("interpolates resource checks", func(t *testing.T) {
|
||||
// build will fail if ((check_failure)) doesn't get interpolated to ""
|
||||
err = fly.Run("check-resource", "-r", "test/custom-resource")
|
||||
require.NoError(t, err)
|
||||
fly.Run(t, "check-resource", "-r", "test/custom-resource")
|
||||
})
|
||||
|
||||
t.Run("interpolates job builds", func(t *testing.T) {
|
||||
// build will fail and return err if any values are wrong
|
||||
err := fly.Run("trigger-job", "-w", "-j", "test/some-job")
|
||||
require.NoError(t, err)
|
||||
fly.Run(t, "trigger-job", "-w", "-j", "test/some-job")
|
||||
})
|
||||
|
||||
t.Run("interpolates one-off builds with job inputs", func(t *testing.T) {
|
||||
// build will fail and return err if any values are wrong
|
||||
err := fly.WithEnv(
|
||||
fly.WithEnv(
|
||||
"EXPECTED_RESOURCE_SECRET=some resource secret",
|
||||
"EXPECTED_RESOURCE_VERSION_SECRET=exposed some version not-so-secret",
|
||||
).Run(
|
||||
).Run(t,
|
||||
"execute",
|
||||
"-c", "tasks/credential-management-with-job-inputs.yml",
|
||||
"-j", "test/some-job",
|
||||
)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("interpolates one-off builds", func(t *testing.T) {
|
||||
// build will fail and return err if any values are wrong
|
||||
err := fly.WithEnv(
|
||||
fly.WithEnv(
|
||||
"EXPECTED_TEAM_SECRET=some team secret",
|
||||
"EXPECTED_RESOURCE_VERSION_SECRET=exposed some version not-so-secret",
|
||||
).Run("execute", "-c", "tasks/credential-management.yml")
|
||||
require.NoError(t, err)
|
||||
).Run(t, "execute", "-c", "tasks/credential-management.yml")
|
||||
})
|
||||
|
||||
t.Run("does not store secrets in database", func(t *testing.T) {
|
||||
pgDump := dc.WithArgs("exec", "-T", "db", "pg_dump")
|
||||
|
||||
dump, err := pgDump.Silence().Output(
|
||||
dump := pgDump.Silence().Output(t,
|
||||
"--exclude-schema=build_id_seq_*",
|
||||
"-U", "dev",
|
||||
"concourse",
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
eachString(pipelineVars, func(val string) {
|
||||
if val != "" && !strings.HasPrefix(val, "exposed ") {
|
||||
|
|
|
@ -8,49 +8,48 @@ import (
|
|||
"github.com/concourse/concourse/integration/internal/dctest"
|
||||
"github.com/concourse/concourse/integration/internal/flytest"
|
||||
"github.com/concourse/concourse/integration/internal/vaulttest"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestVault(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dc := dctest.Init(t, "../docker-compose.yml", "overrides/vault.yml")
|
||||
require.NoError(t, dc.Run("up", "-d"))
|
||||
dc.Run(t, "up", "-d")
|
||||
|
||||
vault := vaulttest.Init(t, dc)
|
||||
|
||||
fly := flytest.Init(t, dc)
|
||||
|
||||
// set up kv v1 store for Concourse
|
||||
require.NoError(t, vault.Run("secrets", "enable", "-version=1", "-path", "concourse/main", "kv"))
|
||||
vault.Run(t, "secrets", "enable", "-version=1", "-path", "concourse/main", "kv")
|
||||
|
||||
// set up a policy for Concourse
|
||||
require.NoError(t, vault.WithInput(bytes.NewBufferString(`
|
||||
vault.WithInput(bytes.NewBufferString(`
|
||||
path "concourse/*" {
|
||||
policy = "read"
|
||||
}
|
||||
`)).Run("policy", "write", "concourse", "-"))
|
||||
`)).Run(t, "policy", "write", "concourse", "-")
|
||||
|
||||
// set up cert-based auth
|
||||
require.NoError(t, vault.Run("auth", "enable", "cert"))
|
||||
require.NoError(t, vault.Write("auth/cert/certs/concourse", map[string]interface{}{
|
||||
vault.Run(t, "auth", "enable", "cert")
|
||||
vault.Write(t, "auth/cert/certs/concourse", map[string]interface{}{
|
||||
"policies": "concourse",
|
||||
"certificate": "@/vault/certs/vault-ca.crt", // resolved within container
|
||||
"ttl": "1h",
|
||||
}))
|
||||
})
|
||||
|
||||
testCredentialManagement(t, fly, dc,
|
||||
func(team, key string, val interface{}) {
|
||||
path := fmt.Sprintf("concourse/%s/%s", team, key)
|
||||
|
||||
err := vault.Write(path, val)
|
||||
require.NoError(t, err)
|
||||
vault.Write(t,
|
||||
fmt.Sprintf("concourse/%s/%s", team, key),
|
||||
val,
|
||||
)
|
||||
},
|
||||
func(team, pipeline, key string, val interface{}) {
|
||||
path := fmt.Sprintf("concourse/%s/%s/%s", team, pipeline, key)
|
||||
|
||||
err := vault.Write(path, val)
|
||||
require.NoError(t, err)
|
||||
vault.Write(t,
|
||||
fmt.Sprintf("concourse/%s/%s/%s", team, pipeline, key),
|
||||
val,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ type Cmd struct {
|
|||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
Silent bool
|
||||
|
||||
ExpectExitCode int
|
||||
}
|
||||
|
||||
func (cmd Cmd) WithEnv(env ...string) Cmd {
|
||||
|
@ -59,7 +61,46 @@ func (cmd Cmd) OutputTo(out io.Writer) Cmd {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func (cmd Cmd) Run(args ...string) error {
|
||||
func (cmd Cmd) ExpectExit(code int) Cmd {
|
||||
cmd.ExpectExitCode = code
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (cmd Cmd) Run(t *testing.T, args ...string) {
|
||||
err := cmd.Try(args...)
|
||||
if err != nil {
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
if exitErr.ExitCode() != cmd.ExpectExitCode {
|
||||
t.Fatalf("ExitCode %d != %d", exitErr.ExitCode(), cmd.ExpectExitCode)
|
||||
}
|
||||
} else {
|
||||
t.Fatalf("Run: %v", err)
|
||||
}
|
||||
} else if cmd.ExpectExitCode != 0 {
|
||||
t.Fatalf("ExitCode %d != %d", 0, cmd.ExpectExitCode)
|
||||
}
|
||||
}
|
||||
|
||||
func (cmd Cmd) Output(t *testing.T, args ...string) string {
|
||||
buf := new(bytes.Buffer)
|
||||
cmd.Stdout = buf
|
||||
cmd.Run(t, args...)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (cmd Cmd) OutputJSON(t *testing.T, dest interface{}, args ...string) {
|
||||
buf := new(bytes.Buffer)
|
||||
cmd.Stdout = buf
|
||||
cmd.Run(t, args...)
|
||||
|
||||
err := json.Unmarshal(buf.Bytes(), dest)
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (cmd Cmd) Try(args ...string) error {
|
||||
env := []string{
|
||||
// only inherit $PATH; we don't want to pass *everything* along because
|
||||
// then it's unclear what's necessary for the tests, but $PATH seems
|
||||
|
@ -111,12 +152,12 @@ func (cmd Cmd) Run(args ...string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (cmd Cmd) Output(args ...string) (string, error) {
|
||||
func (cmd Cmd) TryOutput(args ...string) (string, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
cmd.Stdout = buf
|
||||
|
||||
err := cmd.Run(args...)
|
||||
err := cmd.Try(args...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -124,12 +165,12 @@ func (cmd Cmd) Output(args ...string) (string, error) {
|
|||
return buf.String(), nil
|
||||
}
|
||||
|
||||
func (cmd Cmd) OutputJSON(dest interface{}, args ...string) error {
|
||||
func (cmd Cmd) TryOutputJSON(t *testing.T, dest interface{}, args ...string) error {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
cmd.Stdout = buf
|
||||
|
||||
err := cmd.Run(args...)
|
||||
err := cmd.Try(args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -45,14 +45,14 @@ func Init(t *testing.T, composeFile string, overrides ...string) Cmd {
|
|||
if err == nil {
|
||||
logFile, err := os.Create("logs/" + name + ".log")
|
||||
if err == nil {
|
||||
dc.Silence().OutputTo(logFile).Run("logs", "--no-color")
|
||||
dc.Silence().OutputTo(logFile).Run(t, "logs", "--no-color")
|
||||
logFile.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dc.Run("kill")
|
||||
dc.Run("down")
|
||||
dc.Run(t, "kill")
|
||||
dc.Run(t, "down")
|
||||
})
|
||||
|
||||
return Cmd{
|
||||
|
@ -74,13 +74,10 @@ func InitDynamic(t *testing.T, doc *ypath.Document) Cmd {
|
|||
return Init(t, fileName)
|
||||
}
|
||||
|
||||
func (cmd Cmd) Addr(container string, port int) (string, error) {
|
||||
out, err := cmd.Output("port", container, strconv.Itoa(port))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
func (cmd Cmd) Addr(t *testing.T, container string, port int) string {
|
||||
out := cmd.Output(t, "port", container, strconv.Itoa(port))
|
||||
|
||||
return strings.TrimRight(strings.Replace(out, "0.0.0.0", "127.0.0.1", 1), "\n"), nil
|
||||
return strings.TrimRight(strings.Replace(out, "0.0.0.0", "127.0.0.1", 1), "\n")
|
||||
}
|
||||
|
||||
var onces = new(sync.Map)
|
||||
|
|
|
@ -22,8 +22,7 @@ type Cmd struct {
|
|||
}
|
||||
|
||||
func Init(t *testing.T, dc dctest.Cmd) Cmd {
|
||||
webAddr, err := dc.Addr("web", 8080)
|
||||
require.NoError(t, err)
|
||||
webAddr := dc.Addr(t, "web", 8080)
|
||||
|
||||
webURL := "http://" + webAddr
|
||||
|
||||
|
@ -41,6 +40,7 @@ func Init(t *testing.T, dc dctest.Cmd) Cmd {
|
|||
|
||||
var flyResp *http.Response
|
||||
require.Eventually(t, func() bool {
|
||||
var err error
|
||||
flyResp, err = http.Get(cliURL)
|
||||
return err == nil
|
||||
}, time.Minute, time.Second)
|
||||
|
@ -61,25 +61,17 @@ func Init(t *testing.T, dc dctest.Cmd) Cmd {
|
|||
Cmd: cmd,
|
||||
}
|
||||
|
||||
fly.Run(t, "login", "-c", webURL, "-u", "test", "-p", "test")
|
||||
|
||||
require.Eventually(t, func() bool {
|
||||
err := fly.Run("login", "-c", webURL, "-u", "test", "-p", "test")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
workers, err := fly.Table(t, "workers")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, w := range workers {
|
||||
for _, w := range fly.Table(t, "workers") {
|
||||
if w["state"] == "running" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}, time.Minute, time.Second)
|
||||
}, time.Minute, time.Second, "should have a running worker")
|
||||
|
||||
return fly
|
||||
}
|
||||
|
@ -88,11 +80,8 @@ type Table []map[string]string
|
|||
|
||||
var colSplit = regexp.MustCompile(`\s{2,}`)
|
||||
|
||||
func (cmd Cmd) Table(t *testing.T, args ...string) (Table, error) {
|
||||
table, err := cmd.WithArgs("--print-table-headers").Output(args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func (cmd Cmd) Table(t *testing.T, args ...string) Table {
|
||||
table := cmd.WithArgs("--print-table-headers").Output(t, args...)
|
||||
|
||||
result := []map[string]string{}
|
||||
var headers []string
|
||||
|
@ -123,5 +112,5 @@ func (cmd Cmd) Table(t *testing.T, args ...string) (Table, error) {
|
|||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/concourse/concourse/integration/internal/cmdtest"
|
||||
"github.com/concourse/concourse/integration/internal/dctest"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type Cmd struct {
|
||||
|
@ -21,22 +20,20 @@ func Init(t *testing.T, dc dctest.Cmd) Cmd {
|
|||
RootToken string `json:"root_token"`
|
||||
}
|
||||
|
||||
err := vault.OutputJSON(&initOut, "operator", "init")
|
||||
require.NoError(t, err)
|
||||
vault.OutputJSON(t, &initOut, "operator", "init")
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
err := vault.Run("operator", "unseal", initOut.UnsealKeys[i])
|
||||
require.NoError(t, err)
|
||||
vault.Run(t, "operator", "unseal", initOut.UnsealKeys[i])
|
||||
}
|
||||
|
||||
// log in with root token
|
||||
require.NoError(t, vault.Run("login", initOut.RootToken))
|
||||
vault.Run(t, "login", initOut.RootToken)
|
||||
|
||||
return Cmd{vault}
|
||||
}
|
||||
|
||||
func (cmd Cmd) Write(path string, val interface{}) error {
|
||||
return cmd.WithArgs("write", path).Run(writeArgs(val)...)
|
||||
func (cmd Cmd) Write(t *testing.T, path string, val interface{}) {
|
||||
cmd.WithArgs("write", path).Run(t, writeArgs(val)...)
|
||||
}
|
||||
|
||||
func writeArgs(val interface{}) []string {
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/concourse/concourse/integration/internal/dctest"
|
||||
"github.com/concourse/concourse/integration/internal/flytest"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDowngrade(t *testing.T) {
|
||||
|
@ -15,7 +14,7 @@ func TestDowngrade(t *testing.T) {
|
|||
devDC := dctest.Init(t, "../docker-compose.yml")
|
||||
|
||||
t.Run("deploy dev", func(t *testing.T) {
|
||||
require.NoError(t, devDC.Run("up", "-d"))
|
||||
devDC.Run(t, "up", "-d")
|
||||
})
|
||||
|
||||
fly := flytest.Init(t, devDC)
|
||||
|
@ -25,26 +24,23 @@ func TestDowngrade(t *testing.T) {
|
|||
|
||||
t.Run("migrate down to latest from clean deploy", func(t *testing.T) {
|
||||
// just to see what it was before
|
||||
err := devDC.Run("run", "web", "migrate", "--current-db-version")
|
||||
require.NoError(t, err)
|
||||
devDC.Run(t, "run", "web", "migrate", "--current-db-version")
|
||||
|
||||
latest, err := latestDC.Output("run", "web", "migrate", "--supported-db-version")
|
||||
require.NoError(t, err)
|
||||
latest := latestDC.Output(t, "run", "web", "migrate", "--supported-db-version")
|
||||
latest = strings.TrimRight(latest, "\n")
|
||||
|
||||
err = devDC.Run("run", "web", "migrate", "--migrate-db-to-version", latest)
|
||||
require.NoError(t, err)
|
||||
devDC.Run(t, "run", "web", "migrate", "--migrate-db-to-version", latest)
|
||||
})
|
||||
|
||||
t.Run("deploy latest", func(t *testing.T) {
|
||||
require.NoError(t, latestDC.Run("up", "-d"))
|
||||
latestDC.Run(t, "up", "-d")
|
||||
})
|
||||
|
||||
fly = flytest.Init(t, latestDC)
|
||||
verifyUpgradeDowngrade(t, fly)
|
||||
|
||||
t.Run("migrate up to dev and deploy dev", func(t *testing.T) {
|
||||
require.NoError(t, devDC.Run("up", "-d"))
|
||||
devDC.Run(t, "up", "-d")
|
||||
})
|
||||
|
||||
fly = flytest.Init(t, devDC)
|
||||
|
|
|
@ -9,40 +9,31 @@ import (
|
|||
|
||||
func setupUpgradeDowngrade(t *testing.T, fly flytest.Cmd) {
|
||||
t.Run("set up test pipeline", func(t *testing.T) {
|
||||
err := fly.Run("set-pipeline", "-p", "test", "-c", "pipelines/smoke-pipeline.yml", "-n")
|
||||
require.NoError(t, err)
|
||||
fly.Run(t, "set-pipeline", "-p", "test", "-c", "pipelines/smoke-pipeline.yml", "-n")
|
||||
fly.Run(t, "unpause-pipeline", "-p", "test")
|
||||
|
||||
err = fly.Run("unpause-pipeline", "-p", "test")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = fly.Run("trigger-job", "-j", "test/say-hello", "-w")
|
||||
require.NoError(t, err)
|
||||
fly.Run(t, "trigger-job", "-j", "test/say-hello", "-w")
|
||||
})
|
||||
}
|
||||
|
||||
func verifyUpgradeDowngrade(t *testing.T, fly flytest.Cmd) {
|
||||
t.Run("pipeline and build still exists", func(t *testing.T) {
|
||||
err := fly.Run("get-pipeline", "-p", "test")
|
||||
require.NoError(t, err)
|
||||
fly.Run(t, "get-pipeline", "-p", "test")
|
||||
|
||||
out, err := fly.Output("watch", "-j", "test/say-hello", "--ignore-event-parsing-errors")
|
||||
require.NoError(t, err)
|
||||
out := fly.Output(t, "watch", "-j", "test/say-hello", "--ignore-event-parsing-errors")
|
||||
require.Contains(t, out, "Hello, world!")
|
||||
})
|
||||
|
||||
t.Run("can still run pipeline builds", func(t *testing.T) {
|
||||
err := fly.Run("trigger-job", "-j", "test/say-hello", "-w")
|
||||
require.NoError(t, err)
|
||||
fly.Run(t, "trigger-job", "-j", "test/say-hello", "-w")
|
||||
})
|
||||
|
||||
t.Run("can still run checks", func(t *testing.T) {
|
||||
err := fly.Run("check-resource", "-r", "test/mockery")
|
||||
require.NoError(t, err)
|
||||
fly.Run(t, "check-resource", "-r", "test/mockery")
|
||||
})
|
||||
|
||||
t.Run("can still run one-off builds", func(t *testing.T) {
|
||||
out, err := fly.Output("execute", "-c", "tasks/hello.yml")
|
||||
require.NoError(t, err)
|
||||
out := fly.Output(t, "execute", "-c", "tasks/hello.yml")
|
||||
require.Contains(t, out, "hello")
|
||||
})
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/concourse/concourse/integration/internal/dctest"
|
||||
"github.com/concourse/concourse/integration/internal/flytest"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUpgrade(t *testing.T) {
|
||||
|
@ -14,7 +13,7 @@ func TestUpgrade(t *testing.T) {
|
|||
latestDC := dctest.Init(t, "../docker-compose.yml", "overrides/latest.yml")
|
||||
|
||||
t.Run("deploy latest", func(t *testing.T) {
|
||||
require.NoError(t, latestDC.Run("up", "-d"))
|
||||
latestDC.Run(t, "up", "-d")
|
||||
})
|
||||
|
||||
fly := flytest.Init(t, latestDC)
|
||||
|
@ -23,7 +22,7 @@ func TestUpgrade(t *testing.T) {
|
|||
devDC := dctest.Init(t, "../docker-compose.yml")
|
||||
|
||||
t.Run("upgrade to dev", func(t *testing.T) {
|
||||
require.NoError(t, devDC.Run("up", "-d"))
|
||||
devDC.Run(t, "up", "-d")
|
||||
})
|
||||
|
||||
fly = flytest.Init(t, devDC)
|
||||
|
|
Loading…
Reference in New Issue