4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief Statistics unit tests */
31 //#include "Statistics.test.hh"
32 //#include "Statistics.test.ih"
35 #include "Statistics.hh"
36 #include "StatisticsTargets.hh"
37 #include <boost/tokenizer.hpp>
38 #include <boost/iterator/transform_iterator.hpp>
39 #include <boost/iterator/filter_iterator.hpp>
41 #include "auto_unit_test.hh"
42 #include <boost/test/test_tools.hpp>
43 #include <boost/test/floating_point_comparison.hpp>
46 //-/////////////////////////////////////////////////////////////////////////////////////////////////
52 typedef senf::Collector const & first_argument_type;
53 typedef unsigned result_type;
54 result_type operator()(first_argument_type arg) const
55 { return arg.rank(); }
60 typedef boost::char_separator<char> Separator;
61 typedef boost::tokenizer<Separator> Tokenizer;
63 bool operator()(std::string const & s) const
64 { try { boost::lexical_cast<double>(s); return true; }
65 catch (std::bad_cast &) { return false; } }
67 typedef boost::filter_iterator<Pred,Tokenizer::iterator> FilterIterator;
69 typedef double result_type;
70 result_type operator()(std::string const & s) const
71 { return boost::lexical_cast<double>(s); }
73 typedef boost::transform_iterator<Trafo,FilterIterator> TransformIterator;
75 typedef TransformIterator iterator;
76 typedef TransformIterator const_iterator;
78 splitFloats(std::string const & s) : s_ (s), sep_ (" \n"), tok_ (s_, sep_) {}
79 TransformIterator begin() const
80 { return TransformIterator(FilterIterator(tok_.begin(), tok_.end())); }
81 TransformIterator end() const
82 { return TransformIterator(FilterIterator(tok_.end(), tok_.end())); }
89 template <class R1, class R2>
90 void CHECK_CLOSE_RANGES(R1 const & r1, R2 const & r2, double delta)
92 typedef typename boost::range_const_iterator<R1>::type I1;
93 typedef typename boost::range_const_iterator<R2>::type I2;
95 I1 i1 (boost::begin(r1));
96 I1 i1_end (boost::end(r1));
97 I2 i2 (boost::begin(r2));
98 I2 i2_end (boost::end(r2));
100 for (; i1 != i1_end && i2 != i2_end; ++i1, ++i2) {
101 BOOST_CHECK_CLOSE(*i1, *i2, delta);
104 BOOST_CHECK( i1 == i1_end );
105 BOOST_CHECK( i2 == i2_end );
109 #define CHECK_STATS(a, b) CHECK_CLOSE_RANGES(splitFloats(a),splitFloats(b),0.001f)
110 #define CHECK_STATS_STR(a,b) BOOST_CHECK_EQUAL(a,b)
112 SENF_AUTO_UNIT_TEST(statistics)
114 senf::Statistics stats;
115 senf::log::StringTarget statslog;
118 statslog.showTime(false);
119 statslog.showArea(false);
120 statslog.showLevel(false);
121 statslog.route<senf::StatisticsStream>();
125 senf::StatisticsLogger("level0"))
128 senf::StatisticsLogger("level1"))
130 senf::StatisticsLogger("averaged1"))
134 senf::StatisticsLogger("level3"));
136 unsigned children1[] = { 4u };
137 BOOST_CHECK_EQUAL_COLLECTIONS(
138 boost::make_transform_iterator(stats.collectors().begin(), GetRank()),
139 boost::make_transform_iterator(stats.collectors().end(), GetRank()),
140 children1, children1 + sizeof(children1)/sizeof(children1[0]) );
142 unsigned children2[] = { 3u };
143 BOOST_CHECK_EQUAL_COLLECTIONS(
144 boost::make_transform_iterator(stats[4].collectors().begin(), GetRank()),
145 boost::make_transform_iterator(stats[4].collectors().end(), GetRank()),
146 children2, children2 + sizeof(children2)/sizeof(children2[0]) );
148 unsigned children3[] = { 2u };
149 BOOST_CHECK_EQUAL_COLLECTIONS(
150 boost::make_transform_iterator(stats[4][3].collectors().begin(), GetRank()),
151 boost::make_transform_iterator(stats[4][3].collectors().end(), GetRank()),
152 children3, children3 + sizeof(children3)/sizeof(children3[0]) );
154 float values[][3] = {
155 { -1.0f, 2.3f, 2.5f }, { 0.3f, 2.4f, 3.8f }, { -1.1f, -0.3f, 0.0f },
156 { -0.3f, 3.2f, 3.3f }, { 1.0f, 1.1f, 1.1f }, { 0.5f, 0.5f, 0.5f },
157 { 0.0f, 0.0f, 0.0f }, { -2.0f, -1.8f, -1.0f }, { 0.0f, 2.3f, 2.4f },
158 { 0.4f, 1.2f, 2.0f }, { -1.0f, 2.3f, 2.5f }, { 0.3f, 2.4f, 3.8f },
159 { -1.1f, -0.3f, 0.0f }, { -0.3f, 3.2f, 3.3f }, { 1.0f, 1.1f, 1.1f },
160 { 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f, 0.0f }, { -2.0f, -1.8f, -1.0f },
161 { 0.0f, 2.3f, 2.4f }, { 0.4f, 1.2f, 2.0f }, { -1.0f, 2.3f, 2.5f },
162 { 0.3f, 2.4f, 3.8f }, { -1.1f, -0.3f, 0.0f }, { -0.3f, 3.2f, 3.3f },
163 { 1.0f, 1.1f, 1.1f }, { 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f, 0.0f },
164 { -2.0f, -1.8f, -1.0f }, { 0.0f, 2.3f, 2.4f }, { 0.4f, 1.2f, 4.0f } };
166 // -> 30 calls of stats()
168 // -> 7 calls of stats[4]()
170 // -> 2 calls of stats[4][3]()
172 // -> 1 call of stats[4][3][2]
174 for (unsigned i (0); i < sizeof(values)/sizeof(values[0]); ++i)
175 stats(values[i][0], values[i][1], values[i][2]);
177 BOOST_CHECK_CLOSE( stats.min(), 0.4f, .001f );
178 BOOST_CHECK_CLOSE( stats.avg(), 1.2f, .001f );
179 BOOST_CHECK_CLOSE( stats.max(), 4.0f, .001f );
180 BOOST_CHECK_CLOSE( stats.dev(), 0.0f, .001f );
182 BOOST_CHECK_CLOSE( stats[4].min(), -2.0f, .001f );
183 BOOST_CHECK_CLOSE( stats[4].avg(), -0.05f, .001f );
184 BOOST_CHECK_CLOSE( stats[4].max(), 1.1f, .001f );
185 BOOST_CHECK_CLOSE( stats[4].dev(), 1.08282f, .001f );
187 BOOST_CHECK_CLOSE( stats[4][3].min(), -2.0f, .001f );
188 BOOST_CHECK_CLOSE( stats[4][3].avg(), 1.15f, .001f );
189 BOOST_CHECK_CLOSE( stats[4][3].max(), 3.8f, .001f );
191 CHECK_STATS( statslog.str(),
192 "level0 -1 2.3 2.5 0\n"
193 "level0 -0.35 2.35 3.15 0\n"
194 "level0 -0.4 1.05 1.9 0\n"
195 "level0 -0.7 1.45 1.65 0\n"
196 "level1 -1.1 1.9 3.8 1.31719\n"
197 "averaged1 -1.1 1.9 3.8 1.31719\n"
198 "level0 0.35 2.15 2.2 0\n"
199 "level0 0.75 0.8 0.8 0\n"
200 "level0 0.25 0.25 0.25 0\n"
201 "level0 -1 -0.9 -0.5 0\n"
202 "level1 -2 -0.05 1.1 1.08282\n"
203 "averaged1 -1.55 0.925 2.45 1.20001\n"
204 "level0 -1 0.25 0.7 0\n"
205 "level0 0.2 1.75 2.2 0\n"
206 "level0 -0.3 1.75 2.25 0\n"
207 "level0 -0.35 2.35 3.15 0\n"
208 "level1 -1 2.05 3.8 0.492442\n"
209 "averaged1 -1.36667 1.3 2.9 0.964152\n"
210 "level0 -0.4 1.05 1.9 0\n"
211 "level0 -0.7 1.45 1.65 0\n"
212 "level0 0.35 2.15 2.2 0\n"
213 "level0 0.75 0.8 0.8 0\n"
214 "level1 -1.1 1.125 3.3 1.29687\n"
215 "averaged1 -1.36667 1.04167 2.73333 0.957378\n"
216 "level0 0.25 0.25 0.25 0\n"
217 "level0 -1 -0.9 -0.5 0\n"
218 "level0 -1 0.25 0.7 0\n"
219 "level0 0.2 1.75 2.2 0\n"
220 "level1 -2 0.425 2.4 1.52049\n"
221 "averaged1 -1.36667 1.2 3.16667 1.10327\n"
222 "level0 -0.3 1.75 2.25 0\n"
223 "level0 -0.35 2.35 3.15 0\n"
224 "level0 -0.4 1.05 1.9 0\n"
225 "level0 -0.7 1.45 1.65 0\n"
226 "level1 -1.1 1.9 3.8 1.31719\n"
227 "averaged1 -1.4 1.15 3.16667 1.37818\n"
228 "level3 -2 1.225 3.8 1.45752\n"
229 "level0 0.35 2.15 2.2 0\n"
230 "level0 0.75 0.8 0.8 0\n"
231 "level0 0.25 0.25 0.25 0\n"
232 "level0 -1 -0.9 -0.5 0\n"
233 "level1 -2 -0.05 1.1 1.08282\n"
234 "averaged1 -1.7 0.758333 2.43333 1.30683\n"
235 "level0 -1 0.25 0.7 0\n"
236 "level0 0.2 1.75 3.2 0\n" );
239 stats(20, 10.f, 10.f, 10.f, 0.f);
240 stats(4, 0.f, 0.f, 0.f, 0.f);
242 CHECK_STATS( statslog.str(),
243 "level0 5.2 5.6 7 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 "level0 10 10 10 0\n"
259 "level0 10 10 10 0\n"
260 "level0 10 10 10 0\n"
261 "level0 10 10 10 0\n"
262 "level0 10 10 10 0\n"
263 "level1 0 5.875 10 8.19554\n"
264 "averaged1 -1.03333 2.575 4.96667 3.53185\n"
265 "level1 10 10 10 0\n"
266 "averaged1 2.66667 5.275 7.03333 3.09279\n"
267 "level1 10 10 10 0\n"
268 "averaged1 6.66667 8.625 10 2.73185\n"
269 "level1 10 10 10 0\n"
270 "averaged1 10 10 10 0\n"
271 "level1 10 10 10 0\n"
272 "averaged1 10 10 10 0\n"
273 "level3 -2 7.6375 10 5.04759\n"
278 "level1 0 5 10 8.66025\n"
279 "averaged1 6.66667 8.33333 10 2.88675\n" );
283 //-/////////////////////////////////////////////////////////////////////////////////////////////////
290 // comment-column: 40
291 // c-file-style: "senf"
292 // indent-tabs-mode: nil
293 // ispell-local-dictionary: "american"
294 // compile-command: "scons -u test"