HADOOP-10823. TestReloadingX509TrustManager is flaky. Contributed by Mingliang Liu.
This commit is contained in:
parent
37d939a453
commit
625585950a
|
@ -23,6 +23,8 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.classification.InterfaceStability;
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
@ -44,8 +46,11 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||||
public final class ReloadingX509TrustManager
|
public final class ReloadingX509TrustManager
|
||||||
implements X509TrustManager, Runnable {
|
implements X509TrustManager, Runnable {
|
||||||
|
|
||||||
private static final Log LOG =
|
@VisibleForTesting
|
||||||
LogFactory.getLog(ReloadingX509TrustManager.class);
|
static final Log LOG = LogFactory.getLog(ReloadingX509TrustManager.class);
|
||||||
|
@VisibleForTesting
|
||||||
|
static final String RELOAD_ERROR_MESSAGE =
|
||||||
|
"Could not load truststore (keep using existing one) : ";
|
||||||
|
|
||||||
private String type;
|
private String type;
|
||||||
private File file;
|
private File file;
|
||||||
|
@ -194,8 +199,7 @@ public final class ReloadingX509TrustManager
|
||||||
try {
|
try {
|
||||||
trustManagerRef.set(loadTrustManager());
|
trustManagerRef.set(loadTrustManager());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOG.warn("Could not load truststore (keep using existing one) : " +
|
LOG.warn(RELOAD_ERROR_MESSAGE + ex.toString(), ex);
|
||||||
ex.toString(), ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,10 @@ package org.apache.hadoop.security.ssl;
|
||||||
|
|
||||||
import org.apache.hadoop.fs.FileUtil;
|
import org.apache.hadoop.fs.FileUtil;
|
||||||
import org.apache.hadoop.test.GenericTestUtils;
|
import org.apache.hadoop.test.GenericTestUtils;
|
||||||
|
import org.apache.hadoop.test.GenericTestUtils.LogCapturer;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -30,11 +34,13 @@ import java.security.KeyPair;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.apache.hadoop.security.ssl.KeyStoreTestUtil.createTrustStore;
|
import static org.apache.hadoop.security.ssl.KeyStoreTestUtil.createTrustStore;
|
||||||
import static org.apache.hadoop.security.ssl.KeyStoreTestUtil.generateCertificate;
|
import static org.apache.hadoop.security.ssl.KeyStoreTestUtil.generateCertificate;
|
||||||
import static org.apache.hadoop.security.ssl.KeyStoreTestUtil.generateKeyPair;
|
import static org.apache.hadoop.security.ssl.KeyStoreTestUtil.generateKeyPair;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
||||||
public class TestReloadingX509TrustManager {
|
public class TestReloadingX509TrustManager {
|
||||||
|
|
||||||
|
@ -43,6 +49,8 @@ public class TestReloadingX509TrustManager {
|
||||||
|
|
||||||
private X509Certificate cert1;
|
private X509Certificate cert1;
|
||||||
private X509Certificate cert2;
|
private X509Certificate cert2;
|
||||||
|
private final LogCapturer reloaderLog = LogCapturer.captureLogs(
|
||||||
|
ReloadingX509TrustManager.LOG);
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() throws Exception {
|
public static void setUp() throws Exception {
|
||||||
|
@ -80,7 +88,7 @@ public class TestReloadingX509TrustManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test (timeout = 30000)
|
||||||
public void testReload() throws Exception {
|
public void testReload() throws Exception {
|
||||||
KeyPair kp = generateKeyPair("RSA");
|
KeyPair kp = generateKeyPair("RSA");
|
||||||
cert1 = generateCertificate("CN=Cert1", kp, 30, "SHA1withRSA");
|
cert1 = generateCertificate("CN=Cert1", kp, 30, "SHA1withRSA");
|
||||||
|
@ -88,7 +96,7 @@ public class TestReloadingX509TrustManager {
|
||||||
String truststoreLocation = BASEDIR + "/testreload.jks";
|
String truststoreLocation = BASEDIR + "/testreload.jks";
|
||||||
createTrustStore(truststoreLocation, "password", "cert1", cert1);
|
createTrustStore(truststoreLocation, "password", "cert1", cert1);
|
||||||
|
|
||||||
ReloadingX509TrustManager tm =
|
final ReloadingX509TrustManager tm =
|
||||||
new ReloadingX509TrustManager("jks", truststoreLocation, "password", 10);
|
new ReloadingX509TrustManager("jks", truststoreLocation, "password", 10);
|
||||||
try {
|
try {
|
||||||
tm.init();
|
tm.init();
|
||||||
|
@ -103,19 +111,18 @@ public class TestReloadingX509TrustManager {
|
||||||
certs.put("cert2", cert2);
|
certs.put("cert2", cert2);
|
||||||
createTrustStore(truststoreLocation, "password", certs);
|
createTrustStore(truststoreLocation, "password", certs);
|
||||||
|
|
||||||
// and wait to be sure reload has taken place
|
GenericTestUtils.waitFor(new Supplier<Boolean>() {
|
||||||
assertEquals(10, tm.getReloadInterval());
|
@Override
|
||||||
|
public Boolean get() {
|
||||||
// Wait so that the file modification time is different
|
return tm.getAcceptedIssuers().length == 2;
|
||||||
Thread.sleep((tm.getReloadInterval() + 200));
|
}
|
||||||
|
}, (int) tm.getReloadInterval(), 10000);
|
||||||
assertEquals(2, tm.getAcceptedIssuers().length);
|
|
||||||
} finally {
|
} finally {
|
||||||
tm.destroy();
|
tm.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test (timeout = 30000)
|
||||||
public void testReloadMissingTrustStore() throws Exception {
|
public void testReloadMissingTrustStore() throws Exception {
|
||||||
KeyPair kp = generateKeyPair("RSA");
|
KeyPair kp = generateKeyPair("RSA");
|
||||||
cert1 = generateCertificate("CN=Cert1", kp, 30, "SHA1withRSA");
|
cert1 = generateCertificate("CN=Cert1", kp, 30, "SHA1withRSA");
|
||||||
|
@ -129,19 +136,22 @@ public class TestReloadingX509TrustManager {
|
||||||
tm.init();
|
tm.init();
|
||||||
assertEquals(1, tm.getAcceptedIssuers().length);
|
assertEquals(1, tm.getAcceptedIssuers().length);
|
||||||
X509Certificate cert = tm.getAcceptedIssuers()[0];
|
X509Certificate cert = tm.getAcceptedIssuers()[0];
|
||||||
|
|
||||||
|
assertFalse(reloaderLog.getOutput().contains(
|
||||||
|
ReloadingX509TrustManager.RELOAD_ERROR_MESSAGE));
|
||||||
new File(truststoreLocation).delete();
|
new File(truststoreLocation).delete();
|
||||||
|
|
||||||
// Wait so that the file modification time is different
|
waitForFailedReloadAtLeastOnce((int) tm.getReloadInterval());
|
||||||
Thread.sleep((tm.getReloadInterval() + 200));
|
|
||||||
|
|
||||||
assertEquals(1, tm.getAcceptedIssuers().length);
|
assertEquals(1, tm.getAcceptedIssuers().length);
|
||||||
assertEquals(cert, tm.getAcceptedIssuers()[0]);
|
assertEquals(cert, tm.getAcceptedIssuers()[0]);
|
||||||
} finally {
|
} finally {
|
||||||
|
reloaderLog.stopCapturing();
|
||||||
tm.destroy();
|
tm.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test (timeout = 30000)
|
||||||
public void testReloadCorruptTrustStore() throws Exception {
|
public void testReloadCorruptTrustStore() throws Exception {
|
||||||
KeyPair kp = generateKeyPair("RSA");
|
KeyPair kp = generateKeyPair("RSA");
|
||||||
cert1 = generateCertificate("CN=Cert1", kp, 30, "SHA1withRSA");
|
cert1 = generateCertificate("CN=Cert1", kp, 30, "SHA1withRSA");
|
||||||
|
@ -154,22 +164,39 @@ public class TestReloadingX509TrustManager {
|
||||||
try {
|
try {
|
||||||
tm.init();
|
tm.init();
|
||||||
assertEquals(1, tm.getAcceptedIssuers().length);
|
assertEquals(1, tm.getAcceptedIssuers().length);
|
||||||
X509Certificate cert = tm.getAcceptedIssuers()[0];
|
final X509Certificate cert = tm.getAcceptedIssuers()[0];
|
||||||
|
|
||||||
|
// Wait so that the file modification time is different
|
||||||
|
Thread.sleep((tm.getReloadInterval() + 1000));
|
||||||
|
|
||||||
|
assertFalse(reloaderLog.getOutput().contains(
|
||||||
|
ReloadingX509TrustManager.RELOAD_ERROR_MESSAGE));
|
||||||
OutputStream os = new FileOutputStream(truststoreLocation);
|
OutputStream os = new FileOutputStream(truststoreLocation);
|
||||||
os.write(1);
|
os.write(1);
|
||||||
os.close();
|
os.close();
|
||||||
new File(truststoreLocation).setLastModified(System.currentTimeMillis() -
|
|
||||||
1000);
|
|
||||||
|
|
||||||
// Wait so that the file modification time is different
|
waitForFailedReloadAtLeastOnce((int) tm.getReloadInterval());
|
||||||
Thread.sleep((tm.getReloadInterval() + 200));
|
|
||||||
|
|
||||||
assertEquals(1, tm.getAcceptedIssuers().length);
|
assertEquals(1, tm.getAcceptedIssuers().length);
|
||||||
assertEquals(cert, tm.getAcceptedIssuers()[0]);
|
assertEquals(cert, tm.getAcceptedIssuers()[0]);
|
||||||
} finally {
|
} finally {
|
||||||
|
reloaderLog.stopCapturing();
|
||||||
tm.destroy();
|
tm.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Wait for the reloader thread to load the configurations at least once
|
||||||
|
* by probing the log of the thread if the reload fails.
|
||||||
|
*/
|
||||||
|
private void waitForFailedReloadAtLeastOnce(int reloadInterval)
|
||||||
|
throws InterruptedException, TimeoutException {
|
||||||
|
GenericTestUtils.waitFor(new Supplier<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean get() {
|
||||||
|
return reloaderLog.getOutput().contains(
|
||||||
|
ReloadingX509TrustManager.RELOAD_ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}, reloadInterval, 10 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue