private Task RunCacheAndSessionTestAsync(Func <ICache, ICacheSession, Context, Task> funcAsync) { var context = new Context(Logger); return(RunTestAsync(context, async cache => { var createSessionResult = cache.CreateSession(context, context.Id.ToString(), ImplicitPin.None); createSessionResult.ShouldBeSuccess(); using (ICacheSession session = createSessionResult.Session) { try { var startupResult = await session.StartupAsync(context); startupResult.ShouldBeSuccess(); await funcAsync(cache, session, context); } finally { var shutdownResult = await session.ShutdownAsync(context); shutdownResult.ShouldBeSuccess(); } } })); }
private async Task <CasHash> AddPathSet(ICacheSession session, params string[] thePaths) { var pathTable = new PathTable(); ObservedPathEntry[] paths = new ObservedPathEntry[thePaths.Length]; for (int i = 0; i < thePaths.Length; i++) { AbsolutePath absPath = AbsolutePath.Create(pathTable, thePaths[i]); paths[i] = new ObservedPathEntry(absPath, false, false, false, null, false); } var emptyObservedAccessFileNames = SortedReadOnlyArray <StringId, CaseInsensitiveStringIdComparer> .FromSortedArrayUnsafe( ReadOnlyArray <StringId> .Empty, new CaseInsensitiveStringIdComparer(pathTable.StringTable)); ObservedPathSet pathSet = new ObservedPathSet( SortedReadOnlyArray <ObservedPathEntry, ObservedPathEntryExpandedPathComparer> .FromSortedArrayUnsafe( ReadOnlyArray <ObservedPathEntry> .FromWithoutCopy(paths), new ObservedPathEntryExpandedPathComparer(pathTable.ExpandedPathComparer)), emptyObservedAccessFileNames, null); using (var pathSetBuffer = new MemoryStream()) { using (var writer = new BuildXLWriter(stream: pathSetBuffer, debug: false, leaveOpen: true, logStats: false)) { pathSet.Serialize(pathTable, writer, preserveCasing: false); } pathSetBuffer.Seek(0, SeekOrigin.Begin); // Must await such that the dispose of the MemoryStream is only after the write completes return(await session.AddToCasAsync(pathSetBuffer).SuccessAsync()); } }
private async Task TestForOutOfSpace(string cacheId, Func <ICacheSession, Task> testSessionAsyncFunc) { var jsonConfig = NewCache(cacheId, true); ICacheConfigData cacheData; Exception exception; var success = CacheFactory.TryCreateCacheConfigData(jsonConfig, out cacheData, out exception); XAssert.IsTrue(success); XAssert.IsNull(exception); var maybeCacheConfig = cacheData.Create <MemoizationStoreCacheFactory.Config>(); XAssert.IsTrue(maybeCacheConfig.Succeeded); Possible <ICache, Failure> cachePossible = await InitializeCacheAsync(jsonConfig); ICache cache = cachePossible.Success(); string testSessionId = "Session1-" + cacheId; ICacheSession session = await CreateSessionAsync(cache, testSessionId); await testSessionAsyncFunc(session); await CloseSessionAsync(session, testSessionId); await ShutdownCacheAsync(cache, cacheId); }
public PublishingCacheSession(string name, ICacheSession local, IPublishingSession remote, bool publishAsynchronously) { Name = name; _local = local; _remote = remote; _publishAsynchronously = publishAsynchronously; }
internal static CallbackCacheSessionWrapper UnwrapLocalSession(ICacheSession session) { Contract.Requires(session is VerticalCacheAggregatorSession); Contract.Requires(((VerticalCacheAggregatorSession)session).LocalSession is CallbackCacheSessionWrapper); return(((VerticalCacheAggregatorSession)session).LocalSession as CallbackCacheSessionWrapper); }
/// <nodoc /> public CacheCoreArtifactContentCache( ICacheSession cache, RootTranslator rootTranslator) { m_cache = new PossiblyOpenCacheSession(cache); m_rootTranslator = rootTranslator; }
public async Task TestMustInclude() { const string TestName = "TestMustInclude"; string testCacheId = MakeCacheId(TestName); var cache = await CreateFilterCacheAsync(testCacheId, @".*\\.(EXE|DLL)$", string.Empty).SuccessAsync(); string sessionId = "Session"; ICacheSession session = (await cache.CreateSessionAsync(sessionId)).Success(); XAssert.AreEqual(sessionId, session.CacheSessionId); // This should absolutely work await AddToCache(session, file, libraryDll, tool).SuccessAsync(); // So should this (wish only one of the possible hits) await AddToCache(session, libraryDll).SuccessAsync(); // But this should fail var failed = await AddToCache(session, file, dllLib, toolPdb); XAssert.IsFalse(failed.Succeeded, "We should have caught a failure to have a regex match"); await CloseSessionAsync(session, sessionId); await ShutdownCacheAsync(cache, testCacheId); }
public async Task DuplicateActiveSession() { if (!ImplementsTrackedSessions) { return; } // Should not be able to create two active sessions of the same name const string TestName = nameof(DuplicateActiveSession); string testCacheId = MakeCacheId(TestName); ICache cache = await CreateCacheAsync(testCacheId); string testSessionId = "Session1-" + testCacheId; ICacheSession session = await CreateSessionAsync(cache, testSessionId); var failedSession = await cache.CreateSessionAsync(testSessionId); XAssert.IsTrue(!failedSession.Succeeded, "Session should not have been successfully created"); XAssert.IsTrue(failedSession.Failure is DuplicateSessionIdFailure); await CloseSessionAsync(session, testSessionId); foreach (var sessions in cache.EnumerateCompletedSessions()) { XAssert.Fail("There should not be any sessions in this cache!"); } await ShutdownCacheAsync(cache, testCacheId); }
public async Task DeterminismUpgraded(int fromDeterminism, int toDeterminism, bool differentCasEntries) { string testName = I($"DeterminismUpgraded{fromDeterminism}x{toDeterminism}{(differentCasEntries ? "Diff" : "Same")}"); string testCacheId = MakeCacheId(testName); ICache cache = await CreateCacheAsync(testCacheId); string testSessionId = "Session1-" + testCacheId; ICacheSession session = await CreateSessionAsync(cache, testSessionId); // We need at least 2 to make "differentCasEntries" work PipDefinition[] pips = { new PipDefinition("PipA", determinism: s_determinism[fromDeterminism]), new PipDefinition("PipB", determinism: s_determinism[fromDeterminism]) }; var records = (await pips.BuildAsync(session)).ToArray(); await CloseSessionAsync(session, testSessionId); testSessionId = "Session2-" + testCacheId; session = await CreateSessionAsync(cache, testSessionId); // What we will do here is AddOrGet() a record with the determinism bit changed. for (int i = 0; i < records.Length; i++) { var record = records[i]; // This gets the CasEntries we want CasEntries newEntries = records[(i + (differentCasEntries ? 1 : 0)) % records.Length].CasEntries; // Validate that the entry for the record is what we expect var entries = (await session.GetCacheEntryAsync(record.StrongFingerprint)).Success(); XAssert.AreEqual(s_determinism[fromDeterminism].EffectiveGuid, entries.Determinism.EffectiveGuid); // Now pin the CasElement and all of the CasEntries (await session.PinToCasAsync(record.StrongFingerprint.CasElement, CancellationToken.None)).Success(); (await session.PinToCasAsync(newEntries, CancellationToken.None)).Success(); // Now make a new record var newRecord = (await session.AddOrGetAsync( record.StrongFingerprint.WeakFingerprint, record.StrongFingerprint.CasElement, record.StrongFingerprint.HashElement, new CasEntries(newEntries, s_determinism[toDeterminism]))).Success(); // The new record should be null since the determinism was upgraded XAssert.IsNull(newRecord.Record); // Now, we will try to get the same record from the cache to validate // the setting of the bit entries = (await session.GetCacheEntryAsync(record.StrongFingerprint)).Success(); XAssert.AreEqual(newEntries, entries); XAssert.AreEqual(s_determinism[toDeterminism].EffectiveGuid, entries.Determinism.EffectiveGuid); } await CloseSessionAsync(session, testSessionId); await ShutdownCacheAsync(cache, testCacheId); }
/// <summary> /// Create a session and validate its base constructs /// </summary> /// <param name="cache">The cache</param> /// <param name="sessionId">The session name to create</param> /// <returns>A cache session</returns> protected async Task <ICacheSession> CreateSessionAsync(ICache cache, string sessionId) { ICacheSession session = (await cache.CreateSessionAsync(sessionId)).Success(); XAssert.AreEqual(sessionId, session.CacheSessionId); return(session); }
private async Task BuildPips(BasicFilesystemCache cache, string sessionName, PipDefinition[] pips) { ICacheSession session = await cache.CreateSessionAsync(sessionName).SuccessAsync(); await pips.BuildAsync(session); AssertSuccess(await session.CloseAsync()); }
/// <nodoc /> public CacheCoreArtifactContentCache( ICacheSession cache, RootTranslator rootTranslator, bool replaceExistingFileOnMaterialization = false) { m_cache = new PossiblyOpenCacheSession(cache); m_rootTranslator = rootTranslator; m_replaceExistingFileOnMaterialization = replaceExistingFileOnMaterialization; }
internal CompositingCacheSession( ICacheSession metadataSession, ICacheSession casSesssion, ICache cache) : base(metadataSession, casSesssion, cache) { m_metadataSession = metadataSession; m_casSession = casSesssion; }
public async Task CorruptionRecovery() { const string TestName = nameof(CorruptionRecovery); string testCacheId = MakeCacheId(TestName); ICache cache = await CreateCacheAsync(testCacheId); string testSessionId = "Session1-" + testCacheId; ICacheSession session = await CreateSessionAsync(cache, testSessionId); // Use the testname to generate a CAS items. CasHash item = (await session.AddToCasAsync(TestName.AsStream())).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()) { XAssert.AreEqual(TestName, stream.AsString(), "Failed to read back matching content from cache"); } ValidateContentStatus goodStatus = (await session.ValidateContentAsync(item)).Success(); // We can have implemented ValidateContent and not have a way to test corruption but // we must have implemented ValidateCotent if we have a way to test corruption if (CanTestCorruption || (goodStatus != ValidateContentStatus.NotSupported)) { // We should have returned Ok since the content was not corrupted XAssert.AreEqual(ValidateContentStatus.Ok, goodStatus, "Content should have matched in hash at this point!"); // NoItem should always be valid XAssert.AreEqual(ValidateContentStatus.Ok, (await session.ValidateContentAsync(CasHash.NoItem)).Success(), "NoItem should always be valid!"); // Now, only if we can test corruption (which requires that we can corrupt an item) // do we go down this next path if (CanTestCorruption) { await CorruptCasEntry(cache, item); using (Stream stream = (await session.GetStreamAsync(item)).Success()) { XAssert.AreNotEqual(TestName, stream.AsString(), "Failed to corrupt CAS entry!"); } ValidateContentStatus corruptedStatus = (await session.ValidateContentAsync(item)).Success(); // At this point, caches can do a number of possible things // They can not return OK or NotImplemented (since we already checked that earlier) XAssert.AreNotEqual(ValidateContentStatus.Ok, corruptedStatus, "The item was corrupted - something should have happened"); XAssert.AreNotEqual(ValidateContentStatus.NotSupported, corruptedStatus, "It was implemented a moment earlier"); } } await CloseSessionAsync(session, testSessionId); await ShutdownCacheAsync(cache, testCacheId); }
/// <summary> /// 初始化数据 /// </summary> public void Initial() { //读取 enableRedis = ConfigManage.AppSettings <bool>("RedisConfig:EnableRedis"); if (enableRedis) { cacheRedis = CacheSessionFactory.Instance.CreateCache(); } //版本号 VNo = ConfigManage.AppSettings <string>("AppSettings:VNo"); //系统名称 SysName = ConfigManage.AppSettings <string>("AppSettings:SysName"); //资源域名 Res = ConfigManage.AppSettings <string>("AppSettings:DomainRes"); //后台域名 Admin = ConfigManage.AppSettings <string>("AppSettings:DomainAdmin"); //获取所有菜单 List <SysModelMenu> db_menus = ServiceIoc.Get <SysModelMenuService>().Where(m => m.is_enable == true).OrderByDescending(a => a.order_index).ToList(); //获取所有权限 List <SysPermission> db_permissions = ServiceIoc.Get <SysPermissionService>().GetAll().OrderByDescending(a => a.order_index).ToList(); //角色集合 List <SysRole> db_reles = ServiceIoc.Get <SysRoleService>().Where(r => r.is_enable == true).ToList(); //用户角色权限 List <UserRole> db_user_reles = ServiceIoc.Get <UserRoleService>().GetAll(); //所有用户权限 //List<SysUserPermission> db_user_permissions = ServiceIoc.Get<SysUserPermissionService>().GetAll(); //用户角色权限 List <SysRolePermission> db_role_permissions = ServiceIoc.Get <SysRolePermissionService>().GetAll(); //是否开启Redis缓存 if (EnableRedis) { //系统菜单 cacheRedis.Write(sys_menu_key, db_menus, CacheId.module); //系统权限 cacheRedis.Write(sys_func_key, db_permissions, CacheId.module); //系统角色 cacheRedis.Write(sys_role_key, db_reles, CacheId.module); //系统角色权限 cacheRedis.Write(sys_role_func_key, db_role_permissions, CacheId.module); } else { //系统菜单 menus = db_menus; //系统权限 permissions = db_permissions; //系统角色 roles = db_reles; //系统角色权限 rolePermissions = db_role_permissions; } }
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 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); }; }
/// <summary> /// Initializes a new instance of the <see cref="DistributedCacheSession" /> class. /// </summary> public DistributedCacheSession( ILogger logger, string name, ICacheSession innerCacheSession, Guid innerCacheId, IMetadataCache metadataCache, DistributedCacheSessionTracer tracer, ReadThroughMode readThroughModeMode) : base(logger, name, innerCacheSession, innerCacheId, metadataCache, tracer, readThroughModeMode) { Contract.Requires(logger != null); Contract.Requires(innerCacheSession != null); Contract.Requires(metadataCache != null); _innerCacheSession = innerCacheSession; }
/// <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="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> /// <param name="generateVerifiablePip">Indicates that the pip generated should be verfiiable by CheckContentAsync</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. /// /// The outputs of this pip will be unique for each call, but have the same strong fingerprint. /// /// The WeakFingerprint and input hash element are derived from the pipName. /// </remarks> public static Task <FullCacheRecord> DoNonDeterministicPipAsync( ICacheSession session, string pipName, bool generateVerifiablePip = false, int pipSize = DefaultFakeBuildSize, CacheDeterminism determinism = default(CacheDeterminism), CasAccessMethod accessMethod = CasAccessMethod.Stream) { Contract.Requires(session != null); Contract.Requires(pipName != null); Contract.Requires(pipSize > 0); FakeStrongFingerprint fakePrint = FakeStrongFingerprint.Create(pipName, generateVerifiablePip, pipSize); return(DoPipAsyncImpl(session, fakePrint.WeakFingerprint, fakePrint.HashElement, fakePrint.FakeBuild, determinism, accessMethod)); }
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 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); }
/// <summary> /// Helper method to run a set of pip definitions through the cache /// </summary> /// <param name="testName">Name of the test</param> /// <param name="pips">Pip definitions to run</param> /// <param name="accessMethod">Cas access method (stream or file)</param> /// <returns>async task only - no value</returns> protected async Task TestMultiplePipsAsync(string testName, PipDefinition[] pips, FakeBuild.CasAccessMethod accessMethod) { string testCacheId = MakeCacheId(testName + accessMethod); ICache cache = await CreateCacheAsync(testCacheId); // Now for the session (which we base on the cache ID) string testSessionId = "Session1-" + cache.CacheId; ICacheSession session = await CreateSessionAsync(cache, testSessionId); HashSet <FullCacheRecord> records = await pips.BuildAsync(session); XAssert.AreEqual(pips.Length, records.Count, "Should have had {0} cache records generated!", pips.Length); foreach (var record in records) { XAssert.AreEqual(FakeBuild.NewRecordCacheId, record.CacheId); } // Now we see if we can get back the items we think we should await CloseSessionAsync(session, testSessionId); // Check that the content is fine await ValidateSessionAsync(records, cache, testSessionId, accessMethod); // Cache hits test... testSessionId = "Session2-" + cache.CacheId; session = await CreateSessionAsync(cache, testSessionId); foreach (var record in await pips.BuildAsync(session)) { XAssert.AreNotEqual(FakeBuild.NewRecordCacheId, record.CacheId); XAssert.IsTrue(records.Contains(record)); } await CloseSessionAsync(session, testSessionId); // Check that the content is fine await ValidateSessionAsync(records, cache, testSessionId, accessMethod); await ShutdownCacheAsync(cache, testCacheId); }
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)); }