diff --git a/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/CacheDependencyTests.cs b/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/CacheDependencyTests.cs
new file mode 100644
index 0000000000..a6d5f192a6
--- /dev/null
+++ b/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/CacheDependencyTests.cs
@@ -0,0 +1,162 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.Caching;
+using System.Threading.Tasks;
+using System.Web;
+using System.Web.Caching;
+using AutoFixture;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.TestHost;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.SystemWebAdapters.Tests;
+
+///
+/// Tests for . These use in some cases and must be tested within a host if cache keys are used
+///
+[Collection(nameof(SelfHostedTests))]
+public class CacheDependencyTests
+{
+ private readonly Fixture _fixture;
+
+ public CacheDependencyTests()
+ {
+ _fixture = new Fixture();
+ }
+
+ [Fact]
+ public void InsertWithDependency()
+ {
+ // Arrange
+ var memCache = new Mock(_fixture.Create(), null);
+ var cache = new Cache(memCache.Object);
+ var key = _fixture.Create();
+ var item = new object();
+ var cacheDependency = new Mock();
+
+ // Act
+ cache.Insert(key, item, cacheDependency.Object);
+
+ // Assert
+ memCache.Verify(m => m.Set(key, item, It.Is(e => e.AbsoluteExpiration.DateTime.Equals(Cache.NoAbsoluteExpiration) && e.SlidingExpiration.Equals(Cache.NoSlidingExpiration)), null), Times.Once);
+ }
+
+ [Fact]
+ public async Task DependentFileCallback()
+ {
+ // Arrange
+ using var memCache = new MemoryCache(_fixture.Create());
+ var cache = new Cache(memCache);
+ var item = new object();
+ var key = _fixture.Create();
+ var updated = false;
+ var slidingExpiration = TimeSpan.FromMilliseconds(1);
+ CacheItemUpdateReason? updateReason = default;
+
+ var tcs = new TaskCompletionSource();
+
+ void Callback(string key, CacheItemUpdateReason reason, out object? expensiveObject, out CacheDependency? dependency, out DateTime absoluteExpiration, out TimeSpan slidingExpiration)
+ {
+ expensiveObject = null;
+ dependency = null;
+ absoluteExpiration = Cache.NoAbsoluteExpiration;
+ slidingExpiration = TimeSpan.FromMilliseconds(5);
+
+ updated = true;
+ updateReason = reason;
+
+ tcs.SetResult();
+ }
+
+ var file = Path.GetTempFileName();
+ await File.WriteAllTextAsync(file, key);
+
+ using var cd = new CacheDependency(file);
+ // Act
+ cache.Insert(key, item, cd, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, Callback);
+
+ // Ensure file is updated
+ await File.WriteAllTextAsync(file, DateTime.UtcNow.ToString("O"));
+
+ // Wait for callback to be called
+ await tcs.Task;
+
+ // Wait for callback to be finalized
+ await Task.Delay(100);
+
+ // Assert
+ Assert.True(updated);
+ Assert.Null(cache[key]);
+ Assert.Equal(CacheItemUpdateReason.DependencyChanged, updateReason);
+ }
+
+ [Fact]
+ public async Task DependentItemCallback()
+ {
+ // Arrange
+ using var memCache = new MemoryCache(_fixture.Create());
+ var cache = new Cache(memCache);
+ using var host = StartHost(cache);
+
+ var item1 = new object();
+ var item2 = new object();
+ var key1 = _fixture.Create();
+ var key2 = _fixture.Create();
+ var updateReason = new Dictionary();
+ var slidingExpiration = TimeSpan.FromMilliseconds(1);
+
+ void Callback(string key, CacheItemUpdateReason reason, out object? expensiveObject, out CacheDependency? dependency, out DateTime absoluteExpiration, out TimeSpan slidingExpiration)
+ {
+ expensiveObject = null;
+ dependency = null;
+ absoluteExpiration = Cache.NoAbsoluteExpiration;
+ slidingExpiration = Cache.NoSlidingExpiration;
+
+ updateReason[key] = reason;
+ }
+
+ // Act
+ cache.Insert(key1, item1, null, Cache.NoAbsoluteExpiration, slidingExpiration, Callback);
+
+ using var cd = new CacheDependency(null, new[] { key1 });
+ cache.Insert(key2, item2, cd, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, Callback);
+
+ Assert.Empty(updateReason);
+
+ // Ensure sliding expiration has hit
+ await Task.Delay(slidingExpiration);
+
+ // Force cleanup to initiate callbacks on current thread
+ memCache.Trim(100);
+
+ // Assert
+ Assert.Contains(key1, updateReason.Keys);
+ Assert.Contains(key2, updateReason.Keys);
+
+ Assert.Null(cache[key1]);
+ Assert.Null(cache[key2]);
+
+ Assert.Equal(CacheItemUpdateReason.Expired, updateReason[key1]);
+ Assert.Equal(CacheItemUpdateReason.DependencyChanged, updateReason[key2]);
+ }
+
+ private static IDisposable StartHost(Cache cache) => Host.CreateDefaultBuilder()
+ .ConfigureWebHost(app =>
+ {
+ app.UseTestServer();
+ app.Configure(app => { });
+ app.ConfigureServices(services =>
+ {
+ services.AddSystemWebAdapters();
+ services.AddSingleton(cache);
+ });
+ })
+ .Start();
+}
diff --git a/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/CacheTests.cs b/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/CacheTests.cs
deleted file mode 100644
index f5dc410d40..0000000000
--- a/test/Microsoft.AspNetCore.SystemWebAdapters.CoreServices.Tests/CacheTests.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Web;
-using System.Web.Caching;
-using Microsoft.Extensions.DependencyInjection;
-using Moq;
-using Xunit;
-
-namespace Microsoft.AspNetCore.SystemWebAdapters.Tests
-{
- public class CacheTests
- {
-
- [Fact]
- public void CacheFromHttpContext()
- {
- // Arrange
- var cache = new Cache();
-
- var serviceProvider = new Mock();
- serviceProvider.Setup(s => s.GetService(typeof(Cache))).Returns(cache);
-
- var coreContext = new Mock();
- coreContext.Setup(c => c.RequestServices).Returns(serviceProvider.Object);
-
- var context = new HttpContext(coreContext.Object);
-
- // Act
- var result = context.Cache;
-
- // Assert
- Assert.Same(cache, result);
-
- //Act via GetService
- var cacheFromService = context.GetService();
- Assert.Same(cache, cacheFromService);
- }
-
- [Fact]
- public void CacheFromHttpContextWrapper()
- {
- // Arrange
- var cache = new Cache();
-
- var serviceProvider = new Mock();
- serviceProvider.Setup(s => s.GetService(typeof(Cache))).Returns(cache);
-
- var coreContext = new Mock();
- coreContext.Setup(c => c.RequestServices).Returns(serviceProvider.Object);
-
- var context = new HttpContext(coreContext.Object);
- var contextWrapper = new HttpContextWrapper(context);
-
- // Act
- var result = contextWrapper.Cache;
-
- // Assert
- Assert.Same(cache, result);
-
- //Act via GetService
- var cacheFromService = contextWrapper.GetService();
- Assert.Same(cache, cacheFromService);
- }
- }
-}
diff --git a/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/Caching/CacheTests.cs b/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/Caching/CacheTests.cs
index ef4eeb102b..d395d68781 100644
--- a/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/Caching/CacheTests.cs
+++ b/test/Microsoft.AspNetCore.SystemWebAdapters.Tests/Caching/CacheTests.cs
@@ -2,15 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections;
-using System.Collections.Generic;
using System.IO;
using System.Runtime.Caching;
using System.Threading.Tasks;
-using System.Web.Hosting;
using AutoFixture;
-using Microsoft.AspNetCore.SystemWebAdapters;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Options;
using Moq;
using Xunit;
@@ -316,154 +312,53 @@ public void InsertNoAbsoluteSlidingExpiration()
}
[Fact]
- public void InsertWithDependency()
+ public void CacheFromHttpContext()
{
// Arrange
- var memCache = new Mock(_fixture.Create(), null);
- var cache = new Cache(memCache.Object);
- var key = _fixture.Create();
- var item = new object();
- var cacheDependency = new Mock();
-
- // Act
- cache.Insert(key, item, cacheDependency.Object);
-
- // Assert
- memCache.Verify(m => m.Set(key, item, It.Is(e => e.AbsoluteExpiration.DateTime.Equals(Cache.NoAbsoluteExpiration) && e.SlidingExpiration.Equals(Cache.NoSlidingExpiration)), null), Times.Once);
- }
-
- [Fact]
- public async Task DependentFileCallback()
- {
- // Arrange
- using var memCache = new MemoryCache(_fixture.Create());
- var cache = new Cache(memCache);
- var item = new object();
- var key = _fixture.Create();
- var updated = false;
- var slidingExpiration = TimeSpan.FromMilliseconds(1);
- CacheItemUpdateReason? updateReason = default;
+ var cache = new Cache();
- var tcs = new TaskCompletionSource();
+ var serviceProvider = new Mock();
+ serviceProvider.Setup(s => s.GetService(typeof(Cache))).Returns(cache);
- void Callback(string key, CacheItemUpdateReason reason, out object? expensiveObject, out CacheDependency? dependency, out DateTime absoluteExpiration, out TimeSpan slidingExpiration)
- {
- expensiveObject = null;
- dependency = null;
- absoluteExpiration = Cache.NoAbsoluteExpiration;
- slidingExpiration = TimeSpan.FromMilliseconds(5);
+ var coreContext = new Mock();
+ coreContext.Setup(c => c.RequestServices).Returns(serviceProvider.Object);
- updated = true;
- updateReason = reason;
+ var context = new HttpContext(coreContext.Object);
- tcs.SetResult();
- }
-
- var file = Path.GetTempFileName();
- await File.WriteAllTextAsync(file, key);
-
- using var cd = new CacheDependency(file);
// Act
- cache.Insert(key, item, cd, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, Callback);
-
- // Ensure file is updated
- await File.WriteAllTextAsync(file, DateTime.UtcNow.ToString("O"));
-
- // Wait for callback to be called
- await tcs.Task;
-
- // Wait for callback to be finalized
- await Task.Delay(100);
+ var result = context.Cache;
// Assert
- Assert.True(updated);
- Assert.Null(cache[key]);
- Assert.Equal(CacheItemUpdateReason.DependencyChanged, updateReason);
+ Assert.Same(cache, result);
+
+ //Act via GetService
+ var cacheFromService = context.GetService();
+ Assert.Same(cache, cacheFromService);
}
[Fact]
- public async Task DependentItemCallback()
+ public void CacheFromHttpContextWrapper()
{
// Arrange
- using var memCache = new MemoryCache(_fixture.Create());
-
- var cache = new Cache(memCache);
+ var cache = new Cache();
- using var _ = HostingEnvironmentContext.Initialize(cache);
+ var serviceProvider = new Mock();
+ serviceProvider.Setup(s => s.GetService(typeof(Cache))).Returns(cache);
- var item1 = new object();
- var item2 = new object();
- var key1 = _fixture.Create();
- var key2 = _fixture.Create();
- var updateReason = new Dictionary();
- var slidingExpiration = TimeSpan.FromMilliseconds(1);
+ var coreContext = new Mock();
+ coreContext.Setup(c => c.RequestServices).Returns(serviceProvider.Object);
- void Callback(string key, CacheItemUpdateReason reason, out object? expensiveObject, out CacheDependency? dependency, out DateTime absoluteExpiration, out TimeSpan slidingExpiration)
- {
- expensiveObject = null;
- dependency = null;
- absoluteExpiration = Cache.NoAbsoluteExpiration;
- slidingExpiration = Cache.NoSlidingExpiration;
-
- updateReason[key] = reason;
- }
+ var context = new HttpContext(coreContext.Object);
+ var contextWrapper = new HttpContextWrapper(context);
// Act
- cache.Insert(key1, item1, null, Cache.NoAbsoluteExpiration, slidingExpiration, Callback);
-
- using var cd = new CacheDependency(null, new[] { key1 });
- cache.Insert(key2, item2, cd, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, Callback);
-
- Assert.Empty(updateReason);
-
- // Ensure sliding expiration has hit
- await Task.Delay(slidingExpiration);
-
- // Force cleanup to initiate callbacks on current thread
- memCache.Trim(100);
+ var result = contextWrapper.Cache;
// Assert
- Assert.Contains(key1, updateReason.Keys);
- Assert.Contains(key2, updateReason.Keys);
-
- Assert.Null(cache[key1]);
- Assert.Null(cache[key2]);
-
- Assert.Equal(CacheItemUpdateReason.Expired, updateReason[key1]);
- Assert.Equal(CacheItemUpdateReason.DependencyChanged, updateReason[key2]);
- }
-
- ///
- /// This will ensure we can remove the hosting environment after the test is complete since it is a static instance
- ///
- private sealed class HostingEnvironmentContext : IDisposable, IServiceProvider
- {
- private readonly Cache _cache;
-
- private HostingEnvironmentContext(Cache cache)
- {
- _cache = cache;
- HostingEnvironmentAccessor.Current = new(this, Options.Create(new SystemWebAdaptersOptions()));
- }
+ Assert.Same(cache, result);
- public void Dispose()
- {
- HostingEnvironmentAccessor.Current = null;
- }
-
- public static HostingEnvironmentContext Initialize(Cache cache)
- {
- return new HostingEnvironmentContext(cache);
- }
-
- object? IServiceProvider.GetService(Type serviceType)
- {
- if (serviceType == typeof(Cache))
- {
- return _cache;
- }
-
- return null;
- }
+ //Act via GetService
+ var cacheFromService = contextWrapper.GetService();
+ Assert.Same(cache, cacheFromService);
}
}