/// <summary> /// Verify that the given list of streams contains exactly the range of /// transactions specified, inclusive. /// </summary> /// <exception cref="System.IO.IOException"/> public static void VerifyEdits(IList <EditLogInputStream> streams, int firstTxnId, int lastTxnId) { IEnumerator <EditLogInputStream> iter = streams.GetEnumerator(); NUnit.Framework.Assert.IsTrue(iter.HasNext()); EditLogInputStream stream = iter.Next(); for (int expected = firstTxnId; expected <= lastTxnId; expected++) { FSEditLogOp op = stream.ReadOp(); while (op == null) { NUnit.Framework.Assert.IsTrue("Expected to find txid " + expected + ", " + "but no more streams available to read from" , iter.HasNext()); stream = iter.Next(); op = stream.ReadOp(); } NUnit.Framework.Assert.AreEqual(FSEditLogOpCodes.OpMkdir, op.opCode); NUnit.Framework.Assert.AreEqual(expected, op.GetTransactionId()); } NUnit.Framework.Assert.IsNull(stream.ReadOp()); NUnit.Framework.Assert.IsFalse("Expected no more txns after " + lastTxnId + " but more streams are available" , iter.HasNext()); }
public virtual void TestReaderWhileAnotherWrites() { QuorumJournalManager readerQjm = CloseLater(CreateSpyingQJM()); IList <EditLogInputStream> streams = Lists.NewArrayList(); readerQjm.SelectInputStreams(streams, 0, false); NUnit.Framework.Assert.AreEqual(0, streams.Count); QJMTestUtil.WriteSegment(cluster, qjm, 1, 3, true); readerQjm.SelectInputStreams(streams, 0, false); try { NUnit.Framework.Assert.AreEqual(1, streams.Count); // Validate the actual stream contents. EditLogInputStream stream = streams[0]; NUnit.Framework.Assert.AreEqual(1, stream.GetFirstTxId()); NUnit.Framework.Assert.AreEqual(3, stream.GetLastTxId()); QJMTestUtil.VerifyEdits(streams, 1, 3); NUnit.Framework.Assert.IsNull(stream.ReadOp()); } finally { IOUtils.Cleanup(Log, Sharpen.Collections.ToArray(streams, new IDisposable[0])); streams.Clear(); } // Ensure correct results when there is a stream in-progress, but we don't // ask for in-progress. QJMTestUtil.WriteSegment(cluster, qjm, 4, 3, false); readerQjm.SelectInputStreams(streams, 0, false); try { NUnit.Framework.Assert.AreEqual(1, streams.Count); EditLogInputStream stream = streams[0]; NUnit.Framework.Assert.AreEqual(1, stream.GetFirstTxId()); NUnit.Framework.Assert.AreEqual(3, stream.GetLastTxId()); QJMTestUtil.VerifyEdits(streams, 1, 3); } finally { IOUtils.Cleanup(Log, Sharpen.Collections.ToArray(streams, new IDisposable[0])); streams.Clear(); } // TODO: check results for selectInputStreams with inProgressOK = true. // This doesn't currently work, due to a bug where RedundantEditInputStream // throws an exception if there are any unvalidated in-progress edits in the list! // But, it shouldn't be necessary for current use cases. qjm.FinalizeLogSegment(4, 6); readerQjm.SelectInputStreams(streams, 0, false); try { NUnit.Framework.Assert.AreEqual(2, streams.Count); NUnit.Framework.Assert.AreEqual(4, streams[1].GetFirstTxId()); NUnit.Framework.Assert.AreEqual(6, streams[1].GetLastTxId()); QJMTestUtil.VerifyEdits(streams, 1, 6); } finally { IOUtils.Cleanup(Log, Sharpen.Collections.ToArray(streams, new IDisposable[0])); streams.Clear(); } }
/// <summary>Loads edits file, uses visitor to process all elements</summary> /// <exception cref="System.IO.IOException"/> public override void LoadEdits() { try { visitor.Start(inputStream.GetVersion(true)); while (true) { try { FSEditLogOp op = inputStream.ReadOp(); if (op == null) { break; } if (fixTxIds) { if (nextTxId <= 0) { nextTxId = op.GetTransactionId(); if (nextTxId <= 0) { nextTxId = 1; } } op.SetTransactionId(nextTxId); nextTxId++; } visitor.VisitOp(op); } catch (IOException e) { if (!recoveryMode) { // Tell the visitor to clean up, then re-throw the exception Log.Error("Got IOException at position " + inputStream.GetPosition()); visitor.Close(e); throw; } Log.Error("Got IOException while reading stream! Resyncing.", e); inputStream.Resync(); } catch (RuntimeException e) { if (!recoveryMode) { // Tell the visitor to clean up, then re-throw the exception Log.Error("Got RuntimeException at position " + inputStream.GetPosition()); visitor.Close(e); throw; } Log.Error("Got RuntimeException while reading stream! Resyncing.", e); inputStream.Resync(); } } visitor.Close(null); } finally { IOUtils.Cleanup(Log, inputStream); } }