예제 #1
0
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);
}
예제 #2
0
    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);
            }
        }
    }
예제 #3
0
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);
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
        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);
        }
예제 #7
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;
}