github.com/cloudwego/runtimex@v0.1.0/runtimex_test.go (about) 1 // Copyright 2024 CloudWeGo Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package runtimex_test 16 17 import ( 18 "runtime" 19 "sync" 20 "sync/atomic" 21 "testing" 22 "time" 23 24 "github.com/modern-go/reflect2" 25 26 "github.com/cloudwego/runtimex" 27 ) 28 29 //go:noinline 30 func testStackFunction(n int) int { 31 var stack [1024 * 4]int64 32 for i := 0; i < len(stack); i++ { 33 stack[i] = int64(n + i) 34 } 35 return int(stack[len(stack)/2]) 36 } 37 38 func assert(t *testing.T, cond bool, args ...interface{}) { 39 t.Helper() 40 if cond { 41 return 42 } 43 if len(args) > 0 { 44 t.Fatal(args...) 45 } 46 t.Fatal("assertion failed") 47 } 48 49 func TestReflect2NotFound(t *testing.T) { 50 notFound, _ := reflect2.TypeByName("runtime.xxx123").(reflect2.StructType) 51 assert(t, notFound == nil) 52 53 gType := reflect2.TypeByName("runtime.g").(reflect2.StructType) 54 assert(t, gType != nil, gType) 55 mField := gType.FieldByName("xxx123") 56 assert(t, mField == nil) 57 } 58 59 func TestRuntimeStatus(t *testing.T) { 60 goroutines := 8 61 pnum := 4 62 oldpnum := runtime.GOMAXPROCS(pnum) 63 defer runtime.GOMAXPROCS(oldpnum) 64 65 var ( 66 stop int32 67 wg sync.WaitGroup 68 gm sync.Map 69 pm sync.Map 70 ) 71 for i := 0; i < goroutines; i++ { 72 wg.Add(1) 73 go func(n int) { 74 defer wg.Done() 75 for j := 1; atomic.LoadInt32(&stop) == 0; j++ { 76 testStackFunction(j % 102400) 77 78 if j%1024 == 0 { 79 gid, err := runtimex.GID() 80 assert(t, err == nil) 81 pid, err := runtimex.PID() 82 assert(t, err == nil) 83 t.Logf("gid=%d,pid=%d", gid, pid) 84 85 gm.Store(gid, true) 86 pm.Store(pid, true) 87 } 88 } 89 }(i) 90 } 91 time.Sleep(time.Second) 92 atomic.StoreInt32(&stop, 1) 93 wg.Wait() 94 gcount := 0 95 gm.Range(func(key, value interface{}) bool { 96 gcount++ 97 return true 98 }) 99 pcount := 0 100 pm.Range(func(key, value interface{}) bool { 101 pcount++ 102 return true 103 }) 104 assert(t, gcount == goroutines, gcount, goroutines) 105 assert(t, pcount == pnum, pcount, pnum) 106 } 107 108 func BenchmarkGID(b *testing.B) { 109 b.ReportAllocs() 110 // 0 allocs/op 111 for i := 0; i < b.N; i++ { 112 id, err := runtimex.GID() 113 if id < 0 || err != nil { 114 b.Fatal(err) 115 } 116 } 117 } 118 119 func BenchmarkPID(b *testing.B) { 120 b.ReportAllocs() 121 // 0 allocs/op 122 for i := 0; i < b.N; i++ { 123 id, err := runtimex.PID() 124 if id < 0 || err != nil { 125 b.Fatal(err) 126 } 127 } 128 }