I am working on a Quarkus application to acct as an Operator in a OpenShift/Kubernetes cluster. When writing the tests using a kubernetesMockServer it is working fine for REST calls to developed application but when code runs inside an Initialization Block it is failing, in the log I see that mock server is replying with a 404 error:
2020-02-17 11:04:12,148 INFO [okh.moc.MockWebServer] (MockWebServer /127.0.0.1:53048) MockWebServer[57577] received request: GET /apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions HTTP/1.1 and responded: HTTP/1.1 404 Client Error
On the TestCode I have:
@QuarkusTestResource(KubernetesMockServerTestResource.class)
@QuarkusTest
class TestAIRController {
@MockServer
KubernetesMockServer mockServer;
private CustomResourceDefinition crd;
private CustomResourceDefinitionList crdlist;
@BeforeEach
public void before() {
crd = new CustomResourceDefinitionBuilder()
.withApiVersion("apiextensions.k8s.io/v1beta1")
.withNewMetadata().withName("types.openshift.example-cloud.com")
.endMetadata()
.withNewSpec()
.withNewNames()
.withKind("Type")
.withPlural("types")
.endNames()
.withGroup("openshift.example-cloud.com")
.withVersion("v1")
.withScope("Namespaced")
.endSpec()
.build();
crdlist = new CustomResourceDefinitionListBuilder().withItems(crd).build();
mockServer.expect().get().withPath("/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions")
.andReturn(200, crdlist)
.always();
}
@Test
void test() {
RestAssured.when().get("/dummy").then().body("size()", Is.is(0));
}
}
The dummy rest is using the same code for searching the CRD, and in fact when running withouth the class observing the startup event it works fine
@Path("/dummy")
public class Dummy {
private static final Logger LOGGER =LoggerFactory.getLogger(Dummy.class);
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response listCRDs(){
KubernetesClient oc = new DefaultKubernetesClient();
CustomResourceDefinition crd = oc.customResourceDefinitions()
.list().getItems().stream()
.filter( ob -> ob.getMetadata().getName().equals("types.openshift.example-cloud.com"))
.findFirst().get();
LOGGER.info("CRD NAME is {}", crd.getMetadata().getName());
return Response.ok(new ArrayList<String>()).build();
}
}
Finally this is an except of the
@ApplicationScoped
public class AIRWatcher {
private static final Logger LOGGER = LoggerFactory.getLogger(AIRWatcher.class);
void OnStart(@Observes StartupEvent ev) {
KubernetesClient oc = new DefaultKubernetesClient();
CustomResourceDefinition crd = oc.customResourceDefinitions()
.list().getItems().stream()
.filter( ob -> ob.getMetadata().getName().equals("types.openshift.example-cloud.com"))
.findFirst().get();
LOGGER.info("Using {}", crd.getMetadata().getName());
}
}
It's like for some reason the mock server is still not initialized for the Startup event, is there any way to solve it?
The problem is that the Mock Server is only configured to respond right before the test execution, while this code:
void OnStart(@Observes StartupEvent ev) {
KubernetesClient oc = new DefaultKubernetesClient();
CustomResourceDefinition crd = oc.customResourceDefinitions()
.list().getItems().stream()
.filter( ob -> ob.getMetadata().getName().equals("types.openshift.example-cloud.com"))
.findFirst().get();
LOGGER.info("Using {}", crd.getMetadata().getName());
}
runs when the application is actually comes up (which is before any @BeforeEach
runs).
Can you please open an issue on the Quarkus Github? This should be something we provide a solution for