Merge pull request #420 from docker/cli-test-framework

Move cli to gotest.tools
This commit is contained in:
Chris Crone 2020-08-04 14:15:45 +02:00 committed by GitHub
commit f42f5312ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 83 additions and 129 deletions

View File

@ -19,24 +19,16 @@ package cmd
import ( import (
"testing" "testing"
"github.com/stretchr/testify/require" "gotest.tools/v3/assert"
"github.com/stretchr/testify/suite"
"gotest.tools/v3/golden" "gotest.tools/v3/golden"
_ "github.com/docker/api/example" _ "github.com/docker/api/example"
"github.com/docker/api/tests/framework" "github.com/docker/api/tests/framework"
) )
type InspectSuite struct { func TestInspectId(t *testing.T) {
framework.CliSuite c := framework.NewTestCLI(t)
} err := runInspect(c.Context(), "id")
assert.NilError(t, err)
func (sut *InspectSuite) TestInspectId() { golden.Assert(t, c.GetStdOut(), "inspect-out-id.golden")
err := runInspect(sut.Context(), "id")
require.Nil(sut.T(), err)
golden.Assert(sut.T(), sut.GetStdOut(), "inspect-out-id.golden")
}
func TestInspect(t *testing.T) {
suite.Run(t, new(InspectSuite))
} }

View File

@ -19,40 +19,33 @@ package cmd
import ( import (
"testing" "testing"
"github.com/stretchr/testify/require" "gotest.tools/v3/assert"
"github.com/stretchr/testify/suite"
"gotest.tools/v3/golden" "gotest.tools/v3/golden"
_ "github.com/docker/api/example" _ "github.com/docker/api/example"
"github.com/docker/api/tests/framework" "github.com/docker/api/tests/framework"
) )
type PsSuite struct { func TestPs(t *testing.T) {
framework.CliSuite c := framework.NewTestCLI(t)
}
func (sut *PsSuite) TestPs() {
opts := psOpts{ opts := psOpts{
quiet: false, quiet: false,
} }
err := runPs(sut.Context(), opts) err := runPs(c.Context(), opts)
require.Nil(sut.T(), err) assert.NilError(t, err)
golden.Assert(sut.T(), sut.GetStdOut(), "ps-out.golden") golden.Assert(t, c.GetStdOut(), "ps-out.golden")
} }
func (sut *PsSuite) TestPsQuiet() { func TestPsQuiet(t *testing.T) {
c := framework.NewTestCLI(t)
opts := psOpts{ opts := psOpts{
quiet: true, quiet: true,
} }
err := runPs(sut.Context(), opts) err := runPs(c.Context(), opts)
require.Nil(sut.T(), err) assert.NilError(t, err)
golden.Assert(sut.T(), sut.GetStdOut(), "ps-out-quiet.golden") golden.Assert(t, c.GetStdOut(), "ps-out-quiet.golden")
}
func TestPs(t *testing.T) {
suite.Run(t, new(PsSuite))
} }

View File

@ -19,7 +19,6 @@ package formatter
import ( import (
"testing" "testing"
"github.com/stretchr/testify/require"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"github.com/docker/api/cli/options/run" "github.com/docker/api/cli/options/run"
@ -69,7 +68,7 @@ func TestDisplayPorts(t *testing.T) {
Publish: testCase.in, Publish: testCase.in,
} }
containerConfig, err := runOpts.ToContainerConfig("test") containerConfig, err := runOpts.ToContainerConfig("test")
require.Nil(t, err) assert.NilError(t, err)
out := PortsString(containerConfig.Ports) out := PortsString(containerConfig.Ports)
assert.Equal(t, testCase.expected, out) assert.Equal(t, testCase.expected, out)

View File

@ -22,13 +22,12 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"gotest.tools/v3/assert"
"github.com/docker/api/cli/cmd" "github.com/docker/api/cli/cmd"
"github.com/docker/api/cli/cmd/context" "github.com/docker/api/cli/cmd/context"
"github.com/docker/api/cli/cmd/login" "github.com/docker/api/cli/cmd/login"
"github.com/docker/api/cli/cmd/run" "github.com/docker/api/cli/cmd/run"
"github.com/stretchr/testify/require"
"github.com/docker/api/config" "github.com/docker/api/config"
) )
@ -40,33 +39,33 @@ func TestDetermineCurrentContext(t *testing.T) {
d, err := ioutil.TempDir("", "") d, err := ioutil.TempDir("", "")
// nolint errcheck // nolint errcheck
defer os.RemoveAll(d) defer os.RemoveAll(d)
require.NoError(t, err) assert.NilError(t, err)
err = ioutil.WriteFile(filepath.Join(d, config.ConfigFileName), contextSetConfig, 0644) err = ioutil.WriteFile(filepath.Join(d, config.ConfigFileName), contextSetConfig, 0644)
require.NoError(t, err) assert.NilError(t, err)
// If nothing set, fallback to default // If nothing set, fallback to default
c := determineCurrentContext("", "") c := determineCurrentContext("", "")
require.Equal(t, "default", c) assert.Equal(t, c, "default")
// If context flag set, use that // If context flag set, use that
c = determineCurrentContext("other-context", "") c = determineCurrentContext("other-context", "")
require.Equal(t, "other-context", c) assert.Equal(t, c, "other-context")
// If no context flag, use config // If no context flag, use config
c = determineCurrentContext("", d) c = determineCurrentContext("", d)
require.Equal(t, "some-context", c) assert.Equal(t, c, "some-context")
// Ensure context flag overrides config // Ensure context flag overrides config
c = determineCurrentContext("other-context", d) c = determineCurrentContext("other-context", d)
require.Equal(t, "other-context", c) assert.Equal(t, "other-context", c)
} }
func TestCheckOwnCommand(t *testing.T) { func TestCheckOwnCommand(t *testing.T) {
require.True(t, isOwnCommand(login.Command())) assert.Assert(t, isOwnCommand(login.Command()))
require.True(t, isOwnCommand(context.Command())) assert.Assert(t, isOwnCommand(context.Command()))
require.True(t, isOwnCommand(cmd.ServeCommand())) assert.Assert(t, isOwnCommand(cmd.ServeCommand()))
require.False(t, isOwnCommand(run.Command())) assert.Assert(t, !isOwnCommand(run.Command()))
require.False(t, isOwnCommand(cmd.ExecCommand())) assert.Assert(t, !isOwnCommand(cmd.ExecCommand()))
require.False(t, isOwnCommand(cmd.LogsCommand())) assert.Assert(t, !isOwnCommand(cmd.LogsCommand()))
require.False(t, isOwnCommand(cmd.PsCommand())) assert.Assert(t, !isOwnCommand(cmd.PsCommand()))
} }

View File

@ -3,18 +3,12 @@ package mobycli
import ( import (
"testing" "testing"
. "github.com/onsi/gomega" "gotest.tools/v3/assert"
"github.com/stretchr/testify/suite"
"github.com/docker/api/context/store" "github.com/docker/api/context/store"
"github.com/docker/api/tests/framework"
) )
type MobyExecSuite struct { func TestDelegateContextTypeToMoby(t *testing.T) {
framework.CliSuite
}
func (sut *MobyExecSuite) TestDelegateContextTypeToMoby() {
isDelegated := func(val string) bool { isDelegated := func(val string) bool {
for _, ctx := range delegatedContextTypes { for _, ctx := range delegatedContextTypes {
@ -28,14 +22,9 @@ func (sut *MobyExecSuite) TestDelegateContextTypeToMoby() {
allCtx := []string{store.AciContextType, store.EcsContextType, store.AwsContextType, store.DefaultContextType} allCtx := []string{store.AciContextType, store.EcsContextType, store.AwsContextType, store.DefaultContextType}
for _, ctx := range allCtx { for _, ctx := range allCtx {
if isDelegated(ctx) { if isDelegated(ctx) {
Expect(mustDelegateToMoby(ctx)).To(BeTrue()) assert.Assert(t, mustDelegateToMoby(ctx))
continue continue
} }
Expect(mustDelegateToMoby(ctx)).To(BeFalse()) assert.Assert(t, !mustDelegateToMoby(ctx))
} }
} }
func TestExec(t *testing.T) {
RegisterTestingT(t)
suite.Run(t, new(MobyExecSuite))
}

View File

@ -21,17 +21,12 @@ import (
"regexp" "regexp"
"testing" "testing"
"github.com/stretchr/testify/assert" "gotest.tools/v3/assert"
"github.com/stretchr/testify/require" "gotest.tools/v3/assert/cmp"
"github.com/stretchr/testify/suite"
"github.com/docker/api/containers" "github.com/docker/api/containers"
) )
type RunOptsSuite struct {
suite.Suite
}
var ( var (
// AzureNameRegex is used to validate container names // AzureNameRegex is used to validate container names
// Regex was taken from server side error: // Regex was taken from server side error:
@ -40,14 +35,14 @@ var (
) )
// TestAzureRandomName ensures compliance with Azure naming requirements // TestAzureRandomName ensures compliance with Azure naming requirements
func (s *RunOptsSuite) TestAzureRandomName() { func TestAzureRandomName(t *testing.T) {
n := getRandomName() n := getRandomName()
require.Less(s.T(), len(n), 64) assert.Assert(t, len(n) < 64)
require.Greater(s.T(), len(n), 1) assert.Assert(t, len(n) > 1)
require.Regexp(s.T(), AzureNameRegex, n) assert.Assert(t, cmp.Regexp(AzureNameRegex, n))
} }
func (s *RunOptsSuite) TestPortParse() { func TestPortParse(t *testing.T) {
testCases := []struct { testCases := []struct {
in string in string
expected []containers.Port expected []containers.Port
@ -125,12 +120,12 @@ func (s *RunOptsSuite) TestPortParse() {
Publish: []string{testCase.in}, Publish: []string{testCase.in},
} }
result, err := opts.toPorts() result, err := opts.toPorts()
require.Nil(s.T(), err) assert.NilError(t, err)
assert.ElementsMatch(s.T(), testCase.expected, result) assert.DeepEqual(t, result, testCase.expected)
} }
} }
func (s *RunOptsSuite) TestLabels() { func TestLabels(t *testing.T) {
testCases := []struct { testCases := []struct {
in []string in []string
expected map[string]string expected map[string]string
@ -167,11 +162,11 @@ func (s *RunOptsSuite) TestLabels() {
for _, testCase := range testCases { for _, testCase := range testCases {
result, err := toLabels(testCase.in) result, err := toLabels(testCase.in)
assert.Equal(s.T(), testCase.expectedError, err) if testCase.expectedError == nil {
assert.Equal(s.T(), testCase.expected, result) assert.NilError(t, err)
} else {
assert.Error(t, err, testCase.expectedError.Error())
}
assert.DeepEqual(t, result, testCase.expected)
} }
} }
func TestExampleTestSuite(t *testing.T) {
suite.Run(t, new(RunOptsSuite))
}

View File

@ -20,72 +20,59 @@ import (
"context" "context"
"io/ioutil" "io/ioutil"
"os" "os"
"testing"
"github.com/stretchr/testify/require" "gotest.tools/v3/assert"
"github.com/stretchr/testify/suite" "gotest.tools/v3/assert/cmp"
apicontext "github.com/docker/api/context" apicontext "github.com/docker/api/context"
"github.com/docker/api/context/store" "github.com/docker/api/context/store"
) )
// CliSuite is a helper struct that creates a configured context // TestCLI is a helper struct for CLI tests.
// and captures the output of a command. it should be used in the type TestCLI struct {
// same way as testify.suite.Suite ctx context.Context
type CliSuite struct { writer *os.File
suite.Suite reader *os.File
ctx context.Context
writer *os.File
reader *os.File
OriginalStdout *os.File
storeRoot string
} }
// BeforeTest is called by testify.suite // NewTestCLI returns a CLI testing helper.
func (sut *CliSuite) BeforeTest(suiteName, testName string) { func NewTestCLI(t *testing.T) *TestCLI {
ctx := context.Background()
ctx = apicontext.WithCurrentContext(ctx, "example")
dir, err := ioutil.TempDir("", "store") dir, err := ioutil.TempDir("", "store")
require.Nil(sut.T(), err) assert.Check(t, cmp.Nil(err))
originalStdout := os.Stdout
t.Cleanup(func() {
os.Stdout = originalStdout
_ = os.RemoveAll(dir)
})
s, err := store.New( s, err := store.New(
store.WithRoot(dir), store.WithRoot(dir),
) )
require.Nil(sut.T(), err) assert.Check(t, cmp.Nil(err))
err = s.Create("example", "example", "", store.ContextMetadata{}) err = s.Create("example", "example", "", store.ContextMetadata{})
require.Nil(sut.T(), err) assert.Check(t, cmp.Nil(err))
sut.storeRoot = dir
ctx := context.Background()
ctx = store.WithContextStore(ctx, s) ctx = store.WithContextStore(ctx, s)
sut.ctx = ctx ctx = apicontext.WithCurrentContext(ctx, "example")
sut.OriginalStdout = os.Stdout
r, w, err := os.Pipe() r, w, err := os.Pipe()
require.Nil(sut.T(), err)
os.Stdout = w os.Stdout = w
sut.writer = w assert.Check(t, cmp.Nil(err))
sut.reader = r return &TestCLI{ctx, w, r}
} }
// Context returns a configured context // Context returns a configured context
func (sut *CliSuite) Context() context.Context { func (c *TestCLI) Context() context.Context {
return sut.ctx return c.ctx
} }
// GetStdOut returns the output of the command // GetStdOut returns the output of the command
func (sut *CliSuite) GetStdOut() string { func (c *TestCLI) GetStdOut() string {
err := sut.writer.Close() _ = c.writer.Close()
require.Nil(sut.T(), err) out, _ := ioutil.ReadAll(c.reader)
out, _ := ioutil.ReadAll(sut.reader)
return string(out) return string(out)
} }
// AfterTest is called by testify.suite
func (sut *CliSuite) AfterTest(suiteName, testName string) {
os.Stdout = sut.OriginalStdout
err := os.RemoveAll(sut.storeRoot)
require.Nil(sut.T(), err)
}