More profiler tests

This commit is contained in:
Carlos Salguero
2017-04-10 16:51:52 -03:00
parent 64a5c6d8b6
commit ced858214d
9 changed files with 740 additions and 37 deletions

View File

@@ -1,6 +1,7 @@
package profiler
import (
"fmt"
"log"
"os"
"reflect"
@@ -25,6 +26,11 @@ type testVars struct {
var vars testVars
func parseDate(dateStr string) time.Time {
date, _ := time.Parse(time.RFC3339Nano, dateStr)
return date
}
func TestMain(m *testing.M) {
var err error
if vars.RootPath, err = tutil.RootPath(); err != nil {
@@ -58,8 +64,8 @@ func TestRegularIterator(t *testing.T) {
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
prof := NewProfiler(iter, filters, nil, fp)
firstSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914-03:00")
lastSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:20.214-03:00")
firstSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914+00:00")
lastSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:20.214+00:00")
want := []QueryInfoAndCounters{
QueryInfoAndCounters{
ID: "c6466139b21c392acd0699e863b50d81",
@@ -113,17 +119,14 @@ func TestIteratorTimeout(t *testing.T) {
iter.EXPECT().Timeout().Return(false),
// When there are no more docs, iterator will close
iter.EXPECT().Close(),
// And we are closing it again (to force the getData go-routine to end)
// at the profiler.Stop() method
iter.EXPECT().Close(),
)
filters := []filter.Filter{}
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
prof := NewProfiler(iter, filters, nil, fp)
firstSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914-03:00")
lastSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914-03:00")
firstSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914+00:00")
lastSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914+00:00")
want := []QueryInfoAndCounters{
QueryInfoAndCounters{
ID: "c6466139b21c392acd0699e863b50d81",
@@ -196,7 +199,7 @@ func TestTailIterator(t *testing.T) {
iter.EXPECT().Timeout().Return(false),
// A Tail iterator will wait if the are no available docs.
// Do a 1500 ms sleep before returning the second doc to simulate a tail wait
// and to let the ticker ticks
// and to let the ticker tick
iter.EXPECT().Next(gomock.Any()).Do(sleep).SetArg(0, docs[1]).Return(true),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Next(gomock.Any()).Return(false),
@@ -209,12 +212,6 @@ func TestTailIterator(t *testing.T) {
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
prof := NewProfiler(iter, filters, ticker.C, fp)
firstSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:20.214-03:00")
lastSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:20.214-03:00")
firstSeen2, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914-03:00")
lastSeen2, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914-03:00")
want := []QueryInfoAndCounters{
QueryInfoAndCounters{
ID: "c6466139b21c392acd0699e863b50d81",
@@ -225,8 +222,8 @@ func TestTailIterator(t *testing.T) {
"shardVersion": []interface{}{float64(0), "000000000000000000000000"},
},
Fingerprint: "find",
FirstSeen: firstSeen,
LastSeen: lastSeen,
FirstSeen: parseDate("2017-04-01T23:01:20.214+00:00"),
LastSeen: parseDate("2017-04-01T23:01:20.214+00:00"),
TableScan: false,
Count: 1,
BlockedTime: Times(nil),
@@ -245,8 +242,8 @@ func TestTailIterator(t *testing.T) {
"shardVersion": []interface{}{float64(0), "000000000000000000000000"},
},
Fingerprint: "find",
FirstSeen: firstSeen2,
LastSeen: lastSeen2,
FirstSeen: parseDate("2017-04-01T23:01:19.914+00:00"),
LastSeen: parseDate("2017-04-01T23:01:19.914+00:00"),
TableScan: false,
Count: 1,
BlockedTime: Times(nil),
@@ -271,3 +268,202 @@ func TestTailIterator(t *testing.T) {
}
}
}
func TestCalcStats(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
docs := []proto.SystemProfile{}
err := tutil.LoadJson(vars.RootPath+samples+"profiler_docs_stats.json", &docs)
if err != nil {
t.Fatalf("cannot load samples: %s", err.Error())
}
want := []QueryStats{}
err = tutil.LoadJson(vars.RootPath+samples+"profiler_docs_stats.want.json", &want)
if err != nil {
t.Fatalf("cannot load expected results: %s", err.Error())
}
iter := pmgomock.NewMockIterManager(ctrl)
gomock.InOrder(
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[0]).Return(true),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[1]).Return(true),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[2]).Return(true),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Next(gomock.Any()).Return(false),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Close(),
)
filters := []filter.Filter{}
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
prof := NewProfiler(iter, filters, nil, fp)
prof.Start()
select {
case queries := <-prof.QueriesChan():
stats := CalcQueriesStats(queries, 1)
if os.Getenv("UPDATE_SAMPLES") != "" {
tutil.WriteJson(vars.RootPath+samples+"profiler_docs_stats.want.json", stats)
}
if !reflect.DeepEqual(stats, want) {
t.Errorf("Invalid stats.\nGot:%#v\nWant: %#v\n", stats, want)
}
case <-time.After(2 * time.Second):
t.Error("Didn't get any query")
}
}
func TestCalcTotalStats(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
docs := []proto.SystemProfile{}
err := tutil.LoadJson(vars.RootPath+samples+"profiler_docs_stats.json", &docs)
if err != nil {
t.Fatalf("cannot load samples: %s", err.Error())
}
want := QueryStats{}
err = tutil.LoadJson(vars.RootPath+samples+"profiler_docs_total_stats.want.json", &want)
if err != nil && !tutil.ShouldUpdateSamples() {
t.Fatalf("cannot load expected results: %s", err.Error())
}
iter := pmgomock.NewMockIterManager(ctrl)
gomock.InOrder(
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[0]).Return(true),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[1]).Return(true),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[2]).Return(true),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Next(gomock.Any()).Return(false),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Close(),
)
filters := []filter.Filter{}
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
prof := NewProfiler(iter, filters, nil, fp)
prof.Start()
select {
case queries := <-prof.QueriesChan():
stats := CalcTotalQueriesStats(queries, 1)
if os.Getenv("UPDATE_SAMPLES") != "" {
fmt.Println("Updating samples: " + vars.RootPath + samples + "profiler_docs_total_stats.want.json")
err := tutil.WriteJson(vars.RootPath+samples+"profiler_docs_total_stats.want.json", stats)
if err != nil {
fmt.Printf("cannot update samples: %s", err.Error())
}
}
if !reflect.DeepEqual(stats, want) {
t.Errorf("Invalid stats.\nGot:%#v\nWant: %#v\n", stats, want)
}
case <-time.After(2 * time.Second):
t.Error("Didn't get any query")
}
}
func TestCalcTotalCounters(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
docs := []proto.SystemProfile{}
err := tutil.LoadJson(vars.RootPath+samples+"profiler_docs_stats.json", &docs)
if err != nil {
t.Fatalf("cannot load samples: %s", err.Error())
}
want := totalCounters{}
err = tutil.LoadJson(vars.RootPath+samples+"profiler_docs_total_counters.want.json", &want)
if err != nil && !tutil.ShouldUpdateSamples() {
t.Fatalf("cannot load expected results: %s", err.Error())
}
iter := pmgomock.NewMockIterManager(ctrl)
gomock.InOrder(
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[0]).Return(true),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[1]).Return(true),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[2]).Return(true),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Next(gomock.Any()).Return(false),
iter.EXPECT().Timeout().Return(false),
iter.EXPECT().Close(),
)
filters := []filter.Filter{}
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
prof := NewProfiler(iter, filters, nil, fp)
prof.Start()
select {
case queries := <-prof.QueriesChan():
counters := calcTotalCounters(queries)
if tutil.ShouldUpdateSamples() {
fmt.Println("Updating samples: " + vars.RootPath + samples + "profiler_docs_total_counters.want.json")
err := tutil.WriteJson(vars.RootPath+samples+"profiler_docs_total_counters.want.json", counters)
if err != nil {
fmt.Printf("cannot update samples: %s", err.Error())
}
}
if !reflect.DeepEqual(counters, want) {
t.Errorf("Invalid counters.\nGot:%#v\nWant: %#v\n", counters, want)
}
case <-time.After(2 * time.Second):
t.Error("Didn't get any query")
}
}
func TestProcessDoc(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
docs := []proto.SystemProfile{}
err := tutil.LoadJson(vars.RootPath+samples+"profiler_docs_stats.json", &docs)
if err != nil {
t.Fatalf("cannot load samples: %s", err.Error())
}
iter := pmgomock.NewMockIterManager(ctrl)
filters := []filter.Filter{}
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
prof := NewProfiler(iter, filters, nil, fp)
var stats = make(map[StatsGroupKey]*QueryInfoAndCounters)
err = prof.ProcessDoc(docs[1], stats)
if err != nil {
t.Errorf("Error processing doc: %s\n", err.Error())
}
statsKey := StatsGroupKey{Operation: "query", Fingerprint: "s2", Namespace: "samples.col1"}
statsVal := &QueryInfoAndCounters{
ID: "84e09ef6a3dc35f472df05fa98eee7d3",
Namespace: "samples.col1",
Operation: "query",
Query: map[string]interface{}{"s2": map[string]interface{}{"$gte": "41991", "$lt": "33754"}},
Fingerprint: "s2",
FirstSeen: parseDate("2017-04-10T13:15:53.532-03:00"),
LastSeen: parseDate("2017-04-10T13:15:53.532-03:00"),
TableScan: false,
Count: 1,
BlockedTime: nil,
LockTime: nil,
NReturned: []float64{0},
NScanned: []float64{10000},
QueryTime: []float64{7},
ResponseLength: []float64{215},
}
want := map[StatsGroupKey]*QueryInfoAndCounters{statsKey: statsVal}
if !reflect.DeepEqual(stats, want) {
t.Errorf("Error in ProcessDoc.\nGot:%#v\nWant: %#v\n", stats, want)
}
}