I am trying to learn how to test custom resource watcher in the Fabric8, I follow the example from this link https://github.com/r0haaaan/kubernetes-mockserver-demo/blob/master/src/test/java/io/fabric8/demo/kubernetes/mockserver/CustomResourceMockTest.java
My custom resource is "UserACL", I am using Java junit5, this is my fabric8 version. implementation group: 'io.fabric8', name: 'kubernetes-client', version: '5.9.0' implementation group: 'io.fabric8', name: 'kubernetes-api', version: '3.0.12' testImplementation group: 'io.fabric8', name: 'kubernetes-server-mock', version: '5.9.0'
This test case failed, seem there is no any WatchEvent emitted, so countLatch never count down.
Could anybody help take a look and point out what's wrong here? Anything is missing in the following code. I appreciate it in advanced.
import io.fabric8.kubernetes.api.model.Condition;
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.fabric8.kubernetes.api.model.WatchEvent;
import io.fabric8.kubernetes.api.model.WatchEventBuilder;
import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.Watch;
import io.fabric8.kubernetes.client.Watcher;
import io.fabric8.kubernetes.client.WatcherException;
import io.fabric8.kubernetes.client.dsl.MixedOperation;
import io.fabric8.kubernetes.client.dsl.Resource;
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
import io.fabric8.kubernetes.internal.KubernetesDeserializer;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Kind;
import io.fabric8.kubernetes.model.annotation.Version;
import io.vertx.junit5.VertxExtension;
import java.net.HttpURLConnection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
public class TestKafkaHelperUtilFourth {
@Rule
public KubernetesServer server = new KubernetesServer(true, true);
@Test
@DisplayName("Should watch all custom resources")
public void testWatch() throws InterruptedException {
// Given
server.expect().withPath("/apis/custom.example.com/v1/namespaces/default/useracls?watch=true")
.andUpgradeToWebSocket()
.open()
.waitFor(10L)
.andEmit(new WatchEvent(getUserACL("test-resource"), "ADDED"))
.waitFor(10L)
.andEmit(new WatchEventBuilder()
.withNewStatusObject()
.withMessage("410 - the event requested is outdated")
.withCode(HttpURLConnection.HTTP_GONE)
.endStatusObject()
.build()).done().always();
KubernetesClient client = server.getClient();
MixedOperation<
UserACL,
KubernetesResourceList<UserACL>,
Resource<UserACL>>
userAclClient = client.resources(UserACL.class);
// When
CountDownLatch eventRecieved = new CountDownLatch(1);
KubernetesDeserializer.registerCustomKind("custom.example.com/v1", "UserACL", UserACL.class);
Watch watch = userAclClient.inNamespace("default").watch(new Watcher<UserACL>() {
@Override
public void eventReceived(Action action, UserACL userAcl) {
if (action.name().contains("ADDED"))
eventRecieved.countDown();
}
@Override
public void onClose(WatcherException e) { }
});
// Then
eventRecieved.await(20, TimeUnit.SECONDS);
Assertions.assertEquals(0, eventRecieved.getCount());
watch.close();
}
private UserACL getUserACL(String resourceName) {
UserACLSpec spec = new UserACLSpec();
spec.setUserName("test-user-name");
UserACL createdUserACL = new UserACL();
createdUserACL.setMetadata(
new ObjectMetaBuilder().withName(resourceName).build());
createdUserACL.setSpec(spec);
Condition condition = new Condition();
condition.setMessage("Last reconciliation succeeded");
condition.setReason("Successful");
condition.setStatus("True");
condition.setType("Successful");
UserACLStatus status = new UserACLStatus();
status.setCondition(new Condition[]{condition});
createdUserACL.setStatus(status);
return createdUserACL;
}
@Group("custom.example.com")
@Version("v1")
@Kind("UserACL")
public static final class UserACL
extends CustomResource<UserACLSpec, UserACLStatus> {
}
public static final class UserACLSpec {
private String userName;
public UserACLSpec() {}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
public static final class UserACLStatus {
Condition[] condition;
public UserACLStatus() {};
public Condition[] getCondition() {
return condition;
}
public void setCondition(Condition[] condition) {
this.condition = condition;
}
}
}
I checked your code; after resolving these problems I was able to get test working:
server.expect()
for mocking watch call. But you've initialized KubernetesMockServer to enable CRUD mode (this doesn't require any expectations). You need to do this instead (see false
being passed as second argument which disables CRUD mode): @Rule
public KubernetesServer server = new KubernetesServer(true, false);
io.fabric8.kubernetes.api.model.Namespaced
interface: @Group("custom.example.com")
@Version("v1")
@Kind("UserACL")
public static final class UserACL extends CustomResource<UserACLSpec, UserACLStatus> implements Namespaced { }
org.junit.Test
to org.junit.jupiter.api.Test
and also add @EnableRuleMigrationSupport
annotation in order to run this test on my JUnit5 project:@EnableRuleMigrationSupport
public class TestKafkaHelperUtilFourth {
After making these changes, test seemed to run okay for me:
$ mvn -Dtest=io.fabric8.demo.kubernetes.mockserver.TestKafkaHelperUtilFourth test
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running io.fabric8.demo.kubernetes.mockserver.TestKafkaHelperUtilFourth
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
जुल॰ 08, 2022 10:29:31 अपराह्न okhttp3.mockwebserver.MockWebServer$2 execute
INFO: MockWebServer[49697] starting to accept connections
जुल॰ 08, 2022 10:29:31 अपराह्न okhttp3.mockwebserver.MockWebServer$3 processOneRequest
INFO: MockWebServer[49697] received request: GET /apis/custom.example.com/v1/namespaces/default/useracls?watch=true HTTP/1.1 and responded: HTTP/1.1 101 Switching Protocols
जुल॰ 08, 2022 10:29:31 अपराह्न okhttp3.mockwebserver.MockWebServer$2 acceptConnections
INFO: MockWebServer[49697] done accepting connections: Socket closed
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.779 s - in io.fabric8.demo.kubernetes.mockserver.TestKafkaHelperUtilFourth