예제 #1
0
        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();
                    }
                }
            }));
        }
예제 #2
0
        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);
        }
예제 #4
0
 public PublishingCacheSession(string name, ICacheSession local, IPublishingSession remote, bool publishAsynchronously)
 {
     Name    = name;
     _local  = local;
     _remote = remote;
     _publishAsynchronously = publishAsynchronously;
 }
예제 #5
0
        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;
 }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
        /// <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);
        }
예제 #11
0
        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());
        }
예제 #12
0
 /// <nodoc />
 public CacheCoreArtifactContentCache(
     ICacheSession cache,
     RootTranslator rootTranslator,
     bool replaceExistingFileOnMaterialization = false)
 {
     m_cache          = new PossiblyOpenCacheSession(cache);
     m_rootTranslator = rootTranslator;
     m_replaceExistingFileOnMaterialization = replaceExistingFileOnMaterialization;
 }
예제 #13
0
 internal CompositingCacheSession(
     ICacheSession metadataSession,
     ICacheSession casSesssion,
     ICache cache)
     : base(metadataSession, casSesssion, cache)
 {
     m_metadataSession = metadataSession;
     m_casSession      = casSesssion;
 }
예제 #14
0
        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);
        }
예제 #15
0
        /// <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;
            }
        }
예제 #16
0
        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);
        }
예제 #17
0
        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);
        }
예제 #18
0
        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);
        }
예제 #19
0
        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]));
        }
예제 #20
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();
        }
예제 #21
0
        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);
            };
        }
예제 #22
0
        /// <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;
        }
예제 #23
0
        /// <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));
        }
예제 #24
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);
        }
예제 #25
0
        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);
        }
예제 #26
0
        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);
        }
예제 #27
0
        /// <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);
        }
예제 #28
0
        /// <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);
        }
예제 #29
0
        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);
        }
예제 #30
0
        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));
        }