github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/mongo/mongometrics/dialmetrics_test.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENSE file for details.
     3  
     4  package mongometrics_test
     5  
     6  import (
     7  	"errors"
     8  	"net"
     9  	"reflect"
    10  	"time"
    11  
    12  	"github.com/juju/testing"
    13  	jc "github.com/juju/testing/checkers"
    14  	"github.com/prometheus/client_golang/prometheus"
    15  	dto "github.com/prometheus/client_model/go"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/mongo/mongometrics"
    19  )
    20  
    21  type DialCollectorSuite struct {
    22  	testing.IsolationSuite
    23  	collector *mongometrics.DialCollector
    24  }
    25  
    26  var _ = gc.Suite(&DialCollectorSuite{})
    27  
    28  func (s *DialCollectorSuite) SetUpTest(c *gc.C) {
    29  	s.IsolationSuite.SetUpTest(c)
    30  	s.collector = mongometrics.NewDialCollector()
    31  }
    32  
    33  func (s *DialCollectorSuite) TestDescribe(c *gc.C) {
    34  	ch := make(chan *prometheus.Desc)
    35  	go func() {
    36  		defer close(ch)
    37  		s.collector.Describe(ch)
    38  	}()
    39  	var descs []*prometheus.Desc
    40  	for desc := range ch {
    41  		descs = append(descs, desc)
    42  	}
    43  	c.Assert(descs, gc.HasLen, 2)
    44  	c.Assert(descs[0].String(), gc.Matches, `.*fqName: "juju_mongo_dials_total".*`)
    45  	c.Assert(descs[1].String(), gc.Matches, `.*fqName: "juju_mongo_dial_duration_seconds".*`)
    46  }
    47  
    48  func (s *DialCollectorSuite) TestCollect(c *gc.C) {
    49  	s.collector.PostDialServer("foo", time.Second, nil)
    50  	s.collector.PostDialServer("foo", 2*time.Second, nil)
    51  	s.collector.PostDialServer("foo", 3*time.Second, nil)
    52  	s.collector.PostDialServer("bar", time.Millisecond, errors.New("bewm"))
    53  	s.collector.PostDialServer("baz", time.Minute, &net.OpError{
    54  		Op:  "read",
    55  		Err: errors.New("bewm"),
    56  	})
    57  	s.collector.PostDialServer("qux", time.Hour, netError{
    58  		error:     errors.New("bewm"),
    59  		timeout:   true,
    60  		temporary: true,
    61  	})
    62  
    63  	ch := make(chan prometheus.Metric)
    64  	go func() {
    65  		defer close(ch)
    66  		s.collector.Collect(ch)
    67  	}()
    68  
    69  	var dtoMetrics [8]dto.Metric
    70  	var metrics []prometheus.Metric
    71  	for metric := range ch {
    72  		metrics = append(metrics, metric)
    73  	}
    74  	c.Assert(metrics, gc.HasLen, len(dtoMetrics))
    75  
    76  	for i, metric := range metrics {
    77  		err := metric.Write(&dtoMetrics[i])
    78  		c.Assert(err, jc.ErrorIsNil)
    79  	}
    80  
    81  	float64ptr := func(v float64) *float64 {
    82  		return &v
    83  	}
    84  	uint64ptr := func(v uint64) *uint64 {
    85  		return &v
    86  	}
    87  	labelpair := func(n, v string) *dto.LabelPair {
    88  		return &dto.LabelPair{Name: &n, Value: &v}
    89  	}
    90  	expected := []dto.Metric{{
    91  		Counter: &dto.Counter{Value: float64ptr(3)},
    92  		Label: []*dto.LabelPair{
    93  			labelpair("failed", ""),
    94  			labelpair("server", "foo"),
    95  			labelpair("timeout", ""),
    96  		},
    97  	}, {
    98  		Counter: &dto.Counter{Value: float64ptr(1)},
    99  		Label: []*dto.LabelPair{
   100  			labelpair("failed", "failed"),
   101  			labelpair("server", "bar"),
   102  			labelpair("timeout", ""),
   103  		},
   104  	}, {
   105  		Counter: &dto.Counter{Value: float64ptr(1)},
   106  		Label: []*dto.LabelPair{
   107  			labelpair("failed", "read"),
   108  			labelpair("server", "baz"),
   109  			labelpair("timeout", ""),
   110  		},
   111  	}, {
   112  		Counter: &dto.Counter{Value: float64ptr(1)},
   113  		Label: []*dto.LabelPair{
   114  			labelpair("failed", "failed"),
   115  			labelpair("server", "qux"),
   116  			labelpair("timeout", "timed out"),
   117  		},
   118  	}, {
   119  		Label: []*dto.LabelPair{
   120  			labelpair("failed", ""),
   121  			labelpair("server", "foo"),
   122  			labelpair("timeout", ""),
   123  		},
   124  		Summary: &dto.Summary{
   125  			SampleCount: uint64ptr(3),
   126  			SampleSum:   float64ptr(6),
   127  			Quantile: []*dto.Quantile{{
   128  				Quantile: float64ptr(0.5),
   129  				Value:    float64ptr(1),
   130  			}, {
   131  				Quantile: float64ptr(0.9),
   132  				Value:    float64ptr(2),
   133  			}, {
   134  				Quantile: float64ptr(0.99),
   135  				Value:    float64ptr(2),
   136  			}},
   137  		},
   138  	}, {
   139  		Label: []*dto.LabelPair{
   140  			labelpair("failed", "failed"),
   141  			labelpair("server", "bar"),
   142  			labelpair("timeout", ""),
   143  		},
   144  		Summary: &dto.Summary{
   145  			SampleCount: uint64ptr(1),
   146  			SampleSum:   float64ptr(0.001),
   147  			Quantile: []*dto.Quantile{{
   148  				Quantile: float64ptr(0.5),
   149  				Value:    float64ptr(0.001),
   150  			}, {
   151  				Quantile: float64ptr(0.9),
   152  				Value:    float64ptr(0.001),
   153  			}, {
   154  				Quantile: float64ptr(0.99),
   155  				Value:    float64ptr(0.001),
   156  			}},
   157  		},
   158  	}, {
   159  		Label: []*dto.LabelPair{
   160  			labelpair("failed", "read"),
   161  			labelpair("server", "baz"),
   162  			labelpair("timeout", ""),
   163  		},
   164  		Summary: &dto.Summary{
   165  			SampleCount: uint64ptr(1),
   166  			SampleSum:   float64ptr(60),
   167  			Quantile: []*dto.Quantile{{
   168  				Quantile: float64ptr(0.5),
   169  				Value:    float64ptr(60),
   170  			}, {
   171  				Quantile: float64ptr(0.9),
   172  				Value:    float64ptr(60),
   173  			}, {
   174  				Quantile: float64ptr(0.99),
   175  				Value:    float64ptr(60),
   176  			}},
   177  		},
   178  	}, {
   179  		Label: []*dto.LabelPair{
   180  			labelpair("failed", "failed"),
   181  			labelpair("server", "qux"),
   182  			labelpair("timeout", "timed out"),
   183  		},
   184  		Summary: &dto.Summary{
   185  			SampleCount: uint64ptr(1),
   186  			SampleSum:   float64ptr(3600),
   187  			Quantile: []*dto.Quantile{{
   188  				Quantile: float64ptr(0.5),
   189  				Value:    float64ptr(3600),
   190  			}, {
   191  				Quantile: float64ptr(0.9),
   192  				Value:    float64ptr(3600),
   193  			}, {
   194  				Quantile: float64ptr(0.99),
   195  				Value:    float64ptr(3600),
   196  			}},
   197  		},
   198  	}}
   199  	for _, dm := range dtoMetrics {
   200  		var found bool
   201  		for i, m := range expected {
   202  			if !reflect.DeepEqual(dm, m) {
   203  				continue
   204  			}
   205  			expected = append(expected[:i], expected[i+1:]...)
   206  			found = true
   207  			break
   208  		}
   209  		if !found {
   210  			c.Errorf("metric %+v not expected", dm)
   211  		}
   212  	}
   213  }
   214  
   215  type netError struct {
   216  	error
   217  	timeout   bool
   218  	temporary bool
   219  }
   220  
   221  func (e netError) Timeout() bool {
   222  	return e.timeout
   223  }
   224  
   225  func (e netError) Temporary() bool {
   226  	return e.temporary
   227  }