private async Task ValidateSessionAsync(HashSet <FullCacheRecord> expectedRecords, ICache cache, string sessionId, FakeBuild.CasAccessMethod accessMethod) { if (!ImplementsTrackedSessions || DummySessionName != null) { return; } ICacheReadOnlySession readOnlySession = (await cache.CreateReadOnlySessionAsync()).Success(); // Check that the content is fine HashSet <FullCacheRecord> foundRecords = new HashSet <FullCacheRecord>(); foreach (var strongFingerprintTask in cache.EnumerateSessionStrongFingerprints(DummySessionName ?? sessionId).Success().OutOfOrderTasks()) { StrongFingerprint strongFingerprint = await strongFingerprintTask; CasEntries casEntries = (await readOnlySession.GetCacheEntryAsync(strongFingerprint)).Success(); FullCacheRecord record = new FullCacheRecord(strongFingerprint, casEntries); XAssert.IsTrue(expectedRecords.Contains(record), "Found record that was not expected!"); foundRecords.Add(record); } (await readOnlySession.CloseAsync()).Success(); await FakeBuild.CheckContentsAsync(cache, foundRecords, accessMethod); XAssert.AreEqual(expectedRecords.Count, foundRecords.Count); }
/// <summary> /// Creates a FakeStrongFingerpint and the associated FakeBuild streams. /// </summary> /// <param name="pipName">Name of the pip</param> /// <param name="generateVerifiablePip">Determines if CheckContentsAsync can verify the contents of the build</param> /// <param name="pipSize">Number of files to include in the pip</param> /// <remarks> /// This method is the StrongFingerprint generation algorithm for FakeBuild.DoNondeterministicPipAsync /// </remarks> /// <returns>A FakeStrongFingerprint that has the FakeBuild class</returns> public static FakeStrongFingerprint Create(string pipName, bool generateVerifiablePip = false, int pipSize = 3) { FakeBuild fake = new FakeBuild(pipName, pipSize, forceUniqueOutputs: !generateVerifiablePip); WeakFingerprintHash weak = CreateWeak(pipName.ToLowerInvariant()); Hash simpleHash = CreateHash(pipName.ToUpperInvariant()); return(new FakeStrongFingerprint(weak, simpleHash, fake)); }
public virtual async Task NonDeterministicContentRespectsDisconnect() { string testCacheId = "Disconnected"; ICache testCache = await InitializeCacheAsync(NewCache(testCacheId, false)).SuccessAsync(); VerticalCacheAggregator vertCache = testCache as VerticalCacheAggregator; XAssert.IsNotNull(vertCache); ICacheSession aggregatorSession = (await testCache.CreateSessionAsync()).Success(); ICacheSession localSession = (await vertCache.LocalCache.CreateSessionAsync()).Success(); ICacheSession remoteSession = (await vertCache.RemoteCache.CreateSessionAsync()).Success(); VerticalCacheAggregatorSession vertSession = aggregatorSession as VerticalCacheAggregatorSession; XAssert.IsNotNull(vertSession); CallbackCacheSessionWrapper wrappedSession = vertSession.RemoteSession as CallbackCacheSessionWrapper; XAssert.IsNotNull(wrappedSession); PoisonSession(wrappedSession); CacheDeterminism determinismSource = CacheDeterminism.None; const string PipName = "TestPip"; // Populate the remote cache with one set of outputs. FullCacheRecord remoteCacheRecord = await FakeBuild.DoNonDeterministicPipAsync(remoteSession, PipName); // And the local cache with a set forced to be unique. FullCacheRecord localCacheRecord = await FakeBuild.DoNonDeterministicPipAsync(localSession, PipName, generateVerifiablePip: true); PoisonAllRemoteSessions(testCache); DisconnectRemoteCache(testCache); // Now query each cache, and verify only the remote content is in each. // Make sure the content is in each cache. (Placing the aggregator cache first will cause backfill of the local cache) foreach (var currentCache in new Tuple <ICache, CacheDeterminism, string, int>[] { new Tuple <ICache, CacheDeterminism, string, int>(testCache, CacheDeterminism.None, vertCache.LocalCache.CacheId, 1), new Tuple <ICache, CacheDeterminism, string, int>(vertCache.LocalCache, CacheDeterminism.None, vertCache.LocalCache.CacheId, 1) }) { await VerticalAggregatorBaseTests.ValidateItemsInCacheAsync( currentCache.Item1, localCacheRecord.StrongFingerprint.WeakFingerprint, new List <CasHash>(localCacheRecord.CasEntries), currentCache.Item2, localCacheRecord.StrongFingerprint.CasElement, currentCache.Item3, currentCache.Item4); } XAssert.IsTrue((await testCache.ShutdownAsync()).Succeeded); }
private async Task AddToEmptyCacheAsync(bool contentIsDeterministic) { string testCacheId = "Disconnected"; ICache testCache = await InitializeCacheAsync(NewCache(testCacheId, false)).SuccessAsync(); VerticalCacheAggregator vertCache = testCache as VerticalCacheAggregator; XAssert.IsNotNull(vertCache); CacheDeterminism localDeterminism = CacheDeterminism.None; if (contentIsDeterministic) { localDeterminism = CacheDeterminism.Tool; } CacheDeterminism initialDeterminism = contentIsDeterministic ? CacheDeterminism.Tool : CacheDeterminism.None; ICacheSession session = (await testCache.CreateSessionAsync()).Success(); VerticalCacheAggregatorSession vertSession = session as VerticalCacheAggregatorSession; XAssert.IsNotNull(vertSession); CallbackCacheSessionWrapper wrappedSession = vertSession.RemoteSession as CallbackCacheSessionWrapper; XAssert.IsNotNull(wrappedSession); PoisonSession(wrappedSession); DisconnectRemoteCache(testCache); FullCacheRecord cacheRecord = await FakeBuild.DoPipAsync(session, "TestPip", determinism: initialDeterminism); await VerticalAggregatorBaseTests.ValidateItemsInCacheAsync( vertCache.LocalCache, cacheRecord.StrongFingerprint.WeakFingerprint, new List <CasHash>(cacheRecord.CasEntries), localDeterminism, cacheRecord.StrongFingerprint.CasElement, vertCache.LocalCache.CacheId, 1); await VerticalAggregatorBaseTests.ValidateItemsInCacheAsync( vertCache.RemoteCache, cacheRecord.StrongFingerprint.WeakFingerprint, new List <CasHash>(cacheRecord.CasEntries), localDeterminism, cacheRecord.StrongFingerprint.CasElement, vertCache.RemoteCache.CacheId, 0); XAssert.IsTrue((await testCache.ShutdownAsync()).Succeeded); }
public async Task NoItemFingerprint() { const string TestName = nameof(NoItemFingerprint); string testCacheId = MakeCacheId(TestName); ICache cache = await CreateCacheAsync(testCacheId); // Now for the session (which we base on the cache ID) string testSessionId = "Session1-" + testCacheId; ICacheSession session = await CreateSessionAsync(cache, testSessionId); // Note that we will be making a new fingerprint with a CasHash of NoItem // without pre-sending it as NoItem is a special case - it is nothing FullCacheRecord record = await FakeBuild.DoPipAsync(session, TestName); // We place this in and did not pin the NoItem yet or even send it around // Note that this also is doing a zero-length CasEntries var strong = new StrongFingerprint(record.StrongFingerprint.WeakFingerprint, CasHash.NoItem, new Hash(FingerprintUtilities.ZeroFingerprint), TestName); FullCacheRecordWithDeterminism oldRecord = (await session.AddOrGetAsync( strong.WeakFingerprint, strong.CasElement, strong.HashElement, CasEntries.FromCasHashes())).Success("Should work even though I did not pin CasHash.NoItem, instead it failed with {0}"); XAssert.IsNull(oldRecord.Record, "Should have been the first one like this"); var result = await session.GetCacheEntryAsync(strong).SuccessAsync(); XAssert.AreEqual(0, result.Count, "We should have gotten a zero-length CasEntries"); // We place this in and did not pin the NoItem yet or even send it around // Note that this does an array of NoItem CasEntries and use the // record.CasElement as the weak fingerprint CasHash[] empties = { CasHash.NoItem, CasHash.NoItem, CasHash.NoItem }; strong = new StrongFingerprint(new WeakFingerprintHash(strong.CasElement.ToFingerprint()), CasHash.NoItem, new Hash(FingerprintUtilities.ZeroFingerprint), TestName); oldRecord = (await session.AddOrGetAsync( strong.WeakFingerprint, CasHash.NoItem, new Hash(FingerprintUtilities.ZeroFingerprint), empties)).Success("Should work even though I did not pin CasHash.NoItem, instead it failed with {0}"); XAssert.IsNull(oldRecord.Record, "Should have been the first one like this"); result = await session.GetCacheEntryAsync(strong).SuccessAsync(); XAssert.AreEqual(empties, result, "We should have gotten the set of empties"); await CloseSessionAsync(session, testSessionId); await ShutdownCacheAsync(cache, testCacheId); }
public virtual async Task WritethroughRemoteIsNotWrittenToWhenDisconnectedFileName() { string testCacheId = "Disconnected"; ICache testCache = await InitializeCacheAsync(NewWrappedRemoteCache(testCacheId, false, true)).SuccessAsync(); PoisonAllRemoteSessions(testCache); DisconnectRemoteCache(testCache); ICacheSession aggSession = await testCache.CreateSessionAsync().SuccessAsync(); FakeBuild fb = new FakeBuild("test", 1); AssertSuccess(await aggSession.AddToCasAsync(fb.Outputs[0])); }
public async Task PinErrors() { const string TestName = nameof(PinErrors); string testCacheId = MakeCacheId(TestName); ICache cache = await CreateCacheAsync(testCacheId); ICacheSession session = await cache.CreateSessionAsync().SuccessAsync(); FakeBuild fb = new FakeBuild("test", 3); var result = await session.PinToCasAsync(new CasHash(fb.OutputHashes[0]), CancellationToken.None); XAssert.IsFalse(result.Succeeded, "Pin should fail"); XAssert.AreEqual(typeof(NoCasEntryFailure), result.Failure.GetType(), "Incorrect failure returned {0}", result.Failure.Describe()); await CloseSessionAsync(session, null); await ShutdownCacheAsync(cache, testCacheId); }
public async Task DisconnectedCacheNotQueriedForStrongFingerprints() { string testCacheId = "Disconnected"; ICache testCache = await InitializeCacheAsync(NewCache(testCacheId, false)).SuccessAsync(); PoisonAllRemoteSessions(testCache); ICacheReadOnlySession roSession = await testCache.CreateReadOnlySessionAsync().SuccessAsync(); DisconnectRemoteCache(testCache); FakeBuild fb = new FakeBuild("test", 1); foreach (var fingerprint in roSession.EnumerateStrongFingerprints(new WeakFingerprintHash(FingerprintUtilities.Hash("fingerprint").ToByteArray()))) { // Just run the enumerator, should all return. } }
public async Task AddWithoutPinWeak() { const string TestName = nameof(AddWithoutPinWeak); string testCacheId = MakeCacheId(TestName); ICache cache = await CreateCacheAsync(testCacheId, strictMetadataCasCoupling : false); // Only caches that are not strict metadata to CAS coupling need this test if (cache.StrictMetadataCasCoupling) { (await cache.ShutdownAsync()).Success(); return; } string testSessionId = "Session1-" + testCacheId; ICacheSession session = await CreateSessionAsync(cache, testSessionId); FakeBuild fake = new FakeBuild(TestName, 2); // We fake up a CasHash - never actually add to the cache - weak cas CasHash inputList = fake.OutputListHash; CasHash[] items = new CasHash[fake.Outputs.Length]; for (int i = 0; i < fake.Outputs.Length; i++) { items[i] = new CasHash(fake.OutputHashes[i]); } // We use the hash of our output list as the weak fingerprint and extra hash var outputListFingerprintHash = fake.OutputListHash.ToFingerprint(); WeakFingerprintHash weak = new WeakFingerprintHash(outputListFingerprintHash); // This should work since the session is weak. FullCacheRecordWithDeterminism record = (await session.AddOrGetAsync(weak, inputList, outputListFingerprintHash, items)).Success(); XAssert.IsNull(record.Record, "There should not have been anything in the cache"); // Doing it twice does not change things... record = (await session.AddOrGetAsync(weak, inputList, outputListFingerprintHash, items)).Success(); XAssert.IsNull(record.Record, "It matches exactly, so no bother"); await CloseSessionAsync(session, testSessionId); await ShutdownCacheAsync(cache, testCacheId); }
public async Task GetWithoutPin() { const string TestName = nameof(GetWithoutPin); string testCacheId = MakeCacheId(TestName); ICache cache = await CreateCacheAsync(testCacheId); string testSessionId = "Session1-" + testCacheId; ICacheSession session = await CreateSessionAsync(cache, testSessionId); FakeBuild fake = new FakeBuild(TestName, 1); CasHash item = (await session.AddToCasAsync(fake.OutputList)).Success(); // Verify that we can read the content after it was added in // this session since it was pinned using (Stream stream = (await session.GetStreamAsync(item)).Success()) { stream.AsString(); } await CloseSessionAsync(session, testSessionId); testSessionId = "Session2-" + testCacheId; session = await CreateSessionAsync(cache, testSessionId); if (RequiresPinBeforeGet) { // This time we will just get the content stream and it should fail // in this session since it is not open. var error = await session.GetStreamAsync(item); XAssert.IsTrue(!error.Succeeded, "Call to GetStream was successful, and should have failed for unpinned CAS access."); XAssert.IsTrue(error.Failure is UnpinnedCasEntryFailure, "Failed with unexpected error type {0} and error {1}", error.Failure, error.Failure.Describe()); // Doing it twice did not change the case error = await session.GetStreamAsync(item); XAssert.IsTrue(!error.Succeeded, "Second call to GetStream was successful, and should have failed for unpinned CAS access."); XAssert.IsTrue(error.Failure is UnpinnedCasEntryFailure, "Failed with unexpected error type {0} and error {1}", error.Failure, error.Failure.Describe()); } await CloseSessionAsync(session, testSessionId); await ShutdownCacheAsync(cache, testCacheId); }
/// <summary> /// Execute a fake build based on this pip definition into the given cache session /// </summary> /// <param name="session">The cache session to use</param> /// <returns>The FullCacheRecord of the build operation</returns> public async Task <FullCacheRecord> BuildAsync(ICacheSession session) { Contract.Requires(session != null); FullCacheRecord record = await FakeBuild.DoPipAsync( session, pipName : PipName, pipSize : PipSize, weakIndex : WeakIndex, hashIndex : HashIndex, determinism : Determinism); if (Determinism.IsDeterministicTool) { XAssert.IsTrue(record.CasEntries.Determinism.IsDeterministicTool, "Tool was supposed to be deterministic"); } return(record); }
public async Task CacheMissTest() { const string TestName = nameof(CacheMissTest); string testCacheId = MakeCacheId(TestName); ICache cache = await CreateCacheAsync(testCacheId); ICacheSession session = await cache.CreateSessionAsync().SuccessAsync(); FakeBuild fb = new FakeBuild("test", 3); StrongFingerprint fakeFingerprint = new StrongFingerprint(WeakFingerprintHash.Random(), new CasHash(fb.OutputHashes[0]), fb.OutputHashes[0], "fake"); var response = await session.GetCacheEntryAsync(fakeFingerprint); XAssert.IsFalse(response.Succeeded); XAssert.AreEqual(typeof(NoMatchingFingerprintFailure), response.Failure.GetType(), response.Failure.Describe()); await CloseSessionAsync(session, null); await ShutdownCacheAsync(cache, testCacheId); }
private static async Task <FullCacheRecord> DoPipAsyncImpl(ICacheSession session, WeakFingerprintHash weak, Hash simpleHash, FakeBuild fake, CacheDeterminism determinism, CasAccessMethod accessMethod) { foreach (var strongTask in session.EnumerateStrongFingerprints(weak)) { StrongFingerprint possibleHit = await strongTask.SuccessAsync(); if (fake.OutputListHash.Equals(possibleHit.CasElement)) { if (simpleHash.Equals(possibleHit.HashElement)) { // A cache hit! Our strong fingerprint matched return(new FullCacheRecord(possibleHit, await session.GetCacheEntryAsync(possibleHit).SuccessAsync())); } } } // A cache miss - add the content to the cache and then // add the build. CasHash inputList = await AddToCasAsync(fake.OutputList, accessMethod, session).SuccessAsync(); CasHash[] items = new CasHash[fake.Outputs.Length]; for (int i = 0; i < items.Length; i++) { items[i] = await AddToCasAsync(fake.Outputs[i], accessMethod, session).SuccessAsync(); } CasEntries entries = new CasEntries(items, determinism); FullCacheRecordWithDeterminism cacheRecord = await session.AddOrGetAsync(weak, inputList, simpleHash, entries).SuccessAsync(); XAssert.AreEqual(null, cacheRecord.Record); // Produce a full cache record manually - such that the CacheId is our own "NewRecordCacheId" return(new FullCacheRecord(new StrongFingerprint(weak, inputList, simpleHash, NewRecordCacheId), entries)); }
public async Task CacheDataPersistedReadOnlyCache() { string testName = "CacheDataPersistedReadOnly"; ICache firstInvocation = await CreateCacheAsync(testName, true); Guid originalGuid = firstInvocation.CacheGuid; ICacheSession session = (await firstInvocation.CreateSessionAsync("sessionName")).Success(); FullCacheRecord cacheRecord = await FakeBuild.DoPipAsync(session, "PipA"); (await session.CloseAsync()).Success(); await ShutdownCacheAsync(firstInvocation, testName); ICache secondInvocation = await GetExistingCacheAsync(testName, true, true); XAssert.AreEqual(originalGuid, secondInvocation.CacheGuid, "Persistent caches: GUID should not change"); XAssert.IsTrue(secondInvocation.IsReadOnly, "This should have been a read-only cache"); ICacheReadOnlySession newSession = (await secondInvocation.CreateReadOnlySessionAsync()).Success(); int fingerprintsFound = 0; foreach (var singleFingerprint in newSession.EnumerateStrongFingerprints(cacheRecord.StrongFingerprint.WeakFingerprint)) { var sfp = (await singleFingerprint).Success(); XAssert.AreEqual(cacheRecord.StrongFingerprint, sfp, "Fingerprints must match"); fingerprintsFound++; } XAssert.AreEqual(1, fingerprintsFound, "A single instance of the fingerprint should have been found after restarting the cache."); (await newSession.CloseAsync()).Success(); await ShutdownCacheAsync(secondInvocation, testName); }
/// <summary> /// This will do a build into the session with a given name /// and output count. /// </summary> /// <param name="session">The cache session to work with</param> /// <param name="pipName">Some text that acts as a base element in the output</param> /// <param name="pipSize">Number of elements in the output. Must be enough to cover the variants</param> /// <param name="weakIndex">Variant with different weak index - defaults to 1</param> /// <param name="hashIndex">Variant with different hash index - defaults to 0</param> /// <param name="accessMethod">Method (File or stream) for how files are materialized from the cache</param> /// <param name="determinism">Determinism to provide for new build records</param> /// <returns>The FullCacheRecord of the build</returns> /// <remarks> /// This will do a "fake build" including a cache lookup via weak fingerprints /// and then return either the existing FullCacheRecord or add the build as a new /// one. A new FullCacheRecord will have the StrongFingerprint.CacheId set to NewRecordCacheId /// </remarks> public static Task <FullCacheRecord> DoPipAsync( ICacheSession session, string pipName, int pipSize = DefaultFakeBuildSize, int weakIndex = 1, int hashIndex = 0, CacheDeterminism determinism = default(CacheDeterminism), CasAccessMethod accessMethod = CasAccessMethod.Stream) { Contract.Requires(session != null); Contract.Requires(pipName != null); Contract.Requires(pipSize > 0); Contract.Requires(weakIndex >= 0 && weakIndex < pipSize); Contract.Requires(hashIndex >= 0 && hashIndex < pipSize); FakeBuild fake = new FakeBuild(pipName, pipSize); WeakFingerprintHash weak = new WeakFingerprintHash(FingerprintUtilities.Hash(fake.OutputHashes[weakIndex].ToString()).ToByteArray()); Hash simpleHash = new Hash(FingerprintUtilities.Hash(fake.OutputHashes[hashIndex].ToString())); return(DoPipAsyncImpl(session, weak, simpleHash, fake, determinism, accessMethod)); }
public async Task ProduceFileWithDirectories(FileState fileState) { const string TestName = nameof(ProduceFileWithDirectories); string testCacheId = MakeCacheId(TestName); ICache cache = await CreateCacheAsync(testCacheId); string testSessionId = "Session1-" + testCacheId; ICacheSession session = await CreateSessionAsync(cache, testSessionId); FakeBuild fake = new FakeBuild(TestName, 1); CasHash item = await session.AddToCasAsync(fake.OutputList).SuccessAsync(); // Now, lets make a temp file name with a path that does not exist // We need to make sure it gets produced during ProduceFile string tmpFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("D"), "Test.txt"); await session.ProduceFileAsync(item, tmpFile, fileState).SuccessAsync("Did not produce a file with a directory that did not exist!"); Directory.Delete(Path.GetDirectoryName(tmpFile), true); await CloseSessionAsync(session, testSessionId); await ShutdownCacheAsync(cache, testCacheId); }
public virtual async Task ReadOnlyRemoteIsNotUpdatedWhenDisconnected() { string testCacheId = "Disconnected"; ICache testCache = await InitializeCacheAsync(NewCache(testCacheId, false)).SuccessAsync(); VerticalCacheAggregator vertCache = testCache as VerticalCacheAggregator; XAssert.IsNotNull(vertCache); PoisonAllRemoteSessions(testCache); DisconnectRemoteCache(testCache); ICacheSession session = (await testCache.CreateSessionAsync()).Success(); FullCacheRecord cacheRecord = await FakeBuild.DoPipAsync(session, "TestPip"); await VerticalAggregatorBaseTests.ValidateItemsInCacheAsync( vertCache.LocalCache, cacheRecord.StrongFingerprint.WeakFingerprint, new List <CasHash>(cacheRecord.CasEntries), CacheDeterminism.None, cacheRecord.StrongFingerprint.CasElement, vertCache.LocalCache.CacheId, 1); var remoteSession = await vertCache.RemoteCache.CreateReadOnlySessionAsync().SuccessAsync(); int fingerprintsReturned = 0; foreach (var fingerprint in remoteSession.EnumerateStrongFingerprints(cacheRecord.StrongFingerprint.WeakFingerprint)) { fingerprintsReturned++; } XAssert.AreEqual(0, fingerprintsReturned, "No fingerprints should have been found in the remote cache."); AssertSuccess(await testCache.ShutdownAsync()); }
public async Task AddWithoutPin() { const string TestName = nameof(AddWithoutPin); string testCacheId = MakeCacheId(TestName); ICache cache = await CreateCacheAsync(testCacheId); string testSessionId = "Session1-" + testCacheId; ICacheSession session = await CreateSessionAsync(cache, testSessionId); FakeBuild fake = new FakeBuild(TestName, 2); CasHash inputList = (await session.AddToCasAsync(fake.OutputList)).Success(); // Verify that we can read the content after it was added in // this session since it was pinned using (Stream stream = (await session.GetStreamAsync(inputList)).Success()) { stream.AsString(); } CasHash[] items = new CasHash[fake.Outputs.Length]; for (int i = 0; i < fake.Outputs.Length; i++) { items[i] = (await session.AddToCasAsync(fake.Outputs[i])).Success(); // Verify that we can read the content after it was added in // this session since it was pinned using (Stream stream = (await session.GetStreamAsync(items[i])).Success()) { stream.AsString(); } } await CloseSessionAsync(session, testSessionId); testSessionId = "Session2-" + testCacheId; session = await CreateSessionAsync(cache, testSessionId); // We use the hash of our output list as the weak fingerprint and extra hash var outputListFingerprintHash = fake.OutputListHash.ToFingerprint(); WeakFingerprintHash weak = new WeakFingerprintHash(outputListFingerprintHash); if (cache.StrictMetadataCasCoupling) { // This should fail as we did not pin or add the content yet var error = await session.AddOrGetAsync(weak, inputList, outputListFingerprintHash, items); XAssert.IsFalse(error.Succeeded, "Add of weak fingerprint when items not first added to CAS was successful."); XAssert.IsTrue(error.Failure is UnpinnedCasEntryFailure, "Error failure was not expected type {0}, it was {1} {2}", typeof(UnpinnedCasEntryFailure).Name, error.Failure.GetType().Name, error.Failure.Describe()); // Doing it twice does not change things... error = await session.AddOrGetAsync(weak, inputList, outputListFingerprintHash, items); XAssert.IsFalse(error.Succeeded, "Add of weak fingerprint when items not first added to CAS was successful."); XAssert.IsTrue(error.Failure is UnpinnedCasEntryFailure, "Error failure was not expected type {0}, it was {1}, {2}", typeof(UnpinnedCasEntryFailure).Name, error.Failure.GetType().Name, error.Failure.Describe()); } await CloseSessionAsync(session, testSessionId); await ShutdownCacheAsync(cache, testCacheId); }
public async Task SimpleDummySession() { const string TestName = "SimpleSession"; string testCacheId = MakeCacheId(TestName); ICache cache = await CreateCacheAsync(testCacheId); // Now for the session (which we base on the cache ID) string testSessionId = "Session1-" + testCacheId; ICacheSession session = await CreateSessionAsync(cache, testSessionId); // Do the default fake build for this test (first time, no cache hit) FullCacheRecord built = await FakeBuild.DoPipAsync(session, TestName); XAssert.AreEqual(FakeBuild.NewRecordCacheId, built.CacheId, "Should have been a new cache entry!"); // Now we see if we can get back the items we think we should await CloseSessionAsync(session, testSessionId); // We need a read only session to get the CasEntries ICacheReadOnlySession readOnlySession = (await cache.CreateReadOnlySessionAsync()).Success(); // Validate that the cache contains a dummy session and it has the one cache record it needs. HashSet <FullCacheRecord> found = new HashSet <FullCacheRecord>(); foreach (var strongFingerprintTask in cache.EnumerateSessionStrongFingerprints(MemoizationStoreAdapterCache.DummySessionName).Success().OutOfOrderTasks()) { StrongFingerprint strongFingerprint = await strongFingerprintTask; CasEntries casEntries = (await readOnlySession.GetCacheEntryAsync(strongFingerprint)).Success(); FullCacheRecord record = new FullCacheRecord(strongFingerprint, casEntries); // If it is not the record we already found... if (!found.Contains(record)) { found.Add(record); } XAssert.AreEqual(1, found.Count, "There should be only 1 unique record in the session"); XAssert.AreEqual(built.StrongFingerprint.WeakFingerprint, record.StrongFingerprint.WeakFingerprint); XAssert.AreEqual(built.StrongFingerprint.CasElement, record.StrongFingerprint.CasElement); XAssert.AreEqual(built.StrongFingerprint.HashElement, record.StrongFingerprint.HashElement); XAssert.AreEqual(built.CasEntries.Count, record.CasEntries.Count, "Did not return the same number of items"); XAssert.IsTrue(record.CasEntries.Equals(built.CasEntries), "Items returned are not the same hash and/or order order"); XAssert.AreEqual(built, record); // We can not check record.CasEntries.IsDeterministic // as the cache may have determined that they are deterministic // via cache determinism recovery. } XAssert.AreEqual(1, found.Count, "There should be 1 and only 1 record in the session!"); await readOnlySession.CloseAsync().SuccessAsync(); // Check that the cache has the items in it await FakeBuild.CheckContentsAsync(cache, built); // Now redo the "build" with a cache hit testSessionId = "Session2-" + testCacheId; session = await CreateSessionAsync(cache, testSessionId); FullCacheRecord rebuilt = await FakeBuild.DoPipAsync(session, TestName); XAssert.AreEqual(built, rebuilt, "Should have been the same build!"); // We make sure we did get it from a cache rather than a manual rebuild. XAssert.AreNotEqual(built.CacheId, rebuilt.CacheId, "Should not be the same cache ID"); await CloseSessionAsync(session, testSessionId); readOnlySession = await cache.CreateReadOnlySessionAsync().SuccessAsync(); // Now that we have done the second build via a cache hit, it should produce the // same cache record as before foreach (var strongFingerprintTask in cache.EnumerateSessionStrongFingerprints(MemoizationStoreAdapterCache.DummySessionName).Success().OutOfOrderTasks()) { StrongFingerprint strongFingerprint = await strongFingerprintTask; CasEntries casEntries = (await readOnlySession.GetCacheEntryAsync(strongFingerprint)).Success(); FullCacheRecord record = new FullCacheRecord(strongFingerprint, casEntries); XAssert.IsTrue(found.Contains(record), "Second session should produce the same cache record but did not!"); } (await readOnlySession.CloseAsync()).Success(); await ShutdownCacheAsync(cache, testCacheId); }
private FakeStrongFingerprint(WeakFingerprintHash weak, Hash hashElement, FakeBuild fake) : base(weak, fake.OutputListHash, hashElement, "FakeCache") { FakeBuild = fake; }