Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 

366 rindas
11 KiB

  1. // Copyright 2018, OpenCensus Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package metric
  15. import (
  16. "fmt"
  17. "go.opencensus.io/metric/metricdata"
  18. "sort"
  19. "testing"
  20. "time"
  21. "github.com/google/go-cmp/cmp"
  22. )
  23. func TestGauge(t *testing.T) {
  24. r := NewRegistry()
  25. f, _ := r.AddFloat64Gauge("TestGauge", "", "", "k1", "k2")
  26. e, _ := f.GetEntry(metricdata.LabelValue{}, metricdata.LabelValue{})
  27. e.Set(5)
  28. e, _ = f.GetEntry(metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
  29. e.Add(1)
  30. e, _ = f.GetEntry(metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
  31. e.Add(1)
  32. e, _ = f.GetEntry(metricdata.NewLabelValue("k1v2"), metricdata.NewLabelValue("k2v2"))
  33. e.Add(1)
  34. m := r.Read()
  35. want := []*metricdata.Metric{
  36. {
  37. Descriptor: metricdata.Descriptor{
  38. Name: "TestGauge",
  39. LabelKeys: []string{"k1", "k2"},
  40. },
  41. TimeSeries: []*metricdata.TimeSeries{
  42. {
  43. LabelValues: []metricdata.LabelValue{
  44. {}, {},
  45. },
  46. Points: []metricdata.Point{
  47. metricdata.NewFloat64Point(time.Time{}, 5),
  48. },
  49. },
  50. {
  51. LabelValues: []metricdata.LabelValue{
  52. metricdata.NewLabelValue("k1v1"),
  53. {},
  54. },
  55. Points: []metricdata.Point{
  56. metricdata.NewFloat64Point(time.Time{}, 2),
  57. },
  58. },
  59. {
  60. LabelValues: []metricdata.LabelValue{
  61. metricdata.NewLabelValue("k1v2"),
  62. metricdata.NewLabelValue("k2v2"),
  63. },
  64. Points: []metricdata.Point{
  65. metricdata.NewFloat64Point(time.Time{}, 1),
  66. },
  67. },
  68. },
  69. },
  70. }
  71. canonicalize(m)
  72. canonicalize(want)
  73. if diff := cmp.Diff(m, want, cmp.Comparer(ignoreTimes)); diff != "" {
  74. t.Errorf("-got +want: %s", diff)
  75. }
  76. }
  77. func TestFloat64Entry_Add(t *testing.T) {
  78. r := NewRegistry()
  79. g, _ := r.AddFloat64Gauge("g", "", metricdata.UnitDimensionless)
  80. e, _ := g.GetEntry()
  81. e.Add(0)
  82. ms := r.Read()
  83. if got, want := ms[0].TimeSeries[0].Points[0].Value.(float64), 0.0; got != want {
  84. t.Errorf("value = %v, want %v", got, want)
  85. }
  86. e, _ = g.GetEntry()
  87. e.Add(1)
  88. ms = r.Read()
  89. if got, want := ms[0].TimeSeries[0].Points[0].Value.(float64), 1.0; got != want {
  90. t.Errorf("value = %v, want %v", got, want)
  91. }
  92. e, _ = g.GetEntry()
  93. e.Add(-1)
  94. ms = r.Read()
  95. if got, want := ms[0].TimeSeries[0].Points[0].Value.(float64), 0.0; got != want {
  96. t.Errorf("value = %v, want %v", got, want)
  97. }
  98. }
  99. func TestFloat64Gauge_Add_NegativeTotals(t *testing.T) {
  100. r := NewRegistry()
  101. g, _ := r.AddFloat64Gauge("g", "", metricdata.UnitDimensionless)
  102. e, _ := g.GetEntry()
  103. e.Add(-1.0)
  104. ms := r.Read()
  105. if got, want := ms[0].TimeSeries[0].Points[0].Value.(float64), float64(0); got != want {
  106. t.Errorf("value = %v, want %v", got, want)
  107. }
  108. }
  109. func TestInt64GaugeEntry_Add(t *testing.T) {
  110. r := NewRegistry()
  111. g, _ := r.AddInt64Gauge("g", "", metricdata.UnitDimensionless)
  112. e, _ := g.GetEntry()
  113. e.Add(0)
  114. ms := r.Read()
  115. if got, want := ms[0].TimeSeries[0].Points[0].Value.(int64), int64(0); got != want {
  116. t.Errorf("value = %v, want %v", got, want)
  117. }
  118. e, _ = g.GetEntry()
  119. e.Add(1)
  120. ms = r.Read()
  121. if got, want := ms[0].TimeSeries[0].Points[0].Value.(int64), int64(1); got != want {
  122. t.Errorf("value = %v, want %v", got, want)
  123. }
  124. }
  125. func TestInt64Gauge_Add_NegativeTotals(t *testing.T) {
  126. r := NewRegistry()
  127. g, _ := r.AddInt64Gauge("g", "", metricdata.UnitDimensionless)
  128. e, _ := g.GetEntry()
  129. e.Add(-1)
  130. ms := r.Read()
  131. if got, want := ms[0].TimeSeries[0].Points[0].Value.(int64), int64(0); got != want {
  132. t.Errorf("value = %v, want %v", got, want)
  133. }
  134. }
  135. func TestGaugeWithSameNameDiffType(t *testing.T) {
  136. r := NewRegistry()
  137. r.AddInt64Gauge("g", "", metricdata.UnitDimensionless)
  138. _, gotErr := r.AddFloat64Gauge("g", "", metricdata.UnitDimensionless)
  139. if gotErr == nil {
  140. t.Errorf("got: nil, want error: %v", errGaugeExistsWithDiffType)
  141. }
  142. _, gotErr = r.AddInt64DerivedGauge("g", "", metricdata.UnitDimensionless)
  143. if gotErr == nil {
  144. t.Errorf("got: nil, want error: %v", errGaugeExistsWithDiffType)
  145. }
  146. _, gotErr = r.AddFloat64DerivedGauge("g", "", metricdata.UnitDimensionless)
  147. if gotErr == nil {
  148. t.Errorf("got: nil, want error: %v", errGaugeExistsWithDiffType)
  149. }
  150. }
  151. func TestGaugeWithLabelMismatch(t *testing.T) {
  152. r := NewRegistry()
  153. g, _ := r.AddInt64Gauge("g", "", metricdata.UnitDimensionless, "k1")
  154. _, gotErr := g.GetEntry(metricdata.NewLabelValue("k1v2"), metricdata.NewLabelValue("k2v2"))
  155. if gotErr == nil {
  156. t.Errorf("got: nil, want error: %v", errKeyValueMismatch)
  157. }
  158. }
  159. func TestMapKey(t *testing.T) {
  160. cases := [][]metricdata.LabelValue{
  161. {},
  162. {metricdata.LabelValue{}},
  163. {metricdata.NewLabelValue("")},
  164. {metricdata.NewLabelValue("-")},
  165. {metricdata.NewLabelValue(",")},
  166. {metricdata.NewLabelValue("v1"), metricdata.NewLabelValue("v2")},
  167. {metricdata.NewLabelValue("v1"), metricdata.LabelValue{}},
  168. {metricdata.NewLabelValue("v1"), metricdata.LabelValue{}, metricdata.NewLabelValue(string([]byte{0}))},
  169. {metricdata.LabelValue{}, metricdata.LabelValue{}},
  170. }
  171. for i, tc := range cases {
  172. t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
  173. g := &gauge{
  174. keys: make([]string, len(tc)),
  175. }
  176. mk := g.mapKey(tc)
  177. vals := g.labelValues(mk)
  178. if diff := cmp.Diff(vals, tc); diff != "" {
  179. t.Errorf("values differ after serialization -got +want: %s", diff)
  180. }
  181. })
  182. }
  183. }
  184. func TestRaceCondition(t *testing.T) {
  185. r := NewRegistry()
  186. // start reader before adding Gauge metric.
  187. var ms = []*metricdata.Metric{}
  188. for i := 0; i < 5; i++ {
  189. go func(k int) {
  190. for j := 0; j < 5; j++ {
  191. g, _ := r.AddInt64Gauge(fmt.Sprintf("g%d%d", k, j), "", metricdata.UnitDimensionless)
  192. e, _ := g.GetEntry()
  193. e.Add(1)
  194. }
  195. }(i)
  196. }
  197. time.Sleep(1 * time.Second)
  198. ms = r.Read()
  199. if got, want := ms[0].TimeSeries[0].Points[0].Value.(int64), int64(1); got != want {
  200. t.Errorf("value = %v, want %v", got, want)
  201. }
  202. }
  203. func ignoreTimes(_, _ time.Time) bool {
  204. return true
  205. }
  206. func canonicalize(ms []*metricdata.Metric) {
  207. for _, m := range ms {
  208. sort.Slice(m.TimeSeries, func(i, j int) bool {
  209. // sort time series by their label values
  210. iLabels := m.TimeSeries[i].LabelValues
  211. jLabels := m.TimeSeries[j].LabelValues
  212. for k := 0; k < len(iLabels); k++ {
  213. if !iLabels[k].Present {
  214. if jLabels[k].Present {
  215. return true
  216. }
  217. } else if !jLabels[k].Present {
  218. return false
  219. } else {
  220. return iLabels[k].Value < jLabels[k].Value
  221. }
  222. }
  223. panic("should have returned")
  224. })
  225. }
  226. }
  227. type queueInt64 struct {
  228. size int64
  229. }
  230. func (q *queueInt64) ToInt64() int64 {
  231. return q.size
  232. }
  233. func TestInt64DerivedGaugeEntry_Add(t *testing.T) {
  234. r := NewRegistry()
  235. q := &queueInt64{3}
  236. g, _ := r.AddInt64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
  237. err := g.UpsertEntry(q.ToInt64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
  238. if err != nil {
  239. t.Errorf("want: nil, got: %v", err)
  240. }
  241. ms := r.Read()
  242. if got, want := ms[0].TimeSeries[0].Points[0].Value.(int64), int64(3); got != want {
  243. t.Errorf("value = %v, want %v", got, want)
  244. }
  245. q.size = 5
  246. ms = r.Read()
  247. if got, want := ms[0].TimeSeries[0].Points[0].Value.(int64), int64(5); got != want {
  248. t.Errorf("value = %v, want %v", got, want)
  249. }
  250. }
  251. func TestInt64DerivedGaugeEntry_AddWithNilObj(t *testing.T) {
  252. r := NewRegistry()
  253. g, _ := r.AddInt64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
  254. gotErr := g.UpsertEntry(nil, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
  255. if gotErr == nil {
  256. t.Errorf("expected error but got nil")
  257. }
  258. }
  259. func TestInt64DerivedGaugeEntry_AddWithInvalidLabels(t *testing.T) {
  260. r := NewRegistry()
  261. q := &queueInt64{3}
  262. g, _ := r.AddInt64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
  263. gotErr := g.UpsertEntry(q.ToInt64, metricdata.NewLabelValue("k1v1"))
  264. if gotErr == nil {
  265. t.Errorf("expected error but got nil")
  266. }
  267. }
  268. func TestInt64DerivedGaugeEntry_Update(t *testing.T) {
  269. r := NewRegistry()
  270. q := &queueInt64{3}
  271. q2 := &queueInt64{5}
  272. g, _ := r.AddInt64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
  273. g.UpsertEntry(q.ToInt64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
  274. gotErr := g.UpsertEntry(q2.ToInt64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
  275. if gotErr != nil {
  276. t.Errorf("got: %v, want: nil", gotErr)
  277. }
  278. ms := r.Read()
  279. if got, want := ms[0].TimeSeries[0].Points[0].Value.(int64), int64(5); got != want {
  280. t.Errorf("value = %v, want %v", got, want)
  281. }
  282. }
  283. type queueFloat64 struct {
  284. size float64
  285. }
  286. func (q *queueFloat64) ToFloat64() float64 {
  287. return q.size
  288. }
  289. func TestFloat64DerivedGaugeEntry_Add(t *testing.T) {
  290. r := NewRegistry()
  291. q := &queueFloat64{5.0}
  292. g, _ := r.AddFloat64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
  293. err := g.UpsertEntry(q.ToFloat64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
  294. if err != nil {
  295. t.Errorf("want: nil, got: %v", err)
  296. }
  297. ms := r.Read()
  298. if got, want := ms[0].TimeSeries[0].Points[0].Value.(float64), float64(5.0); got != want {
  299. t.Errorf("value = %v, want %v", got, want)
  300. }
  301. q.size = 5
  302. ms = r.Read()
  303. if got, want := ms[0].TimeSeries[0].Points[0].Value.(float64), float64(5.0); got != want {
  304. t.Errorf("value = %v, want %v", got, want)
  305. }
  306. }
  307. func TestFloat64DerivedGaugeEntry_AddWithNilObj(t *testing.T) {
  308. r := NewRegistry()
  309. g, _ := r.AddFloat64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
  310. gotErr := g.UpsertEntry(nil, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
  311. if gotErr == nil {
  312. t.Errorf("expected error but got nil")
  313. }
  314. }
  315. func TestFloat64DerivedGaugeEntry_AddWithInvalidLabels(t *testing.T) {
  316. r := NewRegistry()
  317. q := &queueFloat64{3}
  318. g, _ := r.AddFloat64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
  319. gotErr := g.UpsertEntry(q.ToFloat64, metricdata.NewLabelValue("k1v1"))
  320. if gotErr == nil {
  321. t.Errorf("expected error but got nil")
  322. }
  323. }
  324. func TestFloat64DerivedGaugeEntry_Update(t *testing.T) {
  325. r := NewRegistry()
  326. q := &queueFloat64{3.0}
  327. q2 := &queueFloat64{5.0}
  328. g, _ := r.AddFloat64DerivedGauge("g", "", metricdata.UnitDimensionless, "k1", "k2")
  329. g.UpsertEntry(q.ToFloat64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
  330. gotErr := g.UpsertEntry(q2.ToFloat64, metricdata.NewLabelValue("k1v1"), metricdata.LabelValue{})
  331. if gotErr != nil {
  332. t.Errorf("got: %v, want: nil", gotErr)
  333. }
  334. ms := r.Read()
  335. if got, want := ms[0].TimeSeries[0].Points[0].Value.(float64), float64(5.0); got != want {
  336. t.Errorf("value = %v, want %v", got, want)
  337. }
  338. }