github.com/leromarinvit/goid@v0.0.0-20170210194639-329af3046b24/goid_test.go (about) 1 package goid 2 3 import ( 4 "reflect" 5 "runtime" 6 "strconv" 7 "strings" 8 "testing" 9 10 "github.com/leromarinvit/typist" 11 ) 12 13 func TestGoid(t *testing.T) { 14 done := make(chan int) 15 compareGoid(100, t, done) 16 <-done 17 } 18 19 func compareGoid(count int, t *testing.T, done chan<- int) { 20 goid := Goid() 21 stack := goidFromStack() 22 if goid != stack { 23 t.Fatalf("Goid() returned %d, stack trace said %d\n", goid, stack) 24 } 25 if count == 0 { 26 done <- 1 27 } else { 28 go compareGoid(count-1, t, done) 29 } 30 } 31 32 func goidFromStack() (id int64) { 33 buf := make([]byte, 20) 34 runtime.Stack(buf, false) 35 num := string(buf[len("goroutine "):]) 36 num = num[:strings.IndexByte(num, ' ')] 37 id, _ = strconv.ParseInt(num, 10, 64) 38 return id 39 } 40 41 func BenchmarkGoid(b *testing.B) { 42 for i := 0; i < b.N; i++ { 43 Goid() 44 } 45 } 46 47 func TestRuntimeG(t *testing.T) { 48 pg, err := typist.TypeByString("*runtime.g") 49 if err != nil { 50 t.Fatal("*runtime.g not found") 51 } 52 if pg.Kind() != reflect.Ptr { 53 t.Fatal("*runtime.g isn't reflect.Ptr but", pg.Kind()) 54 } 55 g := pg.Elem() 56 if g.Kind() != reflect.Struct { 57 t.Fatal("runtime.g isn't reflect.Struct but", g.Kind()) 58 } 59 goid, ok := g.FieldByName("goid") 60 if !ok { 61 t.Fatal("runtime.g has no goid field") 62 } 63 if goid.Type.Kind() != reflect.Int64 { 64 t.Fatal("runtime.g.goid isn't int64 but", goid.Type.String()) 65 } 66 _, ok = g.FieldByName("sched") 67 if !ok { 68 t.Fatal("runtime.g.sched has no sched field") 69 } 70 }