1package prometheus 2 3import ( 4 "runtime" 5 "testing" 6 "time" 7 8 dto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_model/go" 9) 10 11func TestGoCollector(t *testing.T) { 12 var ( 13 c = NewGoCollector() 14 ch = make(chan Metric) 15 waitc = make(chan struct{}) 16 closec = make(chan struct{}) 17 old = -1 18 ) 19 defer close(closec) 20 21 go func() { 22 c.Collect(ch) 23 go func(c <-chan struct{}) { 24 <-c 25 }(closec) 26 <-waitc 27 c.Collect(ch) 28 }() 29 30 for { 31 select { 32 case metric := <-ch: 33 switch m := metric.(type) { 34 // Attention, this also catches Counter... 35 case Gauge: 36 pb := &dto.Metric{} 37 m.Write(pb) 38 if pb.GetGauge() == nil { 39 continue 40 } 41 42 if old == -1 { 43 old = int(pb.GetGauge().GetValue()) 44 close(waitc) 45 continue 46 } 47 48 if diff := int(pb.GetGauge().GetValue()) - old; diff != 1 { 49 // TODO: This is flaky in highly concurrent situations. 50 t.Errorf("want 1 new goroutine, got %d", diff) 51 } 52 53 // GoCollector performs two sends per call. 54 // On line 27 we need to receive the second send 55 // to shut down cleanly. 56 <-ch 57 return 58 } 59 case <-time.After(1 * time.Second): 60 t.Fatalf("expected collect timed out") 61 } 62 } 63} 64 65func TestGCCollector(t *testing.T) { 66 var ( 67 c = NewGoCollector() 68 ch = make(chan Metric) 69 waitc = make(chan struct{}) 70 closec = make(chan struct{}) 71 oldGC uint64 72 oldPause float64 73 ) 74 defer close(closec) 75 76 go func() { 77 c.Collect(ch) 78 // force GC 79 runtime.GC() 80 <-waitc 81 c.Collect(ch) 82 }() 83 84 first := true 85 for { 86 select { 87 case metric := <-ch: 88 switch m := metric.(type) { 89 case *constSummary, *value: 90 pb := &dto.Metric{} 91 m.Write(pb) 92 if pb.GetSummary() == nil { 93 continue 94 } 95 96 if len(pb.GetSummary().Quantile) != 5 { 97 t.Errorf("expected 4 buckets, got %d", len(pb.GetSummary().Quantile)) 98 } 99 for idx, want := range []float64{0.0, 0.25, 0.5, 0.75, 1.0} { 100 if *pb.GetSummary().Quantile[idx].Quantile != want { 101 t.Errorf("bucket #%d is off, got %f, want %f", idx, *pb.GetSummary().Quantile[idx].Quantile, want) 102 } 103 } 104 if first { 105 first = false 106 oldGC = *pb.GetSummary().SampleCount 107 oldPause = *pb.GetSummary().SampleSum 108 close(waitc) 109 continue 110 } 111 if diff := *pb.GetSummary().SampleCount - oldGC; diff != 1 { 112 t.Errorf("want 1 new garbage collection run, got %d", diff) 113 } 114 if diff := *pb.GetSummary().SampleSum - oldPause; diff <= 0 { 115 t.Errorf("want moar pause, got %f", diff) 116 } 117 return 118 } 119 case <-time.After(1 * time.Second): 120 t.Fatalf("expected collect timed out") 121 } 122 } 123} 124