diff --git a/cmd/composectl/cmd/list.go b/cmd/composectl/cmd/list.go index 7b61a30..460ad9e 100644 --- a/cmd/composectl/cmd/list.go +++ b/cmd/composectl/cmd/list.go @@ -18,7 +18,7 @@ type ( listOptions struct { Format string } - appJsonOutput struct { + AppJsonOutput struct { Name string `json:"name"` URI string `json:"uri"` } @@ -42,9 +42,9 @@ func listApps(cmd *cobra.Command, args []string, opts *listOptions) { apps, err := cs.ListApps(cmd.Context()) DieNotNil(err) if opts.Format == "json" { - var lsOutput []appJsonOutput + var lsOutput []AppJsonOutput for _, app := range apps { - lsOutput = append(lsOutput, appJsonOutput{ + lsOutput = append(lsOutput, AppJsonOutput{ Name: app.Name, URI: app.String(), }) diff --git a/test/integration/e2e_test.go b/test/integration/e2e_test.go index be9488b..67b9f46 100644 --- a/test/integration/e2e_test.go +++ b/test/integration/e2e_test.go @@ -1,44 +1,144 @@ package main import ( - "fmt" + "encoding/json" + composectl "github.com/foundriesio/composeapp/cmd/composectl/cmd" "os" "os/exec" "path" "testing" ) -func TestBasic(t *testing.T) { +func TestSmoke(t *testing.T) { + composeExec := os.Getenv("COMPOSECTL_EXE") + appName := "app" appBaseUri := "registry:5000/factory/app" - appComposeDef := "services:\n busybox:\n image: busybox:latest" - appDir := path.Join(t.TempDir(), "app") - digestFile := path.Join(t.TempDir(), "app.sha256") - os.MkdirAll(appDir, 0o755) - err := os.WriteFile(path.Join(appDir, "docker-compose.yml"), []byte(appComposeDef), 0o640) - if err != nil { - t.Fatal(err) - } - cmpsCtl := os.Getenv("COMPOSECTL_EXE") + appComposeDef := "services:\n busybox:\n image: busybox:latest\n command: sh -c \"while true; do sleep 60; done\"" + appDir := path.Join(t.TempDir(), appName) + digestFile := path.Join(t.TempDir(), "app.sha256") - fmt.Println("Publishing app...") - cmd := exec.Command(cmpsCtl, "publish", "-d", digestFile, appBaseUri + ":asdsa", "amd64") - cmd.Dir = appDir - output, err := cmd.CombinedOutput() + err := os.MkdirAll(appDir, 0o755) if err != nil { - t.Errorf("Failed to run publish: %s, err: %s\n", output, err) + t.Fatal(err) } - appDigest, err := os.ReadFile(digestFile) + err = os.WriteFile(path.Join(appDir, "docker-compose.yml"), []byte(appComposeDef), 0o640) if err != nil { t.Fatal(err) } - fmt.Printf("OK, app digest: %s\n", appDigest) - fmt.Println("Pulling app...") - cmd = exec.Command(cmpsCtl, "pull", appBaseUri + "@" + string(appDigest), "-u", "90") - output, err = cmd.CombinedOutput() - if err != nil { - t.Errorf("Failed to run pull: %s, err: %s\n", output, err) + var appUri string + removeApp := func(t *testing.T) { + t.Run("remove app", func(t *testing.T) { + cmd := exec.Command(composeExec, "rm", appUri) + output, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("failed to remove app: %s, err: %s\n", output, err) + } + }) + } + + uninstallApp := func(t *testing.T) { + t.Run("uninstall app", func(t *testing.T) { + cmd := exec.Command(composeExec, "uninstall", appName) + output, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("failed to uninstall app: %s, err: %s\n", output, err) + } + }) + } + + stopApp := func(t *testing.T) { + t.Run("stop app", func(t *testing.T) { + cmd := exec.Command(composeExec, "stop", appName) + output, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("failed to stop app: %s, err: %s\n", output, err) + } + }) } -} + t.Run("publish app", func(t *testing.T) { + cmd := exec.Command(composeExec, "publish", "-d", digestFile, appBaseUri+":asdsa", "amd64") + cmd.Dir = appDir + output, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("failed to publish app: %s, err: %s\n", output, err) + } + if b, err := os.ReadFile(digestFile); err == nil { + appUri = appBaseUri + "@" + string(b) + } else { + t.Errorf("failed to read the published app digest: %s\n", err) + } + }) + + t.Run("pull app", func(t *testing.T) { + cmd := exec.Command(composeExec, "pull", appUri, "-u", "90") + output, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("failed to pull app: %s, err: %s\n", output, err) + } + }) + defer removeApp(t) + + t.Run("list app", func(t *testing.T) { + cmd := exec.Command(composeExec, "ls", "--format", "json") + output, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("failed to list app: %s, err: %s\n", output, err) + } + + var lsOutput []composectl.AppJsonOutput + if err := json.Unmarshal(output, &lsOutput); err != nil { + t.Errorf("failed to unmarshal app list output: %s\n", err) + } + + if appUri != lsOutput[0].URI { + t.Errorf("app uri in the list output does not equal to the published app;"+ + " published app uri: %s, app list uri: %s\n", appUri, lsOutput[0].URI) + } + }) + + t.Run("install app", func(t *testing.T) { + cmd := exec.Command(composeExec, "install", appUri) + output, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("failed to install app: %s, err: %s\n", output, err) + } + }) + defer uninstallApp(t) + + t.Run("run app", func(t *testing.T) { + cmd := exec.Command(composeExec, "run", appName) + output, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("failed to run app: %s, err: %s\n", output, err) + } + }) + defer stopApp(t) + + t.Run("check if running", func(t *testing.T) { + cmd := exec.Command(composeExec, "ps", appUri, "--format", "json") + output, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("failed to run app: %s, err: %s\n", output, err) + } + + var psOutput map[string]composectl.App + if err := json.Unmarshal(output, &psOutput); err != nil { + t.Errorf("failed to unmarshal app ps output: %s\n", err) + } + + if len(psOutput) != 1 { + t.Errorf("expected one element in ps output, got: %d\n", len(psOutput)) + } + + appStatus, ok := psOutput[appUri] + if !ok { + t.Errorf("no app URI in the ps output: %+v\n", psOutput) + } + if appStatus.State != "running" { + t.Errorf("app is not running, its state: %+s\n", appStatus.State) + } + }) +}