testMath.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #include "squid.h"
10 #include "base/Optional.h"
11 #include "compat/cppunit.h"
12 #include "SquidMath.h"
13 #include "unitTestMain.h"
14 
15 class TestMath: public CPPUNIT_NS::TestFixture
16 {
20 
21 protected:
22  void testNaturalSum();
23 };
24 
26 
31 static const auto zero8s = int8_t(0);
32 static const auto zero8u = uint8_t(0);
33 static const auto zero64s = int64_t(0);
34 static const auto zero64u = uint64_t(0);
35 static const auto one8s = int8_t(1);
36 static const auto one8u = uint8_t(1);
37 static const auto one64s = int64_t(1);
38 static const auto one64u = uint64_t(1);
44 
47 
48 template <typename A>
49 static std::string
51 {
52  const std::string prefix = std::is_signed<A>::value ? "" : "u";
53  return prefix + "int" + std::to_string(sizeof(A)*8);
54 }
55 
56 template <typename A>
57 static std::string
59 {
60  return TypeToString<A>() + '(' + std::to_string(+a) + ')';
61 }
62 
63 template <typename S, typename A, typename B>
64 static std::string
65 SumToString(const A a, const B b)
66 {
67  return TypeToString<S>() + ": " + OperandToString(a) + " + " + OperandToString(b);
68 }
69 
70 template <typename S, typename A, typename B, typename C>
71 static std::string
72 SumToString(const A a, const B b, const C c)
73 {
74  return TypeToString<S>() + ": " + OperandToString(a) + " + " + OperandToString(b) + " + " + OperandToString(c);
75 }
76 
78 
80 template <typename S>
81 static S
83 {
84  return S(0);
85 }
86 
89 template <typename S, typename A, typename... Args>
90 static S
91 RawSum(A a, Args... args)
92 {
93  return S(a) + RawSum<S>(args...);
94 }
95 
98 template <typename S>
100 {
101 public:
102  template <typename... Args>
103  static S Test(Args... args)
104  {
105  // to show every non-overflowing sum to be tested:
106  //std::cout << SumToString<S>(args...) << " = " << +sum << "\n";
107 
108  const auto ns = NaturalSum<S>(args...);
109  CPPUNIT_ASSERT_MESSAGE(SumToString<S>(args...) + " does not overflow",
110  ns.has_value());
111 
112  const auto sum = ns.value();
113  const auto expected = RawSum<S>(args...);
114  CPPUNIT_ASSERT_MESSAGE(
115  SumToString<S>(args...) + " = " + OperandToString(expected) + " rather than " + OperandToString(sum),
116  sum == expected);
117 
118  return sum;
119  }
120 };
121 
124 template <typename S>
126 {
127 public:
128  template <typename... Args>
129  static void Test(Args... args)
130  {
131  // to show every overflowing sum to be tested:
132  //std::cout << SumToString<S>(args...) << " = overflow\n";
133 
134  CPPUNIT_ASSERT_MESSAGE(SumToString<S>(args...) + " must overflow",
135  !NaturalSum<S>(args...).has_value());
136  }
137 };
138 
140 template <typename S, template<typename> class Tester, typename A, typename B>
141 static void
142 TestWithZeros(const A a, const B b)
143 {
144  Tester<S>::Test(a, b);
145 
146  Tester<S>::Test(zero8u, a, b);
147  Tester<S>::Test(zero8s, a, b);
148  Tester<S>::Test(zero64u, a, b);
149  Tester<S>::Test(zero64s, a, b);
150  Tester<S>::Test(a, zero8u, b);
151  Tester<S>::Test(a, zero8s, b);
152  Tester<S>::Test(a, zero64u, b);
153  Tester<S>::Test(a, zero64s, b);
154  Tester<S>::Test(a, b, zero8u);
155  Tester<S>::Test(a, b, zero8s);
156  Tester<S>::Test(a, b, zero64u);
157  Tester<S>::Test(a, b, zero64s);
158 }
159 
161 template <typename S, template<typename> class Tester, typename A, typename B>
162 static void
163 TestOrder(const A a, const B b)
164 {
165  TestWithZeros<S, Tester>(a, b);
166  TestWithZeros<S, Tester>(b, a);
167 }
168 
170 template <typename A, typename B>
171 static void
173 {
174  TestOrder<A, OverflowSumTester>(a, b);
175  TestOrder<B, OverflowSumTester>(a, b);
176 }
177 
180 template <typename A, typename B>
181 static void
183 {
184  TestOrder<A, SuccessSumTester>(a, b);
185  TestOrder<B, OverflowSumTester>(a, b);
186 }
187 
189 template <typename A, typename... Args, typename S = A>
190 static S
191 GoodSum(const A a, Args... args)
192 {
193  return SuccessSumTester<S>::Test(a, args...);
194 }
195 
196 void
198 {
199  /*
200  * To simplify spelling out of these repetitive test cases, we let function
201  * parameters determine the summation type. Regular code should not do that,
202  * and our public summation APIs do not provide this dangerous shortcut.
203  */
204 
205  // negative parameters are banned in any position
220 
221  // these overflow regardless of which parameter determines the summation type
234 
235  // these overflow only if the second parameter determines the summation type
245 
246  // a few sums with known values
247  CPPUNIT_ASSERT_EQUAL(zero8s, GoodSum(zero8s, zero8u));
248  CPPUNIT_ASSERT_EQUAL(zero64s, GoodSum(zero64s, zero64u));
249  CPPUNIT_ASSERT_EQUAL(2, GoodSum(1, 1));
250  CPPUNIT_ASSERT_EQUAL(uint64_t(2), GoodSum(one64u, one64s));
251  CPPUNIT_ASSERT_EQUAL(6u, GoodSum(1u, 2, 3));
252  CPPUNIT_ASSERT_EQUAL(max64u, GoodSum(zero64u, max64u));
253  CPPUNIT_ASSERT_EQUAL(max64s, GoodSum(zero64s, max64s));
254  CPPUNIT_ASSERT_EQUAL(one64u + max64s, GoodSum(one64u, max64s));
255  CPPUNIT_ASSERT_EQUAL(max64u, GoodSum(max64u, zero8s));
256  CPPUNIT_ASSERT_EQUAL(max64s, GoodSum(max64s, zero8s));
257 
258  // long argument lists (odd and even lengths)
259  CPPUNIT_ASSERT_EQUAL(15, NaturalSum<int>(1, 2, 3, 4, 5).value());
260  CPPUNIT_ASSERT_EQUAL(21, NaturalSum<int>(1, 2, 3, 4, 5, 6).value());
261 
262  // test SetToNaturalSumOrMax() when the sum is too big for the variable
263  long expires = 0;
264  const auto result = SetToNaturalSumOrMax(expires, max64u, zero8u);
265  CPPUNIT_ASSERT_EQUAL(std::numeric_limits<long>::max(), expires);
266  CPPUNIT_ASSERT_EQUAL(expires, result);
267 }
268 
static std::string SumToString(const A a, const B b)
Definition: testMath.cc:65
static S RawSum()
ends argument recursion for RawSum() with parameters
Definition: testMath.cc:82
static const auto zero8s
Definition: testMath.cc:31
CPPUNIT_TEST_SUITE(TestMath)
static std::string OperandToString(const A a)
Definition: testMath.cc:58
static void TestOverflowForEitherSummationType(const A a, const B b)
checks that a+b and similar sums overflow for summation types A and B
Definition: testMath.cc:172
static const auto max64s
Definition: testMath.cc:41
A const & max(A const &lhs, A const &rhs)
static void TestOrder(const A a, const B b)
checks that the summation outcome is unaffected by the order of operands
Definition: testMath.cc:163
static void TestSuccessForFirstSummationType(const A a, const B b)
Definition: testMath.cc:182
static const auto one64s
Definition: testMath.cc:37
void testNaturalSum()
Definition: testMath.cc:197
static const auto max8u
Definition: testMath.cc:40
static void Test(Args... args)
Definition: testMath.cc:129
static const auto one8s
Definition: testMath.cc:35
static void TestWithZeros(const A a, const B b)
checks that the summation outcome is unaffected by (not) adding zeros
Definition: testMath.cc:142
static uint32 A
Definition: md4.c:43
static S Test(Args... args)
Definition: testMath.cc:103
CPPUNIT_TEST_SUITE_END()
S SetToNaturalSumOrMax(S &var, const Args... args)
Definition: SquidMath.h:182
static const auto zero64u
Definition: testMath.cc:34
static S GoodSum(const A a, Args... args)
Definition: testMath.cc:191
static uint32 C
Definition: md4.c:43
static const auto max8s
Definition: testMath.cc:39
static const auto max64u
Definition: testMath.cc:42
static const auto one64u
Definition: testMath.cc:38
CPPUNIT_TEST_SUITE_REGISTRATION(TestMath)
static const auto one8u
Definition: testMath.cc:36
static const auto min8s
Definition: testMath.cc:30
static const auto min64s
Definition: testMath.cc:29
static uint32 B
Definition: md4.c:43
static std::string TypeToString()
Definition: testMath.cc:50
A const & min(A const &lhs, A const &rhs)
static const auto zero8u
Definition: testMath.cc:32
CPPUNIT_TEST(testNaturalSum)
static const auto zero64s
Definition: testMath.cc:33

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors