Assert state of your Kubernetes Cluster in Java using Fabric8 Kubernetes Assertions

Rohan Kumar
3 min readMay 16, 2020

--

There are times when we’re writing tests for our Kubernetes related resources and we need to verify each small detail for the resources we deploy to the cluster. It’s quite tiresome to type nested object calls to assert spec , metadata and other details. Fabric8 also provides a very useful library called Kubernetes Assertions:

https://github.com/fabric8io/kubernetes-assertions

It provides assertions based on assertj and Fabric8 Kubernetes Java Client making it easy for Java developers writing better tests when working with Kubernetes/OpenShift native applications. In this blog, I would be giving you a brief overview of this library.

You can find it on Maven Central as usual. You can start using this library by just adding it as a dependency in your pom.xml like this:

<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-assertions</artifactId>
<version>${kubernetes-assertions.version}</version>
</dependency>

Once added as a dependency, you can start using assertions provided by this library inside your tests. Let’s take a look at some of the examples of asserting different scenarios:

Asserting Pod:

Suppose you have a Pod object with a format like this:

apiVersion: v1
kind: Pod
metadata:
name: testpod
labels:
app: website
role: frontend
spec:
containers:
- name: website
image: nginx:1.7.9
ports:
- containerPort: 80

In order to assert this object you can use Kubernetes Assertions library like this:

@Test
public void testPod() {
// Given
Pod pod = getPodObject();

// When + Then
assertThat
(pod).metadata().name().isEqualTo("testpod");
assertThat(pod).metadata().labels().containsKey("app");
assertThat(pod).metadata().labels().containsKey("role");
assertThat(pod).spec()
.containers().hasSize(1);
assertThat(pod).spec()
.containers()
.item(0).name().isEqualTo("website");
assertThat(pod).spec()
.containers()
.item(0).image().isEqualTo("nginx:1.7.9");
assertThat(pod).spec()
.containers()
.item(0).ports().item(0).hasContainerPort(80);
}

Asserting Deployment:

Suppose you want to assert a Deployment object like this:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80

This is also very similar to what we did while asserting Pod , it’s just that we have to assert PodTemplate inside it along with metadata :

@Test
public void testDeployment() {
// Given
Deployment deployment = getDeploymentObj();

// When + Then
AbstractMap.SimpleEntry<String, String> entry = new AbstractMap.SimpleEntry<>("app", "nginx");
assertThat(deployment).metadata()
.name().isEqualTo("nginx-deployment");
assertThat(deployment).metadata()
.labels()
.contains(entry);
assertThat(deployment).spec()
.hasReplicas(1);
assertThat(deployment).spec()
.selector()
.matchLabels()
.contains(entry);
assertThat(deployment).spec()
.template()
.metadata()
.labels()
.contains(entry);
assertThat(deployment).spec()
.template()
.spec()
.containers().hasSize(1);
assertThat(deployment).spec()
.template()
.spec()
.containers()
.item(0)
.name().isEqualTo("nginx");
assertThat(deployment).spec()
.template()
.spec()
.containers()
.item(0)
.image().isEqualTo("nginx:1.7.9");
assertThat(deployment).spec()
.template()
.spec()
.containers()
.item(0)
.ports()
.item(0).hasContainerPort(80);
}

Asserting Service:

For a Service object like this one:

apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376

You can assert it like this:

@Test
public void testService() {
// Given
Service service = getServiceObj();

// When + Then
assertThat
(service).metadata().name().isEqualTo("my-service");
assertThat(service).spec().selector().isNotEmpty();
assertThat(service).spec().selector().containsKey("app");
assertThat(service).spec().ports().hasSize(1);
assertThat(service).spec().ports().item(0).hasPort(80);
}

Asserting things in real Kubernetes Client with Kubernetes Client:

You can also pass KubernetesClient object to assertThat(..) and do real assertions on real Kubernetes server. For example suppose you have a Pod running in your Kubernetes cluster like this:

~/work/repos/kubernetes-assertions-demo : $ kubectl get pods
NAME READY STATUS RESTARTS AGE
testpod 1/1 Running 0 16m
~/work/repos/kubernetes-assertions-demo : $

You can assert it like this:

@Test
public void testAssertWithClientOnRealK8s() {
// Given
final KubernetesClient client = new DefaultKubernetesClient();

// When + Then
assertThat
(client).pods()
.runningStatus().filterNamespace("default").hasSize(1);
}

Suppose you want to assert log output of a Pod , you can also do it like this:

@Test
public void testAssertWithClientOnRealK8s2() {
// Given
final KubernetesClient client = new DefaultKubernetesClient();

// When + Then
assertThat
(client).pods()
.runningStatus()
.filterNamespace("default")
.filterName("helloworld")
.logs().containsText("hello-world");
}

If you have a Deployment and you want to assert whether all Pod objects related to this Deployment have become available or not, You can do something like this:

@Test
public void testAssertWithClientOnRealK8s3() {
// Given
final KubernetesClient client = new DefaultKubernetesClient();

assertThat(client)
.namespace("default")
.deployment("nginx-deployment")
.pods().isPodReadyForPeriod(1000L, 1000L);
}

This concludes this blog for Kubernetes Assertions. I hope I was able to provide a clear overview of Kubernetes Assertions to you. I hope you would find it helpful. I have provided all the code for this blog in this repository:

https://github.com/r0haaaan/kubernetes-assertions-demo

If you face any problems with these assertions, feel free to file a Github issue on our repository. If you like our stuff, please support us by spreading the word and 🌟 us on Github.

If you want to get involved in our development, please go through our Kubernetes Client’s CONTRIBUTING.md page. We love contributions.

--

--

No responses yet