mirror of
https://github.com/rancher/k3k.git
synced 2026-02-14 10:00:15 +00:00
Adding some tests for k3kcli (#417)
* adding some cli tests * added coverage and tests * fix lint and cli tests * fix defer * some more cli tests
This commit is contained in:
73
.github/workflows/test.yaml
vendored
73
.github/workflows/test.yaml
vendored
@@ -11,7 +11,7 @@ permissions:
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
|
||||
- name: Install Ginkgo
|
||||
run: go install github.com/onsi/ginkgo/v2/ginkgo
|
||||
|
||||
|
||||
- name: Build and package
|
||||
run: |
|
||||
make build
|
||||
@@ -105,12 +105,75 @@ jobs:
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: k3s-logs
|
||||
name: e2e-k3s-logs
|
||||
path: /tmp/k3s.log
|
||||
|
||||
|
||||
- name: Archive k3k logs
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: k3k-logs
|
||||
name: e2e-k3k-logs
|
||||
path: /tmp/k3k.log
|
||||
|
||||
tests-cli:
|
||||
runs-on: ubuntu-latest
|
||||
needs: validate
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Install Ginkgo
|
||||
run: go install github.com/onsi/ginkgo/v2/ginkgo
|
||||
|
||||
- name: Set coverage environment
|
||||
run: |
|
||||
mkdir ${{ github.workspace }}/covdata
|
||||
|
||||
echo "COVERAGE=true" >> $GITHUB_ENV
|
||||
echo "GOCOVERDIR=${{ github.workspace }}/covdata" >> $GITHUB_ENV
|
||||
|
||||
- name: Build and package
|
||||
run: |
|
||||
make build
|
||||
make package
|
||||
|
||||
# add k3kcli to $PATH
|
||||
echo "${{ github.workspace }}/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Check k3kcli
|
||||
run: k3kcli -v
|
||||
|
||||
- name: Run cli tests
|
||||
run: make test-cli
|
||||
|
||||
- name: Convert coverage data
|
||||
run: go tool covdata textfmt -i=${{ github.workspace }}/covdata -o ${{ github.workspace }}/covdata/cover.out
|
||||
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ${{ github.workspace }}/covdata/cover.out
|
||||
flags: cli
|
||||
|
||||
- name: Archive k3s logs
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: cli-k3s-logs
|
||||
path: /tmp/k3s.log
|
||||
|
||||
- name: Archive k3k logs
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: cli-k3k-logs
|
||||
path: /tmp/k3k.log
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,3 +8,6 @@
|
||||
__debug*
|
||||
*-kubeconfig.yaml
|
||||
.envtest
|
||||
cover.out
|
||||
covcounters.**
|
||||
covmeta.**
|
||||
|
||||
9
Makefile
9
Makefile
@@ -1,5 +1,6 @@
|
||||
|
||||
REPO ?= rancher
|
||||
COVERAGE ?= false
|
||||
VERSION ?= $(shell git describe --tags --always --dirty --match="v[0-9]*")
|
||||
|
||||
## Dependencies
|
||||
@@ -29,7 +30,7 @@ version: ## Print the current version
|
||||
|
||||
.PHONY: build
|
||||
build: ## Build the the K3k binaries (k3k, k3k-kubelet and k3kcli)
|
||||
@VERSION=$(VERSION) ./scripts/build
|
||||
@VERSION=$(VERSION) COVERAGE=$(COVERAGE) ./scripts/build
|
||||
|
||||
.PHONY: package
|
||||
package: package-k3k package-k3k-kubelet ## Package the k3k and k3k-kubelet Docker images
|
||||
@@ -68,7 +69,11 @@ test-kubelet-controller: ## Run the controller tests (pkg/controller)
|
||||
|
||||
.PHONY: test-e2e
|
||||
test-e2e: ## Run the e2e tests
|
||||
$(GINKGO) $(GINKGO_FLAGS) tests
|
||||
$(GINKGO) $(GINKGO_FLAGS) --label-filter=e2e tests
|
||||
|
||||
.PHONY: test-cli
|
||||
test-cli: ## Run the cli tests
|
||||
$(GINKGO) $(GINKGO_FLAGS) --label-filter=cli tests
|
||||
|
||||
.PHONY: generate
|
||||
generate: ## Generate the CRDs specs
|
||||
|
||||
@@ -4,12 +4,20 @@ set -eou pipefail
|
||||
|
||||
LDFLAGS="-X \"github.com/rancher/k3k/pkg/buildinfo.Version=${VERSION}\""
|
||||
|
||||
build_args=()
|
||||
|
||||
# Check if coverage is enabled, e.g., in CI or when manually set
|
||||
if [[ "${COVERAGE:-false}" == "true" ]]; then
|
||||
echo "Coverage build enabled."
|
||||
build_args+=("-cover" "-coverpkg=./..." "-covermode=atomic")
|
||||
fi
|
||||
|
||||
echo "Building k3k... [cli os/arch: $(go env GOOS)/$(go env GOARCH)]"
|
||||
echo "Current TAG: ${VERSION} "
|
||||
|
||||
export CGO_ENABLED=0
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags="${LDFLAGS}" -o bin/k3k
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags="${LDFLAGS}" -o bin/k3k-kubelet ./k3k-kubelet
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags="${LDFLAGS}" "${build_args[@]}" -o bin/k3k
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags="${LDFLAGS}" "${build_args[@]}" -o bin/k3k-kubelet ./k3k-kubelet
|
||||
|
||||
# build the cli for the local OS and ARCH
|
||||
go build -ldflags="${LDFLAGS}" -o bin/k3kcli ./cli
|
||||
go build -ldflags="${LDFLAGS}" "${build_args[@]}" -o bin/k3kcli ./cli
|
||||
|
||||
119
tests/cli_test.go
Normal file
119
tests/cli_test.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package k3k_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/rand"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func K3kcli(args ...string) (string, string, error) {
|
||||
stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
|
||||
|
||||
cmd := exec.CommandContext(context.Background(), "k3kcli", args...)
|
||||
cmd.Stdout = stdout
|
||||
cmd.Stderr = stderr
|
||||
|
||||
err := cmd.Run()
|
||||
|
||||
return stdout.String(), stderr.String(), err
|
||||
}
|
||||
|
||||
var _ = When("using the k3kcli", Label("cli"), func() {
|
||||
It("can get the version", func() {
|
||||
stdout, _, err := K3kcli("--version")
|
||||
Expect(err).To(Not(HaveOccurred()))
|
||||
Expect(stdout).To(ContainSubstring("k3kcli Version: v"))
|
||||
})
|
||||
|
||||
When("trying the cluster commands", func() {
|
||||
It("can create, list and delete a cluster", func() {
|
||||
var (
|
||||
stdout string
|
||||
stderr string
|
||||
err error
|
||||
)
|
||||
|
||||
clusterName := "cluster-" + rand.String(5)
|
||||
clusterNamespace := "k3k-" + clusterName
|
||||
|
||||
_, stderr, err = K3kcli("cluster", "create", clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("You can start using the cluster"))
|
||||
|
||||
stdout, stderr, err = K3kcli("cluster", "list")
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(BeEmpty())
|
||||
Expect(stdout).To(ContainSubstring(clusterNamespace))
|
||||
|
||||
_, stderr, err = K3kcli("cluster", "delete", clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("Deleting [%s] cluster in namespace [%s]", clusterName, clusterNamespace))
|
||||
|
||||
// The deletion could take a bit
|
||||
Eventually(func() string {
|
||||
stdout, stderr, err := K3kcli("cluster", "list", "-n", clusterNamespace)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
return stdout + stderr
|
||||
}).
|
||||
WithTimeout(time.Second * 5).
|
||||
WithPolling(time.Second).
|
||||
Should(BeEmpty())
|
||||
})
|
||||
})
|
||||
|
||||
When("trying the policy commands", func() {
|
||||
It("can create, list and delete a policy", func() {
|
||||
var (
|
||||
stdout string
|
||||
stderr string
|
||||
err error
|
||||
)
|
||||
|
||||
policyName := "policy-" + rand.String(5)
|
||||
|
||||
_, stderr, err = K3kcli("policy", "create", policyName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("Creating policy [%s]", policyName))
|
||||
|
||||
stdout, stderr, err = K3kcli("policy", "list")
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(BeEmpty())
|
||||
Expect(stdout).To(ContainSubstring(policyName))
|
||||
|
||||
stdout, stderr, err = K3kcli("policy", "delete", policyName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stdout).To(BeEmpty())
|
||||
Expect(stderr).To(BeEmpty())
|
||||
|
||||
stdout, stderr, err = K3kcli("policy", "list")
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stdout).To(BeEmpty())
|
||||
Expect(stderr).To(BeEmpty())
|
||||
})
|
||||
})
|
||||
|
||||
When("trying the kubeconfig command", func() {
|
||||
It("can generate a kubeconfig", func() {
|
||||
var (
|
||||
stderr string
|
||||
err error
|
||||
)
|
||||
|
||||
clusterName := "cluster-" + rand.String(5)
|
||||
|
||||
_, stderr, err = K3kcli("cluster", "create", clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("You can start using the cluster"))
|
||||
|
||||
_, stderr, err = K3kcli("kubeconfig", "generate", "--name", clusterName)
|
||||
Expect(err).To(Not(HaveOccurred()), string(stderr))
|
||||
Expect(stderr).To(ContainSubstring("You can start using the cluster"))
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -40,17 +40,20 @@ func TestTests(t *testing.T) {
|
||||
}
|
||||
|
||||
var (
|
||||
k3sContainer *k3s.K3sContainer
|
||||
hostIP string
|
||||
restcfg *rest.Config
|
||||
k8s *kubernetes.Clientset
|
||||
k8sClient client.Client
|
||||
k3sContainer *k3s.K3sContainer
|
||||
hostIP string
|
||||
restcfg *rest.Config
|
||||
k8s *kubernetes.Clientset
|
||||
k8sClient client.Client
|
||||
kubeconfigPath string
|
||||
)
|
||||
|
||||
var _ = BeforeSuite(func() {
|
||||
var err error
|
||||
ctx := context.Background()
|
||||
|
||||
GinkgoWriter.Println("GOCOVERDIR:", os.Getenv("GOCOVERDIR"))
|
||||
|
||||
k3sContainer, err = k3s.Run(ctx, "rancher/k3s:v1.32.1-k3s1")
|
||||
Expect(err).To(Not(HaveOccurred()))
|
||||
|
||||
@@ -62,6 +65,19 @@ var _ = BeforeSuite(func() {
|
||||
kubeconfig, err := k3sContainer.GetKubeConfig(context.Background())
|
||||
Expect(err).To(Not(HaveOccurred()))
|
||||
|
||||
tmpFile, err := os.CreateTemp("", "kubeconfig-")
|
||||
Expect(err).To(Not(HaveOccurred()))
|
||||
|
||||
_, err = tmpFile.Write(kubeconfig)
|
||||
Expect(err).To(Not(HaveOccurred()))
|
||||
Expect(tmpFile.Close()).To(Succeed())
|
||||
|
||||
kubeconfigPath = tmpFile.Name()
|
||||
|
||||
Expect(os.Setenv("KUBECONFIG", kubeconfigPath)).To(Succeed())
|
||||
|
||||
DeferCleanup(os.Remove, kubeconfigPath)
|
||||
|
||||
initKubernetesClient(kubeconfig)
|
||||
installK3kChart(kubeconfig)
|
||||
})
|
||||
@@ -205,7 +221,7 @@ func readFileWithinPod(ctx context.Context, client *kubernetes.Clientset, config
|
||||
|
||||
output := new(bytes.Buffer)
|
||||
|
||||
stderr, err := exec(ctx, client, config, namespace, name, command, nil, output)
|
||||
stderr, err := podExec(ctx, client, config, namespace, name, command, nil, output)
|
||||
if err != nil || len(stderr) > 0 {
|
||||
return nil, fmt.Errorf("faile to read the following file %s: %v", path, err)
|
||||
}
|
||||
@@ -213,7 +229,7 @@ func readFileWithinPod(ctx context.Context, client *kubernetes.Clientset, config
|
||||
return output.Bytes(), nil
|
||||
}
|
||||
|
||||
func exec(ctx context.Context, clientset *kubernetes.Clientset, config *rest.Config, namespace, name string, command []string, stdin io.Reader, stdout io.Writer) ([]byte, error) {
|
||||
func podExec(ctx context.Context, clientset *kubernetes.Clientset, config *rest.Config, namespace, name string, command []string, stdin io.Reader, stdout io.Writer) ([]byte, error) {
|
||||
req := clientset.CoreV1().RESTClient().Post().
|
||||
Resource("pods").
|
||||
Name(name).
|
||||
|
||||
Reference in New Issue
Block a user