From a714c3e2e0330b39e516e48831f5f91e6cbbbe59 Mon Sep 17 00:00:00 2001 From: Bernd Warmuth Date: Fri, 29 Nov 2024 09:59:28 +0100 Subject: [PATCH] fix: consider noop operator for in short circuit logic Signed-off-by: Bernd Warmuth --- openfeature/client.go | 20 +++++++++++--------- openfeature/client_test.go | 21 +++++++++++++++++++-- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/openfeature/client.go b/openfeature/client.go index ea64f05..84338ff 100644 --- a/openfeature/client.go +++ b/openfeature/client.go @@ -713,16 +713,18 @@ func (c *Client) evaluate( c.finallyHooks(ctx, hookCtx, providerInvocationClientApiHooks, options) }() - // short circuit if provider is in NOT READY state - if c.State() == NotReadyState { - c.errorHooks(ctx, hookCtx, providerInvocationClientApiHooks, ProviderNotReadyError, options) - return evalDetails, ProviderNotReadyError - } + if _, ok := provider.(NoopProvider); !ok { + // short circuit if provider is in NOT READY state + if c.State() == NotReadyState { + c.errorHooks(ctx, hookCtx, providerInvocationClientApiHooks, ProviderNotReadyError, options) + return evalDetails, ProviderNotReadyError + } - // short circuit if provider is in FATAL state - if c.State() == FatalState { - c.errorHooks(ctx, hookCtx, providerInvocationClientApiHooks, ProviderFatalError, options) - return evalDetails, ProviderFatalError + // short circuit if provider is in FATAL state + if c.State() == FatalState { + c.errorHooks(ctx, hookCtx, providerInvocationClientApiHooks, ProviderFatalError, options) + return evalDetails, ProviderFatalError + } } evalCtx, err = c.beforeHooks(ctx, hookCtx, apiClientInvocationProviderHooks, evalCtx, options) diff --git a/openfeature/client_test.go b/openfeature/client_test.go index ac257dd..03ed710 100644 --- a/openfeature/client_test.go +++ b/openfeature/client_test.go @@ -3,6 +3,7 @@ package openfeature import ( "context" "errors" + "math" "reflect" "testing" "time" @@ -1385,7 +1386,24 @@ func TestRequirement_1_7_6(t *testing.T) { mockHook.EXPECT().Error(gomock.Any(), gomock.Any(), ProviderNotReadyError, gomock.Any()) mockHook.EXPECT().Finally(gomock.Any(), gomock.Any(), gomock.Any()) - client := GetApiInstance().GetNamedClient(t.Name()) + notReadyEventingProvider := struct { + FeatureProvider + StateHandler + EventHandler + }{ + NoopProvider{}, + &stateHandlerForTests{ + initF: func(e EvaluationContext) error { + <-time.After(math.MaxInt) + return nil + }, + }, + &ProviderEventing{}, + } + + GetApiInstance().SetProvider(notReadyEventingProvider) + + client := GetApiInstance().GetNamedClient("somOtherClient") client.AddHooks(mockHook) if client.State() != NotReadyState { @@ -1401,7 +1419,6 @@ func TestRequirement_1_7_6(t *testing.T) { if res != defaultVal { t.Fatalf("expected resolved boolean value to default to %t, got %t", defaultVal, res) } - } // The client MUST default, run error hooks, and indicate an error if flag resolution is attempted while the provider