1// Copyright 2018 Prometheus Team 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14package store 15 16import ( 17 "context" 18 "testing" 19 "time" 20 21 "github.com/prometheus/alertmanager/types" 22 "github.com/prometheus/common/model" 23 "github.com/stretchr/testify/require" 24) 25 26func TestSetGet(t *testing.T) { 27 a := NewAlerts() 28 alert := &types.Alert{ 29 UpdatedAt: time.Now(), 30 } 31 require.NoError(t, a.Set(alert)) 32 want := alert.Fingerprint() 33 got, err := a.Get(want) 34 35 require.NoError(t, err) 36 require.Equal(t, want, got.Fingerprint()) 37} 38 39func TestDelete(t *testing.T) { 40 a := NewAlerts() 41 alert := &types.Alert{ 42 UpdatedAt: time.Now(), 43 } 44 require.NoError(t, a.Set(alert)) 45 46 fp := alert.Fingerprint() 47 48 err := a.Delete(fp) 49 require.NoError(t, err) 50 51 got, err := a.Get(fp) 52 require.Nil(t, got) 53 require.Equal(t, ErrNotFound, err) 54} 55 56func TestGC(t *testing.T) { 57 now := time.Now() 58 newAlert := func(key string, start, end time.Duration) *types.Alert { 59 return &types.Alert{ 60 Alert: model.Alert{ 61 Labels: model.LabelSet{model.LabelName(key): "b"}, 62 StartsAt: now.Add(start * time.Minute), 63 EndsAt: now.Add(end * time.Minute), 64 }, 65 } 66 } 67 active := []*types.Alert{ 68 newAlert("b", 10, 20), 69 newAlert("c", -10, 10), 70 } 71 resolved := []*types.Alert{ 72 newAlert("a", -10, -5), 73 newAlert("d", -10, -1), 74 } 75 s := NewAlerts() 76 var ( 77 n int 78 done = make(chan struct{}) 79 ctx, cancel = context.WithCancel(context.Background()) 80 ) 81 s.SetGCCallback(func(a []*types.Alert) { 82 n += len(a) 83 if n >= len(resolved) { 84 cancel() 85 } 86 }) 87 for _, alert := range append(active, resolved...) { 88 require.NoError(t, s.Set(alert)) 89 } 90 go func() { 91 s.Run(ctx, 10*time.Millisecond) 92 close(done) 93 }() 94 select { 95 case <-done: 96 break 97 case <-time.After(1 * time.Second): 98 t.Fatal("garbage collection didn't complete in time") 99 } 100 101 for _, alert := range active { 102 if _, err := s.Get(alert.Fingerprint()); err != nil { 103 t.Errorf("alert %v should not have been gc'd", alert) 104 } 105 } 106 for _, alert := range resolved { 107 if _, err := s.Get(alert.Fingerprint()); err == nil { 108 t.Errorf("alert %v should have been gc'd", alert) 109 } 110 } 111 require.Equal(t, len(resolved), n) 112} 113