HBASE-23783: Address tests writing and reading SSL/Security files in a common location. (#1116)

This is causing me issues with parallel test runs.

Also allow setting the surefire reports and temp directories via command line.

Signed-off-by: stack <stack@apache.org>
This commit is contained in:
Mark Robert Miller 2020-02-04 16:38:56 -06:00 committed by GitHub
parent 1cacf27d5c
commit 299b6bebc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 103 additions and 88 deletions

View File

@ -24,7 +24,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import org.apache.commons.io.FileUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
@ -155,7 +154,7 @@ public class HBaseCommonTestingUtility {
return new Path(getBaseTestDir(), getRandomUUID().toString());
}
public UUID getRandomUUID() {
public static UUID getRandomUUID() {
return new UUID(ThreadLocalRandom.current().nextLong(),
ThreadLocalRandom.current().nextLong());
}

View File

@ -26,6 +26,7 @@ import javax.net.ssl.HttpsURLConnection;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.http.ssl.KeyStoreTestUtil;
import org.apache.hadoop.hbase.testclassification.MediumTests;
@ -57,44 +58,48 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
"target/test-dir") + "/" + TestSSLHttpServer.class.getSimpleName();
private static final Logger LOG = LoggerFactory.getLogger(TestSSLHttpServer.class);
private static Configuration conf;
private static Configuration serverConf;
private static HttpServer server;
private static URL baseUrl;
private static String keystoresDir;
private static File keystoresDir;
private static String sslConfDir;
private static SSLFactory clientSslFactory;
private static HBaseCommonTestingUtility HTU;
@BeforeClass
public static void setup() throws Exception {
conf = new Configuration();
conf.setInt(HttpServer.HTTP_MAX_THREADS, TestHttpServer.MAX_THREADS);
File base = new File(BASEDIR);
FileUtil.fullyDelete(base);
base.mkdirs();
keystoresDir = new File(BASEDIR).getAbsolutePath();
HTU = new HBaseCommonTestingUtility();
serverConf = HTU.getConfiguration();
serverConf.setInt(HttpServer.HTTP_MAX_THREADS, TestHttpServer.MAX_THREADS);
keystoresDir = new File(HTU.getDataTestDir("keystore").toString());
keystoresDir.mkdirs();
sslConfDir = KeyStoreTestUtil.getClasspathDir(TestSSLHttpServer.class);
KeyStoreTestUtil.setupSSLConfig(keystoresDir, sslConfDir, conf, false);
Configuration sslConf = new Configuration(false);
sslConf.addResource("ssl-server.xml");
sslConf.addResource("ssl-client.xml");
KeyStoreTestUtil.setupSSLConfig(keystoresDir.getAbsolutePath(), sslConfDir, serverConf, false);
Configuration clientConf = new Configuration(false);
clientConf.addResource(serverConf.get(SSLFactory.SSL_CLIENT_CONF_KEY));
serverConf.addResource(serverConf.get(SSLFactory.SSL_SERVER_CONF_KEY));
clientConf.set(SSLFactory.SSL_CLIENT_CONF_KEY, serverConf.get(SSLFactory.SSL_CLIENT_CONF_KEY));
clientSslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, sslConf);
clientSslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, clientConf);
clientSslFactory.init();
server = new HttpServer.Builder()
.setName("test")
.addEndpoint(new URI("https://localhost"))
.setConf(conf)
.keyPassword(HBaseConfiguration.getPassword(sslConf, "ssl.server.keystore.keypassword",
.setConf(serverConf)
.keyPassword(HBaseConfiguration.getPassword(serverConf, "ssl.server.keystore.keypassword",
null))
.keyStore(sslConf.get("ssl.server.keystore.location"),
HBaseConfiguration.getPassword(sslConf, "ssl.server.keystore.password", null),
sslConf.get("ssl.server.keystore.type", "jks"))
.trustStore(sslConf.get("ssl.server.truststore.location"),
HBaseConfiguration.getPassword(sslConf, "ssl.server.truststore.password", null),
sslConf.get("ssl.server.truststore.type", "jks")).build();
.keyStore(serverConf.get("ssl.server.keystore.location"),
HBaseConfiguration.getPassword(serverConf, "ssl.server.keystore.password", null),
clientConf.get("ssl.server.keystore.type", "jks"))
.trustStore(serverConf.get("ssl.server.truststore.location"),
HBaseConfiguration.getPassword(serverConf, "ssl.server.truststore.password", null),
serverConf.get("ssl.server.truststore.type", "jks")).build();
server.addUnprivilegedServlet("echo", "/echo", TestHttpServer.EchoServlet.class);
server.start();
baseUrl = new URL("https://"
@ -105,8 +110,8 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
@AfterClass
public static void cleanup() throws Exception {
server.stop();
FileUtil.fullyDelete(new File(BASEDIR));
KeyStoreTestUtil.cleanupSSLConfig(keystoresDir, sslConfDir);
FileUtil.fullyDelete(new File(HTU.getDataTestDir().toString()));
KeyStoreTestUtil.cleanupSSLConfig(serverConf);
clientSslFactory.destroy();
}

View File

@ -28,6 +28,7 @@ import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosTicket;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
import org.apache.hadoop.hbase.http.TestHttpServer.EchoServlet;
import org.apache.hadoop.hbase.http.resource.JerseyResource;
import org.apache.hadoop.hbase.testclassification.MiscTests;
@ -85,15 +86,14 @@ public class TestSpnegoHttpServer extends HttpServerFunctionalTest {
@BeforeClass
public static void setupServer() throws Exception {
Configuration conf = new Configuration();
HBaseCommonTestingUtility htu = new HBaseCommonTestingUtility(conf);
final String serverPrincipal = "HTTP/" + KDC_SERVER_HOST;
final File target = new File(System.getProperty("user.dir"), "target");
assertTrue(target.exists());
kdc = buildMiniKdc();
kdc.start();
File keytabDir = new File(target, TestSpnegoHttpServer.class.getSimpleName()
+ "_keytabs");
File keytabDir = new File(htu.getDataTestDir("keytabs").toString());
if (keytabDir.exists()) {
deleteRecursively(keytabDir);
}
@ -105,7 +105,7 @@ public class TestSpnegoHttpServer extends HttpServerFunctionalTest {
setupUser(kdc, clientKeytab, CLIENT_PRINCIPAL);
setupUser(kdc, infoServerKeytab, serverPrincipal);
Configuration conf = buildSpnegoConfiguration(serverPrincipal, infoServerKeytab);
buildSpnegoConfiguration(conf, serverPrincipal, infoServerKeytab);
server = createTestServerWithSecurity(conf);
server.addUnprivilegedServlet("echo", "/echo", EchoServlet.class);
@ -164,9 +164,8 @@ public class TestSpnegoHttpServer extends HttpServerFunctionalTest {
return kdc;
}
private static Configuration buildSpnegoConfiguration(String serverPrincipal, File
serverKeytab) {
Configuration conf = new Configuration();
private static Configuration buildSpnegoConfiguration(Configuration conf, String serverPrincipal,
File serverKeytab) {
KerberosName.setRules("DEFAULT");
conf.setInt(HttpServer.HTTP_MAX_THREADS, TestHttpServer.MAX_THREADS);

View File

@ -22,7 +22,6 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.net.BindException;
import java.net.SocketException;
@ -30,7 +29,6 @@ import java.net.URI;
import java.security.PrivilegedExceptionAction;
import java.util.Properties;
import javax.net.ssl.SSLException;
import org.apache.commons.io.FileUtils;
import org.apache.hadoop.HadoopIllegalArgumentException;
import org.apache.hadoop.conf.Configuration;
@ -56,7 +54,6 @@ import org.apache.hadoop.util.StringUtils;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
@ -72,7 +69,6 @@ public class TestLogLevel {
public static final HBaseClassTestRule CLASS_RULE =
HBaseClassTestRule.forClass(TestLogLevel.class);
private static File BASEDIR;
private static String keystoresDir;
private static String sslConfDir;
private static Configuration serverConf;
@ -84,31 +80,29 @@ public class TestLogLevel {
private final static String KEYTAB = "loglevel.keytab";
private static MiniKdc kdc;
private static HBaseCommonTestingUtility htu = new HBaseCommonTestingUtility();
private static final String LOCALHOST = "localhost";
private static final String clientPrincipal = "client/" + LOCALHOST;
private static String HTTP_PRINCIPAL = "HTTP/" + LOCALHOST;
private static final File KEYTAB_FILE = new File(
htu.getDataTestDir("keytab").toUri().getPath());
private static HBaseCommonTestingUtility HTU;
private static File keyTabFile;
@BeforeClass
public static void setUp() throws Exception {
BASEDIR = new File(htu.getDataTestDir().toUri().getPath());
FileUtil.fullyDelete(BASEDIR);
if (!BASEDIR.mkdirs()) {
throw new Exception("unable to create the base directory for testing");
}
serverConf = new Configuration();
HTU = new HBaseCommonTestingUtility(serverConf);
File keystoreDir = new File(HTU.getDataTestDir("keystore").toString());
keystoreDir.mkdirs();
keyTabFile = new File(HTU.getDataTestDir("keytab").toString(), "keytabfile");
keyTabFile.getParentFile().mkdirs();
clientConf = new Configuration();
setupSSL(BASEDIR);
setupSSL(keystoreDir);
kdc = setupMiniKdc();
// Create two principles: a client and an HTTP principal
kdc.createPrincipal(KEYTAB_FILE, clientPrincipal, HTTP_PRINCIPAL);
kdc.createPrincipal(keyTabFile, clientPrincipal, HTTP_PRINCIPAL);
}
/**
@ -127,7 +121,7 @@ public class TestLogLevel {
do {
try {
bindException = false;
dir = new File(htu.getDataTestDir("kdc").toUri().getPath());
dir = new File(HTU.getDataTestDir("kdc").toUri().getPath());
kdc = new MiniKdc(conf, dir);
kdc.start();
} catch (BindException e) {
@ -145,27 +139,27 @@ public class TestLogLevel {
}
static private void setupSSL(File base) throws Exception {
Configuration conf = new Configuration();
conf.set(DFSConfigKeys.DFS_HTTP_POLICY_KEY, HttpConfig.Policy.HTTPS_ONLY.name());
conf.set(DFSConfigKeys.DFS_NAMENODE_HTTPS_ADDRESS_KEY, "localhost:0");
conf.set(DFSConfigKeys.DFS_DATANODE_HTTPS_ADDRESS_KEY, "localhost:0");
clientConf.set(DFSConfigKeys.DFS_HTTP_POLICY_KEY, HttpConfig.Policy.HTTPS_ONLY.name());
clientConf.set(DFSConfigKeys.DFS_NAMENODE_HTTPS_ADDRESS_KEY, "localhost:0");
clientConf.set(DFSConfigKeys.DFS_DATANODE_HTTPS_ADDRESS_KEY, "localhost:0");
keystoresDir = base.getAbsolutePath();
sslConfDir = KeyStoreTestUtil.getClasspathDir(TestLogLevel.class);
KeyStoreTestUtil.setupSSLConfig(keystoresDir, sslConfDir, conf, false);
KeyStoreTestUtil.setupSSLConfig(keystoresDir, sslConfDir, serverConf, false);
sslConf = getSslConfig();
sslConf = getSslConfig(serverConf);
}
/**
* Get the SSL configuration.
* This method is copied from KeyStoreTestUtil#getSslConfig() in Hadoop.
* @return {@link Configuration} instance with ssl configs loaded.
* @param conf to pull client/server SSL settings filename from
*/
private static Configuration getSslConfig(){
private static Configuration getSslConfig(Configuration conf){
Configuration sslConf = new Configuration(false);
String sslServerConfFile = "ssl-server.xml";
String sslClientConfFile = "ssl-client.xml";
String sslServerConfFile = conf.get(SSLFactory.SSL_SERVER_CONF_KEY);
String sslClientConfFile = conf.get(SSLFactory.SSL_CLIENT_CONF_KEY);
sslConf.addResource(sslServerConfFile);
sslConf.addResource(sslClientConfFile);
sslConf.set(SSLFactory.SSL_SERVER_CONF_KEY, sslServerConfFile);
@ -179,7 +173,7 @@ public class TestLogLevel {
kdc.stop();
}
FileUtil.fullyDelete(BASEDIR);
FileUtil.fullyDelete(new File(HTU.getDataTestDir().toString()));
}
/**
@ -309,7 +303,7 @@ public class TestLogLevel {
// configs needed for SPNEGO at server side
if (isSpnego) {
serverConf.set(PRINCIPAL, HTTP_PRINCIPAL);
serverConf.set(KEYTAB, KEYTAB_FILE.getAbsolutePath());
serverConf.set(KEYTAB, keyTabFile.getAbsolutePath());
serverConf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, "kerberos");
serverConf.setBoolean(CommonConfigurationKeys.HADOOP_SECURITY_AUTHORIZATION, true);
UserGroupInformation.setConfiguration(serverConf);
@ -323,7 +317,7 @@ public class TestLogLevel {
// get server port
final String authority = NetUtils.getHostPortString(server.getConnectorAddress(0));
String keytabFilePath = KEYTAB_FILE.getAbsolutePath();
String keytabFilePath = keyTabFile.getAbsolutePath();
UserGroupInformation clientUGI = UserGroupInformation.
loginUserFromKeytabAndReturnUGI(clientPrincipal, keytabFilePath);
@ -353,7 +347,7 @@ public class TestLogLevel {
*/
private void getLevel(String protocol, String authority) throws Exception {
String[] getLevelArgs = {"-getlevel", authority, logName, "-protocol", protocol};
CLI cli = new CLI(clientConf);
CLI cli = new CLI(protocol.equalsIgnoreCase("https") ? sslConf : clientConf);
cli.run(getLevelArgs);
}
@ -368,7 +362,7 @@ public class TestLogLevel {
private void setLevel(String protocol, String authority, String newLevel)
throws Exception {
String[] setLevelArgs = {"-setlevel", authority, logName, newLevel, "-protocol", protocol};
CLI cli = new CLI(clientConf);
CLI cli = new CLI(protocol.equalsIgnoreCase("https") ? sslConf : clientConf);
cli.run(setLevelArgs);
assertEquals("new level not equal to expected: ", newLevel.toUpperCase(),

View File

@ -41,10 +41,9 @@ import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.x500.X500Principal;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
import org.apache.hadoop.security.ssl.FileBasedKeyStoresFactory;
import org.apache.hadoop.security.ssl.SSLFactory;
import org.bouncycastle.x509.X509V1CertificateGenerator;
@ -169,17 +168,27 @@ public final class KeyStoreTestUtil {
saveKeyStore(ks, filename, password);
}
public static void cleanupSSLConfig(String keystoresDir, String sslConfDir)
public static void cleanupSSLConfig(Configuration conf)
throws Exception {
File f = new File(keystoresDir + "/clientKS.jks");
File f = new File(conf.get(FileBasedKeyStoresFactory.resolvePropertyName(SSLFactory.Mode.SERVER,
FileBasedKeyStoresFactory.SSL_TRUSTSTORE_LOCATION_TPL_KEY)));
f.delete();
f = new File(keystoresDir + "/serverKS.jks");
f = new File(conf.get(FileBasedKeyStoresFactory.resolvePropertyName(SSLFactory.Mode.SERVER,
FileBasedKeyStoresFactory.SSL_KEYSTORE_LOCATION_TPL_KEY)));
f.delete();
f = new File(keystoresDir + "/trustKS.jks");
String clientKeyStore = conf.get(FileBasedKeyStoresFactory
.resolvePropertyName(SSLFactory.Mode.CLIENT,
FileBasedKeyStoresFactory.SSL_KEYSTORE_LOCATION_TPL_KEY));
if (clientKeyStore != null) {
f = new File(clientKeyStore);
f.delete();
f = new File(sslConfDir + "/ssl-client.xml");
}
f = new File(KeyStoreTestUtil.getClasspathDir(KeyStoreTestUtil.class) + "/" + conf
.get(SSLFactory.SSL_CLIENT_CONF_KEY));
f.delete();
f = new File(sslConfDir + "/ssl-server.xml");
f = new File(KeyStoreTestUtil.getClasspathDir(KeyStoreTestUtil.class) + "/" + conf
.get(SSLFactory.SSL_SERVER_CONF_KEY));
f.delete();
}
@ -206,8 +215,12 @@ public final class KeyStoreTestUtil {
String trustKS = keystoresDir + "/trustKS.jks";
String trustPassword = "trustP";
File sslClientConfFile = new File(sslConfDir + "/ssl-client.xml");
File sslServerConfFile = new File(sslConfDir + "/ssl-server.xml");
File sslClientConfFile = new File(
sslConfDir + "/ssl-client-" + System.nanoTime() + "-" + HBaseCommonTestingUtility
.getRandomUUID() + ".xml");
File sslServerConfFile = new File(
sslConfDir + "/ssl-server-" + System.nanoTime() + "-" + HBaseCommonTestingUtility
.getRandomUUID() + ".xml");
Map<String, X509Certificate> certs = new HashMap<>();
@ -242,6 +255,9 @@ public final class KeyStoreTestUtil {
conf.set(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY, "ALLOW_ALL");
conf.set(SSLFactory.SSL_CLIENT_CONF_KEY, sslClientConfFile.getName());
conf.set(SSLFactory.SSL_SERVER_CONF_KEY, sslServerConfFile.getName());
conf.set("dfs.https.server.keystore.resource", sslServerConfFile.getName());
conf.setBoolean(SSLFactory.SSL_REQUIRE_CLIENT_CERT_KEY, useClientCert);
}

View File

@ -24,7 +24,6 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.File;
import java.util.List;
import java.util.Random;
@ -42,6 +41,7 @@ import org.apache.hadoop.hbase.testclassification.MiscTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.security.ssl.SSLFactory;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@ -75,7 +75,7 @@ public class TestHBaseTestingUtility {
* Basic sanity test that spins up multiple HDFS and HBase clusters that share
* the same ZK ensemble. We then create the same table in both and make sure
* that what we insert in one place doesn't end up in the other.
* @throws Exception
* @throws Exception on error
*/
@Test
public void testMultiClusters() throws Exception {
@ -177,8 +177,8 @@ public class TestHBaseTestingUtility {
KeyStoreTestUtil.setupSSLConfig(keystoresDir, sslConfDir, hbt.getConfiguration(), false);
hbt.getConfiguration().set("hbase.ssl.enabled", "true");
hbt.getConfiguration().addResource("ssl-server.xml");
hbt.getConfiguration().addResource("ssl-client.xml");
hbt.getConfiguration().addResource(hbt.getConfiguration().get(SSLFactory.SSL_CLIENT_CONF_KEY));
hbt.getConfiguration().addResource(hbt.getConfiguration().get(SSLFactory.SSL_SERVER_CONF_KEY));
MiniHBaseCluster cluster = hbt.startMiniCluster();
try {

View File

@ -729,6 +729,8 @@
<skip>${surefire.skipFirstPart}</skip>
<forkCount>${surefire.firstPartForkCount}</forkCount>
<reuseForks>false</reuseForks>
<reportsDirectory>${surefire.reportsDirectory}</reportsDirectory>
<tempDir>${surefire.tempDir}</tempDir>
<testFailureIgnore>${surefire.testFailureIgnore}</testFailureIgnore>
<forkedProcessTimeoutInSeconds>${surefire.timeout}</forkedProcessTimeoutInSeconds>
<redirectTestOutputToFile>${test.output.tofile}</redirectTestOutputToFile>