// Case anomaly after an anomaly. func TestAnomalyAfterBigAnomaly(t *testing.T) { wf := 0.05 leastC := 18 c := New(wf, leastC) l := genMetrics(120.0, 140.0, 100) var s *models.State for _, m := range l { s = c.Next(s, m) assert.Ok(t, !m.IsAnomalous()) } // Give a big anomaly m := &models.Metric{Value: 2000} s = c.Next(s, m) assert.Ok(t, m.IsAnomalousTrendUp()) // Test up and down anomaly m = &models.Metric{Value: 190} s = c.Next(s, m) assert.Ok(t, m.IsAnomalousTrendUp()) m = &models.Metric{Value: 80} s = c.Next(s, m) assert.Ok(t, m.IsAnomalousTrendDown()) // Test normal m = &models.Metric{Value: 130} s = c.Next(s, m) assert.Ok(t, !m.IsAnomalous()) }
func TestToFixed(t *testing.T) { assert.Ok(t, ToFixed(1.2345, 2) == "1.23") assert.Ok(t, ToFixed(10000.12121121, 5) == "10000.12121") assert.Ok(t, ToFixed(102, 3) == "102") assert.Ok(t, ToFixed(102.22, 3) == "102.22") assert.Ok(t, ToFixed(100, 3) == "100") }
func TestPut(t *testing.T) { // Open db. fileName := "db-testing" db, _ := Open(fileName) defer os.RemoveAll(fileName) defer db.Close() // Put. m := &models.Metric{ Name: "foo", Stamp: 1452758773, Value: 3.14, Score: 0.1892, Average: 3.133, } err := db.Put(m) assert.Ok(t, err == nil) // Must in db key := encodeKey(m) value, err := db.db.Get(key, nil) assert.Ok(t, err == nil) m1 := &models.Metric{ Name: m.Name, Stamp: m.Stamp, } err = decodeValue(value, m1) assert.Ok(t, err == nil) assert.Ok(t, reflect.DeepEqual(m, m1)) }
func TestHitLimit(t *testing.T) { // Currently disable logging log.Disable() defer log.Enable() //New and add rules. config := config.New() config.Interval = 1 rule1 := &models.Rule{Pattern: "a.*.c.d"} filter := New() filter.addRule(rule1) filter.SetHitLimit(config) for i := 0; i < config.Detector.IntervalHitLimit; i++ { //hit rule when counter < intervalHitLimit rules := filter.MatchedRules(&models.Metric{Name: "a.b.c.d"}) assert.Ok(t, 1 == len(rules)) } //counter over limit, matched rules = 0 rules := filter.MatchedRules(&models.Metric{Name: "a.b.c.d"}) assert.Ok(t, 0 == len(rules)) time.Sleep(time.Second * 2) //after interval counter is cleared, matched rules = 1 rules = filter.MatchedRules(&models.Metric{Name: "a.b.c.d"}) assert.Ok(t, 1 == len(rules)) }
func TestExampleConfigParsing(t *testing.T) { config := New() err := config.UpdateWithJSONFile("./exampleConfig.json") assert.Ok(t, err == nil) defaults := New() assert.Ok(t, reflect.DeepEqual(config, defaults)) }
func TestDecodeKey(t *testing.T) { key := []byte("foo000001f") m := &models.Metric{} err := decodeKey(key, m) assert.Ok(t, err == nil) assert.Ok(t, m.Name == "foo") assert.Ok(t, m.Stamp == 36+0xf+horizon) }
func TestOpen(t *testing.T) { fileName := "db-testing" db, err := Open(fileName) assert.Ok(t, err == nil) assert.Ok(t, util.IsFileExist(fileName)) db.Close() os.RemoveAll(fileName) }
func TestParseMetric(t *testing.T) { line := "foo 1449655769 3.14" m, err := parseMetric(line) assert.Ok(t, err == nil) assert.Ok(t, m.Name == "foo") assert.Ok(t, m.Stamp == uint32(1449655769)) assert.Ok(t, m.Value == 3.14) }
func TestOpen(t *testing.T) { fileName := "db-testing" db, err := Open(fileName, &Options{288, 300}) defer db.Close() defer os.RemoveAll(fileName) assert.Ok(t, err == nil) assert.Ok(t, util.IsFileExist(fileName)) }
func TestDecodeValue(t *testing.T) { m := &models.Metric{} value := []byte("1.23:0.72:0.79") err := decodeValue(value, m) assert.Ok(t, err == nil) assert.Ok(t, m.Value == 1.23) assert.Ok(t, m.Score == 0.72) assert.Ok(t, m.Average == 0.79) }
func TestDecode(t *testing.T) { s := "1450422576:1.2:3.1" idx := &models.Index{} err := decode([]byte(s), idx) assert.Ok(t, err == nil) assert.Ok(t, idx.Stamp == 1450422576) assert.Ok(t, idx.Score == 1.2) assert.Ok(t, idx.Average == 3.1) }
func TestStampLenEnoughToUse(t *testing.T) { stamp := uint32(90*365*24*60*60) + horizon m := &models.Metric{Name: "foo", Stamp: stamp} key := encodeKey(m) n := &models.Metric{} err := decodeKey(key, n) assert.Ok(t, err == nil) assert.Ok(t, n.Name == m.Name) assert.Ok(t, n.Stamp == m.Stamp) }
func TestMakeEventID(t *testing.T) { // Metric with the same name but different stamps. m1 := &models.Metric{Name: "foo", Stamp: 1456815973} m2 := &models.Metric{Name: "foo", Stamp: 1456815974} assert.Ok(t, makeEventID(m1) != makeEventID(m2)) // Metric with the same stamp but different names. m1 = &models.Metric{Name: "foo", Stamp: 1456815973} m2 = &models.Metric{Name: "bar", Stamp: 1456815973} assert.Ok(t, makeEventID(m1) != makeEventID(m2)) }
func TestGenerateID(t *testing.T) { // Metric with the same name but different stamps. ev1 := NewEvent(&Metric{Name: "foo", Stamp: 1456815973}, nil) ev2 := NewEvent(&Metric{Name: "foo", Stamp: 1456815974}, nil) assert.Ok(t, ev1.ID != ev2.ID) // Metric with the same stamp but different names. ev1 = NewEvent(&Metric{Name: "foo", Stamp: 1456815973}, nil) ev2 = NewEvent(&Metric{Name: "bar", Stamp: 1456815973}, nil) assert.Ok(t, ev1.ID != ev2.ID) }
func TestEncoding(t *testing.T) { idx := &models.Index{Stamp: 1450426828, Score: 0.678888, Average: 877.234} value := encode(idx) idx1 := &models.Index{} err := decode(value, idx1) assert.Ok(t, err == nil) assert.Ok(t, idx1.Stamp == idx.Stamp) assert.Ok(t, idx1.Score == 0.67889) assert.Ok(t, idx1.Average == 877.234) }
// Case count not enough func TestNotEnough(t *testing.T) { wf := 0.05 leastC := 18 c := New(wf, leastC) s := &models.State{Count: leastC - 1, Average: 0.1, StdDev: 0.1} m := &models.Metric{Value: 0.1} n := c.Next(s, m) assert.Ok(t, m.Score == 0) assert.Ok(t, n.Count == leastC) }
func TestDecodeValue(t *testing.T) { // New DB just for testing db := &DB{numGrid: 288, gridLen: 300} // Test value := []byte("123.12:1.23333:19") s, err := db.decodeValue(value) assert.Ok(t, err == nil) assert.Ok(t, s.Average == 123.12) assert.Ok(t, s.StdDev == 1.23333) assert.Ok(t, s.Count == 19) }
// Case as first func TestAsFirst(t *testing.T) { wf := 0.05 leastC := 18 c := New(wf, leastC) m := &models.Metric{Value: 1.32} s := c.Next(nil, m) assert.Ok(t, m.Average == m.Value) assert.Ok(t, m.Score == 0) assert.Ok(t, s.Count == 1) assert.Ok(t, s.StdDev == 0) }
func TestValueEncoding(t *testing.T) { // New DB just for testing db := &DB{numGrid: 288, gridLen: 300} // Test s := &models.State{Average: 182.092, StdDev: 1.3, Count: 18} value := db.encodeValue(s) n, err := db.decodeValue(value) assert.Ok(t, err == nil) assert.Ok(t, n.Average == s.Average) assert.Ok(t, n.StdDev == s.StdDev) assert.Ok(t, n.Count == s.Count) }
func TestEncodeKey(t *testing.T) { // New DB just for testing db := &DB{numGrid: 288, gridLen: 300} period := db.numGrid * db.gridLen // Test m := &models.Metric{Name: "foo", Stamp: 1450429041} gridNo := db.getGridNo(m) s := fmt.Sprintf("foo:%d", gridNo) assert.Ok(t, s == string(db.encodeKey(m))) m.Stamp += uint32(period) assert.Ok(t, s == string(db.encodeKey(m))) }
func TestRuleBuildRepr(t *testing.T) { var rule *Rule // TrendUp rule = &Rule{TrendUp: true} rule.BuildRepr() assert.Ok(t, rule.Repr == "trend ↑") // TrendDown rule = &Rule{TrendDown: true} rule.BuildRepr() assert.Ok(t, rule.Repr == "trend ↓") // TrendUp Or TrendDown rule = &Rule{TrendUp: true, TrendDown: true} rule.BuildRepr() assert.Ok(t, rule.Repr == "trend ↑ || trend ↓") // Value >= X rule = &Rule{ThresholdMax: 3.1478} rule.BuildRepr() assert.Ok(t, rule.Repr == "value >= 3.148") // Value <= X rule = &Rule{ThresholdMin: 3.1478} rule.BuildRepr() assert.Ok(t, rule.Repr == "value <= 3.148") // TrendUp and Value >= X rule = &Rule{TrendUp: true, ThresholdMax: 1.29} rule.BuildRepr() assert.Ok(t, rule.Repr == "(trend ↑ && value >= 1.29)") // (TrendUp And Value >= X) Or TrendDown rule = &Rule{TrendDown: true, TrendUp: true, ThresholdMax: 2223.8} rule.BuildRepr() assert.Ok(t, rule.Repr == "(trend ↑ && value >= 2223.8) || trend ↓") // (TrendUp And Value >= X) Or (TrendDown And Value <= X) rule = &Rule{TrendUp: true, ThresholdMax: 18987, TrendDown: true, ThresholdMin: 781} rule.BuildRepr() assert.Ok(t, rule.Repr == "(trend ↑ && value >= 18987) || (trend ↓ && value <= 781)") }
func TestOpen(t *testing.T) { // Open db. fileName := "storage_test" db, err := Open(fileName) assert.Ok(t, err == nil) assert.Ok(t, db != nil) // Defer close and remove files. defer db.Close() defer os.RemoveAll(fileName) // Check if child db file exist assert.Ok(t, util.IsFileExist(path.Join(fileName, admindbFileName))) assert.Ok(t, util.IsFileExist(path.Join(fileName, indexdbFileName))) assert.Ok(t, util.IsFileExist(path.Join(fileName, metricdbFileName))) }
func TestGirdNo(t *testing.T) { // New DB just for testing db := &DB{numGrid: 288, gridLen: 300} period := db.numGrid * db.gridLen // Consistence p := &models.Metric{Stamp: 1450428723} q := &models.Metric{Stamp: p.Stamp + uint32(period)} assert.Ok(t, db.getGridNo(p) == db.getGridNo(p)) assert.Ok(t, db.getGridNo(q) == db.getGridNo(p)) // Correcty m := &models.Metric{Stamp: 1450429041} n := &models.Metric{Stamp: m.Stamp + uint32(db.gridLen)} i := db.getGridNo(m) j := db.getGridNo(n) assert.Ok(t, i+1 == j || (i == db.numGrid-1 && j == 0)) }
func TestFilter(t *testing.T) { // Open db. fileName := "db-testing" db, _ := Open(fileName) defer db.Close() defer os.RemoveAll(fileName) // Add indexes. excludeName := "abfxyz" db.Put(&models.Index{Name: "abcefg"}) db.Put(&models.Index{Name: "abcxyz"}) db.Put(&models.Index{Name: excludeName}) // Filter l := db.Filter("abc*") assert.Ok(t, len(l) == 2) assert.Ok(t, l[0].Name != excludeName && l[1].Name != excludeName) }
// Case test random value range cover negative zone func TestNegativeValue(t *testing.T) { wf := 0.05 leastC := 18 c := New(wf, leastC) l := genMetrics(-210.0, -190.0, 60) var s *models.State for _, m := range l { s = c.Next(s, m) assert.Ok(t, !m.IsAnomalous()) } l = genMetricsAroundTrendUpline(-200.0, -100.0, 10.0, 60) for _, m := range l { s = c.Next(s, m) assert.Ok(t, !m.IsAnomalous()) } }
func TestTranslateRuleComment(t *testing.T) { m := &Metric{Name: "timer.count_ps.foo.bar"} r := &Rule{Pattern: "timer.count_ps.*.*", Comment: "$1 and $2 timing"} ev := &Event{Metric: m, Rule: r} ev.TranslateRuleComment() excepted := "foo and bar timing" assert.Ok(t, ev.RuleTranslatedComment == excepted) }
func TestEncodeValue(t *testing.T) { // New DB just for testing db := &DB{numGrid: 288, gridLen: 300} // Test s := &models.State{Average: 891.232898, StdDev: 1.2, Count: 123} v := "891.2329:1.2:123" assert.Ok(t, v == string(db.encodeValue(s))) }
func TestTranslateRuleCommentNoVariables(t *testing.T) { m := &Metric{Name: "foo.bar"} r := &Rule{Pattern: "foo.*", Comment: "no variables"} ev := &Event{Metric: m, Rule: r} ev.TranslateRuleComment() excepted := "no variables" assert.Ok(t, ev.RuleTranslatedComment == excepted) }
func TestInit(t *testing.T) { fileName := "db-testing" db, _ := Open(fileName) defer db.Close() defer os.RemoveAll(fileName) rule := &models.Rule{Pattern: "a.b.*"} // Add one to db. db.DB().Create(rule) // Clear cache. db.RulesCache.rules.Clear() // Reload assert.Ok(t, nil == db.RulesCache.Init(db.DB())) // Get rule r, ok := db.RulesCache.Get(rule.ID) assert.Ok(t, ok) assert.Ok(t, r.Pattern == rule.Pattern) }
func TestGet(t *testing.T) { // Open db. fileName := "db-testing" db, _ := Open(fileName) defer db.Close() defer os.RemoveAll(fileName) // Not found. _, err := db.Get("Not-exist") assert.Ok(t, ErrNotFound == err) // Put one. idx := &models.Index{Name: "foo", Stamp: 1450430837, Score: 0.3, Average: 100} db.Put(idx) // Get it from cache. i, err := db.Get(idx.Name) assert.Ok(t, nil == err) assert.Ok(t, i.Equal(idx)) }