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 some 3.8.5 backports 2 #40663 #1802

Merged
merged 3 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
Expand Up @@ -23,6 +23,7 @@
import static org.apache.http.HttpHeaders.ACCEPT_ENCODING;
import static org.apache.http.HttpHeaders.ACCEPT_LANGUAGE;
import static org.apache.http.HttpHeaders.CONTENT_TYPE;
import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR;
import static org.apache.http.HttpStatus.SC_NOT_FOUND;
import static org.apache.http.HttpStatus.SC_OK;
import static org.hamcrest.MatcherAssert.assertThat;
Expand All @@ -35,7 +36,6 @@
import static org.htmlunit.util.MimeType.IMAGE_PNG;
import static org.htmlunit.util.MimeType.TEXT_CSS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.nio.file.Paths;
import java.time.Duration;
Expand Down Expand Up @@ -182,6 +182,46 @@ public void multipartFormDataReader() {
.body(TEXT, is(TEXT));
}

@Test
@DisplayName("RESTEasy Reactive Multipart Max Parameters test")
jcarranzan marked this conversation as resolved.
Show resolved Hide resolved
michalvavrik marked this conversation as resolved.
Show resolved Hide resolved
public void multiPartFormDataMaxParametersAllowed() {
// We are going to reach the MAX_PARAMETERS_ALLOWED in Quarkus Multipart that it's 1000
final int PARAMETERS_TO_ADD = 998;
// The file itself it's one parameter to add also
var request = getApp().given().multiPart(FILE, Paths.get("src", "test", "resources", "file.txt").toFile());

for (int i = 0; i < PARAMETERS_TO_ADD; i++) {
request = request.multiPart("param" + i, "value" + i);
}
// now we add the parameter TEXT with formParam, so we will get the max limit 1000
request.formParam(TEXT, TEXT);
request
.post(ROOT_PATH + MULTIPART_FORM_PATH)
.then()
.statusCode(SC_OK)
.body(FILE, is("File content"))
.body(TEXT, is(TEXT));

}

@DisplayName("RESTEasy Reactive Multipart Over the Max Parameters limit test")
@Test
public void exceedMultiPartParamsMaxLimit() {
// The file itself it's one parameter to add also
var request = getApp().given().multiPart(FILE, Paths.get("src", "test", "resources", "file.txt").toFile());
// We test the over the max limit of parameters defined by Quarkus that is 1000.
final int PARAMETERS_TO_ADD = 999;
for (int i = 0; i < PARAMETERS_TO_ADD; i++) {
request = request.multiPart("param" + i, "value" + i);
}
// we add the parameter TEXT with formParam so the total parameters will be 1000 + 1 so we are sending 1001
request.formParam(TEXT, TEXT);
request
.post(ROOT_PATH + MULTIPART_FORM_PATH)
.then()
.statusCode(SC_INTERNAL_SERVER_ERROR);
}

@DisplayName("Jakarta REST RouterFilter and Vert.x Web Routes integration")
@Test
public void multipleResponseFilter() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.quarkus.ts.http.advanced;

import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;

import org.jboss.resteasy.annotations.GZIP;

@Path("/gzip")
public class GzipResource {

@POST
public String gzip(@GZIP byte[] message) {
return "OK";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package io.quarkus.ts.http.advanced;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;

import jakarta.ws.rs.core.HttpHeaders;

import org.apache.http.HttpStatus;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import io.quarkus.test.bootstrap.RestService;
import io.quarkus.test.scenarios.QuarkusScenario;
import io.quarkus.test.services.QuarkusApplication;
import io.restassured.response.Response;

@QuarkusScenario
public class GzipMaxInputIT {
jcarranzan marked this conversation as resolved.
Show resolved Hide resolved

final byte[] zero_bytes = new byte[0];
final String invalid_value = "";
final byte[] SMALL_PAYLOAD = new byte[512];
final byte[] LIMIT_PAYLOAD = new byte[100 * 1024 * 1024];
final byte[] OVER_LIMIT_PAYLOAD = new byte[200 * 1024 * 1024];

/**
*
* Tests are checking server response on different size of sent payload
* Limit is configured using quarkus.resteasy.gzip.max-input property
* (According "All configurations options" guide the property 'quarkus.resteasy.gzip.max-input' refers to
* Maximum deflated file bytes size)
* If the limit is exceeded, Resteasy will return a response with status 413("Request Entity Too Large")
*/
@QuarkusApplication(classes = { GzipResource.class }, properties = "gzip.properties")
static RestService app = new RestService();

@Test
void sendInvalidContent() {
Response response = sendStringDataToGzipEndpoint(invalid_value);
assertEquals(HttpStatus.SC_BAD_REQUEST, response.statusCode(),
"Invalid data as this void string should result in 400 BAD_REQUEST response");
}

@Test
void sendZeroBytesPayload() throws IOException {
byte[] compressedData = generateCompressedData(zero_bytes);
Response response = sendDataToGzipEndpoint(compressedData);
assertEquals(HttpStatus.SC_OK, response.statusCode(),
"The response should be 200 OK because the compression returns 2 bytes");
}

@Test
void sendPayloadBelowMaxInputLimit() throws IOException {
byte[] compressedData = generateCompressedData(SMALL_PAYLOAD);
Response response = sendDataToGzipEndpoint(compressedData);
assertEquals(HttpStatus.SC_OK, response.statusCode(),
"The response should be 200 OK because sending just 512 bytes");
}

@Tag("https://github.com/quarkusio/quarkus/issues/39636")
@Test
void sendMaximumAllowedPayload() throws IOException {
byte[] compressedData = generateCompressedData(LIMIT_PAYLOAD);
Response response = sendDataToGzipEndpoint(compressedData);
assertEquals(HttpStatus.SC_OK, response.statusCode(),
"The response should be 200 OK because sending just the limit payload configured using " +
"quarkus.resteasy.gzip.max-input=100M. This fails if the suffix format parsing is not " +
"working and RESTEasy falls back to its default which is 10M");
}

@Test
void sendMoreThanMaximumAllowedPayload() throws IOException {
byte[] compressedData = generateCompressedData(OVER_LIMIT_PAYLOAD);
Response response = sendDataToGzipEndpoint(compressedData);
assertEquals(HttpStatus.SC_REQUEST_TOO_LONG, response.statusCode(),
"The response should be 413 REQUEST_TOO_LONG when sending larger payload than the limit");
}

private Response sendDataToGzipEndpoint(byte[] data) {
return app.given()
.header(HttpHeaders.CONTENT_ENCODING, "gzip")
.body(data)
.when()
.post("/gzip")
.then()
.extract().response();
}

private Response sendStringDataToGzipEndpoint(String data) {
return app.given()
.header("Content-Encoding", "gzip")
.body(data)
.when()
.post("/gzip")
.then()
.extract().response();
}

public byte[] generateCompressedData(byte[] data) throws IOException {
byte[] result;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzipOut = new GZIPOutputStream(baos)) {
gzipOut.write(data);
gzipOut.close();
result = baos.toByteArray();
}
return result;
}

}
4 changes: 4 additions & 0 deletions http/http-advanced/src/test/resources/gzip.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
quarkus.oidc.enabled=false
#Gzip
quarkus.resteasy.gzip.enabled=true
quarkus.resteasy.gzip.max-input=100M
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.quarkus.ts.quarkus.cli;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

import jakarta.inject.Inject;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import io.quarkus.test.bootstrap.QuarkusCliClient;
import io.quarkus.test.bootstrap.QuarkusCliRestService;
import io.quarkus.test.scenarios.QuarkusScenario;

@QuarkusScenario
public class QuarkusCliPomIntegrityIT {
/*
* This scenario is related to the backport https://github.com/quarkusio/quarkus/issues/39088
*
*/
private static final String NEW_EXTENSION = "quarkus-kafka-client";
private static final String COMMENT = "<!-- Disable native build on this module -->";

private static final String APP_NAME = "my-quarkus-app";

@Inject
static QuarkusCliClient cliClient;

@Test
public void shouldKeepCommentInPomAfterAddAndRemoveExtension() throws IOException {
final Path POM_PATH = Paths.get("target", QuarkusCliPomIntegrityIT.class.getSimpleName(), APP_NAME, "pom.xml");
michalvavrik marked this conversation as resolved.
Show resolved Hide resolved
QuarkusCliRestService app = cliClient.createApplication("my-quarkus-app",
michalvavrik marked this conversation as resolved.
Show resolved Hide resolved
QuarkusCliClient.CreateApplicationRequest.defaults());

List<String> initialPomContent = Files.readAllLines(POM_PATH);
initialPomContent.add(1, COMMENT);
michalvavrik marked this conversation as resolved.
Show resolved Hide resolved

// Add extension
app.installExtension(NEW_EXTENSION);
List<String> updatedPomContent = Files.readAllLines(POM_PATH);
Assertions.assertTrue(updatedPomContent.contains(COMMENT), "The comment after add extension still should be there");

// Remove extension
app.removeExtension(NEW_EXTENSION);
List<String> finalPomContent = Files.readAllLines(POM_PATH);
Assertions.assertTrue(finalPomContent.contains(COMMENT), "The comment after remove extension still should be there");
}
}
Loading