You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.9 KiB
89 lines
2.9 KiB
|
2 months ago
|
package mock
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"tera-clone/services/tera-api/internal/domain"
|
||
|
|
"tera-clone/services/tera-api/internal/logstorage"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestReceivedKeywordFromSerialJournalNotDependentOnLogViewer(t *testing.T) {
|
||
|
|
journal := &sequencedMemoryJournal{}
|
||
|
|
delivery := &recordingAlarmDeliveryController{}
|
||
|
|
store, err := NewStoreWithOptions(fixedClock, StoreOptions{LogJournal: journal, AlarmDeliveryController: delivery})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
rule := store.runningAlarms["port_ch20_keyword"]
|
||
|
|
rule.Enabled = true
|
||
|
|
rule.Trigger = "Invalid interface"
|
||
|
|
rule.Delivery = []string{"web"}
|
||
|
|
store.runningAlarms["port_ch20_keyword"] = rule
|
||
|
|
now := fixedClock()
|
||
|
|
appendRX := func(channel, direction, text string, matched bool) {
|
||
|
|
t.Helper()
|
||
|
|
now = now.Add(time.Millisecond)
|
||
|
|
event := domain.PortLogEvent{Timestamp: now, Channel: channel, EventType: "traffic", Direction: direction, Actor: "tera-port-service", Message: "serial payload", Payload: []byte(text), PayloadBytes: len(text), PayloadEncoding: "base64", DisplayFormat: "ascii", AlarmTriggered: matched}
|
||
|
|
if err := journal.Append(logstorage.ClassPort, now, event); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
evaluate := func() {
|
||
|
|
t.Helper()
|
||
|
|
if err := store.EvaluateOperationalAlarms(context.Background()); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
appendRX("CH20", "RX", "Invalid interface", false)
|
||
|
|
evaluate()
|
||
|
|
if len(delivery.requests) != 0 {
|
||
|
|
t.Fatal("replayed old history on startup")
|
||
|
|
}
|
||
|
|
appendRX("CH20", "TX", "Invalid interface", false)
|
||
|
|
appendRX("CH19", "RX", "Invalid interface", false)
|
||
|
|
evaluate()
|
||
|
|
if len(delivery.requests) != 0 {
|
||
|
|
t.Fatal("matched wrong channel or TX")
|
||
|
|
}
|
||
|
|
appendRX("CH20", "RX", "\r\nInvalid inter", false)
|
||
|
|
evaluate()
|
||
|
|
if len(delivery.requests) != 0 {
|
||
|
|
t.Fatal("matched incomplete keyword")
|
||
|
|
}
|
||
|
|
appendRX("CH20", "RX", "face\r\nEnter interface name", false)
|
||
|
|
// A UI read advances its own journal cursor before the alarm evaluator.
|
||
|
|
if _, err := store.PortLogEvents(context.Background(), domain.PortLogFilter{Channel: "CH20"}); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
evaluate()
|
||
|
|
evaluate()
|
||
|
|
if len(delivery.requests) != 1 || delivery.requests[0].RuleID != "port_ch20_keyword" {
|
||
|
|
t.Fatalf("requests=%+v", delivery.requests)
|
||
|
|
}
|
||
|
|
appendRX("CH20", "RX", "more prompt output", false)
|
||
|
|
appendRX("CH20", "RX", "Invalid interface", true)
|
||
|
|
evaluate()
|
||
|
|
if len(delivery.requests) != 1 {
|
||
|
|
t.Fatal("duplicate match or already processed API event")
|
||
|
|
}
|
||
|
|
rule.Enabled = false
|
||
|
|
store.runningAlarms["port_ch20_keyword"] = rule
|
||
|
|
appendRX("CH20", "RX", "Invalid interface", false)
|
||
|
|
evaluate()
|
||
|
|
if len(delivery.requests) != 1 {
|
||
|
|
t.Fatal("disabled rule fired")
|
||
|
|
}
|
||
|
|
rule.Enabled = true
|
||
|
|
rule.Trigger = "NEW KEYWORD"
|
||
|
|
store.runningAlarms["port_ch20_keyword"] = rule
|
||
|
|
appendRX("CH20", "RX", "Invalid interface", false)
|
||
|
|
evaluate()
|
||
|
|
appendRX("CH20", "RX", "new keyword", false)
|
||
|
|
evaluate()
|
||
|
|
if len(delivery.requests) != 2 {
|
||
|
|
t.Fatal("updated case insensitive keyword not observed")
|
||
|
|
}
|
||
|
|
}
|