NIFI-11754 Refactored Groovy test in nifi-jetty to Java (and JUnit 5)

This closes #7442

Signed-off-by: David Handermann <exceptionfactory@apache.org>
This commit is contained in:
dan-s1 2023-06-26 22:27:51 +00:00 committed by exceptionfactory
parent b681d5e98d
commit 2a7fa6d17b
No known key found for this signature in database
GPG Key ID: 29B6A52D2AAE8DBA
3 changed files with 161 additions and 281 deletions

View File

@ -223,10 +223,6 @@
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-test</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,277 +0,0 @@
/*
* 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.
*/
package org.apache.nifi.web.server
import org.apache.commons.lang3.StringUtils
import org.apache.nifi.util.NiFiProperties
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.junit.jupiter.api.Assertions.assertTrue
class HostHeaderHandlerTest {
private static final Logger logger = LoggerFactory.getLogger(HostHeaderHandlerTest.class)
private static final String DEFAULT_HOSTNAME = "nifi.apache.org"
private static final String ACTUAL_HOSTNAME = InetAddress.getLocalHost().getHostName().toLowerCase()
private static final int DEFAULT_PORT = 8080
private static final List<String> DEFAULT_HOSTS_1_5_0 = [DEFAULT_HOSTNAME, "localhost", ACTUAL_HOSTNAME]
private static
final List<String> DEFAULT_HOSTS_AND_PORTS_1_5_0 = DEFAULT_HOSTS_1_5_0.collectMany { it -> [it, "${it}:${DEFAULT_PORT}"] }
// Post 1.5.0 list
private static final String ACTUAL_IP = InetAddress.getLocalHost().getHostAddress()
private static final String LOOPBACK_IP = InetAddress.getLoopbackAddress().getHostAddress()
private static
final List<String> DEFAULT_HOSTS = DEFAULT_HOSTS_1_5_0 - DEFAULT_HOSTNAME + ["[::1]", "127.0.0.1", ACTUAL_IP, LOOPBACK_IP]
private static
final List<String> DEFAULT_HOSTS_AND_PORTS = DEFAULT_HOSTS.collectMany { it -> [it, "${it}:${DEFAULT_PORT}"] }
@BeforeAll
static void setUpOnce() throws Exception {
logger.metaClass.methodMissing = { String name, args ->
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
}
}
@Test
void testConstructorShouldAcceptSingleValues() throws Exception {
// Arrange
String hostname = DEFAULT_HOSTNAME
int port = DEFAULT_PORT
logger.info("Hostname: ${hostname} | port: ${port}")
// Act
HostHeaderHandler handler = new HostHeaderHandler(hostname, port)
logger.info("Handler: ${handler}")
// Assert
assertTrue(handler.hostHeaderIsValid(hostname))
assertTrue(handler.hostHeaderIsValid("${hostname}:${port}"))
}
/**
* The feature was introduced in Apache NiFi 1.5.0 but the behavior was changed following that release to include the actual IP address of the server, IPv6 ::1, and 127.0.0.1.
* @throws Exception
*/
@Test
void testShouldHandle_1_5_0_DefaultValues() throws Exception {
// Arrange
String hostname = DEFAULT_HOSTNAME
int port = DEFAULT_PORT
logger.info("Hostname: ${hostname} | port: ${port}")
// Act
HostHeaderHandler handler = new HostHeaderHandler(hostname, port)
logger.info("Handler: ${handler}")
// Assert
DEFAULT_HOSTS_AND_PORTS_1_5_0.each { String host ->
logger.debug("Validating ${host}")
assertTrue(handler.hostHeaderIsValid(host))
}
}
@Test
void testNewConstructorShouldHandleCurrentDefaultValues() throws Exception {
// Arrange
String hostname = DEFAULT_HOSTNAME
int port = DEFAULT_PORT
logger.info("Hostname: ${hostname} | port: ${port}")
Properties rawProps = new Properties()
rawProps.putAll([
(NiFiProperties.WEB_HTTPS_HOST): DEFAULT_HOSTNAME,
(NiFiProperties.WEB_HTTPS_PORT): "${DEFAULT_PORT}".toString(),
])
NiFiProperties simpleProperties = new NiFiProperties(rawProps)
// Act
HostHeaderHandler handler = new HostHeaderHandler(simpleProperties)
logger.info("Handler: ${handler}")
// Assert
DEFAULT_HOSTS_AND_PORTS.each { String host ->
logger.debug("Validating ${host}")
assertTrue(handler.hostHeaderIsValid(host))
}
}
@Test
void testShouldParseCustomHostnames() throws Exception {
// Arrange
String hostname = DEFAULT_HOSTNAME
int port = DEFAULT_PORT
logger.info("Hostname: ${hostname} | port: ${port}")
List<String> otherHosts = ["someotherhost.com:9999", "yetanotherbadhost.com", "10.10.10.1:1234", "100.100.100.1"]
String concatenatedHosts = otherHosts.join(",")
Properties rawProps = new Properties()
rawProps.putAll([
(NiFiProperties.WEB_HTTPS_HOST): DEFAULT_HOSTNAME,
(NiFiProperties.WEB_HTTPS_PORT): "${DEFAULT_PORT}".toString(),
(NiFiProperties.WEB_PROXY_HOST): concatenatedHosts
])
NiFiProperties simpleProperties = new NiFiProperties(rawProps)
HostHeaderHandler handler = new HostHeaderHandler(simpleProperties)
logger.info("Handler: ${handler}")
// Act
List<String> customHostnames = handler.parseCustomHostnames(simpleProperties)
logger.info("Parsed custom hostnames: ${customHostnames}")
// Assert
assertEquals(otherHosts.size() + 2, customHostnames.size()) // Two provided hostnames had ports
otherHosts.each { String host ->
logger.debug("Checking ${host}")
assertTrue(customHostnames.contains(host))
String portlessHost = "${host.split(":", 2)[0]}".toString()
logger.debug("Checking ${portlessHost}")
assertTrue(customHostnames.contains(portlessHost))
}
}
@Test
void testParseCustomHostnamesShouldHandleIPv6WithoutPorts() throws Exception {
// Arrange
String hostname = DEFAULT_HOSTNAME
int port = DEFAULT_PORT
logger.info("Hostname: ${hostname} | port: ${port}")
List<String> ipv6Hosts = ["ABCD:EF01:2345:6789:ABCD:EF01:2345:6789",
"2001:DB8:0:0:8:800:200C:417A",
"FF01:0:0:0:0:0:0:101",
"0:0:0:0:0:0:0:1",
"0:0:0:0:0:0:0:0",
"2001:DB8::8:800:200C:417A",
"FF01::101",
"::1",
"::",
"0:0:0:0:0:0:13.1.68.3",
"0:0:0:0:0:FFFF:129.144.52.38",
"::13.1.68.3",
"FFFF:129.144.52.38",
"::FFFF:129.144.52.38"]
String concatenatedHosts = ipv6Hosts.join(",")
Properties rawProps = new Properties()
rawProps.putAll([
(NiFiProperties.WEB_HTTPS_HOST): DEFAULT_HOSTNAME,
(NiFiProperties.WEB_HTTPS_PORT): "${DEFAULT_PORT}".toString(),
(NiFiProperties.WEB_PROXY_HOST): concatenatedHosts
])
NiFiProperties simpleProperties = new NiFiProperties(rawProps)
HostHeaderHandler handler = new HostHeaderHandler(simpleProperties)
logger.info("Handler: ${handler}")
// Act
List<String> customHostnames = handler.parseCustomHostnames(simpleProperties)
logger.info("Parsed custom hostnames: ${customHostnames}")
// Assert
assertEquals(ipv6Hosts.size(), customHostnames.size())
ipv6Hosts.each { String host ->
logger.debug("Checking ${host}")
assertTrue(customHostnames.contains(host))
}
}
@Test
void testParseCustomHostnamesShouldHandleIPv6WithPorts() throws Exception {
// Arrange
String hostname = DEFAULT_HOSTNAME
int port = DEFAULT_PORT
logger.info("Hostname: ${hostname} | port: ${port}")
List<String> ipv6Hosts = ["[ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]:1234",
"[2001:DB8:0:0:8:800:200C:417A]:1234",
"[FF01:0:0:0:0:0:0:101]:1234",
"[0:0:0:0:0:0:0:1]:1234",
"[0:0:0:0:0:0:0:0]:1234",
"[2001:DB8::8:800:200C:417A]:1234",
"[FF01::101]:1234",
"[::1]:1234",
"[::]:1234",
"[0:0:0:0:0:0:13.1.68.3]:1234",
"[0:0:0:0:0:FFFF:129.144.52.38]:1234",
"[::13.1.68.3]:1234",
"[FFFF:129.144.52.38]:1234",
"[::FFFF:129.144.52.38]:1234"]
String concatenatedHosts = ipv6Hosts.join(",")
Properties rawProps = new Properties()
rawProps.putAll([
(NiFiProperties.WEB_HTTPS_HOST): DEFAULT_HOSTNAME,
(NiFiProperties.WEB_HTTPS_PORT): "${DEFAULT_PORT}".toString(),
(NiFiProperties.WEB_PROXY_HOST): concatenatedHosts
])
NiFiProperties simpleProperties = new NiFiProperties(rawProps)
HostHeaderHandler handler = new HostHeaderHandler(simpleProperties)
logger.info("Handler: ${handler}")
// Act
List<String> customHostnames = handler.parseCustomHostnames(simpleProperties)
logger.info("Parsed custom hostnames: ${customHostnames}")
// Assert
assertEquals(ipv6Hosts.size() * 2, customHostnames.size())
ipv6Hosts.each { String host ->
logger.debug("Checking ${host}")
assertTrue(customHostnames.contains(host))
String portlessHost = "${StringUtils.substringBeforeLast(host, ":")}".toString()
logger.debug("Checking ${portlessHost}")
assertTrue(customHostnames.contains(portlessHost))
}
}
@Test
void testShouldIdentifyIPv6Addresses() throws Exception {
// Arrange
List<String> ipv6Hosts = ["ABCD:EF01:2345:6789:ABCD:EF01:2345:6789",
"2001:DB8:0:0:8:800:200C:417A",
"FF01:0:0:0:0:0:0:101",
"0:0:0:0:0:0:0:1",
"0:0:0:0:0:0:0:0",
"2001:DB8::8:800:200C:417A",
"FF01::101",
"::1",
"::",
"0:0:0:0:0:0:13.1.68.3",
"0:0:0:0:0:FFFF:129.144.52.38",
"::13.1.68.3",
"FFFF:129.144.52.38",
"::FFFF:129.144.52.38"]
// Act
List<Boolean> hostsAreIPv6 = ipv6Hosts.collect { String host ->
boolean isIPv6 = HostHeaderHandler.isIPv6Address(host)
logger.info("Hostname is IPv6: ${host} | ${isIPv6}")
isIPv6
}
// Assert
hostsAreIPv6.forEach(hostIsIPv6 -> assertTrue(hostIsIPv6))
}
}

View File

@ -0,0 +1,161 @@
/*
* 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.
*/
package org.apache.nifi.web.server;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.util.NiFiProperties;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class HostHeaderHandlerTest {
private static final String DEFAULT_HOSTNAME = "nifi.apache.org";
private static final int DEFAULT_PORT = 8080;
private static final List<String> IPV6_HOSTS = Arrays.asList("ABCD:EF01:2345:6789:ABCD:EF01:2345:6789",
"2001:DB8:0:0:8:800:200C:417A",
"FF01:0:0:0:0:0:0:101",
"0:0:0:0:0:0:0:1",
"0:0:0:0:0:0:0:0",
"2001:DB8::8:800:200C:417A",
"FF01::101",
"::1",
"::",
"0:0:0:0:0:0:13.1.68.3",
"0:0:0:0:0:FFFF:129.144.52.38",
"::13.1.68.3",
"FFFF:129.144.52.38",
"::FFFF:129.144.52.38");
private static List<String> defaultHostsAndPorts150;
private static List<String> defaultHostsAndPorts;
@BeforeAll
public static void setUpOnce() throws Exception {
String actualHostname = InetAddress.getLocalHost().getHostName().toLowerCase();
List<String> defaultHosts150 = Arrays.asList(DEFAULT_HOSTNAME, "localhost", actualHostname);
defaultHostsAndPorts150 = buildHostsWithPorts(defaultHosts150, DEFAULT_PORT);
String actualIp = InetAddress.getLocalHost().getHostAddress();
String loopbackIp = InetAddress.getLoopbackAddress().getHostAddress();
List<String> defaultHosts = new ArrayList<>(defaultHosts150);
defaultHosts.remove(DEFAULT_HOSTNAME);
defaultHosts.addAll(Arrays.asList("[::1]", "127.0.0.1", actualIp, loopbackIp));
defaultHostsAndPorts = buildHostsWithPorts(defaultHosts, DEFAULT_PORT);
}
@SuppressWarnings("deprecation")
@Test
public void testConstructorShouldAcceptSingleValues() {
HostHeaderHandler handler = new HostHeaderHandler(DEFAULT_HOSTNAME, DEFAULT_PORT);
assertTrue(handler.hostHeaderIsValid(DEFAULT_HOSTNAME));
assertTrue(handler.hostHeaderIsValid(DEFAULT_HOSTNAME + ":" + DEFAULT_PORT));
}
/**
* The feature was introduced in Apache NiFi 1.5.0 but the behavior was changed following that release to include the actual IP address of the server, IPv6 ::1, and 127.0.0.1.
*/
@SuppressWarnings("deprecation")
@Test
public void testShouldHandle_1_5_0_DefaultValues() {
HostHeaderHandler handler = new HostHeaderHandler(DEFAULT_HOSTNAME, DEFAULT_PORT);
defaultHostsAndPorts150.forEach(host -> assertTrue(handler.hostHeaderIsValid(host)));
}
@Test
public void testNewConstructorShouldHandleCurrentDefaultValues() {
HostHeaderHandler handler = new HostHeaderHandler(getNifiProperties(null));
defaultHostsAndPorts.forEach(host -> assertTrue(handler.hostHeaderIsValid(host)));
}
@Test
public void testShouldParseCustomHostnames() {
List<String> otherHosts = Arrays.asList("someotherhost.com:9999", "yetanotherbadhost.com", "10.10.10.1:1234", "100.100.100.1");
NiFiProperties nifiProperties = getNifiProperties(otherHosts);
HostHeaderHandler handler = new HostHeaderHandler(nifiProperties);
final List<String> customHostnames = handler.parseCustomHostnames(nifiProperties);
assertEquals(otherHosts.size() + 2, customHostnames.size()); // Two provided hostnames had ports
otherHosts.forEach(host -> {
assertTrue(customHostnames.contains(host));
String portlessHost = host.split(":", 2)[0];
assertTrue(customHostnames.contains(portlessHost));
});
}
@Test
public void testParseCustomHostnamesShouldHandleIPv6WithoutPorts() {
NiFiProperties nifiProperties = getNifiProperties(IPV6_HOSTS);
HostHeaderHandler handler = new HostHeaderHandler(nifiProperties);
List<String> customHostnames = handler.parseCustomHostnames(nifiProperties);
assertEquals(IPV6_HOSTS.size(), customHostnames.size());
IPV6_HOSTS.forEach(host -> assertTrue(customHostnames.contains(host)));
}
@Test
public void testParseCustomHostnamesShouldHandleIPv6WithPorts() {
int port = 1234;
List<String> ipv6HostsWithPorts = buildHostsWithPorts(IPV6_HOSTS.stream()
.map(host -> "[" + host + "]")
.collect(Collectors.toList()), port);
NiFiProperties nifiProperties = getNifiProperties(ipv6HostsWithPorts);
HostHeaderHandler handler = new HostHeaderHandler(nifiProperties);
List<String> customHostnames = handler.parseCustomHostnames(nifiProperties);
assertEquals(ipv6HostsWithPorts.size() * 2, customHostnames.size());
ipv6HostsWithPorts.forEach(host -> {
assertTrue(customHostnames.contains(host));
String portlessHost = StringUtils.substringBeforeLast(host, ":");
assertTrue(customHostnames.contains(portlessHost));
}
);
}
@Test
public void testShouldIdentifyIPv6Addresses() {
IPV6_HOSTS.forEach(host -> assertTrue(HostHeaderHandler.isIPv6Address(host)));
}
private static List<String> buildHostsWithPorts(List<String> hosts, int port) {
return hosts.stream()
.map(host -> host + ":" + port)
.collect(Collectors.toList());
}
private NiFiProperties getNifiProperties(List<String> hosts) {
Properties bareboneProperties = new Properties();
bareboneProperties.put(NiFiProperties.WEB_HTTPS_HOST, DEFAULT_HOSTNAME);
bareboneProperties.put(NiFiProperties.WEB_HTTPS_PORT, Integer.toString(DEFAULT_PORT));
if(hosts != null) {
bareboneProperties.put(NiFiProperties.WEB_PROXY_HOST, String.join(",", hosts));
}
return new NiFiProperties(bareboneProperties);
}
}