/// <summary>Create an unfinalized edit log for testing purposes</summary>
        /// <param name="testDir">Directory to create the edit log in</param>
        /// <param name="numTx">Number of transactions to add to the new edit log</param>
        /// <param name="offsetToTxId">
        /// A map from transaction IDs to offsets in the
        /// edit log file.
        /// </param>
        /// <returns>The new edit log file name.</returns>
        /// <exception cref="System.IO.IOException"/>
        private static FilePath PrepareUnfinalizedTestEditLog(FilePath testDir, int numTx
                                                              , SortedDictionary <long, long> offsetToTxId)
        {
            FilePath inProgressFile = new FilePath(testDir, NNStorage.GetInProgressEditsFileName
                                                       (1));
            FSEditLog fsel   = null;
            FSEditLog spyLog = null;

            try
            {
                fsel   = FSImageTestUtil.CreateStandaloneEditLog(testDir);
                spyLog = Org.Mockito.Mockito.Spy(fsel);
                // Normally, the in-progress edit log would be finalized by
                // FSEditLog#endCurrentLogSegment.  For testing purposes, we
                // disable that here.
                Org.Mockito.Mockito.DoNothing().When(spyLog).EndCurrentLogSegment(true);
                spyLog.OpenForWrite();
                NUnit.Framework.Assert.IsTrue("should exist: " + inProgressFile, inProgressFile.Exists
                                                  ());
                for (int i = 0; i < numTx; i++)
                {
                    long trueOffset = GetNonTrailerLength(inProgressFile);
                    long thisTxId   = spyLog.GetLastWrittenTxId() + 1;
                    offsetToTxId[trueOffset] = thisTxId;
                    System.Console.Error.WriteLine("txid " + thisTxId + " at offset " + trueOffset);
                    spyLog.LogDelete("path" + i, i, false);
                    spyLog.LogSync();
                }
            }
            finally
            {
                if (spyLog != null)
                {
                    spyLog.Close();
                }
                else
                {
                    if (fsel != null)
                    {
                        fsel.Close();
                    }
                }
            }
            return(inProgressFile);
        }
        /// <summary>
        /// Create an aborted in-progress log in the given directory, containing
        /// only a specified number of "mkdirs" operations.
        /// </summary>
        /// <exception cref="System.IO.IOException"/>
        public static void CreateAbortedLogWithMkdirs(FilePath editsLogDir, int numDirs,
                                                      long firstTxId, long newInodeId)
        {
            FSEditLog editLog = FSImageTestUtil.CreateStandaloneEditLog(editsLogDir);

            editLog.SetNextTxId(firstTxId);
            editLog.OpenForWrite();
            PermissionStatus perms = PermissionStatus.CreateImmutable("fakeuser", "fakegroup"
                                                                      , FsPermission.CreateImmutable((short)0x1ed));

            for (int i = 1; i <= numDirs; i++)
            {
                string         dirName = "dir" + i;
                INodeDirectory dir     = new INodeDirectory(newInodeId + i - 1, DFSUtil.String2Bytes(
                                                                dirName), perms, 0L);
                editLog.LogMkDir("/" + dirName, dir);
            }
            editLog.LogSync();
            editLog.AbortCurrentLogSegment();
        }
        /// <param name="args">arguments</param>
        /// <exception cref="System.IO.IOException"></exception>
        public static void Main(string[] args)
        {
            long  startingBlockId  = 1;
            int   numFiles         = 0;
            short replication      = 1;
            int   numBlocksPerFile = 0;
            long  blockSize        = 10;

            if (args.Length == 0)
            {
                PrintUsageExit();
            }
            for (int i = 0; i < args.Length; i++)
            {
                // parse command line
                if (args[i].Equals("-h"))
                {
                    PrintUsageExit();
                }
                if (args[i].Equals("-f"))
                {
                    if (i + 3 >= args.Length || args[i + 1].StartsWith("-") || args[i + 2].StartsWith
                            ("-") || args[i + 3].StartsWith("-"))
                    {
                        PrintUsageExit("Missing num files, starting block and/or number of blocks");
                    }
                    numFiles         = System.Convert.ToInt32(args[++i]);
                    startingBlockId  = System.Convert.ToInt32(args[++i]);
                    numBlocksPerFile = System.Convert.ToInt32(args[++i]);
                    if (numFiles <= 0 || numBlocksPerFile <= 0)
                    {
                        PrintUsageExit("numFiles and numBlocksPerFile most be greater than 0");
                    }
                }
                else
                {
                    if (args[i].Equals("-l"))
                    {
                        if (i + 1 >= args.Length)
                        {
                            PrintUsageExit("Missing block length");
                        }
                        blockSize = long.Parse(args[++i]);
                    }
                    else
                    {
                        if (args[i].Equals("-r") || args[i + 1].StartsWith("-"))
                        {
                            if (i + 1 >= args.Length)
                            {
                                PrintUsageExit("Missing replication factor");
                            }
                            replication = short.ParseShort(args[++i]);
                        }
                        else
                        {
                            if (args[i].Equals("-d"))
                            {
                                if (i + 1 >= args.Length || args[i + 1].StartsWith("-"))
                                {
                                    PrintUsageExit("Missing edits logs directory");
                                }
                                edits_dir = args[++i];
                            }
                            else
                            {
                                PrintUsageExit();
                            }
                        }
                    }
                }
            }
            FilePath editsLogDir     = new FilePath(edits_dir);
            FilePath subStructureDir = new FilePath(edits_dir + "/" + Storage.StorageDirCurrent
                                                    );

            if (!editsLogDir.Exists())
            {
                if (!editsLogDir.Mkdir())
                {
                    System.Console.Out.WriteLine("cannot create " + edits_dir);
                    System.Environment.Exit(-1);
                }
            }
            if (!subStructureDir.Exists())
            {
                if (!subStructureDir.Mkdir())
                {
                    System.Console.Out.WriteLine("cannot create subdirs of " + edits_dir);
                    System.Environment.Exit(-1);
                }
            }
            FileNameGenerator nameGenerator = new FileNameGenerator(BasePath, 100);
            FSEditLog         editLog       = FSImageTestUtil.CreateStandaloneEditLog(editsLogDir);

            editLog.OpenForWrite();
            AddFiles(editLog, numFiles, replication, numBlocksPerFile, startingBlockId, blockSize
                     , nameGenerator);
            editLog.LogSync();
            editLog.Close();
        }