|
@@ -27,6 +27,7 @@ import java.net.InetSocketAddress;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.Date;
|
|
|
import java.util.Random;
|
|
|
+import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
|
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
|
import org.apache.hadoop.fs.CommonConfigurationKeys;
|
|
@@ -36,8 +37,11 @@ import org.apache.hadoop.fs.FileSystem;
|
|
|
import org.apache.hadoop.fs.Path;
|
|
|
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
|
|
|
import org.apache.hadoop.hdfs.protocol.HdfsConstants.DatanodeReportType;
|
|
|
+import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapter;
|
|
|
+import org.apache.hadoop.test.MockitoUtil;
|
|
|
import org.apache.hadoop.util.Time;
|
|
|
import org.junit.Test;
|
|
|
+import org.mockito.Mockito;
|
|
|
|
|
|
/**
|
|
|
* This class tests the access time on files.
|
|
@@ -273,6 +277,37 @@ public class TestSetTimes {
|
|
|
cluster.shutdown();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Test that when access time updates are not needed, the FSNamesystem
|
|
|
+ * write lock is not taken by getBlockLocations.
|
|
|
+ * Regression test for HDFS-3981.
|
|
|
+ */
|
|
|
+ @Test(timeout=60000)
|
|
|
+ public void testGetBlockLocationsOnlyUsesReadLock() throws IOException {
|
|
|
+ Configuration conf = new HdfsConfiguration();
|
|
|
+ conf.setInt(DFSConfigKeys.DFS_NAMENODE_ACCESSTIME_PRECISION_KEY, 100*1000);
|
|
|
+ MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf)
|
|
|
+ .numDataNodes(0)
|
|
|
+ .build();
|
|
|
+ ReentrantReadWriteLock spyLock = NameNodeAdapter.spyOnFsLock(cluster.getNamesystem());
|
|
|
+ try {
|
|
|
+ // Create empty file in the FSN.
|
|
|
+ Path p = new Path("/empty-file");
|
|
|
+ DFSTestUtil.createFile(cluster.getFileSystem(), p, 0, (short)1, 0L);
|
|
|
+
|
|
|
+ // getBlockLocations() should not need the write lock, since we just created
|
|
|
+ // the file (and thus its access time is already within the 100-second
|
|
|
+ // accesstime precision configured above).
|
|
|
+ MockitoUtil.doThrowWhenCallStackMatches(
|
|
|
+ new AssertionError("Should not need write lock"),
|
|
|
+ ".*getBlockLocations.*")
|
|
|
+ .when(spyLock).writeLock();
|
|
|
+ cluster.getFileSystem().getFileBlockLocations(p, 0, 100);
|
|
|
+ } finally {
|
|
|
+ cluster.shutdown();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
|
new TestSetTimes().testTimes();
|