| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | package notifier | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/google/go-cmp/cmp" | 
					
						
							|  |  |  | 	"github.com/google/go-cmp/cmp/cmpopts" | 
					
						
							|  |  |  | 	"github.com/prometheus/alertmanager/config" | 
					
						
							|  |  |  | 	"github.com/prometheus/alertmanager/pkg/labels" | 
					
						
							|  |  |  | 	"github.com/prometheus/common/model" | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/infra/log/logtest" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/services/ngalert/models" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/util" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestAddAutogenConfig(t *testing.T) { | 
					
						
							|  |  |  | 	rootRoute := func() *definitions.Route { | 
					
						
							|  |  |  | 		return &definitions.Route{ | 
					
						
							|  |  |  | 			Receiver: "default", | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	configGen := func(receivers []string, muteIntervals []string) *definitions.PostableApiAlertingConfig { | 
					
						
							|  |  |  | 		cfg := &definitions.PostableApiAlertingConfig{ | 
					
						
							|  |  |  | 			Config: definitions.Config{ | 
					
						
							|  |  |  | 				Route: rootRoute(), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		for _, receiver := range receivers { | 
					
						
							|  |  |  | 			cfg.Receivers = append(cfg.Receivers, &definitions.PostableApiReceiver{ | 
					
						
							|  |  |  | 				Receiver: config.Receiver{ | 
					
						
							|  |  |  | 					Name: receiver, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		for _, muteInterval := range muteIntervals { | 
					
						
							|  |  |  | 			cfg.MuteTimeIntervals = append(cfg.MuteTimeIntervals, config.MuteTimeInterval{ | 
					
						
							|  |  |  | 				Name: muteInterval, | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return cfg | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	withChildRoutes := func(route *definitions.Route, children ...*definitions.Route) *definitions.Route { | 
					
						
							|  |  |  | 		route.Routes = append(route.Routes, children...) | 
					
						
							|  |  |  | 		return route | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	matcher := func(key, val string) definitions.ObjectMatchers { | 
					
						
							|  |  |  | 		m, err := labels.NewMatcher(labels.MatchEqual, key, val) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		return definitions.ObjectMatchers{m} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	basicContactRoute := func(receiver string) *definitions.Route { | 
					
						
							|  |  |  | 		return &definitions.Route{ | 
					
						
							|  |  |  | 			Receiver:       receiver, | 
					
						
							|  |  |  | 			ObjectMatchers: matcher(models.AutogeneratedRouteReceiverNameLabel, receiver), | 
					
						
							|  |  |  | 			GroupByStr:     []string{models.FolderTitleLabel, model.AlertNameLabel}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		name             string | 
					
						
							|  |  |  | 		existingConfig   *definitions.PostableApiAlertingConfig | 
					
						
							|  |  |  | 		storeSettings    []models.NotificationSettings | 
					
						
							|  |  |  | 		skipInvalid      bool | 
					
						
							|  |  |  | 		expRoute         *definitions.Route | 
					
						
							|  |  |  | 		expErrorContains string | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name:           "no settings or receivers, no change", | 
					
						
							|  |  |  | 			existingConfig: configGen(nil, nil), | 
					
						
							|  |  |  | 			storeSettings:  []models.NotificationSettings{}, | 
					
						
							|  |  |  | 			expRoute:       rootRoute(), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name:           "no settings but some receivers, add default routes for receivers", | 
					
						
							|  |  |  | 			existingConfig: configGen([]string{"receiver1", "receiver2", "receiver3"}, nil), | 
					
						
							|  |  |  | 			storeSettings:  []models.NotificationSettings{}, | 
					
						
							|  |  |  | 			expRoute: withChildRoutes(rootRoute(), &definitions.Route{ | 
					
						
							|  |  |  | 				Receiver:       "default", | 
					
						
							|  |  |  | 				ObjectMatchers: matcher(models.AutogeneratedRouteLabel, "true"), | 
					
						
							|  |  |  | 				Routes: []*definitions.Route{ | 
					
						
							|  |  |  | 					basicContactRoute("receiver2"), | 
					
						
							| 
									
										
										
										
											2025-09-11 19:44:06 +08:00
										 |  |  | 					basicContactRoute("receiver3"), | 
					
						
							|  |  |  | 					basicContactRoute("receiver1"), | 
					
						
							| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			}), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name:           "settings with no custom options, add default routes only", | 
					
						
							|  |  |  | 			existingConfig: configGen([]string{"receiver1", "receiver2", "receiver3"}, nil), | 
					
						
							|  |  |  | 			storeSettings:  []models.NotificationSettings{models.NewDefaultNotificationSettings("receiver1"), models.NewDefaultNotificationSettings("receiver2")}, | 
					
						
							|  |  |  | 			expRoute: withChildRoutes(rootRoute(), &definitions.Route{ | 
					
						
							|  |  |  | 				Receiver:       "default", | 
					
						
							|  |  |  | 				ObjectMatchers: matcher(models.AutogeneratedRouteLabel, "true"), | 
					
						
							|  |  |  | 				Routes: []*definitions.Route{ | 
					
						
							|  |  |  | 					basicContactRoute("receiver2"), | 
					
						
							| 
									
										
										
										
											2025-09-11 19:44:06 +08:00
										 |  |  | 					basicContactRoute("receiver3"), | 
					
						
							|  |  |  | 					basicContactRoute("receiver1"), | 
					
						
							| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			}), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name:           "settings with custom options, add option-specific routes", | 
					
						
							| 
									
										
										
										
											2025-05-08 07:19:33 +08:00
										 |  |  | 			existingConfig: configGen([]string{"receiver1", "receiver2", "receiver3", "receiver4", "receiver5"}, []string{"maintenance", "active"}), | 
					
						
							| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | 			storeSettings: []models.NotificationSettings{ | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver1"), models.NSMuts.WithGroupInterval(util.Pointer(1*time.Minute))), | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver2"), models.NSMuts.WithGroupWait(util.Pointer(2*time.Minute))), | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver3"), models.NSMuts.WithRepeatInterval(util.Pointer(3*time.Minute))), | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver4"), models.NSMuts.WithGroupBy(model.AlertNameLabel, models.FolderTitleLabel, "custom")), | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver5"), models.NSMuts.WithMuteTimeIntervals("maintenance")), | 
					
						
							| 
									
										
										
										
											2025-05-08 07:19:33 +08:00
										 |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver5"), models.NSMuts.WithActiveTimeIntervals("active")), | 
					
						
							| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2025-05-08 07:19:33 +08:00
										 |  |  | 					Receiver:            "receiver1", | 
					
						
							|  |  |  | 					GroupBy:             []string{model.AlertNameLabel, models.FolderTitleLabel, "custom"}, | 
					
						
							|  |  |  | 					GroupInterval:       util.Pointer(model.Duration(1 * time.Minute)), | 
					
						
							|  |  |  | 					GroupWait:           util.Pointer(model.Duration(2 * time.Minute)), | 
					
						
							|  |  |  | 					RepeatInterval:      util.Pointer(model.Duration(3 * time.Minute)), | 
					
						
							|  |  |  | 					MuteTimeIntervals:   []string{"maintenance"}, | 
					
						
							|  |  |  | 					ActiveTimeIntervals: []string{"active"}, | 
					
						
							| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			expRoute: withChildRoutes(rootRoute(), &definitions.Route{ | 
					
						
							|  |  |  | 				Receiver:       "default", | 
					
						
							|  |  |  | 				ObjectMatchers: matcher(models.AutogeneratedRouteLabel, "true"), | 
					
						
							|  |  |  | 				Routes: []*definitions.Route{ | 
					
						
							| 
									
										
										
										
											2025-10-02 03:21:33 +08:00
										 |  |  | 					withChildRoutes(basicContactRoute("receiver1"), &definitions.Route{ | 
					
						
							|  |  |  | 						Receiver:            "receiver1", | 
					
						
							|  |  |  | 						ObjectMatchers:      matcher(models.AutogeneratedRouteSettingsHashLabel, "02466789dc88da23"), | 
					
						
							|  |  |  | 						GroupByStr:          []string{models.FolderTitleLabel, model.AlertNameLabel, "custom"}, | 
					
						
							|  |  |  | 						GroupInterval:       util.Pointer(model.Duration(1 * time.Minute)), | 
					
						
							|  |  |  | 						GroupWait:           util.Pointer(model.Duration(2 * time.Minute)), | 
					
						
							|  |  |  | 						RepeatInterval:      util.Pointer(model.Duration(3 * time.Minute)), | 
					
						
							|  |  |  | 						MuteTimeIntervals:   []string{"maintenance"}, | 
					
						
							|  |  |  | 						ActiveTimeIntervals: []string{"active"}, | 
					
						
							|  |  |  | 					}, &definitions.Route{ | 
					
						
							|  |  |  | 						Receiver:       "receiver1", | 
					
						
							|  |  |  | 						ObjectMatchers: matcher(models.AutogeneratedRouteSettingsHashLabel, "efc87d76ccc550bc"), | 
					
						
							|  |  |  | 						GroupInterval:  util.Pointer(model.Duration(1 * time.Minute)), | 
					
						
							|  |  |  | 					}), | 
					
						
							|  |  |  | 					withChildRoutes(basicContactRoute("receiver2"), &definitions.Route{ | 
					
						
							|  |  |  | 						Receiver:       "receiver2", | 
					
						
							|  |  |  | 						ObjectMatchers: matcher(models.AutogeneratedRouteSettingsHashLabel, "63ad04d6c21c3aec"), | 
					
						
							|  |  |  | 						GroupWait:      util.Pointer(model.Duration(2 * time.Minute)), | 
					
						
							|  |  |  | 					}), | 
					
						
							|  |  |  | 					withChildRoutes(basicContactRoute("receiver5"), &definitions.Route{ | 
					
						
							|  |  |  | 						Receiver:            "receiver5", | 
					
						
							|  |  |  | 						ObjectMatchers:      matcher(models.AutogeneratedRouteSettingsHashLabel, "8cd5f9adeac58123"), | 
					
						
							|  |  |  | 						ActiveTimeIntervals: []string{"active"}, | 
					
						
							|  |  |  | 					}, &definitions.Route{ | 
					
						
							|  |  |  | 						Receiver:          "receiver5", | 
					
						
							|  |  |  | 						ObjectMatchers:    matcher(models.AutogeneratedRouteSettingsHashLabel, "f0770544f1741cf6"), | 
					
						
							|  |  |  | 						MuteTimeIntervals: []string{"maintenance"}, | 
					
						
							|  |  |  | 					}), | 
					
						
							|  |  |  | 					withChildRoutes(basicContactRoute("receiver4"), &definitions.Route{ | 
					
						
							|  |  |  | 						Receiver:       "receiver4", | 
					
						
							|  |  |  | 						ObjectMatchers: matcher(models.AutogeneratedRouteSettingsHashLabel, "9bbbec5f72627ae5"), | 
					
						
							|  |  |  | 						GroupByStr:     []string{models.FolderTitleLabel, model.AlertNameLabel, "custom"}, | 
					
						
							|  |  |  | 					}), | 
					
						
							|  |  |  | 					withChildRoutes(basicContactRoute("receiver3"), &definitions.Route{ | 
					
						
							|  |  |  | 						Receiver:       "receiver3", | 
					
						
							|  |  |  | 						ObjectMatchers: matcher(models.AutogeneratedRouteSettingsHashLabel, "fbcacbfae385a901"), | 
					
						
							|  |  |  | 						RepeatInterval: util.Pointer(model.Duration(3 * time.Minute)), | 
					
						
							|  |  |  | 					}), | 
					
						
							| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			}), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2024-04-17 00:14:39 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			name:           "settings with custom options and nil groupBy, groupBy should inherit from parent", | 
					
						
							|  |  |  | 			existingConfig: configGen([]string{"receiver1"}, nil), | 
					
						
							|  |  |  | 			storeSettings: []models.NotificationSettings{ | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver1"), models.NSMuts.WithGroupInterval(util.Pointer(1*time.Minute)), models.NSMuts.WithGroupBy()), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			expRoute: withChildRoutes(rootRoute(), &definitions.Route{ | 
					
						
							|  |  |  | 				Receiver:       "default", | 
					
						
							|  |  |  | 				ObjectMatchers: matcher(models.AutogeneratedRouteLabel, "true"), | 
					
						
							|  |  |  | 				Routes: []*definitions.Route{ | 
					
						
							| 
									
										
										
										
											2025-10-02 03:21:33 +08:00
										 |  |  | 					withChildRoutes(basicContactRoute("receiver1"), &definitions.Route{ | 
					
						
							|  |  |  | 						Receiver:       "receiver1", | 
					
						
							|  |  |  | 						ObjectMatchers: matcher(models.AutogeneratedRouteSettingsHashLabel, "efc87d76ccc550bc"), | 
					
						
							|  |  |  | 						GroupByStr:     nil, | 
					
						
							|  |  |  | 						GroupInterval:  util.Pointer(model.Duration(1 * time.Minute)), | 
					
						
							|  |  |  | 					}), | 
					
						
							| 
									
										
										
										
											2024-04-17 00:14:39 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			}), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name:           "settings with nil groupBy should have different fingerprint than default groupBy", | 
					
						
							|  |  |  | 			existingConfig: configGen([]string{"receiver1"}, nil), | 
					
						
							|  |  |  | 			storeSettings: []models.NotificationSettings{ | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver1"), models.NSMuts.WithGroupInterval(util.Pointer(1*time.Minute)), models.NSMuts.WithGroupBy()), | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver1"), models.NSMuts.WithGroupInterval(util.Pointer(1*time.Minute)), models.NSMuts.WithGroupBy(models.DefaultNotificationSettingsGroupBy...)), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			expRoute: withChildRoutes(rootRoute(), &definitions.Route{ | 
					
						
							|  |  |  | 				Receiver:       "default", | 
					
						
							|  |  |  | 				ObjectMatchers: matcher(models.AutogeneratedRouteLabel, "true"), | 
					
						
							|  |  |  | 				Routes: []*definitions.Route{ | 
					
						
							| 
									
										
										
										
											2025-10-02 03:21:33 +08:00
										 |  |  | 					withChildRoutes(basicContactRoute("receiver1"), &definitions.Route{ | 
					
						
							|  |  |  | 						Receiver:       "receiver1", | 
					
						
							|  |  |  | 						ObjectMatchers: matcher(models.AutogeneratedRouteSettingsHashLabel, "828092ed6f427a00"), // Different hash.
 | 
					
						
							|  |  |  | 						GroupByStr:     []string{models.FolderTitleLabel, model.AlertNameLabel}, | 
					
						
							|  |  |  | 						GroupInterval:  util.Pointer(model.Duration(1 * time.Minute)), | 
					
						
							|  |  |  | 					}, &definitions.Route{ | 
					
						
							|  |  |  | 						Receiver:       "receiver1", | 
					
						
							|  |  |  | 						ObjectMatchers: matcher(models.AutogeneratedRouteSettingsHashLabel, "efc87d76ccc550bc"), | 
					
						
							|  |  |  | 						GroupByStr:     nil, | 
					
						
							|  |  |  | 						GroupInterval:  util.Pointer(model.Duration(1 * time.Minute)), | 
					
						
							|  |  |  | 					}), | 
					
						
							| 
									
										
										
										
											2024-04-17 00:14:39 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			}), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name:           "settings with incomplete required groupBy labels will be completed and should have the same fingerprint", | 
					
						
							|  |  |  | 			existingConfig: configGen([]string{"receiver1"}, nil), | 
					
						
							|  |  |  | 			storeSettings: []models.NotificationSettings{ | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver1"), models.NSMuts.WithGroupInterval(util.Pointer(1*time.Minute)), models.NSMuts.WithGroupBy(models.FolderTitleLabel)), | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver1"), models.NSMuts.WithGroupInterval(util.Pointer(1*time.Minute)), models.NSMuts.WithGroupBy(model.AlertNameLabel)), | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver1"), models.NSMuts.WithGroupInterval(util.Pointer(1*time.Minute)), models.NSMuts.WithGroupBy(models.DefaultNotificationSettingsGroupBy...)), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			expRoute: withChildRoutes(rootRoute(), &definitions.Route{ | 
					
						
							|  |  |  | 				Receiver:       "default", | 
					
						
							|  |  |  | 				ObjectMatchers: matcher(models.AutogeneratedRouteLabel, "true"), | 
					
						
							|  |  |  | 				Routes: []*definitions.Route{ | 
					
						
							| 
									
										
										
										
											2025-10-02 03:21:33 +08:00
										 |  |  | 					withChildRoutes(basicContactRoute("receiver1"), &definitions.Route{ | 
					
						
							|  |  |  | 						Receiver:       "receiver1", | 
					
						
							|  |  |  | 						ObjectMatchers: matcher(models.AutogeneratedRouteSettingsHashLabel, "828092ed6f427a00"), | 
					
						
							|  |  |  | 						GroupByStr:     []string{models.FolderTitleLabel, model.AlertNameLabel}, | 
					
						
							|  |  |  | 						GroupInterval:  util.Pointer(model.Duration(1 * time.Minute)), | 
					
						
							|  |  |  | 					}), | 
					
						
							| 
									
										
										
										
											2024-04-17 00:14:39 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			}), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			name:           "when skipInvalid=true, invalid settings are skipped", | 
					
						
							|  |  |  | 			existingConfig: configGen([]string{"receiver1", "receiver2", "receiver3"}, nil), | 
					
						
							|  |  |  | 			storeSettings: []models.NotificationSettings{ | 
					
						
							|  |  |  | 				models.NewDefaultNotificationSettings("receiverA"), // Doesn't exist.
 | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver1"), models.NSMuts.WithMuteTimeIntervals("maintenance")),        // Doesn't exist.
 | 
					
						
							|  |  |  | 				models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver2"), models.NSMuts.WithGroupWait(util.Pointer(-2*time.Minute))), // Negative.
 | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2025-10-02 03:21:33 +08:00
										 |  |  | 			skipInvalid: true, | 
					
						
							| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | 			expRoute: withChildRoutes(rootRoute(), &definitions.Route{ | 
					
						
							|  |  |  | 				Receiver:       "default", | 
					
						
							|  |  |  | 				ObjectMatchers: matcher(models.AutogeneratedRouteLabel, "true"), | 
					
						
							|  |  |  | 				Routes: []*definitions.Route{ | 
					
						
							|  |  |  | 					basicContactRoute("receiver2"), | 
					
						
							| 
									
										
										
										
											2025-09-11 19:44:06 +08:00
										 |  |  | 					basicContactRoute("receiver3"), | 
					
						
							|  |  |  | 					basicContactRoute("receiver1"), | 
					
						
							| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			}), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name:             "when skipInvalid=false, invalid receiver throws error", | 
					
						
							|  |  |  | 			existingConfig:   configGen([]string{"receiver1", "receiver2", "receiver3"}, nil), | 
					
						
							|  |  |  | 			storeSettings:    []models.NotificationSettings{models.NewDefaultNotificationSettings("receiverA")}, | 
					
						
							|  |  |  | 			skipInvalid:      false, | 
					
						
							|  |  |  | 			expErrorContains: "receiverA", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name:             "when skipInvalid=false, invalid settings throws error", | 
					
						
							|  |  |  | 			existingConfig:   configGen([]string{"receiver1", "receiver2", "receiver3"}, nil), | 
					
						
							|  |  |  | 			storeSettings:    []models.NotificationSettings{models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver1"), models.NSMuts.WithMuteTimeIntervals("maintenance"))}, | 
					
						
							|  |  |  | 			skipInvalid:      false, | 
					
						
							|  |  |  | 			expErrorContains: "maintenance", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name:             "when skipInvalid=false, invalid settings throws error", | 
					
						
							|  |  |  | 			existingConfig:   configGen([]string{"receiver1", "receiver2", "receiver3"}, nil), | 
					
						
							|  |  |  | 			storeSettings:    []models.NotificationSettings{models.CopyNotificationSettings(models.NewDefaultNotificationSettings("receiver2"), models.NSMuts.WithGroupWait(util.Pointer(-2*time.Minute)))}, | 
					
						
							|  |  |  | 			skipInvalid:      false, | 
					
						
							|  |  |  | 			expErrorContains: "group wait", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, tt := range testCases { | 
					
						
							|  |  |  | 		t.Run(tt.name, func(t *testing.T) { | 
					
						
							|  |  |  | 			orgId := int64(1) | 
					
						
							|  |  |  | 			store := &fakeConfigStore{ | 
					
						
							|  |  |  | 				notificationSettings: make(map[int64]map[models.AlertRuleKey][]models.NotificationSettings), | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			store.notificationSettings[orgId] = make(map[models.AlertRuleKey][]models.NotificationSettings) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for _, setting := range tt.storeSettings { | 
					
						
							|  |  |  | 				store.notificationSettings[orgId][models.AlertRuleKey{OrgID: orgId, UID: util.GenerateShortUID()}] = []models.NotificationSettings{setting} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-02 03:21:33 +08:00
										 |  |  | 			err := AddAutogenConfig(context.Background(), &logtest.Fake{}, store, orgId, tt.existingConfig, tt.skipInvalid, nil) | 
					
						
							| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | 			if tt.expErrorContains != "" { | 
					
						
							|  |  |  | 				require.Error(t, err) | 
					
						
							|  |  |  | 				require.ErrorContains(t, err, tt.expErrorContains) | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				require.NoError(t, err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-19 09:08:14 +08:00
										 |  |  | 			// We compare against the upstream normalized route.
 | 
					
						
							|  |  |  | 			require.NoError(t, tt.expRoute.Validate()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-15 22:45:10 +08:00
										 |  |  | 			cOpt := []cmp.Option{ | 
					
						
							|  |  |  | 				cmpopts.IgnoreUnexported(definitions.Route{}, labels.Matcher{}), | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if !cmp.Equal(tt.expRoute, tt.existingConfig.Route, cOpt...) { | 
					
						
							|  |  |  | 				t.Errorf("Unexpected Route: %v", cmp.Diff(tt.expRoute, tt.existingConfig.Route, cOpt...)) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |