File indexing completed on 2025-01-18 09:13:09
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Plugins/FpeMonitoring/FpeMonitor.hpp"
0012
0013 #include <cmath>
0014 #include <optional>
0015
0016 namespace {
0017
0018 __attribute__((noinline)) void divbyzero() {
0019 volatile float j = 0.0;
0020 volatile float r = 123 / j;
0021 (void)r;
0022 }
0023
0024 __attribute__((noinline)) void overflow() {
0025 std::cout << "PRE OVERFLOW" << std::endl;
0026 volatile float j = std::numeric_limits<float>::max();
0027 volatile float r = j * j;
0028 (void)r;
0029 std::cout << "POST OVERFLOW" << std::endl;
0030 }
0031
0032 __attribute__((noinline)) void invalid() {
0033 volatile float j = -1;
0034 volatile float r = std::sqrt(j);
0035 (void)r;
0036 }
0037
0038 __attribute__((noinline)) void invalid2() {
0039 volatile float k = 0;
0040 volatile float p = k / 0.0;
0041 (void)p;
0042 }
0043
0044 }
0045
0046 namespace Acts::Test {
0047
0048 BOOST_AUTO_TEST_SUITE(FpeMonitorTest)
0049
0050 BOOST_AUTO_TEST_CASE(Invalid) {
0051 FpeMonitor mon;
0052 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0053 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0054 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0055
0056 invalid();
0057
0058 BOOST_CHECK(mon.result().encountered(FpeType::FLTINV));
0059 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0060 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0061 }
0062
0063 BOOST_AUTO_TEST_CASE(DivByZero) {
0064 FpeMonitor mon;
0065 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0066 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0067 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0068
0069 divbyzero();
0070
0071 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0072 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0073 BOOST_CHECK(mon.result().encountered(FpeType::FLTDIV));
0074 }
0075
0076 BOOST_AUTO_TEST_CASE(Overflow) {
0077 FpeMonitor mon;
0078 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0079 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0080 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0081
0082 overflow();
0083 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0084 BOOST_CHECK(mon.result().encountered(FpeType::FLTOVF));
0085 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0086 }
0087
0088 BOOST_AUTO_TEST_CASE(Combinations) {
0089 FpeMonitor mon;
0090 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0091 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0092 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0093
0094 invalid();
0095 BOOST_CHECK(mon.result().encountered(FpeType::FLTINV));
0096 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0097 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0098
0099 overflow();
0100 BOOST_CHECK(mon.result().encountered(FpeType::FLTINV));
0101 BOOST_CHECK(mon.result().encountered(FpeType::FLTOVF));
0102 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0103
0104 divbyzero();
0105
0106 BOOST_CHECK(mon.result().encountered(FpeType::FLTINV));
0107 BOOST_CHECK(mon.result().encountered(FpeType::FLTOVF));
0108 BOOST_CHECK(mon.result().encountered(FpeType::FLTDIV));
0109 }
0110
0111 BOOST_AUTO_TEST_CASE(ClearOnEnter) {
0112 invalid();
0113 divbyzero();
0114 overflow();
0115
0116 FpeMonitor mon;
0117 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0118 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0119 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0120 }
0121
0122 BOOST_AUTO_TEST_CASE(CheckRearmCount) {
0123 FpeMonitor mon;
0124 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 0);
0125 BOOST_CHECK(mon.result().stackTraces().empty());
0126
0127 invalid();
0128 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 1);
0129 BOOST_CHECK_EQUAL(mon.result().stackTraces().size(), 1);
0130
0131 invalid();
0132
0133 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 1);
0134 BOOST_CHECK_EQUAL(mon.result().stackTraces().size(), 1);
0135
0136 mon.rearm();
0137 invalid();
0138 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 2);
0139 BOOST_CHECK_EQUAL(mon.result().stackTraces().size(),
0140 1);
0141
0142 mon.rearm();
0143 invalid2();
0144 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 3);
0145 BOOST_CHECK_EQUAL(mon.result().stackTraces().size(), 2);
0146 mon.result().deduplicate();
0147 BOOST_CHECK_EQUAL(mon.result().stackTraces().size(), 2);
0148 }
0149
0150 BOOST_AUTO_TEST_CASE(Scoping) {
0151 FpeMonitor mon;
0152 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0153 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0154 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0155
0156 invalid();
0157
0158 {
0159 FpeMonitor mon2;
0160 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTINV));
0161 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTOVF));
0162 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTDIV));
0163
0164 overflow();
0165
0166 {
0167 FpeMonitor mon3;
0168 BOOST_CHECK(!mon3.result().encountered(FpeType::FLTINV));
0169 BOOST_CHECK(!mon3.result().encountered(FpeType::FLTOVF));
0170 BOOST_CHECK(!mon3.result().encountered(FpeType::FLTDIV));
0171
0172 divbyzero();
0173
0174 BOOST_CHECK(!mon3.result().encountered(FpeType::FLTINV));
0175 BOOST_CHECK(!mon3.result().encountered(FpeType::FLTOVF));
0176 BOOST_CHECK(mon3.result().encountered(FpeType::FLTDIV));
0177
0178
0179 auto merged = mon.result().merged(mon2.result());
0180 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 1);
0181 BOOST_CHECK_EQUAL(mon2.result().count(FpeType::FLTOVF), 1);
0182 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTINV), 1);
0183 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTOVF), 1);
0184 BOOST_CHECK_EQUAL(merged.numStackTraces(), 2);
0185 merged = merged.merged(mon3.result());
0186 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTINV), 1);
0187 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTOVF), 1);
0188 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTDIV), 1);
0189 BOOST_CHECK_EQUAL(merged.numStackTraces(), 3);
0190 }
0191
0192 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTINV));
0193 BOOST_CHECK(mon2.result().encountered(FpeType::FLTOVF));
0194 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTDIV));
0195 }
0196
0197 BOOST_CHECK(mon.result().encountered(FpeType::FLTINV));
0198 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0199 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0200 }
0201
0202 BOOST_AUTO_TEST_CASE(MergeDeduplication) {
0203 FpeMonitor mon;
0204 invalid();
0205 {
0206 FpeMonitor mon2;
0207 invalid();
0208
0209 auto merged = mon.result().merged(mon2.result());
0210 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTINV), 2);
0211 BOOST_CHECK_EQUAL(merged.stackTraces().size(), 1);
0212 }
0213 }
0214
0215 BOOST_AUTO_TEST_CASE(ScopedSuppression) {
0216 FpeMonitor mon;
0217 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0218 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0219 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0220
0221 invalid();
0222
0223 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 1);
0224 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTOVF), 0);
0225 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTDIV), 0);
0226
0227 {
0228 FpeMonitor mon2{0};
0229 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTINV));
0230 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTOVF));
0231 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTDIV));
0232 invalid();
0233 divbyzero();
0234 overflow();
0235
0236 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTINV));
0237 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTOVF));
0238 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTDIV));
0239 }
0240
0241
0242 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 1);
0243 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTOVF), 0);
0244 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTDIV), 0);
0245
0246 invalid();
0247
0248
0249 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 2);
0250 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTOVF), 0);
0251 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTDIV), 0);
0252 }
0253
0254 BOOST_AUTO_TEST_SUITE_END()
0255
0256 }