|
@@ -30,6 +30,12 @@ import java.util.Iterator;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
|
+import java.util.concurrent.Callable;
|
|
|
+import org.apache.hadoop.fs.statistics.IOStatisticAssertions;
|
|
|
+import org.apache.hadoop.fs.statistics.MeanStatistic;
|
|
|
+import org.apache.hadoop.metrics2.lib.MutableCounterLong;
|
|
|
+import org.apache.hadoop.metrics2.lib.MutableRate;
|
|
|
+import org.apache.hadoop.test.LambdaTestUtils;
|
|
|
import org.junit.Assert;
|
|
|
|
|
|
import org.apache.hadoop.io.DataInputBuffer;
|
|
@@ -155,6 +161,55 @@ public class TestDelegationToken {
|
|
|
return allKeys.get(id.getMasterKeyId());
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ public static class TestFailureDelegationTokenSecretManager
|
|
|
+ extends TestDelegationTokenSecretManager {
|
|
|
+ private boolean throwError = false;
|
|
|
+ private long errorSleepMillis;
|
|
|
+
|
|
|
+ public TestFailureDelegationTokenSecretManager(long errorSleepMillis) {
|
|
|
+ super(24*60*60*1000, 10*1000, 1*1000, 60*60*1000);
|
|
|
+ this.errorSleepMillis = errorSleepMillis;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setThrowError(boolean throwError) {
|
|
|
+ this.throwError = throwError;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sleepAndThrow() throws IOException {
|
|
|
+ try {
|
|
|
+ Thread.sleep(errorSleepMillis);
|
|
|
+ throw new IOException("Test exception");
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void storeNewToken(TestDelegationTokenIdentifier ident, long renewDate)
|
|
|
+ throws IOException {
|
|
|
+ if (throwError) {
|
|
|
+ sleepAndThrow();
|
|
|
+ }
|
|
|
+ super.storeNewToken(ident, renewDate);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void removeStoredToken(TestDelegationTokenIdentifier ident) throws IOException {
|
|
|
+ if (throwError) {
|
|
|
+ sleepAndThrow();
|
|
|
+ }
|
|
|
+ super.removeStoredToken(ident);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void updateStoredToken(TestDelegationTokenIdentifier ident, long renewDate)
|
|
|
+ throws IOException {
|
|
|
+ if (throwError) {
|
|
|
+ sleepAndThrow();
|
|
|
+ }
|
|
|
+ super.updateStoredToken(ident, renewDate);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
public static class TokenSelector extends
|
|
|
AbstractDelegationTokenSelector<TestDelegationTokenIdentifier>{
|
|
@@ -579,4 +634,85 @@ public class TestDelegationToken {
|
|
|
assertEquals(token1, token2);
|
|
|
assertEquals(token1.encodeToUrlString(), token2.encodeToUrlString());
|
|
|
}
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testDelegationTokenSecretManagerMetrics() throws Exception {
|
|
|
+ TestDelegationTokenSecretManager dtSecretManager =
|
|
|
+ new TestDelegationTokenSecretManager(24*60*60*1000,
|
|
|
+ 10*1000, 1*1000, 60*60*1000);
|
|
|
+ try {
|
|
|
+ dtSecretManager.startThreads();
|
|
|
+
|
|
|
+ final Token<TestDelegationTokenIdentifier> token = callAndValidateMetrics(
|
|
|
+ dtSecretManager, dtSecretManager.getMetrics().getStoreToken(), "storeToken",
|
|
|
+ () -> generateDelegationToken(dtSecretManager, "SomeUser", "JobTracker"), 1);
|
|
|
+
|
|
|
+ callAndValidateMetrics(dtSecretManager, dtSecretManager.getMetrics().getUpdateToken(),
|
|
|
+ "updateToken", () -> dtSecretManager.renewToken(token, "JobTracker"), 1);
|
|
|
+
|
|
|
+ callAndValidateMetrics(dtSecretManager, dtSecretManager.getMetrics().getRemoveToken(),
|
|
|
+ "removeToken", () -> dtSecretManager.cancelToken(token, "JobTracker"), 1);
|
|
|
+ } finally {
|
|
|
+ dtSecretManager.stopThreads();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testDelegationTokenSecretManagerMetricsFailures() throws Exception {
|
|
|
+ int errorSleepMillis = 200;
|
|
|
+ TestFailureDelegationTokenSecretManager dtSecretManager =
|
|
|
+ new TestFailureDelegationTokenSecretManager(errorSleepMillis);
|
|
|
+
|
|
|
+ try {
|
|
|
+ dtSecretManager.startThreads();
|
|
|
+
|
|
|
+ final Token<TestDelegationTokenIdentifier> token =
|
|
|
+ generateDelegationToken(dtSecretManager, "SomeUser", "JobTracker");
|
|
|
+
|
|
|
+ dtSecretManager.setThrowError(true);
|
|
|
+
|
|
|
+ callAndValidateFailureMetrics(dtSecretManager, "storeToken", 1, 1, false,
|
|
|
+ errorSleepMillis,
|
|
|
+ () -> generateDelegationToken(dtSecretManager, "SomeUser", "JobTracker"));
|
|
|
+
|
|
|
+ callAndValidateFailureMetrics(dtSecretManager, "updateToken", 1, 2, true,
|
|
|
+ errorSleepMillis, () -> dtSecretManager.renewToken(token, "JobTracker"));
|
|
|
+
|
|
|
+ callAndValidateFailureMetrics(dtSecretManager, "removeToken", 1, 3, true,
|
|
|
+ errorSleepMillis, () -> dtSecretManager.cancelToken(token, "JobTracker"));
|
|
|
+ } finally {
|
|
|
+ dtSecretManager.stopThreads();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T> T callAndValidateMetrics(TestDelegationTokenSecretManager dtSecretManager,
|
|
|
+ MutableRate metric, String statName, Callable<T> callable, int expectedCount)
|
|
|
+ throws Exception {
|
|
|
+ MeanStatistic stat = IOStatisticAssertions.lookupMeanStatistic(
|
|
|
+ dtSecretManager.getMetrics().getIoStatistics(), statName + ".mean");
|
|
|
+ assertEquals(expectedCount - 1, metric.lastStat().numSamples());
|
|
|
+ assertEquals(expectedCount - 1, stat.getSamples());
|
|
|
+ T returnedObject = callable.call();
|
|
|
+ assertEquals(expectedCount, metric.lastStat().numSamples());
|
|
|
+ assertEquals(expectedCount, stat.getSamples());
|
|
|
+ return returnedObject;
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T> void callAndValidateFailureMetrics(TestDelegationTokenSecretManager dtSecretManager,
|
|
|
+ String statName, int expectedStatCount, int expectedMetricCount, boolean expectError,
|
|
|
+ int errorSleepMillis, Callable<T> callable) throws Exception {
|
|
|
+ MutableCounterLong counter = dtSecretManager.getMetrics().getTokenFailure();
|
|
|
+ MeanStatistic failureStat = IOStatisticAssertions.lookupMeanStatistic(
|
|
|
+ dtSecretManager.getMetrics().getIoStatistics(), statName + ".failures.mean");
|
|
|
+ assertEquals(expectedMetricCount - 1, counter.value());
|
|
|
+ assertEquals(expectedStatCount - 1, failureStat.getSamples());
|
|
|
+ if (expectError) {
|
|
|
+ LambdaTestUtils.intercept(IOException.class, callable);
|
|
|
+ } else {
|
|
|
+ callable.call();
|
|
|
+ }
|
|
|
+ assertEquals(expectedMetricCount, counter.value());
|
|
|
+ assertEquals(expectedStatCount, failureStat.getSamples());
|
|
|
+ assertTrue(failureStat.getSum() >= errorSleepMillis);
|
|
|
+ }
|
|
|
}
|