metrics_receiver_honor_timestamp_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package prometheusreceiver
  4. import (
  5. "fmt"
  6. "sync"
  7. "testing"
  8. "time"
  9. promcfg "github.com/prometheus/prometheus/config"
  10. "github.com/stretchr/testify/assert"
  11. "go.opentelemetry.io/collector/pdata/pcommon"
  12. "go.opentelemetry.io/collector/pdata/pmetric"
  13. )
  14. var (
  15. timeNow = time.Now()
  16. ts1 = timeNow.Add(10 * time.Second).UnixMilli()
  17. ts2 = timeNow.Add(20 * time.Second).UnixMilli()
  18. ts3 = timeNow.Add(30 * time.Second).UnixMilli()
  19. ts4 = timeNow.Add(40 * time.Second).UnixMilli()
  20. ts5 = timeNow.Add(50 * time.Second).UnixMilli()
  21. ts6 = timeNow.Add(60 * time.Second).UnixMilli()
  22. ts7 = timeNow.Add(70 * time.Second).UnixMilli()
  23. ts8 = timeNow.Add(80 * time.Second).UnixMilli()
  24. ts9 = timeNow.Add(90 * time.Second).UnixMilli()
  25. ts10 = timeNow.Add(100 * time.Second).UnixMilli()
  26. ts11 = timeNow.Add(110 * time.Second).UnixMilli()
  27. ts12 = timeNow.Add(120 * time.Second).UnixMilli()
  28. ts13 = timeNow.Add(130 * time.Second).UnixMilli()
  29. ts14 = timeNow.Add(140 * time.Second).UnixMilli()
  30. ts15 = timeNow.Add(150 * time.Second).UnixMilli()
  31. )
  32. var onlyOnce sync.Once
  33. // honorTimestampsPage2 has lower values for metrics than honorTimestampsPage1.
  34. // So, the start_timestamp should get reset.
  35. var honorTimestampsPage1 = `
  36. # HELP go_threads Number of OS threads created
  37. # TYPE go_thread gauge
  38. go_threads 19 %v
  39. # HELP http_requests_total The total number of HTTP requests.
  40. # TYPE http_requests_total counter
  41. http_requests_total{method="post",code="200"} 100 %v
  42. http_requests_total{method="post",code="400"} 5 %v
  43. # HELP http_request_duration_seconds A histogram of the request duration.
  44. # TYPE http_request_duration_seconds histogram
  45. http_request_duration_seconds_bucket{le="0.05"} 1000 %v
  46. http_request_duration_seconds_bucket{le="0.5"} 1500 %v
  47. http_request_duration_seconds_bucket{le="1"} 2000 %v
  48. http_request_duration_seconds_bucket{le="+Inf"} 2500 %v
  49. http_request_duration_seconds_sum 5000 %v
  50. http_request_duration_seconds_count 2500 %v
  51. # HELP rpc_duration_seconds A summary of the RPC duration in seconds.
  52. # TYPE rpc_duration_seconds summary
  53. rpc_duration_seconds{quantile="0.01"} 1 %v
  54. rpc_duration_seconds{quantile="0.9"} 5 %v
  55. rpc_duration_seconds{quantile="0.99"} 8 %v
  56. rpc_duration_seconds_sum 5000 %v
  57. rpc_duration_seconds_count 1000 %v
  58. `
  59. var honorTimestampsPage2 = `
  60. # HELP go_threads Number of OS threads created
  61. # TYPE go_thread gauge
  62. go_threads 18 %v
  63. # HELP http_requests_total The total number of HTTP requests.
  64. # TYPE http_requests_total counter
  65. http_requests_total{method="post",code="200"} 99 %v
  66. http_requests_total{method="post",code="400"} 3 %v
  67. # HELP http_request_duration_seconds A histogram of the request duration.
  68. # TYPE http_request_duration_seconds histogram
  69. http_request_duration_seconds_bucket{le="0.05"} 900 %v
  70. http_request_duration_seconds_bucket{le="0.5"} 1400 %v
  71. http_request_duration_seconds_bucket{le="1"} 1900 %v
  72. http_request_duration_seconds_bucket{le="+Inf"} 2400 %v
  73. http_request_duration_seconds_sum 4950 %v
  74. http_request_duration_seconds_count 2400 %v
  75. # HELP rpc_duration_seconds A summary of the RPC duration in seconds.
  76. # TYPE rpc_duration_seconds summary
  77. rpc_duration_seconds{quantile="0.01"} 1 %v
  78. rpc_duration_seconds{quantile="0.9"} 6 %v
  79. rpc_duration_seconds{quantile="0.99"} 8 %v
  80. rpc_duration_seconds_sum 4980 %v
  81. rpc_duration_seconds_count 900 %v
  82. `
  83. // honorTimestampsPage3 has higher value than previous scrape.
  84. // So, start_timestamp should not be reset for honorTimestampsPage3
  85. var honorTimestampsPage3 = `
  86. # HELP go_threads Number of OS threads created
  87. # TYPE go_thread gauge
  88. go_threads 19 %v
  89. # HELP http_requests_total The total number of HTTP requests.
  90. # TYPE http_requests_total counter
  91. http_requests_total{method="post",code="200"} 100 %v
  92. http_requests_total{method="post",code="400"} 5 %v
  93. # HELP http_request_duration_seconds A histogram of the request duration.
  94. # TYPE http_request_duration_seconds histogram
  95. http_request_duration_seconds_bucket{le="0.05"} 1000 %v
  96. http_request_duration_seconds_bucket{le="0.5"} 1500 %v
  97. http_request_duration_seconds_bucket{le="1"} 2000 %v
  98. http_request_duration_seconds_bucket{le="+Inf"} 2500 %v
  99. http_request_duration_seconds_sum 5000 %v
  100. http_request_duration_seconds_count 2500 %v
  101. # HELP rpc_duration_seconds A summary of the RPC duration in seconds.
  102. # TYPE rpc_duration_seconds summary
  103. rpc_duration_seconds{quantile="0.01"} 1 %v
  104. rpc_duration_seconds{quantile="0.9"} 5 %v
  105. rpc_duration_seconds{quantile="0.99"} 8 %v
  106. rpc_duration_seconds_sum 5000 %v
  107. rpc_duration_seconds_count 1000 %v
  108. `
  109. // TestHonorTimeStampsWithTrue validates honor_timestamp configuration
  110. // where all metricFamilies (and each datapoint) in the testdata has explicit timestamps.
  111. // TestHonorTimeStampsWithTrue does not check for scenario where timestamp is not provided
  112. // to all metric families in a scrape- as those situations are rare though valid.
  113. // TestHonorTimeStampsWithTrue has testdata such that
  114. // For valid data- Start_timestamps should not be ahead of point_timestamps.
  115. // TestHonorTimeStampsWithTrue validates:
  116. // - For initial scrape, start_timestamp is same as point timestamp,
  117. // - Start_timestamp should be the explicit timestamp of first-time a particular metric is seen
  118. // - Start_timestamp should get reset if current scrape has lower value than previous scrape
  119. func TestHonorTimeStampsWithTrue(t *testing.T) {
  120. setMetricsTimestamp()
  121. targets := []*testData{
  122. {
  123. name: "target1",
  124. pages: []mockPrometheusResponse{
  125. {code: 200, data: honorTimestampsPage1},
  126. {code: 200, data: honorTimestampsPage2},
  127. {code: 200, data: honorTimestampsPage3},
  128. },
  129. validateFunc: verifyHonorTimeStampsTrue,
  130. },
  131. }
  132. testComponent(t, targets, nil)
  133. }
  134. // TestHonorTimeStampsWithFalse validates that with honor_timestamp config set to false,
  135. // valid testdata provided with explicit timestamps does not get honored.
  136. func TestHonorTimeStampsWithFalse(t *testing.T) {
  137. setMetricsTimestamp()
  138. targets := []*testData{
  139. {
  140. name: "target1",
  141. pages: []mockPrometheusResponse{
  142. {code: 200, data: honorTimestampsPage1},
  143. {code: 200, data: honorTimestampsPage2},
  144. },
  145. validateFunc: verifyHonorTimeStampsFalse,
  146. },
  147. }
  148. testComponent(t, targets, nil, func(cfg *promcfg.Config) {
  149. for _, scrapeConfig := range cfg.ScrapeConfigs {
  150. scrapeConfig.HonorTimestamps = false
  151. }
  152. })
  153. }
  154. func setMetricsTimestamp() {
  155. onlyOnce.Do(func() {
  156. honorTimestampsPage1 = fmt.Sprintf(honorTimestampsPage1,
  157. ts1, // timestamp for gauge
  158. ts2, ts3, // timestamp for counter
  159. ts4, ts4, ts4, ts4, ts4, ts4, // timestamp for histogram
  160. ts5, ts5, ts5, ts5, ts5, // timestamp for summary
  161. )
  162. honorTimestampsPage2 = fmt.Sprintf(honorTimestampsPage2,
  163. ts6, // timestamp for gauge
  164. ts7, ts8, // timestamp for counter
  165. ts9, ts9, ts9, ts9, ts9, ts9, // timestamp for histogram
  166. ts10, ts10, ts10, ts10, ts10, // timestamp for summary
  167. )
  168. honorTimestampsPage3 = fmt.Sprintf(honorTimestampsPage3,
  169. ts11, // timestamp for gauge
  170. ts12, ts13, // timestamp for counter
  171. ts14, ts14, ts14, ts14, ts14, ts14, // timestamp for histogram
  172. ts15, ts15, ts15, ts15, ts15, // timestamp for summary
  173. )
  174. })
  175. }
  176. func verifyHonorTimeStampsTrue(t *testing.T, td *testData, resourceMetrics []pmetric.ResourceMetrics) {
  177. verifyNumValidScrapeResults(t, td, resourceMetrics)
  178. m1 := resourceMetrics[0]
  179. // m1 has 4 metrics + 5 internal scraper metrics
  180. assert.Equal(t, 9, metricsCount(m1))
  181. wantAttributes := td.attributes
  182. e1 := []testExpectation{
  183. assertMetricPresent("go_threads",
  184. compareMetricType(pmetric.MetricTypeGauge),
  185. compareMetricUnit(""),
  186. []dataPointExpectation{
  187. {
  188. numberPointComparator: []numberPointComparator{
  189. compareTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts1))),
  190. compareDoubleValue(19),
  191. },
  192. },
  193. }),
  194. assertMetricPresent("http_requests_total",
  195. compareMetricType(pmetric.MetricTypeSum),
  196. compareMetricUnit(""),
  197. []dataPointExpectation{
  198. {
  199. numberPointComparator: []numberPointComparator{
  200. compareStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts2))),
  201. compareTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts2))),
  202. compareDoubleValue(100),
  203. compareAttributes(map[string]string{"method": "post", "code": "200"}),
  204. },
  205. },
  206. {
  207. numberPointComparator: []numberPointComparator{
  208. compareStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts3))),
  209. compareTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts3))),
  210. compareDoubleValue(5),
  211. compareAttributes(map[string]string{"method": "post", "code": "400"}),
  212. },
  213. },
  214. }),
  215. assertMetricPresent("http_request_duration_seconds",
  216. compareMetricType(pmetric.MetricTypeHistogram),
  217. compareMetricUnit(""),
  218. []dataPointExpectation{
  219. {
  220. histogramPointComparator: []histogramPointComparator{
  221. compareHistogramStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts4))),
  222. compareHistogramTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts4))),
  223. compareHistogram(2500, 5000, []float64{0.05, 0.5, 1}, []uint64{1000, 500, 500, 500}),
  224. },
  225. },
  226. }),
  227. assertMetricPresent("rpc_duration_seconds",
  228. compareMetricType(pmetric.MetricTypeSummary),
  229. compareMetricUnit(""),
  230. []dataPointExpectation{
  231. {
  232. summaryPointComparator: []summaryPointComparator{
  233. compareSummaryStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts5))),
  234. compareSummaryTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts5))),
  235. compareSummary(1000, 5000, [][]float64{{0.01, 1}, {0.9, 5}, {0.99, 8}}),
  236. },
  237. },
  238. }),
  239. }
  240. doCompare(t, "scrape-honorTimestamp-1", wantAttributes, m1, e1)
  241. m2 := resourceMetrics[1]
  242. // m1 has 4 metrics + 5 internal scraper metrics
  243. assert.Equal(t, 9, metricsCount(m2))
  244. e2 := []testExpectation{
  245. assertMetricPresent("go_threads",
  246. compareMetricType(pmetric.MetricTypeGauge),
  247. compareMetricUnit(""),
  248. []dataPointExpectation{
  249. {
  250. numberPointComparator: []numberPointComparator{
  251. compareTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts6))),
  252. compareDoubleValue(18),
  253. },
  254. },
  255. }),
  256. assertMetricPresent("http_requests_total",
  257. compareMetricType(pmetric.MetricTypeSum),
  258. compareMetricUnit(""),
  259. []dataPointExpectation{
  260. {
  261. numberPointComparator: []numberPointComparator{
  262. compareStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts7))),
  263. compareTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts7))),
  264. compareDoubleValue(99),
  265. compareAttributes(map[string]string{"method": "post", "code": "200"}),
  266. },
  267. },
  268. {
  269. numberPointComparator: []numberPointComparator{
  270. compareStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts8))),
  271. compareTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts8))),
  272. compareDoubleValue(3),
  273. compareAttributes(map[string]string{"method": "post", "code": "400"}),
  274. },
  275. },
  276. }),
  277. assertMetricPresent("http_request_duration_seconds",
  278. compareMetricType(pmetric.MetricTypeHistogram),
  279. compareMetricUnit(""),
  280. []dataPointExpectation{
  281. {
  282. histogramPointComparator: []histogramPointComparator{
  283. compareHistogramStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts9))),
  284. compareHistogramTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts9))),
  285. compareHistogram(2400, 4950, []float64{0.05, 0.5, 1}, []uint64{900, 500, 500, 500}),
  286. },
  287. },
  288. }),
  289. assertMetricPresent("rpc_duration_seconds",
  290. compareMetricType(pmetric.MetricTypeSummary),
  291. compareMetricUnit(""),
  292. []dataPointExpectation{
  293. {
  294. summaryPointComparator: []summaryPointComparator{
  295. compareSummaryStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts10))),
  296. compareSummaryTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts10))),
  297. compareSummary(900, 4980, [][]float64{{0.01, 1}, {0.9, 6}, {0.99, 8}}),
  298. },
  299. },
  300. }),
  301. }
  302. doCompare(t, "scrape-honorTimestamp-2", wantAttributes, m2, e2)
  303. m3 := resourceMetrics[2]
  304. // m1 has 4 metrics + 5 internal scraper metrics
  305. assert.Equal(t, 9, metricsCount(m3))
  306. e3 := []testExpectation{
  307. assertMetricPresent("go_threads",
  308. compareMetricType(pmetric.MetricTypeGauge),
  309. compareMetricUnit(""),
  310. []dataPointExpectation{
  311. {
  312. numberPointComparator: []numberPointComparator{
  313. compareTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts11))),
  314. compareDoubleValue(19),
  315. },
  316. },
  317. }),
  318. assertMetricPresent("http_requests_total",
  319. compareMetricType(pmetric.MetricTypeSum),
  320. compareMetricUnit(""),
  321. []dataPointExpectation{
  322. {
  323. numberPointComparator: []numberPointComparator{
  324. compareStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts7))),
  325. compareTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts12))),
  326. compareDoubleValue(100),
  327. compareAttributes(map[string]string{"method": "post", "code": "200"}),
  328. },
  329. },
  330. {
  331. numberPointComparator: []numberPointComparator{
  332. compareStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts8))),
  333. compareTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts13))),
  334. compareDoubleValue(5),
  335. compareAttributes(map[string]string{"method": "post", "code": "400"}),
  336. },
  337. },
  338. }),
  339. assertMetricPresent("http_request_duration_seconds",
  340. compareMetricType(pmetric.MetricTypeHistogram),
  341. compareMetricUnit(""),
  342. []dataPointExpectation{
  343. {
  344. histogramPointComparator: []histogramPointComparator{
  345. compareHistogramStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts9))),
  346. compareHistogramTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts14))),
  347. compareHistogram(2500, 5000, []float64{0.05, 0.5, 1}, []uint64{1000, 500, 500, 500}),
  348. },
  349. },
  350. }),
  351. assertMetricPresent("rpc_duration_seconds",
  352. compareMetricType(pmetric.MetricTypeSummary),
  353. compareMetricUnit(""),
  354. []dataPointExpectation{
  355. {
  356. summaryPointComparator: []summaryPointComparator{
  357. compareSummaryStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts10))),
  358. compareSummaryTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts15))),
  359. compareSummary(1000, 5000, [][]float64{{0.01, 1}, {0.9, 5}, {0.99, 8}}),
  360. },
  361. },
  362. }),
  363. }
  364. doCompare(t, "scrape-honorTimestamp-3", wantAttributes, m3, e3)
  365. }
  366. func verifyHonorTimeStampsFalse(t *testing.T, td *testData, resourceMetrics []pmetric.ResourceMetrics) {
  367. verifyNumValidScrapeResults(t, td, resourceMetrics)
  368. m1 := resourceMetrics[0]
  369. // m1 has 4 metrics + 5 internal scraper metrics
  370. assert.Equal(t, 9, metricsCount(m1))
  371. wantAttributes := td.attributes
  372. metrics1 := m1.ScopeMetrics().At(0).Metrics()
  373. ts1 := getTS(metrics1)
  374. e1 := []testExpectation{
  375. assertMetricPresent("go_threads",
  376. compareMetricType(pmetric.MetricTypeGauge),
  377. compareMetricUnit(""),
  378. []dataPointExpectation{
  379. {
  380. numberPointComparator: []numberPointComparator{
  381. compareTimestamp(ts1),
  382. compareDoubleValue(19),
  383. },
  384. },
  385. }),
  386. assertMetricPresent("http_requests_total",
  387. compareMetricType(pmetric.MetricTypeSum),
  388. compareMetricUnit(""),
  389. []dataPointExpectation{
  390. {
  391. numberPointComparator: []numberPointComparator{
  392. compareStartTimestamp(ts1),
  393. compareTimestamp(ts1),
  394. compareDoubleValue(100),
  395. compareAttributes(map[string]string{"method": "post", "code": "200"}),
  396. },
  397. },
  398. {
  399. numberPointComparator: []numberPointComparator{
  400. compareStartTimestamp(ts1),
  401. compareTimestamp(ts1),
  402. compareDoubleValue(5),
  403. compareAttributes(map[string]string{"method": "post", "code": "400"}),
  404. },
  405. },
  406. }),
  407. assertMetricPresent("http_request_duration_seconds",
  408. compareMetricType(pmetric.MetricTypeHistogram),
  409. compareMetricUnit(""),
  410. []dataPointExpectation{
  411. {
  412. histogramPointComparator: []histogramPointComparator{
  413. compareHistogramStartTimestamp(ts1),
  414. compareHistogramTimestamp(ts1),
  415. compareHistogram(2500, 5000, []float64{0.05, 0.5, 1}, []uint64{1000, 500, 500, 500}),
  416. },
  417. },
  418. }),
  419. assertMetricPresent("rpc_duration_seconds",
  420. compareMetricType(pmetric.MetricTypeSummary),
  421. compareMetricUnit(""),
  422. []dataPointExpectation{
  423. {
  424. summaryPointComparator: []summaryPointComparator{
  425. compareSummaryStartTimestamp(ts1),
  426. compareSummaryTimestamp(ts1),
  427. compareSummary(1000, 5000, [][]float64{{0.01, 1}, {0.9, 5}, {0.99, 8}}),
  428. },
  429. },
  430. }),
  431. }
  432. doCompare(t, "scrape-honorTimestamp-1", wantAttributes, m1, e1)
  433. m2 := resourceMetrics[1]
  434. // m2 has 4 metrics + 5 internal scraper metrics
  435. assert.Equal(t, 9, metricsCount(m2))
  436. metricsScrape2 := m2.ScopeMetrics().At(0).Metrics()
  437. ts2 := getTS(metricsScrape2)
  438. e2 := []testExpectation{
  439. assertMetricPresent("go_threads",
  440. compareMetricType(pmetric.MetricTypeGauge),
  441. compareMetricUnit(""),
  442. []dataPointExpectation{
  443. {
  444. numberPointComparator: []numberPointComparator{
  445. compareTimestamp(ts2),
  446. compareDoubleValue(18),
  447. },
  448. },
  449. }),
  450. assertMetricPresent("http_requests_total",
  451. compareMetricType(pmetric.MetricTypeSum),
  452. compareMetricUnit(""),
  453. []dataPointExpectation{
  454. {
  455. numberPointComparator: []numberPointComparator{
  456. compareStartTimestamp(ts2),
  457. compareTimestamp(ts2),
  458. compareDoubleValue(99),
  459. compareAttributes(map[string]string{"method": "post", "code": "200"}),
  460. },
  461. },
  462. {
  463. numberPointComparator: []numberPointComparator{
  464. compareStartTimestamp(ts2),
  465. compareTimestamp(ts2),
  466. compareDoubleValue(3),
  467. compareAttributes(map[string]string{"method": "post", "code": "400"}),
  468. },
  469. },
  470. }),
  471. assertMetricPresent("http_request_duration_seconds",
  472. compareMetricType(pmetric.MetricTypeHistogram),
  473. compareMetricUnit(""),
  474. []dataPointExpectation{
  475. {
  476. histogramPointComparator: []histogramPointComparator{
  477. compareHistogramStartTimestamp(ts2),
  478. compareHistogramTimestamp(ts2),
  479. compareHistogram(2400, 4950, []float64{0.05, 0.5, 1}, []uint64{900, 500, 500, 500}),
  480. },
  481. },
  482. }),
  483. assertMetricPresent("rpc_duration_seconds",
  484. compareMetricType(pmetric.MetricTypeSummary),
  485. compareMetricUnit(""),
  486. []dataPointExpectation{
  487. {
  488. summaryPointComparator: []summaryPointComparator{
  489. compareSummaryStartTimestamp(ts2),
  490. compareSummaryTimestamp(ts2),
  491. compareSummary(900, 4980, [][]float64{{0.01, 1}, {0.9, 6}, {0.99, 8}}),
  492. },
  493. },
  494. }),
  495. }
  496. doCompare(t, "scrape-honorTimestamp-2", wantAttributes, m2, e2)
  497. }