Testing a Kubernetes CLI tool
Table of Contents
I'm testing a clk extension that manages Kubernetes clusters via Kind. The integration tests need to create a real Kind cluster, which means Docker must be running inside the CI container. daggerlib's Docker-in-Docker support handles the daemon lifecycle — cgroup v2 setup, tmpfs mounts, dockerd startup — so I can focus on my tests.
The real test flow (from the project's Earthfile) installs Kind, creates a cluster, deploys an app, and runs assertions. Here I show how daggerlib provides the DinD foundation those tests build on.
This example calls daggerlib functions directly — useful for exploring what a function does before wrapping it in your own module.
First I set up my Dagger project and install daggerlib:
dagger init --sdk=python
dagger install github.com/Konubinix/daggerlib
The following is only for testing purposes — it makes the project use the local daggerlib checkout instead of the published version:
sed -i '/pin/d; s|"github.com/Konubinix/daggerlib@main"|"../.."|; s|"\.\./\.\.",|"../.."|' dagger.json
Then I write my Dagger module. The <<...>> reference below is
filled in by the function definition that follows — it shows the
function code and its output:
from typing import Annotated
import dagger
from dagger import DefaultPath, dag, function, object_type
@object_type
class ContainerTesting:
@function
async def test_kind(self) -> str:
"""Run a mocked Kind workflow inside Docker-in-Docker."""
return await (
dag.lib().dind_with_docker(
cmd="kind() { echo 'Creating cluster...'; echo \"Cluster 'test' created.\"; };"
" kubectl() { echo 'NAME STATUS ROLES AGE';"
" echo 'test-node Ready control-plane 1m'; };"
" export -f kind kubectl;"
" kind create cluster --wait 60s && kubectl get nodes",
)
.stdout()
)
1. Running a command with a live Docker daemon
Having Docker installed isn't enough — I need a running dockerd.
The dind-with-docker target starts the daemon with proper cgroup
v2 setup, then runs my command. In production I'd run Kind here;
for this example I mock the workflow:
@function
async def test_kind(self) -> str:
"""Run a mocked Kind workflow inside Docker-in-Docker."""
return await (
dag.lib().dind_with_docker(
cmd="kind() { echo 'Creating cluster...'; echo \"Cluster 'test' created.\"; };"
" kubectl() { echo 'NAME STATUS ROLES AGE';"
" echo 'test-node Ready control-plane 1m'; };"
" export -f kind kubectl;"
" kind create cluster --wait 60s && kubectl get nodes",
)
.stdout()
)
dagger call test-kind