public async Task PutObject_NoActiveReferences_ForceOneEviction_VerifyCorrectEviction()
        {
            int    contentSize  = 2 * 1024 * 1024; // 2MB
            int    cacheSize    = 6 * 1024 * 1024; // 6MB
            string cacheSizeVal = cacheSize.ToString();

            IEnvironment environment = new TestEnvironment();

            environment.SetEnvironmentVariable(FunctionDataCacheConstants.FunctionDataCacheMaximumSizeBytesSettingName, cacheSizeVal);
            environment.SetEnvironmentVariable(FunctionDataCacheConstants.FunctionDataCacheEnabledSettingName, "1");

            using (ISharedMemoryManager manager = new SharedMemoryManager(_loggerFactory, _mapAccessor))
                using (FunctionDataCache cache = new FunctionDataCache(manager, _loggerFactory, environment))
                {
                    // Prepare content
                    byte[] content = TestUtils.GetRandomBytesInArray(contentSize);

                    // Put into shared memory as three distinct objects
                    SharedMemoryMetadata metadata1 = await manager.PutObjectAsync(content);

                    SharedMemoryMetadata metadata2 = await manager.PutObjectAsync(content);

                    SharedMemoryMetadata metadata3 = await manager.PutObjectAsync(content);

                    // Put the three objects into the cache
                    FunctionDataCacheKey key1 = new FunctionDataCacheKey("foo1", "bar1");
                    FunctionDataCacheKey key2 = new FunctionDataCacheKey("foo2", "bar2");
                    FunctionDataCacheKey key3 = new FunctionDataCacheKey("foo3", "bar3");
                    Assert.True(cache.TryPut(key1, metadata1, isIncrementActiveReference: false, isDeleteOnFailure: false));
                    Assert.True(cache.TryPut(key2, metadata2, isIncrementActiveReference: false, isDeleteOnFailure: false));
                    Assert.True(cache.TryPut(key3, metadata3, isIncrementActiveReference: false, isDeleteOnFailure: false));

                    // Verify that the cache is full
                    Assert.Equal(0, cache.RemainingCapacityBytes);

                    // At this point, the cache is full.
                    // We will create another object and try to insert it.
                    // This should be inserted (as another object will be evicted to make room for this).
                    SharedMemoryMetadata metadata4 = await manager.PutObjectAsync(content);

                    FunctionDataCacheKey key4 = new FunctionDataCacheKey("foo4", "bar4");
                    Assert.True(cache.TryPut(key4, metadata4, isIncrementActiveReference: false, isDeleteOnFailure: false));

                    // The first object should be evicted (least recently used) by now
                    Assert.False(cache.TryGet(key1, isIncrementActiveReference: false, out var _));

                    // Try to open the shared memory map of the first object and ensure it is removed and cannot be opened
                    Assert.False(_mapAccessor.TryOpen(metadata1.MemoryMapName, out var _));

                    // The last three objects (the first two added before eviction and the one resulting in eviction) should be present
                    Assert.True(cache.TryGet(key2, isIncrementActiveReference: false, out var _));
                    Assert.True(cache.TryGet(key3, isIncrementActiveReference: false, out var _));
                    Assert.True(cache.TryGet(key4, isIncrementActiveReference: false, out var _));

                    // Verify that the cache is full
                    Assert.Equal(0, cache.RemainingCapacityBytes);
                }
        }
Пример #2
0
        /// <summary>
        /// Helper method to open a <see cref="SharedMemoryMap"/> for tests.
        /// </summary>
        /// <param name="mapName">Name of the <see cref="MemoryMappedFile"/> backing the <see cref="SharedMemoryMap"/>.</param>
        /// <returns><see cref="SharedMemoryMap"/> that was opened, <see cref="null"/> in case of failure.</returns>
        private SharedMemoryMap Open(string mapName)
        {
            if (_mapAccessor.TryOpen(mapName, out MemoryMappedFile mmf))
            {
                return(new SharedMemoryMap(_loggerFactory, _mapAccessor, mapName, mmf));
            }

            return(null);
        }
Пример #3
0
        /// <summary>
        /// Open a <see cref="SharedMemoryMap"/> with the given name.
        /// </summary>
        /// <param name="mapName">Size of <see cref="SharedMemoryMap"/> to open.</param>
        /// <returns><see cref="SharedMemoryMap"/> if opened successfully, <see cref="null"/> otherwise.</returns>
        private SharedMemoryMap Open(string mapName)
        {
            if (_mapAccessor.TryOpen(mapName, out MemoryMappedFile mmf))
            {
                return(new SharedMemoryMap(_loggerFactory, _mapAccessor, mapName, mmf));
            }

            _logger.LogTrace("Cannot open shared memory map: {MapName}", mapName);
            return(null);
        }
Пример #4
0
        public async Task FreeSharedMemoryMap_VerifySuccess()
        {
            // Prepare content
            string content = "foobar";

            using (SharedMemoryManager manager = new SharedMemoryManager(_loggerFactory, _mapAccessor))
            {
                // Put content into shared memory
                SharedMemoryMetadata metadata = await manager.PutObjectAsync(content);

                string mapName = metadata.MemoryMapName;

                // Free the shared memory map and try top open it after freeing; should not open
                Assert.True(manager.TryFreeSharedMemoryMap(mapName));
                Assert.False(_mapAccessor.TryOpen(mapName, out _));
            }
        }
Пример #5
0
        public void Create_Open_VerifyOpened()
        {
            long   size    = 1024;
            string mapName = Guid.NewGuid().ToString();

            // Create
            Assert.True(_mapAccessor.TryCreate(mapName, size, out MemoryMappedFile mmf1));
            Assert.NotNull(mmf1);

            // Open
            Assert.True(_mapAccessor.TryOpen(mapName, out MemoryMappedFile mmf2));
            Assert.NotNull(mmf2);

            _mapAccessor.Delete(mapName, mmf1);
            _mapAccessor.Delete(mapName, mmf2);
        }