diff --git a/pom.xml b/pom.xml
index 58f3a46..617732b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,6 +49,12 @@
spring-boot-starter-test
test
+
+ com.dajudge.kindcontainer
+ kindcontainer
+ 1.2.3
+ test
+
diff --git a/src/test/java/io/spring/FooControllerApplicationTest.java b/src/test/java/io/spring/FooControllerApplicationTest.java
new file mode 100644
index 0000000..af525b2
--- /dev/null
+++ b/src/test/java/io/spring/FooControllerApplicationTest.java
@@ -0,0 +1,61 @@
+package io.spring;
+
+import com.dajudge.kindcontainer.exception.ExecutionException;
+import io.kubernetes.client.openapi.ApiClient;
+import io.kubernetes.client.openapi.ApiException;
+import io.kubernetes.client.openapi.apis.AppsV1Api;
+import io.kubernetes.client.openapi.models.V1Deployment;
+import io.kubernetes.client.openapi.models.V1ObjectMeta;
+import io.kubernetes.client.util.generic.GenericKubernetesApi;
+import io.spring.models.V1Foo;
+import io.spring.models.V1FooList;
+import io.spring.models.V1FooSpec;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.UUID;
+
+import static io.spring.TestApiClientFactory.API_SERVER;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
+
+@SpringBootTest(classes = {TestApiClientFactory.class})
+class FooControllerApplicationTest {
+ @Autowired
+ ApiClient client;
+ @Autowired
+ GenericKubernetesApi fooClient;
+ @Autowired
+ AppsV1Api appsApi;
+
+ String namespace = UUID.randomUUID().toString();
+
+ @BeforeEach
+ public void setup() throws IOException, ExecutionException, InterruptedException {
+ API_SERVER.kubectl().create.namespace.run(namespace);
+ }
+
+ @Test
+ public void testReconciler() {
+ fooClient.create(new V1Foo()
+ .kind("Foo")
+ .apiVersion("spring.io/v1")
+ .metadata(new V1ObjectMeta()
+ .name("my-foo")
+ .namespace(namespace))
+ .spec(new V1FooSpec()
+ .name("oh-my")));
+
+ await("deployment")
+ .timeout(10, SECONDS)
+ .until(() -> !getDeployments().isEmpty());
+ }
+
+ private List getDeployments() throws ApiException {
+ return appsApi.listNamespacedDeployment(namespace, null, null, null, null, null, null, null, null, null, null).getItems();
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/io/spring/TestApiClientFactory.java b/src/test/java/io/spring/TestApiClientFactory.java
new file mode 100644
index 0000000..4f2aa78
--- /dev/null
+++ b/src/test/java/io/spring/TestApiClientFactory.java
@@ -0,0 +1,42 @@
+package io.spring;
+
+import com.dajudge.kindcontainer.ApiServerContainer;
+import io.kubernetes.client.openapi.ApiClient;
+import io.kubernetes.client.util.ClientBuilder;
+import io.kubernetes.client.util.KubeConfig;
+import org.junit.ClassRule;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.testcontainers.utility.MountableFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+
+@TestConfiguration
+public class TestApiClientFactory {
+ // TODO this would be unnecessary if the CRD was on the classpath
+ private static final File CRD_PATH = getCrdPath();
+
+ public static final ApiServerContainer> API_SERVER = new ApiServerContainer<>()
+ .withKubectl(kubectl -> {
+ // TODO this could be prettier if the CRD was on the classpath
+ kubectl.copyFileToContainer(MountableFile.forHostPath(new File(CRD_PATH, "foo.yaml").getAbsolutePath()), "/tmp/foo.yaml");
+ kubectl.apply.from("/tmp/foo.yaml").run();
+ kubectl.wait.forCondition("Established").run("crd", "foos.spring.io");
+ });
+
+ @Bean
+ public ApiClient getTestApiClient() throws IOException {
+ API_SERVER.start();
+ return ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new StringReader(API_SERVER.getKubeconfig()))).build();
+ }
+
+ private static File getCrdPath() {
+ final ClassLoader classLoader = FooControllerApplicationTest.class.getClassLoader();
+ final File file = new File(classLoader.getResource("application.properties").getFile());
+ final File projectDir = file.getParentFile().getParentFile().getParentFile();
+ return new File(projectDir, "k8s/crds");
+ }
+}