...

Source file src/runtime/histogram_test.go

Documentation: runtime

		 1  // Copyright 2020 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  package runtime_test
		 6  
		 7  import (
		 8  	"math"
		 9  	. "runtime"
		10  	"testing"
		11  )
		12  
		13  var dummyTimeHistogram TimeHistogram
		14  
		15  func TestTimeHistogram(t *testing.T) {
		16  	// We need to use a global dummy because this
		17  	// could get stack-allocated with a non-8-byte alignment.
		18  	// The result of this bad alignment is a segfault on
		19  	// 32-bit platforms when calling Record.
		20  	h := &dummyTimeHistogram
		21  
		22  	// Record exactly one sample in each bucket.
		23  	for i := 0; i < TimeHistNumSuperBuckets; i++ {
		24  		var base int64
		25  		if i > 0 {
		26  			base = int64(1) << (i + TimeHistSubBucketBits - 1)
		27  		}
		28  		for j := 0; j < TimeHistNumSubBuckets; j++ {
		29  			v := int64(j)
		30  			if i > 0 {
		31  				v <<= i - 1
		32  			}
		33  			h.Record(base + v)
		34  		}
		35  	}
		36  	// Hit the underflow bucket.
		37  	h.Record(int64(-1))
		38  
		39  	// Check to make sure there's exactly one count in each
		40  	// bucket.
		41  	for i := uint(0); i < TimeHistNumSuperBuckets; i++ {
		42  		for j := uint(0); j < TimeHistNumSubBuckets; j++ {
		43  			c, ok := h.Count(i, j)
		44  			if !ok {
		45  				t.Errorf("hit underflow bucket unexpectedly: (%d, %d)", i, j)
		46  			} else if c != 1 {
		47  				t.Errorf("bucket (%d, %d) has count that is not 1: %d", i, j, c)
		48  			}
		49  		}
		50  	}
		51  	c, ok := h.Count(TimeHistNumSuperBuckets, 0)
		52  	if ok {
		53  		t.Errorf("expected to hit underflow bucket: (%d, %d)", TimeHistNumSuperBuckets, 0)
		54  	}
		55  	if c != 1 {
		56  		t.Errorf("underflow bucket has count that is not 1: %d", c)
		57  	}
		58  
		59  	// Check overflow behavior.
		60  	// By hitting a high value, we should just be adding into the highest bucket.
		61  	h.Record(math.MaxInt64)
		62  	c, ok = h.Count(TimeHistNumSuperBuckets-1, TimeHistNumSubBuckets-1)
		63  	if !ok {
		64  		t.Error("hit underflow bucket in highest bucket unexpectedly")
		65  	} else if c != 2 {
		66  		t.Errorf("highest has count that is not 2: %d", c)
		67  	}
		68  
		69  	dummyTimeHistogram = TimeHistogram{}
		70  }
		71  
		72  func TestTimeHistogramMetricsBuckets(t *testing.T) {
		73  	buckets := TimeHistogramMetricsBuckets()
		74  
		75  	nonInfBucketsLen := TimeHistNumSubBuckets * TimeHistNumSuperBuckets
		76  	expBucketsLen := nonInfBucketsLen + 2 // Count -Inf and +Inf.
		77  	if len(buckets) != expBucketsLen {
		78  		t.Fatalf("unexpected length of buckets: got %d, want %d", len(buckets), expBucketsLen)
		79  	}
		80  	// Check the first non-Inf 2*TimeHistNumSubBuckets buckets in order, skipping the
		81  	// first bucket which should be -Inf (checked later).
		82  	//
		83  	// Because of the way this scheme works, the bottom TimeHistNumSubBuckets
		84  	// buckets are fully populated, and then the next TimeHistNumSubBuckets
		85  	// have the TimeHistSubBucketBits'th bit set, while the bottom are once
		86  	// again fully populated.
		87  	for i := 1; i <= 2*TimeHistNumSubBuckets+1; i++ {
		88  		if got, want := buckets[i], float64(i-1)/1e9; got != want {
		89  			t.Errorf("expected bucket %d to have value %e, got %e", i, want, got)
		90  		}
		91  	}
		92  	// Check some values.
		93  	idxToBucket := map[int]float64{
		94  		0:								 math.Inf(-1),
		95  		33:								float64(0x10<<1) / 1e9,
		96  		34:								float64(0x11<<1) / 1e9,
		97  		49:								float64(0x10<<2) / 1e9,
		98  		58:								float64(0x19<<2) / 1e9,
		99  		65:								float64(0x10<<3) / 1e9,
	 100  		513:							 float64(0x10<<31) / 1e9,
	 101  		519:							 float64(0x16<<31) / 1e9,
	 102  		expBucketsLen - 2: float64(0x1f<<43) / 1e9,
	 103  		expBucketsLen - 1: math.Inf(1),
	 104  	}
	 105  	for idx, bucket := range idxToBucket {
	 106  		if got, want := buckets[idx], bucket; got != want {
	 107  			t.Errorf("expected bucket %d to have value %e, got %e", idx, want, got)
	 108  		}
	 109  	}
	 110  }
	 111  

View as plain text