Skip to content

Commit fbfe33c

Browse files
authored
feat: Implement cache lookup value in emulator (#64)
1 parent 61cee0a commit fbfe33c

File tree

6 files changed

+236
-1
lines changed

6 files changed

+236
-1
lines changed

src/Testing/Document/MockCacheLookupValueProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,7 @@ internal Setup(
3535

3636
public void WithCallback(Action<GatewayContext, CacheLookupValueConfig> callback) =>
3737
_handler.CallbackSetup.Add((_predicate, callback).ToTuple());
38+
39+
public void WithValue(object value) => _handler.ValueSetup.Add((_predicate, value).ToTuple());
3840
}
3941
}

src/Testing/Document/TestDocumentExtensions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@ public static MockPoliciesProvider<IOnErrorContext> SetupOnError(this TestDocume
2222

2323
public static CertificateStore SetupCertificateStore(this TestDocument document) =>
2424
document.Context.CertificateStore;
25+
26+
public static CacheStore SetupCacheStore(this TestDocument document) =>
27+
document.Context.CacheStore;
2528
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
namespace Azure.ApiManagement.PolicyToolkit.Testing.Emulator.Data;
5+
6+
public class CacheStore
7+
{
8+
private readonly Dictionary<string, object> _internalCache = new();
9+
private readonly Dictionary<string, object> _externalCache = new();
10+
11+
private bool _isExternalCacheSetup = false;
12+
13+
internal Dictionary<string, object>? GetCache(string type) =>
14+
type switch
15+
{
16+
"internal" => _internalCache,
17+
"external" => _isExternalCacheSetup ? _externalCache : null,
18+
"prefer-external" => _isExternalCacheSetup ? _externalCache : _internalCache,
19+
_ => throw new ArgumentException($"Unrecognized type {type}", nameof(type)),
20+
};
21+
22+
public IReadOnlyDictionary<string, object> InternalCache => _internalCache;
23+
public IReadOnlyDictionary<string, object> ExternalCache => _externalCache;
24+
25+
public CacheStore WithExternalCacheSetup(bool isSetup = true)
26+
{
27+
_isExternalCacheSetup = isSetup;
28+
return this;
29+
}
30+
31+
public CacheStore WithExternalCacheValue(string key, object value)
32+
{
33+
_externalCache.Add(key, value);
34+
return this;
35+
}
36+
37+
public CacheStore WithInternalCacheValue(string key, object value)
38+
{
39+
_internalCache.Add(key, value);
40+
return this;
41+
}
42+
}

src/Testing/Emulator/Policies/CacheLookupValueHandler.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,40 @@ namespace Azure.ApiManagement.PolicyToolkit.Testing.Emulator.Policies;
1313
]
1414
internal class CacheLookupValueHandler : PolicyHandler<CacheLookupValueConfig>
1515
{
16+
public List<Tuple<
17+
Func<GatewayContext, CacheLookupValueConfig, bool>,
18+
object
19+
>> ValueSetup { get; } = new();
20+
1621
public override string PolicyName => nameof(IInboundContext.CacheLookupValue);
1722

1823
protected override void Handle(GatewayContext context, CacheLookupValueConfig config)
1924
{
20-
throw new NotImplementedException();
25+
var fromSetup = ValueSetup.Find(tuple => tuple.Item1(context, config))?.Item2;
26+
if (fromSetup is not null)
27+
{
28+
context.Variables[config.VariableName] = fromSetup;
29+
return;
30+
}
31+
32+
var cachingType = config.CachingType ?? "prefer-external";
33+
34+
35+
var store = context.CacheStore.GetCache(cachingType);
36+
if (store is null)
37+
{
38+
return;
39+
}
40+
41+
if (store.TryGetValue(config.Key, out var value))
42+
{
43+
context.Variables[config.VariableName] = value;
44+
return;
45+
}
46+
47+
if (config.DefaultValue is not null)
48+
{
49+
context.Variables[config.VariableName] = config.DefaultValue;
50+
}
2151
}
2252
}

src/Testing/GatewayContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class GatewayContext : MockExpressionContext
1515
internal readonly SectionContextProxy<IOutboundContext> OutboundProxy;
1616
internal readonly SectionContextProxy<IOnErrorContext> OnErrorProxy;
1717
internal readonly CertificateStore CertificateStore = new();
18+
internal readonly CacheStore CacheStore = new();
1819

1920
public GatewayContext()
2021
{
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using Azure.ApiManagement.PolicyToolkit.Authoring;
5+
using Azure.ApiManagement.PolicyToolkit.Testing;
6+
using Azure.ApiManagement.PolicyToolkit.Testing.Document;
7+
8+
namespace Test.Emulator.Emulator.Policies;
9+
10+
[TestClass]
11+
public class CacheLookupValueTests
12+
{
13+
class SimpleCacheLookupValuePreferExternal : IDocument
14+
{
15+
public void Inbound(IInboundContext context)
16+
{
17+
context.CacheLookupValue(new CacheLookupValueConfig()
18+
{
19+
Key = "key", VariableName = "variable", CachingType = "prefer-external"
20+
});
21+
}
22+
}
23+
24+
class SimpleCacheLookupValueFromInternal : IDocument
25+
{
26+
public void Inbound(IInboundContext context)
27+
{
28+
context.CacheLookupValue(new CacheLookupValueConfig()
29+
{
30+
Key = "key", VariableName = "variable", CachingType = "internal"
31+
});
32+
}
33+
}
34+
35+
class SimpleCacheLookupValueFromExternal : IDocument
36+
{
37+
public void Inbound(IInboundContext context)
38+
{
39+
context.CacheLookupValue(new CacheLookupValueConfig()
40+
{
41+
Key = "key", VariableName = "variable", CachingType = "external"
42+
});
43+
}
44+
}
45+
46+
class SimpleCacheLookupValueWithDefaultValue : IDocument
47+
{
48+
public void Inbound(IInboundContext context)
49+
{
50+
context.CacheLookupValue(new CacheLookupValueConfig()
51+
{
52+
Key = "key", VariableName = "variable", DefaultValue = "test-value"
53+
});
54+
}
55+
}
56+
57+
[TestMethod]
58+
public void CacheLookupValue_Callback()
59+
{
60+
var test = new SimpleCacheLookupValuePreferExternal().AsTestDocument();
61+
var executedCallback = false;
62+
test.SetupInbound().CacheLookupValue().WithCallback((_, _) =>
63+
{
64+
executedCallback = true;
65+
});
66+
67+
test.RunInbound();
68+
69+
executedCallback.Should().BeTrue();
70+
}
71+
72+
[TestMethod]
73+
public void CacheLookupValue_WithValueCallback()
74+
{
75+
var test = new SimpleCacheLookupValuePreferExternal().AsTestDocument();
76+
test.SetupInbound().CacheLookupValue().WithValue("test");
77+
78+
test.RunInbound();
79+
80+
test.Context.Variables.Should().ContainKey("variable").WhoseValue.Should().Be("test");
81+
}
82+
83+
[TestMethod]
84+
public void CacheLookupValue_PreferExternal_SetupCacheStore_WithInternalValue()
85+
{
86+
var test = new SimpleCacheLookupValuePreferExternal().AsTestDocument();
87+
test.SetupCacheStore().WithInternalCacheValue("key", "test");
88+
89+
test.RunInbound();
90+
91+
test.Context.Variables.Should().ContainKey("variable").WhoseValue.Should().Be("test");
92+
}
93+
94+
[TestMethod]
95+
public void CacheLookupValue_PreferExternal_SetupCacheStore_WithExternalCacheSetup()
96+
{
97+
var test = new SimpleCacheLookupValuePreferExternal().AsTestDocument();
98+
test.SetupCacheStore().WithExternalCacheSetup().WithExternalCacheValue("key", "test");
99+
100+
test.RunInbound();
101+
102+
test.Context.Variables.Should().ContainKey("variable").WhoseValue.Should().Be("test");
103+
}
104+
105+
[TestMethod]
106+
public void CacheLookupValue_WithDefaultValue()
107+
{
108+
var test = new SimpleCacheLookupValueWithDefaultValue().AsTestDocument();
109+
110+
test.RunInbound();
111+
112+
test.Context.Variables.Should().ContainKey("variable").WhoseValue.Should().Be("test-value");
113+
}
114+
115+
[TestMethod]
116+
public void CacheLookupValue_InternalCache_WillNotFindValueFromExternalCache()
117+
{
118+
var test = new SimpleCacheLookupValueFromInternal().AsTestDocument();
119+
test.SetupCacheStore().WithExternalCacheSetup().WithExternalCacheValue("key", "test");
120+
121+
test.RunInbound();
122+
123+
test.Context.Variables.Should().NotContainKey("variable");
124+
}
125+
126+
[TestMethod]
127+
public void CacheLookupValue_Internal_WillNotFindValueInInternalCache()
128+
{
129+
var test = new SimpleCacheLookupValueFromInternal().AsTestDocument();
130+
131+
test.RunInbound();
132+
133+
test.Context.Variables.Should().NotContainKey("variable");
134+
}
135+
136+
[TestMethod]
137+
public void CacheLookupValue_ExternalCache_WillNotFindValueInInternalCache()
138+
{
139+
var test = new SimpleCacheLookupValueFromExternal().AsTestDocument();
140+
test.SetupCacheStore().WithInternalCacheValue("key", "test");
141+
142+
test.RunInbound();
143+
144+
test.Context.Variables.Should().NotContainKey("variable");
145+
}
146+
147+
[TestMethod]
148+
public void CacheLookupValue_ExternalCache_WillNotFindValue_WhenExternalCacheNotSetup()
149+
{
150+
var test = new SimpleCacheLookupValueFromExternal().AsTestDocument();
151+
test.SetupCacheStore().WithExternalCacheValue("key", "test");
152+
153+
test.RunInbound();
154+
155+
test.Context.Variables.Should().NotContainKey("variable");
156+
}
157+
}

0 commit comments

Comments
 (0)