1 // Copyright (C) 2015-2020 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
9 #include <stats/stats_mgr.h>
10 #include <exceptions/exceptions.h>
11 #include <cc/data.h>
12 #include <cc/command_interpreter.h>
13 #include <util/chrono_time_utils.h>
14 #include <boost/shared_ptr.hpp>
15 #include <gtest/gtest.h>
16 
17 #include <iostream>
18 #include <sstream>
19 
20 using namespace isc;
21 using namespace isc::data;
22 using namespace isc::stats;
23 using namespace isc::config;
24 using namespace std::chrono;
25 
26 namespace {
27 
28 static const StatsDuration& dur1234(hours(1) + minutes(2) + seconds(3) +
29                                     milliseconds(4));
30 static const StatsDuration& dur5678(hours(5) + minutes(6) + seconds(7) +
31                                     milliseconds(8));
32 static const StatsDuration& dur1245(hours(1) + minutes(2) + seconds(45));
33 
34 /// @brief Fixture class for StatsMgr testing
35 ///
36 /// Very simple class that makes sure that StatsMgr is indeed instantiated
37 /// before the test and any statistics are wiped out after it.
38 class StatsMgrTest : public ::testing::Test {
39 public:
40     /// @brief Constructor
41     /// Makes sure that the Statistics Manager is instantiated.
StatsMgrTest()42     StatsMgrTest() {
43         StatsMgr::instance();
44         StatsMgr::instance().removeAll();
45     }
46 
47     /// @brief Destructor
48     /// Removes all statistics and restores class defaults.
~StatsMgrTest()49     ~StatsMgrTest() {
50         StatsMgr::instance().removeAll();
51         StatsMgr::instance().setMaxSampleAgeDefault(StatsDuration::zero());
52         StatsMgr::instance().setMaxSampleCountDefault(20);
53     }
54 };
55 
56 // Basic test for statistics manager interface.
TEST_F(StatsMgrTest,basic)57 TEST_F(StatsMgrTest, basic) {
58     // Getting an instance
59     EXPECT_NO_THROW(StatsMgr::instance());
60 
61     // Check that there are no statistics recorded by default.
62     EXPECT_EQ(0, StatsMgr::instance().count());
63 }
64 
65 // Test checks whether it's possible to record and later report
66 // an integer statistic.
TEST_F(StatsMgrTest,integerStat)67 TEST_F(StatsMgrTest, integerStat) {
68     EXPECT_NO_THROW(StatsMgr::instance().setValue("alpha",
69                                                   static_cast<int64_t>(1234)));
70 
71     ObservationPtr alpha;
72     EXPECT_NO_THROW(alpha = StatsMgr::instance().getObservation("alpha"));
73     ASSERT_TRUE(alpha);
74 
75     std::string exp = "{ \"alpha\": [ [ 1234, \"" +
76         isc::util::clockToText(alpha->getInteger().second) + "\" ] ] }";
77 
78     EXPECT_EQ(exp, StatsMgr::instance().get("alpha")->str());
79 }
80 
81 // Test checks whether it's possible to record and later report
82 // a floating point statistic.
TEST_F(StatsMgrTest,floatStat)83 TEST_F(StatsMgrTest, floatStat) {
84     EXPECT_NO_THROW(StatsMgr::instance().setValue("beta", 12.34));
85 
86     ObservationPtr beta;
87     EXPECT_NO_THROW(beta = StatsMgr::instance().getObservation("beta"));
88     ASSERT_TRUE(beta);
89 
90     std::string exp = "{ \"beta\": [ [ 12.34, \"" +
91         isc::util::clockToText(beta->getFloat().second) + "\" ] ] }";
92 
93     EXPECT_EQ(exp, StatsMgr::instance().get("beta")->str());
94 }
95 
96 // Test checks whether it's possible to record and later report
97 // a duration statistic.
TEST_F(StatsMgrTest,durationStat)98 TEST_F(StatsMgrTest, durationStat) {
99     EXPECT_NO_THROW(StatsMgr::instance().setValue("gamma", dur1234));
100 
101     ObservationPtr gamma;
102     EXPECT_NO_THROW(gamma = StatsMgr::instance().getObservation("gamma"));
103     ASSERT_TRUE(gamma);
104 
105     std::string exp = "{ \"gamma\": [ [ \"01:02:03.004000\", \"" +
106         isc::util::clockToText(gamma->getDuration().second) + "\" ] ] }";
107 
108     EXPECT_EQ(exp, StatsMgr::instance().get("gamma")->str());
109 }
110 
111 // Test checks whether it's possible to record and later report
112 // a string statistic.
TEST_F(StatsMgrTest,stringStat)113 TEST_F(StatsMgrTest, stringStat) {
114     EXPECT_NO_THROW(StatsMgr::instance().setValue("delta",
115                                                   "Lorem ipsum"));
116 
117     ObservationPtr delta;
118     EXPECT_NO_THROW(delta = StatsMgr::instance().getObservation("delta"));
119     ASSERT_TRUE(delta);
120 
121     std::string exp = "{ \"delta\": [ [ \"Lorem ipsum\", \"" +
122         isc::util::clockToText(delta->getString().second) + "\" ] ] }";
123 
124     EXPECT_EQ(exp, StatsMgr::instance().get("delta")->str());
125 }
126 
127 // Basic test of getSize function.
TEST_F(StatsMgrTest,getSize)128 TEST_F(StatsMgrTest, getSize) {
129     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
130     StatsMgr::instance().setValue("beta", 12.34);
131     StatsMgr::instance().setValue("gamma", dur1234);
132     StatsMgr::instance().setValue("delta", "Lorem ipsum");
133 
134     EXPECT_NO_THROW(StatsMgr::instance().getSize("alpha"));
135     EXPECT_NO_THROW(StatsMgr::instance().getSize("beta"));
136     EXPECT_NO_THROW(StatsMgr::instance().getSize("gamma"));
137     EXPECT_NO_THROW(StatsMgr::instance().getSize("delta"));
138 
139     EXPECT_EQ(StatsMgr::instance().getSize("alpha"), 1);
140     EXPECT_EQ(StatsMgr::instance().getSize("beta"), 1);
141     EXPECT_EQ(StatsMgr::instance().getSize("gamma"), 1);
142     EXPECT_EQ(StatsMgr::instance().getSize("delta"), 1);
143 }
144 
145 // Test checks whether setting age limit and count limit works properly.
TEST_F(StatsMgrTest,setLimits)146 TEST_F(StatsMgrTest, setLimits) {
147     // Initializing of an integer type observation
148     StatsMgr::instance().setValue("foo", static_cast<int64_t>(1));
149 
150     EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleAge("foo",
151                                                          seconds(1)));
152 
153     for (uint32_t i = 0; i < 10; ++i) {
154         if (i == 5) {
155             sleep(1); // wait one second to force exceeding the time limit
156         }
157         StatsMgr::instance().setValue("foo", static_cast<int64_t>(i));
158     }
159 
160     EXPECT_EQ(StatsMgr::instance().getSize("foo"), 5);
161     EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleCount("foo", 100));
162 
163     for (int64_t i = 0; i < 200; ++i) {
164         StatsMgr::instance().setValue("foo", i);
165     }
166 
167     EXPECT_EQ(StatsMgr::instance().getSize("foo"), 100);
168 }
169 
170 // Test checks whether setting age limit and count limit to existing
171 // statistics works properly.
TEST_F(StatsMgrTest,setLimitsAll)172 TEST_F(StatsMgrTest, setLimitsAll) {
173     // Set a couple of statistics
174     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
175     StatsMgr::instance().setValue("beta", 12.34);
176     StatsMgr::instance().setValue("gamma", dur1234);
177     StatsMgr::instance().setValue("delta", "Lorem ipsum");
178 
179     // check the setting of time limit to existing statistics
180     EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleAgeAll(seconds(1)));
181 
182     // check if time limit was set properly and whether count limit is disabled
183     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, true);
184     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second,
185               seconds(1));
186     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, false);
187 
188     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, true);
189     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().second,
190               seconds(1));
191     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, false);
192 
193     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, true);
194     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().second,
195               seconds(1));
196     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, false);
197 
198     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, true);
199     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().second,
200               seconds(1));
201     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, false);
202 
203     // check the setting of count limit to existing statistics
204     EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleCountAll(1200));
205 
206     // check if count limit was set properly and whether count limit is disabled
207     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, true);
208     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().second, 1200);
209     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, false);
210 
211     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, true);
212     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().second, 1200);
213     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, false);
214 
215     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, true);
216     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().second, 1200);
217     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, false);
218 
219     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, true);
220     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().second, 1200);
221     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, false);
222 }
223 
224 // Test checks whether setting default age limit and count limit works
225 // properly.
TEST_F(StatsMgrTest,setLimitsDefault)226 TEST_F(StatsMgrTest, setLimitsDefault) {
227     ASSERT_EQ(StatsMgr::instance().getMaxSampleCountDefault(), 20);
228     ASSERT_EQ(StatsMgr::instance().getMaxSampleAgeDefault(), StatsDuration::zero());
229 
230     // Set a couple of statistics
231     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
232     StatsMgr::instance().setValue("beta", 12.34);
233     StatsMgr::instance().setValue("gamma", seconds(1234));
234     StatsMgr::instance().setValue("delta", "Lorem ipsum");
235 
236     // check what default applied
237     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, true);
238     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().second, 20);
239     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, false);
240     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second, StatsDuration::zero());
241     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, true);
242     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().second, 20);
243     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, false);
244     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().second, StatsDuration::zero());
245     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, true);
246     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().second, 20);
247     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, false);
248     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().second, StatsDuration::zero());
249     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, true);
250     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().second, 20);
251     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, false);
252     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().second, StatsDuration::zero());
253 
254     // Retry with another default count limits.
255     EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleCountDefault(10));
256     EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleAgeDefault(seconds(5)));
257     ASSERT_EQ(StatsMgr::instance().getMaxSampleCountDefault(), 10);
258     ASSERT_EQ(StatsMgr::instance().getMaxSampleAgeDefault(), seconds(5));
259 
260     // Check the existing statistics were not updated.
261     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, true);
262     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().second, 20);
263     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, false);
264     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second, StatsDuration::zero());
265     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, true);
266     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().second, 20);
267     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, false);
268     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().second, StatsDuration::zero());
269     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, true);
270     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().second, 20);
271     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, false);
272     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().second, StatsDuration::zero());
273     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, true);
274     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().second, 20);
275     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, false);
276     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().second, StatsDuration::zero());
277 
278     // Remove all test statistics.
279     EXPECT_NO_THROW(StatsMgr::instance().removeAll());
280 
281     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
282     StatsMgr::instance().setValue("beta", 12.34);
283     StatsMgr::instance().setValue("gamma", seconds(1234));
284     StatsMgr::instance().setValue("delta", "Lorem ipsum");
285 
286     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, true);
287     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().second, 10);
288     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, false);
289     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second, seconds(5));
290     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, true);
291     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().second, 10);
292     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, false);
293     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().second, seconds(5));
294     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, true);
295     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().second, 10);
296     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, false);
297     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().second, seconds(5));
298     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, true);
299     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().second, 10);
300     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, false);
301     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().second, seconds(5));
302 
303     // Retry with count limit disable.
304     EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleCountDefault(0));
305     ASSERT_EQ(StatsMgr::instance().getMaxSampleCountDefault(), 0);
306 
307     // Check the existing statistics were not updated.
308     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, true);
309     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().second, 10);
310     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, false);
311     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second, seconds(5));
312     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, true);
313     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().second, 10);
314     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, false);
315     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().second, seconds(5));
316     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, true);
317     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().second, 10);
318     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, false);
319     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().second, seconds(5));
320     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, true);
321     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().second, 10);
322     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, false);
323     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().second, seconds(5));
324 
325     // Remove all test statistics.
326     EXPECT_NO_THROW(StatsMgr::instance().removeAll());
327 
328     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
329     StatsMgr::instance().setValue("beta", 12.34);
330     StatsMgr::instance().setValue("gamma", seconds(1234));
331     StatsMgr::instance().setValue("delta", "Lorem ipsum");
332 
333     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, false);
334     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().second, 10);
335     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, true);
336     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second, seconds(5));
337     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, false);
338     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().second, 10);
339     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, true);
340     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().second, seconds(5));
341     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, false);
342     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().second, 10);
343     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, true);
344     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().second, seconds(5));
345     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, false);
346     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().second, 10);
347     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, true);
348     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().second, seconds(5));
349 
350     EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleCountDefault(20));
351     EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleAgeDefault(StatsDuration::zero()));
352 }
353 
354 // This test checks whether a single (get("foo")) and all (getAll())
355 // statistics are reported properly.
TEST_F(StatsMgrTest,getGetAll)356 TEST_F(StatsMgrTest, getGetAll) {
357     // Set a couple of statistics
358     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
359     StatsMgr::instance().setValue("beta", 12.34);
360     StatsMgr::instance().setValue("gamma", dur1234);
361     StatsMgr::instance().setValue("delta", "Lorem");
362 
363     // The string's representation of firstly added statistics
364     std::string alpha_first = ", [ 1234, \"" +
365         isc::util::clockToText(StatsMgr::instance().getObservation("alpha")
366                                    ->getInteger().second) + "\" ] ]";
367     std::string beta_first = ", [ 12.34, \"" +
368         isc::util::clockToText(StatsMgr::instance().getObservation("beta")
369                                    ->getFloat().second) + "\" ] ]";
370     std::string gamma_first = ", [ \"01:02:03.004000\", \"" +
371         isc::util::clockToText(StatsMgr::instance().getObservation("gamma")
372                                    ->getDuration().second) + "\" ] ]";
373     std::string delta_first = ", [ \"Lorem\", \"" +
374         isc::util::clockToText(StatsMgr::instance().getObservation("delta")
375                                    ->getString().second) + "\" ] ]";
376 
377     // Now add some values to them
378     StatsMgr::instance().addValue("alpha", static_cast<int64_t>(5678));
379     StatsMgr::instance().addValue("beta", 56.78);
380     StatsMgr::instance().addValue("gamma", dur5678);
381     StatsMgr::instance().addValue("delta", " ipsum");
382 
383     // There should be 4 statistics reported
384     EXPECT_EQ(4, StatsMgr::instance().count());
385 
386     // Now check whether they can be reported back
387     ConstElementPtr rep_alpha = StatsMgr::instance().get("alpha");
388     ConstElementPtr rep_beta = StatsMgr::instance().get("beta");
389     ConstElementPtr rep_gamma = StatsMgr::instance().get("gamma");
390     ConstElementPtr rep_delta = StatsMgr::instance().get("delta");
391 
392     ASSERT_TRUE(rep_alpha);
393     ASSERT_TRUE(rep_beta);
394     ASSERT_TRUE(rep_gamma);
395     ASSERT_TRUE(rep_delta);
396 
397     std::string exp_str_alpha = "[ [ 6912, \"" +
398         isc::util::clockToText(StatsMgr::instance().getObservation("alpha")
399                                    ->getInteger().second) + "\" ]" + alpha_first;
400     std::string exp_str_beta = "[ [ 69.12, \"" +
401         isc::util::clockToText(StatsMgr::instance().getObservation("beta")
402                                    ->getFloat().second) + "\" ]" + beta_first;
403     std::string exp_str_gamma = "[ [ \"06:08:10.012000\", \"" +
404         isc::util::clockToText(StatsMgr::instance().getObservation("gamma")
405                                    ->getDuration().second) + "\" ]" + gamma_first;
406     std::string exp_str_delta = "[ [ \"Lorem ipsum\", \"" +
407         isc::util::clockToText(StatsMgr::instance().getObservation("delta")
408                                    ->getString().second) + "\" ]" + delta_first;
409 
410     // Check that individual stats are reported properly
411     EXPECT_EQ("{ \"alpha\": " + exp_str_alpha + " }", rep_alpha->str());
412     EXPECT_EQ("{ \"beta\": " + exp_str_beta + " }", rep_beta->str());
413     EXPECT_EQ("{ \"gamma\": " + exp_str_gamma + " }", rep_gamma->str());
414     EXPECT_EQ("{ \"delta\": " + exp_str_delta + " }", rep_delta->str());
415 
416     // Check that non-existent metric is not reported.
417     EXPECT_EQ("{  }", StatsMgr::instance().get("epsilon")->str());
418 
419     // Check that all of them can be reported at once
420     ConstElementPtr rep_all = StatsMgr::instance().getAll();
421     ASSERT_TRUE(rep_all);
422 
423     // Verifying this is a bit more involved, as we don't know whether the
424     // order would be preserved or not.
425     EXPECT_EQ(4, rep_all->size());
426     ASSERT_TRUE(rep_all->get("alpha"));
427     ASSERT_TRUE(rep_all->get("beta"));
428     ASSERT_TRUE(rep_all->get("delta"));
429     ASSERT_TRUE(rep_all->get("gamma"));
430     EXPECT_FALSE(rep_all->get("epsilon"));
431 
432     EXPECT_EQ(exp_str_alpha, rep_all->get("alpha")->str());
433     EXPECT_EQ(exp_str_beta, rep_all->get("beta")->str());
434     EXPECT_EQ(exp_str_gamma, rep_all->get("gamma")->str());
435     EXPECT_EQ(exp_str_delta, rep_all->get("delta")->str());
436 }
437 
438 // This test checks whether existing statistics can be reset.
TEST_F(StatsMgrTest,reset)439 TEST_F(StatsMgrTest, reset) {
440     // Set a couple of statistics
441     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
442     StatsMgr::instance().setValue("beta", 12.34);
443     StatsMgr::instance().setValue("gamma", dur1234);
444     StatsMgr::instance().setValue("delta", "Lorem ipsum");
445 
446     // This should reset alpha to 0
447     EXPECT_NO_THROW(StatsMgr::instance().reset("alpha"));
448     EXPECT_EQ(0,
449               StatsMgr::instance().getObservation("alpha")->getInteger().first);
450 
451     // The other stats should remain untouched
452     EXPECT_EQ(12.34,
453               StatsMgr::instance().getObservation("beta")->getFloat().first);
454     EXPECT_EQ(dur1234,
455               StatsMgr::instance().getObservation("gamma")->getDuration().first);
456     EXPECT_EQ("Lorem ipsum",
457               StatsMgr::instance().getObservation("delta")->getString().first);
458 
459     // Now let's wipe them, too.
460     EXPECT_NO_THROW(StatsMgr::instance().reset("beta"));
461     EXPECT_NO_THROW(StatsMgr::instance().reset("gamma"));
462     EXPECT_NO_THROW(StatsMgr::instance().reset("delta"));
463     EXPECT_EQ(0.0,
464               StatsMgr::instance().getObservation("beta")->getFloat().first);
465     EXPECT_EQ(StatsDuration::zero(),
466               StatsMgr::instance().getObservation("gamma")->getDuration().first);
467     EXPECT_EQ("",
468               StatsMgr::instance().getObservation("delta")->getString().first);
469 
470     // Resetting statistics should not remove them
471     EXPECT_EQ(4, StatsMgr::instance().count());
472 }
473 
474 // This test checks whether existing statistics can be reset.
TEST_F(StatsMgrTest,resetAll)475 TEST_F(StatsMgrTest, resetAll) {
476     // Set a couple of statistics
477     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
478     StatsMgr::instance().setValue("beta", 12.34);
479     StatsMgr::instance().setValue("gamma", dur1234);
480     StatsMgr::instance().setValue("delta", "Lorem ipsum");
481 
482     // This should reset alpha to 0
483     EXPECT_NO_THROW(StatsMgr::instance().resetAll());
484     EXPECT_EQ(0,
485               StatsMgr::instance().getObservation("alpha")->getInteger().first);
486     EXPECT_EQ(0.0,
487               StatsMgr::instance().getObservation("beta")->getFloat().first);
488     EXPECT_EQ(StatsDuration::zero(),
489               StatsMgr::instance().getObservation("gamma")->getDuration().first);
490     EXPECT_EQ("",
491               StatsMgr::instance().getObservation("delta")->getString().first);
492 
493     // Resetting all statistics should not remove them
494     EXPECT_EQ(4, StatsMgr::instance().count());
495 }
496 
497 // This test checks whether statistics can be removed.
TEST_F(StatsMgrTest,removeAll)498 TEST_F(StatsMgrTest, removeAll) {
499     // Set a couple of statistics
500     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
501     StatsMgr::instance().setValue("beta", 12.34);
502     StatsMgr::instance().setValue("gamma", dur1234);
503     StatsMgr::instance().setValue("delta", "Lorem ipsum");
504 
505     // This should reset alpha to 0
506     EXPECT_NO_THROW(StatsMgr::instance().removeAll());
507 
508     // Resetting all statistics should not remove them
509     EXPECT_EQ(0, StatsMgr::instance().count());
510 
511     // There should be no such statistics anymore
512     EXPECT_EQ("{  }", StatsMgr::instance().get("alpha")->str());
513     EXPECT_EQ("{  }", StatsMgr::instance().get("beta")->str());
514     EXPECT_EQ("{  }", StatsMgr::instance().get("gamma")->str());
515     EXPECT_EQ("{  }", StatsMgr::instance().get("delta")->str());
516 
517     // There should be no such statistics anymore
518     EXPECT_FALSE(StatsMgr::instance().getObservation("alpha"));
519     EXPECT_FALSE(StatsMgr::instance().getObservation("beta"));
520     EXPECT_FALSE(StatsMgr::instance().getObservation("gamma"));
521     EXPECT_FALSE(StatsMgr::instance().getObservation("delta"));
522 }
523 
524 // This is a performance benchmark that checks how long does it take
525 // to increment a single statistic million times.
526 //
527 // Data points:
528 // It took 00:00:00.363709 (363ms) on late 2013 Mac with Mac OS X 10.9.5.
TEST_F(StatsMgrTest,DISABLED_performanceSingleAdd)529 TEST_F(StatsMgrTest, DISABLED_performanceSingleAdd) {
530     StatsMgr::instance().removeAll();
531 
532     uint32_t cycles = 1000000;
533 
534     auto before = SampleClock::now();
535     for (uint32_t i = 0; i < cycles; ++i) {
536         StatsMgr::instance().addValue("metric1", 0.1 * i);
537     }
538     auto after = SampleClock::now();
539 
540     auto dur = after - before;
541 
542     std::cout << "Incrementing a single statistic " << cycles << " times took: "
543               << isc::util::durationToText(dur) << std::endl;
544 }
545 
546 // This is a performance benchmark that checks how long does it take
547 // to set absolute value of a single statistic million times.
548 //
549 // Data points:
550 // It took 00:00:00.361003 (361ms) on late 2013 Mac with Mac OS X 10.9.5.
TEST_F(StatsMgrTest,DISABLED_performanceSingleSet)551 TEST_F(StatsMgrTest, DISABLED_performanceSingleSet) {
552     StatsMgr::instance().removeAll();
553 
554     uint32_t cycles = 1000000;
555 
556     auto before = SampleClock::now();
557     for (uint32_t i = 0; i < cycles; ++i) {
558         StatsMgr::instance().setValue("metric1", 0.1 * i);
559     }
560     auto after = SampleClock::now();
561 
562     auto dur = after - before;
563 
564     std::cout << "Setting a single statistic " << cycles << " times took: "
565               << isc::util::durationToText(dur) << std::endl;
566 }
567 
568 // This is a performance benchmark that checks how long does it take to
569 // increment one statistic a million times, when there is 1000 other statistics
570 // present.
571 //
572 // Data points:
573 // 00:00:00.436943 (436ms) on late 2013 Mac with Mac OS X 10.9.5
TEST_F(StatsMgrTest,DISABLED_performanceMultipleAdd)574 TEST_F(StatsMgrTest, DISABLED_performanceMultipleAdd) {
575     StatsMgr::instance().removeAll();
576 
577     uint32_t cycles = 1000000;
578     uint32_t stats = 1000;
579 
580     for (uint32_t i = 0; i < stats; ++i) {
581         std::stringstream tmp;
582         tmp << "statistic" << i;
583         StatsMgr::instance().setValue(tmp.str(), static_cast<int64_t>(i));
584     }
585 
586     auto before = SampleClock::now();
587     for (uint32_t i = 0; i < cycles; ++i) {
588         StatsMgr::instance().addValue("metric1", static_cast<int64_t>(i));
589     }
590     auto after = SampleClock::now();
591 
592     auto dur = after - before;
593 
594     std::cout << "Incrementing one of " << stats << " statistics " << cycles
595               << " times took: " << isc::util::durationToText(dur) << std::endl;
596 }
597 
598 // This is a performance benchmark that checks how long does it take to
599 // set one statistic to a given value a million times, when there is 1000 other
600 // statistics present.
601 //
602 // Data points:
603 // 00:00:00.424518 (424ms) on late 2013 Mac with Mac OS X 10.9.5
TEST_F(StatsMgrTest,DISABLED_performanceMultipleSet)604 TEST_F(StatsMgrTest, DISABLED_performanceMultipleSet) {
605     StatsMgr::instance().removeAll();
606 
607     uint32_t cycles = 1000000;
608     uint32_t stats = 1000;
609 
610     for (uint32_t i = 0; i < stats; ++i) {
611         std::stringstream tmp;
612         tmp << "statistic" << i;
613         StatsMgr::instance().setValue(tmp.str(), static_cast<int64_t>(i));
614     }
615 
616     auto before = SampleClock::now();
617     for (uint32_t i = 0; i < cycles; ++i) {
618         StatsMgr::instance().setValue("metric1", static_cast<int64_t>(i));
619     }
620     auto after = SampleClock::now();
621 
622     auto dur = after - before;
623 
624     std::cout << "Setting one of " << stats << " statistics " << cycles
625               << " times took: " << isc::util::durationToText(dur) << std::endl;
626 }
627 
628 // Test checks whether statistics name can be generated using various
629 // indexes.
TEST_F(StatsMgrTest,generateName)630 TEST_F(StatsMgrTest, generateName) {
631     // generateName is a templated method, so in principle anything printable
632     // to stream can be used as index. However, in practice only integers
633     // and possibly strings will be used.
634 
635     // Let's text integer as index.
636     EXPECT_EQ("subnet[123].pkt4-received",
637               StatsMgr::generateName("subnet", 123, "pkt4-received"));
638 
639     // Lets' test string as index.
640     EXPECT_EQ("subnet[foo].pkt4-received",
641               StatsMgr::generateName("subnet", "foo", "pkt4-received"));
642 }
643 
644 // Test checks if statistic-get handler is able to return specified statistic.
TEST_F(StatsMgrTest,commandStatisticGet)645 TEST_F(StatsMgrTest, commandStatisticGet) {
646     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
647 
648     ElementPtr params = Element::createMap();
649     params->set("name", Element::create("alpha"));
650 
651     ConstElementPtr rsp = StatsMgr::instance().statisticGetHandler("statistic-get",
652                                                                    params);
653 
654     ObservationPtr alpha;
655     EXPECT_NO_THROW(alpha = StatsMgr::instance().getObservation("alpha"));
656     ASSERT_TRUE(alpha);
657 
658     std::string exp = "{ \"alpha\": [ [ 1234, \"" +
659         isc::util::clockToText(alpha->getInteger().second) + "\" ] ] }";
660 
661     EXPECT_EQ("{ \"arguments\": " + exp + ", \"result\": 0 }", rsp->str());
662 }
663 
664 // Test checks if statistic-get is able to handle:
665 // - a request without parameters
666 // - a request with missing statistic name
667 // - a request for non-existing statistic.
TEST_F(StatsMgrTest,commandStatisticGetNegative)668 TEST_F(StatsMgrTest, commandStatisticGetNegative) {
669     // Case 1: a request without parameters
670     ConstElementPtr rsp = StatsMgr::instance().statisticGetHandler("statistic-get",
671                                                                    ElementPtr());
672     int status_code;
673     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
674     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
675 
676     // Case 2: a request with missing statistic name
677     ElementPtr params = Element::createMap();
678     rsp = StatsMgr::instance().statisticGetHandler("statistic-get", params);
679     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
680     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
681 
682     // Case 3: a request for non-existing statistic
683     params->set("name", Element::create("alpha"));
684     rsp = StatsMgr::instance().statisticGetHandler("statistic-get", params);
685     EXPECT_EQ("{ \"arguments\": {  }, \"result\": 0 }", rsp->str());
686 }
687 
688 // This test checks whether statistic-get-all command returns all statistics
689 // correctly.
TEST_F(StatsMgrTest,commandGetAll)690 TEST_F(StatsMgrTest, commandGetAll) {
691     // Set a couple of statistics
692     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
693     StatsMgr::instance().setValue("beta", 12.34);
694     StatsMgr::instance().setValue("gamma", dur1234);
695     StatsMgr::instance().setValue("delta", "Lorem ipsum");
696 
697     // Now get them. They're used to generate expected output
698     ConstElementPtr rep_alpha = StatsMgr::instance().get("alpha");
699     ConstElementPtr rep_beta = StatsMgr::instance().get("beta");
700     ConstElementPtr rep_gamma = StatsMgr::instance().get("gamma");
701     ConstElementPtr rep_delta = StatsMgr::instance().get("delta");
702 
703     ASSERT_TRUE(rep_alpha);
704     ASSERT_TRUE(rep_beta);
705     ASSERT_TRUE(rep_gamma);
706     ASSERT_TRUE(rep_delta);
707 
708     std::string exp_str_alpha = "[ [ 1234, \"" +
709         isc::util::clockToText(StatsMgr::instance().getObservation("alpha")
710                                    ->getInteger().second) + "\" ] ]";
711     std::string exp_str_beta = "[ [ 12.34, \"" +
712         isc::util::clockToText(StatsMgr::instance().getObservation("beta")
713                                    ->getFloat().second) + "\" ] ]";
714     std::string exp_str_gamma = "[ [ \"01:02:03.004000\", \"" +
715         isc::util::clockToText(StatsMgr::instance().getObservation("gamma")
716                                    ->getDuration().second) + "\" ] ]";
717     std::string exp_str_delta = "[ [ \"Lorem ipsum\", \"" +
718         isc::util::clockToText(StatsMgr::instance().getObservation("delta")
719                                    ->getString().second) + "\" ] ]";
720 
721     // Check that all of them can be reported at once
722     ConstElementPtr rsp = StatsMgr::instance().statisticGetAllHandler(
723         "statistic-get-all", ElementPtr());
724     ASSERT_TRUE(rsp);
725     int status_code;
726     ConstElementPtr rep_all = parseAnswer(status_code, rsp);
727     ASSERT_EQ(0, status_code);
728     ASSERT_TRUE(rep_all);
729 
730     // Verifying this is a bit more involved, as we don't know whether the
731     // order would be preserved or not.
732     EXPECT_EQ(4, rep_all->size());
733     ASSERT_TRUE(rep_all->get("alpha"));
734     ASSERT_TRUE(rep_all->get("beta"));
735     ASSERT_TRUE(rep_all->get("delta"));
736     ASSERT_TRUE(rep_all->get("gamma"));
737     EXPECT_FALSE(rep_all->get("epsilon"));
738 
739     EXPECT_EQ(exp_str_alpha, rep_all->get("alpha")->str());
740     EXPECT_EQ(exp_str_beta, rep_all->get("beta")->str());
741     EXPECT_EQ(exp_str_gamma, rep_all->get("gamma")->str());
742     EXPECT_EQ(exp_str_delta, rep_all->get("delta")->str());
743 }
744 
745 // Test checks if statistic-reset handler is able to reset specified statistic.
TEST_F(StatsMgrTest,commandStatisticReset)746 TEST_F(StatsMgrTest, commandStatisticReset) {
747     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
748 
749     ElementPtr params = Element::createMap();
750     params->set("name", Element::create("alpha"));
751 
752     ConstElementPtr rsp =
753         StatsMgr::instance().statisticResetHandler("statistic-reset", params);
754     int status_code;
755     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
756     EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code);
757 
758     ObservationPtr alpha;
759     EXPECT_NO_THROW(alpha = StatsMgr::instance().getObservation("alpha"));
760     ASSERT_TRUE(alpha);
761 
762     // Check that it was indeed reset
763     EXPECT_EQ(0, alpha->getInteger().first);
764 }
765 
766 // Test checks if statistic-reset is able to handle:
767 // - a request without parameters
768 // - a request with missing statistic name
769 // - a request for non-existing statistic.
TEST_F(StatsMgrTest,commandStatisticResetNegative)770 TEST_F(StatsMgrTest, commandStatisticResetNegative) {
771     // Case 1: a request without parameters
772     ConstElementPtr rsp =
773         StatsMgr::instance().statisticResetHandler("statistic-reset", ElementPtr());
774     int status_code;
775     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
776     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
777 
778     // Case 2: a request with missing statistic name
779     ElementPtr params = Element::createMap();
780     rsp = StatsMgr::instance().statisticResetHandler("statistic-reset", params);
781     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
782     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
783 
784     // Case 3: a request for non-existing statistic
785     params->set("name", Element::create("alpha"));
786     rsp = StatsMgr::instance().statisticResetHandler("statistic-reset", params);
787     EXPECT_EQ("{ \"result\": 1, \"text\": \"No 'alpha' statistic found\" }",
788               rsp->str());
789 }
790 
791 // This test checks whether statistic-reset-all command really resets all
792 // statistics correctly.
TEST_F(StatsMgrTest,commandResetAll)793 TEST_F(StatsMgrTest, commandResetAll) {
794     // Set a couple of statistics
795     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
796     StatsMgr::instance().setValue("beta", 12.34);
797     StatsMgr::instance().setValue("gamma", dur1234);
798     StatsMgr::instance().setValue("delta", "Lorem ipsum");
799 
800     // Now get them. They're used to generate expected output
801     ConstElementPtr rep_alpha = StatsMgr::instance().get("alpha");
802     ConstElementPtr rep_beta = StatsMgr::instance().get("beta");
803     ConstElementPtr rep_gamma = StatsMgr::instance().get("gamma");
804     ConstElementPtr rep_delta = StatsMgr::instance().get("delta");
805 
806     ASSERT_TRUE(rep_alpha);
807     ASSERT_TRUE(rep_beta);
808     ASSERT_TRUE(rep_gamma);
809     ASSERT_TRUE(rep_delta);
810 
811     std::string exp_str_alpha = "[ [ 1234, \"" +
812         isc::util::clockToText(StatsMgr::instance().getObservation("alpha")
813                                    ->getInteger().second) + "\" ] ]";
814     std::string exp_str_beta = "[ [ 12.34, \"" +
815         isc::util::clockToText(StatsMgr::instance().getObservation("beta")
816                                    ->getFloat().second) + "\" ] ]";
817     std::string exp_str_gamma = "[ [ \"01:02:03.004000\", \"" +
818         isc::util::clockToText(StatsMgr::instance().getObservation("gamma")
819                                    ->getDuration().second) + "\" ] ]";
820     std::string exp_str_delta = "[ [ \"Lorem ipsum\", \"" +
821         isc::util::clockToText(StatsMgr::instance().getObservation("delta")
822                                    ->getString().second) + "\" ] ]";
823 
824     // Check that all of them can be reset at once
825     ConstElementPtr rsp = StatsMgr::instance().statisticResetAllHandler(
826         "statistic-reset-all", ElementPtr());
827     ASSERT_TRUE(rsp);
828     int status_code;
829     ConstElementPtr rep_all = parseAnswer(status_code, rsp);
830     ASSERT_EQ(0, status_code);
831     ASSERT_TRUE(rep_all);
832 
833     // Check that they're indeed reset
834     EXPECT_EQ(0,
835               StatsMgr::instance().getObservation("alpha")->getInteger().first);
836     EXPECT_EQ(0.0f,
837               StatsMgr::instance().getObservation("beta")->getFloat().first);
838     EXPECT_EQ(StatsDuration::zero(),
839               StatsMgr::instance().getObservation("gamma")->getDuration().first);
840     EXPECT_EQ("",
841               StatsMgr::instance().getObservation("delta")->getString().first);
842 }
843 
844 // Test checks if statistic-remove handler is able to remove a statistic.
TEST_F(StatsMgrTest,commandStatisticRemove)845 TEST_F(StatsMgrTest, commandStatisticRemove) {
846     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
847 
848     ElementPtr params = Element::createMap();
849     params->set("name", Element::create("alpha"));
850 
851     ConstElementPtr rsp =
852         StatsMgr::instance().statisticRemoveHandler("statistic-remove", params);
853     int status_code;
854     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
855     EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code);
856 
857     // It should be gone.
858     EXPECT_FALSE(StatsMgr::instance().getObservation("alpha"));
859     EXPECT_EQ(0, StatsMgr::instance().count());
860 }
861 
862 // Test checks if statistic-remove is able to handle:
863 // - a request without parameters
864 // - a request with missing statistic name
865 // - a request for non-existing statistic.
TEST_F(StatsMgrTest,commandStatisticRemoveNegative)866 TEST_F(StatsMgrTest, commandStatisticRemoveNegative) {
867     // Case 1: a request without parameters
868     ConstElementPtr rsp =
869         StatsMgr::instance().statisticRemoveHandler("statistic-remove", ElementPtr());
870     int status_code;
871     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
872     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
873 
874     // Case 2: a request with missing statistic name
875     ElementPtr params = Element::createMap();
876     rsp = StatsMgr::instance().statisticRemoveHandler("statistic-remove", params);
877     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
878     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
879 
880     // Case 3: a request for non-existing statistic
881     params->set("name", Element::create("alpha"));
882     rsp = StatsMgr::instance().statisticRemoveHandler("statistic-remove", params);
883     EXPECT_EQ("{ \"result\": 1, \"text\": \"No 'alpha' statistic found\" }",
884               rsp->str());
885 }
886 
887 // This test checks whether statistic-remove-all command really resets all
888 // statistics correctly.
TEST_F(StatsMgrTest,commandRemoveAll)889 TEST_F(StatsMgrTest, commandRemoveAll) {
890     // Set a couple of statistics
891     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
892     StatsMgr::instance().setValue("beta", 12.34);
893     StatsMgr::instance().setValue("gamma", dur1234);
894     StatsMgr::instance().setValue("delta", "Lorem ipsum");
895 
896     // Check that all of them can be reset at once
897     ConstElementPtr rsp = StatsMgr::instance().statisticRemoveAllHandler(
898         "statistic-remove-all", ElementPtr());
899     ASSERT_TRUE(rsp);
900     int status_code;
901     ConstElementPtr rep_all = parseAnswer(status_code, rsp);
902     ASSERT_EQ(0, status_code);
903     ASSERT_TRUE(rep_all);
904     std::string exp = "\"Warning: statistic-remove-all command is deprecated.";
905     exp += " All statistics removed.\"";
906     EXPECT_EQ(exp, rep_all->str());
907 
908     EXPECT_FALSE(StatsMgr::instance().getObservation("alpha"));
909     EXPECT_FALSE(StatsMgr::instance().getObservation("beta"));
910     EXPECT_FALSE(StatsMgr::instance().getObservation("gamma"));
911     EXPECT_FALSE(StatsMgr::instance().getObservation("delta"));
912     EXPECT_EQ(0, StatsMgr::instance().count());
913 }
914 
915 // This test checks whether statistic-sample-age-set command really set
916 // max_sample_age_ limit correctly.
TEST_F(StatsMgrTest,commandSetMaxSampleAge)917 TEST_F(StatsMgrTest, commandSetMaxSampleAge) {
918     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
919 
920     ElementPtr params = Element::createMap();
921     params->set("name", Element::create("alpha"));
922     params->set("duration", Element::create(1245)); // minutes(20) + seconds(45)
923 
924     ConstElementPtr rsp =
925         StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-sample-age-set", params);
926     int status_code;
927     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
928     EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code);
929 
930     // check if time limit was set properly and whether count limit is disabled
931     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, true);
932     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second,
933               minutes(20) + seconds(45));
934     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, false);
935 }
936 
937 // Test checks if statistic-sample-age-set is able to handle:
938 // - a request without parameters
939 // - a request without duration parameter
940 // - a request with missing statistic name
941 // - a request for non-existing statistic.
TEST_F(StatsMgrTest,commandSetMaxSampleAgeNegative)942 TEST_F(StatsMgrTest, commandSetMaxSampleAgeNegative) {
943     // Case 1: a request without parameters
944     ConstElementPtr rsp =
945         StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-sample-age-set", ElementPtr());
946     int status_code;
947     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
948     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
949 
950     // Case 2: a request without duration parameter
951     ElementPtr params = Element::createMap();
952     params->set("name", Element::create("alpha"));
953     rsp = StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-sample-age-set", params);
954     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
955     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
956 
957     // Case 3: a request with missing statistic name
958     params = Element::createMap();
959     params->set("duration", Element::create(100));
960     rsp = StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-sample-age-set", params);
961     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
962     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
963 
964     // Case 4: a request for non-existing statistic
965     params->set("name", Element::create("alpha"));
966     rsp = StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-sample-age-set", params);
967     EXPECT_EQ("{ \"result\": 1, \"text\": \"No 'alpha' statistic found\" }",
968               rsp->str());
969 }
970 
TEST_F(StatsMgrTest,commandSetMaxSampleAgeAll)971 TEST_F(StatsMgrTest, commandSetMaxSampleAgeAll) {
972     // Set a couple of statistics
973     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
974     StatsMgr::instance().setValue("beta", 12.34);
975     StatsMgr::instance().setValue("gamma", dur1234);
976     StatsMgr::instance().setValue("delta", "Lorem ipsum");
977 
978     ElementPtr params = Element::createMap();
979     params->set("duration", Element::create(3765)); // set duration to 3765 seconds
980 
981     ConstElementPtr rsp =
982         StatsMgr::instance().statisticSetMaxSampleAgeAllHandler(params);
983     int status_code;
984     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
985     EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code);
986 
987     // check defaults
988     EXPECT_EQ(StatsMgr::instance().getMaxSampleAgeDefault(), seconds(3765));
989     EXPECT_EQ(StatsMgr::instance().getMaxSampleCountDefault(), 0);
990 
991     // check if time limit was set properly and whether count limit is disabled
992     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, true);
993     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second,
994               dur1245);
995     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, false);
996 
997     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, true);
998     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().second,
999               dur1245);
1000     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, false);
1001 
1002     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, true);
1003     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().second,
1004               dur1245);
1005     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, false);
1006 
1007     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, true);
1008     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().second,
1009               dur1245);
1010     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, false);
1011 }
1012 
1013 // This test checks whether statistic-sample-count-set command really set
1014 // max_sample_count_ limit correctly.
TEST_F(StatsMgrTest,commandSetMaxSampleCount)1015 TEST_F(StatsMgrTest, commandSetMaxSampleCount) {
1016     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
1017 
1018     ElementPtr params = Element::createMap();
1019     params->set("name", Element::create("alpha"));
1020     params->set("max-samples", Element::create(15));
1021 
1022     ConstElementPtr rsp =
1023         StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-sample-count-set", params);
1024     int status_code;
1025     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
1026     EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code);
1027 
1028     // check if time limit was set properly and whether duration limit is disabled
1029     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, true);
1030     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().second, 15);
1031     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, false);
1032 }
1033 
1034 // Test checks if statistic-sample-count-set is able to handle:
1035 // - a request without parameters
1036 // - a request without max-samples parameter
1037 // - a request with missing statistic name
1038 // - a request for non-existing statistic.
TEST_F(StatsMgrTest,commandSetMaxSampleCountNegative)1039 TEST_F(StatsMgrTest, commandSetMaxSampleCountNegative) {
1040     // Case 1: a request without parameters
1041     ConstElementPtr rsp =
1042         StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-sample-count-set", ElementPtr());
1043     int status_code;
1044     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
1045     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
1046 
1047     // Case 2: a request without max-samples parameter
1048     ElementPtr params = Element::createMap();
1049     params->set("name", Element::create("alpha"));
1050     rsp = StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-sample-count-set", params);
1051     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
1052     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
1053 
1054     // Case 3: a request with missing statistic name
1055     params = Element::createMap();
1056     params->set("max-samples", Element::create(10));
1057     rsp = StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-sample-count-set", params);
1058     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
1059     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
1060 
1061     // Case 4: a request for non-existing statistic
1062     params->set("name", Element::create("alpha"));
1063     rsp = StatsMgr::instance().statisticSetMaxSampleCountHandler("statistic-sample-count-set", params);
1064     EXPECT_EQ("{ \"result\": 1, \"text\": \"No 'alpha' statistic found\" }",
1065               rsp->str());
1066 }
1067 
TEST_F(StatsMgrTest,commandSetMaxSampleCountAll)1068 TEST_F(StatsMgrTest, commandSetMaxSampleCountAll) {
1069     // Set a couple of statistics
1070     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
1071     StatsMgr::instance().setValue("beta", 12.34);
1072     StatsMgr::instance().setValue("gamma", dur1234);
1073     StatsMgr::instance().setValue("delta", "Lorem ipsum");
1074 
1075     ElementPtr params = Element::createMap();
1076     params->set("max-samples", Element::create(200));
1077 
1078     ConstElementPtr rsp =
1079         StatsMgr::instance().statisticSetMaxSampleCountAllHandler(params);
1080     int status_code;
1081     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
1082     EXPECT_EQ(CONTROL_RESULT_SUCCESS, status_code);
1083 
1084     // check default
1085     EXPECT_EQ(StatsMgr::instance().getMaxSampleCountDefault(), 200);
1086 
1087     // check if count limit was set properly and whether count limit is disabled
1088     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, true);
1089     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().second, 200);
1090     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, false);
1091 
1092     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, true);
1093     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().second, 200);
1094     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, false);
1095 
1096     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, true);
1097     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().second, 200);
1098     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, false);
1099 
1100     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, true);
1101     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().second, 200);
1102     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, false);
1103 }
1104 
1105 // Test checks if statistics-sample-count-set-all fails on zero.
TEST_F(StatsMgrTest,commandSetMaxSampleCountAllZero)1106 TEST_F(StatsMgrTest, commandSetMaxSampleCountAllZero) {
1107     ElementPtr params = Element::createMap();
1108     params->set("max-samples", Element::create(0));
1109 
1110     ConstElementPtr rsp =
1111         StatsMgr::instance().statisticSetMaxSampleCountAllHandler(params);
1112     int status_code;
1113     ASSERT_NO_THROW(parseAnswer(status_code, rsp));
1114     EXPECT_EQ(status_code, CONTROL_RESULT_ERROR);
1115 }
1116 
1117 }
1118