PageRenderTime 188ms CodeModel.GetById 61ms app.highlight 85ms RepoModel.GetById 35ms app.codeStats 1ms

/indra/newview/tests/llsimplestat_test.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 580 lines | 400 code | 103 blank | 77 comment | 118 complexity | 61d79e18df3bc0bb77a2b327fbacbe31 MD5 | raw file
  1/** 
  2 * @file llsimplestats_test.cpp
  3 * @date 2010-10-22
  4 * @brief Test cases for some of llsimplestat.h
  5 *
  6 * $LicenseInfo:firstyear=2010&license=viewerlgpl$
  7 * Second Life Viewer Source Code
  8 * Copyright (C) 2010, Linden Research, Inc.
  9 * 
 10 * This library is free software; you can redistribute it and/or
 11 * modify it under the terms of the GNU Lesser General Public
 12 * License as published by the Free Software Foundation;
 13 * version 2.1 of the License only.
 14 * 
 15 * This library is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 18 * Lesser General Public License for more details.
 19 * 
 20 * You should have received a copy of the GNU Lesser General Public
 21 * License along with this library; if not, write to the Free Software
 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 23 * 
 24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 25 * $/LicenseInfo$
 26 */
 27
 28#include "linden_common.h"
 29
 30#include <tut/tut.hpp>
 31
 32#include "lltut.h"
 33#include "../llsimplestat.h"
 34#include "llsd.h"
 35#include "llmath.h"
 36
 37// @brief Used as a pointer cast type to get access to LLSimpleStatCounter
 38class TutStatCounter: public LLSimpleStatCounter
 39{
 40public:
 41	TutStatCounter();							// Not defined
 42	~TutStatCounter();							// Not defined
 43	void operator=(const TutStatCounter &);		// Not defined
 44	
 45	void setRawCount(U32 c)				{ mCount = c; }
 46	U32 getRawCount() const				{ return mCount; }
 47};
 48
 49
 50namespace tut
 51{
 52	struct stat_counter_index
 53	{};
 54	typedef test_group<stat_counter_index> stat_counter_index_t;
 55	typedef stat_counter_index_t::object stat_counter_index_object_t;
 56	tut::stat_counter_index_t tut_stat_counter_index("stat_counter_test");
 57
 58	// Testing LLSimpleStatCounter's external interface
 59	template<> template<>
 60	void stat_counter_index_object_t::test<1>()
 61	{
 62		LLSimpleStatCounter c1;
 63		ensure("Initialized counter is zero", (0 == c1.getCount()));
 64
 65		ensure("Counter increment return is 1", (1 == ++c1));
 66		ensure("Counter increment return is 2", (2 == ++c1));
 67
 68		ensure("Current counter is 2", (2 == c1.getCount()));
 69
 70		c1.reset();
 71		ensure("Counter is 0 after reset", (0 == c1.getCount()));
 72		
 73		ensure("Counter increment return is 1", (1 == ++c1));
 74	}
 75
 76	// Testing LLSimpleStatCounter's internal state
 77	template<> template<>
 78	void stat_counter_index_object_t::test<2>()
 79	{
 80		LLSimpleStatCounter c1;
 81		TutStatCounter * tc1 = (TutStatCounter *) &c1;
 82		
 83		ensure("Initialized private counter is zero", (0 == tc1->getRawCount()));
 84
 85		++c1;
 86		++c1;
 87		
 88		ensure("Current private counter is 2", (2 == tc1->getRawCount()));
 89
 90		c1.reset();
 91		ensure("Raw counter is 0 after reset", (0 == tc1->getRawCount()));
 92	}
 93
 94	// Testing LLSimpleStatCounter's wrapping behavior
 95	template<> template<>
 96	void stat_counter_index_object_t::test<3>()
 97	{
 98		LLSimpleStatCounter c1;
 99		TutStatCounter * tc1 = (TutStatCounter *) &c1;
100
101		tc1->setRawCount(U32_MAX);
102		ensure("Initialized private counter is zero", (U32_MAX == c1.getCount()));
103
104		ensure("Increment of max value wraps to 0", (0 == ++c1));
105	}
106
107	// Testing LLSimpleStatMMM's external behavior
108	template<> template<>
109	void stat_counter_index_object_t::test<4>()
110	{
111		LLSimpleStatMMM<> m1;
112		typedef LLSimpleStatMMM<>::Value lcl_float;
113		lcl_float zero(0);
114
115		// Freshly-constructed
116		ensure("Constructed MMM<> has 0 count", (0 == m1.getCount()));
117		ensure("Constructed MMM<> has 0 min", (zero == m1.getMin()));
118		ensure("Constructed MMM<> has 0 max", (zero == m1.getMax()));
119		ensure("Constructed MMM<> has 0 mean no div-by-zero", (zero == m1.getMean()));
120
121		// Single insert
122		m1.record(1.0);
123		ensure("Single insert MMM<> has 1 count", (1 == m1.getCount()));
124		ensure("Single insert MMM<> has 1.0 min", (1.0 == m1.getMin()));
125		ensure("Single insert MMM<> has 1.0 max", (1.0 == m1.getMax()));
126		ensure("Single insert MMM<> has 1.0 mean", (1.0 == m1.getMean()));
127		
128		// Second insert
129		m1.record(3.0);
130		ensure("2nd insert MMM<> has 2 count", (2 == m1.getCount()));
131		ensure("2nd insert MMM<> has 1.0 min", (1.0 == m1.getMin()));
132		ensure("2nd insert MMM<> has 3.0 max", (3.0 == m1.getMax()));
133		ensure_approximately_equals("2nd insert MMM<> has 2.0 mean", m1.getMean(), lcl_float(2.0), 1);
134
135		// Third insert
136		m1.record(5.0);
137		ensure("3rd insert MMM<> has 3 count", (3 == m1.getCount()));
138		ensure("3rd insert MMM<> has 1.0 min", (1.0 == m1.getMin()));
139		ensure("3rd insert MMM<> has 5.0 max", (5.0 == m1.getMax()));
140		ensure_approximately_equals("3rd insert MMM<> has 3.0 mean", m1.getMean(), lcl_float(3.0), 1);
141
142		// Fourth insert
143		m1.record(1000000.0);
144		ensure("4th insert MMM<> has 4 count", (4 == m1.getCount()));
145		ensure("4th insert MMM<> has 1.0 min", (1.0 == m1.getMin()));
146		ensure("4th insert MMM<> has 100000.0 max", (1000000.0 == m1.getMax()));
147		ensure_approximately_equals("4th insert MMM<> has 250002.0 mean", m1.getMean(), lcl_float(250002.0), 1);
148
149		// Reset
150		m1.reset();
151		ensure("Reset MMM<> has 0 count", (0 == m1.getCount()));
152		ensure("Reset MMM<> has 0 min", (zero == m1.getMin()));
153		ensure("Reset MMM<> has 0 max", (zero == m1.getMax()));
154		ensure("Reset MMM<> has 0 mean no div-by-zero", (zero == m1.getMean()));
155	}
156
157	// Testing LLSimpleStatMMM's response to large values
158	template<> template<>
159	void stat_counter_index_object_t::test<5>()
160	{
161		LLSimpleStatMMM<> m1;
162		typedef LLSimpleStatMMM<>::Value lcl_float;
163		lcl_float zero(0);
164
165		// Insert overflowing values
166		const lcl_float bignum(F32_MAX / 2);
167
168		m1.record(bignum);
169		m1.record(bignum);
170		m1.record(bignum);
171		m1.record(bignum);
172		m1.record(bignum);
173		m1.record(bignum);
174		m1.record(bignum);
175		m1.record(zero);
176
177		ensure("Overflowed MMM<> has 8 count", (8 == m1.getCount()));
178		ensure("Overflowed MMM<> has 0 min", (zero == m1.getMin()));
179		ensure("Overflowed MMM<> has huge max", (bignum == m1.getMax()));
180		ensure("Overflowed MMM<> has fetchable mean", (1.0 == m1.getMean() || true));
181		// We should be infinte but not interested in proving the IEEE standard here.
182		LLSD sd1(m1.getMean());
183		// std::cout << "Thingy:  " << m1.getMean() << " and as LLSD:  " << sd1 << std::endl;
184		ensure("Overflowed MMM<> produces LLSDable Real", (sd1.isReal()));
185	}
186
187	// Testing LLSimpleStatMMM<F32>'s external behavior
188	template<> template<>
189	void stat_counter_index_object_t::test<6>()
190	{
191		LLSimpleStatMMM<F32> m1;
192		typedef LLSimpleStatMMM<F32>::Value lcl_float;
193		lcl_float zero(0);
194
195		// Freshly-constructed
196		ensure("Constructed MMM<F32> has 0 count", (0 == m1.getCount()));
197		ensure("Constructed MMM<F32> has 0 min", (zero == m1.getMin()));
198		ensure("Constructed MMM<F32> has 0 max", (zero == m1.getMax()));
199		ensure("Constructed MMM<F32> has 0 mean no div-by-zero", (zero == m1.getMean()));
200
201		// Single insert
202		m1.record(1.0);
203		ensure("Single insert MMM<F32> has 1 count", (1 == m1.getCount()));
204		ensure("Single insert MMM<F32> has 1.0 min", (1.0 == m1.getMin()));
205		ensure("Single insert MMM<F32> has 1.0 max", (1.0 == m1.getMax()));
206		ensure("Single insert MMM<F32> has 1.0 mean", (1.0 == m1.getMean()));
207		
208		// Second insert
209		m1.record(3.0);
210		ensure("2nd insert MMM<F32> has 2 count", (2 == m1.getCount()));
211		ensure("2nd insert MMM<F32> has 1.0 min", (1.0 == m1.getMin()));
212		ensure("2nd insert MMM<F32> has 3.0 max", (3.0 == m1.getMax()));
213		ensure_approximately_equals("2nd insert MMM<F32> has 2.0 mean", m1.getMean(), lcl_float(2.0), 1);
214
215		// Third insert
216		m1.record(5.0);
217		ensure("3rd insert MMM<F32> has 3 count", (3 == m1.getCount()));
218		ensure("3rd insert MMM<F32> has 1.0 min", (1.0 == m1.getMin()));
219		ensure("3rd insert MMM<F32> has 5.0 max", (5.0 == m1.getMax()));
220		ensure_approximately_equals("3rd insert MMM<F32> has 3.0 mean", m1.getMean(), lcl_float(3.0), 1);
221
222		// Fourth insert
223		m1.record(1000000.0);
224		ensure("4th insert MMM<F32> has 4 count", (4 == m1.getCount()));
225		ensure("4th insert MMM<F32> has 1.0 min", (1.0 == m1.getMin()));
226		ensure("4th insert MMM<F32> has 1000000.0 max", (1000000.0 == m1.getMax()));
227		ensure_approximately_equals("4th insert MMM<F32> has 250002.0 mean", m1.getMean(), lcl_float(250002.0), 1);
228
229		// Reset
230		m1.reset();
231		ensure("Reset MMM<F32> has 0 count", (0 == m1.getCount()));
232		ensure("Reset MMM<F32> has 0 min", (zero == m1.getMin()));
233		ensure("Reset MMM<F32> has 0 max", (zero == m1.getMax()));
234		ensure("Reset MMM<F32> has 0 mean no div-by-zero", (zero == m1.getMean()));
235	}
236
237	// Testing LLSimpleStatMMM's response to large values
238	template<> template<>
239	void stat_counter_index_object_t::test<7>()
240	{
241		LLSimpleStatMMM<F32> m1;
242		typedef LLSimpleStatMMM<F32>::Value lcl_float;
243		lcl_float zero(0);
244
245		// Insert overflowing values
246		const lcl_float bignum(F32_MAX / 2);
247
248		m1.record(bignum);
249		m1.record(bignum);
250		m1.record(bignum);
251		m1.record(bignum);
252		m1.record(bignum);
253		m1.record(bignum);
254		m1.record(bignum);
255		m1.record(zero);
256
257		ensure("Overflowed MMM<F32> has 8 count", (8 == m1.getCount()));
258		ensure("Overflowed MMM<F32> has 0 min", (zero == m1.getMin()));
259		ensure("Overflowed MMM<F32> has huge max", (bignum == m1.getMax()));
260		ensure("Overflowed MMM<F32> has fetchable mean", (1.0 == m1.getMean() || true));
261		// We should be infinte but not interested in proving the IEEE standard here.
262		LLSD sd1(m1.getMean());
263		// std::cout << "Thingy:  " << m1.getMean() << " and as LLSD:  " << sd1 << std::endl;
264		ensure("Overflowed MMM<F32> produces LLSDable Real", (sd1.isReal()));
265	}
266
267	// Testing LLSimpleStatMMM<F64>'s external behavior
268	template<> template<>
269	void stat_counter_index_object_t::test<8>()
270	{
271		LLSimpleStatMMM<F64> m1;
272		typedef LLSimpleStatMMM<F64>::Value lcl_float;
273		lcl_float zero(0);
274
275		// Freshly-constructed
276		ensure("Constructed MMM<F64> has 0 count", (0 == m1.getCount()));
277		ensure("Constructed MMM<F64> has 0 min", (zero == m1.getMin()));
278		ensure("Constructed MMM<F64> has 0 max", (zero == m1.getMax()));
279		ensure("Constructed MMM<F64> has 0 mean no div-by-zero", (zero == m1.getMean()));
280
281		// Single insert
282		m1.record(1.0);
283		ensure("Single insert MMM<F64> has 1 count", (1 == m1.getCount()));
284		ensure("Single insert MMM<F64> has 1.0 min", (1.0 == m1.getMin()));
285		ensure("Single insert MMM<F64> has 1.0 max", (1.0 == m1.getMax()));
286		ensure("Single insert MMM<F64> has 1.0 mean", (1.0 == m1.getMean()));
287		
288		// Second insert
289		m1.record(3.0);
290		ensure("2nd insert MMM<F64> has 2 count", (2 == m1.getCount()));
291		ensure("2nd insert MMM<F64> has 1.0 min", (1.0 == m1.getMin()));
292		ensure("2nd insert MMM<F64> has 3.0 max", (3.0 == m1.getMax()));
293		ensure_approximately_equals("2nd insert MMM<F64> has 2.0 mean", m1.getMean(), lcl_float(2.0), 1);
294
295		// Third insert
296		m1.record(5.0);
297		ensure("3rd insert MMM<F64> has 3 count", (3 == m1.getCount()));
298		ensure("3rd insert MMM<F64> has 1.0 min", (1.0 == m1.getMin()));
299		ensure("3rd insert MMM<F64> has 5.0 max", (5.0 == m1.getMax()));
300		ensure_approximately_equals("3rd insert MMM<F64> has 3.0 mean", m1.getMean(), lcl_float(3.0), 1);
301
302		// Fourth insert
303		m1.record(1000000.0);
304		ensure("4th insert MMM<F64> has 4 count", (4 == m1.getCount()));
305		ensure("4th insert MMM<F64> has 1.0 min", (1.0 == m1.getMin()));
306		ensure("4th insert MMM<F64> has 1000000.0 max", (1000000.0 == m1.getMax()));
307		ensure_approximately_equals("4th insert MMM<F64> has 250002.0 mean", m1.getMean(), lcl_float(250002.0), 1);
308
309		// Reset
310		m1.reset();
311		ensure("Reset MMM<F64> has 0 count", (0 == m1.getCount()));
312		ensure("Reset MMM<F64> has 0 min", (zero == m1.getMin()));
313		ensure("Reset MMM<F64> has 0 max", (zero == m1.getMax()));
314		ensure("Reset MMM<F64> has 0 mean no div-by-zero", (zero == m1.getMean()));
315	}
316
317	// Testing LLSimpleStatMMM's response to large values
318	template<> template<>
319	void stat_counter_index_object_t::test<9>()
320	{
321		LLSimpleStatMMM<F64> m1;
322		typedef LLSimpleStatMMM<F64>::Value lcl_float;
323		lcl_float zero(0);
324
325		// Insert overflowing values
326		const lcl_float bignum(F64_MAX / 2);
327
328		m1.record(bignum);
329		m1.record(bignum);
330		m1.record(bignum);
331		m1.record(bignum);
332		m1.record(bignum);
333		m1.record(bignum);
334		m1.record(bignum);
335		m1.record(zero);
336
337		ensure("Overflowed MMM<F64> has 8 count", (8 == m1.getCount()));
338		ensure("Overflowed MMM<F64> has 0 min", (zero == m1.getMin()));
339		ensure("Overflowed MMM<F64> has huge max", (bignum == m1.getMax()));
340		ensure("Overflowed MMM<F64> has fetchable mean", (1.0 == m1.getMean() || true));
341		// We should be infinte but not interested in proving the IEEE standard here.
342		LLSD sd1(m1.getMean());
343		// std::cout << "Thingy:  " << m1.getMean() << " and as LLSD:  " << sd1 << std::endl;
344		ensure("Overflowed MMM<F64> produces LLSDable Real", (sd1.isReal()));
345	}
346
347	// Testing LLSimpleStatMMM<U64>'s external behavior
348	template<> template<>
349	void stat_counter_index_object_t::test<10>()
350	{
351		LLSimpleStatMMM<U64> m1;
352		typedef LLSimpleStatMMM<U64>::Value lcl_int;
353		lcl_int zero(0);
354
355		// Freshly-constructed
356		ensure("Constructed MMM<U64> has 0 count", (0 == m1.getCount()));
357		ensure("Constructed MMM<U64> has 0 min", (zero == m1.getMin()));
358		ensure("Constructed MMM<U64> has 0 max", (zero == m1.getMax()));
359		ensure("Constructed MMM<U64> has 0 mean no div-by-zero", (zero == m1.getMean()));
360
361		// Single insert
362		m1.record(1);
363		ensure("Single insert MMM<U64> has 1 count", (1 == m1.getCount()));
364		ensure("Single insert MMM<U64> has 1 min", (1 == m1.getMin()));
365		ensure("Single insert MMM<U64> has 1 max", (1 == m1.getMax()));
366		ensure("Single insert MMM<U64> has 1 mean", (1 == m1.getMean()));
367		
368		// Second insert
369		m1.record(3);
370		ensure("2nd insert MMM<U64> has 2 count", (2 == m1.getCount()));
371		ensure("2nd insert MMM<U64> has 1 min", (1 == m1.getMin()));
372		ensure("2nd insert MMM<U64> has 3 max", (3 == m1.getMax()));
373		ensure("2nd insert MMM<U64> has 2 mean", (2 == m1.getMean()));
374
375		// Third insert
376		m1.record(5);
377		ensure("3rd insert MMM<U64> has 3 count", (3 == m1.getCount()));
378		ensure("3rd insert MMM<U64> has 1 min", (1 == m1.getMin()));
379		ensure("3rd insert MMM<U64> has 5 max", (5 == m1.getMax()));
380		ensure("3rd insert MMM<U64> has 3 mean", (3 == m1.getMean()));
381
382		// Fourth insert
383		m1.record(U64L(1000000000000));
384		ensure("4th insert MMM<U64> has 4 count", (4 == m1.getCount()));
385		ensure("4th insert MMM<U64> has 1 min", (1 == m1.getMin()));
386		ensure("4th insert MMM<U64> has 1000000000000ULL max", (U64L(1000000000000) == m1.getMax()));
387		ensure("4th insert MMM<U64> has 250000000002ULL mean", (U64L( 250000000002) == m1.getMean()));
388
389		// Reset
390		m1.reset();
391		ensure("Reset MMM<U64> has 0 count", (0 == m1.getCount()));
392		ensure("Reset MMM<U64> has 0 min", (zero == m1.getMin()));
393		ensure("Reset MMM<U64> has 0 max", (zero == m1.getMax()));
394		ensure("Reset MMM<U64> has 0 mean no div-by-zero", (zero == m1.getMean()));
395	}
396
397	// Testing LLSimpleStatMMM's response to large values
398	template<> template<>
399	void stat_counter_index_object_t::test<11>()
400	{
401		LLSimpleStatMMM<U64> m1;
402		typedef LLSimpleStatMMM<U64>::Value lcl_int;
403		lcl_int zero(0);
404
405		// Insert overflowing values
406		const lcl_int bignum(U64L(0xffffffffffffffff) / 2);
407
408		m1.record(bignum);
409		m1.record(bignum);
410		m1.record(bignum);
411		m1.record(bignum);
412		m1.record(bignum);
413		m1.record(bignum);
414		m1.record(bignum);
415		m1.record(zero);
416
417		ensure("Overflowed MMM<U64> has 8 count", (8 == m1.getCount()));
418		ensure("Overflowed MMM<U64> has 0 min", (zero == m1.getMin()));
419		ensure("Overflowed MMM<U64> has huge max", (bignum == m1.getMax()));
420		ensure("Overflowed MMM<U64> has fetchable mean", (zero == m1.getMean() || true));
421	}
422
423    // Testing LLSimpleStatCounter's merge() method
424	template<> template<>
425	void stat_counter_index_object_t::test<12>()
426	{
427		LLSimpleStatCounter c1;
428		LLSimpleStatCounter c2;
429
430		++c1;
431		++c1;
432		++c1;
433		++c1;
434
435		++c2;
436		++c2;
437		c2.merge(c1);
438		
439		ensure_equals("4 merged into 2 results in 6", 6, c2.getCount());
440
441		ensure_equals("Source of merge is undamaged", 4, c1.getCount());
442	}
443
444    // Testing LLSimpleStatMMM's merge() method
445	template<> template<>
446	void stat_counter_index_object_t::test<13>()
447	{
448		LLSimpleStatMMM<> m1;
449		LLSimpleStatMMM<> m2;
450
451		m1.record(3.5);
452		m1.record(4.5);
453		m1.record(5.5);
454		m1.record(6.5);
455
456		m2.record(5.0);
457		m2.record(7.0);
458		m2.record(9.0);
459		
460		m2.merge(m1);
461
462		ensure_equals("Count after merge (p1)", 7, m2.getCount());
463		ensure_approximately_equals("Min after merge (p1)", F32(3.5), m2.getMin(), 22);
464		ensure_approximately_equals("Max after merge (p1)", F32(9.0), m2.getMax(), 22);
465		ensure_approximately_equals("Mean after merge (p1)", F32(41.000/7.000), m2.getMean(), 22);
466		
467
468		ensure_equals("Source count of merge is undamaged (p1)", 4, m1.getCount());
469		ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(3.5), m1.getMin(), 22);
470		ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(6.5), m1.getMax(), 22);
471		ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(5.0), m1.getMean(), 22);
472
473		m2.reset();
474
475		m2.record(-22.0);
476		m2.record(-1.0);
477		m2.record(30.0);
478		
479		m2.merge(m1);
480
481		ensure_equals("Count after merge (p2)", 7, m2.getCount());
482		ensure_approximately_equals("Min after merge (p2)", F32(-22.0), m2.getMin(), 22);
483		ensure_approximately_equals("Max after merge (p2)", F32(30.0), m2.getMax(), 22);
484		ensure_approximately_equals("Mean after merge (p2)", F32(27.000/7.000), m2.getMean(), 22);
485
486	}
487
488    // Testing LLSimpleStatMMM's merge() method when src contributes nothing
489	template<> template<>
490	void stat_counter_index_object_t::test<14>()
491	{
492		LLSimpleStatMMM<> m1;
493		LLSimpleStatMMM<> m2;
494
495		m2.record(5.0);
496		m2.record(7.0);
497		m2.record(9.0);
498		
499		m2.merge(m1);
500
501		ensure_equals("Count after merge (p1)", 3, m2.getCount());
502		ensure_approximately_equals("Min after merge (p1)", F32(5.0), m2.getMin(), 22);
503		ensure_approximately_equals("Max after merge (p1)", F32(9.0), m2.getMax(), 22);
504		ensure_approximately_equals("Mean after merge (p1)", F32(7.000), m2.getMean(), 22);
505
506		ensure_equals("Source count of merge is undamaged (p1)", 0, m1.getCount());
507		ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(0), m1.getMin(), 22);
508		ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(0), m1.getMax(), 22);
509		ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(0), m1.getMean(), 22);
510
511		m2.reset();
512
513		m2.record(-22.0);
514		m2.record(-1.0);
515		
516		m2.merge(m1);
517
518		ensure_equals("Count after merge (p2)", 2, m2.getCount());
519		ensure_approximately_equals("Min after merge (p2)", F32(-22.0), m2.getMin(), 22);
520		ensure_approximately_equals("Max after merge (p2)", F32(-1.0), m2.getMax(), 22);
521		ensure_approximately_equals("Mean after merge (p2)", F32(-11.5), m2.getMean(), 22);
522	}
523
524    // Testing LLSimpleStatMMM's merge() method when dst contributes nothing
525	template<> template<>
526	void stat_counter_index_object_t::test<15>()
527	{
528		LLSimpleStatMMM<> m1;
529		LLSimpleStatMMM<> m2;
530
531		m1.record(5.0);
532		m1.record(7.0);
533		m1.record(9.0);
534		
535		m2.merge(m1);
536
537		ensure_equals("Count after merge (p1)", 3, m2.getCount());
538		ensure_approximately_equals("Min after merge (p1)", F32(5.0), m2.getMin(), 22);
539		ensure_approximately_equals("Max after merge (p1)", F32(9.0), m2.getMax(), 22);
540		ensure_approximately_equals("Mean after merge (p1)", F32(7.000), m2.getMean(), 22);
541
542		ensure_equals("Source count of merge is undamaged (p1)", 3, m1.getCount());
543		ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(5.0), m1.getMin(), 22);
544		ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(9.0), m1.getMax(), 22);
545		ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(7.0), m1.getMean(), 22);
546
547		m1.reset();
548		m2.reset();
549		
550		m1.record(-22.0);
551		m1.record(-1.0);
552		
553		m2.merge(m1);
554
555		ensure_equals("Count after merge (p2)", 2, m2.getCount());
556		ensure_approximately_equals("Min after merge (p2)", F32(-22.0), m2.getMin(), 22);
557		ensure_approximately_equals("Max after merge (p2)", F32(-1.0), m2.getMax(), 22);
558		ensure_approximately_equals("Mean after merge (p2)", F32(-11.5), m2.getMean(), 22);
559	}
560
561    // Testing LLSimpleStatMMM's merge() method when neither dst nor src contributes
562	template<> template<>
563	void stat_counter_index_object_t::test<16>()
564	{
565		LLSimpleStatMMM<> m1;
566		LLSimpleStatMMM<> m2;
567
568		m2.merge(m1);
569
570		ensure_equals("Count after merge (p1)", 0, m2.getCount());
571		ensure_approximately_equals("Min after merge (p1)", F32(0), m2.getMin(), 22);
572		ensure_approximately_equals("Max after merge (p1)", F32(0), m2.getMax(), 22);
573		ensure_approximately_equals("Mean after merge (p1)", F32(0), m2.getMean(), 22);
574
575		ensure_equals("Source count of merge is undamaged (p1)", 0, m1.getCount());
576		ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(0), m1.getMin(), 22);
577		ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(0), m1.getMax(), 22);
578		ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(0), m1.getMean(), 22);
579	}
580}