Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert legacy docker tests from bash to golang #11357

Merged
merged 14 commits into from
Nov 26, 2024
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ require (
go.etcd.io/etcd/server/v3 v3.5.16
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.27.0
golang.org/x/mod v0.20.0
golang.org/x/net v0.29.0
golang.org/x/sync v0.8.0
golang.org/x/sys v0.25.0
Expand Down Expand Up @@ -449,7 +450,6 @@ require (
go.uber.org/mock v0.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/oauth2 v0.22.0 // indirect
golang.org/x/term v0.24.0 // indirect
golang.org/x/text v0.18.0 // indirect
Expand Down
121 changes: 121 additions & 0 deletions tests/docker/basics/basics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package main

import (
"flag"
"fmt"
"os"
"strings"
"testing"

tester "github.com/k3s-io/k3s/tests/docker"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var k3sImage = flag.String("k3sImage", "", "The k3s image used to provision containers")
var config *tester.TestConfig

func Test_DockerBasic(t *testing.T) {
flag.Parse()
RegisterFailHandler(Fail)
RunSpecs(t, "Basic Docker Test Suite")
}

var _ = Describe("Basic Tests", Ordered, func() {

Context("Setup Cluster", func() {
It("should provision servers and agents", func() {
var err error
config, err = tester.NewTestConfig(*k3sImage)
Expect(err).NotTo(HaveOccurred())
Expect(config.ProvisionServers(1)).To(Succeed())
Expect(config.ProvisionAgents(1)).To(Succeed())
Eventually(func() error {
return tester.DeploymentsReady([]string{"coredns", "local-path-provisioner", "metrics-server", "traefik"}, config.KubeconfigFile)
}, "60s", "5s").Should(Succeed())
Eventually(func() error {
return tester.NodesReady(config.KubeconfigFile)
}, "40s", "5s").Should(Succeed())
})
})

Context("Verify Binaries and Images", func() {
It("has valid bundled binaries", func() {
for _, server := range config.Servers {
Expect(tester.VerifyValidVersion(server.Name, "kubectl")).To(Succeed())
Expect(tester.VerifyValidVersion(server.Name, "ctr")).To(Succeed())
Expect(tester.VerifyValidVersion(server.Name, "crictl")).To(Succeed())
}
})
It("has valid airgap images", func() {
Expect(config).To(Not(BeNil()))
err := VerifyAirgapImages(config.Servers)
Expect(err).NotTo(HaveOccurred())
})
})

Context("Use Local Storage Volume", func() {
It("should apply local storage volume", func() {
const volumeTestManifest = "../resources/volume-test.yaml"

// Apply the manifest
cmd := fmt.Sprintf("kubectl apply -f %s --kubeconfig=%s", volumeTestManifest, config.KubeconfigFile)
_, err := tester.RunCommand(cmd)
Expect(err).NotTo(HaveOccurred(), "failed to apply volume test manifest")
})
It("should validate local storage volume", func() {
Eventually(func() (bool, error) {
return tester.PodReady("volume-test", config.KubeconfigFile)
}, "20s", "5s").Should(BeTrue())
})
})
})

var failed bool
var _ = AfterEach(func() {
failed = failed || CurrentSpecReport().Failed()
})

var _ = AfterSuite(func() {
if config != nil && !failed {
config.Cleanup()
}
})

// VerifyAirgapImages checks for changes in the airgap image list
func VerifyAirgapImages(servers []tester.ServerConfig) error {
// This file is generated during the build packaging step
const airgapImageList = "../../../scripts/airgap/image-list.txt"

// Use a map to automatically handle duplicates
imageSet := make(map[string]struct{})
// Collect all images from containers
for _, server := range servers {
name := server.Name
cmd := fmt.Sprintf("docker exec %s crictl images -o json | jq -r '.images[].repoTags[0] | select(. != null)'", name)
output, err := tester.RunCommand(cmd)
Expect(err).NotTo(HaveOccurred(), "failed to execute crictl and jq: %v", err)

for _, line := range strings.Split(strings.TrimSpace(string(output)), "\n") {
if line != "" {
imageSet[line] = struct{}{}
}
}
}

// Convert map keys to slice
uniqueImages := make([]string, 0, len(imageSet))
for image := range imageSet {
uniqueImages = append(uniqueImages, image)
}

existing, err := os.ReadFile(airgapImageList)
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("failed to read airgap list file: %v", err)
}

// Sorting doesn't matter with ContainElements
existingImages := strings.Split(strings.TrimSpace(string(existing)), "\n")
Expect(existingImages).To(ContainElements(uniqueImages))
dereknola marked this conversation as resolved.
Show resolved Hide resolved
return nil
}
30 changes: 30 additions & 0 deletions tests/docker/resources/volume-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: local-path-pvc
namespace: kube-system
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:
name: volume-test
namespace: kube-system
spec:
containers:
- name: volume-test
image: rancher/mirrored-pause:3.6
imagePullPolicy: IfNotPresent
volumeMounts:
- name: volv
mountPath: /data
volumes:
- name: volv
persistentVolumeClaim:
claimName: local-path-pvc
Loading