jdk-24/test/jdk/com/sun/net/httpserver/simpleserver/IdempotencyAndCommutativityTest.java
Julia Boes 9d191fce55 8245095: Implementation of JEP 408: Simple Web Server
Co-authored-by: Julia Boes <jboes@openjdk.org>
Co-authored-by: Chris Hegarty <chegar@openjdk.org>
Co-authored-by: Michael McMahon <michaelm@openjdk.org>
Co-authored-by: Daniel Fuchs <dfuchs@openjdk.org>
Co-authored-by: Jan Lahoda <jlahoda@openjdk.org>
Co-authored-by: Ivan Šipka <isipka@openjdk.org>
Reviewed-by: ihse, jlaskey, michaelm, chegar, dfuchs
2021-10-19 10:19:15 +00:00

147 lines
6.0 KiB
Java

/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import jdk.test.lib.net.URIBuilder;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.SimpleFileServer;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static java.net.http.HttpClient.Builder.NO_PROXY;
import static java.nio.file.StandardOpenOption.CREATE;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
/*
* @test
* @summary Test idempotency and commutativity of responses with an exhaustive
* set of binary request sequences
* @library /test/lib
* @build jdk.test.lib.net.URIBuilder
* @run testng/othervm IdempotencyAndCommutativityTest
*/
public class IdempotencyAndCommutativityTest {
static final Path CWD = Path.of(".").toAbsolutePath().normalize();
static final InetSocketAddress LOOPBACK_ADDR = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
static final String FILE_NAME = "file.txt";
static final String DIR_NAME = "";
static final String MISSING_FILE_NAME = "doesNotExist";
static HttpServer server;
static HttpClient client;
static final boolean ENABLE_LOGGING = true;
static final Logger LOGGER = Logger.getLogger("com.sun.net.httpserver");
@BeforeTest
public void setup() throws IOException {
if (ENABLE_LOGGING) {
ConsoleHandler ch = new ConsoleHandler();
LOGGER.setLevel(Level.ALL);
ch.setLevel(Level.ALL);
LOGGER.addHandler(ch);
}
Path root = Files.createDirectories(CWD.resolve("testDirectory"));
Files.writeString(root.resolve(FILE_NAME), "some text", CREATE);
client = HttpClient.newBuilder().proxy(NO_PROXY).build();
server = SimpleFileServer.createFileServer(LOOPBACK_ADDR, root, SimpleFileServer.OutputLevel.VERBOSE);
server.start();
}
// Container of expected response state for a given request
record ExchangeValues(String method, String resource, int respCode, String contentType) {}
// Creates an exhaustive set of binary exchange sequences
@DataProvider
public Object[][] allBinarySequences() {
final List<ExchangeValues> sequences = List.of(
new ExchangeValues("GET", FILE_NAME, 200, "text/plain"),
new ExchangeValues("GET", DIR_NAME, 200, "text/html; charset=UTF-8"),
new ExchangeValues("GET", MISSING_FILE_NAME, 404, "text/html; charset=UTF-8"),
new ExchangeValues("HEAD", FILE_NAME, 200, "text/plain"),
new ExchangeValues("HEAD", DIR_NAME, 200, "text/html; charset=UTF-8"),
new ExchangeValues("HEAD", MISSING_FILE_NAME, 404, "text/html; charset=UTF-8"),
new ExchangeValues("UNKNOWN", FILE_NAME, 501, null),
new ExchangeValues("UNKNOWN", DIR_NAME, 501, null),
new ExchangeValues("UNKNOWN", MISSING_FILE_NAME, 501, null)
);
return sequences.stream() // cartesian product
.flatMap(s1 -> sequences.stream().map(s2 -> new ExchangeValues[] { s1, s2 }))
.toArray(Object[][]::new);
}
@Test(dataProvider = "allBinarySequences")
public void testBinarySequences(ExchangeValues e1, ExchangeValues e2) throws Exception {
System.out.println("---");
System.out.println(e1);
executeExchange(e1);
System.out.println(e2);
executeExchange(e2);
}
private static void executeExchange(ExchangeValues e) throws Exception {
var request = HttpRequest.newBuilder(uri(server, e.resource()))
.method(e.method(), HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
assertEquals(response.statusCode(), e.respCode());
if (e.contentType != null) {
assertEquals(response.headers().firstValue("content-type").get(), e.contentType());
} else {
assertTrue(response.headers().firstValue("content-type").isEmpty());
}
}
@AfterTest
public static void teardown() {
server.stop(0);
}
static URI uri(HttpServer server, String path) {
return URIBuilder.newBuilder()
.host("localhost")
.port(server.getAddress().getPort())
.scheme("http")
.path("/" + path)
.buildUnchecked();
}
}