• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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