Skip to content

Commit

Permalink
Redesign of compatibility integration tests for greater flexibility a…
Browse files Browse the repository at this point in the history
…nd extensibility; added classic i/o and TLS compatibility tests
  • Loading branch information
ok2c committed Oct 20, 2024
1 parent b525b94 commit 1ed6e17
Show file tree
Hide file tree
Showing 25 changed files with 1,679 additions and 244 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ maven-eclipse.xml
*.iml
**/log4j2-debug.xml
**/.checkstyle
/test-CA/newcerts/
/test-CA/serial.txt*
/test-CA/index.txt*
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/

package org.apache.hc.core5.testing.compatibility;

import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.testing.compatibility.classic.ClassicHttpCompatTest;
import org.apache.hc.core5.testing.compatibility.nio.AsyncHttp1CompatTest;
import org.apache.hc.core5.testing.compatibility.nio.AsyncHttp2CompatTest;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers(disabledWithoutDocker = true)
class ApacheHttpDCompatIT {

private static Network NETWORK = Network.newNetwork();
@Container
static final GenericContainer<?> HTTPD_CONTAINER = ContainerImages.apacheHttpD(NETWORK);

@AfterAll
static void cleanup() {
HTTPD_CONTAINER.close();
}

static HttpHost targetContainerHost() {
return new HttpHost(URIScheme.HTTP.id, HTTPD_CONTAINER.getHost(), HTTPD_CONTAINER.getMappedPort(ContainerImages.HTTP_PORT));
}

static HttpHost targetContainerH2CHost() {
return new HttpHost(URIScheme.HTTP.id, HTTPD_CONTAINER.getHost(), HTTPD_CONTAINER.getMappedPort(ContainerImages.H2C_PORT));
}

static HttpHost targetContainerTLSHost() {
return new HttpHost(URIScheme.HTTPS.id, HTTPD_CONTAINER.getHost(), HTTPD_CONTAINER.getMappedPort(ContainerImages.HTTPS_PORT));
}

@Nested
@DisplayName("Classic, HTTP/1, plain")
class ClassicHttp1 extends ClassicHttpCompatTest {

public ClassicHttp1() throws Exception {
super(targetContainerHost());
}

}

@Nested
@DisplayName("Classic, HTTP/1, TLS")
class ClassicHttp1Tls extends ClassicHttpCompatTest {

public ClassicHttp1Tls() throws Exception {
super(targetContainerTLSHost());
}

}

@Nested
@DisplayName("Async, HTTP/1, plain")
class AsyncHttp1 extends AsyncHttp1CompatTest {

public AsyncHttp1() throws Exception {
super(targetContainerHost());
}

}

@Nested
@DisplayName("Async, HTTP/2, plain")
class AsyncHttp2 extends AsyncHttp2CompatTest {

public AsyncHttp2() throws Exception {
super(targetContainerH2CHost(), HttpVersionPolicy.FORCE_HTTP_2);
}

}

@Nested
@DisplayName("Async, HTTP/1, TLS")
class AsyncHttp1Tls extends AsyncHttp1CompatTest {

public AsyncHttp1Tls() throws Exception {
super(targetContainerTLSHost());
}

}

@Nested
@DisplayName("Async, protocol HTTP/2, TLS")
class AsyncHttp2Tls extends AsyncHttp2CompatTest {

public AsyncHttp2Tls() throws Exception {
super(targetContainerTLSHost(), HttpVersionPolicy.FORCE_HTTP_2);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,69 +26,110 @@
*/
package org.apache.hc.core5.testing.compatibility;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.utility.DockerImageName;

public final class ContainerImages {

private static final Logger LOG = LoggerFactory.getLogger(ContainerImages.class);

public static final String AAA = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
public static final String BBB = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
public static final String CCC = "ccccccccccccccccccccccccccccccccccccccccccccccccc";
public static final String PUSHY = "I am being very pushy";

public static final String APACHE_HTTPD = "test-apache";
public static final String NGINX = "test-nginx";
public static final String HTTPBIN = "test-httpbin";

public static int HTTP_PORT = 80;
public static int H2C_PORT = 81;
public static int HTTPS_PORT = 443;

public static GenericContainer<?> httpBin() {
public static GenericContainer<?> httpBin(final Network network) {
return new GenericContainer<>(DockerImageName.parse("kennethreitz/httpbin:latest"))
.withNetwork(network)
.withNetworkAliases(HTTPBIN)
.withLogConsumer(new Slf4jLogConsumer(LOG))
.withExposedPorts(HTTP_PORT);
}

public static GenericContainer<?> apacheHttpD() {
public static GenericContainer<?> apacheHttpD(final Network network) {
return new GenericContainer<>(new ImageFromDockerfile()
.withFileFromClasspath("httpd-vhosts.conf", "docker/httpd/httpd-vhosts.conf")
.withFileFromClasspath("httpd-default.conf", "docker/httpd/httpd-default.conf")
.withFileFromClasspath("httpd-h2c.conf", "docker/httpd/httpd-h2c.conf")
.withFileFromClasspath("httpd-ssl.conf", "docker/httpd/httpd-ssl.conf")
.withFileFromClasspath("server-cert.pem", "docker/server-cert.pem")
.withFileFromClasspath("server-key.pem", "docker/server-key.pem")
.withFileFromString("pushy", PUSHY)
.withFileFromString("aaa", AAA)
.withFileFromString("bbb", BBB)
.withFileFromString("ccc", CCC)
.withDockerfileFromBuilder(builder ->
builder
.from("httpd:2.4")
.env("var_dir", "/var/httpd")
.env("www_dir", "${var_dir}/www")
.run("mkdir -p ${var_dir}")
.run("sed -i -E 's/^\\s*#\\s*(LoadModule\\s+http2_module\\s+modules\\/mod_http2.so)/\\1/' conf/httpd.conf")
.run("sed -i -E 's/^\\s*ServerAdmin.*$/ServerAdmin [email protected]/' conf/httpd.conf")
.run("sed -i -E 's/^\\s*#\\s*(Include\\s+conf\\/extra\\/httpd-vhosts.conf)/\\1/' conf/httpd.conf")
.copy("httpd-vhosts.conf", "/usr/local/apache2/conf/extra/httpd-vhosts.conf")
.copy("pushy", "${www_dir}/")
.copy("aaa", "${www_dir}/")
.copy("bbb", "${www_dir}/")
.copy("ccc", "${www_dir}/")
.build()))
.withExposedPorts(HTTP_PORT);
.withDockerfileFromBuilder(builder -> builder
.from("httpd:2.4")
.env("var_dir", "/var/httpd")
.env("www_dir", "${var_dir}/www")
.run("mkdir -p ${var_dir}")
.run("mkdir -p ${www_dir}")
.run("echo '\\n" +
"LoadModule http2_module modules/mod_http2.so\\n" +
"LoadModule ssl_module modules/mod_ssl.so\\n" +
"Include conf/extra/httpd-default.conf\\n" +
"Include conf/extra/httpd-h2c.conf\\n" +
"Include conf/extra/httpd-ssl.conf\\n" +
"'" +
" >> /usr/local/apache2/conf/httpd.conf")
.copy("httpd-default.conf", "/usr/local/apache2/conf/extra/httpd-default.conf")
.copy("httpd-h2c.conf", "/usr/local/apache2/conf/extra/httpd-h2c.conf")
.copy("httpd-ssl.conf", "/usr/local/apache2/conf/extra/httpd-ssl.conf")
.copy("server-cert.pem", "/usr/local/apache2/conf/server-cert.pem")
.copy("server-key.pem", "/usr/local/apache2/conf/server-key.pem")
.copy("pushy", "${www_dir}/")
.copy("aaa", "${www_dir}/")
.copy("bbb", "${www_dir}/")
.copy("ccc", "${www_dir}/")
.build()))
.withNetwork(network)
.withNetworkAliases(APACHE_HTTPD)
.withLogConsumer(new Slf4jLogConsumer(LOG))
.withExposedPorts(HTTP_PORT, H2C_PORT, HTTPS_PORT);
}

public static GenericContainer<?> ngnix() {
public static GenericContainer<?> nginx(final Network network) {
return new GenericContainer<>(new ImageFromDockerfile()
.withFileFromClasspath("default.conf", "docker/ngnix/default.conf")
.withFileFromClasspath("default.conf", "docker/nginx/default.conf")
.withFileFromClasspath("h2c.conf", "docker/nginx/h2c.conf")
.withFileFromClasspath("ssl.conf", "docker/nginx/ssl.conf")
.withFileFromClasspath("server-cert.pem", "docker/server-cert.pem")
.withFileFromClasspath("server-key.pem", "docker/server-key.pem")
.withFileFromString("pushy", PUSHY)
.withFileFromString("aaa", AAA)
.withFileFromString("bbb", BBB)
.withFileFromString("ccc", CCC)
.withDockerfileFromBuilder(builder ->
builder
.from("nginx:1.22")
.env("var_dir", "/var/nginx")
.env("www_dir", "${var_dir}/www")
.run("mkdir -p ${var_dir}")
.copy("default.conf", "/etc/nginx/conf.d/default.conf")
.copy("pushy", "${www_dir}/")
.copy("aaa", "${www_dir}/")
.copy("bbb", "${www_dir}/")
.copy("ccc", "${www_dir}/")
.build()))
.withExposedPorts(HTTP_PORT);
.withDockerfileFromBuilder(builder -> builder
.from("nginx:1.22")
.env("var_dir", "/var/nginx")
.env("www_dir", "${var_dir}/www")
.run("mkdir -p ${var_dir}")
.copy("default.conf", "/etc/nginx/conf.d/default.conf")
.copy("h2c.conf", "/etc/nginx/conf.d/h2c.conf")
.copy("ssl.conf", "/etc/nginx/conf.d/ssl.conf")
.copy("server-cert.pem", "/etc/nginx/server-cert.pem")
.copy("server-key.pem", "/etc/nginx/server-key.pem")
.copy("pushy", "${www_dir}/")
.copy("aaa", "${www_dir}/")
.copy("bbb", "${www_dir}/")
.copy("ccc", "${www_dir}/")
.build()))
.withNetwork(network)
.withNetworkAliases(NGINX)
.withLogConsumer(new Slf4jLogConsumer(LOG))
.withExposedPorts(HTTP_PORT, H2C_PORT, HTTPS_PORT);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,48 @@
*
*/

package org.apache.hc.core5.testing.compatibility.http2;
package org.apache.hc.core5.testing.compatibility;

import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
import org.apache.hc.core5.testing.compatibility.ContainerImages;
import org.junit.jupiter.api.AfterAll;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.testing.compatibility.classic.HttpBinClassicCompatTest;
import org.apache.hc.core5.testing.compatibility.nio.HttpBinAsyncCompatTest;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers(disabledWithoutDocker = true)
class ApacheHttpDCompatIT extends AbstractHttp2CompatIT {
class HttpBinCompatIT {

private static Network NETWORK = Network.newNetwork();
@Container
static final GenericContainer<?> CONTAINER = ContainerImages.apacheHttpD();
static final GenericContainer<?> HTTP_BIN_CONTAINER = ContainerImages.httpBin(NETWORK);

@Override
void configure(final H2RequesterBootstrap bootstrap) {
static HttpHost targetContainerHost() {
return new HttpHost(URIScheme.HTTP.id, HTTP_BIN_CONTAINER.getHost(), HTTP_BIN_CONTAINER.getMappedPort(ContainerImages.HTTP_PORT));
}

HttpHost targetHost() {
return new HttpHost("http",
CONTAINER.getHost(),
CONTAINER.getMappedPort(ContainerImages.HTTP_PORT));
@Nested
@DisplayName("Classic")
class Classic extends HttpBinClassicCompatTest {

public Classic() throws Exception {
super(targetContainerHost());
}

}

@AfterAll
static void cleanup() {
CONTAINER.close();
@Nested
@DisplayName("Async")
class Async extends HttpBinAsyncCompatTest {

public Async() throws Exception {
super(targetContainerHost());
}

}

}
Loading

0 comments on commit 1ed6e17

Please sign in to comment.