public void CanWrite() { using (var container = TemporaryDirectory.CreateNew()) { var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); sut.Write(42); } }
public void CanWrite() { using (var container = TemporaryDirectory.CreateNew()) { var sut = new LocalFilesystemStore(container.FullPath, new StubSerialiserProvider()); sut.SetValue("key", 42); } }
public void CanDeleteWrittenValue() { using (var container = TemporaryDirectory.CreateNew()) { var sut = new LocalFilesystemStore(container.FullPath, new StubSerialiserProvider()); sut.SetValue("key", 42); sut.RemoveKey("key"); Assert.That(sut.GetValue <int>("key"), Is.EqualTo(default(int))); } }
public void CanDeleteWrittenValue() { using (var container = TemporaryDirectory.CreateNew()) { var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); sut.Write(42); sut.Delete(); Assert.That(sut.Read(), Is.EqualTo(default(int))); } }
public void CanReadWrittenValue() { using (var container = TemporaryDirectory.CreateNew()) { var sut = new LocalFilesystemStore(container.FullPath, new StubSerialiserProvider()); sut.SetValue("key", 42); var value = sut.GetValue <int>("key"); Assert.That(value, Is.EqualTo(42)); } }
public void CanReplaceWrittenValue() { using (var container = TemporaryDirectory.CreateNew()) { var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); sut.Write(42); sut.Write(23); var value = sut.Read(); Assert.That(value, Is.EqualTo(23)); } }
public void FailedWriteDoesNotOverwriteExistingValue() { using (var container = TemporaryDirectory.CreateNew()) { var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); sut.Write(42); Assume.That(sut.Read(), Is.EqualTo(42)); var failing = new AtomicFile <int>(container.File("key-path"), new RandomlyFailingSerialiser <int>(new StubSerialiser(), 1)); Assume.That(() => failing.Write(23), Throws.InstanceOf <IOException>()); Assert.That(sut.Read(), Is.EqualTo(42)); } }
public async Task FuzzConcurrentAccess() { const int threadCount = 5; const int iterationCountPerThread = 25; var writtenValues = new List <int>(); var random = new Random(); var failures = new List <Exception>(); using (var container = TemporaryDirectory.CreateNew()) { var path = container.File("key-path"); await ConcurrentOperations.Run(threadCount, () => { var sut = new AtomicFile <int>(path, new RandomlyFailingSerialiser <int>(new StubSerialiser(), 0.05)); for (var i = 0; i < iterationCountPerThread; i++) { try { var value = random.Next(100); sut.Write(value); lock (writtenValues) writtenValues.Add(value); } catch (FileLockedException) { // We expect locking conflicts to represent the bulk of failures. } catch (Exception ex) { lock (failures) failures.Add(ex); } try { sut.Read(); } catch (Exception) { } } }); var finalValue = new AtomicFile <int>(path, new StubSerialiser()).Read(); // At least one write should succeed. Assume.That(writtenValues.Count, Is.GreaterThan(1)); // Due to races it's not guaranteed that the last entry in the list is the last one successfully written. // However, this should be vanishingly unlikely because it would require that another Write call ran to // completion between `sut.Write(value);` and `lock (writtenValues)`. Assert.That(finalValue, Is.EqualTo(writtenValues.Last())); } }
public void CanAccessViaMultipleInstances() { using (var container = TemporaryDirectory.CreateNew()) { var sut1 = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); var sut2 = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); var sut3 = new AtomicFile <int>(container.File("key-path"), new StubSerialiser()); sut1.Write(42); sut2.Write(17); sut3.Write(23); var value = sut2.Read(); Assert.That(value, Is.EqualTo(23)); } }
public void RecordsFailureLeadingToTimeoutInDiagnosticLog() { using (var container = TemporaryDirectory.CreateNew()) { var clock = new MockClock(DateTimeOffset.Now); var log = Mock.Of <IDiagnosticsLog>(); var serialiserProvider = new FailingActionSerialiserProvider(() => { clock.Advance(TimeSpan.FromSeconds(10)); throw new OutOfMemoryException(); }); var sut = new LocalFilesystemStore(container.FullPath, serialiserProvider, log) { Clock = clock, Timeout = TimeSpan.FromSeconds(5) }; Assume.That(() => sut.SetValue("key", 42), Throws.InstanceOf <TimeoutException>()); Mock.Get(log).Verify(l => l.Info(It.Is <LocalStoreTimeoutEvent>(t => t.Exception.Type.FullName == typeof(OutOfMemoryException).FullName))); } }