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 #define CHECK_STATS(a, b) CHECK_CLOSE_RANGES(splitFloats(a),splitFloats(b),0.001f)
105 #define CHECK_STATS_STR(a,b) BOOST_CHECK_EQUAL(a,b)
107 SENF_AUTO_UNIT_TEST(statistics)
109 senf::Statistics stats;
110 senf::log::StringTarget statslog;
113 statslog.showTime(false);
114 statslog.showArea(false);
115 statslog.showLevel(false);
116 statslog.route<senf::StatisticsStream>();
120 senf::StatisticsLogger("level0"))
123 senf::StatisticsLogger("level1"))
125 senf::StatisticsLogger("averaged1"))
129 senf::StatisticsLogger("level3"));
131 unsigned children1[] = { 4u };
132 BOOST_CHECK_EQUAL_COLLECTIONS(
133 boost::make_transform_iterator(stats.collectors().begin(), GetRank()),
134 boost::make_transform_iterator(stats.collectors().end(), GetRank()),
135 children1, children1 + sizeof(children1)/sizeof(children1[0]) );
137 unsigned children2[] = { 3u };
138 BOOST_CHECK_EQUAL_COLLECTIONS(
139 boost::make_transform_iterator(stats[4].collectors().begin(), GetRank()),
140 boost::make_transform_iterator(stats[4].collectors().end(), GetRank()),
141 children2, children2 + sizeof(children2)/sizeof(children2[0]) );
143 unsigned children3[] = { 2u };
144 BOOST_CHECK_EQUAL_COLLECTIONS(
145 boost::make_transform_iterator(stats[4][3].collectors().begin(), GetRank()),
146 boost::make_transform_iterator(stats[4][3].collectors().end(), GetRank()),
147 children3, children3 + sizeof(children3)/sizeof(children3[0]) );
149 float values[][3] = {
150 { -1.0f, 2.3f, 2.5f }, { 0.3f, 2.4f, 3.8f }, { -1.1f, -0.3f, 0.0f },
151 { -0.3f, 3.2f, 3.3f }, { 1.0f, 1.1f, 1.1f }, { 0.5f, 0.5f, 0.5f },
152 { 0.0f, 0.0f, 0.0f }, { -2.0f, -1.8f, -1.0f }, { 0.0f, 2.3f, 2.4f },
153 { 0.4f, 1.2f, 2.0f }, { -1.0f, 2.3f, 2.5f }, { 0.3f, 2.4f, 3.8f },
154 { -1.1f, -0.3f, 0.0f }, { -0.3f, 3.2f, 3.3f }, { 1.0f, 1.1f, 1.1f },
155 { 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f, 0.0f }, { -2.0f, -1.8f, -1.0f },
156 { 0.0f, 2.3f, 2.4f }, { 0.4f, 1.2f, 2.0f }, { -1.0f, 2.3f, 2.5f },
157 { 0.3f, 2.4f, 3.8f }, { -1.1f, -0.3f, 0.0f }, { -0.3f, 3.2f, 3.3f },
158 { 1.0f, 1.1f, 1.1f }, { 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f, 0.0f },
159 { -2.0f, -1.8f, -1.0f }, { 0.0f, 2.3f, 2.4f }, { 0.4f, 1.2f, 4.0f } };
161 // -> 30 calls of stats()
163 // -> 7 calls of stats[4]()
165 // -> 2 calls of stats[4][3]()
167 // -> 1 call of stats[4][3][2]
169 for (unsigned i (0); i < sizeof(values)/sizeof(values[0]); ++i)
170 stats(values[i][0], values[i][1], values[i][2]);
172 BOOST_CHECK_CLOSE( stats.min(), 0.4f, .001f );
173 BOOST_CHECK_CLOSE( stats.avg(), 1.2f, .001f );
174 BOOST_CHECK_CLOSE( stats.max(), 4.0f, .001f );
175 BOOST_CHECK_CLOSE( stats.dev(), 0.0f, .001f );
177 BOOST_CHECK_CLOSE( stats[4].min(), -2.0f, .001f );
178 BOOST_CHECK_CLOSE( stats[4].avg(), -0.05f, .001f );
179 BOOST_CHECK_CLOSE( stats[4].max(), 1.1f, .001f );
180 BOOST_CHECK_CLOSE( stats[4].dev(), 1.08282f, .001f );
182 BOOST_CHECK_CLOSE( stats[4][3].min(), -2.0f, .001f );
183 BOOST_CHECK_CLOSE( stats[4][3].avg(), 1.15f, .001f );
184 BOOST_CHECK_CLOSE( stats[4][3].max(), 3.8f, .001f );
186 CHECK_STATS( statslog.str(),
187 "level0 -1 2.3 2.5 0\n"
188 "level0 -0.35 2.35 3.15 0\n"
189 "level0 -0.4 1.05 1.9 0\n"
190 "level0 -0.7 1.45 1.65 0\n"
191 "level1 -1.1 1.9 3.8 1.31719\n"
192 "averaged1 -1.1 1.9 3.8 1.31719\n"
193 "level0 0.35 2.15 2.2 0\n"
194 "level0 0.75 0.8 0.8 0\n"
195 "level0 0.25 0.25 0.25 0\n"
196 "level0 -1 -0.9 -0.5 0\n"
197 "level1 -2 -0.05 1.1 1.08282\n"
198 "averaged1 -1.55 0.925 2.45 1.20001\n"
199 "level0 -1 0.25 0.7 0\n"
200 "level0 0.2 1.75 2.2 0\n"
201 "level0 -0.3 1.75 2.25 0\n"
202 "level0 -0.35 2.35 3.15 0\n"
203 "level1 -1 2.05 3.8 0.492442\n"
204 "averaged1 -1.36667 1.3 2.9 0.964152\n"
205 "level0 -0.4 1.05 1.9 0\n"
206 "level0 -0.7 1.45 1.65 0\n"
207 "level0 0.35 2.15 2.2 0\n"
208 "level0 0.75 0.8 0.8 0\n"
209 "level1 -1.1 1.125 3.3 1.29687\n"
210 "averaged1 -1.36667 1.04167 2.73333 0.957378\n"
211 "level0 0.25 0.25 0.25 0\n"
212 "level0 -1 -0.9 -0.5 0\n"
213 "level0 -1 0.25 0.7 0\n"
214 "level0 0.2 1.75 2.2 0\n"
215 "level1 -2 0.425 2.4 1.52049\n"
216 "averaged1 -1.36667 1.2 3.16667 1.10327\n"
217 "level0 -0.3 1.75 2.25 0\n"
218 "level0 -0.35 2.35 3.15 0\n"
219 "level0 -0.4 1.05 1.9 0\n"
220 "level0 -0.7 1.45 1.65 0\n"
221 "level1 -1.1 1.9 3.8 1.31719\n"
222 "averaged1 -1.4 1.15 3.16667 1.37818\n"
223 "level3 -2 1.225 3.8 1.45752\n"
224 "level0 0.35 2.15 2.2 0\n"
225 "level0 0.75 0.8 0.8 0\n"
226 "level0 0.25 0.25 0.25 0\n"
227 "level0 -1 -0.9 -0.5 0\n"
228 "level1 -2 -0.05 1.1 1.08282\n"
229 "averaged1 -1.7 0.758333 2.43333 1.30683\n"
230 "level0 -1 0.25 0.7 0\n"
231 "level0 0.2 1.75 3.2 0\n" );
234 stats(20, 10.f, 10.f, 10.f, 0.f);
235 stats(4, 0.f, 0.f, 0.f, 0.f);
237 CHECK_STATS( statslog.str(),
238 "level0 5.2 5.6 7 0\n"
239 "level0 10 10 10 0\n"
240 "level0 10 10 10 0\n"
241 "level0 10 10 10 0\n"
242 "level0 10 10 10 0\n"
243 "level0 10 10 10 0\n"
244 "level0 10 10 10 0\n"
245 "level0 10 10 10 0\n"
246 "level0 10 10 10 0\n"
247 "level0 10 10 10 0\n"
248 "level0 10 10 10 0\n"
249 "level0 10 10 10 0\n"
250 "level0 10 10 10 0\n"
251 "level0 10 10 10 0\n"
252 "level0 10 10 10 0\n"
253 "level0 10 10 10 0\n"
254 "level0 10 10 10 0\n"
255 "level0 10 10 10 0\n"
256 "level0 10 10 10 0\n"
257 "level0 10 10 10 0\n"
258 "level1 0 5.875 10 8.19554\n"
259 "averaged1 -1.03333 2.575 4.96667 3.53185\n"
260 "level1 10 10 10 0\n"
261 "averaged1 2.66667 5.275 7.03333 3.09279\n"
262 "level1 10 10 10 0\n"
263 "averaged1 6.66667 8.625 10 2.73185\n"
264 "level1 10 10 10 0\n"
265 "averaged1 10 10 10 0\n"
266 "level1 10 10 10 0\n"
267 "averaged1 10 10 10 0\n"
268 "level3 -2 7.6375 10 5.04759\n"
273 "level1 0 5 10 8.66025\n"
274 "averaged1 6.66667 8.33333 10 2.88675\n" );
278 ///////////////////////////////cc.e////////////////////////////////////////
285 // comment-column: 40
286 // c-file-style: "senf"
287 // indent-tabs-mode: nil
288 // ispell-local-dictionary: "american"
289 // compile-command: "scons -u test"