Back to home page

Project CMSSW displayed by LXR

 
 

    


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     //  throw cms::Exception("DataCorrupt")
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     //  throw cms::Exception("DataCorrupt")
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 }  // namespace
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 }