alerter/fake.go (99 lines of code) (raw):

package alerter import ( "context" "encoding/json" "flag" "io" "net/http" "strings" "github.com/Azure/adx-mon/alerter/alert" "github.com/Azure/adx-mon/pkg/logger" "github.com/Azure/azure-kusto-go/kusto" "github.com/Azure/azure-kusto-go/kusto/data/table" "github.com/Azure/azure-kusto-go/kusto/data/types" "github.com/Azure/azure-kusto-go/kusto/data/value" ) const icmTitleMaxLength = 150 type fakeKustoClient struct { endpoint string } func (f fakeKustoClient) Mgmt(ctx context.Context, db string, query kusto.Stmt, options ...kusto.MgmtOption) (*kusto.RowIterator, error) { return nil, nil } func (f fakeKustoClient) Query(ctx context.Context, db string, query kusto.Stmt, options ...kusto.QueryOption) (*kusto.RowIterator, error) { iter := &kusto.RowIterator{} rows, err := kusto.NewMockRows(table.Columns{ {Name: "Title", Type: types.String}, {Name: "Severity", Type: types.Long}, {Name: "Summary", Type: types.String}, {Name: "CorrelationId", Type: types.String}, }) if err != nil { return nil, err } rows.Row(value.Values{ value.String{Value: "Fake Alert", Valid: true}, value.Long{Value: 1, Valid: true}, value.String{Value: "Fake Alert Summary", Valid: true}, value.String{Value: "Fake CorrelationId", Valid: true}, }) // Work-around to prevent the iter.Mock call from panicing because it's not running in a test. if flag.Lookup("test.v") == nil { flag.String("test.v", "", "") if err := flag.CommandLine.Set("test.v", "true"); err != nil { panic(err) } } if err := iter.Mock(rows); err != nil { panic(err) } return iter, nil } func (f fakeKustoClient) Endpoint() string { return f.endpoint } func fakeAlertHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { b, err := io.ReadAll(r.Body) if err != nil { logger.Errorf("Failed to read request body: %s", err) w.WriteHeader(http.StatusInternalServerError) return } a := alert.Alert{} if err := json.Unmarshal(b, &a); err != nil { logger.Errorf("Failed to unmarshal request body: %s", err) w.WriteHeader(http.StatusBadRequest) return } logger.Infof("Fake Alert Notification Recieved: %v", a) w.WriteHeader(http.StatusCreated) }) } type lintAlertHandler struct { alertCount map[string]int hasFailedQueries bool } func NewLinter() *lintAlertHandler { return &lintAlertHandler{ alertCount: make(map[string]int), } } // Create implements the alert.Client interface for testing purposes. // It logs out the type of failure and tracks that we have had failed queries. func (lh *lintAlertHandler) Create(ctx context.Context, endpoint string, alert alert.Alert) error { lh.alertCount[alert.CorrelationID]++ if len(alert.Title) > icmTitleMaxLength { logger.Errorf("Title Exceeded Max Length: %s", alert.Title) lh.hasFailedQueries = true } if strings.HasPrefix(alert.CorrelationID, "alert-failure") { lh.hasFailedQueries = true } return nil } func (lh *lintAlertHandler) HasFailedQueries() bool { return lh.hasFailedQueries } func (lh *lintAlertHandler) Log() { for k, v := range lh.alertCount { logger.Infof("Alert %s was sent %d times", k, v) } }