package org.apache.hadoop.hdfs;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.server.namenode.FSNamesystem;
import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
public class TestTotalFiles {
private static MiniDFSCluster cluster;
private static Configuration conf;
private static FileSystem fs;
private static final int BLOCK_SIZE = 1024;
private static final int MAX_BLOCKS = 10;
private static final int MAX_FILE_SIZE = MAX_BLOCKS * BLOCK_SIZE;
private static final Random random = new Random();
private static final Log LOG = LogFactory.getLog(TestTotalFiles.class);
@Before
public void setUp() throws Exception {
conf = new Configuration();
conf.setInt("dfs.block.size", BLOCK_SIZE);
cluster = new MiniDFSCluster(conf, 3, true, null);
fs = cluster.getFileSystem();
}
@After
public void tearDown() throws Exception {
cluster.shutdown();
}
private long getFilesTotal() throws Exception {
return fs.getContentSummary(new Path("/")).getFileCount();
}
@Test
public void testBasic() throws Exception {
String topDir = "testBasic";
DFSTestUtil util = new DFSTestUtil(topDir, 100, 10, MAX_FILE_SIZE);
util.createFiles(fs, topDir);
FSNamesystem namesystem = cluster.getNameNode().namesystem;
assertEquals(100, getFilesTotal());
assertTrue(namesystem.getFilesAndDirectoriesTotal() > getFilesTotal());
}
@Test
public void testRestart() throws Exception {
String topDir = "testRestart";
DFSTestUtil util = new DFSTestUtil(topDir, 100, 10, MAX_FILE_SIZE);
util.createFiles(fs, topDir);
FSNamesystem namesystem = cluster.getNameNode().namesystem;
assertEquals(100, getFilesTotal());
assertTrue(namesystem.getFilesAndDirectoriesTotal() > getFilesTotal());
cluster.restartNameNodes();
namesystem = cluster.getNameNode().namesystem;
assertEquals(100, getFilesTotal());
assertTrue(namesystem.getFilesAndDirectoriesTotal() > getFilesTotal());
}
private int deleteFiles(DFSTestUtil util, String topDir) throws Exception {
int deleted = 0;
for (String fileName : util.getFileNames(topDir)) {
if (random.nextBoolean()) {
cluster.getNameNode().delete(fileName, false);
deleted++;
}
}
return deleted;
}
private int concatFiles(DFSTestUtil util, String topDir) throws Exception {
String files[] = util.getFileNames(topDir);
int index = random.nextInt(files.length - 1);
String target = files[index];
String[] srcs = Arrays.copyOfRange(files, index + 1, files.length);
cluster.getNameNode().concat(target, srcs, false);
return srcs.length;
}
@Test
public void testRestartWithSaveNamespace() throws Exception {
String topDir = "/testRestartWithSaveNamespace";
FSNamesystem namesystem = null;
int totalFiles = 0;
for (int i = 0; i < 10; i++) {
DFSTestUtil util = new DFSTestUtil(topDir, 5, 10, MAX_FILE_SIZE);
util.createFiles(fs, topDir);
DFSTestUtil util1 = new DFSTestUtil(topDir, 5, 1, MAX_FILE_SIZE);
util1.createFiles(fs, topDir);
totalFiles += 10;
totalFiles -= deleteFiles(util, topDir);
totalFiles -= concatFiles(util1, topDir);
if (random.nextBoolean()) {
cluster.getNameNode().saveNamespace(true, false);
}
namesystem = cluster.getNameNode().namesystem;
assertEquals(totalFiles, getFilesTotal());
cluster.restartNameNodes();
namesystem = cluster.getNameNode().namesystem;
assertEquals(totalFiles, getFilesTotal());
}
assertTrue(namesystem.getFilesAndDirectoriesTotal() > getFilesTotal());
}
@Test
public void testDeletes() throws Exception {
String topDir = "testDeletes";
DFSTestUtil util = new DFSTestUtil(topDir, 100, 10, MAX_FILE_SIZE);
util.createFiles(fs, topDir);
FSNamesystem namesystem = cluster.getNameNode().namesystem;
assertEquals(100, getFilesTotal());
assertTrue(namesystem.getFilesAndDirectoriesTotal() > getFilesTotal());
int deleted = 0;
for (String fileName : util.getFileNames(topDir)) {
if (random.nextBoolean()) {
deleted++;
fs.delete(new Path(fileName), false);
}
}
assertEquals(100 - deleted, getFilesTotal());
}
@Test
public void testConcat() throws Exception {
String topDir = "/testConcat";
DFSTestUtil util = new DFSTestUtil(topDir, 100, 1, MAX_FILE_SIZE);
util.createFiles(fs, topDir);
FSNamesystem namesystem = cluster.getNameNode().namesystem;
assertEquals(100, getFilesTotal());
assertTrue(namesystem.getFilesAndDirectoriesTotal() > getFilesTotal());
String[] files = util.getFileNames(topDir);
for (int i = 0; i < files.length; i += 10) {
String target = files[i];
String[] srcs = Arrays.copyOfRange(files, i + 1, i + 10);
cluster.getNameNode().concat(target, srcs, false);
}
assertEquals(10, getFilesTotal());
}
@Test
public void testHardLink() throws Exception {
String topDir = "/testHardLink";
DFSTestUtil util = new DFSTestUtil(topDir, 10, 1, MAX_FILE_SIZE);
util.createFiles(fs, topDir);
FSNamesystem namesystem = cluster.getNameNode().namesystem;
assertEquals(10, getFilesTotal());
assertTrue(namesystem.getFilesAndDirectoriesTotal() > getFilesTotal());
String[] files = util.getFileNames(topDir);
int expectedFiles = 10;
for (int i = 0; i < files.length; i++) {
for (int j = 0; j < 3; j++) {
String target = files[i] + "hardlink" + j;
cluster.getNameNode().hardLink(files[i], target);
expectedFiles++;
if (random.nextBoolean()) {
cluster.getNameNode().delete(target, false);
expectedFiles--;
}
}
}
assertEquals(expectedFiles, getFilesTotal());
}
@Test
public void testHardLinkDirectoryDeletes() throws Exception {
String topDir = "/testHardLink";
int nFiles = 10;
int nLinks = 10;
DFSTestUtil util = new DFSTestUtil(topDir, nFiles, 1, MAX_FILE_SIZE);
util.createFiles(fs, topDir);
String[] files = util.getFileNames(topDir);
for (String file : files) {
for (int i = 0; i < nLinks; i++) {
cluster.getNameNode().hardLink(file, file + "_h_" + i);
}
}
int root = 1;
FSNamesystem namesystem = cluster.getNameNode().getNamesystem();
assertEquals(root + 1 + nFiles * (nLinks + 1),
namesystem.getFilesAndDirectoriesTotal());
assertEquals(nFiles * (nLinks + 1), getFilesTotal());
// save namespace should succeed
cluster.getNameNode().saveNamespace(true, false);
// delete the top directory
cluster.getNameNode().delete(topDir, true);
// one directory left
assertEquals(root, namesystem.getFilesAndDirectoriesTotal());
// save namespace should succeed
cluster.getNameNode().saveNamespace(true, false);
// one directory left
assertEquals(root, namesystem.getFilesAndDirectoriesTotal());
}
}