@@ -2,6 +2,7 @@ package annotationsimpl
22
33import (
44 "context"
5+ "errors"
56 "testing"
67 "time"
78
@@ -14,31 +15,30 @@ import (
1415 "github.com/grafana/grafana/pkg/setting"
1516)
1617
17- func TestAnnotationCleanUp (t * testing.T ) {
18- fakeSQL := db .InitTestDB (t )
19-
20- t .Cleanup (func () {
21- err := fakeSQL .WithDbSession (context .Background (), func (session * db.Session ) error {
22- _ , err := session .Exec ("DELETE FROM annotation" )
23- return err
24- })
25- assert .NoError (t , err )
26- })
18+ func TestIntegrationAnnotationCleanUp (t * testing.T ) {
19+ if testing .Short () {
20+ t .Skip ("Skipping integration test" )
21+ }
2722
28- createTestAnnotations (t , fakeSQL , 21 , 6 )
29- assertAnnotationCount (t , fakeSQL , "" , 21 )
30- assertAnnotationTagCount (t , fakeSQL , 42 )
23+ fakeSQL := db .InitTestDB (t )
3124
3225 tests := []struct {
33- name string
34- cfg * setting.Cfg
35- alertAnnotationCount int64
36- dashboardAnnotationCount int64
37- APIAnnotationCount int64
38- affectedAnnotations int64
26+ name string
27+ createAnnotationsNum int
28+ createOldAnnotationsNum int
29+
30+ cfg * setting.Cfg
31+ alertAnnotationCount int64
32+ annotationCleanupJobBatchSize int
33+ dashboardAnnotationCount int64
34+ APIAnnotationCount int64
35+ affectedAnnotations int64
3936 }{
4037 {
41- name : "default settings should not delete any annotations" ,
38+ name : "default settings should not delete any annotations" ,
39+ createAnnotationsNum : 21 ,
40+ createOldAnnotationsNum : 6 ,
41+ annotationCleanupJobBatchSize : 1 ,
4242 cfg : & setting.Cfg {
4343 AlertingAnnotationCleanupSetting : settingsFn (0 , 0 ),
4444 DashboardAnnotationCleanupSettings : settingsFn (0 , 0 ),
@@ -50,7 +50,10 @@ func TestAnnotationCleanUp(t *testing.T) {
5050 affectedAnnotations : 0 ,
5151 },
5252 {
53- name : "should remove annotations created before cut off point" ,
53+ name : "should remove annotations created before cut off point" ,
54+ createAnnotationsNum : 21 ,
55+ createOldAnnotationsNum : 6 ,
56+ annotationCleanupJobBatchSize : 1 ,
5457 cfg : & setting.Cfg {
5558 AlertingAnnotationCleanupSetting : settingsFn (time .Hour * 48 , 0 ),
5659 DashboardAnnotationCleanupSettings : settingsFn (time .Hour * 48 , 0 ),
@@ -62,7 +65,10 @@ func TestAnnotationCleanUp(t *testing.T) {
6265 affectedAnnotations : 6 ,
6366 },
6467 {
65- name : "should only keep three annotations" ,
68+ name : "should only keep three annotations" ,
69+ createAnnotationsNum : 15 ,
70+ createOldAnnotationsNum : 6 ,
71+ annotationCleanupJobBatchSize : 1 ,
6672 cfg : & setting.Cfg {
6773 AlertingAnnotationCleanupSetting : settingsFn (0 , 3 ),
6874 DashboardAnnotationCleanupSettings : settingsFn (0 , 3 ),
@@ -74,7 +80,10 @@ func TestAnnotationCleanUp(t *testing.T) {
7480 affectedAnnotations : 6 ,
7581 },
7682 {
77- name : "running the max count delete again should not remove any annotations" ,
83+ name : "running the max count delete again should not remove any annotations" ,
84+ createAnnotationsNum : 9 ,
85+ createOldAnnotationsNum : 6 ,
86+ annotationCleanupJobBatchSize : 1 ,
7887 cfg : & setting.Cfg {
7988 AlertingAnnotationCleanupSetting : settingsFn (0 , 3 ),
8089 DashboardAnnotationCleanupSettings : settingsFn (0 , 3 ),
@@ -85,12 +94,40 @@ func TestAnnotationCleanUp(t *testing.T) {
8594 APIAnnotationCount : 3 ,
8695 affectedAnnotations : 0 ,
8796 },
97+ {
98+ name : "should not fail if batch size is larger than SQLITE_MAX_VARIABLE_NUMBER for SQLite >= 3.32.0" ,
99+ createAnnotationsNum : 40003 ,
100+ createOldAnnotationsNum : 0 ,
101+ annotationCleanupJobBatchSize : 32767 ,
102+ cfg : & setting.Cfg {
103+ AlertingAnnotationCleanupSetting : settingsFn (0 , 1 ),
104+ DashboardAnnotationCleanupSettings : settingsFn (0 , 1 ),
105+ APIAnnotationCleanupSettings : settingsFn (0 , 1 ),
106+ },
107+ alertAnnotationCount : 1 ,
108+ dashboardAnnotationCount : 1 ,
109+ APIAnnotationCount : 1 ,
110+ affectedAnnotations : 40000 ,
111+ },
88112 }
89113
90114 for _ , test := range tests {
91115 t .Run (test .name , func (t * testing.T ) {
116+ createTestAnnotations (t , fakeSQL , test .createAnnotationsNum , test .createOldAnnotationsNum )
117+ assertAnnotationCount (t , fakeSQL , "" , int64 (test .createAnnotationsNum ))
118+ assertAnnotationTagCount (t , fakeSQL , 2 * int64 (test .createAnnotationsNum ))
119+
120+ t .Cleanup (func () {
121+ err := fakeSQL .WithDbSession (context .Background (), func (session * db.Session ) error {
122+ _ , deleteAnnotationErr := session .Exec ("DELETE FROM annotation" )
123+ _ , deleteAnnotationTagErr := session .Exec ("DELETE FROM annotation_tag" )
124+ return errors .Join (deleteAnnotationErr , deleteAnnotationTagErr )
125+ })
126+ assert .NoError (t , err )
127+ })
128+
92129 cfg := setting .NewCfg ()
93- cfg .AnnotationCleanupJobBatchSize = 1
130+ cfg .AnnotationCleanupJobBatchSize = int64 ( test . annotationCleanupJobBatchSize )
94131 cleaner := ProvideCleanupService (fakeSQL , cfg )
95132 affectedAnnotations , affectedAnnotationTags , err := cleaner .Run (context .Background (), test .cfg )
96133 require .NoError (t , err )
@@ -111,7 +148,11 @@ func TestAnnotationCleanUp(t *testing.T) {
111148 }
112149}
113150
114- func TestOldAnnotationsAreDeletedFirst (t * testing.T ) {
151+ func TestIntegrationOldAnnotationsAreDeletedFirst (t * testing.T ) {
152+ if testing .Short () {
153+ t .Skip ("Skipping integration test" )
154+ }
155+
115156 fakeSQL := db .InitTestDB (t )
116157
117158 t .Cleanup (func () {
@@ -193,8 +234,11 @@ func createTestAnnotations(t *testing.T, store db.DB, expectedCount int, oldAnno
193234
194235 cutoffDate := time .Now ()
195236
237+ newAnnotations := make ([]* annotations.Item , 0 , expectedCount )
238+ newAnnotationTags := make ([]* annotationTag , 0 , 2 * expectedCount )
196239 for i := 0 ; i < expectedCount ; i ++ {
197240 a := & annotations.Item {
241+ ID : int64 (i + 1 ),
198242 DashboardID : 1 ,
199243 OrgID : 1 ,
200244 UserID : 1 ,
@@ -222,20 +266,29 @@ func createTestAnnotations(t *testing.T, store db.DB, expectedCount int, oldAnno
222266 a .Created = cutoffDate .AddDate (- 10 , 0 , - 10 ).UnixNano () / int64 (time .Millisecond )
223267 }
224268
225- err := store .WithDbSession (context .Background (), func (sess * db.Session ) error {
226- _ , err := sess .Insert (a )
227- require .NoError (t , err , "should be able to save annotation" , err )
228-
229- // mimick the SQL annotation Save logic by writing records to the annotation_tag table
230- // we need to ensure they get deleted when we clean up annotations
231- for tagID := range []int {1 , 2 } {
232- _ , err = sess .Exec ("INSERT INTO annotation_tag (annotation_id, tag_id) VALUES(?,?)" , a .ID , tagID )
233- require .NoError (t , err , "should be able to save annotation tag ID" , err )
234- }
235- return err
236- })
237- require .NoError (t , err )
269+ newAnnotations = append (newAnnotations , a )
270+ newAnnotationTags = append (newAnnotationTags , & annotationTag {AnnotationID : a .ID , TagID : 1 }, & annotationTag {AnnotationID : a .ID , TagID : 2 })
238271 }
272+
273+ err := store .WithDbSession (context .Background (), func (sess * db.Session ) error {
274+ batchsize := 500
275+ for i := 0 ; i < len (newAnnotations ); i += batchsize {
276+ _ , err := sess .InsertMulti (newAnnotations [i :min (i + batchsize , len (newAnnotations ))])
277+ require .NoError (t , err )
278+ }
279+ return nil
280+ })
281+ require .NoError (t , err )
282+
283+ err = store .WithDbSession (context .Background (), func (sess * db.Session ) error {
284+ batchsize := 500
285+ for i := 0 ; i < len (newAnnotationTags ); i += batchsize {
286+ _ , err := sess .InsertMulti (newAnnotationTags [i :min (i + batchsize , len (newAnnotationTags ))])
287+ require .NoError (t , err )
288+ }
289+ return nil
290+ })
291+ require .NoError (t , err )
239292}
240293
241294func settingsFn (maxAge time.Duration , maxCount int64 ) setting.AnnotationCleanupSettings {
0 commit comments