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 DisconnectMostRemoteCacheAddNewReconnect() { string cacheId = "MutlipleCacheRemote"; ICache testCache = await InitializeCacheAsync(NewCache(cacheId, true, false, true)).SuccessAsync(); VerticalCacheAggregator lowerVert = testCache as VerticalCacheAggregator; XAssert.IsNotNull(lowerVert); CallbackCacheWrapper callbackCache = lowerVert.RemoteCache as CallbackCacheWrapper; XAssert.IsNotNull(callbackCache); VerticalCacheAggregator upperVert = callbackCache.WrappedCache as VerticalCacheAggregator; XAssert.IsNotNull(upperVert); ICacheSession session = await testCache.CreateSessionAsync().SuccessAsync(); VerticalAggregatorDisconnectTests.DisconnectCache(upperVert.RemoteCache); FullCacheRecord cacheRecord = await FakeBuild.DoPipAsync(session, "Test Pip"); VerticalAggregatorDisconnectTests.ConnectCache(upperVert.RemoteCache); // Now query each cache, and verify only the remote content is in each. var aggregatorStats = new Dictionary <string, double>(); var remoteDeterminism = CacheDeterminism.ViaCache(upperVert.RemoteCache.CacheGuid, CacheDeterminism.NeverExpires); foreach (var currentCache in new Tuple <ICache, CacheDeterminism, string, int, Dictionary <string, double> >[] { new Tuple <ICache, CacheDeterminism, string, int, Dictionary <string, double> >(testCache, remoteDeterminism, lowerVert.LocalCache.CacheId, 3, aggregatorStats), new Tuple <ICache, CacheDeterminism, string, int, Dictionary <string, double> >(lowerVert.LocalCache, remoteDeterminism, lowerVert.LocalCache.CacheId, 1, null), new Tuple <ICache, CacheDeterminism, string, int, Dictionary <string, double> >(upperVert.LocalCache, remoteDeterminism, upperVert.LocalCache.CacheId, 1, null), new Tuple <ICache, CacheDeterminism, string, int, Dictionary <string, double> >(upperVert.RemoteCache, remoteDeterminism, upperVert.RemoteCache.CacheId, 1, null) }) { await ValidateItemsInCacheAsync( currentCache.Item1, cacheRecord.StrongFingerprint.WeakFingerprint, new List <CasHash>(cacheRecord.CasEntries), currentCache.Item2, cacheRecord.StrongFingerprint.CasElement, currentCache.Item3, currentCache.Item4); } await testCache.ShutdownAsync().SuccessAsync(); }
internal static void PoisonAllRemoteSessions(ICache cache) { Contract.Requires(cache is VerticalCacheAggregator); VerticalCacheAggregator vertCache = cache as VerticalCacheAggregator; CallbackCacheWrapper remoteCache = vertCache.RemoteCache as CallbackCacheWrapper; XAssert.IsNotNull(remoteCache); remoteCache.CreateNamedSessionAsyncCallback = async(string sessionId, ICache cacheInstance) => { ICacheSession session = await cacheInstance.CreateSessionAsync(sessionId).SuccessAsync(); CallbackCacheSessionWrapper wrappedSession = new CallbackCacheSessionWrapper(session); PoisonSession(wrappedSession); return(new BuildXL.Utilities.Possible <ICacheSession, BuildXL.Utilities.Failure>(session)); }; remoteCache.CreateSessionAsyncCallback = async(ICache cacheInstance) => { ICacheSession session = await cacheInstance.CreateSessionAsync().SuccessAsync(); CallbackCacheSessionWrapper wrappedSession = new CallbackCacheSessionWrapper(session); PoisonSession(wrappedSession); return(new BuildXL.Utilities.Possible <ICacheSession, BuildXL.Utilities.Failure>(session)); }; remoteCache.CreateReadOnlySessionAsyncCallback = async(ICache cacheInstance) => { ICacheReadOnlySession session = await cacheInstance.CreateReadOnlySessionAsync().SuccessAsync(); CallbackCacheReadOnlySessionWrapper wrappedSession = new CallbackCacheReadOnlySessionWrapper(session); PoisonROSession(wrappedSession); return(new BuildXL.Utilities.Possible <ICacheReadOnlySession, BuildXL.Utilities.Failure>(session)); }; remoteCache.CacheGuidGetCallback = (ICache wrappedcache) => { XAssert.Fail("Remote Cache was called when disconnected (CacheGuid)"); return(Guid.Empty); }; }
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()); }
/// <summary> /// Performs a consistency check of the specified cache. /// If the cache is a VerticalCacheAggregator, a two level /// check will be performed. Otherwise, a single level /// check will be performed. /// </summary> /// <returns>Status code. 0 => success, non-zero => failure</returns> private int DoConsistencyCheck() { Console.Error.WriteLine("\nStarting consistency check"); // Start timing Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); IEnumerable <CacheError> cacheErrors; VerticalCacheAggregator verticalCacheAggregator = m_cache as VerticalCacheAggregator; if (verticalCacheAggregator != null) { ICache localCache = verticalCacheAggregator.LocalCache; ICache remoteCache = verticalCacheAggregator.RemoteCache; TwoLevelCacheChecker cacheChecker = new TwoLevelCacheChecker(localCache, remoteCache, m_rehashCASContent); if (m_inputWeakFingerprints.Count > 0) { Console.Error.WriteLine("\nChecking through the " + m_inputWeakFingerprints.Count + " provided weak fingerprints"); cacheErrors = cacheChecker.CheckCache(m_inputWeakFingerprints, m_weakFingerprintsFound).Result; } else { try { Console.Error.WriteLine("\nChecking through the sessions using the following regex: " + m_sessionRegex.ToString()); cacheErrors = cacheChecker.CheckCache(m_sessionRegex, m_weakFingerprintsFound).Result; Console.Error.WriteLine(string.Format(CultureInfo.InvariantCulture, "\nSessions checked/Total sessions: {0}/{1}", cacheChecker.NumSessionsChecked, cacheChecker.NumSessions)); } catch (NotImplementedException e) { // Not all cache implementations implement all of the interface methods WriteError("Exception caught: " + e.Message); WriteError("The implementation of the specified cache does not implement all required methods for this tool to be able to perform a check."); return(1); } } Console.Error.WriteLine("\nNumber of FullCacheRecords checked: " + cacheChecker.NumFullCacheRecords); } else { SingleCacheChecker cacheChecker = new SingleCacheChecker(m_jsonString, m_rehashCASContent); if (m_inputWeakFingerprints.Count > 0) { Console.Error.WriteLine("\nChecking through the " + m_inputWeakFingerprints.Count + " provided weak fingerprints"); cacheErrors = cacheChecker.CheckCache(m_inputWeakFingerprints, m_weakFingerprintsFound).Result; } else { try { Console.Error.WriteLine("\nChecking through the sessions using the following regex: " + m_sessionRegex.ToString()); cacheErrors = cacheChecker.CheckCache(m_sessionRegex, m_weakFingerprintsFound).Result; Console.Error.WriteLine(string.Format(CultureInfo.InvariantCulture, "\nSessions checked/Total sessions: {0}/{1}", cacheChecker.NumSessionsChecked, cacheChecker.NumSessions)); } catch (NotImplementedException e) { // Not all cache implementations implement all of the interface methods WriteError("Exception caught: " + e.Message); WriteError("The implementation of the specified cache does not implement all required methods for this tool to be able to perform a check."); return(1); } } Console.Error.WriteLine("\nNumber of FullCacheRecords checked: " + cacheChecker.AllFullCacheRecords.Count); } // Output cache errors found during check OutputCacheErrors(cacheErrors); // Stop timing stopwatch.Stop(); Console.Error.WriteLine("\nTotal time to check cache: " + stopwatch.Elapsed.TotalSeconds.ToString("F", CultureInfo.CurrentCulture) + " seconds"); return(0); }