mirror of
https://github.com/docker/compose.git
synced 2025-07-03 03:44:25 +02:00
Add e2e tests for plugin behavior and commands
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com> Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
aa8587095f
commit
6febf68748
@ -4,7 +4,7 @@ clean:
|
|||||||
build:
|
build:
|
||||||
go build -v -o dist/docker-ecs cmd/main/main.go
|
go build -v -o dist/docker-ecs cmd/main/main.go
|
||||||
|
|
||||||
test: ## Run tests
|
test: build ## Run tests
|
||||||
go test ./... -v
|
go test ./... -v
|
||||||
|
|
||||||
dev: build
|
dev: build
|
||||||
|
@ -43,6 +43,12 @@ func NewRootCmd(name string, dockerCli command.Cli) *cobra.Command {
|
|||||||
opts, err = docker.CheckAwsContextExists(contextName)
|
opts, err = docker.CheckAwsContextExists(contextName)
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) != 0 {
|
||||||
|
return fmt.Errorf("%q is not a docker ecs command\nSee 'docker ecs --help'", args[0])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
VersionCommand(),
|
VersionCommand(),
|
||||||
|
@ -50,6 +50,7 @@ require (
|
|||||||
gopkg.in/dancannon/gorethink.v3 v3.0.5 // indirect
|
gopkg.in/dancannon/gorethink.v3 v3.0.5 // indirect
|
||||||
gopkg.in/fatih/pool.v2 v2.0.0 // indirect
|
gopkg.in/fatih/pool.v2 v2.0.0 // indirect
|
||||||
gopkg.in/gorethink/gorethink.v3 v3.0.5 // indirect
|
gopkg.in/gorethink/gorethink.v3 v3.0.5 // indirect
|
||||||
|
gotest.tools v2.2.0+incompatible
|
||||||
gotest.tools/v3 v3.0.2
|
gotest.tools/v3 v3.0.2
|
||||||
vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 // indirect
|
vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 // indirect
|
||||||
)
|
)
|
||||||
|
@ -3,6 +3,7 @@ package docker
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/docker/cli/cli/command"
|
||||||
cliconfig "github.com/docker/cli/cli/config"
|
cliconfig "github.com/docker/cli/cli/config"
|
||||||
"github.com/docker/cli/cli/context/store"
|
"github.com/docker/cli/cli/context/store"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
@ -25,7 +26,12 @@ type AwsContext struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewContext(name string, awsContext *AwsContext) error {
|
func NewContext(name string, awsContext *AwsContext) error {
|
||||||
contextStore := initContextStore()
|
_, err := NewContextWithStore(name, awsContext, cliconfig.ContextStoreDir())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewContextWithStore(name string, awsContext *AwsContext, contextDirectory string) (store.Store, error) {
|
||||||
|
contextStore := initContextStore(contextDirectory)
|
||||||
endpoints := map[string]interface{}{
|
endpoints := map[string]interface{}{
|
||||||
"aws": awsContext,
|
"aws": awsContext,
|
||||||
"docker": awsContext,
|
"docker": awsContext,
|
||||||
@ -36,16 +42,19 @@ func NewContext(name string, awsContext *AwsContext) error {
|
|||||||
Endpoints: endpoints,
|
Endpoints: endpoints,
|
||||||
Metadata: TypeContext{Type: contextType},
|
Metadata: TypeContext{Type: contextType},
|
||||||
}
|
}
|
||||||
return contextStore.CreateOrUpdate(metadata)
|
return contextStore, contextStore.CreateOrUpdate(metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initContextStore() store.Store {
|
func initContextStore(contextDir string) store.Store {
|
||||||
config := store.NewConfig(getter)
|
config := store.NewConfig(getter)
|
||||||
return store.New(cliconfig.ContextStoreDir(), config)
|
return store.New(contextDir, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckAwsContextExists(contextName string) (*AwsContext, error) {
|
func CheckAwsContextExists(contextName string) (*AwsContext, error) {
|
||||||
contextStore := initContextStore()
|
if contextName == command.DefaultContextName {
|
||||||
|
return nil, fmt.Errorf("can't use \"%s\" with ECS command because it is not an AWS context", contextName)
|
||||||
|
}
|
||||||
|
contextStore := initContextStore(cliconfig.ContextStoreDir())
|
||||||
metadata, err := contextStore.GetMetadata(contextName)
|
metadata, err := contextStore.GetMetadata(contextName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
18
ecs/tests/command_test.go
Normal file
18
ecs/tests/command_test.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"gotest.tools/v3/icmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExitErrorCode(t *testing.T) {
|
||||||
|
cmd, cleanup := dockerCli.createTestCmd()
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
cmd.Command = dockerCli.Command("ecs", "unknown_command")
|
||||||
|
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
|
||||||
|
ExitCode: 1,
|
||||||
|
Err: "\"unknown_command\" is not a docker ecs command\nSee 'docker ecs --help'",
|
||||||
|
})
|
||||||
|
}
|
127
ecs/tests/main_test.go
Normal file
127
ecs/tests/main_test.go
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
dockerConfigFile "github.com/docker/cli/cli/config/configfile"
|
||||||
|
"github.com/docker/ecs-plugin/pkg/docker"
|
||||||
|
"gotest.tools/v3/icmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
e2ePath = flag.String("e2e-path", ".", "Set path to the e2e directory")
|
||||||
|
dockerCliPath = os.Getenv("DOCKERCLI_BINARY")
|
||||||
|
dockerCli dockerCliCommand
|
||||||
|
testContextName = "testAwsContextToBeRemoved"
|
||||||
|
)
|
||||||
|
|
||||||
|
type dockerCliCommand struct {
|
||||||
|
path string
|
||||||
|
cliPluginDir string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfigFileOperator func(configFile *dockerConfigFile.ConfigFile)
|
||||||
|
|
||||||
|
func (d dockerCliCommand) createTestCmd(ops ...ConfigFileOperator) (icmd.Cmd, func()) {
|
||||||
|
configDir, err := ioutil.TempDir("", "config")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
configFilePath := filepath.Join(configDir, "config.json")
|
||||||
|
config := dockerConfigFile.ConfigFile{
|
||||||
|
CLIPluginsExtraDirs: []string{
|
||||||
|
d.cliPluginDir,
|
||||||
|
},
|
||||||
|
Filename: configFilePath,
|
||||||
|
}
|
||||||
|
for _, op := range ops {
|
||||||
|
op(&config)
|
||||||
|
}
|
||||||
|
configFile, err := os.Create(configFilePath)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer configFile.Close()
|
||||||
|
err = json.NewEncoder(configFile).Encode(config)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
awsContext := docker.AwsContext{
|
||||||
|
Profile: "TestProfile",
|
||||||
|
Cluster: "TestCluster",
|
||||||
|
Region: "TestRegion",
|
||||||
|
}
|
||||||
|
testStore, err := docker.NewContextWithStore(testContextName, &awsContext, filepath.Join(configDir, "contexts"))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
cleanup := func() {
|
||||||
|
fmt.Println("cleanup")
|
||||||
|
testStore.Remove(testContextName)
|
||||||
|
os.RemoveAll(configDir)
|
||||||
|
}
|
||||||
|
env := append(os.Environ(),
|
||||||
|
"DOCKER_CONFIG="+configDir,
|
||||||
|
"DOCKER_CLI_EXPERIMENTAL=enabled") // TODO: Remove this once docker ecs plugin is no more experimental
|
||||||
|
return icmd.Cmd{Env: env}, cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d dockerCliCommand) Command(args ...string) []string {
|
||||||
|
return append([]string{d.path, "--context", testContextName}, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
flag.Parse()
|
||||||
|
if err := os.Chdir(*e2ePath); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
dockerEcs := os.Getenv("DOCKERECS_BINARY")
|
||||||
|
if dockerEcs == "" {
|
||||||
|
dockerEcs = filepath.Join(cwd, "../dist/docker-ecs")
|
||||||
|
}
|
||||||
|
dockerEcs, err = filepath.Abs(dockerEcs)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if dockerCliPath == "" {
|
||||||
|
dockerCliPath = "docker"
|
||||||
|
} else {
|
||||||
|
dockerCliPath, err = filepath.Abs(dockerCliPath)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Prepare docker cli to call the docker-ecs plugin binary:
|
||||||
|
// - Create a symbolic link with the dockerEcs binary to the plugin directory
|
||||||
|
cliPluginDir, err := ioutil.TempDir("", "configContent")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(cliPluginDir)
|
||||||
|
createDockerECSSymLink(dockerEcs, cliPluginDir)
|
||||||
|
|
||||||
|
dockerCli = dockerCliCommand{path: dockerCliPath, cliPluginDir: cliPluginDir}
|
||||||
|
os.Exit(m.Run())
|
||||||
|
}
|
||||||
|
|
||||||
|
func createDockerECSSymLink(dockerEcs, configDir string) {
|
||||||
|
dockerEcsExecName := "docker-ecs"
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
dockerEcsExecName += ".exe"
|
||||||
|
}
|
||||||
|
if err := os.Symlink(dockerEcs, filepath.Join(configDir, dockerEcsExecName)); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
33
ecs/tests/plugin_test.go
Normal file
33
ecs/tests/plugin_test.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"gotest.tools/assert"
|
||||||
|
"gotest.tools/v3/golden"
|
||||||
|
"gotest.tools/v3/icmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInvokePluginFromCLI(t *testing.T) {
|
||||||
|
cmd, cleanup := dockerCli.createTestCmd()
|
||||||
|
defer cleanup()
|
||||||
|
// docker --help should list app as a top command
|
||||||
|
cmd.Command = dockerCli.Command("--help")
|
||||||
|
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
|
||||||
|
Out: "ecs* Docker ECS (Docker Inc.,",
|
||||||
|
})
|
||||||
|
|
||||||
|
// docker app --help prints docker-app help
|
||||||
|
cmd.Command = dockerCli.Command("ecs", "--help")
|
||||||
|
usage := icmd.RunCmd(cmd).Assert(t, icmd.Success).Combined()
|
||||||
|
|
||||||
|
goldenFile := "plugin-usage.golden"
|
||||||
|
golden.Assert(t, usage, goldenFile)
|
||||||
|
|
||||||
|
// docker info should print app version and short description
|
||||||
|
cmd.Command = dockerCli.Command("info")
|
||||||
|
re := regexp.MustCompile(`ecs: Docker ECS \(Docker Inc\., .*\)`)
|
||||||
|
output := icmd.RunCmd(cmd).Assert(t, icmd.Success).Combined()
|
||||||
|
assert.Assert(t, re.MatchString(output))
|
||||||
|
}
|
34
ecs/tests/setup_command_test.go
Normal file
34
ecs/tests/setup_command_test.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"gotest.tools/assert"
|
||||||
|
"gotest.tools/v3/golden"
|
||||||
|
"gotest.tools/v3/icmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSetupMandatoryArguments(t *testing.T) {
|
||||||
|
cmd, cleanup := dockerCli.createTestCmd()
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
cmd.Command = dockerCli.Command("ecs", "setup")
|
||||||
|
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
|
||||||
|
ExitCode: 1,
|
||||||
|
Err: "required flag(s) \"cluster\", \"profile\", \"region\" not set",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
func TestDefaultAwsContextName(t *testing.T) {
|
||||||
|
cmd, cleanup := dockerCli.createTestCmd()
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
cmd.Command = dockerCli.Command("ecs", "setup", "--cluster", "clusterName", "--profile", "profileName",
|
||||||
|
"--region", "regionName")
|
||||||
|
icmd.RunCmd(cmd).Assert(t, icmd.Success)
|
||||||
|
|
||||||
|
cmd.Command = dockerCli.Command("context", "inspect", "aws")
|
||||||
|
output := icmd.RunCmd(cmd).Assert(t, icmd.Success).Combined()
|
||||||
|
expected := golden.Get(t, "context-inspect.golden")
|
||||||
|
assert.Assert(t, strings.HasPrefix(output, string(expected)))
|
||||||
|
}
|
16
ecs/tests/testdata/context-inspect.golden
vendored
Normal file
16
ecs/tests/testdata/context-inspect.golden
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"Name": "aws",
|
||||||
|
"Metadata": {},
|
||||||
|
"Endpoints": {
|
||||||
|
"aws": {
|
||||||
|
"Cluster": "clusterName",
|
||||||
|
"Profile": "profileName",
|
||||||
|
"Region": "regionName"
|
||||||
|
},
|
||||||
|
"docker": {
|
||||||
|
"SkipTLSVerify": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TLSMaterial": {},
|
||||||
|
"Storage":
|
14
ecs/tests/testdata/plugin-usage.golden
vendored
Normal file
14
ecs/tests/testdata/plugin-usage.golden
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
Usage: docker ecs COMMAND
|
||||||
|
|
||||||
|
run multi-container applications on Amazon ECS.
|
||||||
|
|
||||||
|
Management Commands:
|
||||||
|
compose
|
||||||
|
secret Manages secrets
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
setup
|
||||||
|
version Show version.
|
||||||
|
|
||||||
|
Run 'docker ecs COMMAND --help' for more information on a command.
|
Loading…
x
Reference in New Issue
Block a user