func TestPut(t *testing.T) { // Open db. fileName := "db-testing" opts := &Options{Period: 86400, Expiration: 86400 * 7} db, _ := Open(fileName, opts) defer os.RemoveAll(fileName) defer db.Close() // Put. m := &models.Metric{ Name: "foo", Link: 1, Stamp: 1452758773, Value: 3.14, Score: 0.1892, Average: 3.133, } err := db.Put(m) util.Must(t, err == nil) // Must in db key := encodeKey(m) value, err := db.pool[0].db.Get(key, nil) util.Must(t, err == nil) m1 := &models.Metric{ Name: m.Name, Stamp: m.Stamp, Link: 1, } err = decodeValue(value, m1) util.Must(t, err == nil) util.Must(t, reflect.DeepEqual(m, m1)) }
func TestStorageExpire(t *testing.T) { // Open db. fileName := "db-testing" opts := &Options{Period: 86400, Expiration: 86400 * 7} db, _ := Open(fileName, opts) defer os.RemoveAll(fileName) defer db.Close() // Force creating 7+1 storages. base := uint32(time.Now().Unix()) db.Put(&EventWrapper{ID: "20160525155730.1", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base}) // 0 id := db.pool[0].id // record the id to be deleted db.Put(&EventWrapper{ID: "20160525155730.2", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*1}) // 1 db.Put(&EventWrapper{ID: "20160525155730.3", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*2}) // 2 db.Put(&EventWrapper{ID: "20160525155730.4", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*3}) // 3 db.Put(&EventWrapper{ID: "20160525155730.5", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*4}) // 4 db.Put(&EventWrapper{ID: "20160525155730.6", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*5}) // 5 db.Put(&EventWrapper{ID: "20160525155730.7", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*6}) // 6 util.Must(t, len(db.pool) == 7) db.Put(&EventWrapper{ID: "20160525155730.8", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*7}) // 7 util.Must(t, len(db.pool) == 8) db.Put(&EventWrapper{ID: "20160525155730.9", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*8}) // 8 util.Must(t, len(db.pool) == 8) // Full storages: 1,2,3,4,5,6,7 // Files must be deleted. deleteFileName := path.Join(fileName, strconv.FormatUint(uint64(id), 10)) util.Must(t, !util.IsFileExist(deleteFileName)) }
func TestExampleConfigParsing(t *testing.T) { c := New() err := c.UpdateWithYamlFile("./exampleConfig.yaml") util.Must(t, err == nil) defaults := New() util.Must(t, reflect.DeepEqual(c, defaults)) }
func TestStorageExpire(t *testing.T) { // Open db. fileName := "db-testing" opts := &Options{Period: 86400, Expiration: 86400 * 7} db, _ := Open(fileName, opts) defer os.RemoveAll(fileName) defer db.Close() // Force creating 7+1 storages. base := uint32(time.Now().Unix()) db.Put(&models.Metric{Link: 1, Stamp: base}) // 0 id := db.pool[0].id // record the id to be deleted db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*1}) // 1 db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*2}) // 2 db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*3}) // 3 db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*4}) // 4 db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*5}) // 5 db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*6}) // 6 util.Must(t, len(db.pool) == 7) db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*7}) // 7 util.Must(t, len(db.pool) == 8) db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*8}) // 8 util.Must(t, len(db.pool) == 8) // Full storages: 1,2,3,4,5,6,7 // Files must be deleted. deleteFileName := path.Join(fileName, strconv.FormatUint(uint64(id), 10)) util.Must(t, !util.IsFileExist(deleteFileName)) }
func TestOpen(t *testing.T) { fileName := "db-testing" db, err := Open(fileName, nil) util.Must(t, err == nil) util.Must(t, util.IsFileExist(fileName)) db.Close() os.RemoveAll(fileName) }
func TestParseMetric(t *testing.T) { line := "foo 1449655769 3.14" m, err := parseMetric(line) util.Must(t, err == nil) util.Must(t, m.Name == "foo") util.Must(t, m.Stamp == uint32(1449655769)) util.Must(t, m.Value == 3.14) }
func TestOpenOptionsNil(t *testing.T) { fileName := "db-testing" db, err := Open(fileName, nil) util.Must(t, err == nil) util.Must(t, util.IsFileExist(fileName)) defer os.RemoveAll(fileName) defer db.Close() util.Must(t, len(db.pool) == 0) // should have nothing in pool.. }
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) util.Must(t, err == nil) util.Must(t, idx1.Stamp == idx.Stamp) util.Must(t, idx1.Score == 0.678888) util.Must(t, idx1.Average == 877.234) }
func TestLoad(t *testing.T) { fileName := "db-testing" db, _ := Open(fileName, nil) defer os.RemoveAll(fileName) defer db.Close() idx := &models.Index{Name: "foo", Stamp: 1450430839, Score: 0.7, Average: 78.5} // Add one db.Put(idx) util.Must(t, db.tr.Has(idx.Name)) util.Must(t, idx.Link == 1) // the first link // Clear cache db.tr.Clear() db.idp.Clear() util.Must(t, db.tr.Len() == 0) util.Must(t, !db.tr.Has(idx.Name)) // Reload db.load() // Must not empty and idx in cache util.Must(t, db.tr.Len() == 1) util.Must(t, db.tr.Has(idx.Name)) t.Logf("idp len: %v", db.idp.Len()) util.Must(t, db.idp.Len() == 1) // Get again. i, err := db.Get(idx.Name) util.Must(t, err == nil && i.Equal(idx)) util.Must(t, i.Link == 1) // link should be correct }
func TestEventGenerateID(t *testing.T) { rule := &Rule{ID: 1} // Metric with the same name but different stamps. ev1 := NewEvent(&Metric{Name: "foo", Stamp: 1456815973}, nil, rule) ev2 := NewEvent(&Metric{Name: "foo", Stamp: 1456815974}, nil, rule) util.Must(t, ev1.ID != ev2.ID) // Metric with the same stamp but different names. ev1 = NewEvent(&Metric{Name: "foo", Stamp: 1456815973}, nil, rule) ev2 = NewEvent(&Metric{Name: "bar", Stamp: 1456815973}, nil, rule) util.Must(t, ev1.ID != ev2.ID) }
func TestClear(t *testing.T) { tr := New() // Case simple. tr.Put("a.b.c.d", 4) tr.Put("a.b.c.d.e", 5) tr.Put("a.b.c.d.e.f", 6) util.Must(t, tr.Len() == 3) tr.Clear() util.Must(t, tr.Len() == 0) util.Must(t, !tr.Has("a.b.c.d")) }
func TestPickTrendingFactor(t *testing.T) { cfg := config.New() d := &Detector{cfg: cfg} rules := []*models.Rule{ &models.Rule{Level: models.RuleLevelLow}, } util.Must(t, d.pickTrendingFactor(rules) == cfg.Detector.TrendingFactorLowLevel) rules = append(rules, &models.Rule{Level: models.RuleLevelMiddle}) util.Must(t, d.pickTrendingFactor(rules) == cfg.Detector.TrendingFactorMiddleLevel) rules = append(rules, &models.Rule{Level: models.RuleLevelHigh}) util.Must(t, d.pickTrendingFactor(rules) == cfg.Detector.TrendingFactorHighLevel) }
func TestAlertRecordAlertNotifyAfterConfigSetNotifyAfterToOne(t *testing.T) { cfg := config.New() cfg.Alerter.NotifyAfter = 1 a := &Alerter{cfg: cfg, alertRecords: safemap.New(), lock: &sync.RWMutex{}} metrics := &models.Metric{Name: "test", Stamp: 80, Value: 80} util.Must(t, a.checkAlertCount(metrics)) a.setAlertRecord(metrics) metrics.Stamp = 81 util.Must(t, !a.checkAlertCount(metrics)) a.setAlertRecord(metrics) }
func TestDelete(t *testing.T) { // Open db. fileName := "db-testing" db, _ := Open(fileName, nil) defer os.RemoveAll(fileName) defer db.Close() // Add one. idx := &models.Index{Name: "foo", Stamp: 1450430837, Score: 0.3, Average: 100} db.Put(idx) // Must in cache. util.Must(t, db.tr.Has(idx.Name)) util.Must(t, db.idp.Len() == 1) util.Must(t, idx.Link == 1) // Delete it. err := db.Delete(idx.Name) util.Must(t, err == nil) // Must not exist in cache util.Must(t, !db.tr.Has(idx.Name)) // Must not in db. _, err = db.db.Get([]byte(idx.Name), nil) util.Must(t, err == leveldb.ErrNotFound) // Must not in link pool. util.Must(t, db.idp.Len() == 0) // Cant get again. _, err = db.Get(idx.Name) util.Must(t, ErrNotFound == err) }
func TestMap(t *testing.T) { tr := New() // Case empty. util.Must(t, len(tr.Map()) == 0) // Case simple. tr.Put("a.b.c.d", 41) tr.Put("a.b.c.d.e", 51) tr.Put("a.b.c.d.e.f", 61) m := tr.Map() util.Must(t, len(m) == 3) util.Must(t, m["a.b.c.d"].(int) == 41) util.Must(t, m["a.b.c.d.e"].(int) == 51) util.Must(t, m["a.b.c.d.e.f"].(int) == 61) }
func TestOpenInit(t *testing.T) { fileName := "db-testing" opts := &Options{Period: 86400, Expiration: 86400 * 7} db, err := Open(fileName, opts) util.Must(t, err == nil) defer os.RemoveAll(fileName) stamp := uint32(time.Now().Unix()) db.Put(&EventWrapper{Stamp: stamp}) db.Close() // Reopen. db, err = Open(fileName, opts) util.Must(t, err == nil) util.Must(t, len(db.pool) == 1) // should have one storage util.Must(t, db.pool[0].id*db.opts.Period <= stamp) }
func TestLoadExpired(t *testing.T) { fileName := "db-testing" opts := &Options{86400 * 7} db, _ := Open(fileName, opts) defer os.RemoveAll(fileName) defer db.Close() idx := &models.Index{Name: "foo", Stamp: 1450430839, Score: 0.7, Average: 78.5} db.Put(idx) // Clear cache db.tr.Clear() db.idp.Clear() db.load() util.Must(t, db.tr.Len() == 0) util.Must(t, !db.tr.Has(idx.Name)) }
func TestFilter(t *testing.T) { // Open db. fileName := "db-testing" db, _ := Open(fileName, nil) defer os.RemoveAll(fileName) defer db.Close() // Add indexes. excludeName := "a.b.c.d.e.f" db.Put(&models.Index{Name: "a.b.c.e.f.g"}) db.Put(&models.Index{Name: "a.b.c.d.f.g"}) db.Put(&models.Index{Name: excludeName}) // Filter l := db.Filter("a.b.c.*.f.*") util.Must(t, len(l) == 2) util.Must(t, l[0].Name != excludeName && l[1].Name != excludeName) }
func TestEventTranslateRuleComment(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} excepted := "foo and bar timing" util.Must(t, ev.TranslateRuleComment() == excepted) }
func TestEventTranslateRuleCommentNoVariables(t *testing.T) { m := &Metric{Name: "foo.bar"} r := &Rule{Pattern: "foo.*", Comment: "no variables"} ev := &Event{Metric: m, Rule: r} excepted := "no variables" util.Must(t, ev.TranslateRuleComment() == excepted) }
func TestFill0Issue470(t *testing.T) { // Case https://github.com/eleme/banshee/issues/470 cfg := config.New() d := &Detector{cfg: cfg} ms := []*models.Metric{ &models.Metric{Stamp: 80, Value: 80}, &models.Metric{Stamp: 90, Value: 90}, &models.Metric{Stamp: 120, Value: 120}, } start, stop := uint32(60), uint32(150) excepted := []float64{80, 90, 0, 0, 120, 0, 0} actually := d.fill0(ms, start, stop) util.Must(t, len(actually) == len(excepted)) for i := 0; i < len(excepted); i++ { util.Must(t, excepted[i] == actually[i]) } }
func TestGet(t *testing.T) { // Open db. fileName := "db-testing" db, _ := Open(fileName, nil) defer os.RemoveAll(fileName) defer db.Close() // Not found. _, err := db.Get("Not-exist") util.Must(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) util.Must(t, nil == err) util.Must(t, i.Equal(idx)) }
func TestInit(t *testing.T) { fileName := "db-testing" db, _ := Open(fileName) defer db.Close() defer os.RemoveAll(fileName) rule1 := &models.Rule{Pattern: "a.b.*"} rule2 := &models.Rule{Pattern: "a.b.*.c"} rule3 := &models.Rule{Pattern: "a.*.c.d"} // Add to db. db.DB().Create(rule1) db.DB().Create(rule2) db.DB().Create(rule3) // Clear cache. db.RulesCache.rules.Clear() // Reload util.Must(t, nil == db.RulesCache.Init(db.DB())) // Get rule r1, ok := db.RulesCache.Get(rule1.ID) util.Must(t, ok) util.Must(t, r1.Pattern == rule1.Pattern) r2, ok := db.RulesCache.Get(rule2.ID) util.Must(t, ok) util.Must(t, r2.Pattern == rule2.Pattern) r3, ok := db.RulesCache.Get(rule3.ID) util.Must(t, ok) util.Must(t, r3.Pattern == rule3.Pattern) }
func TestAlertRecordAlertNotifyAfterConfigDisabled(t *testing.T) { cfg := config.New() cfg.Alerter.NotifyAfter = 0 a := &Alerter{cfg: cfg, alertRecords: safemap.New(), lock: &sync.RWMutex{}} metrics := &models.Metric{Name: "test", Stamp: 0, Value: 80} for i := 0; i <= 100; i++ { metrics.Stamp = uint32(i) util.Must(t, !a.checkAlertCount(metrics)) a.setAlertRecord(metrics) } }
func TestGetAcrossStorages(t *testing.T) { // Open db. fileName := "db-testing" opts := &Options{Period: 86400, Expiration: 86400 * 4} db, _ := Open(fileName, opts) defer os.RemoveAll(fileName) defer db.Close() // Force creating 4+1 storages. base := uint32(time.Now().Unix()) db.Put(&models.Metric{Link: 1, Stamp: base}) // 0 db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*1}) // 1 db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*2}) // 2 db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*3}) // 3 db.Put(&models.Metric{Link: 1, Stamp: base + db.opts.Period*4}) // 4 // Get ms, err := db.Get("whatever", 1, base, base+db.opts.Period*3) util.Must(t, err == nil) util.Must(t, len(ms) == 3) util.Must(t, ms[0].Stamp == base) util.Must(t, ms[1].Stamp == base+db.opts.Period*1) util.Must(t, ms[2].Stamp == base+db.opts.Period*2) }
func TestLen(t *testing.T) { // Open db. fileName := "db-testing" db, _ := Open(fileName, nil) defer os.RemoveAll(fileName) defer db.Close() // Add indexes. db.Put(&models.Index{Name: "abc"}) db.Put(&models.Index{Name: "efg"}) db.Put(&models.Index{Name: "fgh"}) // Len util.Must(t, db.Len() == 3) }
func TestGetAcrossStorages(t *testing.T) { // Open db. fileName := "db-testing" opts := &Options{Period: 86400, Expiration: 86400 * 4} db, _ := Open(fileName, opts) defer os.RemoveAll(fileName) defer db.Close() // Force creating 4+1 storages. base := uint32(time.Now().Unix()) db.Put(&EventWrapper{ID: "20160525155730.1", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base}) // 0 db.Put(&EventWrapper{ID: "20160525155730.2", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*1}) // 1 db.Put(&EventWrapper{ID: "20160525155730.3", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*2}) // 2 db.Put(&EventWrapper{ID: "20160525155730.4", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*3}) // 3 db.Put(&EventWrapper{ID: "20160525155730.5", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: base + db.opts.Period*4}) // 4 // Get by project id. ews, err := db.GetByProjectID(1, 0, base, base+db.opts.Period*3) util.Must(t, err == nil) util.Must(t, len(ews) == 3) util.Must(t, ews[0].Stamp == base) util.Must(t, ews[1].Stamp == base+db.opts.Period*1) util.Must(t, ews[2].Stamp == base+db.opts.Period*2) }
func TestHourInRange(t *testing.T) { util.Must(t, hourInRange(3, 0, 6)) util.Must(t, !hourInRange(7, 0, 6)) util.Must(t, !hourInRange(6, 0, 6)) util.Must(t, hourInRange(23, 19, 10)) util.Must(t, hourInRange(6, 19, 10)) util.Must(t, !hourInRange(13, 19, 10)) }
func TestPut(t *testing.T) { // Open db. fileName := "db-testing" opts := &Options{Period: 86400, Expiration: 86400 * 7} db, _ := Open(fileName, opts) defer os.RemoveAll(fileName) defer db.Close() // Put. ew := &EventWrapper{ ID: "20160525152356", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: 1452758773, } util.Must(t, db.Put(ew) == nil) // Must in db. gdb := db.pool[0].db ew1 := &EventWrapper{} util.Must(t, gdb.Where("id = ?", ew.ID).First(ew1).Error == nil) util.Must(t, reflect.DeepEqual(ew, ew1)) }
func TestGetByProjectID(t *testing.T) { // Open db. fileName := "db-testing" opts := &Options{Period: 86400, Expiration: 86400 * 7} db, _ := Open(fileName, opts) defer os.RemoveAll(fileName) defer db.Close() // Nothing. ews, err := db.GetByProjectID(1, 0, 0, 1464162569) util.Must(t, err == nil) util.Must(t, len(ews) == 0) // Put some. db.Put(&EventWrapper{ID: "20160525155330.1", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: 1464162569}) db.Put(&EventWrapper{ID: "20160525155330.2", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: 1464162579}) db.Put(&EventWrapper{ID: "20160525155330.3", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: 1464162589}) db.Put(&EventWrapper{ID: "20160525155330.4", RuleID: 1, ProjectID: 1, Level: 2, Name: "foo", Stamp: 1464162599}) // Get again. ews, err = db.GetByProjectID(1, 0, 0, 1464162599) util.Must(t, err == nil) util.Must(t, len(ews) == 3) // right is closed // Test the value ew := ews[0] util.Must(t, ew.ID == "20160525155330.1") }