public async Task ProcessAsync_RecalculatesValueIfCacheKeyChanges()
        {
            // Arrange - 1
            var childContent1 = "original-child-content";
            var storage       = GetStorage();
            var service       = new DistributedCacheTagHelperService(
                storage,
                Mock.Of <IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance);
            var tagHelperContext1 = GetTagHelperContext();
            var tagHelperOutput1  = GetTagHelperOutput(childContent: childContent1);

            tagHelperOutput1.PreContent.Append("<cache>");
            tagHelperOutput1.PostContent.SetContent("</cache>");
            var cacheTagHelper1 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                VaryByCookie = "cookie1,cookie2",
                ViewContext  = GetViewContext(),
            };

            cacheTagHelper1.ViewContext.HttpContext.Request.Headers["Cookie"] = "cookie1=value1;cookie2=value2";

            // Act - 1
            await cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1);

            // Assert - 1
            Assert.Empty(tagHelperOutput1.PreContent.GetContent());
            Assert.Empty(tagHelperOutput1.PostContent.GetContent());
            Assert.True(tagHelperOutput1.IsContentModified);
            Assert.Equal(childContent1, tagHelperOutput1.Content.GetContent());

            // Arrange - 2
            var childContent2     = "different-content";
            var tagHelperContext2 = GetTagHelperContext();
            var tagHelperOutput2  = GetTagHelperOutput(childContent: childContent2);

            tagHelperOutput2.PreContent.SetContent("<cache>");
            tagHelperOutput2.PostContent.SetContent("</cache>");
            var cacheTagHelper2 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                VaryByCookie = "cookie1,cookie2",
                ViewContext  = GetViewContext(),
            };

            cacheTagHelper2.ViewContext.HttpContext.Request.Headers["Cookie"] = "cookie1=value1;cookie2=not-value2";

            // Act - 2
            await cacheTagHelper2.ProcessAsync(tagHelperContext2, tagHelperOutput2);

            // Assert - 2
            Assert.Empty(tagHelperOutput2.PreContent.GetContent());
            Assert.Empty(tagHelperOutput2.PostContent.GetContent());
            Assert.True(tagHelperOutput2.IsContentModified);
            Assert.Equal(childContent2, tagHelperOutput2.Content.GetContent());
        }
        public async Task ProcessAsync_ReturnsCachedValue_IfEnabled()
        {
            // Arrange
            var childContent = "original-child-content";
            var storage      = new Mock <IDistributedCacheTagHelperStorage>();
            var value        = Encoding.UTF8.GetBytes(childContent);

            storage.Setup(c => c.SetAsync(
                              /*key*/ It.IsAny <string>(),
                              /*value*/ value,
                              /*options*/ It.IsAny <DistributedCacheEntryOptions>()));
            storage.Setup(c => c.GetAsync(It.IsAny <string>()))
            .Returns(Task.FromResult <byte[]>(null));
            var service = new DistributedCacheTagHelperService(
                storage.Object,
                Mock.Of <IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance);
            var tagHelperContext = GetTagHelperContext();
            var tagHelperOutput  = GetTagHelperOutput(
                attributes: new TagHelperAttributeList(),
                childContent: childContent);
            var cacheTagHelper = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled     = true,
                Name        = "some-name"
            };

            // Act
            await cacheTagHelper.ProcessAsync(tagHelperContext, tagHelperOutput);

            // Assert
            Assert.Empty(tagHelperOutput.PreContent.GetContent());
            Assert.Empty(tagHelperOutput.PostContent.GetContent());
            Assert.True(tagHelperOutput.IsContentModified);
            Assert.Equal(childContent, tagHelperOutput.Content.GetContent());

            storage.Verify(c => c.GetAsync(
                               /*key*/ It.IsAny <string>()
                               ),
                           Times.Once);

            storage.Verify(c => c.SetAsync(
                               /*key*/ It.IsAny <string>(),
                               /*value*/ It.IsAny <byte[]>(),
                               /*options*/ It.IsAny <DistributedCacheEntryOptions>()),
                           Times.Once);
        }
        public async Task ProcessAsync_DoesNotCache_IfDisabled()
        {
            // Arrange
            var childContent = "original-child-content";
            var storage      = new Mock <IDistributedCacheTagHelperStorage>();
            var value        = Encoding.UTF8.GetBytes("ok");

            storage.Setup(c => c.SetAsync(
                              /*key*/ It.IsAny <string>(),
                              /*value*/ value,
                              /*options*/ It.IsAny <DistributedCacheEntryOptions>()));
            storage.Setup(c => c.GetAsync(It.IsAny <string>()))
            .Returns(Task.FromResult(value));
            var tagHelperContext = GetTagHelperContext();
            var service          = new DistributedCacheTagHelperService(
                storage.Object,
                Mock.Of <IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance);
            var tagHelperOutput = GetTagHelperOutput(
                attributes: new TagHelperAttributeList(),
                childContent: childContent);
            var cacheTagHelper = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled     = false
            };

            // Act
            await cacheTagHelper.ProcessAsync(tagHelperContext, tagHelperOutput);

            // Assert
            Assert.Equal(childContent, tagHelperOutput.Content.GetContent());
            storage.Verify(c => c.SetAsync(
                               /*key*/ It.IsAny <string>(),
                               /*content*/ value,
                               /*options*/ It.IsAny <DistributedCacheEntryOptions>()),
                           Times.Never);
        }
        public void UpdateCacheEntryOptions_DefaultsTo30SecondsSliding_IfNoEvictionCriteriaIsProvided()
        {
            // Arrange
            var slidingExpiresIn = TimeSpan.FromSeconds(30);
            var storage          = GetStorage();
            var service          = new DistributedCacheTagHelperService(
                storage,
                Mock.Of <IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance
                );
            var cacheTagHelper = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder());

            // Act
            var cacheEntryOptions = cacheTagHelper.GetDistributedCacheEntryOptions();

            // Assert
            Assert.Equal(slidingExpiresIn, cacheEntryOptions.SlidingExpiration);
        }
예제 #5
0
        public async Task ProcessAsync_DoesNotCache_IfDisabled()
        {
            // Arrange
            var childContent = "original-child-content";
            var storage = new Mock<IDistributedCacheTagHelperStorage>();
            var value = Encoding.UTF8.GetBytes("ok");
            storage.Setup(c => c.SetAsync(
                /*key*/ It.IsAny<string>(),
                /*value*/ value,
                /*options*/ It.IsAny<DistributedCacheEntryOptions>()));
            storage.Setup(c => c.GetAsync(It.IsAny<string>()))
                .Returns(Task.FromResult(value));
            var tagHelperContext = GetTagHelperContext();
            var service = new DistributedCacheTagHelperService(
                storage.Object,
                Mock.Of<IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance);
            var tagHelperOutput = GetTagHelperOutput(
                attributes: new TagHelperAttributeList(),
                childContent: childContent);
            var cacheTagHelper = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled = false
            };

            // Act
            await cacheTagHelper.ProcessAsync(tagHelperContext, tagHelperOutput);

            // Assert
            Assert.Equal(childContent, tagHelperOutput.Content.GetContent());
            storage.Verify(c => c.SetAsync(
                /*key*/ It.IsAny<string>(),
                /*content*/ value,
                /*options*/ It.IsAny<DistributedCacheEntryOptions>()),
                Times.Never);
        }
        public void UpdateCacheEntryOptions_SetsAbsoluteExpiration_IfExpiresAfterIsSet()
        {
            // Arrange
            var expiresAfter = TimeSpan.FromSeconds(42);
            var storage      = GetStorage();
            var service      = new DistributedCacheTagHelperService(
                storage,
                Mock.Of <IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder()
                );
            var cacheTagHelper = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ExpiresAfter = expiresAfter
            };

            // Act
            var cacheEntryOptions = cacheTagHelper.GetDistributedCacheEntryOptions();

            // Assert
            Assert.Equal(expiresAfter, cacheEntryOptions.AbsoluteExpirationRelativeToNow);
        }
        public void UpdateCacheEntryOptions_SetsSlidingExpiration_IfExpiresSlidingIsSet()
        {
            // Arrange
            var expiresSliding = TimeSpan.FromSeconds(37);
            var storage        = GetStorage();
            var service        = new DistributedCacheTagHelperService(
                storage,
                Mock.Of <IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder()
                );
            var cacheTagHelper = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ExpiresSliding = expiresSliding
            };

            // Act
            var cacheEntryOptions = cacheTagHelper.GetDistributedCacheEntryOptions();

            // Assert
            Assert.Equal(expiresSliding, cacheEntryOptions.SlidingExpiration);
        }
        public void UpdateCacheEntryOptions_SetsAbsoluteExpiration_IfExpiresOnIsSet()
        {
            // Arrange
            var expiresOn = DateTimeOffset.UtcNow.AddMinutes(4);
            var storage   = GetStorage();
            var service   = new DistributedCacheTagHelperService(
                storage,
                Mock.Of <IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder()
                );
            var cacheTagHelper = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ExpiresOn = expiresOn
            };

            // Act
            var cacheEntryOptions = cacheTagHelper.GetDistributedCacheEntryOptions();

            // Assert
            Assert.Equal(expiresOn, cacheEntryOptions.AbsoluteExpiration);
        }
예제 #9
0
        public async Task ProcessAsync_ReturnsCachedValue_IfVaryByParamIsUnchanged()
        {
            // Arrange - 1
            var childContent = "original-child-content";
            var storage = GetStorage();
            var formatter = GetFormatter();
            var tagHelperContext1 = GetTagHelperContext();
            var tagHelperOutput1 = GetTagHelperOutput(
                attributes: new TagHelperAttributeList(),
                childContent: childContent);
            var service = new DistributedCacheTagHelperService(
                storage,
                formatter,
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance);
            var cacheTagHelper1 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                Enabled = true,
                VaryByQuery = "key1,key2",
                ViewContext = GetViewContext(),
            };
            cacheTagHelper1.ViewContext.HttpContext.Request.QueryString = new QueryString(
                "?key1=value1&key2=value2");

            // Act - 1
            await cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1);

            // Assert - 1
            Assert.Empty(tagHelperOutput1.PreContent.GetContent());
            Assert.Empty(tagHelperOutput1.PostContent.GetContent());
            Assert.True(tagHelperOutput1.IsContentModified);
            Assert.Equal(childContent, tagHelperOutput1.Content.GetContent());

            // Arrange - 2
            var tagHelperContext2 = GetTagHelperContext();
            var tagHelperOutput2 = GetTagHelperOutput(
                attributes: new TagHelperAttributeList(),
                childContent: "different-content");
            var cacheTagHelper2 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                Enabled = true,
                VaryByQuery = "key1,key2",
                ViewContext = GetViewContext(),
            };
            cacheTagHelper2.ViewContext.HttpContext.Request.QueryString = new QueryString(
                "?key1=value1&key2=value2");

            // Act - 2
            await cacheTagHelper2.ProcessAsync(tagHelperContext2, tagHelperOutput2);

            // Assert - 2
            Assert.Empty(tagHelperOutput2.PreContent.GetContent());
            Assert.Empty(tagHelperOutput2.PostContent.GetContent());
            Assert.True(tagHelperOutput2.IsContentModified);
            Assert.Equal(childContent, tagHelperOutput2.Content.GetContent());
        }
        public async Task ProcessAsync_ExceptionInProcessing_DoesntBlockConcurrentRequests()
        {
            // Arrange
            var childContent = "some-content";
            var resetEvent1  = new ManualResetEvent(false);
            var resetEvent2  = new ManualResetEvent(false);
            var resetEvent3  = new ManualResetEvent(false);
            var calls        = 0;
            var formatter    = GetFormatter();
            var storage      = GetStorage();
            var service      = new DistributedCacheTagHelperService(
                storage,
                formatter,
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance
                );
            var tagHelperContext1 = GetTagHelperContext();
            var tagHelperContext2 = GetTagHelperContext();

            var tagHelperOutput1 = new TagHelperOutput(
                "distributed-cache",
                new TagHelperAttributeList(),
                getChildContentAsync: (useCachedResult, encoder) =>
            {
                calls++;
                resetEvent2.Set();

                throw new Exception();
            });

            var tagHelperOutput2 = new TagHelperOutput(
                "distributed-cache",
                new TagHelperAttributeList(),
                getChildContentAsync: (useCachedResult, encoder) =>
            {
                calls++;
                resetEvent3.WaitOne(5000);

                var tagHelperContent = new DefaultTagHelperContent();
                tagHelperContent.SetHtmlContent(childContent);
                return(Task.FromResult <TagHelperContent>(tagHelperContent));
            });

            var cacheTagHelper1 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled     = true
            };

            var cacheTagHelper2 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled     = true
            };

            // Act

            var task1 = Task.Run(async() =>
            {
                resetEvent1.WaitOne(5000);
                await Assert.ThrowsAsync <Exception>(() => cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1));
                resetEvent3.Set();
            });

            var task2 = Task.Run(async() =>
            {
                resetEvent2.WaitOne(5000);
                await cacheTagHelper2.ProcessAsync(tagHelperContext2, tagHelperOutput2);
            });

            resetEvent1.Set();
            await Task.WhenAll(task1, task2);

            // Assert
            Assert.Empty(tagHelperOutput1.PreContent.GetContent());
            Assert.Empty(tagHelperOutput1.PostContent.GetContent());
            Assert.False(tagHelperOutput1.IsContentModified);
            Assert.Empty(tagHelperOutput1.Content.GetContent());

            Assert.Empty(tagHelperOutput2.PreContent.GetContent());
            Assert.Empty(tagHelperOutput2.PostContent.GetContent());
            Assert.True(tagHelperOutput2.IsContentModified);
            Assert.Equal(childContent, tagHelperOutput2.Content.GetContent());

            Assert.Equal(2, calls);
        }
        public async Task ProcessAsync_UsesExpiresSliding_ToExpireCacheEntryWithSlidingExpiration()
        {
            // Arrange - 1
            var currentTime   = new DateTimeOffset(2010, 1, 1, 0, 0, 0, TimeSpan.Zero);
            var childContent1 = "original-child-content";
            var clock         = new Mock <ISystemClock>();

            clock.SetupGet(p => p.UtcNow)
            .Returns(() => currentTime);
            var storage = GetStorage(new MemoryCacheOptions {
                Clock = clock.Object
            });
            var service = new DistributedCacheTagHelperService(
                storage,
                Mock.Of <IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance
                );
            var tagHelperContext1 = GetTagHelperContext();
            var tagHelperOutput1  = GetTagHelperOutput(childContent: childContent1);

            tagHelperOutput1.PreContent.SetContent("<distributed-cache>");
            tagHelperOutput1.PostContent.SetContent("</distributed-cache>");
            var cacheTagHelper1 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext    = GetViewContext(),
                ExpiresSliding = TimeSpan.FromSeconds(30)
            };

            // Act - 1
            await cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1);

            // Assert - 1
            Assert.Empty(tagHelperOutput1.PreContent.GetContent());
            Assert.Empty(tagHelperOutput1.PostContent.GetContent());
            Assert.True(tagHelperOutput1.IsContentModified);
            Assert.Equal(childContent1, tagHelperOutput1.Content.GetContent());

            // Arrange - 2
            currentTime = currentTime.AddSeconds(35);
            var childContent2     = "different-content";
            var tagHelperContext2 = GetTagHelperContext();
            var tagHelperOutput2  = GetTagHelperOutput(childContent: childContent2);

            tagHelperOutput2.PreContent.SetContent("<distributed-cache>");
            tagHelperOutput2.PostContent.SetContent("</distributed-cache>");
            var cacheTagHelper2 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext    = GetViewContext(),
                ExpiresSliding = TimeSpan.FromSeconds(30)
            };

            // Act - 2
            await cacheTagHelper2.ProcessAsync(tagHelperContext2, tagHelperOutput2);

            // Assert - 2
            Assert.Empty(tagHelperOutput2.PreContent.GetContent());
            Assert.Empty(tagHelperOutput2.PostContent.GetContent());
            Assert.True(tagHelperOutput2.IsContentModified);
            Assert.Equal(childContent2, tagHelperOutput2.Content.GetContent());
        }
예제 #12
0
        public void UpdateCacheEntryOptions_SetsAbsoluteExpiration_IfExpiresOnIsSet()
        {
            // Arrange
            var expiresOn = DateTimeOffset.UtcNow.AddMinutes(4);
            var storage = GetStorage();
            var service = new DistributedCacheTagHelperService(
                storage,
                Mock.Of<IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance
                );
            var cacheTagHelper = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ExpiresOn = expiresOn
            };

            // Act
            var cacheEntryOptions = cacheTagHelper.GetDistributedCacheEntryOptions();

            // Assert
            Assert.Equal(expiresOn, cacheEntryOptions.AbsoluteExpiration);
        }
예제 #13
0
        public void UpdateCacheEntryOptions_SetsAbsoluteExpiration_IfExpiresAfterIsSet()
        {
            // Arrange
            var expiresAfter = TimeSpan.FromSeconds(42);
            var storage = GetStorage();
            var service = new DistributedCacheTagHelperService(
                storage,
                Mock.Of<IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance
                );
            var cacheTagHelper = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ExpiresAfter = expiresAfter
            };

            // Act
            var cacheEntryOptions = cacheTagHelper.GetDistributedCacheEntryOptions();

            // Assert
            Assert.Equal(expiresAfter, cacheEntryOptions.AbsoluteExpirationRelativeToNow);
        }
        public async Task ProcessAsync_ReturnsCachedValue_IfVaryByParamIsUnchanged()
        {
            // Arrange - 1
            var childContent      = "original-child-content";
            var storage           = GetStorage();
            var formatter         = GetFormatter();
            var tagHelperContext1 = GetTagHelperContext();
            var tagHelperOutput1  = GetTagHelperOutput(
                attributes: new TagHelperAttributeList(),
                childContent: childContent);
            var service = new DistributedCacheTagHelperService(
                storage,
                formatter,
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance);
            var cacheTagHelper1 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                Enabled     = true,
                VaryByQuery = "key1,key2",
                ViewContext = GetViewContext(),
            };

            cacheTagHelper1.ViewContext.HttpContext.Request.QueryString = new QueryString(
                "?key1=value1&key2=value2");

            // Act - 1
            await cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1);

            // Assert - 1
            Assert.Empty(tagHelperOutput1.PreContent.GetContent());
            Assert.Empty(tagHelperOutput1.PostContent.GetContent());
            Assert.True(tagHelperOutput1.IsContentModified);
            Assert.Equal(childContent, tagHelperOutput1.Content.GetContent());

            // Arrange - 2
            var tagHelperContext2 = GetTagHelperContext();
            var tagHelperOutput2  = GetTagHelperOutput(
                attributes: new TagHelperAttributeList(),
                childContent: "different-content");
            var cacheTagHelper2 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                Enabled     = true,
                VaryByQuery = "key1,key2",
                ViewContext = GetViewContext(),
            };

            cacheTagHelper2.ViewContext.HttpContext.Request.QueryString = new QueryString(
                "?key1=value1&key2=value2");

            // Act - 2
            await cacheTagHelper2.ProcessAsync(tagHelperContext2, tagHelperOutput2);

            // Assert - 2
            Assert.Empty(tagHelperOutput2.PreContent.GetContent());
            Assert.Empty(tagHelperOutput2.PostContent.GetContent());
            Assert.True(tagHelperOutput2.IsContentModified);
            Assert.Equal(childContent, tagHelperOutput2.Content.GetContent());
        }
예제 #15
0
        public void UpdateCacheEntryOptions_SetsSlidingExpiration_IfExpiresSlidingIsSet()
        {
            // Arrange
            var expiresSliding = TimeSpan.FromSeconds(37);
            var storage = GetStorage();
            var service = new DistributedCacheTagHelperService(
                storage,
                Mock.Of<IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance
                );
            var cacheTagHelper = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ExpiresSliding = expiresSliding
            };

            // Act
            var cacheEntryOptions = cacheTagHelper.GetDistributedCacheEntryOptions();

            // Assert
            Assert.Equal(expiresSliding, cacheEntryOptions.SlidingExpiration);
        }
예제 #16
0
        public async Task ProcessAsync_ExceptionInProcessing_DoesntBlockConcurrentRequests()
        {
            // Arrange
            var childContent = "some-content";
            var event1       = new TaskCompletionSource <int>(TaskCreationOptions.RunContinuationsAsynchronously);
            var event2       = new TaskCompletionSource <int>(TaskCreationOptions.RunContinuationsAsynchronously);
            var event3       = new TaskCompletionSource <int>(TaskCreationOptions.RunContinuationsAsynchronously);
            var calls        = 0;
            var formatter    = GetFormatter();
            var storage      = GetStorage();
            var service      = new DistributedCacheTagHelperService(
                storage,
                formatter,
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance
                );
            var tagHelperContext1 = GetTagHelperContext();
            var tagHelperContext2 = GetTagHelperContext();

            var tagHelperOutput1 = new TagHelperOutput(
                "distributed-cache",
                new TagHelperAttributeList(),
                getChildContentAsync: (useCachedResult, encoder) =>
            {
                calls++;
                event2.SetResult(0);

                throw new Exception();
            });

            var tagHelperOutput2 = new TagHelperOutput(
                "distributed-cache",
                new TagHelperAttributeList(),
                getChildContentAsync: async(useCachedResult, encoder) =>
            {
                calls++;
                await event3.Task.TimeoutAfter(TimeSpan.FromSeconds(5));

                var tagHelperContent = new DefaultTagHelperContent();
                tagHelperContent.SetHtmlContent(childContent);
                return(tagHelperContent);
            });

            var cacheTagHelper1 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled     = true
            };

            var cacheTagHelper2 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled     = true
            };

            // Act

            var task1 = Task.Run(async() =>
            {
                await event1.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
                await Assert.ThrowsAsync <Exception>(() => cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1));
                event3.SetResult(0);
            });

            var task2 = Task.Run(async() =>
            {
                await event2.Task.TimeoutAfter(TimeSpan.FromSeconds(5));
                await cacheTagHelper2.ProcessAsync(tagHelperContext2, tagHelperOutput2);
            });

            event1.SetResult(0);
            await Task.WhenAll(task1, task2);

            // Assert
            Assert.Empty(tagHelperOutput1.PreContent.GetContent());
            Assert.Empty(tagHelperOutput1.PostContent.GetContent());
            Assert.False(tagHelperOutput1.IsContentModified);
            Assert.Empty(tagHelperOutput1.Content.GetContent());

            Assert.Empty(tagHelperOutput2.PreContent.GetContent());
            Assert.Empty(tagHelperOutput2.PostContent.GetContent());
            Assert.True(tagHelperOutput2.IsContentModified);
            Assert.Equal(childContent, tagHelperOutput2.Content.GetContent());

            Assert.Equal(2, calls);
        }
        public async Task ProcessAsync_ComputesValueOnce_WithConcurrentRequests()
        {
            // Arrange
            var childContent = "some-content";
            var resetEvent1  = new ManualResetEvent(false);
            var resetEvent2  = new ManualResetEvent(false);
            var calls        = 0;
            var formatter    = GetFormatter();
            var storage      = GetStorage();
            var service      = new DistributedCacheTagHelperService(
                storage,
                formatter,
                new HtmlTestEncoder()
                );
            var tagHelperContext1 = GetTagHelperContext();
            var tagHelperContext2 = GetTagHelperContext();

            TagHelperOutput tagHelperOutput = new TagHelperOutput(
                "distributed-cache",
                new TagHelperAttributeList(),
                getChildContentAsync: (useCachedResult, encoder) =>
            {
                calls++;
                resetEvent2.Set();

                var tagHelperContent = new DefaultTagHelperContent();
                tagHelperContent.SetHtmlContent(childContent);
                return(Task.FromResult <TagHelperContent>(tagHelperContent));
            });

            var cacheTagHelper1 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled     = true
            };

            var cacheTagHelper2 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled     = true
            };

            // Act

            var task1 = Task.Run(async() =>
            {
                resetEvent1.WaitOne(5000);
                await cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput);
            });

            var task2 = Task.Run(async() =>
            {
                resetEvent2.WaitOne(5000);
                await cacheTagHelper2.ProcessAsync(tagHelperContext1, tagHelperOutput);
            });

            resetEvent1.Set();
            await Task.WhenAll(task1, task2);

            // Assert
            Assert.Empty(tagHelperOutput.PreContent.GetContent());
            Assert.Empty(tagHelperOutput.PostContent.GetContent());
            Assert.True(tagHelperOutput.IsContentModified);
            Assert.Equal(childContent, tagHelperOutput.Content.GetContent());

            Assert.Equal(1, calls);
        }
예제 #18
0
        public async Task ProcessAsync_RecalculatesValueIfCacheKeyChanges()
        {
            // Arrange - 1
            var childContent1 = "original-child-content";
            var storage = GetStorage();
            var service = new DistributedCacheTagHelperService(
                storage,
                Mock.Of<IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance);
            var tagHelperContext1 = GetTagHelperContext();
            var tagHelperOutput1 = GetTagHelperOutput(childContent: childContent1);
            tagHelperOutput1.PreContent.Append("<cache>");
            tagHelperOutput1.PostContent.SetContent("</cache>");
            var cacheTagHelper1 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                VaryByCookie = "cookie1,cookie2",
                ViewContext = GetViewContext(),
            };
            cacheTagHelper1.ViewContext.HttpContext.Request.Headers["Cookie"] = "cookie1=value1;cookie2=value2";

            // Act - 1
            await cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1);

            // Assert - 1
            Assert.Empty(tagHelperOutput1.PreContent.GetContent());
            Assert.Empty(tagHelperOutput1.PostContent.GetContent());
            Assert.True(tagHelperOutput1.IsContentModified);
            Assert.Equal(childContent1, tagHelperOutput1.Content.GetContent());

            // Arrange - 2
            var childContent2 = "different-content";
            var tagHelperContext2 = GetTagHelperContext();
            var tagHelperOutput2 = GetTagHelperOutput(childContent: childContent2);
            tagHelperOutput2.PreContent.SetContent("<cache>");
            tagHelperOutput2.PostContent.SetContent("</cache>");
            var cacheTagHelper2 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                VaryByCookie = "cookie1,cookie2",
                ViewContext = GetViewContext(),
            };
            cacheTagHelper2.ViewContext.HttpContext.Request.Headers["Cookie"] = "cookie1=value1;cookie2=not-value2";

            // Act - 2
            await cacheTagHelper2.ProcessAsync(tagHelperContext2, tagHelperOutput2);

            // Assert - 2
            Assert.Empty(tagHelperOutput2.PreContent.GetContent());
            Assert.Empty(tagHelperOutput2.PostContent.GetContent());
            Assert.True(tagHelperOutput2.IsContentModified);
            Assert.Equal(childContent2, tagHelperOutput2.Content.GetContent());
        }
예제 #19
0
        public async Task ProcessAsync_ReturnsCachedValue_IfEnabled()
        {
            // Arrange
            var childContent = "original-child-content";
            var storage = new Mock<IDistributedCacheTagHelperStorage>();
            var value = Encoding.UTF8.GetBytes(childContent);
            storage.Setup(c => c.SetAsync(
                /*key*/ It.IsAny<string>(),
                /*value*/ value,
                /*options*/ It.IsAny<DistributedCacheEntryOptions>()));
            storage.Setup(c => c.GetAsync(It.IsAny<string>()))
                .Returns(Task.FromResult<byte[]>(null));
            var service = new DistributedCacheTagHelperService(
                storage.Object,
                Mock.Of<IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance);
            var tagHelperContext = GetTagHelperContext();
            var tagHelperOutput = GetTagHelperOutput(
                attributes: new TagHelperAttributeList(),
                childContent: childContent);
            var cacheTagHelper = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled = true,
                Name = "some-name"
            };

            // Act
            await cacheTagHelper.ProcessAsync(tagHelperContext, tagHelperOutput);

            // Assert
            Assert.Empty(tagHelperOutput.PreContent.GetContent());
            Assert.Empty(tagHelperOutput.PostContent.GetContent());
            Assert.True(tagHelperOutput.IsContentModified);
            Assert.Equal(childContent, tagHelperOutput.Content.GetContent());

            storage.Verify(c => c.GetAsync(
                /*key*/ It.IsAny<string>()
                ),
                Times.Once);

            storage.Verify(c => c.SetAsync(
                /*key*/ It.IsAny<string>(),
                /*value*/ It.IsAny<byte[]>(),
                /*options*/ It.IsAny<DistributedCacheEntryOptions>()),
                Times.Once);

        }
예제 #20
0
        public async Task ProcessAsync_ExceptionInProcessing_DoesntBlockConcurrentRequests()
        {
            // Arrange
            var childContent = "some-content";
            var resetEvent1 = new ManualResetEvent(false);
            var resetEvent2 = new ManualResetEvent(false);
            var resetEvent3 = new ManualResetEvent(false);
            var calls = 0;
            var formatter = GetFormatter();
            var storage = GetStorage();
            var service = new DistributedCacheTagHelperService(
                storage,
                formatter,
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance
                );
            var tagHelperContext1 = GetTagHelperContext();
            var tagHelperContext2 = GetTagHelperContext();

            var tagHelperOutput1 = new TagHelperOutput(
                "distributed-cache",
                new TagHelperAttributeList(),
                getChildContentAsync: (useCachedResult, encoder) =>
                {
                    calls++;
                    resetEvent2.Set();

                    throw new Exception();
                });

            var tagHelperOutput2 = new TagHelperOutput(
                "distributed-cache",
                new TagHelperAttributeList(),
                getChildContentAsync: (useCachedResult, encoder) =>
                {
                    calls++;
                    resetEvent3.WaitOne(5000);

                    var tagHelperContent = new DefaultTagHelperContent();
                    tagHelperContent.SetHtmlContent(childContent);
                    return Task.FromResult<TagHelperContent>(tagHelperContent);
                });

            var cacheTagHelper1 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled = true
            };

            var cacheTagHelper2 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                Enabled = true
            };

            // Act

            var task1 = Task.Run(async () =>
            {
                resetEvent1.WaitOne(5000);
                await Assert.ThrowsAsync<Exception>(() => cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1));
                resetEvent3.Set();
            });

            var task2 = Task.Run(async () =>
            {
                resetEvent2.WaitOne(5000);
                await cacheTagHelper2.ProcessAsync(tagHelperContext2, tagHelperOutput2);
            });

            resetEvent1.Set();
            await Task.WhenAll(task1, task2);

            // Assert
            Assert.Empty(tagHelperOutput1.PreContent.GetContent());
            Assert.Empty(tagHelperOutput1.PostContent.GetContent());
            Assert.False(tagHelperOutput1.IsContentModified);
            Assert.Empty(tagHelperOutput1.Content.GetContent());

            Assert.Empty(tagHelperOutput2.PreContent.GetContent());
            Assert.Empty(tagHelperOutput2.PostContent.GetContent());
            Assert.True(tagHelperOutput2.IsContentModified);
            Assert.Equal(childContent, tagHelperOutput2.Content.GetContent());

            Assert.Equal(2, calls);
        }
예제 #21
0
        public async Task ProcessAsync_UsesExpiresSliding_ToExpireCacheEntryWithSlidingExpiration()
        {
            // Arrange - 1
            var currentTime = new DateTimeOffset(2010, 1, 1, 0, 0, 0, TimeSpan.Zero);
            var childContent1 = "original-child-content";
            var clock = new Mock<ISystemClock>();
            clock.SetupGet(p => p.UtcNow)
                .Returns(() => currentTime);
            var storage = GetStorage(new MemoryCacheOptions { Clock = clock.Object });
            var service = new DistributedCacheTagHelperService(
                storage,
                Mock.Of<IDistributedCacheTagHelperFormatter>(),
                new HtmlTestEncoder(),
                NullLoggerFactory.Instance
                );
            var tagHelperContext1 = GetTagHelperContext();
            var tagHelperOutput1 = GetTagHelperOutput(childContent: childContent1);
            tagHelperOutput1.PreContent.SetContent("<distributed-cache>");
            tagHelperOutput1.PostContent.SetContent("</distributed-cache>");
            var cacheTagHelper1 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                ExpiresSliding = TimeSpan.FromSeconds(30)
            };

            // Act - 1
            await cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1);

            // Assert - 1
            Assert.Empty(tagHelperOutput1.PreContent.GetContent());
            Assert.Empty(tagHelperOutput1.PostContent.GetContent());
            Assert.True(tagHelperOutput1.IsContentModified);
            Assert.Equal(childContent1, tagHelperOutput1.Content.GetContent());

            // Arrange - 2
            currentTime = currentTime.AddSeconds(35);
            var childContent2 = "different-content";
            var tagHelperContext2 = GetTagHelperContext();
            var tagHelperOutput2 = GetTagHelperOutput(childContent: childContent2);
            tagHelperOutput2.PreContent.SetContent("<distributed-cache>");
            tagHelperOutput2.PostContent.SetContent("</distributed-cache>");
            var cacheTagHelper2 = new DistributedCacheTagHelper(
                service,
                new HtmlTestEncoder())
            {
                ViewContext = GetViewContext(),
                ExpiresSliding = TimeSpan.FromSeconds(30)
            };

            // Act - 2
            await cacheTagHelper2.ProcessAsync(tagHelperContext2, tagHelperOutput2);

            // Assert - 2
            Assert.Empty(tagHelperOutput2.PreContent.GetContent());
            Assert.Empty(tagHelperOutput2.PostContent.GetContent());
            Assert.True(tagHelperOutput2.IsContentModified);
            Assert.Equal(childContent2, tagHelperOutput2.Content.GetContent());
        }