Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test coverage for issue 36402 #1508

Merged
merged 3 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package io.quarkus.ts.http.advanced;

import java.util.Arrays;
import java.util.concurrent.locks.LockSupport;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.sse.OutboundSseEvent;
import jakarta.ws.rs.sse.Sse;
import jakarta.ws.rs.sse.SseEventSink;
import jakarta.ws.rs.sse.SseEventSource;

@Path("/sse")
public class SseResource {
@Context
Sse sse;

@GET
@Path("/client")
public String sseClient() {
try {
return consumeSse();
}
// in case that https://github.com/quarkusio/quarkus/issues/36402 throws java.lang.RuntimeException: java.lang.ClassNotFoundException:
// catch it and return the error message
catch (RuntimeException exception) {
return exception.getMessage();
}
}

private String consumeSse() {
StringBuilder response = new StringBuilder();

/*
* Client connects to itself (to server endpoint running on same app),
* because for https://github.com/quarkusio/quarkus/issues/36402 to reproduce client must run on native app.
* Which cannot be done in test code itself.
* This method acts just as a client
*/
WebTarget target = ClientBuilder.newClient().target("http://localhost:" + getQuarkusPort() + "/api/sse/server");
michalvavrik marked this conversation as resolved.
Show resolved Hide resolved
SseEventSource updateSource = SseEventSource.target(target).build();
updateSource.register(ev -> {
response.append("event: ").append(ev.getName()).append(" ").append(ev.readData());
response.append("\n");

}, thr -> {
response.append("Error in SSE, message: ").append(thr.getMessage()).append("\n");
response.append(Arrays.toString(thr.getStackTrace()));
});
updateSource.open();

LockSupport.parkNanos(2_000_000_000L);
michalvavrik marked this conversation as resolved.
Show resolved Hide resolved
return response.toString();
}

/**
* Test runner assigns random ports, on which the app should run.
* Parse this port from the CLI and return it.
* If no parameter is specified, return the default (8080)
*
* @return port on which the application is running
*/
private int getQuarkusPort() {
String value = System.getProperty("quarkus.http.port");
michalvavrik marked this conversation as resolved.
Show resolved Hide resolved
if (value == null || value.isEmpty()) {
return 8080;
}
return Integer.parseInt(value);
}

@GET
@Path("/server")
@Produces(MediaType.SERVER_SENT_EVENTS)
public void sendSseEvents(@Context SseEventSink eventSink) {
eventSink.send(createEvent("test234", "test"));
LockSupport.parkNanos(1_000_000_000L);
michalvavrik marked this conversation as resolved.
Show resolved Hide resolved
}

private OutboundSseEvent createEvent(String name, String data) {
return sse.newEventBuilder()
.name(name)
.data(data)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.quarkus.ts.http.advanced;

import io.quarkus.test.bootstrap.RestService;
import io.quarkus.test.scenarios.QuarkusScenario;
import io.quarkus.test.services.QuarkusApplication;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

@QuarkusScenario
@Tag("https://github.com/quarkusio/quarkus/issues/36402")
// this test should only fail on native
michalvavrik marked this conversation as resolved.
Show resolved Hide resolved
public class HttpSseIT {

@QuarkusApplication
static RestService app = new RestService()
.withProperty("quarkus.oidc.enabled", "false")
.withProperty("quarkus.keycloak.policy-enforcer.enable", "false")
.withProperty("quarkus.keycloak.devservices.enabled", "false");
private static final String SSE_ERROR_MESSAGE = "java.lang.ClassNotFoundException: Provider for jakarta.ws.rs.sse.SseEventSource.Builder cannot be found";

@Test
michalvavrik marked this conversation as resolved.
Show resolved Hide resolved
public void testWorkingSse() {
String response = app.given().when().get("/api/sse/client").thenReturn().body().asString();

assertFalse(response.contains(SSE_ERROR_MESSAGE),
"SSE failed, https://github.com/quarkusio/quarkus/issues/36402 not fixed");
assertTrue(response.contains("event: test234 test"), "SSE failed, unknown bug. Response: " + response);
}
}
Loading