File indexing completed on 2025-10-16 08:04:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "ActsPlugins/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 using namespace ActsPlugins;
0047
0048 namespace ActsTests {
0049
0050 BOOST_AUTO_TEST_SUITE(FpeMonitoringSuite)
0051
0052 BOOST_AUTO_TEST_CASE(Invalid) {
0053 FpeMonitor mon;
0054 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0055 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0056 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0057
0058 invalid();
0059
0060 BOOST_CHECK(mon.result().encountered(FpeType::FLTINV));
0061 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0062 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0063 }
0064
0065 BOOST_AUTO_TEST_CASE(DivByZero) {
0066 FpeMonitor mon;
0067 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0068 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0069 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0070
0071 divbyzero();
0072
0073 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0074 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0075 BOOST_CHECK(mon.result().encountered(FpeType::FLTDIV));
0076 }
0077
0078 BOOST_AUTO_TEST_CASE(Overflow) {
0079 FpeMonitor mon;
0080 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0081 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0082 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0083
0084 overflow();
0085 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0086 BOOST_CHECK(mon.result().encountered(FpeType::FLTOVF));
0087 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0088 }
0089
0090 BOOST_AUTO_TEST_CASE(Combinations) {
0091 FpeMonitor mon;
0092 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0093 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0094 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0095
0096 invalid();
0097 BOOST_CHECK(mon.result().encountered(FpeType::FLTINV));
0098 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0099 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0100
0101 overflow();
0102 BOOST_CHECK(mon.result().encountered(FpeType::FLTINV));
0103 BOOST_CHECK(mon.result().encountered(FpeType::FLTOVF));
0104 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0105
0106 divbyzero();
0107
0108 BOOST_CHECK(mon.result().encountered(FpeType::FLTINV));
0109 BOOST_CHECK(mon.result().encountered(FpeType::FLTOVF));
0110 BOOST_CHECK(mon.result().encountered(FpeType::FLTDIV));
0111 }
0112
0113 BOOST_AUTO_TEST_CASE(ClearOnEnter) {
0114 invalid();
0115 divbyzero();
0116 overflow();
0117
0118 FpeMonitor mon;
0119 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0120 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0121 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0122 }
0123
0124 BOOST_AUTO_TEST_CASE(CheckRearmCount) {
0125 FpeMonitor mon;
0126 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 0);
0127 BOOST_CHECK(mon.result().stackTraces().empty());
0128
0129 invalid();
0130 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 1);
0131 BOOST_CHECK_EQUAL(mon.result().stackTraces().size(), 1);
0132
0133 invalid();
0134
0135 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 1);
0136 BOOST_CHECK_EQUAL(mon.result().stackTraces().size(), 1);
0137
0138 mon.rearm();
0139 invalid();
0140 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 2);
0141 BOOST_CHECK_EQUAL(mon.result().stackTraces().size(),
0142 1);
0143
0144 mon.rearm();
0145 invalid2();
0146 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 3);
0147 BOOST_CHECK_EQUAL(mon.result().stackTraces().size(), 2);
0148 mon.result().deduplicate();
0149 BOOST_CHECK_EQUAL(mon.result().stackTraces().size(), 2);
0150 }
0151
0152 BOOST_AUTO_TEST_CASE(Scoping) {
0153 FpeMonitor mon;
0154 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0155 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0156 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0157
0158 invalid();
0159
0160 {
0161 FpeMonitor mon2;
0162 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTINV));
0163 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTOVF));
0164 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTDIV));
0165
0166 overflow();
0167
0168 {
0169 FpeMonitor mon3;
0170 BOOST_CHECK(!mon3.result().encountered(FpeType::FLTINV));
0171 BOOST_CHECK(!mon3.result().encountered(FpeType::FLTOVF));
0172 BOOST_CHECK(!mon3.result().encountered(FpeType::FLTDIV));
0173
0174 divbyzero();
0175
0176 BOOST_CHECK(!mon3.result().encountered(FpeType::FLTINV));
0177 BOOST_CHECK(!mon3.result().encountered(FpeType::FLTOVF));
0178 BOOST_CHECK(mon3.result().encountered(FpeType::FLTDIV));
0179
0180
0181 auto merged = mon.result().merged(mon2.result());
0182 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 1);
0183 BOOST_CHECK_EQUAL(mon2.result().count(FpeType::FLTOVF), 1);
0184 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTINV), 1);
0185 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTOVF), 1);
0186 BOOST_CHECK_EQUAL(merged.numStackTraces(), 2);
0187 merged = merged.merged(mon3.result());
0188 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTINV), 1);
0189 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTOVF), 1);
0190 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTDIV), 1);
0191 BOOST_CHECK_EQUAL(merged.numStackTraces(), 3);
0192 }
0193
0194 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTINV));
0195 BOOST_CHECK(mon2.result().encountered(FpeType::FLTOVF));
0196 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTDIV));
0197 }
0198
0199 BOOST_CHECK(mon.result().encountered(FpeType::FLTINV));
0200 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0201 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0202 }
0203
0204 BOOST_AUTO_TEST_CASE(MergeDeduplication) {
0205 FpeMonitor mon;
0206 invalid();
0207 {
0208 FpeMonitor mon2;
0209 invalid();
0210
0211 auto merged = mon.result().merged(mon2.result());
0212 BOOST_CHECK_EQUAL(merged.count(FpeType::FLTINV), 2);
0213 BOOST_CHECK_EQUAL(merged.stackTraces().size(), 1);
0214 }
0215 }
0216
0217 BOOST_AUTO_TEST_CASE(ScopedSuppression) {
0218 FpeMonitor mon;
0219 BOOST_CHECK(!mon.result().encountered(FpeType::FLTINV));
0220 BOOST_CHECK(!mon.result().encountered(FpeType::FLTOVF));
0221 BOOST_CHECK(!mon.result().encountered(FpeType::FLTDIV));
0222
0223 invalid();
0224
0225 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 1);
0226 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTOVF), 0);
0227 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTDIV), 0);
0228
0229 {
0230 FpeMonitor mon2{0};
0231 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTINV));
0232 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTOVF));
0233 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTDIV));
0234 invalid();
0235 divbyzero();
0236 overflow();
0237
0238 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTINV));
0239 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTOVF));
0240 BOOST_CHECK(!mon2.result().encountered(FpeType::FLTDIV));
0241 }
0242
0243
0244 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 1);
0245 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTOVF), 0);
0246 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTDIV), 0);
0247
0248 invalid();
0249
0250
0251 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTINV), 2);
0252 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTOVF), 0);
0253 BOOST_CHECK_EQUAL(mon.result().count(FpeType::FLTDIV), 0);
0254 }
0255
0256 BOOST_AUTO_TEST_SUITE_END()
0257
0258 }