Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
83b9b8a8
Commit
83b9b8a8
authored
May 08, 2015
by
Tomek Mrugalski
🛰
Browse files
[3793] Unit-tests for StatsMgr implemented.
parent
e76178c1
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/lib/stats/stats_mgr.h
View file @
83b9b8a8
...
...
@@ -32,17 +32,14 @@ class StatsMgr : public boost::noncopyable {
static
StatsMgr
&
instance
();
// methods used data producers
void
addValue
(
const
std
::
string
&
name
,
uint64_t
value
=
1
);
void
addValue
(
const
std
::
string
&
name
,
double
value
=
1.0
f
);
void
addValue
(
const
std
::
string
&
name
,
uint64_t
value
);
void
addValue
(
const
std
::
string
&
name
,
double
value
);
void
addValue
(
const
std
::
string
&
name
,
StatsDuration
time
);
void
addValue
(
const
std
::
string
&
name
,
const
std
::
string
&
value
);
void
setValue
(
const
std
::
string
&
name
,
uint64_t
value
=
1
);
void
setValue
(
const
std
::
string
&
name
,
double
value
=
1.0
f
);
void
setValue
(
const
std
::
string
&
name
,
StatsDuration
time
);
// resets statistic
// this is a convenience function and is equivalent to
// setValue(0) or setValue(0.0f)
void
reset
(
const
std
::
string
&
name
);
void
setValue
(
const
std
::
string
&
name
,
const
std
::
string
&
value
);
/// @brief determines whether a given statistic is kept as a single value
/// or as a number of values
...
...
@@ -50,14 +47,17 @@ class StatsMgr : public boost::noncopyable {
/// Specifies that statistic name should be stored not as a single value,
/// but rather as a set of values. duration determines the timespan.
/// Samples older than duration will be discarded. This is time-constrained
/// approach. For sample count constrained approach, see setStorage() below.
/// approach. For sample count constrained approach, see @ref
/// setMaxSampleCount() below.
///
/// @todo: Not implemented.
///
/// Example: to set a statistic to keep observations for the last 5 minutes,
/// call set
Stora
ge("incoming-packets", time_duration(0,5,0,0));
/// call set
MaxSampleA
ge("incoming-packets", time_duration(0,5,0,0));
/// to revert statistic to a single value, call:
/// set
Stora
ge("incoming-packets" time_duration(0,0,0,0))
void
set
Stora
ge
(
const
std
::
string
&
name
,
boost
::
posix_time
::
time_duration
duration
);
/// set
MaxSampleA
ge("incoming-packets" time_duration(0,0,0,0))
void
set
MaxSampleA
ge
(
const
std
::
string
&
name
,
boost
::
posix_time
::
time_duration
duration
);
/// @brief determines how many samples of a given statistic should be kept.
///
...
...
@@ -65,16 +65,50 @@ class StatsMgr : public boost::noncopyable {
/// rather as a set of values. In this form, at most max_samples will be kept.
/// When adding max_samples+1 sample, the oldest sample will be discarded.
///
/// @todo: Not implemented.
///
/// Example:
/// To set a statistic to keep the last 100 observations, call:
/// setStorage("incoming-packets", 100);
void
setStorage
(
const
std
::
string
&
name
,
uint32_t
max_samples
);
/// setMaxSampleCount("incoming-packets", 100);
void
setMaxSampleCount
(
const
std
::
string
&
name
,
uint32_t
max_samples
);
/// @brief Resets specified statistic.
///
/// This is a convenience function and is equivalent to setValue(name,
/// neutral_value), where neutral_value is 0, 0.0 or "".
/// @param name name of the statistic to be reset.
/// @return true if successful, false if there's no such statistic
bool
reset
(
const
std
::
string
&
name
);
/// @brief Removes specified statistic.
/// @param name name of the statistic to be removed.
/// @return true if successful, false if there's no such statistic
bool
remove
(
const
std
::
string
&
name
);
//
methods used by data consumers
const
ObservationPtr
&
getValue
(
const
std
::
string
&
name
);
//
/ @brief Resets all collected statistics back to zero.
void
resetAll
(
);
// returns all statistics
const
std
::
map
<
std
::
string
,
ObservationPtr
>
getValues
();
/// @brief Removes all collected statistics.
void
removeAll
();
/// @brief Returns number of available statistics.
/// @return number of recorded statistics.
size_t
count
();
/// @brief Returns a single statistic as a JSON structure
/// @return JSON structures representing a single statistic
isc
::
data
::
ConstElementPtr
get
(
const
std
::
string
&
name
);
/// @brief Returns all statistics as a JSON structure
/// @return JSON structures representing all statistics
isc
::
data
::
ConstElementPtr
getAll
();
/// @brief Returns an observation
///
/// Used in testing only. Production code should use @ref get() method.
/// @param name name of the statistic
/// @return Pointer to the Observation object
ObservationPtr
getObservation
(
const
std
::
string
&
name
);
private:
/// @brief returns a context for specified name
...
...
@@ -82,8 +116,6 @@ class StatsMgr : public boost::noncopyable {
// This is a global context. All stats will initially be stored here.
StatContextPtr
global_
;
std
::
map
<
std
::
string
,
StatContextPtr
>
contexts_
;
};
};
...
...
src/lib/stats/tests/stats_mgr_unittest.cc
View file @
83b9b8a8
...
...
@@ -16,28 +16,264 @@
#include
<stats/stats_mgr.h>
#include
<exceptions/exceptions.h>
#include
<boost/date_time/posix_time/posix_time_types.hpp>
#include
<boost/shared_ptr.hpp>
#include
<cc/data.h>
#include
<gtest/gtest.h>
#include
<iostream>
#include
<sstream>
using
namespace
isc
;
using
namespace
isc
::
data
;
using
namespace
isc
::
stats
;
using
namespace
boost
::
posix_time
;
namespace
{
class
StatsMgrTest
:
public
::
testing
::
Test
{
public:
StatsMgrTest
()
{
StatsMgr
::
instance
();
}
~
StatsMgrTest
()
{
StatsMgr
::
instance
().
removeAll
();
}
};
// Basic test
s
for
V4 functionality
// Basic test for
statistics manager interface.
TEST_F
(
StatsMgrTest
,
basic
)
{
// EXPECT_NO_THROW(StatsMgr::instance());
// Getting an instance
EXPECT_NO_THROW
(
StatsMgr
::
instance
());
// Check that there are no statistics recorded by default.
EXPECT_EQ
(
0
,
StatsMgr
::
instance
().
count
());
}
// Test checks whether it's possible to record and later report
// an integer statistic.
TEST_F
(
StatsMgrTest
,
integerStat
)
{
EXPECT_NO_THROW
(
StatsMgr
::
instance
().
setValue
(
"alpha"
,
static_cast
<
uint64_t
>
(
1234
)));
ObservationPtr
alpha
;
EXPECT_NO_THROW
(
alpha
=
StatsMgr
::
instance
().
getObservation
(
"alpha"
));
EXPECT_TRUE
(
alpha
);
std
::
string
exp
=
"
\"
alpha
\"
: [ [ 1234,
\"
"
+
Observation
::
ptimeToText
(
alpha
->
getInteger
().
second
)
+
"
\"
] ]"
;
EXPECT_EQ
(
exp
,
StatsMgr
::
instance
().
get
(
"alpha"
)
->
str
());
}
// Test checks whether it's possible to record and later report
// a floating point statistic.
TEST_F
(
StatsMgrTest
,
floatStat
)
{
EXPECT_NO_THROW
(
StatsMgr
::
instance
().
setValue
(
"beta"
,
12.34
));
ObservationPtr
beta
;
EXPECT_NO_THROW
(
beta
=
StatsMgr
::
instance
().
getObservation
(
"beta"
));
EXPECT_TRUE
(
beta
);
std
::
string
exp
=
"
\"
beta
\"
: [ [ 12.34,
\"
"
+
Observation
::
ptimeToText
(
beta
->
getFloat
().
second
)
+
"
\"
] ]"
;
EXPECT_EQ
(
exp
,
StatsMgr
::
instance
().
get
(
"beta"
)
->
str
());
}
// Test checks whether it's possible to record and later report
// a duration statistic.
TEST_F
(
StatsMgrTest
,
durationStat
)
{
EXPECT_NO_THROW
(
StatsMgr
::
instance
().
setValue
(
"gamma"
,
microsec
::
time_duration
(
1
,
2
,
3
,
4
)));
ObservationPtr
gamma
;
EXPECT_NO_THROW
(
gamma
=
StatsMgr
::
instance
().
getObservation
(
"beta"
));
EXPECT_TRUE
(
gamma
);
std
::
string
exp
=
"
\"
gamma
\"
: [ [
\"
01:02:03.000004
\"
,
\"
"
+
Observation
::
ptimeToText
(
gamma
->
getDuration
().
second
)
+
"
\"
] ]"
;
EXPECT_EQ
(
exp
,
StatsMgr
::
instance
().
get
(
"gamma"
)
->
str
());
}
// Test checks whether it's possible to record and later report
// a string statistic.
TEST_F
(
StatsMgrTest
,
stringStat
)
{
EXPECT_NO_THROW
(
StatsMgr
::
instance
().
setValue
(
"delta"
,
"Lorem ipsum"
));
ObservationPtr
delta
;
EXPECT_NO_THROW
(
delta
=
StatsMgr
::
instance
().
getObservation
(
"delta"
));
EXPECT_TRUE
(
delta
);
std
::
string
exp
=
"
\"
delta
\"
: [ [
\"
Lorem impsum
\"
,
\"
"
+
Observation
::
ptimeToText
(
delta
->
getString
().
second
)
+
"
\"
] ]"
;
EXPECT_EQ
(
exp
,
StatsMgr
::
instance
().
get
(
"delta"
)
->
str
());
}
// Setting limits is currently not implemented, so those methods should
// throw.
TEST_F
(
StatsMgrTest
,
setLimits
)
{
EXPECT_THROW
(
StatsMgr
::
instance
().
setMaxSampleAge
(
"foo"
,
time_duration
(
1
,
0
,
0
,
0
)),
NotImplemented
);
EXPECT_THROW
(
StatsMgr
::
instance
().
setMaxSampleCount
(
"foo"
,
100
),
NotImplemented
);
}
// This test checks whether a single (get("foo")) and all (getAll())
// statistics are reported properly.
TEST_F
(
StatsMgrTest
,
getGetAll
)
{
// Set a couple of statistics
StatsMgr
::
instance
().
setValue
(
"alpha"
,
static_cast
<
uint64_t
>
(
1234
));
StatsMgr
::
instance
().
setValue
(
"beta"
,
12.34
);
StatsMgr
::
instance
().
setValue
(
"gamma"
,
time_duration
(
1
,
2
,
3
,
4
));
StatsMgr
::
instance
().
setValue
(
"delta"
,
"Lorem"
);
// Now add some values to them
StatsMgr
::
instance
().
addValue
(
"alpha"
,
static_cast
<
uint64_t
>
(
5678
));
StatsMgr
::
instance
().
addValue
(
"beta"
,
56.78
);
StatsMgr
::
instance
().
addValue
(
"gamma"
,
time_duration
(
5
,
6
,
7
,
8
));
StatsMgr
::
instance
().
addValue
(
"delta"
,
" ipsum"
);
// There should be 4 statistics reported
EXPECT_EQ
(
4
,
StatsMgr
::
instance
().
count
());
// Now check whether they can be reported back
ConstElementPtr
rep_alpha
=
StatsMgr
::
instance
().
get
(
"alpha"
);
ConstElementPtr
rep_beta
=
StatsMgr
::
instance
().
get
(
"beta"
);
ConstElementPtr
rep_gamma
=
StatsMgr
::
instance
().
get
(
"gamma"
);
ConstElementPtr
rep_delta
=
StatsMgr
::
instance
().
get
(
"delta"
);
ASSERT_TRUE
(
rep_alpha
);
ASSERT_TRUE
(
rep_beta
);
ASSERT_TRUE
(
rep_gamma
);
ASSERT_TRUE
(
rep_delta
);
std
::
string
exp_str_alpha
=
"
\"
alpha
\"
: [ [ 1234,
\"
"
+
Observation
::
ptimeToText
(
StatsMgr
::
instance
().
getObservation
(
"alpha"
)
->
getInteger
().
second
)
+
"
\"
] ]"
;
std
::
string
exp_str_beta
=
"
\"
beta
\"
: [ [ 12.34,
\"
"
+
Observation
::
ptimeToText
(
StatsMgr
::
instance
().
getObservation
(
"beta"
)
->
getFloat
().
second
)
+
"
\"
] ]"
;
std
::
string
exp_str_gamma
=
"
\"
gamma
\"
: [ [
\"
01:02:03.000004
\"
,
\"
"
+
Observation
::
ptimeToText
(
StatsMgr
::
instance
().
getObservation
(
"gamma"
)
->
getDuration
().
second
)
+
"
\"
] ]"
;
std
::
string
exp_str_delta
=
"
\"
delta
\"
: [ [
\"
Lorem impsum
\"
,
\"
"
+
Observation
::
ptimeToText
(
StatsMgr
::
instance
().
getObservation
(
"delta"
)
->
getString
().
second
)
+
"
\"
] ]"
;
// Check that individual stats are reported properly
EXPECT_EQ
(
exp_str_alpha
,
rep_alpha
->
str
());
EXPECT_EQ
(
exp_str_beta
,
rep_beta
->
str
());
EXPECT_EQ
(
exp_str_gamma
,
rep_gamma
->
str
());
EXPECT_EQ
(
exp_str_delta
,
rep_delta
->
str
());
// Check that non-existent metric is not reported.
EXPECT_FALSE
(
StatsMgr
::
instance
().
get
(
"epsilon"
));
// Check that all of them can be reported at once
ConstElementPtr
rep_all
=
StatsMgr
::
instance
().
getAll
();
ASSERT_TRUE
(
rep_all
);
// This may not be the best verification. There's no guarantee that the
// statistics will be reported in this specific order.
std
::
string
exp_all
=
exp_str_alpha
+
", "
+
exp_str_beta
+
", "
+
exp_str_gamma
+
", "
+
exp_str_delta
;
EXPECT_EQ
(
exp_all
,
rep_all
->
str
());
}
// This test checks whether existing statistics can be reset.
TEST_F
(
StatsMgrTest
,
reset
)
{
// Set a couple of statistics
StatsMgr
::
instance
().
setValue
(
"alpha"
,
static_cast
<
uint64_t
>
(
1234
));
StatsMgr
::
instance
().
setValue
(
"beta"
,
12.34
);
StatsMgr
::
instance
().
setValue
(
"gamma"
,
time_duration
(
1
,
2
,
3
,
4
));
StatsMgr
::
instance
().
setValue
(
"delta"
,
"Lorem ipsum"
);
// This should reset alpha to 0
EXPECT_NO_THROW
(
StatsMgr
::
instance
().
reset
(
"alpha"
));
EXPECT_EQ
(
0
,
StatsMgr
::
instance
().
getObservation
(
"alpha"
)
->
getInteger
().
first
);
// The other stats should remain untouched
EXPECT_EQ
(
12.34
,
StatsMgr
::
instance
().
getObservation
(
"beta"
)
->
getFloat
().
first
);
EXPECT_EQ
(
time_duration
(
1
,
2
,
3
,
4
),
StatsMgr
::
instance
().
getObservation
(
"gamma"
)
->
getDuration
().
first
);
EXPECT_EQ
(
"Lorem ipsum"
,
StatsMgr
::
instance
().
getObservation
(
"delta"
)
->
getString
().
first
);
// Now let's wipe them, too.
EXPECT_NO_THROW
(
StatsMgr
::
instance
().
reset
(
"beta"
));
EXPECT_NO_THROW
(
StatsMgr
::
instance
().
reset
(
"gamma"
));
EXPECT_NO_THROW
(
StatsMgr
::
instance
().
reset
(
"delta"
));
EXPECT_EQ
(
0.0
,
StatsMgr
::
instance
().
getObservation
(
"beta"
)
->
getFloat
().
first
);
EXPECT_EQ
(
time_duration
(
0
,
0
,
0
,
0
),
StatsMgr
::
instance
().
getObservation
(
"gamma"
)
->
getDuration
().
first
);
EXPECT_EQ
(
""
,
StatsMgr
::
instance
().
getObservation
(
"delta"
)
->
getString
().
first
);
// Resetting statistics should not remove them
EXPECT_EQ
(
4
,
StatsMgr
::
instance
().
count
());
}
// This test checks whether existing statistics can be reset.
TEST_F
(
StatsMgrTest
,
resetAll
)
{
// Set a couple of statistics
StatsMgr
::
instance
().
setValue
(
"alpha"
,
static_cast
<
uint64_t
>
(
1234
));
StatsMgr
::
instance
().
setValue
(
"beta"
,
12.34
);
StatsMgr
::
instance
().
setValue
(
"gamma"
,
time_duration
(
1
,
2
,
3
,
4
));
StatsMgr
::
instance
().
setValue
(
"delta"
,
"Lorem ipsum"
);
// This should reset alpha to 0
EXPECT_NO_THROW
(
StatsMgr
::
instance
().
resetAll
());
EXPECT_EQ
(
0
,
StatsMgr
::
instance
().
getObservation
(
"alpha"
)
->
getInteger
().
first
);
EXPECT_EQ
(
0.0
,
StatsMgr
::
instance
().
getObservation
(
"beta"
)
->
getFloat
().
first
);
EXPECT_EQ
(
time_duration
(
0
,
0
,
0
,
0
),
StatsMgr
::
instance
().
getObservation
(
"gamma"
)
->
getDuration
().
first
);
EXPECT_EQ
(
""
,
StatsMgr
::
instance
().
getObservation
(
"delta"
)
->
getString
().
first
);
// Resetting all statistics should not remove them
EXPECT_EQ
(
4
,
StatsMgr
::
instance
().
count
());
}
// This test checks whether statistics can be removed.
TEST_F
(
StatsMgrTest
,
removeAll
)
{
// Set a couple of statistics
StatsMgr
::
instance
().
setValue
(
"alpha"
,
static_cast
<
uint64_t
>
(
1234
));
StatsMgr
::
instance
().
setValue
(
"beta"
,
12.34
);
StatsMgr
::
instance
().
setValue
(
"gamma"
,
time_duration
(
1
,
2
,
3
,
4
));
StatsMgr
::
instance
().
setValue
(
"delta"
,
"Lorem ipsum"
);
// This should reset alpha to 0
EXPECT_NO_THROW
(
StatsMgr
::
instance
().
removeAll
());
// Resetting all statistics should not remove them
EXPECT_EQ
(
0
,
StatsMgr
::
instance
().
count
());
// There should be no such statistics anymore
EXPECT_FALSE
(
StatsMgr
::
instance
().
get
(
"alpha"
));
EXPECT_FALSE
(
StatsMgr
::
instance
().
get
(
"beta"
));
EXPECT_FALSE
(
StatsMgr
::
instance
().
get
(
"gamma"
));
EXPECT_FALSE
(
StatsMgr
::
instance
().
get
(
"delta"
));
// There should be no such statistics anymore
EXPECT_FALSE
(
StatsMgr
::
instance
().
getObservation
(
"alpha"
));
EXPECT_FALSE
(
StatsMgr
::
instance
().
getObservation
(
"beta"
));
EXPECT_FALSE
(
StatsMgr
::
instance
().
getObservation
(
"gamma"
));
EXPECT_FALSE
(
StatsMgr
::
instance
().
getObservation
(
"delta"
));
}
};
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment