|
@@ -70,12 +70,15 @@ import org.apache.hadoop.metrics2.impl.MetricsSystemImpl;
|
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
|
import org.apache.hadoop.security.token.Token;
|
|
|
import org.apache.hadoop.service.ServiceStateException;
|
|
|
+import org.apache.hadoop.test.GenericTestUtils;
|
|
|
+import org.apache.hadoop.util.DiskChecker;
|
|
|
import org.apache.hadoop.util.PureJavaCrc32;
|
|
|
import org.apache.hadoop.util.StringUtils;
|
|
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
|
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
|
|
import org.apache.hadoop.yarn.server.api.ApplicationInitializationContext;
|
|
|
import org.apache.hadoop.yarn.server.api.ApplicationTerminationContext;
|
|
|
+import org.apache.hadoop.yarn.server.api.AuxiliaryLocalPathHandler;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ContainerLocalizer;
|
|
|
import org.apache.hadoop.yarn.server.records.Version;
|
|
|
import org.jboss.netty.channel.Channel;
|
|
@@ -92,6 +95,9 @@ import org.jboss.netty.handler.codec.http.HttpResponseStatus;
|
|
|
import org.jboss.netty.handler.codec.http.HttpMethod;
|
|
|
import org.junit.Assert;
|
|
|
import org.junit.Test;
|
|
|
+import static org.mockito.Matchers.anyString;
|
|
|
+import static org.mockito.Mockito.mock;
|
|
|
+import static org.mockito.Mockito.when;
|
|
|
import org.mockito.invocation.InvocationOnMock;
|
|
|
import org.mockito.stubbing.Answer;
|
|
|
import org.mockito.Mockito;
|
|
@@ -100,8 +106,12 @@ import org.mortbay.jetty.HttpHeaders;
|
|
|
public class TestShuffleHandler {
|
|
|
static final long MiB = 1024 * 1024;
|
|
|
private static final Log LOG = LogFactory.getLog(TestShuffleHandler.class);
|
|
|
+ private static final File ABS_LOG_DIR = GenericTestUtils.getTestDir(
|
|
|
+ TestShuffleHandler.class.getSimpleName() + "LocDir");
|
|
|
|
|
|
class MockShuffleHandler extends org.apache.hadoop.mapred.ShuffleHandler {
|
|
|
+ private AuxiliaryLocalPathHandler pathHandler =
|
|
|
+ new TestAuxiliaryLocalPathHandler();
|
|
|
@Override
|
|
|
protected Shuffle getShuffle(final Configuration conf) {
|
|
|
return new Shuffle(conf) {
|
|
@@ -141,11 +151,35 @@ public class TestShuffleHandler {
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public AuxiliaryLocalPathHandler getAuxiliaryLocalPathHandler() {
|
|
|
+ return pathHandler;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- private static class MockShuffleHandler2 extends org.apache.hadoop.mapred.ShuffleHandler {
|
|
|
- boolean socketKeepAlive = false;
|
|
|
+ private class TestAuxiliaryLocalPathHandler
|
|
|
+ implements AuxiliaryLocalPathHandler {
|
|
|
+ @Override
|
|
|
+ public Path getLocalPathForRead(String path) throws IOException {
|
|
|
+ return new Path(ABS_LOG_DIR.getAbsolutePath(), path);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Path getLocalPathForWrite(String path) throws IOException {
|
|
|
+ return new Path(ABS_LOG_DIR.getAbsolutePath());
|
|
|
+ }
|
|
|
|
|
|
+ @Override
|
|
|
+ public Path getLocalPathForWrite(String path, long size)
|
|
|
+ throws IOException {
|
|
|
+ return new Path(ABS_LOG_DIR.getAbsolutePath());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static class MockShuffleHandler2 extends
|
|
|
+ org.apache.hadoop.mapred.ShuffleHandler {
|
|
|
+ boolean socketKeepAlive = false;
|
|
|
@Override
|
|
|
protected Shuffle getShuffle(final Configuration conf) {
|
|
|
return new Shuffle(conf) {
|
|
@@ -479,6 +513,11 @@ public class TestShuffleHandler {
|
|
|
conf.setInt(ShuffleHandler.SHUFFLE_CONNECTION_KEEP_ALIVE_TIME_OUT, -100);
|
|
|
HttpURLConnection conn = null;
|
|
|
MockShuffleHandler2 shuffleHandler = new MockShuffleHandler2();
|
|
|
+ AuxiliaryLocalPathHandler pathHandler =
|
|
|
+ mock(AuxiliaryLocalPathHandler.class);
|
|
|
+ when(pathHandler.getLocalPathForRead(anyString())).thenThrow(
|
|
|
+ new DiskChecker.DiskErrorException("Test"));
|
|
|
+ shuffleHandler.setAuxiliaryLocalPathHandler(pathHandler);
|
|
|
try {
|
|
|
shuffleHandler.init(conf);
|
|
|
shuffleHandler.start();
|
|
@@ -661,19 +700,16 @@ public class TestShuffleHandler {
|
|
|
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
|
|
|
"kerberos");
|
|
|
UserGroupInformation.setConfiguration(conf);
|
|
|
- File absLogDir = new File("target",
|
|
|
- TestShuffleHandler.class.getSimpleName() + "LocDir").getAbsoluteFile();
|
|
|
- conf.set(YarnConfiguration.NM_LOCAL_DIRS, absLogDir.getAbsolutePath());
|
|
|
+ conf.set(YarnConfiguration.NM_LOCAL_DIRS, ABS_LOG_DIR.getAbsolutePath());
|
|
|
ApplicationId appId = ApplicationId.newInstance(12345, 1);
|
|
|
LOG.info(appId.toString());
|
|
|
String appAttemptId = "attempt_12345_1_m_1_0";
|
|
|
String user = "randomUser";
|
|
|
String reducerId = "0";
|
|
|
List<File> fileMap = new ArrayList<File>();
|
|
|
- createShuffleHandlerFiles(absLogDir, user, appId.toString(), appAttemptId,
|
|
|
+ createShuffleHandlerFiles(ABS_LOG_DIR, user, appId.toString(), appAttemptId,
|
|
|
conf, fileMap);
|
|
|
ShuffleHandler shuffleHandler = new ShuffleHandler() {
|
|
|
-
|
|
|
@Override
|
|
|
protected Shuffle getShuffle(Configuration conf) {
|
|
|
// replace the shuffle handler with one stubbed for testing
|
|
@@ -689,6 +725,8 @@ public class TestShuffleHandler {
|
|
|
};
|
|
|
}
|
|
|
};
|
|
|
+ AuxiliaryLocalPathHandler pathHandler = new TestAuxiliaryLocalPathHandler();
|
|
|
+ shuffleHandler.setAuxiliaryLocalPathHandler(pathHandler);
|
|
|
shuffleHandler.init(conf);
|
|
|
try {
|
|
|
shuffleHandler.start();
|
|
@@ -733,7 +771,7 @@ public class TestShuffleHandler {
|
|
|
Assert.assertTrue((new String(byteArr)).contains(message));
|
|
|
} finally {
|
|
|
shuffleHandler.stop();
|
|
|
- FileUtil.fullyDelete(absLogDir);
|
|
|
+ FileUtil.fullyDelete(ABS_LOG_DIR);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -794,10 +832,13 @@ public class TestShuffleHandler {
|
|
|
final File tmpDir = new File(System.getProperty("test.build.data",
|
|
|
System.getProperty("java.io.tmpdir")),
|
|
|
TestShuffleHandler.class.getName());
|
|
|
+ ShuffleHandler shuffle = new ShuffleHandler();
|
|
|
+ AuxiliaryLocalPathHandler pathHandler = new TestAuxiliaryLocalPathHandler();
|
|
|
+ shuffle.setAuxiliaryLocalPathHandler(pathHandler);
|
|
|
Configuration conf = new Configuration();
|
|
|
conf.setInt(ShuffleHandler.SHUFFLE_PORT_CONFIG_KEY, 0);
|
|
|
conf.setInt(ShuffleHandler.MAX_SHUFFLE_CONNECTIONS, 3);
|
|
|
- ShuffleHandler shuffle = new ShuffleHandler();
|
|
|
+ conf.set(YarnConfiguration.NM_LOCAL_DIRS, ABS_LOG_DIR.getAbsolutePath());
|
|
|
// emulate aux services startup with recovery enabled
|
|
|
shuffle.setRecoveryPath(new Path(tmpDir.toString()));
|
|
|
tmpDir.mkdirs();
|
|
@@ -823,6 +864,7 @@ public class TestShuffleHandler {
|
|
|
// emulate shuffle handler restart
|
|
|
shuffle.close();
|
|
|
shuffle = new ShuffleHandler();
|
|
|
+ shuffle.setAuxiliaryLocalPathHandler(pathHandler);
|
|
|
shuffle.setRecoveryPath(new Path(tmpDir.toString()));
|
|
|
shuffle.init(conf);
|
|
|
shuffle.start();
|
|
@@ -865,6 +907,9 @@ public class TestShuffleHandler {
|
|
|
conf.setInt(ShuffleHandler.SHUFFLE_PORT_CONFIG_KEY, 0);
|
|
|
conf.setInt(ShuffleHandler.MAX_SHUFFLE_CONNECTIONS, 3);
|
|
|
ShuffleHandler shuffle = new ShuffleHandler();
|
|
|
+ AuxiliaryLocalPathHandler pathHandler = new TestAuxiliaryLocalPathHandler();
|
|
|
+ shuffle.setAuxiliaryLocalPathHandler(pathHandler);
|
|
|
+ conf.set(YarnConfiguration.NM_LOCAL_DIRS, ABS_LOG_DIR.getAbsolutePath());
|
|
|
// emulate aux services startup with recovery enabled
|
|
|
shuffle.setRecoveryPath(new Path(tmpDir.toString()));
|
|
|
tmpDir.mkdirs();
|
|
@@ -890,6 +935,7 @@ public class TestShuffleHandler {
|
|
|
// emulate shuffle handler restart
|
|
|
shuffle.close();
|
|
|
shuffle = new ShuffleHandler();
|
|
|
+ shuffle.setAuxiliaryLocalPathHandler(pathHandler);
|
|
|
shuffle.setRecoveryPath(new Path(tmpDir.toString()));
|
|
|
shuffle.init(conf);
|
|
|
shuffle.start();
|
|
@@ -907,6 +953,7 @@ public class TestShuffleHandler {
|
|
|
Assert.assertEquals(version11, shuffle.loadVersion());
|
|
|
shuffle.close();
|
|
|
shuffle = new ShuffleHandler();
|
|
|
+ shuffle.setAuxiliaryLocalPathHandler(pathHandler);
|
|
|
shuffle.setRecoveryPath(new Path(tmpDir.toString()));
|
|
|
shuffle.init(conf);
|
|
|
shuffle.start();
|
|
@@ -923,6 +970,7 @@ public class TestShuffleHandler {
|
|
|
Assert.assertEquals(version21, shuffle.loadVersion());
|
|
|
shuffle.close();
|
|
|
shuffle = new ShuffleHandler();
|
|
|
+ shuffle.setAuxiliaryLocalPathHandler(pathHandler);
|
|
|
shuffle.setRecoveryPath(new Path(tmpDir.toString()));
|
|
|
shuffle.init(conf);
|
|
|
|
|
@@ -972,16 +1020,15 @@ public class TestShuffleHandler {
|
|
|
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
|
|
|
"simple");
|
|
|
UserGroupInformation.setConfiguration(conf);
|
|
|
- File absLogDir = new File("target", TestShuffleHandler.class.
|
|
|
- getSimpleName() + "LocDir").getAbsoluteFile();
|
|
|
- conf.set(YarnConfiguration.NM_LOCAL_DIRS, absLogDir.getAbsolutePath());
|
|
|
+ conf.set(YarnConfiguration.NM_LOCAL_DIRS, ABS_LOG_DIR.getAbsolutePath());
|
|
|
ApplicationId appId = ApplicationId.newInstance(12345, 1);
|
|
|
String appAttemptId = "attempt_12345_1_m_1_0";
|
|
|
String user = "randomUser";
|
|
|
String reducerId = "0";
|
|
|
List<File> fileMap = new ArrayList<File>();
|
|
|
- createShuffleHandlerFiles(absLogDir, user, appId.toString(), appAttemptId,
|
|
|
+ createShuffleHandlerFiles(ABS_LOG_DIR, user, appId.toString(), appAttemptId,
|
|
|
conf, fileMap);
|
|
|
+ AuxiliaryLocalPathHandler pathHandler = new TestAuxiliaryLocalPathHandler();
|
|
|
ShuffleHandler shuffleHandler = new ShuffleHandler() {
|
|
|
@Override
|
|
|
protected Shuffle getShuffle(Configuration conf) {
|
|
@@ -1025,6 +1072,7 @@ public class TestShuffleHandler {
|
|
|
};
|
|
|
}
|
|
|
};
|
|
|
+ shuffleHandler.setAuxiliaryLocalPathHandler(pathHandler);
|
|
|
shuffleHandler.init(conf);
|
|
|
try {
|
|
|
shuffleHandler.start();
|
|
@@ -1063,7 +1111,7 @@ public class TestShuffleHandler {
|
|
|
0, failures.size());
|
|
|
} finally {
|
|
|
shuffleHandler.stop();
|
|
|
- FileUtil.fullyDelete(absLogDir);
|
|
|
+ FileUtil.fullyDelete(ABS_LOG_DIR);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1073,10 +1121,10 @@ public class TestShuffleHandler {
|
|
|
new ArrayList<ShuffleHandler.ReduceMapFileCount>();
|
|
|
|
|
|
final ChannelHandlerContext mockCtx =
|
|
|
- Mockito.mock(ChannelHandlerContext.class);
|
|
|
- final MessageEvent mockEvt = Mockito.mock(MessageEvent.class);
|
|
|
- final Channel mockCh = Mockito.mock(AbstractChannel.class);
|
|
|
- final ChannelPipeline mockPipeline = Mockito.mock(ChannelPipeline.class);
|
|
|
+ mock(ChannelHandlerContext.class);
|
|
|
+ final MessageEvent mockEvt = mock(MessageEvent.class);
|
|
|
+ final Channel mockCh = mock(AbstractChannel.class);
|
|
|
+ final ChannelPipeline mockPipeline = mock(ChannelPipeline.class);
|
|
|
|
|
|
// Mock HttpRequest and ChannelFuture
|
|
|
final HttpRequest mockHttpRequest = createMockHttpRequest();
|
|
@@ -1087,16 +1135,16 @@ public class TestShuffleHandler {
|
|
|
|
|
|
// Mock Netty Channel Context and Channel behavior
|
|
|
Mockito.doReturn(mockCh).when(mockCtx).getChannel();
|
|
|
- Mockito.when(mockCh.getPipeline()).thenReturn(mockPipeline);
|
|
|
- Mockito.when(mockPipeline.get(
|
|
|
+ when(mockCh.getPipeline()).thenReturn(mockPipeline);
|
|
|
+ when(mockPipeline.get(
|
|
|
Mockito.any(String.class))).thenReturn(timerHandler);
|
|
|
- Mockito.when(mockCtx.getChannel()).thenReturn(mockCh);
|
|
|
+ when(mockCtx.getChannel()).thenReturn(mockCh);
|
|
|
Mockito.doReturn(mockFuture).when(mockCh).write(Mockito.any(Object.class));
|
|
|
- Mockito.when(mockCh.write(Object.class)).thenReturn(mockFuture);
|
|
|
+ when(mockCh.write(Object.class)).thenReturn(mockFuture);
|
|
|
|
|
|
//Mock MessageEvent behavior
|
|
|
Mockito.doReturn(mockCh).when(mockEvt).getChannel();
|
|
|
- Mockito.when(mockEvt.getChannel()).thenReturn(mockCh);
|
|
|
+ when(mockEvt.getChannel()).thenReturn(mockCh);
|
|
|
Mockito.doReturn(mockHttpRequest).when(mockEvt).getMessage();
|
|
|
|
|
|
final ShuffleHandler sh = new MockShuffleHandler();
|
|
@@ -1120,8 +1168,8 @@ public class TestShuffleHandler {
|
|
|
|
|
|
public ChannelFuture createMockChannelFuture(Channel mockCh,
|
|
|
final List<ShuffleHandler.ReduceMapFileCount> listenerList) {
|
|
|
- final ChannelFuture mockFuture = Mockito.mock(ChannelFuture.class);
|
|
|
- Mockito.when(mockFuture.getChannel()).thenReturn(mockCh);
|
|
|
+ final ChannelFuture mockFuture = mock(ChannelFuture.class);
|
|
|
+ when(mockFuture.getChannel()).thenReturn(mockCh);
|
|
|
Mockito.doReturn(true).when(mockFuture).isSuccess();
|
|
|
Mockito.doAnswer(new Answer() {
|
|
|
@Override
|
|
@@ -1139,7 +1187,7 @@ public class TestShuffleHandler {
|
|
|
}
|
|
|
|
|
|
public HttpRequest createMockHttpRequest() {
|
|
|
- HttpRequest mockHttpRequest = Mockito.mock(HttpRequest.class);
|
|
|
+ HttpRequest mockHttpRequest = mock(HttpRequest.class);
|
|
|
Mockito.doReturn(HttpMethod.GET).when(mockHttpRequest).getMethod();
|
|
|
Mockito.doAnswer(new Answer() {
|
|
|
@Override
|