Skip to content

Commit e268d01

Browse files
committed
HADOOP-19164. Hadoop CLI MiniCluster is broken (#7050). Contributed by Ayush Saxena.
Reviewed-by: Vinayakumar B <vinayakumarb@apache.org>
1 parent f01adaf commit e268d01

File tree

13 files changed

+151
-128
lines changed

13 files changed

+151
-128
lines changed

hadoop-common-project/hadoop-common/src/site/markdown/CLIMiniCluster.md.vm

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,16 @@ You should be able to obtain the Hadoop tarball from the release. Also, you can
3232
$ mvn clean install -DskipTests
3333
$ mvn package -Pdist -Dtar -DskipTests -Dmaven.javadoc.skip
3434

35-
**NOTE:** You will need [protoc 2.5.0](http://code.google.com/p/protobuf/) installed.
36-
3735
The tarball should be available in `hadoop-dist/target/` directory.
3836

3937
Running the MiniCluster
4038
-----------------------
4139

4240
From inside the root directory of the extracted tarball, you can start the CLI MiniCluster using the following command:
4341

44-
$ bin/mapred minicluster -rmport RM_PORT -jhsport JHS_PORT
42+
$ bin/mapred minicluster -format
4543

46-
In the example command above, `RM_PORT` and `JHS_PORT` should be replaced by the user's choice of these port numbers. If not specified, random free ports will be used.
44+
The format option is required when running the minicluster for the first time, from next time -format option isn't required.
4745

4846
There are a number of command line arguments that the users can use to control which services to start, and to pass other configuration properties. The available command line arguments:
4947

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestFileCreation.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
import org.apache.hadoop.hdfs.server.namenode.LeaseManager;
8585
import org.apache.hadoop.hdfs.server.namenode.NameNode;
8686
import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapter;
87+
import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapterMockitoUtil;
8788
import org.apache.hadoop.hdfs.server.protocol.NamenodeProtocols;
8889
import org.apache.hadoop.io.EnumSetWritable;
8990
import org.apache.hadoop.io.IOUtils;
@@ -201,7 +202,7 @@ public void testServerDefaultsWithCaching()
201202
cluster.waitActive();
202203
// Set a spy namesystem inside the namenode and return it
203204
FSNamesystem spyNamesystem =
204-
NameNodeAdapter.spyOnNamesystem(cluster.getNameNode());
205+
NameNodeAdapterMockitoUtil.spyOnNamesystem(cluster.getNameNode());
205206
InetSocketAddress nameNodeAddr = cluster.getNameNode().getNameNodeAddress();
206207
try {
207208
// Create a dfs client and set a long enough validity interval
@@ -252,7 +253,7 @@ public void testServerDefaultsWithMinimalCaching() throws Exception {
252253
cluster.waitActive();
253254
// Set a spy namesystem inside the namenode and return it
254255
FSNamesystem spyNamesystem =
255-
NameNodeAdapter.spyOnNamesystem(cluster.getNameNode());
256+
NameNodeAdapterMockitoUtil.spyOnNamesystem(cluster.getNameNode());
256257
InetSocketAddress nameNodeAddr = cluster.getNameNode().getNameNodeAddress();
257258
try {
258259
// Create a dfs client and set a minimal validity interval

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestSetTimes.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import org.apache.hadoop.fs.Path;
3838
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
3939
import org.apache.hadoop.hdfs.protocol.HdfsConstants.DatanodeReportType;
40-
import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapter;
40+
import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapterMockitoUtil;
4141
import org.apache.hadoop.test.MockitoUtil;
4242
import org.apache.hadoop.util.Time;
4343
import org.junit.Assert;
@@ -297,7 +297,8 @@ public void testGetBlockLocationsOnlyUsesReadLock() throws IOException {
297297
MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf)
298298
.numDataNodes(0)
299299
.build();
300-
ReentrantReadWriteLock spyLock = NameNodeAdapter.spyOnFsLock(cluster.getNamesystem());
300+
ReentrantReadWriteLock spyLock =
301+
NameNodeAdapterMockitoUtil.spyOnFsLock(cluster.getNamesystem());
301302
try {
302303
// Create empty file in the FSN.
303304
Path p = new Path("/empty-file");

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/balancer/TestBalancer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
import org.apache.hadoop.hdfs.server.datanode.SimulatedFSDataset;
112112
import org.apache.hadoop.hdfs.server.namenode.FSNamesystem;
113113
import org.apache.hadoop.hdfs.server.namenode.NameNode;
114-
import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapter;
114+
import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapterMockitoUtil;
115115
import org.apache.hadoop.hdfs.server.protocol.BlocksWithLocations;
116116
import org.apache.hadoop.http.HttpConfig;
117117
import org.apache.hadoop.io.IOUtils;
@@ -1877,7 +1877,7 @@ public Void run() throws Exception {
18771877
}
18781878

18791879
private void spyFSNamesystem(NameNode nn) throws IOException {
1880-
FSNamesystem fsnSpy = NameNodeAdapter.spyOnNamesystem(nn);
1880+
FSNamesystem fsnSpy = NameNodeAdapterMockitoUtil.spyOnNamesystem(nn);
18811881
doAnswer(new Answer<BlocksWithLocations>() {
18821882
@Override
18831883
public BlocksWithLocations answer(InvocationOnMock invocation)

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/balancer/TestBalancerWithHANameNodes.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
import org.apache.hadoop.hdfs.server.blockmanagement.BlockManager;
5252
import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeStorageInfo;
5353
import org.apache.hadoop.hdfs.server.namenode.FSNamesystem;
54-
import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapter;
54+
import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapterMockitoUtil;
5555
import org.apache.hadoop.hdfs.server.namenode.ha.HATestUtil;
5656
import org.apache.hadoop.hdfs.server.namenode.ha.ObserverReadProxyProvider;
5757
import org.apache.hadoop.hdfs.server.protocol.DatanodeStorageReport;
@@ -259,7 +259,7 @@ private void testBalancerWithObserver(boolean withObserverFailure)
259259
List<FSNamesystem> namesystemSpies = new ArrayList<>();
260260
for (int i = 0; i < cluster.getNumNameNodes(); i++) {
261261
namesystemSpies.add(
262-
NameNodeAdapter.spyOnNamesystem(cluster.getNameNode(i)));
262+
NameNodeAdapterMockitoUtil.spyOnNamesystem(cluster.getNameNode(i)));
263263
}
264264
if (withObserverFailure) {
265265
// First observer NN is at index 2

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/NameNodeAdapter.java

Lines changed: 0 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,15 @@
1919

2020
import org.apache.hadoop.ha.HAServiceProtocol.HAServiceState;
2121
import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfo;
22-
import org.apache.hadoop.hdfs.server.blockmanagement.BlockManager;
2322
import org.apache.hadoop.hdfs.server.protocol.SlowDiskReports;
2423

25-
import static org.mockito.Mockito.doAnswer;
26-
import static org.mockito.Mockito.spy;
2724

2825
import java.io.File;
2926
import java.io.IOException;
30-
import java.util.concurrent.locks.ReentrantReadWriteLock;
3127

32-
import org.apache.commons.lang3.reflect.FieldUtils;
3328
import org.apache.hadoop.fs.UnresolvedLinkException;
3429
import org.apache.hadoop.fs.permission.FsPermission;
3530
import org.apache.hadoop.fs.permission.PermissionStatus;
36-
import org.apache.hadoop.hdfs.DFSTestUtil;
3731
import org.apache.hadoop.hdfs.protocol.Block;
3832
import org.apache.hadoop.hdfs.protocol.BlockType;
3933
import org.apache.hadoop.hdfs.protocol.DatanodeID;
@@ -47,7 +41,6 @@
4741
import org.apache.hadoop.hdfs.server.namenode.FSDirectory.DirOp;
4842
import org.apache.hadoop.hdfs.server.namenode.FSEditLogOp.MkdirOp;
4943
import org.apache.hadoop.hdfs.server.namenode.LeaseManager.Lease;
50-
import org.apache.hadoop.hdfs.server.namenode.ha.EditLogTailer;
5144
import org.apache.hadoop.hdfs.server.protocol.DatanodeRegistration;
5245
import org.apache.hadoop.hdfs.server.protocol.HeartbeatResponse;
5346
import org.apache.hadoop.hdfs.server.protocol.NamenodeCommand;
@@ -57,11 +50,6 @@
5750
import org.apache.hadoop.ipc.StandbyException;
5851
import org.apache.hadoop.security.AccessControlException;
5952
import org.apache.hadoop.test.Whitebox;
60-
import org.mockito.ArgumentMatcher;
61-
import org.mockito.ArgumentMatchers;
62-
import org.mockito.Mockito;
63-
import org.mockito.invocation.InvocationOnMock;
64-
import org.mockito.stubbing.Answer;
6553

6654
import static org.apache.hadoop.hdfs.server.namenode.NameNodeHttpServer.FSIMAGE_ATTRIBUTE_KEY;
6755

@@ -269,97 +257,6 @@ public static BlockInfo getStoredBlock(final FSNamesystem fsn,
269257
return fsn.getStoredBlock(b);
270258
}
271259

272-
public static FSNamesystem spyOnNamesystem(NameNode nn) {
273-
FSNamesystem fsnSpy = Mockito.spy(nn.getNamesystem());
274-
FSNamesystem fsnOld = nn.namesystem;
275-
fsnOld.writeLock();
276-
fsnSpy.writeLock();
277-
nn.namesystem = fsnSpy;
278-
try {
279-
FieldUtils.writeDeclaredField(
280-
(NameNodeRpcServer)nn.getRpcServer(), "namesystem", fsnSpy, true);
281-
FieldUtils.writeDeclaredField(
282-
fsnSpy.getBlockManager(), "namesystem", fsnSpy, true);
283-
FieldUtils.writeDeclaredField(
284-
fsnSpy.getLeaseManager(), "fsnamesystem", fsnSpy, true);
285-
FieldUtils.writeDeclaredField(
286-
fsnSpy.getBlockManager().getDatanodeManager(),
287-
"namesystem", fsnSpy, true);
288-
FieldUtils.writeDeclaredField(
289-
BlockManagerTestUtil.getHeartbeatManager(fsnSpy.getBlockManager()),
290-
"namesystem", fsnSpy, true);
291-
} catch (IllegalAccessException e) {
292-
throw new RuntimeException("Cannot set spy FSNamesystem", e);
293-
} finally {
294-
fsnSpy.writeUnlock();
295-
fsnOld.writeUnlock();
296-
}
297-
return fsnSpy;
298-
}
299-
300-
public static BlockManager spyOnBlockManager(NameNode nn) {
301-
BlockManager bmSpy = Mockito.spy(nn.getNamesystem().getBlockManager());
302-
nn.getNamesystem().setBlockManagerForTesting(bmSpy);
303-
return bmSpy;
304-
}
305-
306-
public static ReentrantReadWriteLock spyOnFsLock(FSNamesystem fsn) {
307-
ReentrantReadWriteLock spy = Mockito.spy(fsn.getFsLockForTests());
308-
fsn.setFsLockForTests(spy);
309-
return spy;
310-
}
311-
312-
public static FSImage spyOnFsImage(NameNode nn1) {
313-
FSNamesystem fsn = nn1.getNamesystem();
314-
FSImage spy = Mockito.spy(fsn.getFSImage());
315-
Whitebox.setInternalState(fsn, "fsImage", spy);
316-
return spy;
317-
}
318-
319-
public static FSEditLog spyOnEditLog(NameNode nn) {
320-
FSEditLog spyEditLog = spy(nn.getNamesystem().getFSImage().getEditLog());
321-
DFSTestUtil.setEditLogForTesting(nn.getNamesystem(), spyEditLog);
322-
EditLogTailer tailer = nn.getNamesystem().getEditLogTailer();
323-
if (tailer != null) {
324-
tailer.setEditLog(spyEditLog);
325-
}
326-
return spyEditLog;
327-
}
328-
329-
/**
330-
* Spy on EditLog to delay execution of doEditTransaction() for MkdirOp.
331-
*/
332-
public static FSEditLog spyDelayMkDirTransaction(
333-
final NameNode nn, final long delay) {
334-
FSEditLog realEditLog = nn.getFSImage().getEditLog();
335-
FSEditLogAsync spyEditLog = (FSEditLogAsync) spy(realEditLog);
336-
DFSTestUtil.setEditLogForTesting(nn.getNamesystem(), spyEditLog);
337-
Answer<Boolean> ans = new Answer<Boolean>() {
338-
@Override
339-
public Boolean answer(InvocationOnMock invocation) throws Throwable {
340-
Thread.sleep(delay);
341-
return (Boolean) invocation.callRealMethod();
342-
}
343-
};
344-
ArgumentMatcher<FSEditLogOp> am = new ArgumentMatcher<FSEditLogOp>() {
345-
@Override
346-
public boolean matches(FSEditLogOp argument) {
347-
FSEditLogOp op = (FSEditLogOp) argument;
348-
return op.opCode == FSEditLogOpCodes.OP_MKDIR;
349-
}
350-
};
351-
doAnswer(ans).when(spyEditLog).doEditTransaction(
352-
ArgumentMatchers.argThat(am));
353-
return spyEditLog;
354-
}
355-
356-
public static JournalSet spyOnJournalSet(NameNode nn) {
357-
FSEditLog editLog = nn.getFSImage().getEditLog();
358-
JournalSet js = Mockito.spy(editLog.getJournalSet());
359-
editLog.setJournalSetForTesting(js);
360-
return js;
361-
}
362-
363260
public static String getMkdirOpPath(FSEditLogOp op) {
364261
if (op.opCode == FSEditLogOpCodes.OP_MKDIR) {
365262
return ((MkdirOp) op).path;
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.hadoop.hdfs.server.namenode;
20+
21+
import java.util.concurrent.locks.ReentrantReadWriteLock;
22+
23+
import org.mockito.ArgumentMatcher;
24+
import org.mockito.ArgumentMatchers;
25+
import org.mockito.stubbing.Answer;
26+
27+
import org.apache.commons.lang3.reflect.FieldUtils;
28+
import org.apache.hadoop.hdfs.DFSTestUtil;
29+
import org.apache.hadoop.hdfs.server.blockmanagement.BlockManager;
30+
import org.apache.hadoop.hdfs.server.blockmanagement.BlockManagerTestUtil;
31+
import org.apache.hadoop.hdfs.server.namenode.ha.EditLogTailer;
32+
import org.apache.hadoop.test.Whitebox;
33+
34+
import static org.mockito.Mockito.doAnswer;
35+
import static org.mockito.Mockito.spy;
36+
37+
/**
38+
* This is a Mockito based utility class to expose NameNode functionality for unit tests.
39+
*/
40+
public final class NameNodeAdapterMockitoUtil {
41+
42+
private NameNodeAdapterMockitoUtil() {
43+
}
44+
45+
public static BlockManager spyOnBlockManager(NameNode nn) {
46+
BlockManager bmSpy = spy(nn.getNamesystem().getBlockManager());
47+
nn.getNamesystem().setBlockManagerForTesting(bmSpy);
48+
return bmSpy;
49+
}
50+
51+
public static ReentrantReadWriteLock spyOnFsLock(FSNamesystem fsn) {
52+
ReentrantReadWriteLock spy = spy(fsn.getFsLockForTests());
53+
fsn.setFsLockForTests(spy);
54+
return spy;
55+
}
56+
57+
public static FSImage spyOnFsImage(NameNode nn1) {
58+
FSNamesystem fsn = nn1.getNamesystem();
59+
FSImage spy = spy(fsn.getFSImage());
60+
Whitebox.setInternalState(fsn, "fsImage", spy);
61+
return spy;
62+
}
63+
64+
public static JournalSet spyOnJournalSet(NameNode nn) {
65+
FSEditLog editLog = nn.getFSImage().getEditLog();
66+
JournalSet js = spy(editLog.getJournalSet());
67+
editLog.setJournalSetForTesting(js);
68+
return js;
69+
}
70+
71+
public static FSNamesystem spyOnNamesystem(NameNode nn) {
72+
FSNamesystem fsnSpy = spy(nn.getNamesystem());
73+
FSNamesystem fsnOld = nn.namesystem;
74+
fsnOld.writeLock();
75+
fsnSpy.writeLock();
76+
nn.namesystem = fsnSpy;
77+
try {
78+
FieldUtils.writeDeclaredField(nn.getRpcServer(), "namesystem", fsnSpy, true);
79+
FieldUtils.writeDeclaredField(
80+
fsnSpy.getBlockManager(), "namesystem", fsnSpy, true);
81+
FieldUtils.writeDeclaredField(
82+
fsnSpy.getLeaseManager(), "fsnamesystem", fsnSpy, true);
83+
FieldUtils.writeDeclaredField(
84+
fsnSpy.getBlockManager().getDatanodeManager(),
85+
"namesystem", fsnSpy, true);
86+
FieldUtils.writeDeclaredField(
87+
BlockManagerTestUtil.getHeartbeatManager(fsnSpy.getBlockManager()),
88+
"namesystem", fsnSpy, true);
89+
} catch (IllegalAccessException e) {
90+
throw new RuntimeException("Cannot set spy FSNamesystem", e);
91+
} finally {
92+
fsnSpy.writeUnlock();
93+
fsnOld.writeUnlock();
94+
}
95+
return fsnSpy;
96+
}
97+
98+
public static FSEditLog spyOnEditLog(NameNode nn) {
99+
FSEditLog spyEditLog = spy(nn.getNamesystem().getFSImage().getEditLog());
100+
DFSTestUtil.setEditLogForTesting(nn.getNamesystem(), spyEditLog);
101+
EditLogTailer tailer = nn.getNamesystem().getEditLogTailer();
102+
if (tailer != null) {
103+
tailer.setEditLog(spyEditLog);
104+
}
105+
return spyEditLog;
106+
}
107+
108+
/**
109+
* Spy on EditLog to delay execution of doEditTransaction() for MkdirOp.
110+
*/
111+
public static FSEditLog spyDelayMkDirTransaction(
112+
final NameNode nn, final long delay) {
113+
FSEditLog realEditLog = nn.getFSImage().getEditLog();
114+
FSEditLogAsync spyEditLog = (FSEditLogAsync) spy(realEditLog);
115+
DFSTestUtil.setEditLogForTesting(nn.getNamesystem(), spyEditLog);
116+
Answer<Boolean> ans = invocation -> {
117+
Thread.sleep(delay);
118+
return (Boolean) invocation.callRealMethod();
119+
};
120+
ArgumentMatcher<FSEditLogOp> am = argument -> argument.opCode == FSEditLogOpCodes.OP_MKDIR;
121+
doAnswer(ans).when(spyEditLog).doEditTransaction(ArgumentMatchers.argThat(am));
122+
return spyEditLog;
123+
}
124+
}

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/ha/TestFailureToReadEdits.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.apache.hadoop.hdfs.server.namenode.FSEditLogOp;
5151
import org.apache.hadoop.hdfs.server.namenode.NameNode;
5252
import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapter;
53+
import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapterMockitoUtil;
5354
import org.apache.hadoop.test.GenericTestUtils;
5455
import org.apache.hadoop.util.ExitUtil.ExitException;
5556
import org.junit.After;
@@ -336,7 +337,7 @@ public void testFailureToReadEditsOnTransitionToActive() throws Exception {
336337
}
337338

338339
private LimitedEditLogAnswer causeFailureOnEditLogRead() throws IOException {
339-
FSEditLog spyEditLog = NameNodeAdapter.spyOnEditLog(nn1);
340+
FSEditLog spyEditLog = NameNodeAdapterMockitoUtil.spyOnEditLog(nn1);
340341
LimitedEditLogAnswer answer = new LimitedEditLogAnswer();
341342
doAnswer(answer).when(spyEditLog).selectInputStreams(
342343
anyLong(), anyLong(), any(), anyBoolean(), anyBoolean());

0 commit comments

Comments
 (0)