void *operator new(size_t bytes) { if (gInstrumented) { if (!gExpectAllocations) { // Only flag the first unexpected allocation, so we don't end up // with thousands of failures. gInstrumented = false; std::cout << "***************************************" << std::endl; std::cout << "Unexpected memory allocation. Call stack:" << std::endl; std::cout << StackTrace().toString() << std::endl; std::cout << "***************************************" << std::endl; RCF_CHECK(0 && "Unexpected memory allocation."); } ++gnAllocations; } return malloc(bytes); }
void clientObjectLoadTest( RCF::I_ClientTransport & clientTransport, unsigned int clientReps, unsigned int maxDelayMs) { RcfClient<I_Y> client( clientTransport.clone() ); client.getClientStub().setRemoteCallTimeoutMs(1000*20); // 20s timeout bool ok = tryCreateRemoteObject<I_Y>(client); { RCF::Lock lock(rcfCheckMutex); RCF_CHECK(ok); } for (unsigned int i=0; i<clientReps; ++i) { //if ((i*100) % (20*clientReps) == 0) //{ // Platform::OS::ThreadId threadId = // Platform::OS::GetCurrentThreadId(); // RCF::Lock lock(ioMutex); // std::cout // << "Client thread #" << threadId // << ": progress: " << i*100/clientReps // << "%\n"; //} unsigned int whichTask = i%2; unsigned int delayMs = maxDelayMs > 0 ? rand()%maxDelayMs : 0; switch (whichTask) { case 0: { int n = client.ping(); RCF::Lock lock(rcfCheckMutex); RCF_CHECK_EQ(n , 17); } break; case 1: { int n = client.wait(delayMs); RCF::Lock lock(rcfCheckMutex); RCF_CHECK_EQ(n , 17); } break; default: RCF_ASSERT(0)(whichTask); } } }
int crtAllocationHook( int allocType, void *userData, size_t size, int blockType, long requestNumber, const unsigned char *filename, // Can't be UNICODE int lineNumber) { // Check for unexpected memory allocations. if ( gInstrumented && (allocType == _HOOK_ALLOC || allocType == _HOOK_REALLOC) && !gExpectAllocations) { // Only flag the first unexpected allocation, so we don't end up // with thousands of failures. gInstrumented = false; // If we do want to track further allocations, uncomment this. //gInstrumented = true; std::cout << "***************************************" << std::endl; std::cout << "Unexpected memory allocation. Call stack:" << std::endl; std::cout << StackTrace().toString() << std::endl; std::cout << "***************************************" << std::endl; RCF_CHECK(0 && "Unexpected memory allocation."); } if (allocType == _HOOK_ALLOC || allocType == _HOOK_REALLOC) { ++gnAllocations; } return pfnOldCrtAllocHook( allocType, userData, size, blockType, requestNumber, filename, lineNumber); }
void *operator new [](size_t bytes) { if (gInstrumented) { if (!gExpectAllocations) { // Only flag the first unexpected allocation, so we don't end up // with thousands of failures. gInstrumented = false; RCF_CHECK(gExpectAllocations); std::cout << "Unexpected memory allocation." << std::endl; } ++gnAllocations; } return malloc(bytes); }
int main(int argc, char **argv) { Platform::OS::BsdSockets::disableBrokenPipeSignals(); RCF::RcfInitDeinit init; RCF::Timer testTimer; RCF::initializeTransportFactories(); std::cout << "Commandline: "; for (int i=0; i<argc; ++i) { std::cout << argv[i] << " "; } std::cout << std::endl; bool shoudNotCatch = false; { util::CommandLineOption<std::string> clTestCase( "testcase", "", "Run a specific test case."); util::CommandLineOption<bool> clListTests("list", false, "List all test cases."); util::CommandLineOption<bool> clAssert( "assert", false, "Enable assert popups, and assert on test failures."); util::CommandLineOption<int> clLogLevel( "loglevel", 1, "Set RCF log level."); util::CommandLineOption<bool> clLogTime( "logtime", false, "Set RCF time stamp logging."); util::CommandLineOption<bool> clLogTid( "logtid", false, "Set RCF thread id logging."); util::CommandLineOption<std::string> clLogFormat("logformat", "", "Set RCF log format."); util::CommandLineOption<bool> clNoCatch( "nocatch", false, "Don't catch exceptions at top level."); util::CommandLineOption<unsigned int> clTimeLimit("timelimit", 5*60, "Set program time limit in seconds. 0 to disable."); #if defined(_MSC_VER) && _MSC_VER >= 1310 util::CommandLineOption<bool> clMinidump("minidump", true, "Enable minidump creation."); #endif bool exitOnHelp = false; util::CommandLine::getSingleton().parse(argc, argv, exitOnHelp); // -testcase std::string testCase = clTestCase.get(); if (!testCase.empty()) { gTestEnv().setTestCaseToRun(testCase); } // -list bool list = clListTests.get(); if (list) { gTestEnv().setEnumerationOnly(); } // -assert bool assertOnFail = clAssert.get(); gTestEnv().setAssertOnFail(assertOnFail); #ifdef BOOST_WINDOWS if (!assertOnFail) { // Try to prevent those pesky crash dialogs from popping up. DWORD dwFlags = SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS; DWORD dwOldFlags = SetErrorMode(dwFlags); SetErrorMode(dwOldFlags | dwFlags); #ifdef _MSC_VER // Disable CRT asserts. _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); #endif } #endif // -loglevel int logName = RCF::LogNameRcf; int logLevel = clLogLevel.get(); bool includeTid = clLogTid.get(); bool includeTimestamp = clLogTime.get(); std::string logFormat = clLogFormat.get(); if (logFormat.empty()) { if (!includeTid && !includeTimestamp) { logFormat = "%E(%F): %X"; } if (includeTid && !includeTimestamp) { logFormat = "%E(%F): (Tid:%D): %X"; } else if (!includeTid && includeTimestamp) { logFormat = "%E(%F): (Time:%H): %X"; } else if (includeTid && includeTimestamp) { logFormat = "%E(%F): (Tid:%D)(Time::%H): %X"; } } #ifdef BOOST_WINDOWS util::LoggerPtr loggerPtr(new util::Logger(logName, logLevel, util::LogToDebugWindow(), logFormat) ); loggerPtr->activate(); #else util::LoggerPtr loggerPtr(new util::Logger(logName, logLevel, util::LogToStdout(), logFormat) ); loggerPtr->activate(); #endif // -minidump #if defined(_MSC_VER) && _MSC_VER >= 1310 bool enableMinidumps = clMinidump.get(); if (enableMinidumps) { setMiniDumpExceptionFilter(); } #endif // -timelimit unsigned int timeLimitS = clTimeLimit.get(); gpProgramTimeLimit = new ProgramTimeLimit(timeLimitS); shoudNotCatch = clNoCatch.get(); } int ret = 0; bool shouldCatch = !shoudNotCatch; if (shouldCatch) { try { ret = test_main(argc, argv); } catch(const RCF::RemoteException & e) { std::cout << "Caught top-level exception (RCF::RemoteException): " << e.getErrorString() << std::endl; RCF_CHECK(1==0); } catch(const RCF::Exception & e) { std::cout << "Caught top-level exception (RCF::Exception): " << e.getErrorString() << std::endl; RCF_CHECK(1==0); } catch(const std::exception & e) { std::cout << "Caught top-level exception (std::exception): " << e.what() << std::endl; RCF_CHECK(1==0); } catch (...) { std::cout << "Caught top-level exception (...)" << std::endl; RCF_CHECK(1==0); } } else { ret = test_main(argc, argv); } std::string exitMsg; std::size_t failCount = gTestEnv().getFailCount(); if (failCount) { std::ostringstream os; os << "*** Test Failures: " << failCount << " ***" << std::endl; exitMsg = os.str(); } else { exitMsg = "*** All Tests Passed ***\n"; } gTestEnv().printTestMessage(exitMsg); // Print out how long the test took. boost::uint32_t durationMs = testTimer.getDurationMs(); std::cout << "Time elapsed: " << durationMs/1000 << " (s)" << std::endl; return ret + static_cast<int>(failCount); }
void checkServerHandle() { RCF::I_SessionState & sessionState = RCF::getCurrentRcfSession().getSessionState(); #ifdef BOOST_WINDOWS // TcpIocpServerTransport RCF::TcpIocpSessionState *tcpSessionState = dynamic_cast<RCF::TcpIocpSessionState *>(&sessionState); if (tcpSessionState) { int serverHandle = tcpSessionState->getNativeHandle(); RCF_CHECK(serverHandle != 0 && serverHandle != -1); return; } // Win32NamedPipeServerTransport RCF::Win32NamedPipeSessionState * win32PipeSessionState = dynamic_cast<RCF::Win32NamedPipeSessionState *>(&sessionState); if (win32PipeSessionState) { HANDLE serverHandle = win32PipeSessionState->getNativeHandle(); RCF_CHECK_NEQ(serverHandle, 0); return; } #endif #ifdef RCF_USE_BOOST_ASIO // AsioServerTransport RCF::AsioSessionState * asioSessionState = dynamic_cast<RCF::AsioSessionState *>(&sessionState); if (asioSessionState) { int serverHandle = asioSessionState->getNativeHandle(); RCF_CHECK(serverHandle != 0 && serverHandle != -1); return; } #endif #if defined(RCF_USE_BOOST_ASIO) && defined (BOOST_ASIO_HAS_LOCAL_SOCKETS) // UnixLocalServerTransport RCF::AsioSessionState * unixLocalSessionState = dynamic_cast<RCF::AsioSessionState *>(&sessionState); if (unixLocalSessionState) { int serverHandle = unixLocalSessionState->getNativeHandle(); RCF_CHECK(serverHandle != 0 && serverHandle != -1); return; } #endif // UdpServerTransport RCF::UdpSessionState * udpSessionState = dynamic_cast<RCF::UdpSessionState *>(&sessionState); if (udpSessionState) { int serverHandle = udpSessionState->getNativeHandle(); RCF_CHECK(serverHandle != 0 && serverHandle != -1); return; } RCF_CHECK_EQ(1 , 0); }
int test_main(int, char**) { RCF::RcfInitDeinit rcfinitDeinit; #ifdef BOOST_WINDOWS RCF::tstring pipeName = RCF_T("TestPipe"); #else RCF::tstring pipeName = RCF_TEMP_DIR "TestPipe"; #endif RCF::NamedPipeEndpoint ep(pipeName); Echo echo; RCF::RcfServer server(ep); // 10 server threads server.setThreadPool( RCF::ThreadPoolPtr( new RCF::ThreadPool(10)) ); server.bind( (I_Echo *) 0, echo); server.start(); { // Make a single call, no waiting std::string s1 = "test"; RCF::NamedPipeEndpoint ep(pipeName); RcfClient<I_Echo> client(ep); std::string s2 = client.echo(s1); RCF_CHECK_EQ(s1 , s2 ); } { // Make 5 calls, in parallel, each one waiting 2 seconds boost::uint32_t t0 = RCF::getCurrentTimeMs(); boost::uint32_t waitMs = 2000; ThreadGroup clients; for (std::size_t i=0; i<5; ++i) { clients.push_back( RCF::ThreadPtr( new RCF::Thread( boost::bind(clientTask, pipeName, waitMs)))); } joinThreadGroup(clients); // Total time should be little more than 2 seconds boost::uint32_t t1 = RCF::getCurrentTimeMs(); std::cout << "Total time: " << t1-t0 << " ms..." << std::endl; RCF_CHECK_LT(t1-t0 , 2*waitMs); } #ifdef BOOST_WINDOWS { // Named pipe impersonation - use our own credentials RCF::tstring tUserName = RCF::getMyUserName(); std::string userName(util::toString(tUserName)); RCF::NamedPipeEndpoint ep(pipeName); RcfClient<I_Echo> client(ep); std::string s = client.whatsMyWin32UserName(); RCF_CHECK_EQ(s , userName); } { // SSPI impersonation - use our own credentials server.stop(); RCF::FilterServicePtr filterServicePtr(new RCF::FilterService()); filterServicePtr->addFilterFactory( RCF::FilterFactoryPtr( new RCF::NtlmFilterFactory())); server.addService(filterServicePtr); server.start(); RCF::tstring tUserName = RCF::getMyUserName(); std::string userName(util::toString(tUserName)); RCF::NamedPipeEndpoint ep(pipeName); RcfClient<I_Echo> client(ep); RCF::FilterPtr ntlmFilterPtr( new RCF::NtlmFilter() ); client.getClientStub().requestTransportFilters(ntlmFilterPtr); client.getClientStub().setRemoteCallTimeoutMs(1000*3600); std::string s = client.whatsMyWin32UserName(); RCF_CHECK_EQ(s , userName); server.stop(); server.removeService(filterServicePtr); server.start(); } #endif { // Test error reporting, by exceeding the max message length. int maxLengthOrig = server.getServerTransport().getMaxMessageLength(); server.getServerTransport().setMaxMessageLength(10*1024); RCF::ByteBuffer byteBuffer(50*1024); for (std::size_t i=0; i<byteBuffer.getLength(); ++i) { byteBuffer.getPtr()[i] = i%256 ; } RCF::NamedPipeEndpoint ep(pipeName); RcfClient<I_Echo> client(ep); try { RCF_CHECK(byteBuffer == client.echo(byteBuffer) ); RCF_CHECK_FAIL(); } catch(RCF::Exception &e) { RCF_CHECK_OK(); #ifdef BOOST_WINDOWS RCF_CHECK_EQ(e.getErrorId() , RCF::RcfError_ClientWriteFail )(e.getError()); #else RCF_CHECK_EQ(e.getErrorId() , RCF::RcfError_ServerMessageLength )(e.getError()); #endif } server.getServerTransport().setMaxMessageLength(maxLengthOrig); // This time, turn up the message length and check that it goes through. server.getServerTransport().setMaxMessageLength(-1); client.getClientStub().getTransport().setMaxMessageLength(-1); RCF_CHECK(byteBuffer == client.echo(byteBuffer) ); } /* { // Some performance testing. RCF Win32 named pipe server sessions have a // reuse-instead-of-delete feature that needs some exercise. // Several threads, concurrently connecting and disconnecting, especially // disconnecting while a call is in progress. void clientTask2(const std::string & pipeName); std::vector<RCF::ThreadPtr> threads; for (std::size_t i=0; i<10; ++i) { threads.push_back( RCF::ThreadPtr( new RCF::Thread( boost::bind(clientTask2, pipeName)))); } joinThreadGroup(threads); } */ return 0; }