RCFProto
 All Classes Functions Typedefs
TestMinimal.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
19 #ifndef INCLUDE_RCF_TEST_TESTMINIMAL_HPP
20 #define INCLUDE_RCF_TEST_TESTMINIMAL_HPP
21 
22 // Include valarray early so it doesn't get trampled by min/max macro definitions.
23 #if defined(_MSC_VER) && _MSC_VER == 1310 && defined(RCF_USE_BOOST_SERIALIZATION)
24 #include <valarray>
25 #endif
26 
27 // For msvc-7.1, prevent including <locale> from generating warnings.
28 #if defined(_MSC_VER) && _MSC_VER == 1310
29 #pragma warning( disable : 4995 ) // 'func': name was marked as #pragma deprecated
30 #include <locale>
31 #pragma warning( default : 4995 )
32 #endif
33 
34 #include <RCF/Exception.hpp>
35 #include <RCF/InitDeinit.hpp>
36 #include <RCF/ThreadLibrary.hpp>
37 #include <RCF/Tools.hpp>
38 
39 #include <RCF/test/PrintTestHeader.hpp>
40 #include <RCF/test/ProgramTimeLimit.hpp>
41 #include <RCF/test/SpCollector.hpp>
42 #include <RCF/test/Test.hpp>
43 #include <RCF/test/TransportFactories.hpp>
44 
45 #include <RCF/util/Platform/OS/BsdSockets.hpp>
46 #include <RCF/util/Log.hpp>
47 
48 #include <iostream>
49 #include <sstream>
50 
51 #ifdef _MSC_VER
52 #include <RCF/test/MiniDump.hpp>
53 #endif
54 
55 #ifdef _MSC_VER
56 #include <crtdbg.h>
57 #endif
58 
59 // Test custom allocation support, if applicable.
60 #if RCF_FEATURE_CUSTOM_ALLOCATOR==1
61 #if defined(_MSC_VER) && !defined(NDEBUG)
62 #include <RCF/test/AllocationHookCRT.hpp>
63 #endif
64 #endif
65 
66 int test_main(int argc, char **argv);
67 
68 int main(int argc, char **argv)
69 {
70  Platform::OS::BsdSockets::disableBrokenPipeSignals();
71 
72  RCF::RcfInitDeinit rcfInit;
73 
74  RCF::Timer testTimer;
75 
76  RCF::initializeTransportFactories();
77 
78  std::cout << "Commandline: ";
79  for (int i=0; i<argc; ++i)
80  {
81  std::cout << argv[i] << " ";
82  }
83  std::cout << std::endl;
84 
85  bool shoudNotCatch = false;
86 
87  {
88  util::CommandLineOption<std::string> clTestCase( "testcase", "", "Run a specific test case.");
89  util::CommandLineOption<bool> clListTests("list", false, "List all test cases.");
90  util::CommandLineOption<bool> clAssert( "assert", false, "Enable assert popups, and assert on test failures.");
91  util::CommandLineOption<int> clLogLevel( "loglevel", 1, "Set RCF log level.");
92  util::CommandLineOption<bool> clLogTime( "logtime", false, "Set RCF time stamp logging.");
93  util::CommandLineOption<bool> clLogTid( "logtid", false, "Set RCF thread id logging.");
94  util::CommandLineOption<std::string> clLogFormat("logformat", "", "Set RCF log format.");
95  util::CommandLineOption<bool> clNoCatch( "nocatch", false, "Don't catch exceptions at top level.");
96  util::CommandLineOption<unsigned int> clTimeLimit("timelimit", 5*60, "Set program time limit in seconds. 0 to disable.");
97 
98 #ifdef _MSC_VER
99  util::CommandLineOption<bool> clMinidump("minidump", true, "Enable minidump creation.");
100 #endif
101 
102  bool exitOnHelp = false;
103  util::CommandLine::getSingleton().parse(argc, argv, exitOnHelp);
104 
105  // -testcase
106  std::string testCase = clTestCase.get();
107  if (!testCase.empty())
108  {
109  RCF::gTestEnv().setTestCaseToRun(testCase);
110  }
111 
112  // -list
113  bool list = clListTests.get();
114  if (list)
115  {
116  RCF::gTestEnv().setEnumerationOnly();
117  }
118 
119  // -assert
120  bool assertOnFail = clAssert.get();
121  RCF::gTestEnv().setAssertOnFail(assertOnFail);
122 
123 #ifdef BOOST_WINDOWS
124  if (!assertOnFail)
125  {
126  // Try to prevent those pesky crash dialogs from popping up.
127 
128  DWORD dwFlags = SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS;
129  DWORD dwOldFlags = SetErrorMode(dwFlags);
130  SetErrorMode(dwOldFlags | dwFlags);
131 
132 #ifdef _MSC_VER
133  // Disable CRT asserts.
134  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
135  _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
136  _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
137 #endif
138 
139  }
140 #endif
141 
142 
143  // -loglevel
144  int logName = RCF::LogNameRcf;
145  int logLevel = clLogLevel.get();
146  bool includeTid = clLogTid.get();
147  bool includeTimestamp = clLogTime.get();
148 
149  std::string logFormat = clLogFormat.get();
150  if (logFormat.empty())
151  {
152  if (!includeTid && !includeTimestamp)
153  {
154  logFormat = "%E(%F): %X";
155  }
156  if (includeTid && !includeTimestamp)
157  {
158  logFormat = "%E(%F): (Tid:%D): %X";
159  }
160  else if (!includeTid && includeTimestamp)
161  {
162  logFormat = "%E(%F): (Time:%H): %X";
163  }
164  else if (includeTid && includeTimestamp)
165  {
166  logFormat = "%E(%F): (Tid:%D)(Time::%H): %X";
167  }
168  }
169 
170 #ifdef BOOST_WINDOWS
171  RCF::LoggerPtr loggerPtr(new RCF::Logger(logName, logLevel, RCF::LogToDebugWindow(), logFormat) );
172  loggerPtr->activate();
173 #else
174  RCF::LoggerPtr loggerPtr(new RCF::Logger(logName, logLevel, RCF::LogToStdout(), logFormat) );
175  loggerPtr->activate();
176 #endif
177 
178  // -minidump
179 #if defined(_MSC_VER)
180  bool enableMinidumps = clMinidump.get();
181  if (enableMinidumps)
182  {
183  setMiniDumpExceptionFilter();
184  }
185 #endif
186 
187  // -timelimit
188  unsigned int timeLimitS = clTimeLimit.get();
189  gpProgramTimeLimit = new ProgramTimeLimit(timeLimitS);
190 
191  shoudNotCatch = clNoCatch.get();
192  }
193 
194  int ret = 0;
195 
196  bool shouldCatch = !shoudNotCatch;
197  if (shouldCatch)
198  {
199  try
200  {
201  ret = test_main(argc, argv);
202  }
203  catch(const RCF::RemoteException & e)
204  {
205  std::cout << "Caught top-level exception (RCF::RemoteException): " << e.getErrorString() << std::endl;
206  RCF_CHECK(1==0);
207  }
208  catch(const RCF::Exception & e)
209  {
210  std::cout << "Caught top-level exception (RCF::Exception): " << e.getErrorString() << std::endl;
211  RCF_CHECK(1==0);
212  }
213  catch(const std::exception & e)
214  {
215  std::cout << "Caught top-level exception (std::exception): " << e.what() << std::endl;
216  RCF_CHECK(1==0);
217  }
218  catch (...)
219  {
220  std::cout << "Caught top-level exception (...)" << std::endl;
221  RCF_CHECK(1==0);
222  }
223  }
224  else
225  {
226  ret = test_main(argc, argv);
227  }
228 
229  std::string exitMsg;
230  std::size_t failCount = RCF::gTestEnv().getFailCount();
231  if (failCount)
232  {
233  std::ostringstream os;
234  os << "*** Test Failures: " << failCount << " ***" << std::endl;
235  exitMsg = os.str();
236  }
237  else
238  {
239  exitMsg = "*** All Tests Passed ***\n";
240  }
241 
242  RCF::gTestEnv().printTestMessage(exitMsg);
243 
244  // Print out how long the test took.
245  boost::uint32_t durationMs = testTimer.getDurationMs();
246  std::cout << "Time elapsed: " << durationMs/1000 << " (s)" << std::endl;
247 
248  RCF::deinit();
249 
250  // Check that there are no shared_ptr cycles.
251  checkNoCycles();
252 
253  return ret + static_cast<int>(failCount);
254 }
255 
256 namespace RCF {
257  std::string getFilterName(int filterId)
258  {
259  switch (filterId)
260  {
261  case RcfFilter_Unknown : return "Unknown";
262  case RcfFilter_Identity : return "Identity";
263  case RcfFilter_OpenSsl : return "OpenSSL";
264  case RcfFilter_ZlibCompressionStateless : return "Zlib stateless";
265  case RcfFilter_ZlibCompressionStateful : return "Zlib stateful";
266  case RcfFilter_SspiNtlm : return "NTLM";
267  case RcfFilter_SspiKerberos : return "Kerberos";
268  case RcfFilter_SspiNegotiate : return "Negotiate";
269  case RcfFilter_SspiSchannel : return "Schannel";
270  case RcfFilter_Xor : return "Xor";
271  default : return "Unknown";
272  }
273  }
274 
275  bool isFilterRemovable(int filterId)
276  {
277  switch (filterId)
278  {
279  case RcfFilter_Unknown : return true;
280  case RcfFilter_Identity : return true;
281  case RcfFilter_OpenSsl : return true;
282  case RcfFilter_ZlibCompressionStateless : return false;
283  case RcfFilter_ZlibCompressionStateful : return false;
284  case RcfFilter_SspiNtlm : return true;
285  case RcfFilter_SspiKerberos : return true;
286  case RcfFilter_SspiNegotiate : return true;
287  case RcfFilter_SspiSchannel : return true;
288  case RcfFilter_Xor : return true;
289  default : return true;
290  }
291  }
292 }
293 
294 // Minidump creation code, for Visual C++ 2003 and later.
295 #if defined(_MSC_VER)
296 #include <RCF/test/MiniDump.cpp>
297 #endif
298 
299 #include <RCF/../../src/RCF/test/Test.cpp>
300 
301 #endif // ! INCLUDE_RCF_TEST_TESTMINIMAL_HPP