diff --git a/backend/store/etcd/silenced_store.go b/backend/store/etcd/silenced_store.go index cd3cb22a1..8c28c5fdf 100644 --- a/backend/store/etcd/silenced_store.go +++ b/backend/store/etcd/silenced_store.go @@ -211,8 +211,8 @@ func (s *Store) UpdateSilencedEntry(ctx context.Context, silenced *corev2.Silenc // check for maximum allowed duration for silenced allowed if silenced.ExpireAt > 0 && (silenced.ExpireAt > allowedMaxTime) { - err := errors.New("silenced crossed maximum duration configured") - return &store.ErrNotValid{Err: err} + err := errors.New("silenced crossed maximum duration allowed") + return &store.ErrThreshold{Err: err} } if silenced.ExpireAt == 0 && silenced.Expire > 0 { diff --git a/backend/store/etcd/silenced_store_test.go b/backend/store/etcd/silenced_store_test.go index 2fd687b0b..c47b9a27e 100644 --- a/backend/store/etcd/silenced_store_test.go +++ b/backend/store/etcd/silenced_store_test.go @@ -67,8 +67,9 @@ func TestSilencedStorage(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, entry) assert.Equal(t, "subscription:*", entry.Name) - // Entries without expirations should return -1 - assert.Equal(t, int64(-1), entry.Expire) + + // check entries without -1 expiry + assert.NotEqual(t, int64(-1), entry.Expire) // Delete silenced entry by name err = store.DeleteSilencedEntryByName(ctx, silenced.Name) @@ -76,6 +77,7 @@ func TestSilencedStorage(t *testing.T) { // Update a silenced entry's expire time silenced.Expire = 2 + silenced.ExpireAt = 0 err = store.UpdateSilencedEntry(ctx, silenced) assert.NoError(t, err) @@ -100,6 +102,7 @@ func TestSilencedStorageWithExpire(t *testing.T) { silenced := types.FixtureSilenced("subscription:checkname") silenced.Namespace = "default" silenced.Expire = 15 + silenced.ExpireAt = 0 ctx := context.WithValue(context.Background(), types.NamespaceKey, silenced.Namespace) err := store.UpdateSilencedEntry(ctx, silenced) @@ -120,9 +123,9 @@ func TestSilencedStorageWithBegin(t *testing.T) { silenced := types.FixtureSilenced("subscription:checkname") silenced.Namespace = "default" // set a begin time in the future - silenced.Begin = time.Date(1970, 01, 01, 01, 00, 00, 00, time.UTC).Unix() + silenced.Begin = time.Now().Add(time.Duration(1) * time.Second).Unix() // current time is before the start time - currentTime := time.Date(1970, 01, 01, 00, 00, 00, 00, time.UTC).Unix() + currentTime := time.Now().Unix() ctx := context.WithValue(context.Background(), types.NamespaceKey, silenced.Namespace) err := store.UpdateSilencedEntry(ctx, silenced) @@ -137,8 +140,11 @@ func TestSilencedStorageWithBegin(t *testing.T) { require.NotNil(t, entry) assert.False(t, entry.Begin < currentTime) + // Wait for begin time to elapse current time. i.e let silencing begin + time.Sleep(3 * time.Second) + // reset current time to be ahead of begin time - currentTime = time.Date(1970, 01, 01, 02, 00, 00, 00, time.UTC).Unix() + currentTime = time.Now().Unix() assert.True(t, entry.Begin < currentTime) }) } @@ -168,3 +174,26 @@ func TestSilencedStorageWithBeginAndExpire(t *testing.T) { assert.Equal(t, entry.Expire, int64(15)) }) } + +func TestSilencedStorageWithMaxAllowedThresholdExpiry(t *testing.T) { + testWithEtcd(t, func(store store.Store) { + silenced := types.FixtureSilenced("subscription:checkname") + silenced.Namespace = "default" + silenced.ExpireAt = time.Now().Add(time.Duration(30000) * time.Second).Unix() + // set a begin time + silenced.Begin = time.Now().Unix() + ctx := context.WithValue(context.Background(), types.NamespaceKey, silenced.Namespace) + + err := store.UpdateSilencedEntry(ctx, silenced) + + // assert that error is thrown for breaching max expiry time allowed + assert.Error(t, err) + + entry, err := store.GetSilencedEntryByName(ctx, silenced.Name) + + // assert that entry is nil + assert.NoError(t, err) + assert.Nil(t, entry) + + }) +} diff --git a/backend/store/etcd/store_test.go b/backend/store/etcd/store_test.go index 58b729c0f..615a2e6c3 100644 --- a/backend/store/etcd/store_test.go +++ b/backend/store/etcd/store_test.go @@ -7,8 +7,6 @@ import ( "context" "encoding/json" "fmt" - "testing" - "github.com/gogo/protobuf/proto" corev2 "github.com/sensu/core/v2" "github.com/sensu/sensu-go/backend/etcd" @@ -18,6 +16,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.etcd.io/etcd/client/v3" + "testing" + "time" ) func testWithEtcd(t *testing.T, f func(store.Store)) { @@ -28,6 +28,9 @@ func testWithEtcd(t *testing.T, f func(store.Store)) { s := NewStore(client, e.Name()) + s.cfg.MaxSilencedExpiryTimeAllowed = time.Duration(3000 * time.Second) + s.cfg.DefaultSilencedExpiryTime = time.Duration(3000 * time.Second) + // Mock a default namespace require.NoError(t, s.CreateNamespace(context.Background(), types.FixtureNamespace("default"))) @@ -42,6 +45,9 @@ func testWithEtcdStore(t *testing.T, f func(*Store)) { s := NewStore(client, e.Name()) + s.cfg.MaxSilencedExpiryTimeAllowed = time.Duration(3000 * time.Second) + s.cfg.DefaultSilencedExpiryTime = time.Duration(3000 * time.Second) + // Mock a default namespace require.NoError(t, s.CreateNamespace(context.Background(), types.FixtureNamespace("default"))) @@ -56,6 +62,9 @@ func testWithEtcdClient(t *testing.T, f func(store.Store, *clientv3.Client)) { s := NewStore(client, e.Name()) + s.cfg.MaxSilencedExpiryTimeAllowed = time.Duration(3000 * time.Second) + s.cfg.DefaultSilencedExpiryTime = time.Duration(3000 * time.Second) + // Mock a default namespace require.NoError(t, s.CreateNamespace(context.Background(), types.FixtureNamespace("default"))) diff --git a/backend/store/store.go b/backend/store/store.go index 8953242c8..e845c29be 100644 --- a/backend/store/store.go +++ b/backend/store/store.go @@ -65,6 +65,14 @@ type ErrNotValid struct { Err error } +type ErrThreshold struct { + Err error +} + +func (e *ErrThreshold) Error() string { + return fmt.Sprintf("Threshold reached: %s", e.Err.Error()) +} + func (e *ErrNotValid) Error() string { return fmt.Sprintf("resource is invalid: %s", e.Err.Error()) }