func (ma *Retriever) GetHistogramBuckets(t *testing.T, metricName string, labels map[string]string) ([]*pb.Bucket, []*pb.Bucket) {
	t.Helper()
	ma.maybeSnapshotAfter()
	final := maybeGetMetric(t, ma.final, metricName, labels)
	if final == nil {
		return []*pb.Bucket{}, []*pb.Bucket{}
	}
	if final.GetHistogram() == nil {
		t.Fatalf("Can't get histogram values. Metric %q is not a histogram", metricName)
	}
	initial := maybeGetMetric(t, ma.initial, metricName, labels)
	if initial == nil {
		var zeroedBuckets []*pb.Bucket
		for _, b := range final.GetHistogram().GetBucket() {
			zero := uint64(0)
			zeroedBuckets = append(zeroedBuckets, &pb.Bucket{
				CumulativeCount: &zero,
				UpperBound:      b.UpperBound,
			})
		}
		return zeroedBuckets, final.GetHistogram().GetBucket()
	}
	return initial.GetHistogram().GetBucket(), final.GetHistogram().GetBucket()
}
GetHistogramBuckets returns the buckets for both the "initial" and "final" time of a histogram type metric.
If the metric is not a histogram, this method fails.
If the metric does not exist, this method returns empty buckets.
package testmetrics
import (
	"fmt"
	"sort"
	"strings"
	"testing"
	"github.com/google/go-cmp/cmp"
	"github.com/prometheus/client_golang/prometheus"
	"google.golang.org/protobuf/testing/protocmp"
	pb "github.com/prometheus/client_model/go"
)
type retrieveMetricsFunc func() map[string]*pb.MetricFamily
type Retriever struct {
	retrieve      retrieveMetricsFunc
	snapshotDelay func()
	initial       map[string]*pb.MetricFamily
	final         map[string]*pb.MetricFamily
}
func NewRetrieverFromGatherer(t *testing.T) *Retriever {
	ma := &Retriever{
		retrieve: func() map[string]*pb.MetricFamily {
			families, err := prometheus.DefaultGatherer.Gather()
			if err != nil {
				t.Fatalf("prometheus.DefaultGatherer.Gather() failed with %v", err)
			}
			familyMap := make(map[string]*pb.MetricFamily)
			for _, f := range families {
				familyMap[*f.Name] = f
			}
			return familyMap
		},
	}
	ma.snapshotBefore()
	return ma
}
func (ma *Retriever) snapshotBefore() *Retriever {
	ma.initial = ma.retrieve()
	return ma
}
func (ma *Retriever) snapshotAfter() *Retriever {
	if ma.snapshotDelay != nil {
		ma.snapshotDelay()
	}
	ma.final = ma.retrieve()
	return ma
}
func (ma *Retriever) maybeSnapshotAfter() *Retriever {
	if ma.final == nil {
		ma.snapshotAfter()
	}
	return ma
}
func (ma *Retriever) GetCounterValues(t *testing.T, metricName string, labels map[string]string) (float64, float64) {
	t.Helper()
	ma.maybeSnapshotAfter()
	final := maybeGetMetric(t, ma.final, metricName, labels)
	if final == nil {
		return 0, 0
	}
	if final.GetCounter() == nil {
		t.Fatalf("Can't get counter values. Metric %q is not a counter", metricName)
	}
	initial := maybeGetMetric(t, ma.initial, metricName, labels)
	if initial == nil {
		return 0, final.GetCounter().GetValue()
	}
	return initial.GetCounter().GetValue(), final.GetCounter().GetValue()
}