nezha/model/alertrule_test.go
UUBulb 79884c781a
Some checks are pending
CodeQL / Analyze (go) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
Contributors / contributors (push) Waiting to run
Sync / sync-to-jihulab (push) Waiting to run
Run Tests / tests (macos) (push) Waiting to run
Run Tests / tests (ubuntu) (push) Waiting to run
Run Tests / tests (windows) (push) Waiting to run
fix: ignore the duration of out-of-bound rules (#1019)
2025-03-07 20:23:18 +08:00

311 lines
5.2 KiB
Go

package model
import (
"slices"
"testing"
)
type arSt struct {
msg string
rule *AlertRule
points [][]bool
expD int
exp bool
}
func TestCycleRules(t *testing.T) {
cases := []arSt{
{
rule: &AlertRule{
Rules: []*Rule{
{
Type: "_cycle",
},
},
},
msg: "CyclePass",
points: [][]bool{{false}, {true}},
expD: 1,
exp: true,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Type: "_cycle",
},
},
},
msg: "CycleFail",
points: [][]bool{{true}, {false}},
expD: 1,
exp: false,
},
}
for _, c := range cases {
d, passed := c.rule.Check(c.points)
assertEq(t, c.msg, c.expD, d)
assertEq(t, c.msg, c.exp, passed)
}
}
func TestOfflineRules(t *testing.T) {
cases := []arSt{
{
rule: &AlertRule{
Rules: []*Rule{
{
Type: "offline",
Duration: 10,
},
},
},
msg: "OfflineLast",
points: append([][]bool{{true}}, repeat([]bool{false}, 9)...),
expD: 10,
exp: true,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Type: "offline",
Duration: 10,
},
},
},
msg: "OfflineMiddle",
points: mod(repeat([]bool{false}, 10), true, 5),
expD: 5,
exp: true,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Type: "offline",
Duration: 10,
},
},
},
msg: "OfflineFirst",
points: mod(repeat([]bool{false}, 10), true, 9),
expD: 1,
exp: true,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Type: "offline",
Duration: 10,
},
},
},
msg: "OfflineBoundCheck",
points: repeat([]bool{false}, 9),
expD: 0,
exp: true,
},
}
for _, c := range cases {
d, passed := c.rule.Check(c.points)
assertEq(t, c.msg, c.expD, d)
assertEq(t, c.msg, c.exp, passed)
}
}
func TestGeneralRules(t *testing.T) {
cases := []arSt{
{
rule: &AlertRule{
Rules: []*Rule{
{
Duration: 10,
},
},
},
msg: "GeneralFail",
points: repeat([]bool{false}, 10),
expD: 10,
exp: false,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Duration: 10,
},
},
},
msg: "GeneralFail80%",
points: slices.Concat(repeat([]bool{false}, 8), repeat([]bool{true}, 2)),
expD: 10,
exp: false,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Duration: 10,
},
},
},
msg: "GeneralPass30%",
points: slices.Concat(repeat([]bool{false}, 7), repeat([]bool{true}, 3)),
expD: 10,
exp: true,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Duration: 10,
},
},
},
msg: "GeneralPass",
points: slices.Concat(repeat([]bool{false}, 4), repeat([]bool{true}, 6)),
expD: 10,
exp: true,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Duration: 10,
},
},
},
msg: "GeneralBoundCheck",
points: repeat([]bool{false}, 9),
expD: 0,
exp: true,
},
}
for _, c := range cases {
d, passed := c.rule.Check(c.points)
assertEq(t, c.msg, c.expD, d)
assertEq(t, c.msg, c.exp, passed)
}
}
func TestCombinedRules(t *testing.T) {
cases := []arSt{
{
rule: &AlertRule{
Rules: []*Rule{
{
Type: "offline",
Duration: 10,
},
{
Duration: 10,
},
},
},
msg: "OfflineGeneralOfflinePass",
points: slices.Concat(repeat([]bool{false, true}, 2), repeat([]bool{true, false}, 8)),
expD: 1,
exp: true,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Type: "offline",
Duration: 10,
},
{
Duration: 10,
},
},
},
msg: "OfflineGeneralOfflineFail",
points: slices.Concat(repeat([]bool{false, false}, 2), repeat([]bool{false, true}, 8)),
expD: 10,
exp: true,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Duration: 10,
},
{
Type: "offline",
Duration: 10,
},
},
},
msg: "GeneralOffline",
points: slices.Concat(repeat([]bool{false, true}, 2), repeat([]bool{true, false}, 8)),
expD: 10,
exp: true,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Duration: 10,
},
{
Duration: 30,
},
},
},
msg: "GeneralGeneral",
points: slices.Concat(repeat([]bool{false, true}, 2), repeat([]bool{false, false}, 28)),
expD: 30,
exp: false,
},
{
rule: &AlertRule{
Rules: []*Rule{
{
Duration: 10,
},
{
Duration: 30,
},
},
},
msg: "CombinedBoundCheck",
points: slices.Concat(repeat([]bool{false, true}, 2), repeat([]bool{false, false}, 27)),
expD: 10,
exp: true,
},
}
for _, c := range cases {
d, passed := c.rule.Check(c.points)
assertEq(t, c.msg, c.expD, d)
assertEq(t, c.msg, c.exp, passed)
}
}
func repeat[S ~[]E, E any](x S, count int) []S {
var slices []S
for range count {
tmp := make([]E, len(x))
copy(tmp, x)
slices = append(slices, tmp)
}
return slices
}
func mod[S ~[][]E, E any](x S, val E, i int) S {
x[i][0] = val
return x
}
func assertEq(t *testing.T, msg string, exp, act any) {
t.Helper()
if exp != act {
t.Fatalf("failed to test for %s. exp=[%v] but act=[%v]", msg, exp, act)
}
}