File indexing completed on 2024-09-11 04:33:00
0001 #include "catch.hpp"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include <cstdlib>
0004 #include <iomanip>
0005 #include <iostream>
0006 #include <memory>
0007 #include <string>
0008
0009 namespace {
0010 struct Thing {
0011 Thing() : x() {}
0012 explicit Thing(int xx) : x(xx) {}
0013 int x;
0014 };
0015
0016 std::ostream& operator<<(std::ostream& os, const Thing& t) {
0017 os << "Thing(" << t.x << ")";
0018 return os;
0019 }
0020
0021 constexpr char expected[] =
0022 "An exception of category 'InfiniteLoop' occurred.\n"
0023 "Exception Message:\n"
0024 "In func1\n"
0025 "This is just a test: \n"
0026 "double: 1.11111\n"
0027 "float: 2.22222\n"
0028 "uint: 75\n"
0029 "string: a string\n"
0030 "char*: a nonconst pointer\n"
0031 "char[]: a c-style array\n"
0032 "Thing: Thing(4)\n"
0033 "\n"
0034 "double: 1.111110e+00\n"
0035 "float: 2.22e+00\n"
0036 "char*: ..a nonconst pointer\n"
0037 "\n"
0038 "Gave up\n";
0039
0040 constexpr char expected_func4[] =
0041 "An exception of category 'DataCorrupt' occurred.\n"
0042 "Exception Message:\n"
0043 "This is just a test: \n"
0044 "double: 1.11111\n"
0045 "float: 2.22222\n"
0046 "uint: 75\n"
0047 "string: a string\n"
0048 "char*: a nonconst pointer\n"
0049 "char[]: a c-style array\n";
0050
0051 void func3() {
0052 double d = 1.11111;
0053 float f = 2.22222;
0054 unsigned int i = 75U;
0055 std::string s("a string");
0056 char* c1 = const_cast<char*>("a nonconst pointer");
0057 char c2[] = "a c-style array";
0058 Thing thing(4);
0059
0060
0061 cms::Exception e("DataCorrupt");
0062 e << "This is just a test: \n"
0063 << "double: " << d << "\n"
0064 << "float: " << f << "\n"
0065 << "uint: " << i << "\n"
0066 << "string: " << s << "\n"
0067 << "char*: " << c1 << "\n"
0068 << "char[]: " << c2 << "\n"
0069 << "Thing: " << thing << "\n"
0070 << std::endl
0071 << "double: " << std::scientific << d << "\n"
0072 << "float: " << std::setprecision(2) << f << "\n"
0073 << "char*: " << std::setfill('.') << std::setw(20) << c1 << std::setfill(' ') << "\n"
0074 << std::endl;
0075
0076 throw e;
0077 }
0078
0079 void func2() { func3(); }
0080
0081 void func1() {
0082 try {
0083 func2();
0084 } catch (cms::Exception& e) {
0085 cms::Exception toThrow("InfiniteLoop", "In func1", e);
0086 toThrow << "Gave up";
0087 throw toThrow;
0088 }
0089 }
0090
0091 void func4() {
0092 double d = 1.11111;
0093 float f = 2.22222;
0094 unsigned int i = 75U;
0095 std::string s("a string");
0096 char* c1 = const_cast<char*>("a nonconst pointer");
0097 char c2[] = "a c-style array";
0098 Thing thing(4);
0099
0100
0101 cms::Exception e("DataCorrupt");
0102 e.format(
0103 "This is just a test: \n"
0104 "double: {}\n"
0105 "float: {}\n"
0106 "uint: {}\n"
0107 "string: {}\n"
0108 "char*: {}\n"
0109 "char[]: {}\n",
0110 d,
0111 f,
0112 i,
0113 s,
0114 c1,
0115 c2);
0116
0117 throw e;
0118 }
0119
0120 }
0121
0122 TEST_CASE("Test cms::Exception", "[cms::Exception]") {
0123 SECTION("throw") { REQUIRE_THROWS_WITH(func1(), expected); }
0124 SECTION("throw with format") { REQUIRE_THROWS_WITH(func4(), expected_func4); }
0125 SECTION("returnCode") {
0126 cms::Exception e1("ABC");
0127 REQUIRE(e1.returnCode() == 8001);
0128 }
0129 SECTION("alreadyPrinted") {
0130 cms::Exception e1("ABC");
0131 REQUIRE(not e1.alreadyPrinted());
0132 e1.setAlreadyPrinted();
0133 REQUIRE(e1.alreadyPrinted());
0134 SECTION("copy constructor") {
0135 cms::Exception e("ABC");
0136 cms::Exception e2(e);
0137 REQUIRE(not e2.alreadyPrinted());
0138
0139 e.setAlreadyPrinted();
0140 cms::Exception e3(e);
0141 REQUIRE(e3.alreadyPrinted());
0142 }
0143 }
0144 SECTION("message banner") {
0145 cms::Exception e1("ABC");
0146 const std::string expected("An exception of category 'ABC' occurred.\n");
0147 REQUIRE(e1.explainSelf() == expected);
0148 }
0149 SECTION("consistent message") {
0150 cms::Exception e1("ABC");
0151 cms::Exception e1s("ABC");
0152 REQUIRE(e1.explainSelf() == e1s.explainSelf());
0153 }
0154
0155 SECTION("extend message") {
0156 cms::Exception e2("ABC", "foo");
0157 cms::Exception e2cs("ABC", std::string("foo"));
0158 cms::Exception e2sc(std::string("ABC"), "foo");
0159 cms::Exception e2ss(std::string("ABC"), std::string("foo"));
0160 e2 << "bar";
0161 e2cs << "bar";
0162 e2sc << "bar";
0163 e2ss << "bar";
0164 {
0165 const std::string expected(
0166 "An exception of category 'ABC' occurred.\n"
0167 "Exception Message:\n"
0168 "foo bar\n");
0169 REQUIRE(e2.explainSelf() == expected);
0170 }
0171 REQUIRE(e2.explainSelf() == e2cs.explainSelf());
0172 REQUIRE(e2.explainSelf() == e2sc.explainSelf());
0173 REQUIRE(e2.explainSelf() == e2ss.explainSelf());
0174
0175 SECTION("partial message ends with space") {
0176 cms::Exception e3("ABC", "foo ");
0177 e3 << "bar\n";
0178 const std::string expected(
0179 "An exception of category 'ABC' occurred.\n"
0180 "Exception Message:\n"
0181 "foo bar\n");
0182 REQUIRE(e3.explainSelf() == expected);
0183 }
0184 SECTION("partial message ends with new line") {
0185 cms::Exception e4("ABC", "foo\n");
0186 e4 << "bar";
0187 const std::string expected(
0188 "An exception of category 'ABC' occurred.\n"
0189 "Exception Message:\n"
0190 "foo\nbar\n");
0191 REQUIRE(e4.explainSelf() == expected);
0192 }
0193 }
0194 SECTION("addContext") {
0195 cms::Exception e2("ABC", "foo bar");
0196
0197 e2.addContext("context1");
0198 e2.addContext(std::string("context2"));
0199 e2.addAdditionalInfo("info1");
0200 e2.addAdditionalInfo(std::string("info2"));
0201
0202 const std::string expected(
0203 "An exception of category 'ABC' occurred while\n"
0204 " [0] context2\n"
0205 " [1] context1\n"
0206 "Exception Message:\n"
0207 "foo bar \n"
0208 " Additional Info:\n"
0209 " [a] info2\n"
0210 " [b] info1\n");
0211 REQUIRE(e2.explainSelf() == expected);
0212 SECTION("constructor message from other exception") {
0213 cms::Exception e6("DEF", "start", e2);
0214 e6 << "finish";
0215 std::string expected5(
0216 "An exception of category 'DEF' occurred while\n"
0217 " [0] context2\n"
0218 " [1] context1\n"
0219 "Exception Message:\n"
0220 "start\n"
0221 "foo bar "
0222 "finish\n"
0223 " Additional Info:\n"
0224 " [a] info2\n"
0225 " [b] info1\n");
0226 REQUIRE(e6.explainSelf() == expected5);
0227 SECTION("copy constructor") {
0228 cms::Exception e7(e6);
0229 REQUIRE(e7.explainSelf() == expected5);
0230 REQUIRE(e7.category() == std::string("DEF"));
0231 REQUIRE(e7.message() == std::string("start\n"
0232 "foo bar "
0233 "finish"));
0234 }
0235 SECTION("clearContext") {
0236 e6.clearContext();
0237 std::string expected7_1(
0238 "An exception of category 'DEF' occurred.\n"
0239 "Exception Message:\n"
0240 "start\n"
0241 "foo bar "
0242 "finish\n"
0243 " Additional Info:\n"
0244 " [a] info2\n"
0245 " [b] info1\n");
0246 REQUIRE(e6.explainSelf() == expected7_1);
0247 }
0248 SECTION("setContext") {
0249 std::list<std::string> newContext;
0250 newContext.push_back("new1");
0251 newContext.push_back("new2");
0252 newContext.push_back("new3");
0253 e6.setContext(newContext);
0254 REQUIRE(e6.context() == newContext);
0255 }
0256 SECTION("clearAdditionalInfo") {
0257 e6.clearAdditionalInfo();
0258 std::string expected7_2(
0259 "An exception of category 'DEF' occurred while\n"
0260 " [0] context2\n"
0261 " [1] context1\n"
0262 "Exception Message:\n"
0263 "start\n"
0264 "foo bar "
0265 "finish\n");
0266 REQUIRE(e6.explainSelf() == expected7_2);
0267 }
0268 SECTION("setAdditionalInfo") {
0269 std::list<std::string> newAdditionalInfo;
0270 newAdditionalInfo.push_back("newInfo1");
0271 newAdditionalInfo.push_back("newInfo2");
0272 newAdditionalInfo.push_back("newInfo3");
0273 e6.setAdditionalInfo(newAdditionalInfo);
0274 REQUIRE(e6.additionalInfo() == newAdditionalInfo);
0275 std::string expected7_3(
0276 "An exception of category 'DEF' occurred while\n"
0277 " [0] context2\n"
0278 " [1] context1\n"
0279 "Exception Message:\n"
0280 "start\n"
0281 "foo bar "
0282 "finish\n"
0283 " Additional Info:\n"
0284 " [a] newInfo3\n"
0285 " [b] newInfo2\n"
0286 " [c] newInfo1\n");
0287 REQUIRE(e6.explainSelf() == expected7_3);
0288 }
0289 }
0290 }
0291
0292 cms::Exception e6("DEF", "start\nfoo barfinish");
0293 e6.setContext({{"new1", "new2", "new3"}});
0294 e6.setAdditionalInfo({"newInfo1", "newInfo2", "newInfo3"});
0295 SECTION("append") {
0296 e6.append(std::string(" X"));
0297 e6.append("Y");
0298 cms::Exception e8("ZZZ", "Z");
0299 e6.append(e8);
0300 std::string expected7_4(
0301 "An exception of category 'DEF' occurred while\n"
0302 " [0] new3\n"
0303 " [1] new2\n"
0304 " [2] new1\n"
0305 "Exception Message:\n"
0306 "start\n"
0307 "foo bar"
0308 "finish XYZ \n"
0309 " Additional Info:\n"
0310 " [a] newInfo3\n"
0311 " [b] newInfo2\n"
0312 " [c] newInfo1\n");
0313 REQUIRE(e6.explainSelf() == expected7_4);
0314 }
0315 SECTION("clearMessage") {
0316 e6.clearMessage();
0317 std::string expected7_5(
0318 "An exception of category 'DEF' occurred while\n"
0319 " [0] new3\n"
0320 " [1] new2\n"
0321 " [2] new1\n"
0322 " Additional Info:\n"
0323 " [a] newInfo3\n"
0324 " [b] newInfo2\n"
0325 " [c] newInfo1\n");
0326 REQUIRE(e6.explainSelf() == expected7_5);
0327 }
0328 SECTION("raise") {
0329 std::unique_ptr<cms::Exception> ptr(e6.clone());
0330 std::string expected7_6(
0331 "An exception of category 'DEF' occurred while\n"
0332 " [0] new3\n"
0333 " [1] new2\n"
0334 " [2] new1\n"
0335 "Exception Message:\n"
0336 "start\n"
0337 "foo bar"
0338 "finish \n"
0339 " Additional Info:\n"
0340 " [a] newInfo3\n"
0341 " [b] newInfo2\n"
0342 " [c] newInfo1\n");
0343 REQUIRE_THROWS_WITH(ptr->raise(), expected7_6);
0344 }
0345 }