| 
									
										
										
										
											2018-02-23 10:56:08 +01:00
										 |  |  | package metrics | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"runtime" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkRuntimeMemStats(b *testing.B) { | 
					
						
							|  |  |  | 	r := NewRegistry() | 
					
						
							|  |  |  | 	RegisterRuntimeMemStats(r) | 
					
						
							|  |  |  | 	b.ResetTimer() | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							|  |  |  | 		CaptureRuntimeMemStatsOnce(r) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRuntimeMemStats(t *testing.T) { | 
					
						
							|  |  |  | 	r := NewRegistry() | 
					
						
							|  |  |  | 	RegisterRuntimeMemStats(r) | 
					
						
							|  |  |  | 	CaptureRuntimeMemStatsOnce(r) | 
					
						
							|  |  |  | 	zero := runtimeMetrics.MemStats.PauseNs.Count() // Get a "zero" since GC may have run before these tests. | 
					
						
							|  |  |  | 	runtime.GC() | 
					
						
							|  |  |  | 	CaptureRuntimeMemStatsOnce(r) | 
					
						
							| 
									
										
										
										
											2019-11-22 16:04:35 +01:00
										 |  |  | 	if count := runtimeMetrics.MemStats.PauseNs.Count(); count-zero != 1 { | 
					
						
							| 
									
										
										
										
											2018-02-23 10:56:08 +01:00
										 |  |  | 		t.Fatal(count - zero) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	runtime.GC() | 
					
						
							|  |  |  | 	runtime.GC() | 
					
						
							|  |  |  | 	CaptureRuntimeMemStatsOnce(r) | 
					
						
							| 
									
										
										
										
											2019-11-22 16:04:35 +01:00
										 |  |  | 	if count := runtimeMetrics.MemStats.PauseNs.Count(); count-zero != 3 { | 
					
						
							| 
									
										
										
										
											2018-02-23 10:56:08 +01:00
										 |  |  | 		t.Fatal(count - zero) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for i := 0; i < 256; i++ { | 
					
						
							|  |  |  | 		runtime.GC() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	CaptureRuntimeMemStatsOnce(r) | 
					
						
							| 
									
										
										
										
											2019-11-22 16:04:35 +01:00
										 |  |  | 	if count := runtimeMetrics.MemStats.PauseNs.Count(); count-zero != 259 { | 
					
						
							| 
									
										
										
										
											2018-02-23 10:56:08 +01:00
										 |  |  | 		t.Fatal(count - zero) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for i := 0; i < 257; i++ { | 
					
						
							|  |  |  | 		runtime.GC() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	CaptureRuntimeMemStatsOnce(r) | 
					
						
							| 
									
										
										
										
											2019-11-22 16:04:35 +01:00
										 |  |  | 	if count := runtimeMetrics.MemStats.PauseNs.Count(); count-zero != 515 { // We lost one because there were too many GCs between captures. | 
					
						
							| 
									
										
										
										
											2018-02-23 10:56:08 +01:00
										 |  |  | 		t.Fatal(count - zero) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRuntimeMemStatsNumThread(t *testing.T) { | 
					
						
							|  |  |  | 	r := NewRegistry() | 
					
						
							|  |  |  | 	RegisterRuntimeMemStats(r) | 
					
						
							|  |  |  | 	CaptureRuntimeMemStatsOnce(r) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if value := runtimeMetrics.NumThread.Value(); value < 1 { | 
					
						
							|  |  |  | 		t.Fatalf("got NumThread: %d, wanted at least 1", value) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRuntimeMemStatsBlocking(t *testing.T) { | 
					
						
							|  |  |  | 	if g := runtime.GOMAXPROCS(0); g < 2 { | 
					
						
							|  |  |  | 		t.Skipf("skipping TestRuntimeMemStatsBlocking with GOMAXPROCS=%d\n", g) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ch := make(chan int) | 
					
						
							|  |  |  | 	go testRuntimeMemStatsBlocking(ch) | 
					
						
							|  |  |  | 	var memStats runtime.MemStats | 
					
						
							|  |  |  | 	t0 := time.Now() | 
					
						
							|  |  |  | 	runtime.ReadMemStats(&memStats) | 
					
						
							|  |  |  | 	t1 := time.Now() | 
					
						
							|  |  |  | 	t.Log("i++ during runtime.ReadMemStats:", <-ch) | 
					
						
							|  |  |  | 	go testRuntimeMemStatsBlocking(ch) | 
					
						
							|  |  |  | 	d := t1.Sub(t0) | 
					
						
							|  |  |  | 	t.Log(d) | 
					
						
							|  |  |  | 	time.Sleep(d) | 
					
						
							|  |  |  | 	t.Log("i++ during time.Sleep:", <-ch) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testRuntimeMemStatsBlocking(ch chan int) { | 
					
						
							|  |  |  | 	i := 0 | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 		case ch <- i: | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			i++ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |