public void Test_recovery_of_corrupted_storage()
        {
            // add two new blocks
            using (var storage = new ReliableStorage(new NullProcessor()))
            {
                storage.LoadPersistentData();

                Assert.AreEqual(0, storage.BlockCount);

                storage.StoreBlock(new byte[] { 1, 2, 3 }, "a1", 150);
                storage.StoreBlock(new byte[] { 1, 2, 3, 4, 5 }, "a2", 151);
                storage.StoreBlock(new byte[] { 21, 22, 23, 24, 25 }, "a3", 152);

                Assert.AreEqual(3, storage.BlockCount);
                Assert.AreEqual(0, storage.InactiveBlockCount);

                storage.MakeCorruptedBlock("a2");
            }

            // here we apply recovery wile loading
            using (var storage = new ReliableStorage(new NullProcessor()))
            {
                storage.LoadPersistentData();

                Assert.AreEqual(2, storage.BlockCount);

                Assert.AreEqual(1, storage.InactiveBlockCount);

                Assert.AreEqual(2, storage.Keys.Count);

                Assert.AreEqual(1, storage.CorruptedBlocks);

                Assert.IsTrue(storage.Keys.Contains("a1"));
                Assert.IsTrue(storage.Keys.Contains("a3"));
            }


            // here it is clean again (one block was lost)
            using (var storage = new ReliableStorage(new NullProcessor()))
            {
                storage.LoadPersistentData();
                Assert.AreEqual(2, storage.BlockCount);

                Assert.AreEqual(1, storage.InactiveBlockCount);

                Assert.AreEqual(0, storage.CorruptedBlocks);

                Assert.IsTrue(storage.Keys.Contains("a1"));
                Assert.IsTrue(storage.Keys.Contains("a3"));
            }
        }
        public void Test_recovery_of_corrupted_storage_with_backup_available()
        {
            // add two new blocks
            using (var storage = new ReliableStorage(new NullProcessor(), null, "backup"))
            {
                storage.LoadPersistentData();

                Assert.AreEqual(0, storage.BlockCount);

                storage.StoreBlock(new byte[] { 1, 2, 3 }, "a1", 150);
                storage.StoreBlock(new byte[] { 1, 2, 3, 4, 5 }, "a2", 151);
                storage.StoreBlock(new byte[] { 21, 22, 23, 24, 25 }, "a3", 152);

                Assert.AreEqual(3, storage.BlockCount);
                Assert.AreEqual(0, storage.InactiveBlockCount);

                storage.MakeCorruptedBlock("a2");
            }

            // here we apply recovery wile loading
            using (var storage = new ReliableStorage(new NullProcessor(), null, "backup"))
            {
                storage.LoadPersistentData();
                Assert.AreEqual(3, storage.BlockCount);

                Assert.AreEqual(1, storage.InactiveBlockCount);

                Assert.AreEqual(3, storage.Keys.Count);

                Assert.AreEqual(1, storage.CorruptedBlocks);

                Assert.IsTrue(storage.Keys.Contains("a1"));
                Assert.IsTrue(storage.Keys.Contains("a2"));
                Assert.IsTrue(storage.Keys.Contains("a3"));
            }


            // here it is clean again (lost block was recoveres)
            using (var storage = new ReliableStorage(new NullProcessor(), null, "backup"))
            {
                storage.LoadPersistentData();

                Assert.AreEqual(3, storage.BlockCount);

                Assert.AreEqual(1, storage.InactiveBlockCount);

                Assert.AreEqual(0, storage.CorruptedBlocks);

                Assert.IsTrue(storage.Keys.Contains("a1"));
                Assert.IsTrue(storage.Keys.Contains("a2"));
                Assert.IsTrue(storage.Keys.Contains("a3"));


                // do some updates after recovery
                storage.StoreBlock(new byte[] { 121, 122, 123, 124, 125, 126 }, "a4", 152);

                storage.DeleteBlock("a1", 455);
            }

            // check the main storage
            using (var storage = new ReliableStorage(new NullProcessor()))
            {
                storage.LoadPersistentData();

                Assert.AreEqual(4, storage.BlockCount); // deleted blocks are counted too

                Assert.AreEqual(2, storage.InactiveBlockCount);

                Assert.AreEqual(0, storage.CorruptedBlocks);

                Assert.IsTrue(storage.Keys.Contains("a2"));
                Assert.IsTrue(storage.Keys.Contains("a3"));
                Assert.IsTrue(storage.Keys.Contains("a4"));
            }

            // check the backup storage
            using (var storage = new ReliableStorage(new NullProcessor(), null, "backup"))
            {
                storage.LoadPersistentData();

                Assert.AreEqual(4, storage.BlockCount); // deleted blocks are counted too

                Assert.IsTrue(storage.Keys.Contains("a2"));
                Assert.IsTrue(storage.Keys.Contains("a3"));
                Assert.IsTrue(storage.Keys.Contains("a4"));
            }
        }