File indexing completed on 2024-04-06 12:13:15
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 void func3() {
0041 double d = 1.11111;
0042 float f = 2.22222;
0043 unsigned int i = 75U;
0044 std::string s("a string");
0045 char* c1 = const_cast<char*>("a nonconst pointer");
0046 char c2[] = "a c-style array";
0047 Thing thing(4);
0048
0049
0050 cms::Exception e("DataCorrupt");
0051 e << "This is just a test: \n"
0052 << "double: " << d << "\n"
0053 << "float: " << f << "\n"
0054 << "uint: " << i << "\n"
0055 << "string: " << s << "\n"
0056 << "char*: " << c1 << "\n"
0057 << "char[]: " << c2 << "\n"
0058 << "Thing: " << thing << "\n"
0059 << std::endl
0060 << "double: " << std::scientific << d << "\n"
0061 << "float: " << std::setprecision(2) << f << "\n"
0062 << "char*: " << std::setfill('.') << std::setw(20) << c1 << std::setfill(' ') << "\n"
0063 << std::endl;
0064
0065 throw e;
0066 }
0067
0068 void func2() { func3(); }
0069
0070 void func1() {
0071 try {
0072 func2();
0073 } catch (cms::Exception& e) {
0074 cms::Exception toThrow("InfiniteLoop", "In func1", e);
0075 toThrow << "Gave up";
0076 throw toThrow;
0077 }
0078 }
0079
0080 }
0081
0082 TEST_CASE("Test cms::Exception", "[cms::Exception]") {
0083 SECTION("throw") { REQUIRE_THROWS_WITH(func1(), expected); }
0084 SECTION("returnCode") {
0085 cms::Exception e1("ABC");
0086 REQUIRE(e1.returnCode() == 8001);
0087 }
0088 SECTION("alreadyPrinted") {
0089 cms::Exception e1("ABC");
0090 REQUIRE(not e1.alreadyPrinted());
0091 e1.setAlreadyPrinted();
0092 REQUIRE(e1.alreadyPrinted());
0093 SECTION("copy constructor") {
0094 cms::Exception e("ABC");
0095 cms::Exception e2(e);
0096 REQUIRE(not e2.alreadyPrinted());
0097
0098 e.setAlreadyPrinted();
0099 cms::Exception e3(e);
0100 REQUIRE(e3.alreadyPrinted());
0101 }
0102 }
0103 SECTION("message banner") {
0104 cms::Exception e1("ABC");
0105 const std::string expected("An exception of category 'ABC' occurred.\n");
0106 REQUIRE(e1.explainSelf() == expected);
0107 }
0108 SECTION("consistent message") {
0109 cms::Exception e1("ABC");
0110 cms::Exception e1s("ABC");
0111 REQUIRE(e1.explainSelf() == e1s.explainSelf());
0112 }
0113
0114 SECTION("extend message") {
0115 cms::Exception e2("ABC", "foo");
0116 cms::Exception e2cs("ABC", std::string("foo"));
0117 cms::Exception e2sc(std::string("ABC"), "foo");
0118 cms::Exception e2ss(std::string("ABC"), std::string("foo"));
0119 e2 << "bar";
0120 e2cs << "bar";
0121 e2sc << "bar";
0122 e2ss << "bar";
0123 {
0124 const std::string expected(
0125 "An exception of category 'ABC' occurred.\n"
0126 "Exception Message:\n"
0127 "foo bar\n");
0128 REQUIRE(e2.explainSelf() == expected);
0129 }
0130 REQUIRE(e2.explainSelf() == e2cs.explainSelf());
0131 REQUIRE(e2.explainSelf() == e2sc.explainSelf());
0132 REQUIRE(e2.explainSelf() == e2ss.explainSelf());
0133
0134 SECTION("partial message ends with space") {
0135 cms::Exception e3("ABC", "foo ");
0136 e3 << "bar\n";
0137 const std::string expected(
0138 "An exception of category 'ABC' occurred.\n"
0139 "Exception Message:\n"
0140 "foo bar\n");
0141 REQUIRE(e3.explainSelf() == expected);
0142 }
0143 SECTION("partial message ends with new line") {
0144 cms::Exception e4("ABC", "foo\n");
0145 e4 << "bar";
0146 const std::string expected(
0147 "An exception of category 'ABC' occurred.\n"
0148 "Exception Message:\n"
0149 "foo\nbar\n");
0150 REQUIRE(e4.explainSelf() == expected);
0151 }
0152 }
0153 SECTION("addContext") {
0154 cms::Exception e2("ABC", "foo bar");
0155
0156 e2.addContext("context1");
0157 e2.addContext(std::string("context2"));
0158 e2.addAdditionalInfo("info1");
0159 e2.addAdditionalInfo(std::string("info2"));
0160
0161 const std::string expected(
0162 "An exception of category 'ABC' occurred while\n"
0163 " [0] context2\n"
0164 " [1] context1\n"
0165 "Exception Message:\n"
0166 "foo bar \n"
0167 " Additional Info:\n"
0168 " [a] info2\n"
0169 " [b] info1\n");
0170 REQUIRE(e2.explainSelf() == expected);
0171 SECTION("constructor message from other exception") {
0172 cms::Exception e6("DEF", "start", e2);
0173 e6 << "finish";
0174 std::string expected5(
0175 "An exception of category 'DEF' occurred while\n"
0176 " [0] context2\n"
0177 " [1] context1\n"
0178 "Exception Message:\n"
0179 "start\n"
0180 "foo bar "
0181 "finish\n"
0182 " Additional Info:\n"
0183 " [a] info2\n"
0184 " [b] info1\n");
0185 REQUIRE(e6.explainSelf() == expected5);
0186 SECTION("copy constructor") {
0187 cms::Exception e7(e6);
0188 REQUIRE(e7.explainSelf() == expected5);
0189 REQUIRE(e7.category() == std::string("DEF"));
0190 REQUIRE(e7.message() == std::string("start\n"
0191 "foo bar "
0192 "finish"));
0193 }
0194 SECTION("clearContext") {
0195 e6.clearContext();
0196 std::string expected7_1(
0197 "An exception of category 'DEF' occurred.\n"
0198 "Exception Message:\n"
0199 "start\n"
0200 "foo bar "
0201 "finish\n"
0202 " Additional Info:\n"
0203 " [a] info2\n"
0204 " [b] info1\n");
0205 REQUIRE(e6.explainSelf() == expected7_1);
0206 }
0207 SECTION("setContext") {
0208 std::list<std::string> newContext;
0209 newContext.push_back("new1");
0210 newContext.push_back("new2");
0211 newContext.push_back("new3");
0212 e6.setContext(newContext);
0213 REQUIRE(e6.context() == newContext);
0214 }
0215 SECTION("clearAdditionalInfo") {
0216 e6.clearAdditionalInfo();
0217 std::string expected7_2(
0218 "An exception of category 'DEF' occurred while\n"
0219 " [0] context2\n"
0220 " [1] context1\n"
0221 "Exception Message:\n"
0222 "start\n"
0223 "foo bar "
0224 "finish\n");
0225 REQUIRE(e6.explainSelf() == expected7_2);
0226 }
0227 SECTION("setAdditionalInfo") {
0228 std::list<std::string> newAdditionalInfo;
0229 newAdditionalInfo.push_back("newInfo1");
0230 newAdditionalInfo.push_back("newInfo2");
0231 newAdditionalInfo.push_back("newInfo3");
0232 e6.setAdditionalInfo(newAdditionalInfo);
0233 REQUIRE(e6.additionalInfo() == newAdditionalInfo);
0234 std::string expected7_3(
0235 "An exception of category 'DEF' occurred while\n"
0236 " [0] context2\n"
0237 " [1] context1\n"
0238 "Exception Message:\n"
0239 "start\n"
0240 "foo bar "
0241 "finish\n"
0242 " Additional Info:\n"
0243 " [a] newInfo3\n"
0244 " [b] newInfo2\n"
0245 " [c] newInfo1\n");
0246 REQUIRE(e6.explainSelf() == expected7_3);
0247 }
0248 }
0249 }
0250
0251 cms::Exception e6("DEF", "start\nfoo barfinish");
0252 e6.setContext({{"new1", "new2", "new3"}});
0253 e6.setAdditionalInfo({"newInfo1", "newInfo2", "newInfo3"});
0254 SECTION("append") {
0255 e6.append(std::string(" X"));
0256 e6.append("Y");
0257 cms::Exception e8("ZZZ", "Z");
0258 e6.append(e8);
0259 std::string expected7_4(
0260 "An exception of category 'DEF' occurred while\n"
0261 " [0] new3\n"
0262 " [1] new2\n"
0263 " [2] new1\n"
0264 "Exception Message:\n"
0265 "start\n"
0266 "foo bar"
0267 "finish XYZ \n"
0268 " Additional Info:\n"
0269 " [a] newInfo3\n"
0270 " [b] newInfo2\n"
0271 " [c] newInfo1\n");
0272 REQUIRE(e6.explainSelf() == expected7_4);
0273 }
0274 SECTION("clearMessage") {
0275 e6.clearMessage();
0276 std::string expected7_5(
0277 "An exception of category 'DEF' occurred while\n"
0278 " [0] new3\n"
0279 " [1] new2\n"
0280 " [2] new1\n"
0281 " Additional Info:\n"
0282 " [a] newInfo3\n"
0283 " [b] newInfo2\n"
0284 " [c] newInfo1\n");
0285 REQUIRE(e6.explainSelf() == expected7_5);
0286 }
0287 SECTION("raise") {
0288 std::unique_ptr<cms::Exception> ptr(e6.clone());
0289 std::string expected7_6(
0290 "An exception of category 'DEF' occurred while\n"
0291 " [0] new3\n"
0292 " [1] new2\n"
0293 " [2] new1\n"
0294 "Exception Message:\n"
0295 "start\n"
0296 "foo bar"
0297 "finish \n"
0298 " Additional Info:\n"
0299 " [a] newInfo3\n"
0300 " [b] newInfo2\n"
0301 " [c] newInfo1\n");
0302 REQUIRE_THROWS_WITH(ptr->raise(), expected7_6);
0303 }
0304 }