Пример #1
0
        public async Task MixSyncModes(SynchronizationMode fromSyncMode, SynchronizationMode toSyncMode)
        {
            var context = new Context(Logger);

            using (var testDirectory = new DisposableDirectory(FileSystem))
            {
                StrongFingerprint sfp = StrongFingerprint.Random();
                ContentHashListWithDeterminism value = new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None);
                await RunTestAsync(
                    context,
                    testDirectory,
                    async (store, session) =>
                {
                    // Add a value to a store with one sync mode
                    AddOrGetContentHashListResult addResult = await session.AddOrGetContentHashListAsync(context, sfp, value, Token);
                    Assert.True(addResult.Succeeded);
                    Assert.Null(addResult.ContentHashListWithDeterminism.ContentHashList);
                },
                    testDir => CreateSQLiteMemoizationStore(testDirectory.Path, fromSyncMode));

                await RunTestAsync(
                    context,
                    testDirectory,
                    async (store, session) =>
                {
                    // Make sure the same value can still be read from another sync mode
                    GetContentHashListResult getResult = await session.GetContentHashListAsync(context, sfp, Token);
                    getResult.ShouldBeSuccess();
                    Assert.Equal(value, getResult.ContentHashListWithDeterminism);

                    // Make sure a new value can be written in another sync mode
                    StrongFingerprint newSfp = StrongFingerprint.Random();
                    ContentHashListWithDeterminism newValue =
                        new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None);
                    AddOrGetContentHashListResult addResult = await session.AddOrGetContentHashListAsync(context, newSfp, newValue, Token);
                    Assert.True(addResult.Succeeded);
                    Assert.Null(addResult.ContentHashListWithDeterminism.ContentHashList);
                },
                    testDir => CreateSQLiteMemoizationStore(testDirectory.Path, toSyncMode));
            }
        }
Пример #2
0
        public async Task AddOrGetContentHashListGets()
        {
            List <Record> items = null;

            await Run(
                nameof(AddOrGetContentHashListGets),
                async (session, store) =>
            {
                List <StrongFingerprint> strongFingerprints;
                if (_initialDatabaseSize == InitialDatabaseSize.Full)
                {
                    strongFingerprints = await EnumerateStrongFingerprintsAsync(_context, store, _itemCount);
                }
                else
                {
                    List <Record> records = CreateRandom(_itemCount);
                    await AddOrGet(_context, session, records);
                    strongFingerprints = records.Select(record => record.StrongFingerprint).ToList();
                }

                items = strongFingerprints.Select(strongFingerprint => new Record(
                                                      strongFingerprint,
                                                      new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None))).ToList();
            },
                async session => await AddOrGet(_context, session, items));
        }
        protected MemoizationPerformanceTests
        (
            ILogger logger,
            PerformanceResultsFixture resultsFixture,
            InitialDatabaseSize initialDatabaseSize,
            string databaseFileName,
            Func <DisposableDirectory, IMemoizationStore> createStoreFunc
        )
            : base(() => new PassThroughFileSystem(logger), logger)
        {
            _context = new Context(Logger);
            var itemCountEnvironmentVariable = Environment.GetEnvironmentVariable(ItemCountEnvironmentVariableName);

            _itemCount = itemCountEnvironmentVariable == null ? ItemCountDefault : int.Parse(itemCountEnvironmentVariable);
            _context.Debug($"Using itemCount=[{_itemCount}] (MaxRowCount=[{MaxRowCount}])");

            ResultsFixture       = resultsFixture;
            _initialDatabaseSize = initialDatabaseSize;
            CreateStoreFunc      = createStoreFunc;

            _prePopulatedRootPath = FileSystem.GetTempPath() / "CloudStore" / "MemoizationPerformanceTestsPrePopulated";
            if (!FileSystem.DirectoryExists(_prePopulatedRootPath))
            {
                FileSystem.CreateDirectory(_prePopulatedRootPath);
            }

            AbsolutePath databaseFilePath = _prePopulatedRootPath / databaseFileName;

            if (FileSystem.FileExists(databaseFilePath))
            {
                return;
            }

            _context.Always($"Creating prepopulated database at path={databaseFilePath}");

            using (var disposableDirectory = new DisposableDirectory(FileSystem))
            {
                using (var store = createStoreFunc(disposableDirectory))
                {
                    try
                    {
                        var startupStoreResult = store.StartupAsync(_context).Result;
                        startupStoreResult.ShouldBeSuccess();

                        var createSessionResult = store.CreateSession(_context, Name);
                        createSessionResult.ShouldBeSuccess();

                        using (var session = createSessionResult.Session)
                        {
                            try
                            {
                                var startupSessionResult = session.StartupAsync(_context).Result;
                                startupSessionResult.ShouldBeSuccess();

                                for (var i = 0; i < MaxRowCount; i++)
                                {
                                    var strongFingerprint = StrongFingerprint.Random();
                                    var contentHashList   = ContentHashList.Random();
                                    var r = session.AddOrGetContentHashListAsync(
                                        _context, strongFingerprint, new ContentHashListWithDeterminism(contentHashList, CacheDeterminism.None), Token).Result;
                                    r.Succeeded.Should().BeTrue();
                                    r.ContentHashListWithDeterminism.ContentHashList.Should().BeNull();
                                }
                            }
                            finally
                            {
                                var shutdownSessionResult = session.ShutdownAsync(_context).Result;
                                shutdownSessionResult.ShouldBeSuccess();
                            }
                        }
                    }
                    finally
                    {
                        var shutdownStoreResult = store.ShutdownAsync(_context).Result;
                        shutdownStoreResult.ShouldBeSuccess();
                    }
                }

                FileSystem.CopyFileAsync(disposableDirectory.Path / databaseFileName, databaseFilePath, false).Wait();
            }
        }
Пример #4
0
        public async Task VerifyIntegrityCheckRunsAtStartupAutomaticallyIfPreviousCacheRunFailedToShutdownCleanly()
        {
            var context           = new Context(Logger);
            var strongFingerprint = StrongFingerprint.Random();
            var contentHashListWithDeterminism = new ContentHashListWithDeterminism(
                ContentHashList.Random(), Determinism[DeterminismNone]);

            using (var testDirectory = new DisposableDirectory(FileSystem))
            {
                var          safeDefaultFilePath = Path.GetTempFileName();
                AbsolutePath dbFilePath          = new AbsolutePath(safeDefaultFilePath),
                             dbInUseMarkerPath   = new AbsolutePath(safeDefaultFilePath);

                // Write a cached entry to a fresh master DB file and bloat the DB by adding random fingerprints
                await RunTestAsync(context, testDirectory, async (store, session) =>
                {
                    var result = await session.AddOrGetContentHashListAsync(
                        context, strongFingerprint, contentHashListWithDeterminism, Token);
                    Assert.True(result.Succeeded);

                    dbFilePath        = ((TestSQLiteMemoizationStore)store).DatabaseFilePathExtracted;
                    dbInUseMarkerPath = ((TestSQLiteMemoizationStore)store).DatabaseInUseMarkerFilePathExtracted;
                    Assert.True(File.Exists(dbInUseMarkerPath.Path));
                    await BloatDbAsync(context, session);
                });

                Assert.True(dbFilePath.Path != safeDefaultFilePath);
                Assert.True(dbInUseMarkerPath.Path != safeDefaultFilePath);

                // Corrupt the DB and make sure there is no marker to force a integrity check
                await CorruptRandomDbPageThatIsNotAtTheHeadAsync(dbFilePath);

                Assert.True(!File.Exists(dbInUseMarkerPath.Path));

                // The DB has been corrupted at the tail. Reading a value from one of the early pages should succeed,
                // even though the db is corrupted
                await RunTestAsync(context, testDirectory, async (store, session) =>
                {
                    var result = await session.GetContentHashListAsync(
                        context, strongFingerprint, Token);
                    Assert.True(result.Succeeded);
                    Assert.Equal(result.ContentHashListWithDeterminism, contentHashListWithDeterminism);
                    Assert.True(File.Exists(dbInUseMarkerPath.Path));
                });

                Assert.True(!File.Exists(dbInUseMarkerPath.Path));

#pragma warning disable AsyncFixer02 // WriteAllBytesAsync should be used instead of File.WriteAllBytes
                // Leave a marker, to make sure an integrity check is automatically run on the next startup
                File.WriteAllBytes(dbInUseMarkerPath.Path, new byte[] { });
#pragma warning restore AsyncFixer02 // WriteAllBytesAsync should be used instead of File.WriteAllBytes

                // When the in use marker is left behind, and integrity check should be run even if not explicitly
                // asked for (to ask explicitly see RunTestWithIntegrityCheckAtStartupAsync in this file). The
                // integrity check should fail and clear out the database. A fresh DB is used that no longer has the
                // fingerprint inserted at the start of this test.
                await RunTestAsync(context, testDirectory, async (store, session) =>
                {
                    var result = await session.GetContentHashListAsync(
                        context, strongFingerprint, Token);
                    Assert.True(result.Succeeded);
                    Assert.Null(result.ContentHashListWithDeterminism.ContentHashList);
                });

                Assert.True(!File.Exists(dbInUseMarkerPath.Path));
            }
        }
Пример #5
0
        public void EqualsFalseContentHashListMismatch()
        {
            var determinism = CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), CacheDeterminism.NeverExpires);
            var v1          = new GetContentHashListResult(new ContentHashListWithDeterminism(ContentHashList.Random(), determinism));
            var v2          = new GetContentHashListResult(new ContentHashListWithDeterminism(ContentHashList.Random(), determinism));

            Assert.False(v1.Equals(v2));
        }
Пример #6
0
 public void Success()
 {
     Assert.True(
         new GetContentHashListResult(new ContentHashListWithDeterminism(
                                          ContentHashList.Random(), CacheDeterminism.None)).Succeeded);
 }
Пример #7
0
 public void CodePropertySuccess()
 {
     Assert.Equal(
         AddOrGetContentHashListResult.ResultCode.Success,
         new AddOrGetContentHashListResult(new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None)).Code);
 }
Пример #8
0
        public void EqualsObjectFalse()
        {
            var v1 = new AddOrGetContentHashListResult(new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None));
            var v2 = new object();

            Assert.False(v1.Equals(v2));
        }
Пример #9
0
 public void EmptyContentHashListWithDeterminismRoundtrip()
 {
     TestContentHashListWithDeterminismRoundtrip(new ContentHashListWithDeterminism(
                                                     ContentHashList.Random(contentHashCount: 0),
                                                     CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), DateTime.UtcNow)));
 }
Пример #10
0
        public void EqualsFalseCodeMismatch()
        {
            var v1 = new AddOrGetContentHashListResult(new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None));
            var v2 = new AddOrGetContentHashListResult("error");

            Assert.False(v1.Equals(v2));
        }
Пример #11
0
        public void SerializeWithDeterminismRoundtrip()
        {
            var value = new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None);

            Utilities.TestSerializationRoundtrip(value, value.Serialize, ContentHashListWithDeterminism.Deserialize);
        }
Пример #12
0
        public void SerializeRoundtripNonNullPayload()
        {
            var value = ContentHashList.Random(payload: new byte[] { 1, 2, 3 });

            Utilities.TestSerializationRoundtrip(value, value.Serialize, ContentHashList.Deserialize);
        }
Пример #13
0
        public void SerializeRoundtrip()
        {
            var value = ContentHashList.Random();

            Utilities.TestSerializationRoundtrip(value, value.Serialize, ContentHashList.Deserialize);
        }
Пример #14
0
 public void RandomNullPayload()
 {
     Assert.Null(ContentHashList.Random().Payload);
 }
Пример #15
0
        private async Task <HashSet <StrongFingerprint> > AddRandomContentHashListsAsync(
            Context context, int count, IMemoizationSession session)
        {
            var strongFingerprints = new HashSet <StrongFingerprint>();

            for (int i = 0; i < count; i++)
            {
                var strongFingerprint = StrongFingerprint.Random();
                var contentHashListWithDeterminism = new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None);
                await session.AddOrGetContentHashListAsync(context, strongFingerprint, contentHashListWithDeterminism, Token).ShouldBeSuccess();

                strongFingerprints.Add(strongFingerprint);
            }

            return(strongFingerprints);
        }