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)); } }
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(); } }
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)); } }
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)); }
public void Success() { Assert.True( new GetContentHashListResult(new ContentHashListWithDeterminism( ContentHashList.Random(), CacheDeterminism.None)).Succeeded); }
public void CodePropertySuccess() { Assert.Equal( AddOrGetContentHashListResult.ResultCode.Success, new AddOrGetContentHashListResult(new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None)).Code); }
public void EqualsObjectFalse() { var v1 = new AddOrGetContentHashListResult(new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None)); var v2 = new object(); Assert.False(v1.Equals(v2)); }
public void EmptyContentHashListWithDeterminismRoundtrip() { TestContentHashListWithDeterminismRoundtrip(new ContentHashListWithDeterminism( ContentHashList.Random(contentHashCount: 0), CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), DateTime.UtcNow))); }
public void EqualsFalseCodeMismatch() { var v1 = new AddOrGetContentHashListResult(new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None)); var v2 = new AddOrGetContentHashListResult("error"); Assert.False(v1.Equals(v2)); }
public void SerializeWithDeterminismRoundtrip() { var value = new ContentHashListWithDeterminism(ContentHashList.Random(), CacheDeterminism.None); Utilities.TestSerializationRoundtrip(value, value.Serialize, ContentHashListWithDeterminism.Deserialize); }
public void SerializeRoundtripNonNullPayload() { var value = ContentHashList.Random(payload: new byte[] { 1, 2, 3 }); Utilities.TestSerializationRoundtrip(value, value.Serialize, ContentHashList.Deserialize); }
public void SerializeRoundtrip() { var value = ContentHashList.Random(); Utilities.TestSerializationRoundtrip(value, value.Serialize, ContentHashList.Deserialize); }
public void RandomNullPayload() { Assert.Null(ContentHashList.Random().Payload); }
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); }