From 975a640345cf27081907d98bcee5e528abf9c1f0 Mon Sep 17 00:00:00 2001 From: ZLoo Date: Tue, 23 Jul 2024 10:52:51 +0300 Subject: [PATCH] Fix CA1062 warnings (#2240) Fix CA1062 warnings for `CacheSyntax`. --- src/Polly/Caching/CacheSyntax.cs | 54 +++++- test/Polly.Specs/Caching/CacheSpecs.cs | 232 ++++++++++++++++++++++++- 2 files changed, 272 insertions(+), 14 deletions(-) diff --git a/src/Polly/Caching/CacheSyntax.cs b/src/Polly/Caching/CacheSyntax.cs index 221bd288587..7babe72907f 100644 --- a/src/Polly/Caching/CacheSyntax.cs +++ b/src/Polly/Caching/CacheSyntax.cs @@ -1,7 +1,6 @@ #nullable enable namespace Polly; -#pragma warning disable CA1062 // Validate arguments of public methods public partial class Policy { /// @@ -46,8 +45,19 @@ public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy t /// The policy instance. /// Thrown when is . /// Thrown when is . - public static CachePolicy Cache(ISyncCacheProvider cacheProvider, TimeSpan ttl, ICacheKeyStrategy cacheKeyStrategy, Action? onCacheError = null) => - Cache(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheError); + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + TimeSpan ttl, + ICacheKeyStrategy cacheKeyStrategy, + Action? onCacheError = null) + { + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + + return Cache(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheError); + } /// /// Builds a that will function like a result cache for delegate executions returning a result. @@ -222,8 +232,23 @@ public static CachePolicy Cache( Action onCacheMiss, Action onCachePut, Action? onCacheGetError, - Action? onCachePutError) => - Cache(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + Action? onCachePutError) + { + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + + return Cache( + cacheProvider, + new RelativeTtl(ttl), + cacheKeyStrategy.GetCacheKey, + onCacheGet, + onCacheMiss, + onCachePut, + onCacheGetError, + onCachePutError); + } /// /// Builds a that will function like a result cache for delegate executions returning a result. @@ -254,8 +279,23 @@ public static CachePolicy Cache( Action onCacheMiss, Action onCachePut, Action? onCacheGetError, - Action? onCachePutError) => - Cache(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + Action? onCachePutError) + { + if (cacheKeyStrategy is null) + { + throw new ArgumentNullException(nameof(cacheKeyStrategy)); + } + + return Cache( + cacheProvider, + ttlStrategy, + cacheKeyStrategy.GetCacheKey, + onCacheGet, + onCacheMiss, + onCachePut, + onCacheGetError, + onCachePutError); + } /// /// Builds a that will function like a result cache for delegate executions returning a result. diff --git a/test/Polly.Specs/Caching/CacheSpecs.cs b/test/Polly.Specs/Caching/CacheSpecs.cs index 9836b24a4f7..11ce7deca32 100644 --- a/test/Polly.Specs/Caching/CacheSpecs.cs +++ b/test/Polly.Specs/Caching/CacheSpecs.cs @@ -62,8 +62,49 @@ public void Should_throw_when_action_is_null() public void Should_throw_when_cache_provider_is_null() { ISyncCacheProvider cacheProvider = null!; - Action action = () => Policy.Cache(cacheProvider, TimeSpan.MaxValue); - action.Should().Throw().And.ParamName.Should().Be("cacheProvider"); + var ttl = TimeSpan.MaxValue; + ITtlStrategy ttlStrategy = new ContextualTtl(); + ICacheKeyStrategy cacheKeyStrategy = new StubCacheKeyStrategy(context => context.OperationKey + context["id"]); + Func cacheKeyStrategyFunc = (_) => string.Empty; + Action onCache = (_, _) => { }; + Action? onCacheError = null; + const string CacheProviderExpected = "cacheProvider"; + + Action action = () => Policy.Cache(cacheProvider, ttl, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); + + action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategy, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategy, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); + + action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategyFunc, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategyFunc, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); + + action = () => Policy.Cache(cacheProvider, ttl, onCache, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, onCache, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); + + action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategy, onCache, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategy, onCache, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); + + action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategyFunc, onCache, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategyFunc, onCache, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheProviderExpected); } [Fact] @@ -71,17 +112,194 @@ public void Should_throw_when_ttl_strategy_is_null() { ISyncCacheProvider cacheProvider = new StubCacheProvider(); ITtlStrategy ttlStrategy = null!; - Action action = () => Policy.Cache(cacheProvider, ttlStrategy); - action.Should().Throw().And.ParamName.Should().Be("ttlStrategy"); + ICacheKeyStrategy cacheKeyStrategy = new StubCacheKeyStrategy(context => context.OperationKey + context["id"]); + Func cacheKeyStrategyFunc = (_) => string.Empty; + Action onCache = (_, _) => { }; + Action? onCacheError = null; + const string TtlStrategyExpected = "ttlStrategy"; + + Action action = () => Policy.Cache(cacheProvider, ttlStrategy, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(TtlStrategyExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategy, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(TtlStrategyExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategyFunc, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(TtlStrategyExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, onCache, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(TtlStrategyExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategy, onCache, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(TtlStrategyExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategyFunc, onCache, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(TtlStrategyExpected); } [Fact] public void Should_throw_when_cache_key_strategy_is_null() { ISyncCacheProvider cacheProvider = new StubCacheProvider(); - Func cacheKeyStrategy = null!; - Action action = () => Policy.Cache(cacheProvider, TimeSpan.MaxValue, cacheKeyStrategy); - action.Should().Throw().And.ParamName.Should().Be("cacheKeyStrategy"); + var ttl = TimeSpan.MaxValue; + ITtlStrategy ttlStrategy = new ContextualTtl(); + ICacheKeyStrategy cacheKeyStrategy = null!; + Func cacheKeyStrategyFunc = null!; + Action onCache = (_, _) => { }; + Action? onCacheError = null; + const string CacheKeyStrategyExpected = "cacheKeyStrategy"; + + Action action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategy, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategy, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategyFunc, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategyFunc, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.Cache( + cacheProvider, + ttl, + cacheKeyStrategy, + onCache, + onCache, + onCache, + onCacheError, + onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.Cache( + cacheProvider, + ttlStrategy, + cacheKeyStrategy, + onCache, + onCache, + onCache, + onCacheError, + onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.Cache( + cacheProvider, + ttl, + cacheKeyStrategyFunc, + onCache, + onCache, + onCache, + onCacheError, + onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + + action = () => Policy.Cache( + cacheProvider, + ttlStrategy, + cacheKeyStrategyFunc, + onCache, + onCache, + onCache, + onCacheError, + onCacheError); + action.Should().Throw().And.ParamName.Should().Be(CacheKeyStrategyExpected); + } + + [Fact] + public void Should_throw_when_on_cache_get_is_null() + { + ISyncCacheProvider cacheProvider = new StubCacheProvider(); + var ttl = TimeSpan.MaxValue; + ITtlStrategy ttlStrategy = new ContextualTtl(); + ICacheKeyStrategy cacheKeyStrategy = new StubCacheKeyStrategy(context => context.OperationKey + context["id"]); + Func cacheKeyStrategyFunc = (_) => string.Empty; + Action onCacheGet = null!; + Action onCache = (_, _) => { }; + Action? onCacheError = null; + const string OnCacheGetExpected = "onCacheGet"; + + Action action = () => Policy.Cache(cacheProvider, ttl, onCacheGet, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheGetExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, onCacheGet, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheGetExpected); + + action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategy, onCacheGet, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheGetExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategy, onCacheGet, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheGetExpected); + + action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategyFunc, onCacheGet, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheGetExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategyFunc, onCacheGet, onCache, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheGetExpected); + } + + [Fact] + public void Should_throw_when_on_cache_miss_is_null() + { + ISyncCacheProvider cacheProvider = new StubCacheProvider(); + var ttl = TimeSpan.MaxValue; + ITtlStrategy ttlStrategy = new ContextualTtl(); + ICacheKeyStrategy cacheKeyStrategy = new StubCacheKeyStrategy(context => context.OperationKey + context["id"]); + Func cacheKeyStrategyFunc = (_) => string.Empty; + Action onCacheMiss = null!; + Action onCache = (_, _) => { }; + Action? onCacheError = null; + const string OnCacheMissExpected = "onCacheMiss"; + + Action action = () => Policy.Cache(cacheProvider, ttl, onCache, onCacheMiss, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheMissExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, onCache, onCacheMiss, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheMissExpected); + + action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategy, onCache, onCacheMiss, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheMissExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategy, onCache, onCacheMiss, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheMissExpected); + + action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategyFunc, onCache, onCacheMiss, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheMissExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategyFunc, onCache, onCacheMiss, onCache, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCacheMissExpected); + } + + [Fact] + public void Should_throw_when_on_cache_put_is_null() + { + ISyncCacheProvider cacheProvider = new StubCacheProvider(); + var ttl = TimeSpan.MaxValue; + ITtlStrategy ttlStrategy = new ContextualTtl(); + ICacheKeyStrategy cacheKeyStrategy = new StubCacheKeyStrategy(context => context.OperationKey + context["id"]); + Func cacheKeyStrategyFunc = (_) => string.Empty; + Action onCachePut = null!; + Action onCache = (_, _) => { }; + Action? onCacheError = null; + const string OnCachePutExpected = "onCachePut"; + + Action action = () => Policy.Cache(cacheProvider, ttl, onCache, onCache, onCachePut, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCachePutExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, onCache, onCache, onCachePut, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCachePutExpected); + + action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategy, onCache, onCache, onCachePut, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCachePutExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategy, onCache, onCache, onCachePut, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCachePutExpected); + + action = () => Policy.Cache(cacheProvider, ttl, cacheKeyStrategyFunc, onCache, onCache, onCachePut, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCachePutExpected); + + action = () => Policy.Cache(cacheProvider, ttlStrategy, cacheKeyStrategyFunc, onCache, onCache, onCachePut, onCacheError, onCacheError); + action.Should().Throw().And.ParamName.Should().Be(OnCachePutExpected); } [Fact]