public void VerifyCommitAsTransaction() { using (TempFile temp1 = new TempFile()) using (TempFile temp2 = new TempFile()) { var options = new TransactedCompoundFile.Options(temp1.TempPath) { BlockSize = 512 }; const int count = 4; byte[] sample1 = new byte[options.MaxWriteSize / 3]; byte[] sample2 = (byte[])sample1.Clone(); new Random().NextBytes(sample1); new Random().NextBytes(sample2); using (TransactedCompoundFile file = new TransactedCompoundFile(options)) { for (uint h = 1u; h < count; h++) { Assert.AreEqual(h, file.Create()); } for (uint h = 1u; h < count; h++) { file.Write(h, sample1, 0, sample1.Length); } file.Commit();//persist. for (uint h = 1u; h < count; h++) { file.Write(h, sample2, 0, sample2.Length); } file.Commit(x => temp1.CopyTo(temp2.TempPath, true), 0); } options = new TransactedCompoundFile.Options(temp2.TempPath) { BlockSize = 512, CommitOnDispose = false }; //Verify primary has sample2 data options.LoadingRule = TransactedCompoundFile.LoadingRule.Primary; using (TransactedCompoundFile file = new TransactedCompoundFile(options)) { for (uint h = 1u; h < count; h++) { CompareBytes(sample2, 0, sample2.Length, IOStream.ReadAllBytes(file.Read(h))); } } //Verify secondary has sample1 data options.LoadingRule = TransactedCompoundFile.LoadingRule.Secondary; using (TransactedCompoundFile file = new TransactedCompoundFile(options)) { for (uint h = 1u; h < count; h++) { CompareBytes(sample1, 0, sample1.Length, IOStream.ReadAllBytes(file.Read(h))); } } } }
public void TestCommit() { using (TempFile temp = new TempFile()) using (TempFile temp2 = new TempFile()) { byte[] sample = new byte[1024]; new Random().NextBytes(sample); List <uint> handles = new List <uint>(); using (TransactedCompoundFile file = new TransactedCompoundFile( new TransactedCompoundFile.Options(temp.TempPath) { FileOptions = FileOptions.WriteThrough } )) { for (int i = 0; i < 1000; i++) { var hid = file.Create(); handles.Add(hid); file.Write(hid, sample, i, sample.Length - i); } file.Commit(); File.Copy(temp.TempPath, temp2.TempPath, true); } using (TransactedCompoundFile file = new TransactedCompoundFile(temp2.TempPath)) { for (int i = 0; i < 1000; i++) { CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(handles[i]))); } } } }
public void TestRevertWithChanges() { using (TempFile temp = new TempFile()) { byte[] sample = new byte[1024]; new Random().NextBytes(sample); List <uint> handles = new List <uint>(); using (TransactedCompoundFile file = new TransactedCompoundFile(temp.TempPath)) { for (int i = 0; i < 1000; i++) { var hid = file.Create(); handles.Add(hid); file.Write(hid, sample, i, sample.Length - i); CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(hid))); } file.Commit(); } using (TransactedCompoundFile file = new TransactedCompoundFile(temp.TempPath)) { byte[] dummy = new byte[1024]; for (int i = 0; i < 1000; i++) { file.Write(handles[i], dummy, 0, dummy.Length); file.Delete(handles[i]); } file.Rollback(); for (int i = 0; i < 1000; i++) { CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(handles[i]))); } } } }
public void TestClear() { using (TempFile temp = new TempFile()) { byte[] sample = new byte[1024]; new Random().NextBytes(sample); List <uint> handles = new List <uint>(); using (TransactedCompoundFile file = new TransactedCompoundFile(temp.TempPath)) { for (int i = 0; i < 100; i++) { var hid = file.Create(); handles.Add(hid); file.Write(hid, sample, i, sample.Length - i); CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(hid))); file.Commit(); } file.Clear(); for (int i = 0; i < 100; i++) { try { IOStream.ReadAllBytes(file.Read(handles[i])); Assert.Fail(); } catch (ArgumentOutOfRangeException) { } } } } }
public void TestLargeWrite() { using (TempFile temp = new TempFile()) { var options = new TransactedCompoundFile.Options(temp.TempPath) { BlockSize = 512 }; byte[] sample = new byte[options.MaxWriteSize]; new Random().NextBytes(sample); List <uint> handles = new List <uint>(); using (TransactedCompoundFile file = new TransactedCompoundFile(options)) { for (int i = 0; i < 2; i++) { var hid = file.Create(); handles.Add(hid); file.Write(hid, sample, i, sample.Length - i); CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(handles[i]))); } file.Commit(); } long size = temp.Info.Length; using (TransactedCompoundFile file = new TransactedCompoundFile(options)) { for (int i = 0; i < 2; i++) { CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(handles[i]))); file.Delete(handles[i]); } file.Commit(); Assert.AreEqual(size, temp.Info.Length); for (int i = 0; i < 252; i++) { var hid = file.Create(); handles.Add(hid); file.Write(hid, sample, i, 300); } file.Commit(); Assert.AreEqual(size, temp.Info.Length); file.Create(); Assert.AreNotEqual(size, temp.Info.Length); } } }
public void VerifyLoadRulesWithCorruptSecondary() { using (TempFile temp = new TempFile()) { var options = new TransactedCompoundFile.Options(temp.TempPath) { BlockSize = 512 }; const int count = 4; byte[] sample = new byte[options.MaxWriteSize / 3]; new Random().NextBytes(sample); using (TransactedCompoundFile file = new TransactedCompoundFile(options)) { for (uint h = 1u; h < count; h++) { Assert.AreEqual(h, file.Create()); } for (uint h = 1u; h < count; h++) { file.Write(h, sample, 0, sample.Length); } file.Commit(); } //Corrupts the secondary storage: using (Stream f = temp.Open()) { f.Seek(-100, SeekOrigin.End); f.Write(sample, 0, 100); } try { options.LoadingRule = TransactedCompoundFile.LoadingRule.Secondary; new TransactedCompoundFile(options).Dispose(); Assert.Fail("Should not load"); } catch (InvalidDataException) { } options.LoadingRule = TransactedCompoundFile.LoadingRule.Primary; using (TransactedCompoundFile file = new TransactedCompoundFile(options)) { for (uint h = 1u; h < count; h++) { CompareBytes(sample, 0, sample.Length, IOStream.ReadAllBytes(file.Read(h))); } //Commit fixes corruption file.Commit(); } options.LoadingRule = TransactedCompoundFile.LoadingRule.Secondary; new TransactedCompoundFile(options).Dispose(); } }
private static void CreateRoot(TransactedCompoundFile file) { uint rootId; rootId = file.Create(); if (rootId != TransactedCompoundFile.FirstIdentity) { throw new InvalidNodeHandleException(); } file.Write(rootId, new byte[0], 0, 0); file.Commit(); }
public void SimpleTest() { uint handle; byte[] bytes = RandomBytes(2140); using (TempFile temp = new TempFile()) { using (TransactedCompoundFile test = new TransactedCompoundFile(new TransactedCompoundFile.Options(temp.TempPath) { BlockSize = 512, CreateNew = true })) { Assert.AreEqual(TransactedCompoundFile.FirstIdentity, test.Create()); test.Write(TransactedCompoundFile.FirstIdentity, Encoding.UTF8.GetBytes("Roger was here."), 0, 15); Assert.AreEqual("Roger was here.", Encoding.UTF8.GetString(IOStream.ReadAllBytes(test.Read(TransactedCompoundFile.FirstIdentity)))); for (int i = 0; i < 10; i++) { var id = test.Create(); test.Write(id, bytes, i, 300); if (i % 2 == 0) { test.Delete(id); } } handle = test.Create(); test.Write(handle, bytes, 1000, bytes.Length - 1000); CompareBytes(bytes, 1000, bytes.Length - 1000, IOStream.ReadAllBytes(test.Read(handle))); test.Write(handle, bytes, 0, bytes.Length); CompareBytes(bytes, 0, bytes.Length, IOStream.ReadAllBytes(test.Read(handle))); test.Commit(); } using (TransactedCompoundFile test = new TransactedCompoundFile(new TransactedCompoundFile.Options(temp.TempPath) { BlockSize = 512, CreateNew = false })) { Assert.AreEqual("Roger was here.", Encoding.UTF8.GetString(IOStream.ReadAllBytes(test.Read(TransactedCompoundFile.FirstIdentity)))); CompareBytes(bytes, 0, bytes.Length, IOStream.ReadAllBytes(test.Read(handle))); } } }
void TestWriteWithOptions(TransactedCompoundFile.Options options) { byte[] sample = new byte[1024]; new Random().NextBytes(sample); List <uint> handles = new List <uint>(); using (TransactedCompoundFile file = new TransactedCompoundFile(options)) { for (int i = 0; i < 1000; i++) { var hid = file.Create(); handles.Add(hid); file.Write(hid, sample, i, sample.Length - i); CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(hid))); if (i == 500) { file.Commit(); } } } options.CreateNew = false; using (TransactedCompoundFile file = new TransactedCompoundFile(options)) { for (int i = 0; i < 1000; i++) { if (i <= 500 || options.CommitOnWrite || options.CommitOnDispose) { CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(handles[i]))); } else { try { IOStream.ReadAllBytes(file.Read(handles[i])); Assert.Fail(); } catch (ArgumentOutOfRangeException) { } } } } }
public void ConcurrencyTest() { using (TempFile temp = new TempFile()) using (ManualResetEvent stop = new ManualResetEvent(false)) using (TempFile copy = new TempFile()) using (TransactedCompoundFile test = new TransactedCompoundFile( new TransactedCompoundFile.Options(temp.TempPath) { BlockSize = 512, CreateNew = true })) using (WorkQueue workers = new WorkQueue(5)) { bool failed = false; workers.OnError += (o, e) => failed = true; for (int i = 0; i < 5; i++) { workers.Enqueue(() => ExersizeFile(stop, test)); } do { System.Threading.Thread.Sleep(1000); test.Commit(); File.Copy(temp.TempPath, copy.TempPath, true); Assert.AreEqual(0, copy.Length % 512); int hcount = (int)(copy.Length / 512); using (TransactedCompoundFile verify = new TransactedCompoundFile( new TransactedCompoundFile.Options(copy.TempPath) { BlockSize = 512, CreateNew = false })) { OrdinalList free = new OrdinalList(); free.Ceiling = hcount; for (int i = 0; i < hcount; i++) { uint h = verify.Create(); free.Add((int)h); if (h >= hcount) { break; } } int verifiedCount = 0; OrdinalList used = free.Invert(hcount); foreach (uint h in used) { // skip reserved offsets. if (h % (512 / 4) == 0 || (h + 1) % (512 / 4) == 0) { continue; } IOStream.ReadAllBytes(verify.Read(h)); verifiedCount++; } System.Diagnostics.Trace.WriteLine("Verified handle count: " + verifiedCount); } } while (!failed && System.Diagnostics.Debugger.IsAttached); stop.Set(); workers.Complete(false, 1000); Assert.IsFalse(failed); } }