From 39ad992cf18f6a29be55d31d5cc7b4f6bbd6911c Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Fri, 10 Jan 2025 15:25:29 +0700 Subject: [PATCH 1/7] refactor: handleFetchError method start writing tests --- checker/check.go | 25 ++++++++++++++-- checker/check_test.go | 68 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/checker/check.go b/checker/check.go index 698869cb8..03aa5283e 100644 --- a/checker/check.go +++ b/checker/check.go @@ -132,7 +132,7 @@ func (triggerChecker *TriggerChecker) handleFetchError(checkData moira.CheckData triggerChecker.trigger.ClusterKey(), ) } - case remote.ErrRemoteTriggerResponse: + case remote.ErrRemoteUnavailable: timeSinceLastSuccessfulCheck := checkData.Timestamp - checkData.LastSuccessfulCheckTimestamp if timeSinceLastSuccessfulCheck >= triggerChecker.ttl { checkData.State = moira.StateEXCEPTION @@ -149,7 +149,7 @@ func (triggerChecker *TriggerChecker) handleFetchError(checkData moira.CheckData } logTriggerCheckException(triggerChecker.logger, triggerChecker.triggerID, err) - case local.ErrUnknownFunction, local.ErrEvalExpr: + case local.ErrUnknownFunction, local.ErrEvalExpr, remote.ErrRemoteTriggerResponse: checkData.State = moira.StateEXCEPTION checkData.Message = err.Error() logTriggerCheckException(triggerChecker.logger, triggerChecker.triggerID, err) @@ -170,6 +170,27 @@ func (triggerChecker *TriggerChecker) handleFetchError(checkData moira.CheckData ) } +func (triggerChecker *TriggerChecker) reactOnSourceUnavailableError(checkData moira.CheckData, err error) moira.CheckData { + timeSinceLastSuccessfulCheck := checkData.Timestamp - checkData.LastSuccessfulCheckTimestamp + if timeSinceLastSuccessfulCheck >= triggerChecker.ttl { + checkData.State = moira.StateEXCEPTION + checkData.Message = fmt.Sprintf("Remote server unavailable. Trigger is not checked for %d seconds", timeSinceLastSuccessfulCheck) + + var comparingErr error + checkData, comparingErr = triggerChecker.compareTriggerStates(checkData) + if comparingErr != nil { + triggerChecker.logger.Error(). + Error(comparingErr). + String(moira.LogFieldNameTriggerID, triggerChecker.triggerID). + Msg("cannot compare trigger states") + } + } + + logTriggerCheckException(triggerChecker.logger, triggerChecker.triggerID, err) + + return checkData +} + // handleUndefinedError is a function that check error with undefined type. func (triggerChecker *TriggerChecker) handleUndefinedError(checkData moira.CheckData, err error) error { triggerChecker.metrics.CheckError.Mark(1) diff --git a/checker/check_test.go b/checker/check_test.go index 8a5ae0b1e..ea93f069b 100644 --- a/checker/check_test.go +++ b/checker/check_test.go @@ -1924,3 +1924,71 @@ func TestTriggerChecker_handlePrepareError(t *testing.T) { }) }) } + +func TestTriggerChecker_handleFetchError(t *testing.T) { + Convey("Test handleFetchError", t, func() { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + dataBase := mock_moira_alert.NewMockDatabase(mockCtrl) + logger, _ := logging.GetLogger("Test") + + var retention int64 = 10 + metric := "some.metric" + testTime := time.Date(2022, time.June, 6, 10, 0, 0, 0, time.UTC).Unix() + + trigger := &moira.Trigger{ + ID: "test trigger", + TriggerSource: moira.GraphiteLocal, + ClusterId: moira.DefaultCluster, + } + triggerChecker := TriggerChecker{ + triggerID: trigger.ID, + from: testTime - 5*retention, + until: testTime, + trigger: trigger, + database: dataBase, + logger: logger, + ttlState: moira.TTLStateNODATA, + lastCheck: &moira.CheckData{ + State: moira.StateOK, + Timestamp: testTime - retention, + Metrics: map[string]moira.MetricState{ + metric: { + State: moira.StateOK, + Timestamp: testTime - 4*retention - 1, + }, + }, + }, + } + + Convey("with ErrTriggerHasEmptyTargets, ErrTriggerHasOnlyWildcards", func() { + errorList := []error{ + ErrTriggerHasEmptyTargets{}, + ErrTriggerHasOnlyWildcards{}, + } + + Convey("when triggerChecker.ttl == 0", func() { + for i, givenErr := range errorList { + Convey(fmt.Sprintf("Case %v: %T", i+1, givenErr), func() { + expectedCheckData := moira.CheckData{ + Score: int64(1_000), + Metrics: triggerChecker.lastCheck.Metrics, + State: triggerChecker.ttlState.ToTriggerState(), + Timestamp: triggerChecker.until, + Message: givenErr.Error(), + } + + dataBase.EXPECT().SetTriggerLastCheck( + triggerChecker.triggerID, + &expectedCheckData, + triggerChecker.trigger.ClusterKey(), + ).Return(nil) + + err := triggerChecker.handleFetchError(newCheckData(triggerChecker.lastCheck, triggerChecker.until), givenErr) + So(err, ShouldBeNil) + }) + } + }) + }) + }) +} From 4b52b158be9989fe3d4ab15ef4ed75744d3c2134 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Mon, 13 Jan 2025 16:49:17 +0700 Subject: [PATCH 2/7] test: handleFetchError first case --- checker/check_test.go | 53 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/checker/check_test.go b/checker/check_test.go index ea93f069b..b3410c9a8 100644 --- a/checker/check_test.go +++ b/checker/check_test.go @@ -1968,21 +1968,62 @@ func TestTriggerChecker_handleFetchError(t *testing.T) { } Convey("when triggerChecker.ttl == 0", func() { + triggerChecker.ttl = 0 + for i, givenErr := range errorList { Convey(fmt.Sprintf("Case %v: %T", i+1, givenErr), func() { expectedCheckData := moira.CheckData{ - Score: int64(1_000), - Metrics: triggerChecker.lastCheck.Metrics, - State: triggerChecker.ttlState.ToTriggerState(), - Timestamp: triggerChecker.until, - Message: givenErr.Error(), + Score: int64(1_000), + Metrics: triggerChecker.lastCheck.Metrics, + State: triggerChecker.ttlState.ToTriggerState(), + Timestamp: triggerChecker.until, + Message: givenErr.Error(), + MetricsToTargetRelation: map[string]string{}, } dataBase.EXPECT().SetTriggerLastCheck( triggerChecker.triggerID, &expectedCheckData, triggerChecker.trigger.ClusterKey(), - ).Return(nil) + ).Return(nil).Times(1) + + err := triggerChecker.handleFetchError(newCheckData(triggerChecker.lastCheck, triggerChecker.until), givenErr) + So(err, ShouldBeNil) + }) + } + }) + + Convey("when triggerChecker.ttl != 0", func() { + triggerChecker.ttl = 600 + + for i, givenErr := range errorList { + Convey(fmt.Sprintf("Case %v: %T", i+1, givenErr), func() { + expectedCheckData := moira.CheckData{ + Score: int64(1_000), + Metrics: triggerChecker.lastCheck.Metrics, + State: triggerChecker.ttlState.ToTriggerState(), + Timestamp: triggerChecker.until, + EventTimestamp: triggerChecker.until, + Message: givenErr.Error(), + MetricsToTargetRelation: map[string]string{}, + } + + dataBase.EXPECT().PushNotificationEvent( + &moira.NotificationEvent{ + IsTriggerEvent: true, + TriggerID: triggerChecker.triggerID, + State: triggerChecker.ttlState.ToTriggerState(), + OldState: triggerChecker.lastCheck.State, + Timestamp: triggerChecker.until, + Metric: triggerChecker.trigger.Name, + }, + true, + ).Return(nil).Times(1) + dataBase.EXPECT().SetTriggerLastCheck( + triggerChecker.triggerID, + &expectedCheckData, + triggerChecker.trigger.ClusterKey(), + ).Return(nil).Times(1) err := triggerChecker.handleFetchError(newCheckData(triggerChecker.lastCheck, triggerChecker.until), givenErr) So(err, ShouldBeNil) From c14556ab336e9f5b5b924bb92e8e28ed294bbd81 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Mon, 13 Jan 2025 18:45:54 +0700 Subject: [PATCH 3/7] test: handleFetchError for remote.ErrRemoteUnavailable --- checker/check_test.go | 54 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/checker/check_test.go b/checker/check_test.go index b3410c9a8..994d983ea 100644 --- a/checker/check_test.go +++ b/checker/check_test.go @@ -1,6 +1,7 @@ package checker import ( + "errors" "fmt" "math" "testing" @@ -12,6 +13,7 @@ import ( logging "github.com/moira-alert/moira/logging/zerolog_adapter" metricSource "github.com/moira-alert/moira/metric_source" "github.com/moira-alert/moira/metric_source/local" + "github.com/moira-alert/moira/metric_source/remote" "go.uber.org/mock/gomock" "github.com/moira-alert/moira/metrics" @@ -1932,7 +1934,7 @@ func TestTriggerChecker_handleFetchError(t *testing.T) { dataBase := mock_moira_alert.NewMockDatabase(mockCtrl) logger, _ := logging.GetLogger("Test") - var retention int64 = 10 + //var retention int64 = 10 metric := "some.metric" testTime := time.Date(2022, time.June, 6, 10, 0, 0, 0, time.UTC).Unix() @@ -1943,7 +1945,7 @@ func TestTriggerChecker_handleFetchError(t *testing.T) { } triggerChecker := TriggerChecker{ triggerID: trigger.ID, - from: testTime - 5*retention, + from: testTime - 50, until: testTime, trigger: trigger, database: dataBase, @@ -1951,11 +1953,11 @@ func TestTriggerChecker_handleFetchError(t *testing.T) { ttlState: moira.TTLStateNODATA, lastCheck: &moira.CheckData{ State: moira.StateOK, - Timestamp: testTime - retention, + Timestamp: testTime - 10, Metrics: map[string]moira.MetricState{ metric: { State: moira.StateOK, - Timestamp: testTime - 4*retention - 1, + Timestamp: testTime - 41, }, }, }, @@ -2031,5 +2033,49 @@ func TestTriggerChecker_handleFetchError(t *testing.T) { } }) }) + + Convey("with graphite remote unavailable", func() { + givenErr := remote.ErrRemoteUnavailable{ + InternalError: errors.New("some err"), + } + + Convey("time since last successful check >= triggerChecker.ttl", func() { + triggerChecker.ttl = 10 + triggerChecker.lastCheck.LastSuccessfulCheckTimestamp = triggerChecker.until - 20 + + expectedCheckData := moira.CheckData{ + Score: int64(100_000), + Metrics: triggerChecker.lastCheck.Metrics, + State: moira.StateEXCEPTION, + Timestamp: triggerChecker.until, + EventTimestamp: triggerChecker.until, + LastSuccessfulCheckTimestamp: triggerChecker.lastCheck.LastSuccessfulCheckTimestamp, + Message: fmt.Sprintf( + "Remote server unavailable. Trigger is not checked for %d seconds", + triggerChecker.until-triggerChecker.lastCheck.LastSuccessfulCheckTimestamp), + MetricsToTargetRelation: map[string]string{}, + } + + dataBase.EXPECT().PushNotificationEvent( + &moira.NotificationEvent{ + IsTriggerEvent: true, + TriggerID: triggerChecker.triggerID, + State: moira.StateEXCEPTION, + OldState: triggerChecker.lastCheck.State, + Timestamp: triggerChecker.until, + Metric: triggerChecker.trigger.Name, + }, + true, + ).Return(nil).Times(2) + dataBase.EXPECT().SetTriggerLastCheck( + triggerChecker.triggerID, + &expectedCheckData, + triggerChecker.trigger.ClusterKey(), + ).Return(nil).Times(1) + + err := triggerChecker.handleFetchError(newCheckData(triggerChecker.lastCheck, triggerChecker.until), givenErr) + So(err, ShouldBeNil) + }) + }) }) } From 5201c3532572cd790fc3169299502f46b7ff4705 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Tue, 14 Jan 2025 11:52:14 +0700 Subject: [PATCH 4/7] test: for handleFetchError --- checker/check.go | 21 ------ checker/check_test.go | 116 +++++++++++++++++++++++++++++++++- metric_source/local/errors.go | 7 ++ metric_source/local/eval.go | 5 +- 4 files changed, 123 insertions(+), 26 deletions(-) diff --git a/checker/check.go b/checker/check.go index 03aa5283e..e874e2391 100644 --- a/checker/check.go +++ b/checker/check.go @@ -170,27 +170,6 @@ func (triggerChecker *TriggerChecker) handleFetchError(checkData moira.CheckData ) } -func (triggerChecker *TriggerChecker) reactOnSourceUnavailableError(checkData moira.CheckData, err error) moira.CheckData { - timeSinceLastSuccessfulCheck := checkData.Timestamp - checkData.LastSuccessfulCheckTimestamp - if timeSinceLastSuccessfulCheck >= triggerChecker.ttl { - checkData.State = moira.StateEXCEPTION - checkData.Message = fmt.Sprintf("Remote server unavailable. Trigger is not checked for %d seconds", timeSinceLastSuccessfulCheck) - - var comparingErr error - checkData, comparingErr = triggerChecker.compareTriggerStates(checkData) - if comparingErr != nil { - triggerChecker.logger.Error(). - Error(comparingErr). - String(moira.LogFieldNameTriggerID, triggerChecker.triggerID). - Msg("cannot compare trigger states") - } - } - - logTriggerCheckException(triggerChecker.logger, triggerChecker.triggerID, err) - - return checkData -} - // handleUndefinedError is a function that check error with undefined type. func (triggerChecker *TriggerChecker) handleUndefinedError(checkData moira.CheckData, err error) error { triggerChecker.metrics.CheckError.Mark(1) diff --git a/checker/check_test.go b/checker/check_test.go index 994d983ea..cc6a880ba 100644 --- a/checker/check_test.go +++ b/checker/check_test.go @@ -2066,7 +2066,7 @@ func TestTriggerChecker_handleFetchError(t *testing.T) { Metric: triggerChecker.trigger.Name, }, true, - ).Return(nil).Times(2) + ).Return(nil).Times(2) // this is strange... why 2? dataBase.EXPECT().SetTriggerLastCheck( triggerChecker.triggerID, &expectedCheckData, @@ -2076,6 +2076,120 @@ func TestTriggerChecker_handleFetchError(t *testing.T) { err := triggerChecker.handleFetchError(newCheckData(triggerChecker.lastCheck, triggerChecker.until), givenErr) So(err, ShouldBeNil) }) + + Convey("time since last successful check < triggerChecker.ttl", func() { + triggerChecker.ttl = 30 + triggerChecker.lastCheck.LastSuccessfulCheckTimestamp = triggerChecker.until - 15 + + expectedCheckData := moira.CheckData{ + Score: 0, + Metrics: triggerChecker.lastCheck.Metrics, + State: triggerChecker.lastCheck.State, + Timestamp: triggerChecker.until, + EventTimestamp: triggerChecker.until, + LastSuccessfulCheckTimestamp: triggerChecker.lastCheck.LastSuccessfulCheckTimestamp, + Message: "", + MetricsToTargetRelation: map[string]string{}, + } + + dataBase.EXPECT().SetTriggerLastCheck( + triggerChecker.triggerID, + &expectedCheckData, + triggerChecker.trigger.ClusterKey(), + ).Return(nil).Times(1) + + err := triggerChecker.handleFetchError(newCheckData(triggerChecker.lastCheck, triggerChecker.until), givenErr) + So(err, ShouldBeNil) + }) + }) + + Convey("with bad functions, problems in expressions, etc", func() { + errorsList := []error{ + local.ErrorUnknownFunction(errors.New("unknown func \"dance\"")), + local.ErrorEvalExpression(errors.New("eval expr"), "badExpr(dancing.mops"), + remote.ErrRemoteTriggerResponse{ + InternalError: errors.New("user write bad target"), + Target: "bad target", + }, + } + + for i, givenErr := range errorsList { + Convey(fmt.Sprintf("Case %v: %T", i+1, givenErr), func() { + expectedCheckData := moira.CheckData{ + Score: int64(100_000), + Metrics: triggerChecker.lastCheck.Metrics, + State: moira.StateEXCEPTION, + Timestamp: triggerChecker.until, + EventTimestamp: triggerChecker.until, + LastSuccessfulCheckTimestamp: triggerChecker.lastCheck.LastSuccessfulCheckTimestamp, + Message: givenErr.Error(), + MetricsToTargetRelation: map[string]string{}, + } + + dataBase.EXPECT().PushNotificationEvent( + &moira.NotificationEvent{ + IsTriggerEvent: true, + TriggerID: triggerChecker.triggerID, + State: moira.StateEXCEPTION, + OldState: triggerChecker.lastCheck.State, + Timestamp: triggerChecker.until, + Metric: triggerChecker.trigger.Name, + }, + true, + ).Return(nil).Times(1) + dataBase.EXPECT().SetTriggerLastCheck( + triggerChecker.triggerID, + &expectedCheckData, + triggerChecker.trigger.ClusterKey(), + ).Return(nil).Times(1) + + err := triggerChecker.handleFetchError(newCheckData(triggerChecker.lastCheck, triggerChecker.until), givenErr) + So(err, ShouldBeNil) + }) + } + }) + + Convey("with undefined err", func() { + givenErr := errors.New("some undefined error") + + checkMetrics, err := metrics.ConfigureCheckerMetrics( + metrics.NewDummyRegistry(), + []moira.ClusterKey{moira.DefaultLocalCluster}, + ).GetCheckMetricsBySource(moira.DefaultLocalCluster) + So(err, ShouldBeNil) + + triggerChecker.metrics = checkMetrics + + expectedCheckData := moira.CheckData{ + Score: int64(100_000), + Metrics: triggerChecker.lastCheck.Metrics, + State: moira.StateEXCEPTION, + Timestamp: triggerChecker.until, + EventTimestamp: triggerChecker.until, + LastSuccessfulCheckTimestamp: triggerChecker.lastCheck.LastSuccessfulCheckTimestamp, + Message: givenErr.Error(), + MetricsToTargetRelation: map[string]string{}, + } + + dataBase.EXPECT().PushNotificationEvent( + &moira.NotificationEvent{ + IsTriggerEvent: true, + TriggerID: triggerChecker.triggerID, + State: moira.StateEXCEPTION, + OldState: triggerChecker.lastCheck.State, + Timestamp: triggerChecker.until, + Metric: triggerChecker.trigger.Name, + }, + true, + ).Return(nil).Times(1) + dataBase.EXPECT().SetTriggerLastCheck( + triggerChecker.triggerID, + &expectedCheckData, + triggerChecker.trigger.ClusterKey(), + ).Return(nil).Times(1) + + err = triggerChecker.handleFetchError(newCheckData(triggerChecker.lastCheck, triggerChecker.until), givenErr) + So(err, ShouldBeNil) }) }) } diff --git a/metric_source/local/errors.go b/metric_source/local/errors.go index b9605024f..c4f43656a 100644 --- a/metric_source/local/errors.go +++ b/metric_source/local/errors.go @@ -58,6 +58,13 @@ type ErrEvalExpr struct { target string } +func ErrorEvalExpression(err error, target string) ErrEvalExpr { + return ErrEvalExpr{ + internalError: err, + target: target, + } +} + // Error is implementation of golang error interface for ErrEvalExpr struct. func (err ErrEvalExpr) Error() string { return fmt.Sprintf("failed to evaluate target '%s': %s", err.target, err.internalError.Error()) diff --git a/metric_source/local/eval.go b/metric_source/local/eval.go index 4b429d189..5b4dacf47 100644 --- a/metric_source/local/eval.go +++ b/metric_source/local/eval.go @@ -95,10 +95,7 @@ func (eval *evaluator) Eval( } else if isErrUnknownFunction(err) { err = ErrorUnknownFunction(err) } else { - err = ErrEvalExpr{ - target: exp.ToString(), - internalError: err, - } + err = ErrorEvalExpression(err, exp.ToString()) } } From a65cc82082dc7cb4237287e542f33b18bba99502 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Tue, 14 Jan 2025 12:18:56 +0700 Subject: [PATCH 5/7] chore: use linter --- checker/check_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/checker/check_test.go b/checker/check_test.go index cc6a880ba..a978a8f2a 100644 --- a/checker/check_test.go +++ b/checker/check_test.go @@ -1934,7 +1934,6 @@ func TestTriggerChecker_handleFetchError(t *testing.T) { dataBase := mock_moira_alert.NewMockDatabase(mockCtrl) logger, _ := logging.GetLogger("Test") - //var retention int64 = 10 metric := "some.metric" testTime := time.Date(2022, time.June, 6, 10, 0, 0, 0, time.UTC).Unix() From 2b0cd50267b8763a0510ebec3582fa845326869c Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Tue, 14 Jan 2025 19:03:19 +0700 Subject: [PATCH 6/7] refactor: switch to EXCEPTION on ErrRemoteUnavailable --- checker/check.go | 23 ++++------- checker/check_test.go | 91 +++++++++++++++---------------------------- 2 files changed, 40 insertions(+), 74 deletions(-) diff --git a/checker/check.go b/checker/check.go index e874e2391..db3e90c6c 100644 --- a/checker/check.go +++ b/checker/check.go @@ -133,22 +133,15 @@ func (triggerChecker *TriggerChecker) handleFetchError(checkData moira.CheckData ) } case remote.ErrRemoteUnavailable: - timeSinceLastSuccessfulCheck := checkData.Timestamp - checkData.LastSuccessfulCheckTimestamp - if timeSinceLastSuccessfulCheck >= triggerChecker.ttl { - checkData.State = moira.StateEXCEPTION - checkData.Message = fmt.Sprintf("Remote server unavailable. Trigger is not checked for %d seconds", timeSinceLastSuccessfulCheck) - - var comparingErr error - checkData, comparingErr = triggerChecker.compareTriggerStates(checkData) - if comparingErr != nil { - triggerChecker.logger.Error(). - Error(comparingErr). - String(moira.LogFieldNameTriggerID, triggerChecker.triggerID). - Msg("cannot compare trigger states") - } - } + checkData.State = moira.StateEXCEPTION + checkData.Message = fmt.Sprintf("Remote server unavailable. Trigger is not checked since: %v", checkData.LastSuccessfulCheckTimestamp) - logTriggerCheckException(triggerChecker.logger, triggerChecker.triggerID, err) + triggerChecker.logger.Error(). + String(moira.LogFieldNameTriggerID, triggerChecker.triggerID). + String("trigger.cluster_id", triggerChecker.trigger.ClusterId.String()). + String("trigger.source", triggerChecker.trigger.TriggerSource.String()). + Error(err). + Msg("Trigger check failed") case local.ErrUnknownFunction, local.ErrEvalExpr, remote.ErrRemoteTriggerResponse: checkData.State = moira.StateEXCEPTION checkData.Message = err.Error() diff --git a/checker/check_test.go b/checker/check_test.go index a978a8f2a..68d26e15c 100644 --- a/checker/check_test.go +++ b/checker/check_test.go @@ -2038,68 +2038,41 @@ func TestTriggerChecker_handleFetchError(t *testing.T) { InternalError: errors.New("some err"), } - Convey("time since last successful check >= triggerChecker.ttl", func() { - triggerChecker.ttl = 10 - triggerChecker.lastCheck.LastSuccessfulCheckTimestamp = triggerChecker.until - 20 + triggerChecker.ttl = 10 + triggerChecker.lastCheck.LastSuccessfulCheckTimestamp = triggerChecker.until - 20 - expectedCheckData := moira.CheckData{ - Score: int64(100_000), - Metrics: triggerChecker.lastCheck.Metrics, - State: moira.StateEXCEPTION, - Timestamp: triggerChecker.until, - EventTimestamp: triggerChecker.until, - LastSuccessfulCheckTimestamp: triggerChecker.lastCheck.LastSuccessfulCheckTimestamp, - Message: fmt.Sprintf( - "Remote server unavailable. Trigger is not checked for %d seconds", - triggerChecker.until-triggerChecker.lastCheck.LastSuccessfulCheckTimestamp), - MetricsToTargetRelation: map[string]string{}, - } - - dataBase.EXPECT().PushNotificationEvent( - &moira.NotificationEvent{ - IsTriggerEvent: true, - TriggerID: triggerChecker.triggerID, - State: moira.StateEXCEPTION, - OldState: triggerChecker.lastCheck.State, - Timestamp: triggerChecker.until, - Metric: triggerChecker.trigger.Name, - }, - true, - ).Return(nil).Times(2) // this is strange... why 2? - dataBase.EXPECT().SetTriggerLastCheck( - triggerChecker.triggerID, - &expectedCheckData, - triggerChecker.trigger.ClusterKey(), - ).Return(nil).Times(1) - - err := triggerChecker.handleFetchError(newCheckData(triggerChecker.lastCheck, triggerChecker.until), givenErr) - So(err, ShouldBeNil) - }) - - Convey("time since last successful check < triggerChecker.ttl", func() { - triggerChecker.ttl = 30 - triggerChecker.lastCheck.LastSuccessfulCheckTimestamp = triggerChecker.until - 15 - - expectedCheckData := moira.CheckData{ - Score: 0, - Metrics: triggerChecker.lastCheck.Metrics, - State: triggerChecker.lastCheck.State, - Timestamp: triggerChecker.until, - EventTimestamp: triggerChecker.until, - LastSuccessfulCheckTimestamp: triggerChecker.lastCheck.LastSuccessfulCheckTimestamp, - Message: "", - MetricsToTargetRelation: map[string]string{}, - } + expectedCheckData := moira.CheckData{ + Score: int64(100_000), + Metrics: triggerChecker.lastCheck.Metrics, + State: moira.StateEXCEPTION, + Timestamp: triggerChecker.until, + EventTimestamp: triggerChecker.until, + LastSuccessfulCheckTimestamp: triggerChecker.lastCheck.LastSuccessfulCheckTimestamp, + Message: fmt.Sprintf( + "Remote server unavailable. Trigger is not checked since: %v", + triggerChecker.lastCheck.LastSuccessfulCheckTimestamp), + MetricsToTargetRelation: map[string]string{}, + } - dataBase.EXPECT().SetTriggerLastCheck( - triggerChecker.triggerID, - &expectedCheckData, - triggerChecker.trigger.ClusterKey(), - ).Return(nil).Times(1) + dataBase.EXPECT().PushNotificationEvent( + &moira.NotificationEvent{ + IsTriggerEvent: true, + TriggerID: triggerChecker.triggerID, + State: moira.StateEXCEPTION, + OldState: triggerChecker.lastCheck.State, + Timestamp: triggerChecker.until, + Metric: triggerChecker.trigger.Name, + }, + true, + ).Return(nil).Times(1) + dataBase.EXPECT().SetTriggerLastCheck( + triggerChecker.triggerID, + &expectedCheckData, + triggerChecker.trigger.ClusterKey(), + ).Return(nil).Times(1) - err := triggerChecker.handleFetchError(newCheckData(triggerChecker.lastCheck, triggerChecker.until), givenErr) - So(err, ShouldBeNil) - }) + err := triggerChecker.handleFetchError(newCheckData(triggerChecker.lastCheck, triggerChecker.until), givenErr) + So(err, ShouldBeNil) }) Convey("with bad functions, problems in expressions, etc", func() { From ef3e89d009a280e19760088b62dcd48deb0cc3a3 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Wed, 15 Jan 2025 15:31:14 +0700 Subject: [PATCH 7/7] docs: godoc for error creating func --- metric_source/local/errors.go | 1 + 1 file changed, 1 insertion(+) diff --git a/metric_source/local/errors.go b/metric_source/local/errors.go index c4f43656a..da14cefd9 100644 --- a/metric_source/local/errors.go +++ b/metric_source/local/errors.go @@ -58,6 +58,7 @@ type ErrEvalExpr struct { target string } +// ErrorEvalExpression creates ErrEvalExpr with given err and target. func ErrorEvalExpression(err error, target string) ErrEvalExpr { return ErrEvalExpr{ internalError: err,