Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,14 @@ test_hypervisors:
.PHONY: test_nerdctl
test_nerdctl:
@echo "Testing nerdctl"
@GOFLAGS=$(TEST_FLAGS) $(GO) test $(TEST_OPTS) ./tests/e2e -run TestNerdctl -v
@GOFLAGS=$(TEST_FLAGS) $(GO) test $(TEST_OPTS) ./tests/e2e -run TestE2E -v --ginkgo.v --ginkgo.focus="Nerdctl"
@echo " "

## test_ctr Run all end-to-end tests with ctr
.PHONY: test_ctr
test_ctr:
@echo "Testing ctr"
@GOFLAGS=$(TEST_FLAGS) $(GO) test $(TEST_OPTS) ./tests/e2e -run TestCtr -v --ginkgo.v
@GOFLAGS=$(TEST_FLAGS) $(GO) test $(TEST_OPTS) ./tests/e2e -run TestE2E -v --ginkgo.v --ginkgo.focus="Ctr"
@echo " "

## test_crictl Run all end-to-end tests with crictl
Expand All @@ -293,14 +293,14 @@ test_docker:
.PHONY: test_nerdctl_%
test_nerdctl_%:
@echo "Testing nerdctl"
@GOFLAGS=$(TEST_FLAGS) $(GO) test $(TEST_OPTS) ./tests/e2e -v -run "TestNerdctl/$*"
@GOFLAGS=$(TEST_FLAGS) $(GO) test $(TEST_OPTS) ./tests/e2e -v --ginkgo.v -run TestE2E --ginkgo.focus="Nerdctl.*$*"
@echo " "

## test_ctr_[pattern] Run all end-to-end tests with ctr that match pattern
.PHONY: test_ctr_%
test_ctr_%:
@echo "Testing ctr"
@GOFLAGS=$(TEST_FLAGS) $(GO) test $(TEST_OPTS) ./tests/e2e -v --ginkgo.v -run TestCtr --ginkgo.focus="$*"
@GOFLAGS=$(TEST_FLAGS) $(GO) test $(TEST_OPTS) ./tests/e2e -v --ginkgo.v -run TestE2E --ginkgo.focus="Ctr.*$*"
@echo " "

## test_crictl_[pattern] Run all end-to-end tests with crictl that match pattern
Expand Down
15 changes: 2 additions & 13 deletions tests/e2e/ctr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ import (
const testCtr = "TestCtr"

var _ = Describe("Ctr", Ordered, ContinueOnFailure, func() {
var (
tool *ctrInfo
cwd string
)
var tool *ctrInfo

BeforeAll(func() {
cases := ctrTestCases()
Expand All @@ -42,15 +39,7 @@ var _ = Describe("Ctr", Ordered, ContinueOnFailure, func() {
})

BeforeEach(func() {
var err error
cwd, err = os.Getwd()
Expect(err).NotTo(HaveOccurred())
testDir := GinkgoT().TempDir()
Expect(os.Chdir(testDir)).To(Succeed())

DeferCleanup(func() {
Expect(os.Chdir(cwd)).To(Succeed())
})
setupTestDir()
})

ReportAfterEach(func(report SpecReport) {
Expand Down
10 changes: 0 additions & 10 deletions tests/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,6 @@ import (
"testing"
)

func TestNerdctl(t *testing.T) {
tests := nerdctlTestCases()
for _, tc := range tests {
t.Run(tc.Name, func(t *testing.T) {
nerdctlTool := newNerdctlTool(tc)
runTest(nerdctlTool, t)
})
}
}

func TestCrictl(t *testing.T) {
tests := crictlTestCases()
for _, tc := range tests {
Expand Down
128 changes: 128 additions & 0 deletions tests/e2e/nerdctl_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright (c) 2023-2026, Nubificus LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package urunce2etesting

import (
"fmt"
"os"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

const testNerdctl = "TestNerdctl"

var _ = Describe("Nerdctl", Ordered, ContinueOnFailure, func() {
var tool *nerdctlInfo

BeforeAll(func() {
cases := nerdctlTestCases()
images := getTestImages(cases)
err := pullAllImages(testNerdctl, images)
Expect(err).NotTo(HaveOccurred(), "Failed to pull nerdctl images")

DeferCleanup(func() {
removeAllImages(testNerdctl, images)
})
})

BeforeEach(func() {
setupTestDir()
})

ReportAfterEach(func(report SpecReport) {
if report.Failed() && tool != nil {
AddReportEntry("test-args", tool.getTestArgs())
}
})

Context("foreground containers", func() {
DescribeTable("unikernel containers",
func(tc containerTestArgs) {
for _, vol := range tc.Volumes {
if _, err := os.Stat(vol.Source); err != nil {
Skip(fmt.Sprintf("Could not find %s", vol.Source))
}
}

tool = newNerdctlTool(tc)
tool.setContainerID(tc.Name)

DeferCleanup(func() {
if tool != nil && tool.getContainerID() != "" {
By("Cleaning up container")
if err := testCleanup(tool); err != nil {
GinkgoLogr.Error(err, "Container cleanup failed")
}
}
})

By("Running container")
output, err := tool.runContainer(false)
Expect(err).NotTo(HaveOccurred(), "Failed to run container: %s", output)

By("Verifying container output")
Expect(output).To(ContainSubstring(tc.ExpectOut))
},
toTableEntries(selectTestCases(nerdctlTestCases(), false)),
)
})

Context("detached containers", func() {
DescribeTable("unikernel containers",
func(tc containerTestArgs) {
for _, vol := range tc.Volumes {
if _, err := os.Stat(vol.Source); err != nil {
Skip(fmt.Sprintf("Could not find %s", vol.Source))
}
}

tool = newNerdctlTool(tc)

By("Creating container")
cID, err := tool.createContainer()
Expect(err).NotTo(HaveOccurred(), "Failed to create container: %s", cID)
tool.setContainerID(cID)

DeferCleanup(func() {
if tool != nil && tool.getContainerID() != "" {
By("Stopping container")
if err := tool.stopContainer(); err != nil {
GinkgoLogr.Error(err, "Failed to stop container")
}
By("Removing container")
if err := tool.rmContainer(); err != nil {
GinkgoLogr.Error(err, "Failed to remove container")
}
By("Verifying container removal")
if err := testVerifyRm(tool); err != nil {
GinkgoLogr.Error(err, "Failed to verify removal")
}
}
})

By("Starting container")
output, err := tool.startContainer(true)
Expect(err).NotTo(HaveOccurred(), "Failed to start container: %s", output)

By("Running test function")
Eventually(func() error {
return tc.TestFunc(tool)
}, defaultTimeout, defaultInterval).Should(Succeed())
},
toTableEntries(selectTestCases(nerdctlTestCases(), true)),
)
})
})
9 changes: 3 additions & 6 deletions tests/e2e/setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
)

const (
testNerdctl = "TestNerdctl"
testE2E = "TestE2E"
testCrictl = "TestCrictl"
testDocker = "TestDocker"
maxPullRetries = 5
Expand Down Expand Up @@ -68,18 +68,15 @@ func parseTestPattern() (string, string) {

func getTestCases(testFunc string) []containerTestArgs {
switch testFunc {
case testNerdctl:
return nerdctlTestCases()
case testCtr:
// Images managed by BeforeAll in ctr_test.go
case testE2E:
// Images managed by BeforeAll in Ginkgo specs
return []containerTestArgs{}
case testCrictl:
return crictlTestCases()
case testDocker:
return dockerTestCases()
default:
var allCases []containerTestArgs
allCases = append(allCases, nerdctlTestCases()...)
allCases = append(allCases, crictlTestCases()...)
allCases = append(allCases, dockerTestCases()...)
return allCases
Expand Down
33 changes: 31 additions & 2 deletions tests/e2e/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,35 @@
package urunce2etesting

import (
"os"
"testing"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/format"
)

func TestCtr(t *testing.T) {
const (
defaultTimeout = 10 * time.Second
defaultInterval = 1 * time.Second
)

func TestE2E(t *testing.T) {
format.MaxLength = 0 // Do not truncate failure output
RegisterFailHandler(Fail)
RunSpecs(t, "Ctr E2E Suite")
RunSpecs(t, "E2E Suite")
}

// setupTestDir switches to a temp directory, restored via DeferCleanup.
func setupTestDir() {
cwd, err := os.Getwd()
Expect(err).NotTo(HaveOccurred())
testDir := GinkgoT().TempDir()
Expect(os.Chdir(testDir)).To(Succeed())
DeferCleanup(func() {
Expect(os.Chdir(cwd)).To(Succeed())
})
}

// toTableEntries converts a slice of containerTestArgs into Ginkgo TableEntry
Expand All @@ -37,3 +55,14 @@ func toTableEntries(cases []containerTestArgs) []TableEntry {
}
return entries
}

// selectTestCases returns cases with or without a TestFunc.
func selectTestCases(cases []containerTestArgs, hasTestFunc bool) []containerTestArgs {
var out []containerTestArgs
for _, tc := range cases {
if (tc.TestFunc != nil) == hasTestFunc {
out = append(out, tc)
}
}
return out
}
Loading