|
@@ -27,11 +27,14 @@ import static org.junit.Assert.assertTrue;
|
|
|
import java.io.IOException;
|
|
|
import java.security.PrivilegedExceptionAction;
|
|
|
import java.util.Collections;
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
|
import org.apache.hadoop.ha.HAServiceProtocol.HAServiceState;
|
|
|
+import org.apache.hadoop.hdfs.protocol.HdfsFileStatus;
|
|
|
import org.apache.hadoop.hdfs.server.federation.MiniRouterDFSCluster.RouterContext;
|
|
|
import org.apache.hadoop.hdfs.server.federation.RouterConfigBuilder;
|
|
|
import org.apache.hadoop.hdfs.server.federation.StateStoreDFSCluster;
|
|
@@ -57,7 +60,6 @@ import org.apache.hadoop.hdfs.server.federation.store.protocol.RemoveMountTableE
|
|
|
import org.apache.hadoop.hdfs.server.federation.store.protocol.UpdateMountTableEntryRequest;
|
|
|
import org.apache.hadoop.hdfs.server.federation.store.records.MountTable;
|
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
|
-import org.apache.hadoop.test.Whitebox;
|
|
|
import org.apache.hadoop.test.LambdaTestUtils;
|
|
|
import org.apache.hadoop.util.Time;
|
|
|
import org.junit.AfterClass;
|
|
@@ -65,6 +67,9 @@ import org.junit.Before;
|
|
|
import org.junit.BeforeClass;
|
|
|
import org.junit.Test;
|
|
|
import org.mockito.Mockito;
|
|
|
+import org.mockito.internal.util.reflection.FieldSetter;
|
|
|
+
|
|
|
+import com.google.common.collect.Lists;
|
|
|
|
|
|
/**
|
|
|
* The administrator interface of the {@link Router} implemented by
|
|
@@ -78,6 +83,7 @@ public class TestRouterAdmin {
|
|
|
"Hadoop:service=Router,name=FederationRPC";
|
|
|
private static List<MountTable> mockMountTable;
|
|
|
private static StateStoreService stateStore;
|
|
|
+ private static RouterRpcClient mockRpcClient;
|
|
|
|
|
|
@BeforeClass
|
|
|
public static void globalSetUp() throws Exception {
|
|
@@ -88,6 +94,7 @@ public class TestRouterAdmin {
|
|
|
.admin()
|
|
|
.rpc()
|
|
|
.build();
|
|
|
+ conf.setBoolean(RBFConfigKeys.DFS_ROUTER_ADMIN_MOUNT_CHECK_ENABLE, true);
|
|
|
cluster.addRouterOverrides(conf);
|
|
|
cluster.startRouters();
|
|
|
routerContext = cluster.getRandomRouter();
|
|
@@ -103,11 +110,51 @@ public class TestRouterAdmin {
|
|
|
createNamenodeReport("ns1", "nn1", HAServiceState.ACTIVE));
|
|
|
stateStore.refreshCaches(true);
|
|
|
|
|
|
+ setUpMocks();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Group all mocks together.
|
|
|
+ *
|
|
|
+ * @throws IOException
|
|
|
+ * @throws NoSuchFieldException
|
|
|
+ */
|
|
|
+ private static void setUpMocks() throws IOException, NoSuchFieldException {
|
|
|
RouterRpcServer spyRpcServer =
|
|
|
Mockito.spy(routerContext.getRouter().createRpcServer());
|
|
|
- Whitebox
|
|
|
- .setInternalState(routerContext.getRouter(), "rpcServer", spyRpcServer);
|
|
|
+ FieldSetter.setField(routerContext.getRouter(),
|
|
|
+ Router.class.getDeclaredField("rpcServer"), spyRpcServer);
|
|
|
Mockito.doReturn(null).when(spyRpcServer).getFileInfo(Mockito.anyString());
|
|
|
+
|
|
|
+ // mock rpc client for destination check when editing mount tables.
|
|
|
+ mockRpcClient = Mockito.spy(spyRpcServer.getRPCClient());
|
|
|
+ FieldSetter.setField(spyRpcServer,
|
|
|
+ RouterRpcServer.class.getDeclaredField("rpcClient"),
|
|
|
+ mockRpcClient);
|
|
|
+ RemoteLocation remoteLocation0 =
|
|
|
+ new RemoteLocation("ns0", "/testdir", null);
|
|
|
+ RemoteLocation remoteLocation1 =
|
|
|
+ new RemoteLocation("ns1", "/", null);
|
|
|
+ final Map<RemoteLocation, HdfsFileStatus> mockResponse0 = new HashMap<>();
|
|
|
+ final Map<RemoteLocation, HdfsFileStatus> mockResponse1 = new HashMap<>();
|
|
|
+ mockResponse0.put(remoteLocation0,
|
|
|
+ new HdfsFileStatus.Builder().build());
|
|
|
+ Mockito.doReturn(mockResponse0).when(mockRpcClient).invokeConcurrent(
|
|
|
+ Mockito.eq(Lists.newArrayList(remoteLocation0)),
|
|
|
+ Mockito.any(RemoteMethod.class),
|
|
|
+ Mockito.eq(false),
|
|
|
+ Mockito.eq(false),
|
|
|
+ Mockito.eq(HdfsFileStatus.class)
|
|
|
+ );
|
|
|
+ mockResponse1.put(remoteLocation1,
|
|
|
+ new HdfsFileStatus.Builder().build());
|
|
|
+ Mockito.doReturn(mockResponse1).when(mockRpcClient).invokeConcurrent(
|
|
|
+ Mockito.eq(Lists.newArrayList(remoteLocation1)),
|
|
|
+ Mockito.any(RemoteMethod.class),
|
|
|
+ Mockito.eq(false),
|
|
|
+ Mockito.eq(false),
|
|
|
+ Mockito.eq(HdfsFileStatus.class)
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
@AfterClass
|
|
@@ -332,6 +379,26 @@ public class TestRouterAdmin {
|
|
|
assertEquals(entry.getSourcePath(), "/ns0");
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void testVerifyFileInDestinations() throws IOException {
|
|
|
+ // this entry has been created in the mock setup
|
|
|
+ MountTable newEntry = MountTable.newInstance(
|
|
|
+ "/testpath", Collections.singletonMap("ns0", "/testdir"),
|
|
|
+ Time.now(), Time.now());
|
|
|
+ RouterAdminServer adminServer =
|
|
|
+ this.routerContext.getRouter().getAdminServer();
|
|
|
+ List<String> result = adminServer.verifyFileInDestinations(newEntry);
|
|
|
+ assertEquals(0, result.size());
|
|
|
+
|
|
|
+ // this entry was not created in the mock
|
|
|
+ newEntry = MountTable.newInstance(
|
|
|
+ "/testpath", Collections.singletonMap("ns0", "/testdir1"),
|
|
|
+ Time.now(), Time.now());
|
|
|
+ result = adminServer.verifyFileInDestinations(newEntry);
|
|
|
+ assertEquals(1, result.size());
|
|
|
+ assertEquals("ns0", result.get(0));
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Gets an existing mount table record in the state store.
|
|
|
*
|