/// <summary>Find out where the edit log ends.</summary>
 /// <remarks>
 /// Find out where the edit log ends.
 /// This will update the lastTxId of the EditLogFile or
 /// mark it as corrupt if it is.
 /// </remarks>
 /// <exception cref="System.IO.IOException"/>
 public virtual void ValidateLog()
 {
     FSEditLogLoader.EditLogValidation val = EditLogFileInputStream.ValidateEditLog(file
                                                                                    );
     this.lastTxId         = val.GetEndTxId();
     this.hasCorruptHeader = val.HasCorruptHeader();
 }
        public virtual void TestValidateEmptyEditLog()
        {
            FilePath testDir = new FilePath(TestDir, "testValidateEmptyEditLog");
            SortedDictionary <long, long> offsetToTxId = Maps.NewTreeMap();
            FilePath logFile = PrepareUnfinalizedTestEditLog(testDir, 0, offsetToTxId);

            // Truncate the file so that there is nothing except the header and
            // layout flags section.
            TruncateFile(logFile, 8);
            FSEditLogLoader.EditLogValidation validation = EditLogFileInputStream.ValidateEditLog
                                                               (logFile);
            NUnit.Framework.Assert.IsTrue(!validation.HasCorruptHeader());
            NUnit.Framework.Assert.AreEqual(HdfsConstants.InvalidTxid, validation.GetEndTxId(
                                                ));
        }
        public virtual void TestValidateEditLogWithCorruptBody()
        {
            FilePath testDir = new FilePath(TestDir, "testValidateEditLogWithCorruptBody");
            SortedDictionary <long, long> offsetToTxId = Maps.NewTreeMap();
            int      NumTxns = 20;
            FilePath logFile = PrepareUnfinalizedTestEditLog(testDir, NumTxns, offsetToTxId);
            // Back up the uncorrupted log
            FilePath logFileBak = new FilePath(testDir, logFile.GetName() + ".bak");

            Files.Copy(logFile, logFileBak);
            FSEditLogLoader.EditLogValidation validation = EditLogFileInputStream.ValidateEditLog
                                                               (logFile);
            NUnit.Framework.Assert.IsTrue(!validation.HasCorruptHeader());
            // We expect that there will be an OP_START_LOG_SEGMENT, followed by
            // NUM_TXNS opcodes, followed by an OP_END_LOG_SEGMENT.
            NUnit.Framework.Assert.AreEqual(NumTxns + 1, validation.GetEndTxId());
            // Corrupt each edit and verify that validation continues to work
            foreach (KeyValuePair <long, long> entry in offsetToTxId)
            {
                long txOffset = entry.Key;
                long txId     = entry.Value;
                // Restore backup, corrupt the txn opcode
                Files.Copy(logFileBak, logFile);
                CorruptByteInFile(logFile, txOffset);
                validation = EditLogFileInputStream.ValidateEditLog(logFile);
                long expectedEndTxId = (txId == (NumTxns + 1)) ? NumTxns : (NumTxns + 1);
                NUnit.Framework.Assert.AreEqual("Failed when corrupting txn opcode at " + txOffset
                                                , expectedEndTxId, validation.GetEndTxId());
                NUnit.Framework.Assert.IsTrue(!validation.HasCorruptHeader());
            }
            // Truncate right before each edit and verify that validation continues
            // to work
            foreach (KeyValuePair <long, long> entry_1 in offsetToTxId)
            {
                long txOffset = entry_1.Key;
                long txId     = entry_1.Value;
                // Restore backup, corrupt the txn opcode
                Files.Copy(logFileBak, logFile);
                TruncateFile(logFile, txOffset);
                validation = EditLogFileInputStream.ValidateEditLog(logFile);
                long expectedEndTxId = (txId == 0) ? HdfsConstants.InvalidTxid : (txId - 1);
                NUnit.Framework.Assert.AreEqual("Failed when corrupting txid " + txId + " txn opcode "
                                                + "at " + txOffset, expectedEndTxId, validation.GetEndTxId());
                NUnit.Framework.Assert.IsTrue(!validation.HasCorruptHeader());
            }
        }
        public virtual void TestValidateEditLogWithCorruptHeader()
        {
            FilePath testDir = new FilePath(TestDir, "testValidateEditLogWithCorruptHeader");
            SortedDictionary <long, long> offsetToTxId = Maps.NewTreeMap();
            FilePath         logFile = PrepareUnfinalizedTestEditLog(testDir, 2, offsetToTxId);
            RandomAccessFile rwf     = new RandomAccessFile(logFile, "rw");

            try
            {
                rwf.Seek(0);
                rwf.WriteLong(42);
            }
            finally
            {
                // corrupt header
                rwf.Close();
            }
            FSEditLogLoader.EditLogValidation validation = EditLogFileInputStream.ValidateEditLog
                                                               (logFile);
            NUnit.Framework.Assert.IsTrue(validation.HasCorruptHeader());
        }