diff --git a/e2e/tests/up/provider_podman.go b/e2e/tests/up/provider_podman.go index f994696d6..b903c9cba 100644 --- a/e2e/tests/up/provider_podman.go +++ b/e2e/tests/up/provider_podman.go @@ -4,9 +4,11 @@ import ( "context" "os" "os/exec" + "strings" "github.com/devsy-org/devsy/e2e/framework" "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" ) var _ = ginkgo.Describe( @@ -30,17 +32,142 @@ var _ = ginkgo.Describe( framework.ExpectNoError(err) }) - ginkgo.It( - "should start a new workspace with existing image", - func(ctx context.Context) { - tempDir, err := setupWorkspace("tests/up/testdata/docker", initialDir, f) - framework.ExpectNoError(err) + ginkgo.Context("basic", func() { + ginkgo.It( + "should start a new workspace with existing image", + func(ctx context.Context) { + tempDir, err := setupWorkspace("tests/up/testdata/docker", initialDir, f) + framework.ExpectNoError(err) - err = f.DevsyUp(ctx, tempDir) - framework.ExpectNoError(err) - }, - ginkgo.SpecTimeout(framework.TimeoutShort()), - ) + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) + + ginkgo.Context("build", func() { + ginkgo.It( + "should start a workspace with a multistage Dockerfile build", + func(ctx context.Context) { + tempDir, err := setupWorkspace( + "tests/up/testdata/docker-with-multi-stage-build", + initialDir, + f, + ) + framework.ExpectNoError(err) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + }, + ginkgo.SpecTimeout(framework.TimeoutLong()), + ) + + ginkgo.It( + "should build and respect overrideCommand false", + func(ctx context.Context) { + tempDir, err := setupWorkspace( + "tests/up/testdata/docker-override-command-false", + initialDir, + f, + ) + framework.ExpectNoError(err) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) + + ginkgo.Context("lifecycle commands", func() { + ginkgo.It( + "should run postCreateCommand with object syntax", + func(ctx context.Context) { + tempDir, err := setupWorkspace( + "tests/up/testdata/docker-postcreate-parallel", + initialDir, + f, + ) + framework.ExpectNoError(err) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + + one, err := f.DevsySSH(ctx, tempDir, "cat /tmp/post-create-one.out") + framework.ExpectNoError(err) + gomega.Expect(strings.TrimSpace(one)).To(gomega.Equal("postCreateOne")) + + two, err := f.DevsySSH(ctx, tempDir, "cat /tmp/post-create-two.out") + framework.ExpectNoError(err) + gomega.Expect(strings.TrimSpace(two)).To(gomega.Equal("postCreateTwo")) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) + + ginkgo.Context("agent delivery", func() { + ginkgo.It( + "should deliver the agent binary and execute SSH commands", + func(ctx context.Context) { + tempDir, err := setupWorkspace("tests/up/testdata/docker", initialDir, f) + framework.ExpectNoError(err) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + + err = f.DevsySSHEchoTestString(ctx, tempDir) + framework.ExpectNoError(err) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) + + ginkgo.Context("exec", func() { + ginkgo.It( + "should execute commands inside the container via SSH", + func(ctx context.Context) { + tempDir, err := setupWorkspace("tests/up/testdata/docker", initialDir, f) + framework.ExpectNoError(err) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + + out, err := f.DevsySSH(ctx, tempDir, "echo -n hello-podman") + framework.ExpectNoError(err) + framework.ExpectEqual(out, "hello-podman") + + out, err = f.DevsySSH(ctx, tempDir, "pwd") + framework.ExpectNoError(err) + gomega.Expect(strings.TrimSpace(out)).NotTo(gomega.BeEmpty()) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) + + ginkgo.Context("cleanup", func() { + ginkgo.It( + "should delete workspace and clean up resources", + func(ctx context.Context) { + tempDir, err := framework.CopyToTempDir("tests/up/testdata/docker") + framework.ExpectNoError(err) + ginkgo.DeferCleanup(framework.CleanupTempDir, initialDir, tempDir) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + + _, err = f.FindWorkspace(ctx, tempDir) + framework.ExpectNoError(err) + + err = f.DevsyWorkspaceDelete(ctx, tempDir) + framework.ExpectNoError(err) + + _, err = f.FindWorkspace(ctx, tempDir) + framework.ExpectError(err) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) }) ginkgo.Context("with rootful podman", func() { @@ -59,7 +186,7 @@ var _ = ginkgo.Describe( err = wrapper.Close() framework.ExpectNoError(err) - // #nosec G302 -- TODO Consider using a more secure permission setting and ownership if needed. + // #nosec G302 -- wrapper script needs execute permission err = os.Chmod(initialDir+"/bin/podman-rootful", 0o755) framework.ExpectNoError(err) @@ -74,17 +201,142 @@ var _ = ginkgo.Describe( framework.ExpectNoError(err) }) - ginkgo.It( - "should start a new workspace with existing image", - func(ctx context.Context) { - tempDir, err := setupWorkspace("tests/up/testdata/docker", initialDir, f) - framework.ExpectNoError(err) + ginkgo.Context("basic", func() { + ginkgo.It( + "should start a new workspace with existing image", + func(ctx context.Context) { + tempDir, err := setupWorkspace("tests/up/testdata/docker", initialDir, f) + framework.ExpectNoError(err) - err = f.DevsyUp(ctx, tempDir) - framework.ExpectNoError(err) - }, - ginkgo.SpecTimeout(framework.TimeoutShort()), - ) + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) + + ginkgo.Context("build", func() { + ginkgo.It( + "should start a workspace with a multistage Dockerfile build", + func(ctx context.Context) { + tempDir, err := setupWorkspace( + "tests/up/testdata/docker-with-multi-stage-build", + initialDir, + f, + ) + framework.ExpectNoError(err) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + }, + ginkgo.SpecTimeout(framework.TimeoutLong()), + ) + + ginkgo.It( + "should build and respect overrideCommand false", + func(ctx context.Context) { + tempDir, err := setupWorkspace( + "tests/up/testdata/docker-override-command-false", + initialDir, + f, + ) + framework.ExpectNoError(err) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) + + ginkgo.Context("lifecycle commands", func() { + ginkgo.It( + "should run postCreateCommand with object syntax", + func(ctx context.Context) { + tempDir, err := setupWorkspace( + "tests/up/testdata/docker-postcreate-parallel", + initialDir, + f, + ) + framework.ExpectNoError(err) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + + one, err := f.DevsySSH(ctx, tempDir, "cat /tmp/post-create-one.out") + framework.ExpectNoError(err) + gomega.Expect(strings.TrimSpace(one)).To(gomega.Equal("postCreateOne")) + + two, err := f.DevsySSH(ctx, tempDir, "cat /tmp/post-create-two.out") + framework.ExpectNoError(err) + gomega.Expect(strings.TrimSpace(two)).To(gomega.Equal("postCreateTwo")) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) + + ginkgo.Context("agent delivery", func() { + ginkgo.It( + "should deliver the agent binary and execute SSH commands", + func(ctx context.Context) { + tempDir, err := setupWorkspace("tests/up/testdata/docker", initialDir, f) + framework.ExpectNoError(err) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + + err = f.DevsySSHEchoTestString(ctx, tempDir) + framework.ExpectNoError(err) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) + + ginkgo.Context("exec", func() { + ginkgo.It( + "should execute commands inside the container via SSH", + func(ctx context.Context) { + tempDir, err := setupWorkspace("tests/up/testdata/docker", initialDir, f) + framework.ExpectNoError(err) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + + out, err := f.DevsySSH(ctx, tempDir, "echo -n hello-podman") + framework.ExpectNoError(err) + framework.ExpectEqual(out, "hello-podman") + + out, err = f.DevsySSH(ctx, tempDir, "pwd") + framework.ExpectNoError(err) + gomega.Expect(strings.TrimSpace(out)).NotTo(gomega.BeEmpty()) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) + + ginkgo.Context("cleanup", func() { + ginkgo.It( + "should delete workspace and clean up resources", + func(ctx context.Context) { + tempDir, err := framework.CopyToTempDir("tests/up/testdata/docker") + framework.ExpectNoError(err) + ginkgo.DeferCleanup(framework.CleanupTempDir, initialDir, tempDir) + + err = f.DevsyUp(ctx, tempDir) + framework.ExpectNoError(err) + + _, err = f.FindWorkspace(ctx, tempDir) + framework.ExpectNoError(err) + + err = f.DevsyWorkspaceDelete(ctx, tempDir) + framework.ExpectNoError(err) + + _, err = f.FindWorkspace(ctx, tempDir) + framework.ExpectError(err) + }, + ginkgo.SpecTimeout(framework.TimeoutShort()), + ) + }) }) }, )