1 /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
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 ==============================================================================*/
15
16 #include "tensorflow/core/lib/monitoring/collection_registry.h"
17
18 #include "tensorflow/core/lib/monitoring/counter.h"
19 #include "tensorflow/core/lib/monitoring/gauge.h"
20 #include "tensorflow/core/lib/monitoring/percentile_sampler.h"
21 #include "tensorflow/core/lib/monitoring/sampler.h"
22 #include "tensorflow/core/lib/strings/strcat.h"
23 #include "tensorflow/core/platform/protobuf.h"
24 #include "tensorflow/core/platform/test.h"
25
26 namespace tensorflow {
27 namespace monitoring {
28
29 using histogram::Histogram;
30
31 namespace test_util {
32
33 class CollectionRegistryTestAccess {
34 public:
CreateRegistry(Env * const env)35 static std::unique_ptr<CollectionRegistry> CreateRegistry(Env* const env) {
36 return std::unique_ptr<CollectionRegistry>(new CollectionRegistry(env));
37 }
38 };
39
40 } // namespace test_util
41
42 namespace {
43
EmptyCollectionFunction(MetricCollectorGetter getter)44 void EmptyCollectionFunction(MetricCollectorGetter getter) {}
45
TEST(CollectionRegistryTest,RegistrationUnregistration)46 TEST(CollectionRegistryTest, RegistrationUnregistration) {
47 auto* collection_registry = CollectionRegistry::Default();
48 const MetricDef<MetricKind::kCumulative, int64, 0> metric_def0(
49 "/tensorflow/metric0", "An example metric with no labels.");
50 const MetricDef<MetricKind::kGauge, HistogramProto, 1> metric_def1(
51 "/tensorflow/metric1", "An example metric with one label.", "LabelName");
52
53 {
54 // Enclosed in a scope so that we unregister before the stack variables
55 // above are destroyed.
56
57 std::unique_ptr<CollectionRegistry::RegistrationHandle> handle0 =
58 collection_registry->Register(&metric_def0, EmptyCollectionFunction);
59 std::unique_ptr<CollectionRegistry::RegistrationHandle> handle1 =
60 collection_registry->Register(&metric_def1, EmptyCollectionFunction);
61
62 handle0.reset();
63
64 // Able to register again because it was unregistered earlier.
65 handle0 =
66 collection_registry->Register(&metric_def0, EmptyCollectionFunction);
67 }
68 }
69
TEST(CollectionRegistryDeathTest,DuplicateRegistration)70 TEST(CollectionRegistryDeathTest, DuplicateRegistration) {
71 auto* collection_registry = CollectionRegistry::Default();
72 const MetricDef<MetricKind::kCumulative, int64, 0> metric_def(
73 "/tensorflow/metric", "An example metric with no labels.");
74
75 auto handle =
76 collection_registry->Register(&metric_def, EmptyCollectionFunction);
77 auto duplicate_handle =
78 collection_registry->Register(&metric_def, EmptyCollectionFunction);
79 EXPECT_EQ(duplicate_handle, nullptr);
80 }
81
TEST(CollectMetricsTest,Counter)82 TEST(CollectMetricsTest, Counter) {
83 auto counter_with_labels = std::unique_ptr<Counter<2>>(
84 Counter<2>::New("/tensorflow/test/counter_with_labels",
85 "Counter with labels.", "MyLabel0", "MyLabel1"));
86 auto counter_without_labels = std::unique_ptr<Counter<0>>(Counter<0>::New(
87 "/tensorflow/test/counter_without_labels", "Counter without labels."));
88
89 counter_with_labels->GetCell("Label00", "Label10")->IncrementBy(42);
90 counter_with_labels->GetCell("Label01", "Label11")->IncrementBy(58);
91 counter_without_labels->GetCell()->IncrementBy(7);
92
93 for (const bool collect_metric_descriptors : {true, false}) {
94 SCOPED_TRACE(strings::StrCat("collect_metric_descriptors: ",
95 collect_metric_descriptors));
96
97 auto* collection_registry = CollectionRegistry::Default();
98 CollectionRegistry::CollectMetricsOptions options;
99 options.collect_metric_descriptors = collect_metric_descriptors;
100 const std::unique_ptr<CollectedMetrics> collected_metrics =
101 collection_registry->CollectMetrics(options);
102
103 if (collect_metric_descriptors) {
104 ASSERT_GE(collected_metrics->metric_descriptor_map.size(), 2);
105
106 const MetricDescriptor& ld = *collected_metrics->metric_descriptor_map.at(
107 "/tensorflow/test/counter_with_labels");
108 EXPECT_EQ("/tensorflow/test/counter_with_labels", ld.name);
109 EXPECT_EQ("Counter with labels.", ld.description);
110 ASSERT_EQ(2, ld.label_names.size());
111 EXPECT_EQ("MyLabel0", ld.label_names[0]);
112 EXPECT_EQ("MyLabel1", ld.label_names[1]);
113 EXPECT_EQ(MetricKind::kCumulative, ld.metric_kind);
114 EXPECT_EQ(ValueType::kInt64, ld.value_type);
115
116 const MetricDescriptor& ud = *collected_metrics->metric_descriptor_map.at(
117 "/tensorflow/test/counter_without_labels");
118 EXPECT_EQ("/tensorflow/test/counter_without_labels", ud.name);
119 EXPECT_EQ("Counter without labels.", ud.description);
120 ASSERT_EQ(0, ud.label_names.size());
121 EXPECT_EQ(MetricKind::kCumulative, ud.metric_kind);
122 EXPECT_EQ(ValueType::kInt64, ud.value_type);
123 } else {
124 EXPECT_EQ(0, collected_metrics->metric_descriptor_map.size());
125 }
126
127 ASSERT_GE(collected_metrics->point_set_map.size(), 2);
128
129 const PointSet& lps = *collected_metrics->point_set_map.at(
130 "/tensorflow/test/counter_with_labels");
131 EXPECT_EQ("/tensorflow/test/counter_with_labels", lps.metric_name);
132 ASSERT_EQ(2, lps.points.size());
133 ASSERT_EQ(2, lps.points[0]->labels.size());
134 EXPECT_EQ("MyLabel0", lps.points[0]->labels[0].name);
135 EXPECT_EQ("Label00", lps.points[0]->labels[0].value);
136 EXPECT_EQ("MyLabel1", lps.points[0]->labels[1].name);
137 EXPECT_EQ("Label10", lps.points[0]->labels[1].value);
138 EXPECT_EQ(ValueType::kInt64, lps.points[0]->value_type);
139 EXPECT_EQ(42, lps.points[0]->int64_value);
140 EXPECT_LT(0, lps.points[0]->start_timestamp_millis);
141 EXPECT_LT(0, lps.points[0]->end_timestamp_millis);
142 EXPECT_GE(lps.points[0]->end_timestamp_millis,
143 lps.points[0]->start_timestamp_millis);
144 ASSERT_EQ(2, lps.points[1]->labels.size());
145 EXPECT_EQ("MyLabel0", lps.points[1]->labels[0].name);
146 EXPECT_EQ("Label01", lps.points[1]->labels[0].value);
147 EXPECT_EQ("MyLabel1", lps.points[1]->labels[1].name);
148 EXPECT_EQ("Label11", lps.points[1]->labels[1].value);
149 EXPECT_EQ(ValueType::kInt64, lps.points[1]->value_type);
150 EXPECT_EQ(58, lps.points[1]->int64_value);
151 EXPECT_LT(0, lps.points[1]->start_timestamp_millis);
152 EXPECT_LT(0, lps.points[1]->end_timestamp_millis);
153 EXPECT_GE(lps.points[1]->end_timestamp_millis,
154 lps.points[1]->start_timestamp_millis);
155
156 const PointSet& ups = *collected_metrics->point_set_map.at(
157 "/tensorflow/test/counter_without_labels");
158 EXPECT_EQ("/tensorflow/test/counter_without_labels", ups.metric_name);
159 ASSERT_EQ(1, ups.points.size());
160 EXPECT_EQ(0, ups.points[0]->labels.size());
161 EXPECT_EQ(ValueType::kInt64, ups.points[0]->value_type);
162 EXPECT_EQ(7, ups.points[0]->int64_value);
163 EXPECT_LT(0, ups.points[0]->start_timestamp_millis);
164 EXPECT_LT(0, ups.points[0]->end_timestamp_millis);
165 EXPECT_GE(ups.points[0]->end_timestamp_millis,
166 ups.points[0]->start_timestamp_millis);
167 }
168 }
169
TEST(CollectMetricsTest,Gauge)170 TEST(CollectMetricsTest, Gauge) {
171 auto string_gauge_with_labels =
172 std::unique_ptr<Gauge<string, 2>>(Gauge<string, 2>::New(
173 "/tensorflow/test/string_gauge_with_labels",
174 "String gauge with labels.", "MyLabel0", "MyLabel1"));
175 auto inteter_gauge_without_labels = std::unique_ptr<Gauge<int64, 0>>(
176 Gauge<int64, 0>::New("/tensorflow/test/integer_gauge_without_labels",
177 "Integer gauge without labels."));
178
179 string_gauge_with_labels->GetCell("Label00", "Label10")->Set("test1");
180 string_gauge_with_labels->GetCell("Label01", "Label11")->Set("test2");
181 inteter_gauge_without_labels->GetCell()->Set(7);
182
183 for (const bool collect_metric_descriptors : {true, false}) {
184 SCOPED_TRACE(strings::StrCat("collect_metric_descriptors: ",
185 collect_metric_descriptors));
186
187 auto* collection_registry = CollectionRegistry::Default();
188 CollectionRegistry::CollectMetricsOptions options;
189 options.collect_metric_descriptors = collect_metric_descriptors;
190 const std::unique_ptr<CollectedMetrics> collected_metrics =
191 collection_registry->CollectMetrics(options);
192
193 if (collect_metric_descriptors) {
194 ASSERT_GE(collected_metrics->metric_descriptor_map.size(), 2);
195
196 const MetricDescriptor& ld = *collected_metrics->metric_descriptor_map.at(
197 "/tensorflow/test/string_gauge_with_labels");
198 EXPECT_EQ("/tensorflow/test/string_gauge_with_labels", ld.name);
199 EXPECT_EQ("String gauge with labels.", ld.description);
200 ASSERT_EQ(2, ld.label_names.size());
201 EXPECT_EQ("MyLabel0", ld.label_names[0]);
202 EXPECT_EQ("MyLabel1", ld.label_names[1]);
203 EXPECT_EQ(MetricKind::kGauge, ld.metric_kind);
204 EXPECT_EQ(ValueType::kString, ld.value_type);
205
206 const MetricDescriptor& ud = *collected_metrics->metric_descriptor_map.at(
207 "/tensorflow/test/integer_gauge_without_labels");
208 EXPECT_EQ("/tensorflow/test/integer_gauge_without_labels", ud.name);
209 EXPECT_EQ("Integer gauge without labels.", ud.description);
210 ASSERT_EQ(0, ud.label_names.size());
211 EXPECT_EQ(MetricKind::kGauge, ud.metric_kind);
212 EXPECT_EQ(ValueType::kInt64, ud.value_type);
213 } else {
214 EXPECT_EQ(0, collected_metrics->metric_descriptor_map.size());
215 }
216
217 ASSERT_GE(collected_metrics->point_set_map.size(), 2);
218
219 const PointSet& lps = *collected_metrics->point_set_map.at(
220 "/tensorflow/test/string_gauge_with_labels");
221 EXPECT_EQ("/tensorflow/test/string_gauge_with_labels", lps.metric_name);
222 ASSERT_EQ(2, lps.points.size());
223 ASSERT_EQ(2, lps.points[0]->labels.size());
224 EXPECT_EQ("MyLabel0", lps.points[0]->labels[0].name);
225 EXPECT_EQ("Label00", lps.points[0]->labels[0].value);
226 EXPECT_EQ("MyLabel1", lps.points[0]->labels[1].name);
227 EXPECT_EQ("Label10", lps.points[0]->labels[1].value);
228 EXPECT_EQ(ValueType::kString, lps.points[0]->value_type);
229 EXPECT_EQ("test1", lps.points[0]->string_value);
230 EXPECT_LT(0, lps.points[0]->start_timestamp_millis);
231 EXPECT_LT(0, lps.points[0]->end_timestamp_millis);
232 EXPECT_GE(lps.points[0]->end_timestamp_millis,
233 lps.points[0]->start_timestamp_millis);
234 ASSERT_EQ(2, lps.points[1]->labels.size());
235 EXPECT_EQ("MyLabel0", lps.points[1]->labels[0].name);
236 EXPECT_EQ("Label01", lps.points[1]->labels[0].value);
237 EXPECT_EQ("MyLabel1", lps.points[1]->labels[1].name);
238 EXPECT_EQ("Label11", lps.points[1]->labels[1].value);
239 EXPECT_EQ(ValueType::kString, lps.points[1]->value_type);
240 EXPECT_EQ("test2", lps.points[1]->string_value);
241 EXPECT_LT(0, lps.points[1]->start_timestamp_millis);
242 EXPECT_LT(0, lps.points[1]->end_timestamp_millis);
243 EXPECT_GE(lps.points[1]->end_timestamp_millis,
244 lps.points[1]->start_timestamp_millis);
245
246 const PointSet& ups = *collected_metrics->point_set_map.at(
247 "/tensorflow/test/integer_gauge_without_labels");
248 EXPECT_EQ("/tensorflow/test/integer_gauge_without_labels", ups.metric_name);
249 ASSERT_EQ(1, ups.points.size());
250 EXPECT_EQ(0, ups.points[0]->labels.size());
251 EXPECT_EQ(ValueType::kInt64, ups.points[0]->value_type);
252 EXPECT_EQ(7, ups.points[0]->int64_value);
253 EXPECT_LT(0, ups.points[0]->start_timestamp_millis);
254 EXPECT_LT(0, ups.points[0]->end_timestamp_millis);
255 EXPECT_GE(ups.points[0]->end_timestamp_millis,
256 ups.points[0]->start_timestamp_millis);
257 }
258 }
259
EqHistograms(const Histogram & expected,const HistogramProto & actual_proto)260 void EqHistograms(const Histogram& expected,
261 const HistogramProto& actual_proto) {
262 Histogram actual;
263 ASSERT_TRUE(actual.DecodeFromProto(actual_proto));
264
265 EXPECT_EQ(expected.ToString(), actual.ToString());
266 }
267
TEST(CollectMetricsTest,Sampler)268 TEST(CollectMetricsTest, Sampler) {
269 auto sampler_with_labels = std::unique_ptr<Sampler<2>>(
270 Sampler<2>::New({"/tensorflow/test/sampler_with_labels",
271 "Sampler with labels.", "MyLabel0", "MyLabel1"},
272 Buckets::Explicit({1.0, 2.0})));
273 auto sampler_without_labels = std::unique_ptr<Sampler<0>>(Sampler<0>::New(
274 {"/tensorflow/test/sampler_without_labels", "Sampler without labels."},
275 Buckets::Explicit({0.0})));
276
277 Histogram with_labels0({1.0, 2.0, DBL_MAX});
278 sampler_with_labels->GetCell("Label00", "Label10")->Add(0.7);
279 with_labels0.Add(0.7);
280
281 Histogram with_labels1({1.0, 2.0, DBL_MAX});
282 sampler_with_labels->GetCell("Label01", "Label11")->Add(1.5);
283 with_labels1.Add(1.5);
284
285 Histogram without_labels({0.0, DBL_MAX});
286 sampler_without_labels->GetCell()->Add(0.5);
287 without_labels.Add(0.5);
288
289 for (const bool collect_metric_descriptors : {true, false}) {
290 SCOPED_TRACE(strings::StrCat("collect_metric_descriptors: ",
291 collect_metric_descriptors));
292
293 auto* collection_registry = CollectionRegistry::Default();
294 CollectionRegistry::CollectMetricsOptions options;
295 options.collect_metric_descriptors = collect_metric_descriptors;
296 const std::unique_ptr<CollectedMetrics> collected_metrics =
297 collection_registry->CollectMetrics(options);
298
299 if (collect_metric_descriptors) {
300 ASSERT_GE(collected_metrics->metric_descriptor_map.size(), 2);
301
302 const MetricDescriptor& ld = *collected_metrics->metric_descriptor_map.at(
303 "/tensorflow/test/sampler_with_labels");
304 EXPECT_EQ("/tensorflow/test/sampler_with_labels", ld.name);
305 EXPECT_EQ("Sampler with labels.", ld.description);
306 ASSERT_EQ(2, ld.label_names.size());
307 EXPECT_EQ("MyLabel0", ld.label_names[0]);
308 EXPECT_EQ("MyLabel1", ld.label_names[1]);
309 EXPECT_EQ(MetricKind::kCumulative, ld.metric_kind);
310 EXPECT_EQ(ValueType::kHistogram, ld.value_type);
311
312 const MetricDescriptor& ud = *collected_metrics->metric_descriptor_map.at(
313 "/tensorflow/test/sampler_without_labels");
314 EXPECT_EQ("/tensorflow/test/sampler_without_labels", ud.name);
315 EXPECT_EQ("Sampler without labels.", ud.description);
316 ASSERT_EQ(0, ud.label_names.size());
317 EXPECT_EQ(MetricKind::kCumulative, ud.metric_kind);
318 EXPECT_EQ(ValueType::kHistogram, ud.value_type);
319 } else {
320 EXPECT_EQ(0, collected_metrics->metric_descriptor_map.size());
321 }
322
323 ASSERT_GE(collected_metrics->point_set_map.size(), 2);
324
325 const PointSet& lps = *collected_metrics->point_set_map.at(
326 "/tensorflow/test/sampler_with_labels");
327 EXPECT_EQ("/tensorflow/test/sampler_with_labels", lps.metric_name);
328 ASSERT_EQ(2, lps.points.size());
329 ASSERT_EQ(2, lps.points[0]->labels.size());
330 EXPECT_EQ("MyLabel0", lps.points[0]->labels[0].name);
331 EXPECT_EQ("Label00", lps.points[0]->labels[0].value);
332 EXPECT_EQ("MyLabel1", lps.points[0]->labels[1].name);
333 EXPECT_EQ("Label10", lps.points[0]->labels[1].value);
334 EXPECT_EQ(ValueType::kHistogram, lps.points[0]->value_type);
335 EqHistograms(with_labels0, lps.points[0]->histogram_value);
336 EXPECT_LT(0, lps.points[0]->start_timestamp_millis);
337 EXPECT_LT(0, lps.points[0]->end_timestamp_millis);
338 EXPECT_GE(lps.points[0]->end_timestamp_millis,
339 lps.points[0]->start_timestamp_millis);
340 ASSERT_EQ(2, lps.points[1]->labels.size());
341 EXPECT_EQ("MyLabel0", lps.points[1]->labels[0].name);
342 EXPECT_EQ("Label01", lps.points[1]->labels[0].value);
343 EXPECT_EQ("MyLabel1", lps.points[1]->labels[1].name);
344 EXPECT_EQ("Label11", lps.points[1]->labels[1].value);
345 EXPECT_EQ(ValueType::kHistogram, lps.points[1]->value_type);
346 EqHistograms(with_labels1, lps.points[1]->histogram_value);
347 EXPECT_LT(0, lps.points[1]->start_timestamp_millis);
348 EXPECT_LT(0, lps.points[1]->end_timestamp_millis);
349 EXPECT_GE(lps.points[1]->end_timestamp_millis,
350 lps.points[1]->start_timestamp_millis);
351
352 const PointSet& ups = *collected_metrics->point_set_map.at(
353 "/tensorflow/test/sampler_without_labels");
354 EXPECT_EQ("/tensorflow/test/sampler_without_labels", ups.metric_name);
355 ASSERT_EQ(1, ups.points.size());
356 EXPECT_EQ(0, ups.points[0]->labels.size());
357 EXPECT_EQ(ValueType::kHistogram, ups.points[0]->value_type);
358 EqHistograms(without_labels, ups.points[0]->histogram_value);
359 EXPECT_LT(0, ups.points[0]->start_timestamp_millis);
360 EXPECT_LT(0, ups.points[0]->end_timestamp_millis);
361 EXPECT_GE(ups.points[0]->end_timestamp_millis,
362 ups.points[0]->start_timestamp_millis);
363 }
364 }
365
TEST(CollectMetricsTest,PercentileSampler)366 TEST(CollectMetricsTest, PercentileSampler) {
367 auto sampler_with_labels =
368 std::unique_ptr<PercentileSampler<2>>(PercentileSampler<2>::New(
369 {"/tensorflow/test/pctsampler_with_labels",
370 "Percentile sampler with labels.", "MyLabel0", "MyLabel1"},
371 {25.0, 50.0, 75.0}, 1024, UnitOfMeasure::kNumber));
372 auto sampler_without_labels =
373 std::unique_ptr<PercentileSampler<0>>(PercentileSampler<0>::New(
374 {"/tensorflow/test/pctsampler_without_labels",
375 "Percentile sampler without labels."},
376 {25.0, 50.0, 75.0}, 1024, UnitOfMeasure::kNumber));
377
378 sampler_with_labels->GetCell("Label00", "Label10")->Add(0.7);
379 sampler_with_labels->GetCell("Label01", "Label11")->Add(1.5);
380
381 sampler_without_labels->GetCell()->Add(0.5);
382
383 for (const bool collect_metric_descriptors : {true, false}) {
384 SCOPED_TRACE(strings::StrCat("collect_metric_descriptors: ",
385 collect_metric_descriptors));
386
387 auto* collection_registry = CollectionRegistry::Default();
388 CollectionRegistry::CollectMetricsOptions options;
389 options.collect_metric_descriptors = collect_metric_descriptors;
390 const std::unique_ptr<CollectedMetrics> collected_metrics =
391 collection_registry->CollectMetrics(options);
392
393 if (collect_metric_descriptors) {
394 ASSERT_GE(collected_metrics->metric_descriptor_map.size(), 2);
395
396 const MetricDescriptor& ld = *collected_metrics->metric_descriptor_map.at(
397 "/tensorflow/test/pctsampler_with_labels");
398 EXPECT_EQ("/tensorflow/test/pctsampler_with_labels", ld.name);
399 EXPECT_EQ("Percentile sampler with labels.", ld.description);
400 ASSERT_EQ(2, ld.label_names.size());
401 EXPECT_EQ("MyLabel0", ld.label_names[0]);
402 EXPECT_EQ("MyLabel1", ld.label_names[1]);
403 EXPECT_EQ(MetricKind::kCumulative, ld.metric_kind);
404 EXPECT_EQ(ValueType::kPercentiles, ld.value_type);
405
406 const MetricDescriptor& ud = *collected_metrics->metric_descriptor_map.at(
407 "/tensorflow/test/pctsampler_without_labels");
408 EXPECT_EQ("/tensorflow/test/pctsampler_without_labels", ud.name);
409 EXPECT_EQ("Percentile sampler without labels.", ud.description);
410 ASSERT_EQ(0, ud.label_names.size());
411 EXPECT_EQ(MetricKind::kCumulative, ud.metric_kind);
412 EXPECT_EQ(ValueType::kPercentiles, ud.value_type);
413 } else {
414 EXPECT_EQ(0, collected_metrics->metric_descriptor_map.size());
415 }
416
417 ASSERT_GE(collected_metrics->point_set_map.size(), 2);
418
419 const PointSet& lps = *collected_metrics->point_set_map.at(
420 "/tensorflow/test/pctsampler_with_labels");
421 EXPECT_EQ("/tensorflow/test/pctsampler_with_labels", lps.metric_name);
422 ASSERT_EQ(2, lps.points.size());
423 ASSERT_EQ(2, lps.points[0]->labels.size());
424 EXPECT_EQ("MyLabel0", lps.points[0]->labels[0].name);
425 EXPECT_EQ("Label00", lps.points[0]->labels[0].value);
426 EXPECT_EQ("MyLabel1", lps.points[0]->labels[1].name);
427 EXPECT_EQ("Label10", lps.points[0]->labels[1].value);
428 EXPECT_EQ(ValueType::kPercentiles, lps.points[0]->value_type);
429
430 EXPECT_LT(0, lps.points[0]->start_timestamp_millis);
431 EXPECT_LT(0, lps.points[0]->end_timestamp_millis);
432 EXPECT_GE(lps.points[0]->end_timestamp_millis,
433 lps.points[0]->start_timestamp_millis);
434 ASSERT_EQ(2, lps.points[1]->labels.size());
435 EXPECT_EQ("MyLabel0", lps.points[1]->labels[0].name);
436 EXPECT_EQ("Label01", lps.points[1]->labels[0].value);
437 EXPECT_EQ("MyLabel1", lps.points[1]->labels[1].name);
438 EXPECT_EQ("Label11", lps.points[1]->labels[1].value);
439 EXPECT_EQ(ValueType::kPercentiles, lps.points[1]->value_type);
440 EXPECT_LT(0, lps.points[1]->start_timestamp_millis);
441 EXPECT_LT(0, lps.points[1]->end_timestamp_millis);
442 EXPECT_GE(lps.points[1]->end_timestamp_millis,
443 lps.points[1]->start_timestamp_millis);
444
445 const PointSet& ups = *collected_metrics->point_set_map.at(
446 "/tensorflow/test/pctsampler_without_labels");
447 EXPECT_EQ("/tensorflow/test/pctsampler_without_labels", ups.metric_name);
448 ASSERT_EQ(1, ups.points.size());
449 EXPECT_EQ(0, ups.points[0]->labels.size());
450 EXPECT_EQ(ValueType::kPercentiles, ups.points[0]->value_type);
451 EXPECT_LT(0, ups.points[0]->start_timestamp_millis);
452 EXPECT_LT(0, ups.points[0]->end_timestamp_millis);
453 EXPECT_GE(ups.points[0]->end_timestamp_millis,
454 ups.points[0]->start_timestamp_millis);
455 }
456 }
457
458 // A FakeClockEnv to manually advance time.
459 class FakeClockEnv : public EnvWrapper {
460 public:
FakeClockEnv()461 FakeClockEnv() : EnvWrapper(Env::Default()), current_millis_(0) {}
462
463 // Manually advance the current time by 'millis' milliseconds.
AdvanceByMillis(const uint64 millis)464 void AdvanceByMillis(const uint64 millis) { current_millis_ += millis; }
465
466 // Method that this environment specifically overrides.
NowMicros() const467 uint64 NowMicros() const override { return current_millis_ * 1000; }
468
469 private:
470 uint64 current_millis_;
471 };
472
TEST(CollectionRegistryTest,WriteTimestamps)473 TEST(CollectionRegistryTest, WriteTimestamps) {
474 FakeClockEnv fake_clock_env;
475 auto collection_registry =
476 test_util::CollectionRegistryTestAccess::CreateRegistry(&fake_clock_env);
477
478 fake_clock_env.AdvanceByMillis(25);
479 {
480 const MetricDef<MetricKind::kCumulative, int64, 0> cumulative_metric(
481 "/tensorflow/cumulative/metric", "An example metric with no labels.");
482 auto handle = collection_registry->Register(
483 &cumulative_metric, [&](MetricCollectorGetter getter) {
484 auto metric_collector = getter.Get(&cumulative_metric);
485 metric_collector.CollectValue({}, 42);
486 });
487 fake_clock_env.AdvanceByMillis(75);
488 const std::unique_ptr<CollectedMetrics> collected_metrics =
489 collection_registry->CollectMetrics({});
490 const PointSet& point_set =
491 *collected_metrics->point_set_map.at("/tensorflow/cumulative/metric");
492 ASSERT_EQ(1, point_set.points.size());
493 EXPECT_EQ(25, point_set.points[0]->start_timestamp_millis);
494 EXPECT_EQ(100, point_set.points[0]->end_timestamp_millis);
495 }
496 {
497 const MetricDef<MetricKind::kGauge, int64, 0> gauge_metric(
498 "/tensorflow/gauge/metric", "An example metric with no labels.");
499 auto handle = collection_registry->Register(
500 &gauge_metric, [&](MetricCollectorGetter getter) {
501 auto metric_collector = getter.Get(&gauge_metric);
502 metric_collector.CollectValue({}, 42);
503 });
504 fake_clock_env.AdvanceByMillis(75);
505 const std::unique_ptr<CollectedMetrics> collected_metrics =
506 collection_registry->CollectMetrics({});
507 const PointSet& point_set =
508 *collected_metrics->point_set_map.at("/tensorflow/gauge/metric");
509 ASSERT_EQ(1, point_set.points.size());
510 EXPECT_EQ(175, point_set.points[0]->start_timestamp_millis);
511 EXPECT_EQ(175, point_set.points[0]->end_timestamp_millis);
512 }
513 }
514
515 } // namespace
516 } // namespace monitoring
517 } // namespace tensorflow
518