package middleware_test import ( "context" "fmt" "testing" "time" "github.com/influxdata/influxdb/v2" "github.com/influxdata/influxdb/v2/notification/rule" "github.com/influxdata/influxdb/v2/task/backend/middleware" ) func newNotificationRuleSvcStack() (mockedSvc, *middleware.CoordinatingNotificationRuleStore) { msvcs := newMockServices() return msvcs, middleware.NewNotificationRuleStore(msvcs.notificationSvc, msvcs.taskSvc, msvcs.pipingCoordinator) } func TestNotificationRuleCreate(t *testing.T) { mocks, nrService := newNotificationRuleSvcStack() ch := mocks.pipingCoordinator.taskCreatedChan() nr := &rule.HTTP{} nr.SetTaskID(4) nrc := influxdb.NotificationRuleCreate{ NotificationRule: nr, Status: influxdb.Active, } err := nrService.CreateNotificationRule(context.Background(), nrc, 1) if err != nil { t.Fatal(err) } select { case task := <-ch: if task.ID != nr.GetTaskID() { t.Fatalf("task sent to coordinator doesn't match expected") } default: t.Fatal("didn't receive task") } mocks.pipingCoordinator.err = fmt.Errorf("bad") mocks.notificationSvc.DeleteNotificationRuleF = func(context.Context, influxdb.ID) error { return fmt.Errorf("AARGH") } err = nrService.CreateNotificationRule(context.Background(), nrc, 1) if err.Error() != "schedule task failed: bad\n\tcleanup also failed: AARGH" { t.Fatal(err) } } func TestNotificationRuleUpdateFromInactive(t *testing.T) { mocks, nrService := newNotificationRuleSvcStack() latest := time.Now().UTC() nrService.Now = func() time.Time { return latest } ch := mocks.pipingCoordinator.taskUpdatedChan() mocks.notificationSvc.UpdateNotificationRuleF = func(_ context.Context, _ influxdb.ID, c influxdb.NotificationRuleCreate, _ influxdb.ID) (influxdb.NotificationRule, error) { c.SetTaskID(10) c.SetUpdatedAt(latest.Add(-20 * time.Hour)) return c, nil } mocks.notificationSvc.PatchNotificationRuleF = func(_ context.Context, id influxdb.ID, _ influxdb.NotificationRuleUpdate) (influxdb.NotificationRule, error) { ic := &rule.HTTP{} ic.SetTaskID(10) ic.SetUpdatedAt(latest.Add(-20 * time.Hour)) return ic, nil } mocks.notificationSvc.FindNotificationRuleByIDF = func(_ context.Context, id influxdb.ID) (influxdb.NotificationRule, error) { c := &rule.HTTP{} c.SetID(id) c.SetTaskID(1) return c, nil } mocks.taskSvc.FindTaskByIDFn = func(_ context.Context, id influxdb.ID) (*influxdb.Task, error) { if id == 1 { return &influxdb.Task{ID: id, Status: string(influxdb.TaskInactive)}, nil } else if id == 10 { return &influxdb.Task{ID: id, Status: string(influxdb.TaskActive)}, nil } return &influxdb.Task{ID: id}, nil } deadman := &rule.HTTP{} deadman.SetTaskID(10) nrc := influxdb.NotificationRuleCreate{ NotificationRule: deadman, Status: influxdb.Active, } therule, err := nrService.UpdateNotificationRule(context.Background(), 1, nrc, 11) if err != nil { t.Fatal(err) } select { case task := <-ch: if task.ID != therule.GetTaskID() { t.Fatalf("task sent to coordinator doesn't match expected") } if task.LatestCompleted != latest { t.Fatalf("update returned incorrect LatestCompleted, expected %s got %s, or ", latest.Format(time.RFC3339), task.LatestCompleted) } default: t.Fatal("didn't receive task") } action := influxdb.Active therule, err = nrService.PatchNotificationRule(context.Background(), 1, influxdb.NotificationRuleUpdate{Status: &action}) if err != nil { t.Fatal(err) } select { case task := <-ch: if task.ID != therule.GetTaskID() { t.Fatalf("task sent to coordinator doesn't match expected") } if task.LatestCompleted != latest { t.Fatalf("update returned incorrect LatestCompleted, expected %s got %s, or ", latest.Format(time.RFC3339), task.LatestCompleted) } default: t.Fatal("didn't receive task") } } func TestNotificationRuleUpdate(t *testing.T) { mocks, nrService := newNotificationRuleSvcStack() ch := mocks.pipingCoordinator.taskUpdatedChan() mocks.notificationSvc.UpdateNotificationRuleF = func(_ context.Context, _ influxdb.ID, c influxdb.NotificationRuleCreate, _ influxdb.ID) (influxdb.NotificationRule, error) { c.SetTaskID(10) return c, nil } deadman := &rule.HTTP{} deadman.SetTaskID(4) nrc := influxdb.NotificationRuleCreate{ NotificationRule: deadman, Status: influxdb.Active, } nr, err := nrService.UpdateNotificationRule(context.Background(), 1, nrc, 2) if err != nil { t.Fatal(err) } select { case task := <-ch: if task.ID != nr.GetTaskID() { t.Fatalf("task sent to coordinator doesn't match expected") } default: t.Fatal("didn't receive task") } } func TestNotificationRulePatch(t *testing.T) { mocks, nrService := newNotificationRuleSvcStack() ch := mocks.pipingCoordinator.taskUpdatedChan() deadman := &rule.HTTP{} deadman.SetTaskID(4) mocks.notificationSvc.PatchNotificationRuleF = func(context.Context, influxdb.ID, influxdb.NotificationRuleUpdate) (influxdb.NotificationRule, error) { return deadman, nil } nr, err := nrService.PatchNotificationRule(context.Background(), 1, influxdb.NotificationRuleUpdate{}) if err != nil { t.Fatal(err) } select { case task := <-ch: if task.ID != nr.GetTaskID() { t.Fatalf("task sent to coordinator doesn't match expected") } default: t.Fatal("didn't receive task") } } func TestNotificationRuleDelete(t *testing.T) { mocks, nrService := newNotificationRuleSvcStack() ch := mocks.pipingCoordinator.taskDeletedChan() mocks.notificationSvc.FindNotificationRuleByIDF = func(_ context.Context, id influxdb.ID) (influxdb.NotificationRule, error) { c := &rule.HTTP{} c.SetID(id) c.SetTaskID(21) return c, nil } err := nrService.DeleteNotificationRule(context.Background(), 1) if err != nil { t.Fatal(err) } select { case id := <-ch: if id != influxdb.ID(21) { t.Fatalf("task sent to coordinator doesn't match expected") } default: t.Fatal("didn't receive task") } }