Skip to content

Commit 2b513d1

Browse files
committed
wip
1 parent 14d856a commit 2b513d1

File tree

6 files changed

+148
-26
lines changed

6 files changed

+148
-26
lines changed

src/Testing/Document/MockCacheLookupProvider.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public static Setup CacheLookup(
2121

2222
public class Setup
2323
{
24-
private readonly Func<GatewayContext, CacheLookupConfig, bool> _predicate;
2524
private readonly CacheLookupHandler _handler;
25+
private readonly Func<GatewayContext, CacheLookupConfig, bool> _predicate;
2626

2727
internal Setup(
2828
Func<GatewayContext, CacheLookupConfig, bool> predicate,
@@ -34,5 +34,15 @@ internal Setup(
3434

3535
public void WithCallback(Action<GatewayContext, CacheLookupConfig> callback) =>
3636
_handler.CallbackSetup.Add((_predicate, callback).ToTuple());
37+
38+
public void WithCacheKey(Func<GatewayContext, CacheLookupConfig, string> callback)
39+
{
40+
_handler.CacheKeyProvider.Add((_predicate, callback).ToTuple());
41+
}
42+
43+
public void WithCacheKey(string key)
44+
{
45+
WithCacheKey((_, _) => key);
46+
}
3747
}
3848
}

src/Testing/Emulator/Data/CacheInfo.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
using System.Text;
22

3-
using Azure.ApiManagement.PolicyToolkit.Authoring;
3+
using Microsoft.Azure.ApiManagement.PolicyToolkit.Authoring;
44

5-
namespace Azure.ApiManagement.PolicyToolkit.Testing.Emulator.Data;
5+
namespace Microsoft.Azure.ApiManagement.PolicyToolkit.Testing.Emulator.Data;
66

77
public class CacheInfo
88
{
9+
internal bool AllowPrivateResponseCaching;
910
internal bool CacheSetup = false;
10-
11-
internal bool VaryByDeveloper = false;
12-
internal bool VaryByDeveloperGroups = false;
1311
internal string CachingType = "prefer-external";
1412
internal string DownstreamCachingType = "none";
1513
internal bool MustRevalidate = true;
16-
internal bool AllowPrivateResponseCaching = false;
14+
internal bool ShouldBeCached = false;
15+
16+
internal bool VaryByDeveloper = false;
17+
internal bool VaryByDeveloperGroups = false;
1718
internal string[]? VaryByHeaders;
1819
internal string[]? VaryByQueryParameters;
1920

@@ -23,7 +24,7 @@ public CacheInfo WithExecutedCacheLookup(bool isSetup = true)
2324
return this;
2425
}
2526

26-
internal CacheInfo WithExecutedCacheLookup(CacheLookupConfig config)
27+
public CacheInfo WithExecutedCacheLookup(CacheLookupConfig config)
2728
{
2829
CacheSetup = true;
2930
VaryByDeveloper = config.VaryByDeveloper;

src/Testing/Emulator/Policies/CacheLookupHandler.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,50 @@
22
// Licensed under the MIT License.
33

44
using Microsoft.Azure.ApiManagement.PolicyToolkit.Authoring;
5+
using Microsoft.Azure.ApiManagement.PolicyToolkit.Testing.Emulator.Data;
6+
using Microsoft.Azure.ApiManagement.PolicyToolkit.Testing.Expressions;
57

68
namespace Microsoft.Azure.ApiManagement.PolicyToolkit.Testing.Emulator.Policies;
79

810
[Section(nameof(IInboundContext))]
911
internal class CacheLookupHandler : PolicyHandler<CacheLookupConfig>
1012
{
13+
public List<Tuple<
14+
Func<GatewayContext, CacheLookupConfig, bool>,
15+
Func<GatewayContext, CacheLookupConfig, string>
16+
>> CacheKeyProvider { get; } = new();
17+
1118
public override string PolicyName => nameof(IInboundContext.CacheLookup);
1219

1320
protected override void Handle(GatewayContext context, CacheLookupConfig config)
1421
{
15-
throw new NotImplementedException();
22+
if (context.CacheInfo.CacheSetup)
23+
{
24+
return;
25+
}
26+
27+
Dictionary<string, CacheValue>? store = context.CacheStore.GetCache(context.CacheInfo.CachingType);
28+
if (store is null)
29+
{
30+
return;
31+
}
32+
33+
context.CacheInfo.WithExecutedCacheLookup(config);
34+
35+
string key = CacheKeyProvider.Find(hook => hook.Item1(context, config))
36+
?.Item2(context, config)
37+
?? CacheInfo.CacheKey(context);
38+
if (!store.TryGetValue(key, out CacheValue? cacheHit))
39+
{
40+
return;
41+
}
42+
43+
if (cacheHit.Value is not MockResponse cachedResponse)
44+
{
45+
return;
46+
}
47+
48+
context.Response = cachedResponse.Clone();
49+
throw new FinishSectionProcessingException();
1650
}
1751
}

src/Testing/Emulator/Policies/CacheStoreHandler.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,23 @@ private void Handle(GatewayContext context, uint duration, bool cacheResponse)
4545
return;
4646
}
4747

48+
if (!context.Request.Method.Equals("GET", StringComparison.InvariantCultureIgnoreCase))
49+
{
50+
return;
51+
}
52+
4853
var store = context.CacheStore.GetCache(context.CacheInfo.CachingType);
4954
if (store is null)
5055
{
5156
return;
5257
}
5358

54-
if (context.Response.StatusCode != 200 && !cacheResponse)
59+
if (!cacheResponse || context.Response.StatusCode != 200)
60+
{
61+
return;
62+
}
63+
64+
if (context.Response.Headers.ContainsKey("Authorization") && !context.CacheInfo.AllowPrivateResponseCaching)
5565
{
5666
return;
5767
}
@@ -62,6 +72,7 @@ private void Handle(GatewayContext context, uint duration, bool cacheResponse)
6272
?.Item2(context, duration, cacheResponse)
6373
?? CacheInfo.CacheKey(context);
6474

75+
6576
store[key] = new CacheValue(cacheValue) { Duration = duration };
6677
}
6778

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Azure.ApiManagement.PolicyToolkit.Authoring;
2+
3+
namespace Test.Emulator.Emulator.Policies;
4+
5+
[TestClass]
6+
public class CacheLookupTests
7+
{
8+
private class SimpleCacheLookup : IDocument
9+
{
10+
public void Inbound(IInboundContext context)
11+
{
12+
context.CacheLookup(new CacheLookupConfig { VaryByDeveloper = false, VaryByDeveloperGroups = false });
13+
}
14+
}
15+
16+
private class SimpleCacheLookup1 : IDocument
17+
{
18+
public void Outbound(IOutboundContext context)
19+
{
20+
context.CacheStore(10, true);
21+
}
22+
}
23+
}

test/Test.Testing/Emulator/Policies/CacheStoreTests.cs

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,13 @@
55
using Azure.ApiManagement.PolicyToolkit.Authoring.Expressions;
66
using Azure.ApiManagement.PolicyToolkit.Testing;
77
using Azure.ApiManagement.PolicyToolkit.Testing.Document;
8+
using Azure.ApiManagement.PolicyToolkit.Testing.Emulator.Data;
89

910
namespace Test.Emulator.Emulator.Policies;
1011

1112
[TestClass]
1213
public class CacheStoreTests
1314
{
14-
class SimpleCacheStore : IDocument
15-
{
16-
public void Outbound(IOutboundContext context)
17-
{
18-
context.CacheStore(10);
19-
}
20-
}
21-
22-
class SimpleCacheStoreStoreResponse : IDocument
23-
{
24-
public void Outbound(IOutboundContext context)
25-
{
26-
context.CacheStore(10, true);
27-
}
28-
}
29-
3015
[TestMethod]
3116
public void CacheStore_Callback()
3217
{
@@ -42,6 +27,18 @@ public void CacheStore_Callback()
4227
executedCallback.Should().BeTrue();
4328
}
4429

30+
[TestMethod]
31+
public void CacheStore_NotStoreWhenLookupWasNotExecuted()
32+
{
33+
TestDocument test = new SimpleCacheStore().AsTestDocument();
34+
CacheStore cache = test.SetupCacheStore();
35+
test.SetupOutbound().CacheStore().WithCacheKey("key");
36+
37+
test.RunOutbound();
38+
39+
cache.InternalCache.Should().NotContainKey("key");
40+
}
41+
4542
[TestMethod]
4643
public void CacheStore_StoreResponseInCache()
4744
{
@@ -62,6 +59,23 @@ public void CacheStore_StoreResponseInCache()
6259
response.Headers.Should().Equal(contextResponse.Headers);
6360
}
6461

62+
[TestMethod]
63+
public void CacheStore_StoreResponseInCache_WhenExternal()
64+
{
65+
TestDocument test = new SimpleCacheStore().AsTestDocument();
66+
CacheStore cache = test.SetupCacheStore();
67+
test.SetupCacheStore().WithExternalCacheSetup();
68+
test.SetupCacheInfo().WithExecutedCacheLookup();
69+
test.SetupOutbound().CacheStore().WithCacheKey("key");
70+
71+
test.RunOutbound();
72+
73+
CacheValue? cacheValue = cache.ExternalCache.Should().ContainKey("key").WhoseValue;
74+
cacheValue.Duration.Should().Be(10);
75+
cacheValue.Value.Should().BeAssignableTo<IResponse>()
76+
.And.NotBeSameAs(test.Context.Response, "Should be a copy of response");
77+
}
78+
6579
[TestMethod]
6680
public void CacheStore_NotStoreIfResponseIsNot200()
6781
{
@@ -98,4 +112,33 @@ public void CacheStore_StoreIfResponseIsNot200_WhenCacheResponseIsSetToTrue()
98112
response.StatusReason.Should().Be(contextResponse.StatusReason);
99113
response.Headers.Should().Equal(contextResponse.Headers);
100114
}
115+
116+
[TestMethod]
117+
public void CacheStore_()
118+
{
119+
TestDocument test = new SimpleCacheStore().AsTestDocument();
120+
test.SetupCacheInfo().WithExecutedCacheLookup(new CacheLookupConfig
121+
{
122+
VaryByDeveloper = true,
123+
VaryByDeveloperGroups = true,
124+
CachingType = "internal",
125+
AllowPrivateResponseCaching =
126+
});
127+
}
128+
129+
private class SimpleCacheStore : IDocument
130+
{
131+
public void Outbound(IOutboundContext context)
132+
{
133+
context.CacheStore(10);
134+
}
135+
}
136+
137+
private class SimpleCacheStoreStoreResponse : IDocument
138+
{
139+
public void Outbound(IOutboundContext context)
140+
{
141+
context.CacheStore(10, true);
142+
}
143+
}
101144
}

0 commit comments

Comments
 (0)