Home | History | Annotate | Download | only in trace
      1 package main
      2 
      3 import (
      4 	"internal/trace"
      5 	"testing"
      6 )
      7 
      8 // TestGoroutineCount tests runnable/running goroutine counts computed by generateTrace
      9 // remain in the valid range.
     10 //   - the counts must not be negative. generateTrace will return an error.
     11 //   - the counts must not include goroutines blocked waiting on channels or in syscall.
     12 func TestGoroutineCount(t *testing.T) {
     13 	w := trace.NewWriter()
     14 	w.Emit(trace.EvBatch, 0, 0)  // start of per-P batch event [pid, timestamp]
     15 	w.Emit(trace.EvFrequency, 1) // [ticks per second]
     16 
     17 	// In this test, we assume a valid trace contains EvGoWaiting or EvGoInSyscall
     18 	// event for every blocked goroutine.
     19 
     20 	// goroutine 10: blocked
     21 	w.Emit(trace.EvGoCreate, 1, 10, 1, 1) // [timestamp, new goroutine id, new stack id, stack id]
     22 	w.Emit(trace.EvGoWaiting, 1, 10)      // [timestamp, goroutine id]
     23 
     24 	// goroutine 20: in syscall
     25 	w.Emit(trace.EvGoCreate, 1, 20, 2, 1)
     26 	w.Emit(trace.EvGoInSyscall, 1, 20) // [timestamp, goroutine id]
     27 
     28 	// goroutine 30: runnable
     29 	w.Emit(trace.EvGoCreate, 1, 30, 5, 1)
     30 
     31 	w.Emit(trace.EvProcStart, 2, 0) // [timestamp, thread id]
     32 
     33 	// goroutine 40: runnable->running->runnable
     34 	w.Emit(trace.EvGoCreate, 1, 40, 7, 1)
     35 	w.Emit(trace.EvGoStartLocal, 1, 40) // [timestamp, goroutine id]
     36 	w.Emit(trace.EvGoSched, 1, 8)       // [timestamp, stack]
     37 
     38 	events, err := trace.Parse(w, "")
     39 	if err != nil {
     40 		t.Fatalf("failed to parse test trace: %v", err)
     41 	}
     42 
     43 	params := &traceParams{
     44 		events:  events,
     45 		endTime: int64(1<<63 - 1),
     46 	}
     47 
     48 	// If the counts drop below 0, generateTrace will return an error.
     49 	viewerData, err := generateTrace(params)
     50 	if err != nil {
     51 		t.Fatalf("generateTrace failed: %v", err)
     52 	}
     53 	for _, ev := range viewerData.Events {
     54 		if ev.Name == "Goroutines" {
     55 			cnt := ev.Arg.(*goroutineCountersArg)
     56 			if cnt.Runnable+cnt.Running > 2 {
     57 				t.Errorf("goroutine count=%+v; want no more than 2 goroutines in runnable/running state", cnt)
     58 			}
     59 			t.Logf("read %+v %+v", ev, cnt)
     60 		}
     61 	}
     62 }
     63 
     64 func TestGoroutineFilter(t *testing.T) {
     65 	// Test that we handle state changes to selected goroutines
     66 	// caused by events on goroutines that are not selected.
     67 
     68 	w := trace.NewWriter()
     69 	w.Emit(trace.EvBatch, 0, 0)  // start of per-P batch event [pid, timestamp]
     70 	w.Emit(trace.EvFrequency, 1) // [ticks per second]
     71 
     72 	// goroutine 10: blocked
     73 	w.Emit(trace.EvGoCreate, 1, 10, 1, 1) // [timestamp, new goroutine id, new stack id, stack id]
     74 	w.Emit(trace.EvGoWaiting, 1, 10)      // [timestamp, goroutine id]
     75 
     76 	// goroutine 20: runnable->running->unblock 10
     77 	w.Emit(trace.EvGoCreate, 1, 20, 7, 1)
     78 	w.Emit(trace.EvGoStartLocal, 1, 20)      // [timestamp, goroutine id]
     79 	w.Emit(trace.EvGoUnblockLocal, 1, 10, 8) // [timestamp, goroutine id, stack]
     80 	w.Emit(trace.EvGoEnd, 1)                 // [timestamp]
     81 
     82 	// goroutine 10: runnable->running->block
     83 	w.Emit(trace.EvGoStartLocal, 1, 10) // [timestamp, goroutine id]
     84 	w.Emit(trace.EvGoBlock, 1, 9)       // [timestamp, stack]
     85 
     86 	events, err := trace.Parse(w, "")
     87 	if err != nil {
     88 		t.Fatalf("failed to parse test trace: %v", err)
     89 	}
     90 
     91 	params := &traceParams{
     92 		events:  events,
     93 		endTime: int64(1<<63 - 1),
     94 		gs:      map[uint64]bool{10: true},
     95 	}
     96 
     97 	_, err = generateTrace(params)
     98 	if err != nil {
     99 		t.Fatalf("generateTrace failed: %v", err)
    100 	}
    101 }
    102