Files
grafana/pkg/util/testutil/context_test.go
Denis Vodopianov ce9ab6a89a Add non-boolean feature flags support to the StaticProvider (#115085)
* initial commit

* add support of integerts

* finialise the static provider

* minor refactoring

* the rest

* revert:  the rest

* add new thiongs

* more tests added

* add ff parsing tests to check if types are handled correctly

* update tests according to recent changes

* address golint issues

* Update pkg/setting/setting_feature_toggles.go

Co-authored-by: Dave Henderson <dave.henderson@grafana.com>

* fix rebase issues

* addressing review comments

* add test cases for enterprise

* handle enterprise cases

* minor refactoring to make api a bit easier to debug

* make test names a bit more precise

* fix linter

* add openfeature sdk to goleak ignore in testutil

* Remove only boolean check in ff gen tests

* add non-boolean types top the doc in default.ini and doc string in FeatureFlag type

* apply remarks, add docs to sample.ini

* reflect changes in feature flags in the public grafana configuration doc

* fix doc formatting

* apply suggestions to the doc file

---------

Co-authored-by: Dave Henderson <dave.henderson@grafana.com>
2026-01-12 22:53:23 +01:00

94 lines
2.4 KiB
Go

package testutil
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"
"github.com/grafana/grafana/pkg/util/testutil/mocks"
)
func TestMain(m *testing.M) {
// make sure we don't leak goroutines after tests in this package have
// finished, which means we haven't leaked contexts either
// (Except for goroutines running specific functions. If possible we should fix this.)
goleak.VerifyTestMain(m,
goleak.IgnoreTopFunction("github.com/open-feature/go-sdk/openfeature.(*eventExecutor).startEventListener.func1.1"),
)
}
func TestTestContextFunc(t *testing.T) {
t.Parallel()
const tolerance = 100 * time.Millisecond
t.Run("no explicit deadline - no test deadline", func(t *testing.T) {
t.Parallel()
tt := mocks.NewT(t)
tt.EXPECT().Helper()
tt.EXPECT().Deadline().Return(time.Time{}, false).Once()
tt.EXPECT().Cleanup(mock.Anything).Once()
ctx := NewDefaultTestContext(tt)
d, ok := ctx.Deadline()
require.True(t, ok)
require.False(t, d.IsZero())
diff := time.Now().Add(DefaultContextTimeout).Sub(d)
require.GreaterOrEqual(t, diff, time.Duration(0))
require.Less(t, diff, tolerance)
ctx.Cancel()
require.ErrorIs(t, ctx.Err(), context.Canceled)
// already canceled, we shouldn't be able to set a cause now
ctx.CancelCause(context.DeadlineExceeded)
require.ErrorIs(t, context.Cause(ctx), context.Canceled)
select {
case <-ctx.Done():
default:
t.Fatalf("done channel not closed")
}
})
t.Run("explicit deadline - earlier test deadline", func(t *testing.T) {
t.Parallel()
// make sure the context will be deadlined already at creation
now := time.Now().Add(-time.Second)
tt := mocks.NewT(t)
tt.EXPECT().Helper()
tt.EXPECT().Deadline().Return(now, true).Once()
tt.EXPECT().Cleanup(mock.Anything).Once()
ctx := NewTestContext(tt, now.Add(time.Second))
d, ok := ctx.Deadline()
require.True(t, ok)
require.Equal(t, now, d)
require.ErrorIs(t, ctx.Err(), context.DeadlineExceeded)
})
t.Run("explicit deadline - later test deadline", func(t *testing.T) {
t.Parallel()
now := time.Now().Add(-time.Second)
tt := mocks.NewT(t)
tt.EXPECT().Helper()
tt.EXPECT().Deadline().Return(now.Add(time.Hour), true).Once()
tt.EXPECT().Cleanup(mock.Anything).Once()
ctx := NewTestContext(tt, now)
d, ok := ctx.Deadline()
require.True(t, ok)
require.Equal(t, now, d)
require.ErrorIs(t, ctx.Err(), context.DeadlineExceeded)
})
}