github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/src/cmd/trace/trace_test.go (about)

     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  }