Beispiel #1
0
 public void CanWrite()
 {
     using (var container = TemporaryDirectory.CreateNew())
     {
         var sut = new AtomicFile <int>(container.File("key-path"), new StubSerialiser());
         sut.Write(42);
     }
 }
Beispiel #2
0
 public void CanWrite()
 {
     using (var container = TemporaryDirectory.CreateNew())
     {
         var sut = new LocalFilesystemStore(container.FullPath, new StubSerialiserProvider());
         sut.SetValue("key", 42);
     }
 }
Beispiel #3
0
        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)));
            }
        }
Beispiel #4
0
        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)));
            }
        }
Beispiel #5
0
        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));
            }
        }
Beispiel #6
0
        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));
            }
        }
Beispiel #7
0
        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));
            }
        }
Beispiel #8
0
        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()));
            }
        }
Beispiel #9
0
        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));
            }
        }
Beispiel #10
0
        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)));
            }
        }