org.apache.hadoop.raid.TestStatisticsCollector.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.raid.TestStatisticsCollector.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.raid;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.zip.CRC32;

import junit.framework.TestCase;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.raid.Statistics.Counters;
import org.apache.hadoop.raid.protocol.PolicyInfo;
import org.apache.hadoop.raid.Utils.Builder;

/**
 * Verifies {@link Statistics} collects raid statistics
 */
public class TestStatisticsCollector extends TestCase {
    public TestStatisticsCollector(String name) {
        super(name);
    }

    final static Log LOG = LogFactory.getLog(TestStatisticsCollector.class);
    final static Random rand = new Random();
    final Configuration conf = new Configuration();
    final FakeConfigManager fakeConfigManager = new FakeConfigManager();
    final FakeRaidNode fakeRaidNode = new FakeRaidNode();

    // Test scenario with mixed file-level raid and dir-level raid 
    public void testCollectMixedRaid() throws Exception {
        MiniDFSCluster dfs = null;
        try {
            conf.setLong(RaidNode.MINIMUM_RAIDABLE_FILESIZE_KEY, 0L);
            dfs = new MiniDFSCluster(conf, 3, true, null);
            dfs.waitActive();
            FileSystem fs = dfs.getFileSystem();
            TestDirectoryRaidDfs.setupStripeStore(conf, fs);
            // load the test directory codecs.
            Utils.loadTestCodecs(conf, new Builder[] { Utils.getDirXORBuilder(), Utils.getDirRSBuilder(),
                    Utils.getRSBuilder(), Utils.getXORBuilder() });
            List<PolicyInfo> allPolicies = new ArrayList<PolicyInfo>();
            for (Codec codec : Codec.getCodecs()) {
                PolicyInfo info = new PolicyInfo(codec.id, conf);
                info.setSrcPath("/a");
                info.setProperty("modTimePeriod", "0");
                info.setProperty("targetReplication", "1");
                info.setCodecId(codec.id);
                allPolicies.add(info);
            }
            createFile(fs, new Path("/a/dir-xor/RAIDED1"), 1, 3, 512L);
            createFile(fs, new Path("/a/dir-xor/RAIDED2"), 1, 3, 512L);
            doRaid(fs, new Path("/a/dir-xor"), Codec.getCodec("dir-xor"), 1, 1);

            createFile(fs, new Path("/a/dir-rs/RAIDED1"), 1, 3, 512L);
            createFile(fs, new Path("/a/dir-rs/RAIDED2"), 1, 3, 512L);
            doRaid(fs, new Path("/a/dir-rs"), Codec.getCodec("dir-rs"), 1, 1);

            createFile(fs, new Path("/a/xor/RAIDED1"), 1, 3, 512L);
            createFile(fs, new Path("/a/xor/RAIDED2"), 1, 3, 512L);
            doRaid(fs, new Path("/a/xor/RAIDED1"), Codec.getCodec("xor"), 1, 1);
            doRaid(fs, new Path("/a/xor/RAIDED2"), Codec.getCodec("xor"), 1, 1);

            createFile(fs, new Path("/a/rs/RAIDED1"), 1, 3, 512L);
            createFile(fs, new Path("/a/rs/RAIDED2"), 1, 3, 512L);
            doRaid(fs, new Path("/a/rs/RAIDED1"), Codec.getCodec("rs"), 1, 1);
            doRaid(fs, new Path("/a/rs/RAIDED2"), Codec.getCodec("rs"), 1, 1);

            StatisticsCollector collector = new StatisticsCollector(fakeRaidNode, fakeConfigManager, conf);
            collector.collect(allPolicies);
            for (Codec codec : Codec.getCodecs()) {
                Statistics st = collector.getRaidStatistics(codec.id);
                Counters raided = st.getSourceCounters(RaidState.RAIDED);
                if (codec.isDirRaid) {
                    assertCounters(raided, 1, 2, 6, 6 * 512L, 6 * 512L);
                } else {
                    assertCounters(raided, 2, 6, 6 * 512L, 6 * 512L);
                }
            }
        } finally {
            if (dfs != null) {
                dfs.shutdown();
            }
        }
    }

    // Test the case that raided files are counted for low-priority policies
    public void testLowPriorityRaidedPolicy() throws Exception {
        MiniDFSCluster dfs = null;
        try {
            conf.setLong(RaidNode.MINIMUM_RAIDABLE_FILESIZE_KEY, 0L);
            dfs = new MiniDFSCluster(conf, 3, true, null);
            dfs.waitActive();
            FileSystem fs = dfs.getFileSystem();
            TestDirectoryRaidDfs.setupStripeStore(conf, fs);
            Utils.loadTestCodecs(conf, new Builder[] { Utils.getDirXORBuilder(), Utils.getDirRSBuilder(),
                    Utils.getXORBuilder(), Utils.getRSBuilder() });
            verifyLowPrioritySourceCollect("xor", "rs", fs);
            verifyLowPrioritySourceCollect("dir-xor", "dir-rs", fs);
        } finally {
            if (dfs != null) {
                dfs.shutdown();
            }
        }
    }

    public void verifyLowPrioritySourceCollect(String lpId, String hpId, FileSystem fs) throws IOException {
        PolicyInfo lpInfo = new PolicyInfo("Test-Low-Pri-" + lpId, conf);
        lpInfo.setSrcPath("/a");
        lpInfo.setProperty("modTimePeriod", "0");
        lpInfo.setProperty("targetReplication", "1");
        lpInfo.setCodecId(lpId);

        PolicyInfo hpInfo = new PolicyInfo("Test-High-Pri-" + hpId, conf);
        hpInfo.setSrcPath("/a");
        hpInfo.setProperty("modTimePeriod", "0");
        hpInfo.setProperty("targetReplication", "2");
        hpInfo.setCodecId(hpId);

        Codec lpCodec = Codec.getCodec(lpId);
        createFile(fs, new Path("/a/b/f/g/RAIDED"), 1, 3, 1024L);
        doRaid(fs, new Path("/a/b/f/g/RAIDED"), lpCodec, 1, 1);
        createFile(fs, new Path("/a/b/f/h/RAIDED"), 1, 4, 1024L);
        doRaid(fs, new Path("/a/b/f/h/RAIDED"), lpCodec, 1, 1);
        createFile(fs, new Path("/a/b/f/i/NOT_RAIDED"), 3, 5, 1024L);

        StatisticsCollector collector = new StatisticsCollector(fakeRaidNode, fakeConfigManager, conf);
        List<PolicyInfo> allPolicies = Arrays.asList(lpInfo, hpInfo);
        collector.collect(allPolicies);
        Statistics lpSt = collector.getRaidStatistics(lpId);
        LOG.info("Statistics collected " + lpSt);
        LOG.info("Statistics html:\n " + lpSt.htmlTable());
        Counters raided = lpSt.getSourceCounters(RaidState.RAIDED);
        Counters tooSmall = lpSt.getSourceCounters(RaidState.NOT_RAIDED_TOO_SMALL);
        Counters tooNew = lpSt.getSourceCounters(RaidState.NOT_RAIDED_TOO_NEW);
        Counters otherPolicy = lpSt.getSourceCounters(RaidState.NOT_RAIDED_OTHER_POLICY);
        Counters notRaided = lpSt.getSourceCounters(RaidState.NOT_RAIDED_BUT_SHOULD);
        assertCounters(raided, lpCodec.isDirRaid ? 2 : 0, 2, 7, 7 * 1024L, 7 * 1024L);
        assertCounters(tooSmall, 0, 0, 0, 0L, 0L);
        assertCounters(tooNew, 0, 0, 0, 0L, 0L);
        // the NOT_RAIDED files could be raided by high priority policy 
        assertCounters(otherPolicy, lpCodec.isDirRaid ? 1 : 0, 1, 5, 15 * 1024L, 5 * 1024L);
        assertCounters(notRaided, 0, 0, 0, 0L, 0L);
        fs.delete(new Path("/a"), true);
    }

    public void testExcludes() throws IOException {
        conf.set("raid.exclude.patterns", "/exclude/,/df_mf/");
        RaidState.Checker checker = new RaidState.Checker(new ArrayList<PolicyInfo>(), conf);
        assertEquals(true, checker.shouldExclude("/a/b/c/df_mf/foo/bar"));
        assertEquals(false, checker.shouldExclude("/a/b/c/xdf_mf/foo/bar"));
    }

    public void testExcludeTrash() throws IOException {
        RaidState.Checker checker = new RaidState.Checker(new ArrayList<PolicyInfo>(), conf);
        assertEquals(true, checker.shouldExclude("/a/b/c/.Trash/foo/bar"));
        assertEquals(false, checker.shouldExclude("/a/b/c/foo/bar"));
    }

    public void testTimeFromName() {
        assertEquals(new Date(2011 - 1900, 0, 12).getTime(),
                RaidState.Checker.mtimeFromName("/a/b/c/ds=2011-01-12/d/e/f"));
        assertEquals(new Date(2011 - 1900, 0, 12).getTime(),
                RaidState.Checker.mtimeFromName("/a/b/c/ds=2011-01-12-02/d/e/f"));
        assertEquals(-1, RaidState.Checker.mtimeFromName("/a/b/c/ds=2011/d/e/f"));
        assertEquals(-1, RaidState.Checker.mtimeFromName("/a/b/c/d/e/f"));
    }

    public void testCollect() throws Exception {
        MiniDFSCluster dfs = null;
        try {
            dfs = new MiniDFSCluster(conf, 3, true, null);
            dfs.waitActive();
            FileSystem fs = dfs.getFileSystem();
            TestDirectoryRaidDfs.setupStripeStore(conf, fs);
            Utils.loadTestCodecs(conf);
            verifySourceCollect("rs", fs, false);
            verifySourceCollect("xor", fs, false);
            verifyParityCollect("rs", fs);
            verifyParityCollect("xor", fs);
            verifyLongPrefixOverride(fs);
            verifyRsCodeOverride(fs);
        } finally {
            if (dfs != null) {
                dfs.shutdown();
            }
        }
    }

    public void testCollectDirRaid() throws Exception {

        MiniDFSCluster dfs = null;
        try {
            conf.setLong(RaidNode.MINIMUM_RAIDABLE_FILESIZE_KEY, 0L);
            dfs = new MiniDFSCluster(conf, 3, true, null);
            dfs.waitActive();
            FileSystem fs = dfs.getFileSystem();
            TestDirectoryRaidDfs.setupStripeStore(conf, fs);
            // load the test directory codecs.
            Utils.loadTestCodecs(conf, new Builder[] { Utils.getDirXORBuilder(), Utils.getDirRSBuilder() });
            verifyDirRaidSourceCollect("dir-rs", fs, false);
            verifyDirRaidSourceCollect("dir-xor", fs, false);
            verifyParityCollect("dir-rs", fs);
            verifyParityCollect("dir-xor", fs);
        } finally {
            if (dfs != null) {
                dfs.shutdown();
            }
        }
    }

    public void testSnapshot() throws Exception {
        conf.set(StatisticsCollector.STATS_SNAPSHOT_FILE_KEY, "/tmp/raidStatsSnapshot");
        MiniDFSCluster dfs = null;
        try {
            Utils.loadTestCodecs(conf);
            dfs = new MiniDFSCluster(conf, 3, true, null);
            dfs.waitActive();
            FileSystem fs = dfs.getFileSystem();
            TestDirectoryRaidDfs.setupStripeStore(conf, fs);
            verifySourceCollect("rs", fs, true);
        } finally {
            if (dfs != null) {
                dfs.shutdown();
            }
        }
    }

    public void verifyDirRaidSourceCollect(String codecId, FileSystem fs, boolean writeAndRestoreSnapshot)
            throws IOException {
        PolicyInfo info = new PolicyInfo("Test-Dir-Raid-" + codecId, conf);
        info.setSrcPath("/a");
        info.setProperty("modTimePeriod", "0");
        info.setProperty("targetReplication", "1");
        info.setCodecId(codecId);

        PolicyInfo infoTooNew = new PolicyInfo("Test-Too-New-" + codecId, conf);
        infoTooNew.setSrcPath("/new");
        infoTooNew.setProperty("modTimePeriod", "" + Long.MAX_VALUE);
        infoTooNew.setProperty("targetReplication", "1");
        infoTooNew.setCodecId(codecId);

        Codec curCodec = Codec.getCodec(codecId);

        createFile(fs, new Path("/a/b/NOT_RAIDED1"), 1, 1, 1024L);
        createFile(fs, new Path("/a/b/NOT_RAIDED2"), 2, 2, 1024L);
        createFile(fs, new Path("/a/b/NOT_RAIDED3"), 1, 3, 1024L);

        createFile(fs, new Path("/a/c/RAIDED1"), 1, 1, 1024L);
        createFile(fs, new Path("/a/c/RAIDED2"), 1, 2, 1024L);
        createFile(fs, new Path("/a/c/RAIDED3"), 1, 3, 1024L);
        createFile(fs, new Path("/a/c/RAIDED4"), 1, 4, 1024L);
        createFile(fs, new Path("/a/c/RAIDED5"), 1, 5, 1024L);
        doRaid(fs, new Path("/a/c"), curCodec, 1, 1);

        createFile(fs, new Path("/a/d/TOO_SMALL1"), 1, 1, 1024L);
        createFile(fs, new Path("/a/d/TOO_SMALL2"), 2, 1, 1024L);

        createFile(fs, new Path("/new/TOO_NEW1"), 3, 4, 1024L);
        createFile(fs, new Path("/new/TOO_NEW2"), 3, 5, 1024L);

        StatisticsCollector collector = new StatisticsCollector(fakeRaidNode, fakeConfigManager, conf);
        List<PolicyInfo> allPolicies = Arrays.asList(info, infoTooNew);
        collector.collect(allPolicies);
        Statistics st = collector.getRaidStatistics(codecId);

        LOG.info("Dir Statistics collected " + st);
        LOG.info("Dir Statistics html:\n " + st.htmlTable());
        Counters raided = st.getSourceCounters(RaidState.RAIDED);
        Counters tooSmall = st.getSourceCounters(RaidState.NOT_RAIDED_TOO_SMALL);
        Counters tooNew = st.getSourceCounters(RaidState.NOT_RAIDED_TOO_NEW);
        Counters notRaided = st.getSourceCounters(RaidState.NOT_RAIDED_BUT_SHOULD);

        assertCounters(raided, 1, 5, 15, 15 * 1024L, 15 * 1024L);
        assertCounters(tooSmall, 1, 2, 2, 3 * 1024L, 2 * 1024L);
        assertCounters(tooNew, 1, 2, 9, 27 * 1024L, 9 * 1024L);
        assertCounters(notRaided, 1, 3, 6, 8 * 1024L, 6 * 1024L);
    }

    public void verifySourceCollect(String codecId, FileSystem fs, boolean writeAndRestoreSnapshot)
            throws Exception {
        PolicyInfo info = new PolicyInfo("Test-Raided-" + codecId, conf);
        info.setSrcPath("/a/b");
        info.setProperty("modTimePeriod", "0");
        info.setProperty("targetReplication", "1");
        info.setCodecId(codecId);

        PolicyInfo infoTooNew = new PolicyInfo("Test-Too-New-" + codecId, conf);
        infoTooNew.setSrcPath("/a/new");
        infoTooNew.setProperty("modTimePeriod", "" + Long.MAX_VALUE);
        infoTooNew.setProperty("targetReplication", "1");
        infoTooNew.setCodecId(codecId);

        Codec curCodec = Codec.getCodec(codecId);
        createFile(fs, new Path("/a/b/TOO_SMALL"), 1, 1, 1024L);
        createFile(fs, new Path("/a/b/d/TOO_SMALL"), 2, 2, 1024L);
        createFile(fs, new Path("/a/b/f/g/RAIDED"), 1, 3, 1024L);
        doRaid(fs, new Path("/a/b/f/g/RAIDED"), curCodec, 1, 1);
        createFile(fs, new Path("/a/b/f/g/h/RAIDED"), 1, 4, 1024L);
        doRaid(fs, new Path("/a/b/f/g/h/RAIDED"), curCodec, 1, 1);
        createFile(fs, new Path("/a/b/f/g/NOT_RAIDED"), 3, 5, 1024L);

        createFile(fs, new Path("/a/new/i/TOO_NEW"), 3, 4, 1024L);
        createFile(fs, new Path("/a/new/j/TOO_NEW"), 3, 5, 1024L);

        StatisticsCollector collector = new StatisticsCollector(fakeRaidNode, fakeConfigManager, conf);
        List<PolicyInfo> allPolicies = Arrays.asList(info, infoTooNew);
        collector.collect(allPolicies);
        Statistics st = collector.getRaidStatistics(codecId);
        LOG.info("Statistics collected " + st);
        LOG.info("Statistics html:\n " + st.htmlTable());
        Counters raided = st.getSourceCounters(RaidState.RAIDED);
        Counters tooSmall = st.getSourceCounters(RaidState.NOT_RAIDED_TOO_SMALL);
        Counters tooNew = st.getSourceCounters(RaidState.NOT_RAIDED_TOO_NEW);
        Counters notRaided = st.getSourceCounters(RaidState.NOT_RAIDED_BUT_SHOULD);
        assertCounters(raided, 2, 7, 7 * 1024L, 7 * 1024L);
        assertCounters(tooSmall, 2, 3, 5 * 1024L, 3 * 1024L);
        assertCounters(tooNew, 2, 9, 27 * 1024L, 9 * 1024L);
        assertCounters(notRaided, 1, 5, 15 * 1024L, 5 * 1024L);
        fs.delete(new Path("/a"), true);

        if (writeAndRestoreSnapshot) {
            Map<String, Statistics> stats = collector.getRaidStatisticsMap();
            assertTrue(collector.writeStatsSnapshot());
            collector.clearRaidStatisticsMap();
            assertEquals(null, collector.getRaidStatisticsMap());

            assertTrue(collector.readStatsSnapshot());
            Map<String, Statistics> diskStats = collector.getRaidStatisticsMap();
            assertEquals(stats, diskStats);
        }
    }

    public void verifyParityCollect(String codecId, FileSystem fs) throws Exception {
        LOG.info("Start testing parity collect for " + codecId);
        Codec codec = Codec.getCodec(codecId);
        Path parityPath = new Path(codec.parityDirectory);
        if (fs.exists(parityPath)) {
            fs.delete(parityPath, true);
        }
        fs.mkdirs(parityPath);
        createFile(fs, new Path(parityPath + "/a"), 1, 1, 1024L);
        createFile(fs, new Path(parityPath + "/b/c"), 2, 2, 1024L);
        createFile(fs, new Path(parityPath + "/d/e/f"), 3, 3, 1024L);
        List<PolicyInfo> empty = Collections.emptyList();
        StatisticsCollector collector = new StatisticsCollector(fakeRaidNode, fakeConfigManager, conf);
        collector.collect(empty);
        Statistics st = collector.getRaidStatistics(codecId);
        assertCounters(st.getParityCounters(), 3, 6, 14 * 1024L, 6 * 1024L);
        LOG.info("Statistics collected " + st);
        LOG.info("Statistics html:\n " + st.htmlTable());
        fs.delete(parityPath, true);
    }

    public void verifyLongPrefixOverride(FileSystem fs) throws Exception {
        PolicyInfo info = new PolicyInfo("Test", conf);
        info.setSrcPath("/a/b");
        info.setProperty("modTimePeriod", "0");
        info.setProperty("targetReplication", "1");
        info.setCodecId("rs");

        PolicyInfo infoLongPrefix = new PolicyInfo("Long-Prefix", conf);
        infoLongPrefix.setSrcPath("/a/b/c");
        infoLongPrefix.setProperty("modTimePeriod", "0");
        infoLongPrefix.setProperty("targetReplication", "2");
        infoLongPrefix.setCodecId("xor");

        createFile(fs, new Path("/a/b/k"), 3, 4, 1024L);
        createFile(fs, new Path("/a/b/c/d"), 3, 5, 1024L);
        StatisticsCollector collector = new StatisticsCollector(fakeRaidNode, fakeConfigManager, conf);
        List<PolicyInfo> allPolicies = Arrays.asList(info, infoLongPrefix);
        collector.collect(allPolicies);
        Statistics xorSt = collector.getRaidStatistics("xor");
        Statistics rsSt = collector.getRaidStatistics("rs");
        Counters xorShouldRaid = xorSt.getSourceCounters(RaidState.NOT_RAIDED_BUT_SHOULD);
        Counters rsShouldRaid = rsSt.getSourceCounters(RaidState.NOT_RAIDED_BUT_SHOULD);
        Counters rsOther = rsSt.getSourceCounters(RaidState.NOT_RAIDED_OTHER_POLICY);
        assertCounters(xorShouldRaid, 1, 5, 15 * 1024L, 5 * 1024L);
        assertCounters(rsShouldRaid, 1, 4, 12 * 1024L, 4 * 1024L);
        assertCounters(rsOther, 1, 5, 15 * 1024L, 5 * 1024L);
        fs.delete(new Path("/a"), true);
    }

    public void verifyRsCodeOverride(FileSystem fs) throws Exception {
        PolicyInfo info = new PolicyInfo("Test", conf);
        info.setSrcPath("/a/b/*");
        info.setProperty("modTimePeriod", "0");
        info.setProperty("targetReplication", "1");
        info.setCodecId("xor");

        PolicyInfo infoLongPrefix = new PolicyInfo("Long-Prefix", conf);
        infoLongPrefix.setSrcPath("/a/b/c");
        infoLongPrefix.setProperty("modTimePeriod", "0");
        infoLongPrefix.setProperty("targetReplication", "2");
        infoLongPrefix.setCodecId("rs");

        createFile(fs, new Path("/a/b/k"), 3, 4, 1024L);
        createFile(fs, new Path("/a/b/c/d"), 3, 5, 1024L);
        StatisticsCollector collector = new StatisticsCollector(fakeRaidNode, fakeConfigManager, conf);
        List<PolicyInfo> allPolicies = Arrays.asList(info, infoLongPrefix);
        collector.collect(allPolicies);
        Statistics xorSt = collector.getRaidStatistics("xor");
        Statistics rsSt = collector.getRaidStatistics("rs");
        Counters xorShouldRaid = xorSt.getSourceCounters(RaidState.NOT_RAIDED_BUT_SHOULD);
        Counters xorOther = xorSt.getSourceCounters(RaidState.NOT_RAIDED_OTHER_POLICY);
        Counters rsShouldRaid = rsSt.getSourceCounters(RaidState.NOT_RAIDED_BUT_SHOULD);
        assertCounters(xorShouldRaid, 1, 4, 12 * 1024L, 4 * 1024L);
        assertCounters(xorOther, 1, 5, 15 * 1024L, 5 * 1024L);
        assertCounters(rsShouldRaid, 1, 5, 15 * 1024L, 5 * 1024L);
        fs.delete(new Path("/a"), true);
    }

    private void assertCounters(Counters counters, long numFiles, long numBlocks, long numBytes,
            long numLogicalBytes) {
        assertEquals(numFiles, counters.getNumFiles());
        assertEquals(numBlocks, counters.getNumBlocks());
        assertEquals(numBytes, counters.getNumBytes());
        assertEquals(numLogicalBytes, counters.getNumLogical());
    }

    private void assertCounters(Counters counters, long numDirs, long numFiles, long numBlocks, long numBytes,
            long numLogicalBytes) {
        assertEquals(numDirs, counters.getNumDirs());
        assertCounters(counters, numFiles, numBlocks, numBytes, numLogicalBytes);
    }

    private static void doRaid(FileSystem fileSys, Path name, Codec codec, int targetRepl, int metaRepl)
            throws IOException {
        FileStatus fileStat = fileSys.getFileStatus(name);
        if (codec.isDirRaid && !fileStat.isDir()) {
            // raid its parent
            fileStat = fileSys.getFileStatus(name.getParent());
        }
        assertTrue(RaidNode.doRaid(fileSys.getConf(), fileStat, new Path(codec.parityDirectory), codec,
                new RaidNode.Statistics(), RaidUtils.NULL_PROGRESSABLE, false, targetRepl, metaRepl));
    }

    private static long createFile(FileSystem fileSys, Path name, int repl, int numBlocks, long blocksize)
            throws IOException {
        CRC32 crc = new CRC32();
        int bufSize = fileSys.getConf().getInt("io.file.buffer.size", 4096);
        FSDataOutputStream stm = fileSys.create(name, true, bufSize, (short) repl, blocksize);
        // fill random data into file
        byte[] b = new byte[(int) blocksize];
        for (int i = 0; i < numBlocks; i++) {
            rand.nextBytes(b);
            stm.write(b);
            crc.update(b);
        }
        stm.close();
        return crc.getValue();
    }

    private class FakeRaidNode extends RaidNode {
        @Override
        int getRunningJobsForPolicy(String policyName) {
            return 0;
        }

        @Override
        void raidFiles(PolicyInfo info, List<FileStatus> paths) throws IOException {
            LOG.info("Raiding " + paths.size() + " files for policy:" + info.getName());
        }

        @Override
        public String raidJobsHtmlTable(JobMonitor.STATUS running) {
            return null;
        }
    }

    private class FakeConfigManager extends ConfigManager {
        @Override
        public int getMaxFilesPerJob() {
            return 3;
        }

        @Override
        public int getMaxJobsPerPolicy() {
            return 10;
        }
    }
}