// getTraceDBEntries returns a map of tracedb.Entry instances. func (b *BenchData) getTraceDBEntries() map[string]*tracedb.Entry { ret := make(map[string]*tracedb.Entry, len(b.Results)) keyPrefix := b.keyPrefix() for testName, allConfigs := range b.Results { for configName, result := range allConfigs { key := fmt.Sprintf("%s:%s:%s", keyPrefix, testName, configName) // Construct the Traces params from all the options. params := util.CopyStringMap(b.Key) params["test"] = testName params["config"] = configName util.AddParams(params, b.Options) // If there is an options map inside the result add it to the params. if resultOptions, ok := result["options"]; ok { if opts, ok := resultOptions.(map[string]interface{}); ok { for k, vi := range opts { if s, ok := vi.(string); ok { params[k] = s } } } } // We used to just pick out only "min_ms" as the only result of a bunch // of key, value pairs in the result, such as max_ms, mean_ms, etc. Now // nanobench uploads only the metrics we are interested in, so we need to // use all the values there, except 'options'. for k, vi := range result { if k == "options" { continue } floatVal, ok := vi.(float64) if !ok { glog.Errorf("Found a non-float64 in %s", key) continue } params["sub_result"] = k perResultKey := key if k != "min_ms" { perResultKey = fmt.Sprintf("%s:%s", perResultKey, k) } paramsCopy := util.CopyStringMap(params) ret[perResultKey] = &tracedb.Entry{ Params: paramsCopy, Value: types.BytesFromFloat64(floatVal), } } } } return ret }
func _main(tile *tiling.Tile, ts db.DB) { commits := []*db.CommitID{} for i, commit := range tile.Commits { cid := &db.CommitID{ Timestamp: time.Unix(commit.CommitTime, 0), ID: commit.Hash, Source: "master", } commits = append(commits, cid) values := map[string]*db.Entry{} if !*skip { for traceid, tr := range tile.Traces { if !tr.IsMissing(i) { values[traceid] = &db.Entry{ Params: tr.Params(), } if *gold { values[traceid].Value = []byte(tr.(*types.GoldenTrace).Values[i]) } else { values[traceid].Value = ptypes.BytesFromFloat64(tr.(*ptypes.PerfTrace).Values[i]) } } } glog.Infof("Adding: %d", i) if err := ts.Add(cid, values); err != nil { glog.Errorf("Failed to add data: %s", err) } } } begin := time.Now() if len(commits) > 50 { commits = commits[:50] } _, err := ts.TileFromCommits(commits) if err != nil { glog.Fatalf("Failed to scan Tile: %s", err) } glog.Infof("Time to load tile: %v", time.Now().Sub(begin)) }
func TestAdd(t *testing.T) { ts, cleanup := setupClientServerForTesting(t.Fatalf) defer cleanup() now := time.Unix(100, 0) commitIDs := []*CommitID{ &CommitID{ Timestamp: now.Unix(), ID: "abc123", Source: "master", }, &CommitID{ Timestamp: now.Add(time.Hour).Unix(), ID: "xyz789", Source: "master", }, } entries := map[string]*Entry{ "key:8888:android": &Entry{ Params: map[string]string{ "config": "8888", "platform": "android", "type": "skp", }, Value: types.BytesFromFloat64(0.01), }, "key:gpu:win8": &Entry{ Params: map[string]string{ "config": "gpu", "platform": "win8", "type": "skp", }, Value: types.BytesFromFloat64(1.234), }, } err := ts.Add(commitIDs[0], entries) assert.NoError(t, err) tile, hashes, err := ts.TileFromCommits(commitIDs) assert.NoError(t, err) assert.Equal(t, 2, len(tile.Traces)) assert.Equal(t, 2, len(tile.Commits)) assert.Equal(t, 2, len(hashes)) assert.True(t, util.In("d41d8cd98f00b204e9800998ecf8427e", hashes)) assert.NotEqual(t, hashes[0], hashes[1]) hashes, err = ts.ListMD5(commitIDs) assert.NoError(t, err) assert.Equal(t, 2, len(hashes)) assert.True(t, util.In("d41d8cd98f00b204e9800998ecf8427e", hashes)) assert.NotEqual(t, hashes[0], hashes[1]) tr := tile.Traces["key:8888:android"].(*types.PerfTrace) assert.Equal(t, 0.01, tr.Values[0]) assert.True(t, tr.IsMissing(1)) assert.Equal(t, "8888", tr.Params()["config"]) tr = tile.Traces["key:gpu:win8"].(*types.PerfTrace) assert.Equal(t, 1.234, tr.Values[0]) assert.True(t, tr.IsMissing(1)) assert.Equal(t, "abc123", tile.Commits[0].Hash) assert.Equal(t, "xyz789", tile.Commits[1].Hash) foundCommits, err := ts.List(now, now.Add(time.Hour)) assert.NoError(t, err) assert.Equal(t, 1, len(foundCommits)) }
func TestNewTraceDBBuilder(t *testing.T) { defer cleanup() // First spin up a traceservice server that we wil talk to. server, err := traceservice.NewTraceServiceServer(FILENAME) if err != nil { t.Fatalf("Failed to initialize the tracestore server: %s", err) } // Start the server on an open port. lis, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatalf("failed to listen: %v", err) } port := lis.Addr().String() s := grpc.NewServer() traceservice.RegisterTraceServiceServer(s, server) go func() { t.Fatalf("Failed while serving: %s", s.Serve(lis)) }() // Get a Git repo. tr := util.NewTempRepo() defer tr.Cleanup() // Set up a connection to the server. conn, err := grpc.Dial(port, grpc.WithInsecure()) if err != nil { t.Fatalf("did not connect: %v", err) } ts, err := db.NewTraceServiceDB(conn, types.PerfTraceBuilder) if err != nil { t.Fatalf("Failed to create tracedb.DB: %s", err) } defer util.Close(ts) git, err := gitinfo.NewGitInfo(filepath.Join(tr.Dir, "testrepo"), false, false) if err != nil { t.Fatal(err) } hashes := git.LastN(50) assert.Equal(t, 50, len(hashes)) // Populate the tracedb with some data. commitID := &db.CommitID{ Timestamp: git.Timestamp(hashes[1]).Unix(), ID: hashes[1], Source: "master", } entries := map[string]*db.Entry{ "key:8888:android": &db.Entry{ Params: map[string]string{ "config": "8888", "platform": "android", "type": "skp", }, Value: types.BytesFromFloat64(0.01), }, "key:gpu:win8": &db.Entry{ Params: map[string]string{ "config": "gpu", "platform": "win8", "type": "skp", }, Value: types.BytesFromFloat64(1.234), }, } err = ts.Add(commitID, entries) if err != nil { t.Fatalf("Failed to add data to traceservice: %s", err) } evt := eventbus.New(nil) traceDB, err := db.NewTraceServiceDBFromAddress(port, types.PerfTraceBuilder) assert.Nil(t, err) builder, err := db.NewMasterTileBuilder(traceDB, git, 50, evt) if err != nil { t.Fatalf("Failed to construct TraceStore: %s", err) } tile := builder.GetTile() assert.Equal(t, 50, len(tile.Commits)) assert.Equal(t, 2, len(tile.Traces)) assert.Equal(t, commitID.ID, tile.Commits[1].Hash) assert.Equal(t, "Joe Gregorio ([email protected])", tile.Commits[1].Author) ptrace := tile.Traces["key:8888:android"].(*types.PerfTrace) assert.Equal(t, 0.01, ptrace.Values[1]) assert.Equal(t, config.MISSING_DATA_SENTINEL, ptrace.Values[0]) ptrace = tile.Traces["key:gpu:win8"].(*types.PerfTrace) assert.Equal(t, 1.234, ptrace.Values[1]) assert.Equal(t, config.MISSING_DATA_SENTINEL, ptrace.Values[0]) // Now add more data to the tracestore, trigger LoadTile() and check the results. commitID = &db.CommitID{ Timestamp: git.Timestamp(hashes[2]).Unix(), ID: hashes[2], Source: "master", } entries = map[string]*db.Entry{ "key:8888:android": &db.Entry{ Params: map[string]string{ "config": "8888", "platform": "android", "type": "skp", }, Value: types.BytesFromFloat64(0.02), }, "key:565:ubuntu": &db.Entry{ Params: map[string]string{ "config": "565", "platform": "ubuntu", "type": "skp", }, Value: types.BytesFromFloat64(2.345), }, } err = ts.Add(commitID, entries) if err != nil { t.Fatalf("Failed to add data to traceservice: %s", err) } // Access the LoadTile method without exposing it in the MasterBuilder interface. type hasLoadTile interface { LoadTile() error } masterBuilder := builder.(hasLoadTile) if err := masterBuilder.LoadTile(); err != nil { t.Fatalf("Failed to force load Tile: %s", err) } tile = builder.GetTile() assert.Equal(t, 50, len(tile.Commits)) assert.Equal(t, 3, len(tile.Traces)) assert.Equal(t, commitID.ID, tile.Commits[2].Hash) ptrace = tile.Traces["key:8888:android"].(*types.PerfTrace) assert.Equal(t, 0.01, ptrace.Values[1]) assert.Equal(t, 0.02, ptrace.Values[2]) assert.Equal(t, config.MISSING_DATA_SENTINEL, ptrace.Values[0]) assert.Equal(t, config.MISSING_DATA_SENTINEL, ptrace.Values[3]) ptrace = tile.Traces["key:gpu:win8"].(*types.PerfTrace) assert.Equal(t, 1.234, ptrace.Values[1]) assert.Equal(t, config.MISSING_DATA_SENTINEL, ptrace.Values[0]) ptrace = tile.Traces["key:565:ubuntu"].(*types.PerfTrace) assert.Equal(t, 2.345, ptrace.Values[2]) assert.Equal(t, config.MISSING_DATA_SENTINEL, ptrace.Values[3]) }
func TestImpl(t *testing.T) { ts, err := NewTraceServiceServer(FILENAME) assert.NoError(t, err) defer util.Close(ts) defer cleanup() now := time.Now() first := now.Unix() second := now.Add(time.Minute).Unix() commitIDs := []*CommitID{ &CommitID{ Timestamp: first, Id: "abc123", Source: "master", }, &CommitID{ Timestamp: second, Id: "xyz789", Source: "master", }, } params := &AddParamsRequest{ Params: []*ParamsPair{ &ParamsPair{ Key: "key:8888:android", Params: map[string]string{ "config": "8888", "platform": "android", "type": "skp", }, }, &ParamsPair{ Key: "key:gpu:win8", Params: map[string]string{ "config": "gpu", "platform": "win8", "type": "skp", }, }, }, } ctx := context.Background() // First confirm that Ping() works. _, err = ts.Ping(ctx, &Empty{}) assert.Nil(t, err) // Confirm that these traceids don't have Params stored in the db yet. missingRequest := &MissingParamsRequest{ Traceids: []string{"key:8888:android", "key:gpu:win8"}, } missingResp, err := ts.MissingParams(ctx, missingRequest) assert.NoError(t, err) assert.Equal(t, missingResp.Traceids, missingRequest.Traceids) // Now add the Params for them. _, err = ts.AddParams(ctx, params) assert.NoError(t, err) // Confirm the missing list is now empty. nowMissing, err := ts.MissingParams(ctx, missingRequest) assert.Equal(t, []string{}, nowMissing.Traceids) addReq := &AddRequest{ Commitid: commitIDs[0], Values: []*ValuePair{ &ValuePair{ Key: "key:gpu:win8", Value: types.BytesFromFloat64(1.234), }, &ValuePair{ Key: "key:8888:android", Value: types.BytesFromFloat64(0.01), }, }, } // Add a commit. _, err = ts.Add(ctx, addReq) assert.NoError(t, err) // List, GetValues, and GetParams for the added commit. listReq := &ListRequest{ Begin: first, End: second, } listResp, err := ts.List(ctx, listReq) assert.NoError(t, err) assert.Equal(t, 1, len(listResp.Commitids)) assert.Equal(t, "abc123", listResp.Commitids[0].Id) valuesReq := &GetValuesRequest{ Commitid: commitIDs[0], } valuesResp, err := ts.GetValues(ctx, valuesReq) assert.NoError(t, err) assert.Equal(t, 2, len(valuesResp.Values)) expected := map[string]float64{ "key:gpu:win8": 1.234, "key:8888:android": 0.01, } for _, v := range valuesResp.Values { assert.Equal(t, expected[v.Key], math.Float64frombits(binary.LittleEndian.Uint64(v.Value))) } paramsReq := &GetParamsRequest{ Traceids: []string{"key:8888:android", "key:gpu:win8"}, } paramsResp, err := ts.GetParams(ctx, paramsReq) assert.NoError(t, err) assert.Equal(t, "8888", paramsResp.Params[0].Params["config"]) assert.Equal(t, "win8", paramsResp.Params[1].Params["platform"]) // Remove the commit. removeRequest := &RemoveRequest{ Commitid: commitIDs[0], } _, err = ts.Remove(ctx, removeRequest) assert.NoError(t, err) listResp, err = ts.List(ctx, listReq) assert.NoError(t, err) assert.Equal(t, 0, len(listResp.Commitids)) }
func TestAdd(t *testing.T) { defer cleanup() // First spin up a traceservice server that we wil talk to. server, err := traceservice.NewTraceServiceServer(FILENAME) if err != nil { t.Fatalf("Failed to initialize the tracestore server: %s", err) } // Start the server on an open port. lis, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatalf("failed to listen: %v", err) } port := lis.Addr().String() s := grpc.NewServer() traceservice.RegisterTraceServiceServer(s, server) go func() { t.Fatalf("Failed while serving: %s", s.Serve(lis)) }() // Set up a connection to the server. conn, err := grpc.Dial(port, grpc.WithInsecure()) if err != nil { t.Fatalf("did not connect: %v", err) } defer util.Close(conn) ts, err := NewTraceServiceDB(conn, types.PerfTraceBuilder) if err != nil { t.Fatalf("Failed to create tracedb.DB: %s", err) } defer util.Close(ts) now := time.Now() commitIDs := []*CommitID{ &CommitID{ Timestamp: now, ID: "abc123", Source: "master", }, &CommitID{ Timestamp: now.Add(time.Minute), ID: "xyz789", Source: "master", }, } entries := map[string]*Entry{ "key:8888:android": &Entry{ Params: map[string]string{ "config": "8888", "platform": "android", "type": "skp", }, Value: types.BytesFromFloat64(0.01), }, "key:gpu:win8": &Entry{ Params: map[string]string{ "config": "gpu", "platform": "win8", "type": "skp", }, Value: types.BytesFromFloat64(1.234), }, } err = ts.Add(commitIDs[0], entries) assert.NoError(t, err) tile, err := ts.TileFromCommits(commitIDs) assert.NoError(t, err) assert.Equal(t, 2, len(tile.Traces)) assert.Equal(t, 2, len(tile.Commits)) tr := tile.Traces["key:8888:android"].(*types.PerfTrace) assert.Equal(t, 0.01, tr.Values[0]) assert.True(t, tr.IsMissing(1)) assert.Equal(t, "8888", tr.Params()["config"]) tr = tile.Traces["key:gpu:win8"].(*types.PerfTrace) assert.Equal(t, 1.234, tr.Values[0]) assert.True(t, tr.IsMissing(1)) assert.Equal(t, "abc123", tile.Commits[0].Hash) assert.Equal(t, "xyz789", tile.Commits[1].Hash) foundCommits, err := ts.List(now, now.Add(time.Hour)) assert.NoError(t, err) assert.Equal(t, 1, len(foundCommits)) }
func TestImpl(t *testing.T) { ts, err := NewTraceServiceServer(FILENAME) assert.NoError(t, err) defer util.Close(ts) defer cleanup() now := time.Unix(100, 0) first := now.Unix() second := now.Add(time.Minute).Unix() commitIDs := []*CommitID{ &CommitID{ Timestamp: first, Id: "abc123", Source: "master", }, &CommitID{ Timestamp: second, Id: "xyz789", Source: "master", }, } params := &AddParamsRequest{ Params: []*ParamsPair{ &ParamsPair{ Key: "key:8888:android", Params: map[string]string{ "config": "8888", "platform": "android", "type": "skp", }, }, &ParamsPair{ Key: "key:gpu:win8", Params: map[string]string{ "config": "gpu", "platform": "win8", "type": "skp", }, }, }, } ctx := context.Background() // First confirm that Ping() works. _, err = ts.Ping(ctx, &Empty{}) assert.Nil(t, err) // Confirm that these traceids don't have Params stored in the db yet. missingRequest := &MissingParamsRequest{ Traceids: []string{"key:8888:android", "key:gpu:win8"}, } missingResp, err := ts.MissingParams(ctx, missingRequest) assert.NoError(t, err) assert.Equal(t, missingResp.Traceids, missingRequest.Traceids) // Now add the Params for them. _, err = ts.AddParams(ctx, params) assert.NoError(t, err) // Confirm the missing list is now empty. nowMissing, err := ts.MissingParams(ctx, missingRequest) assert.Equal(t, []string{}, nowMissing.Traceids) addReq := &AddRequest{ Commitid: commitIDs[0], Values: []*ValuePair{ &ValuePair{ Key: "key:gpu:win8", Value: types.BytesFromFloat64(1.234), }, &ValuePair{ Key: "key:8888:android", Value: types.BytesFromFloat64(0.01), }, }, } // Add a commit. _, err = ts.Add(ctx, addReq) assert.NoError(t, err) // List, GetValues, and GetParams for the added commit. listReq := &ListRequest{ Begin: first, End: second, } listResp, err := ts.List(ctx, listReq) assert.NoError(t, err) assert.Equal(t, 1, len(listResp.Commitids)) assert.Equal(t, "abc123", listResp.Commitids[0].Id) valuesReq := &GetValuesRequest{ Commitid: commitIDs[0], } valuesResp, err := ts.GetValues(ctx, valuesReq) assert.NoError(t, err) assert.Equal(t, 2, len(valuesResp.Values)) expected := map[string]float64{ "key:gpu:win8": 1.234, "key:8888:android": 0.01, } for _, v := range valuesResp.Values { assert.Equal(t, expected[v.Key], math.Float64frombits(binary.LittleEndian.Uint64(v.Value))) } assert.NotEqual(t, "", valuesResp.Md5) paramsReq := &GetParamsRequest{ Traceids: []string{"key:8888:android", "key:gpu:win8"}, } paramsResp, err := ts.GetParams(ctx, paramsReq) assert.NoError(t, err) assert.Equal(t, "8888", paramsResp.Params[0].Params["config"]) assert.Equal(t, "win8", paramsResp.Params[1].Params["platform"]) // Request the raw data for the commit. rawRequest := &GetValuesRequest{ Commitid: commitIDs[0], } rawResp, err := ts.GetValuesRaw(ctx, rawRequest) assert.NoError(t, err) assert.Equal(t, 34, len(rawResp.Value)) assert.Equal(t, valuesResp.Md5, rawResp.Md5, "Should get the same md5 regardless of how you request the data.") // Confirm that we can decode the info on the client side. ci, err := NewCommitInfo(rawResp.Value) assert.NoError(t, err) // The keys are trace64ids, so test that we can convert them to traceids, // i.e. from uint64's to strings. keys64 := []uint64{} for k, _ := range ci.Values { keys64 = append(keys64, k) } assert.Equal(t, 2, len(keys64)) traceidsRequest := &GetTraceIDsRequest{ Id: keys64, } traceids, err := ts.GetTraceIDs(ctx, traceidsRequest) assert.NoError(t, err) assert.Equal(t, 2, len(traceids.Ids)) assert.True(t, util.In(traceids.Ids[0].Id, paramsReq.Traceids)) assert.True(t, util.In(traceids.Ids[1].Id, paramsReq.Traceids)) // List the md5s. listMD5Request := &ListMD5Request{ Commitid: commitIDs, } listMD5Response, err := ts.ListMD5(ctx, listMD5Request) assert.NoError(t, err) assert.Equal(t, 2, len(listMD5Response.Commitmd5)) hashes := []string{listMD5Response.Commitmd5[0].Md5, listMD5Response.Commitmd5[1].Md5} assert.True(t, util.In("d41d8cd98f00b204e9800998ecf8427e", hashes)) assert.NotEqual(t, hashes[0], hashes[1]) // Remove the commit. removeRequest := &RemoveRequest{ Commitid: commitIDs[0], } _, err = ts.Remove(ctx, removeRequest) assert.NoError(t, err) listResp, err = ts.List(ctx, listReq) assert.NoError(t, err) assert.Equal(t, 0, len(listResp.Commitids)) }
func TestTileFromCommits(t *testing.T) { ts, cleanup := setupClientServerForTesting(t.Fatalf) defer cleanup() now := time.Unix(100, 0) commitIDs := []*CommitID{ &CommitID{ Timestamp: now.Unix(), ID: "foofoofoo", Source: "master", }, } vcsCommits := []*vcsinfo.LongCommit{ &vcsinfo.LongCommit{ ShortCommit: &vcsinfo.ShortCommit{ Hash: "foofoofoo", Author: "*****@*****.**", Subject: "some commit", }, }, } vcs := ingestion.MockVCS(vcsCommits) entries := map[string]*Entry{ "key:8888:android": &Entry{ Params: map[string]string{ "config": "8888", "platform": "android", "type": "skp", }, Value: types.BytesFromFloat64(0.01), }, "key:gpu:win8": &Entry{ Params: map[string]string{ "config": "gpu", "platform": "win8", "type": "skp", }, Value: types.BytesFromFloat64(1.234), }, } // Populate the tile with some data. err := ts.Add(commitIDs[0], entries) assert.NoError(t, err) // Now test tileBuilder. builder := &tileBuilder{ db: ts, vcs: vcs, tcache: lru.New(2), cache: lru.New(2), } tile, err := builder.CachedTileFromCommits(commitIDs) assert.NoError(t, err) assert.Equal(t, 1, len(tile.Commits)) assert.Equal(t, 2, len(tile.Traces)) assert.Equal(t, 1, builder.tcache.Len(), "The tile should have been added to the cache.") entries = map[string]*Entry{ "key:565:linux": &Entry{ Params: map[string]string{ "config": "565", "platform": "linux", "type": "skp", }, Value: types.BytesFromFloat64(0.05), }, } // Add more data and be sure that the new data is returned when we // call CachedTileFromCommits again. err = ts.Add(commitIDs[0], entries) assert.NoError(t, err) tile, err = builder.CachedTileFromCommits(commitIDs) assert.NoError(t, err) assert.Equal(t, 1, len(tile.Commits)) assert.Equal(t, 3, len(tile.Traces), "The new data should appear in the tile.") assert.Equal(t, 1, builder.tcache.Len(), "The new tile should have replaced the old tile in the cache.") }