diff --git a/kubernetes-server-mock/src/main/java/io/fabric8/kubernetes/client/server/mock/KubernetesResponseComposer.java b/kubernetes-server-mock/src/main/java/io/fabric8/kubernetes/client/server/mock/KubernetesResponseComposer.java index 185af2466f1..d84b64e7c36 100644 --- a/kubernetes-server-mock/src/main/java/io/fabric8/kubernetes/client/server/mock/KubernetesResponseComposer.java +++ b/kubernetes-server-mock/src/main/java/io/fabric8/kubernetes/client/server/mock/KubernetesResponseComposer.java @@ -39,7 +39,8 @@ private static String join(String sep, Collection collection) { @Override public String compose(Collection collection) { return String.format( - "{\"apiVersion\":\"v1\",\"kind\":\"List\", \"items\": [%s]}", + "{\"apiVersion\":\"v1\",\"kind\":\"List\", \"items\": [%s], " + + "\"metadata\": {\"resourceVersion\": \"\", \"selfLink\": \"\"}}", join(",", collection)); } } diff --git a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/CrudInformerTest.java b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/CrudInformerTest.java new file mode 100644 index 00000000000..6f02cbc3bbc --- /dev/null +++ b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/CrudInformerTest.java @@ -0,0 +1,72 @@ +/** + * Copyright (C) 2020 VMware, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.fabric8.kubernetes.client.mock; + +import io.fabric8.kubernetes.api.model.Pod; +import io.fabric8.kubernetes.api.model.PodBuilder; +import io.fabric8.kubernetes.api.model.PodList; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.informers.ResourceEventHandler; +import io.fabric8.kubernetes.client.informers.SharedIndexInformer; +import io.fabric8.kubernetes.client.informers.SharedInformerFactory; +import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import org.junit.Rule; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@EnableRuleMigrationSupport +public class CrudInformerTest { + @Rule + public KubernetesServer server = new KubernetesServer(true, true); + + // https://github.com/fabric8io/kubernetes-client/issues/2306 + @Test + void testCrudInformer() throws InterruptedException { + Pod podToCreate = new PodBuilder().withNewMetadata().withName("pod1").endMetadata().build(); + KubernetesClient client = server.getClient(); + SharedInformerFactory factory = client.informers(); + SharedIndexInformer podInformer = factory.sharedIndexInformerFor(Pod.class, PodList.class, 4000); + BlockingQueue events = new LinkedBlockingQueue<>(); + podInformer.addEventHandler( + new ResourceEventHandler() { + @Override + public void onAdd(Pod obj) { + events.add(obj); + } + + @Override + public void onUpdate(Pod oldObj, Pod newObj) { + } + + @Override + public void onDelete(Pod oldObj, boolean deletedFinalStateUnknown) { + } + }); + factory.startAllRegisteredInformers(); + client.pods().create(podToCreate); + Pod readPod = events.poll(5, TimeUnit.SECONDS); + assertNotNull(readPod); + assertEquals(readPod.getMetadata().getName(), podToCreate.getMetadata().getName()); + factory.stopAllRegisteredInformers(); + } +}