mirror of
https://github.com/golang/go
synced 2024-11-26 17:26:56 -07:00
internal/trace: make Reader output deterministic
Multiple Ms can offer Events with identical timestamps. The Reader edits those so the timestamps are strictly increasing, but it needs a way to break the tie. Use something deterministic (such as the order of the batches), rather than map iteration order. Updates #68277 Change-Id: I4a1f70c1669ce1c9b52d09e2bc99acbc831ef9a4 Reviewed-on: https://go-review.googlesource.com/c/go/+/596355 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Rhys Hiltner <rhys.hiltner@gmail.com> Reviewed-by: Carlos Amedee <carlos@golang.org> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
parent
601ea46a53
commit
1c4acea03d
@ -25,6 +25,7 @@ import (
|
||||
type generation struct {
|
||||
gen uint64
|
||||
batches map[ThreadID][]batch
|
||||
batchMs []ThreadID
|
||||
cpuSamples []cpuSample
|
||||
*evTable
|
||||
}
|
||||
@ -169,6 +170,9 @@ func processBatch(g *generation, b batch) error {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
if _, ok := g.batches[b.m]; !ok {
|
||||
g.batchMs = append(g.batchMs, b.m)
|
||||
}
|
||||
g.batches[b.m] = append(g.batches[b.m], b)
|
||||
}
|
||||
return nil
|
||||
|
@ -142,7 +142,8 @@ func (r *Reader) ReadEvent() (e Event, err error) {
|
||||
r.cpuSamples = r.gen.cpuSamples
|
||||
|
||||
// Reset frontier.
|
||||
for m, batches := range r.gen.batches {
|
||||
for _, m := range r.gen.batchMs {
|
||||
batches := r.gen.batches[m]
|
||||
bc := &batchCursor{m: m}
|
||||
ok, err := bc.nextEvent(batches, r.gen.freq)
|
||||
if err != nil {
|
||||
|
@ -507,7 +507,7 @@ func TestTraceStress(t *testing.T) {
|
||||
case "js", "wasip1":
|
||||
t.Skip("no os.Pipe on " + runtime.GOOS)
|
||||
}
|
||||
testTraceProg(t, "stress.go", nil)
|
||||
testTraceProg(t, "stress.go", checkReaderDeterminism)
|
||||
}
|
||||
|
||||
func TestTraceStressStartStop(t *testing.T) {
|
||||
@ -535,6 +535,43 @@ func TestTraceIterPull(t *testing.T) {
|
||||
testTraceProg(t, "iter-pull.go", nil)
|
||||
}
|
||||
|
||||
func checkReaderDeterminism(t *testing.T, tb, _ []byte, _ bool) {
|
||||
events := func() []trace.Event {
|
||||
var evs []trace.Event
|
||||
|
||||
r, err := trace.NewReader(bytes.NewReader(tb))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
for {
|
||||
ev, err := r.ReadEvent()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
evs = append(evs, ev)
|
||||
}
|
||||
|
||||
return evs
|
||||
}
|
||||
|
||||
evs1 := events()
|
||||
evs2 := events()
|
||||
|
||||
if l1, l2 := len(evs1), len(evs2); l1 != l2 {
|
||||
t.Fatalf("re-reading trace gives different event count (%d != %d)", l1, l2)
|
||||
}
|
||||
for i, ev1 := range evs1 {
|
||||
ev2 := evs2[i]
|
||||
if s1, s2 := ev1.String(), ev2.String(); s1 != s2 {
|
||||
t.Errorf("re-reading trace gives different event %d:\n%s\n%s\n", i, s1, s2)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testTraceProg(t *testing.T, progName string, extra func(t *testing.T, trace, stderr []byte, stress bool)) {
|
||||
testenv.MustHaveGoRun(t)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user