4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief Statistics unit tests */
26 //#include "Statistics.test.hh"
27 //#include "Statistics.test.ih"
30 #include "Statistics.hh"
31 #include "StatisticsTargets.hh"
32 #include <boost/tokenizer.hpp>
33 #include <boost/iterator/transform_iterator.hpp>
34 #include <boost/iterator/filter_iterator.hpp>
36 #include "auto_unit_test.hh"
37 #include <boost/test/test_tools.hpp>
38 #include <boost/test/floating_point_comparison.hpp>
41 ///////////////////////////////cc.p////////////////////////////////////////
47 typedef senf::Collector const & first_argument_type;
48 typedef unsigned result_type;
49 result_type operator()(first_argument_type arg) const
50 { return arg.rank(); }
55 typedef boost::char_separator<char> Separator;
56 typedef boost::tokenizer<Separator> Tokenizer;
58 bool operator()(std::string const & s) const
59 { try { boost::lexical_cast<double>(s); return true; }
60 catch (std::bad_cast &) { return false; } }
62 typedef boost::filter_iterator<Pred,Tokenizer::iterator> FilterIterator;
64 typedef double result_type;
65 result_type operator()(std::string const & s) const
66 { return boost::lexical_cast<double>(s); }
68 typedef boost::transform_iterator<Trafo,FilterIterator> TransformIterator;
70 typedef TransformIterator iterator;
71 typedef TransformIterator const_iterator;
73 splitFloats(std::string const & s) : s_ (s), sep_ (" \n"), tok_ (s_, sep_) {}
74 TransformIterator begin() const
75 { return TransformIterator(FilterIterator(tok_.begin(), tok_.end())); }
76 TransformIterator end() const
77 { return TransformIterator(FilterIterator(tok_.end(), tok_.end())); }
84 template <class R1, class R2>
85 void CHECK_CLOSE_RANGES(R1 const & r1, R2 const & r2, double delta)
87 typedef typename boost::range_const_iterator<R1>::type I1;
88 typedef typename boost::range_const_iterator<R2>::type I2;
90 I1 i1 (boost::begin(r1));
91 I1 i1_end (boost::end(r1));
92 I2 i2 (boost::begin(r2));
93 I2 i2_end (boost::end(r2));
95 for (; i1 != i1_end && i2 != i2_end; ++i1, ++i2) {
96 BOOST_CHECK_CLOSE(*i1, *i2, delta);
99 BOOST_CHECK( i1 == i1_end );
100 BOOST_CHECK( i2 == i2_end );
104 SENF_AUTO_UNIT_TEST(statistics)
106 senf::Statistics stats;
107 senf::log::StringTarget statslog;
110 statslog.showTime(false);
111 statslog.showArea(false);
112 statslog.showLevel(false);
113 statslog.route<senf::StatisticsStream>();
117 senf::StatisticsLogger("level0"))
120 senf::StatisticsLogger("level1"))
122 senf::StatisticsLogger("averaged1"))
126 senf::StatisticsLogger("level3"));
128 unsigned children1[] = { 4u };
129 BOOST_CHECK_EQUAL_COLLECTIONS(
130 boost::make_transform_iterator(stats.collectors().begin(), GetRange()),
131 boost::make_transform_iterator(stats.collectors().end(), GetRange()),
132 children1, children1 + sizeof(children1)/sizeof(children1[0]) );
134 unsigned children2[] = { 3u };
135 BOOST_CHECK_EQUAL_COLLECTIONS(
136 boost::make_transform_iterator(stats[4].collectors().begin(), GetRange()),
137 boost::make_transform_iterator(stats[4].collectors().end(), GetRange()),
138 children2, children2 + sizeof(children2)/sizeof(children2[0]) );
140 unsigned children3[] = { 2u };
141 BOOST_CHECK_EQUAL_COLLECTIONS(
142 boost::make_transform_iterator(stats[4][3].collectors().begin(), GetRange()),
143 boost::make_transform_iterator(stats[4][3].collectors().end(), GetRange()),
144 children3, children3 + sizeof(children3)/sizeof(children3[0]) );
146 float values[][3] = {
147 { -1.0f, 2.3f, 2.5f }, { 0.3f, 2.4f, 3.8f }, { -1.1f, -0.3f, 0.0f },
148 { -0.3f, 3.2f, 3.3f }, { 1.0f, 1.1f, 1.1f }, { 0.5f, 0.5f, 0.5f },
149 { 0.0f, 0.0f, 0.0f }, { -2.0f, -1.8f, -1.0f }, { 0.0f, 2.3f, 2.4f },
150 { 0.4f, 1.2f, 2.0f }, { -1.0f, 2.3f, 2.5f }, { 0.3f, 2.4f, 3.8f },
151 { -1.1f, -0.3f, 0.0f }, { -0.3f, 3.2f, 3.3f }, { 1.0f, 1.1f, 1.1f },
152 { 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f, 0.0f }, { -2.0f, -1.8f, -1.0f },
153 { 0.0f, 2.3f, 2.4f }, { 0.4f, 1.2f, 2.0f }, { -1.0f, 2.3f, 2.5f },
154 { 0.3f, 2.4f, 3.8f }, { -1.1f, -0.3f, 0.0f }, { -0.3f, 3.2f, 3.3f },
155 { 1.0f, 1.1f, 1.1f }, { 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f, 0.0f },
156 { -2.0f, -1.8f, -1.0f }, { 0.0f, 2.3f, 2.4f }, { 0.4f, 1.2f, 4.0f } };
158 for (unsigned i (0); i < sizeof(values)/sizeof(values[0]); ++i)
159 stats(values[i][0], values[i][1], values[i][2]);
161 BOOST_CHECK_CLOSE( stats.min(), 0.4f, .001f );
162 BOOST_CHECK_CLOSE( stats.avg(), 1.2f, .001f );
163 BOOST_CHECK_CLOSE( stats.max(), 4.0f, .001f );
164 BOOST_CHECK_CLOSE( stats.dev(), 0.0f, .001f );
166 BOOST_CHECK_CLOSE( stats[4].min(), -2.0f, .001f );
167 BOOST_CHECK_CLOSE( stats[4].avg(), -0.05f, .001f );
168 BOOST_CHECK_CLOSE( stats[4].max(), 1.1f, .001f );
169 BOOST_CHECK_CLOSE( stats[4].dev(), 1.08282f, .001f );
171 BOOST_CHECK_CLOSE( stats[4][3].min(), -2.0f, .001f );
172 BOOST_CHECK_CLOSE( stats[4][3].avg(), 1.15f, .001f );
173 BOOST_CHECK_CLOSE( stats[4][3].max(), 3.8f, .001f );
175 CHECK_CLOSE_RANGES( splitFloats(statslog.str()),
176 splitFloats("level0 -1 2.3 2.5 0\n"
177 "level0 -0.35 2.35 3.15 0\n"
178 "level0 -0.4 1.05 1.9 0\n"
179 "level0 -0.7 1.45 1.65 0\n"
180 "level1 -1.1 1.9 3.8 1.31719\n"
181 "averaged1 -1.1 1.9 3.8 1.31719\n"
182 "level0 0.35 2.15 2.2 0\n"
183 "level0 0.75 0.8 0.8 0\n"
184 "level0 0.25 0.25 0.25 0\n"
185 "level0 -1 -0.9 -0.5 0\n"
186 "level1 -2 -0.05 1.1 1.08282\n"
187 "averaged1 -1.55 0.925 2.45 1.20001\n"
188 "level0 -1 0.25 0.7 0\n"
189 "level0 0.2 1.75 2.2 0\n"
190 "level0 -0.3 1.75 2.25 0\n"
191 "level0 -0.35 2.35 3.15 0\n"
192 "level1 -1 2.05 3.8 0.492442\n"
193 "averaged1 -1.36667 1.3 2.9 0.964152\n"
194 "level0 -0.4 1.05 1.9 0\n"
195 "level0 -0.7 1.45 1.65 0\n"
196 "level0 0.35 2.15 2.2 0\n"
197 "level0 0.75 0.8 0.8 0\n"
198 "level1 -1.1 1.125 3.3 1.29687\n"
199 "averaged1 -1.36667 1.04167 2.73333 0.957378\n"
200 "level0 0.25 0.25 0.25 0\n"
201 "level0 -1 -0.9 -0.5 0\n"
202 "level0 -1 0.25 0.7 0\n"
203 "level0 0.2 1.75 2.2 0\n"
204 "level1 -2 0.425 2.4 1.52049\n"
205 "averaged1 -1.36667 1.2 3.16667 1.10327\n"
206 "level0 -0.3 1.75 2.25 0\n"
207 "level0 -0.35 2.35 3.15 0\n"
208 "level0 -0.4 1.05 1.9 0\n"
209 "level0 -0.7 1.45 1.65 0\n"
210 "level1 -1.1 1.9 3.8 1.31719\n"
211 "averaged1 -1.4 1.15 3.16667 1.37818\n"
212 "level3 -2 1.225 3.8 1.45752\n"
213 "level0 0.35 2.15 2.2 0\n"
214 "level0 0.75 0.8 0.8 0\n"
215 "level0 0.25 0.25 0.25 0\n"
216 "level0 -1 -0.9 -0.5 0\n"
217 "level1 -2 -0.05 1.1 1.08282\n"
218 "averaged1 -1.7 0.758333 2.43333 1.30683\n"
219 "level0 -1 0.25 0.7 0\n"
220 "level0 0.2 1.75 3.2 0\n"),
224 ///////////////////////////////cc.e////////////////////////////////////////
231 // comment-column: 40
232 // c-file-style: "senf"
233 // indent-tabs-mode: nil
234 // ispell-local-dictionary: "american"
235 // compile-command: "scons -u test"