TensorFlow Serving C++ API Documentation
prometheus_exporter_test.cc
1 /* Copyright 2018 Google Inc. 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_serving/util/prometheus_exporter.h"
17 
18 #include <gtest/gtest.h>
19 #include "absl/memory/memory.h"
20 #include "absl/strings/str_cat.h"
21 #include "absl/strings/str_join.h"
22 #include "tensorflow/core/lib/monitoring/counter.h"
23 #include "tensorflow/core/lib/monitoring/gauge.h"
24 #include "tensorflow/core/lib/monitoring/sampler.h"
25 
26 namespace tensorflow {
27 namespace serving {
28 namespace {
29 
30 TEST(PrometheusExporterTest, Counter) {
31  auto exporter = absl::make_unique<PrometheusExporter>();
32  auto counter = absl::WrapUnique(
33  monitoring::Counter<1>::New("/test/path/total", "A counter.", "name"));
34  counter->GetCell("abc")->IncrementBy(2);
35 
36  string http_page;
37  Status status = exporter->GeneratePage(&http_page);
38 
39  string expected_result = absl::StrJoin(
40  {"# TYPE :test:path:total counter", ":test:path:total{name=\"abc\"} 2"},
41  "\n");
42  absl::StrAppend(&expected_result, "\n");
43  EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_result, http_page);
44 }
45 
46 TEST(PrometheusExporterTest, Gauge) {
47  auto exporter = absl::make_unique<PrometheusExporter>();
48  auto gauge = absl::WrapUnique(monitoring::Gauge<int64_t, 2>::New(
49  "/test/path/gague", "A gauge", "x", "y"));
50  gauge->GetCell("abc", "def")->Set(5);
51 
52  string http_page;
53  Status status = exporter->GeneratePage(&http_page);
54  string expected_result =
55  absl::StrJoin({"# TYPE :test:path:gague gauge",
56  ":test:path:gague{x=\"abc\",y=\"def\"} 5"},
57  "\n");
58  absl::StrAppend(&expected_result, "\n");
59  EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_result, http_page);
60 }
61 
62 TEST(PrometheusExporterTest, Histogram) {
63  auto exporter = absl::make_unique<PrometheusExporter>();
64  auto histogram = absl::WrapUnique(monitoring::Sampler<1>::New(
65  {"/test/path/histogram", "A histogram.", "status"},
66  monitoring::Buckets::Exponential(1, 2, 10)));
67  histogram->GetCell("good")->Add(2);
68  histogram->GetCell("good")->Add(20);
69  histogram->GetCell("good")->Add(200);
70 
71  string http_page;
72  Status status = exporter->GeneratePage(&http_page);
73  string expected_result = absl::StrJoin(
74  {"# TYPE :test:path:histogram histogram",
75  ":test:path:histogram_bucket{status=\"good\",le=\"1\"} 0",
76  ":test:path:histogram_bucket{status=\"good\",le=\"2\"} 0",
77  ":test:path:histogram_bucket{status=\"good\",le=\"4\"} 1",
78  ":test:path:histogram_bucket{status=\"good\",le=\"8\"} 1",
79  ":test:path:histogram_bucket{status=\"good\",le=\"16\"} 1",
80  ":test:path:histogram_bucket{status=\"good\",le=\"32\"} 2",
81  ":test:path:histogram_bucket{status=\"good\",le=\"64\"} 2",
82  ":test:path:histogram_bucket{status=\"good\",le=\"128\"} 2",
83  ":test:path:histogram_bucket{status=\"good\",le=\"256\"} 3",
84  ":test:path:histogram_bucket{status=\"good\",le=\"512\"} 3",
85  ":test:path:histogram_bucket{status=\"good\",le=\"+Inf\"} 3",
86  ":test:path:histogram_sum{status=\"good\"} 222",
87  ":test:path:histogram_count{status=\"good\"} 3"},
88  "\n");
89  absl::StrAppend(&expected_result, "\n");
90  EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_result, http_page);
91 }
92 
93 TEST(PrometheusExporterTest, SanitizeLabelValue) {
94  auto exporter = absl::make_unique<PrometheusExporter>();
95  auto counter = absl::WrapUnique(
96  monitoring::Counter<1>::New("/test/path/total", "A counter.", "name"));
97  // label value: "abc\"
98  counter->GetCell("\"abc\\\"")->IncrementBy(2);
99 
100  string http_page;
101  Status status = exporter->GeneratePage(&http_page);
102 
103  string expected_result =
104  absl::StrJoin({"# TYPE :test:path:total counter",
105  ":test:path:total{name=\"\\\"abc\\\\\\\"\"} 2"},
106  "\n");
107  absl::StrAppend(&expected_result, "\n");
108  EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_result, http_page);
109 }
110 
111 TEST(PrometheusExporterTest, SanitizeLabelName) {
112  auto exporter = absl::make_unique<PrometheusExporter>();
113  auto counter = absl::WrapUnique(monitoring::Counter<1>::New(
114  "/test/path/total", "A counter.", "my-name+1"));
115  counter->GetCell("abc")->IncrementBy(2);
116 
117  string http_page;
118  Status status = exporter->GeneratePage(&http_page);
119 
120  string expected_result =
121  absl::StrJoin({"# TYPE :test:path:total counter",
122  ":test:path:total{my_name_1=\"abc\"} 2"},
123  "\n");
124  absl::StrAppend(&expected_result, "\n");
125  EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_result, http_page);
126 }
127 
128 TEST(PrometheusExporterTest, SanitizeMetricName) {
129  auto exporter = absl::make_unique<PrometheusExporter>();
130  auto counter = absl::WrapUnique(
131  monitoring::Counter<1>::New("0/path-total_count", "A counter.", "name"));
132  counter->GetCell("abc")->IncrementBy(2);
133 
134  string http_page;
135  Status status = exporter->GeneratePage(&http_page);
136 
137  string expected_result =
138  absl::StrJoin({"# TYPE _0:path:total_count counter",
139  "_0:path:total_count{name=\"abc\"} 2"},
140  "\n");
141  absl::StrAppend(&expected_result, "\n");
142  EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_result, http_page);
143 }
144 
145 } // namespace
146 } // namespace serving
147 } // namespace tensorflow