@ -784,13 +784,15 @@ func TestIntegration_DeleteAlertRulesByUID(t *testing.T) {
require . Empty ( t , savedInstances )
} )
t . Run ( "should remove all version and insert one with empty rule_uid" , func ( t * testing . T ) {
t . Run ( "should remove all version and insert one with empty rule_uid when DeletedRuleRetention is set " , func ( t * testing . T ) {
orgID := int64 ( rand . Intn ( 1000 ) )
gen = gen . With ( gen . WithOrgID ( orgID ) )
// Create a new store to pass the custom bus to check the signal
b := & fakeBus { }
logger := log . New ( "test-dbstore" )
cfg . UnifiedAlerting . DeletedRuleRetention = 1000 * time . Hour
store := createTestStore ( sqlStore , folderService , logger , cfg . UnifiedAlerting , b )
store . FeatureToggles = featuremgmt . WithFeatures ( featuremgmt . FlagAlertRuleRestore )
@ -848,6 +850,59 @@ func TestIntegration_DeleteAlertRulesByUID(t *testing.T) {
return nil
} )
} )
t . Run ( "should remove all versions and not keep history if DeletedRuleRetention = 0" , func ( t * testing . T ) {
orgID := int64 ( rand . Intn ( 1000 ) )
gen = gen . With ( gen . WithOrgID ( orgID ) )
// Create a new store to pass the custom bus to check the signal
b := & fakeBus { }
logger := log . New ( "test-dbstore" )
cfg . UnifiedAlerting . DeletedRuleRetention = 0
store := createTestStore ( sqlStore , folderService , logger , cfg . UnifiedAlerting , b )
store . FeatureToggles = featuremgmt . WithFeatures ( featuremgmt . FlagAlertRuleRestore )
result , err := store . InsertAlertRules ( context . Background ( ) , & models . AlertingUserUID , gen . GenerateMany ( 3 ) )
uids := make ( [ ] string , 0 , len ( result ) )
for _ , rule := range result {
uids = append ( uids , rule . UID )
}
require . NoError ( t , err )
rules , err := store . ListAlertRules ( context . Background ( ) , & models . ListAlertRulesQuery { OrgID : orgID , RuleUIDs : uids } )
require . NoError ( t , err )
updates := make ( [ ] models . UpdateRule , 0 , len ( rules ) )
for _ , rule := range rules {
rule2 := models . CopyRule ( rule , gen . WithTitle ( util . GenerateShortUID ( ) ) )
updates = append ( updates , models . UpdateRule {
Existing : rule ,
New : * rule2 ,
} )
}
err = store . UpdateAlertRules ( context . Background ( ) , & models . AlertingUserUID , updates )
require . NoError ( t , err )
versions , err := store . GetAlertRuleVersions ( context . Background ( ) , orgID , rules [ 0 ] . GUID )
require . NoError ( t , err )
require . Len ( t , versions , 2 )
err = store . DeleteAlertRulesByUID ( context . Background ( ) , orgID , util . Pointer ( models . UserUID ( "test" ) ) , uids ... )
require . NoError ( t , err )
guids := make ( [ ] string , 0 , len ( rules ) )
for _ , rule := range rules {
guids = append ( guids , rule . GUID )
}
_ = sqlStore . WithDbSession ( context . Background ( ) , func ( sess * sqlstore . DBSession ) error {
var versions [ ] alertRuleVersion
err = sess . Table ( alertRuleVersion { } ) . Where ( ` rule_uid = '' ` ) . In ( "rule_guid" , guids ) . Find ( & versions )
require . NoError ( t , err )
require . Emptyf ( t , versions , "some rules were not permanently deleted" ) // should be one version per GUID
return nil
} )
} )
}
func TestIntegrationInsertAlertRules ( t * testing . T ) {
@ -1962,6 +2017,7 @@ func TestIntegration_ListDeletedRules(t *testing.T) {
cfg . UnifiedAlerting = setting . UnifiedAlertingSettings {
BaseInterval : 1 * time . Second ,
RuleVersionRecordLimit : - 1 ,
DeletedRuleRetention : 10 * time . Hour ,
}
sqlStore := db . InitTestDB ( t )
folderService := setupFolderService ( t , sqlStore , cfg , featuremgmt . WithFeatures ( ) )
@ -2011,6 +2067,72 @@ func TestIntegration_ListDeletedRules(t *testing.T) {
} )
}
func TestIntegration_CleanUpDeletedAlertRules ( t * testing . T ) {
if testing . Short ( ) {
t . Skip ( "skipping integration test" )
}
oldClk := TimeNow
t . Cleanup ( func ( ) {
TimeNow = oldClk
} )
t0 := time . Now ( ) . UTC ( ) . Truncate ( time . Second )
TimeNow = func ( ) time . Time {
return t0
}
sqlStore := db . InitTestDB ( t , sqlstore . InitTestDBOpt {
Cfg : nil ,
} )
cfg := setting . NewCfg ( )
cfg . UnifiedAlerting . BaseInterval = 1 * time . Second
cfg . UnifiedAlerting . RuleVersionRecordLimit = - 1
cfg . UnifiedAlerting . DeletedRuleRetention = 10 * time . Second
folderService := setupFolderService ( t , sqlStore , cfg , featuremgmt . WithFeatures ( ) )
logger := log . New ( "test-dbstore" )
store := createTestStore ( sqlStore , folderService , logger , cfg . UnifiedAlerting , & fakeBus { } )
store . FeatureToggles = featuremgmt . WithFeatures ( featuremgmt . FlagAlertRuleRestore )
gen := models . RuleGen
orgID := int64 ( rand . Intn ( 1000 ) )
gen = gen . With ( gen . WithOrgID ( orgID ) )
result , err := store . InsertAlertRules ( context . Background ( ) , & models . AlertingUserUID , gen . GenerateMany ( 3 ) )
uids := make ( [ ] string , 0 , len ( result ) )
for _ , rule := range result {
uids = append ( uids , rule . UID )
}
require . NoError ( t , err )
// simulate rule deletion at different time.
// t0, t0+10s, t0+20s
for idx , uid := range uids {
TimeNow = func ( ) time . Time {
return t0 . Add ( time . Duration ( idx ) * 10 * time . Second )
}
err = store . DeleteAlertRulesByUID ( context . Background ( ) , orgID , util . Pointer ( models . UserUID ( "test" ) ) , uid )
require . NoError ( t , err )
}
before , err := store . ListDeletedRules ( context . Background ( ) , orgID )
require . NoError ( t , err )
require . Len ( t , before , 3 )
// retention is 10s, now=t+20s, therefore, only one row should be deleted
_ , err = store . CleanUpDeletedAlertRules ( context . Background ( ) )
require . NoError ( t , err )
after , err := store . ListDeletedRules ( context . Background ( ) , orgID )
require . NoError ( t , err )
assert . Len ( t , after , 1 )
for _ , rule := range after {
assert . GreaterOrEqual ( t , rule . Updated , TimeNow ( ) . Add ( - cfg . UnifiedAlerting . DeletedRuleRetention ) )
}
}
func createTestStore (
sqlStore db . DB ,
folderService folder . Service ,