diff -r f5050f1da672 -r 04becd199f91 javacommons/comms/tsrc/src/connect.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javacommons/comms/tsrc/src/connect.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,424 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: ?Description +* +*/ + +#include +#include "monitor.h" +#include "TestHarness.h" +#include "logger.h" + +#include "commsserverendpoint.h" +#include "commsclientendpoint.h" +#include "commsmessage.h" +#include "echoserver.h" + +using namespace java::comms; +using java::util::Monitor; + +TEST_GROUP(Connect) +{ + CommsServerEndpoint comms; + + TEST_SETUP() + { + comms.start(IPC_ADDRESS_COMMS_MODULE_TEST); + } + + TEST_TEARDOWN() + { + comms.stop(); + } +}; + +/** + * Test open connection + * 1. Normal connect, disconnect + * 2. Multiple connect calls without disconnect + * 3. Disconnect before connect + * 4. Connect to non-existing host + */ + +TEST(Connect, OpenConnection) +{ + CommsClientEndpoint client; + + // 1. Normal connect, disconnect + CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!client.disconnect()); + + // 2. Multiple connect calls without disconnect + CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!client.disconnect()); + + // 3. Disconnect before connect + CHECK(!client.disconnect()); + CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!client.disconnect()); + + // 4. Connect to non-existing host + CHECK(client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+666)); + CHECK(!client.disconnect()); +} + +/** + * Test open connection with multiple clients + * 1. Normal connect, disconnect + * 2. Multiple connect/disconnects + */ + +TEST(Connect, MultiClient) +{ + CommsClientEndpoint a, b, c, d, e; + + // 1. Normal connect, disconnect + CHECK(!a.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!b.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!c.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!d.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!e.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!e.disconnect()); + CHECK(!d.disconnect()); + CHECK(!c.disconnect()); + CHECK(!b.disconnect()); + CHECK(!a.disconnect()); + + // 2. Multiple connect/disconnects + for (int i=0; i<10; i++) + { + CHECK(!a.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!b.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!c.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!d.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!e.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!e.disconnect()); + CHECK(!d.disconnect()); + CHECK(!c.disconnect()); + CHECK(!b.disconnect()); + CHECK(!a.disconnect()); + } +} + +/** + * Test server cases + * 1. Server exits while client is connected + * 2. Address is already in use + * 3. Start/Connect using different addresses + */ + +TEST(Connect, Server) +{ + CommsServerEndpoint server; + CommsClientEndpoint client; + int ADDR = IPC_ADDRESS_COMMS_MODULE_TEST + 1; + + // 1. Server exits while client is connected + CHECK(!server.start(ADDR)); + CHECK(!client.connect(ADDR)); + CHECK(!server.stop()); + CHECK(!client.disconnect()); + + // 2. Address is already in use + CHECK(server.start(IPC_ADDRESS_COMMS_MODULE_TEST)!=0); + CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!server.stop()); + CHECK(!client.disconnect()); + + // 3. Start/Connect using different addresses + CHECK(!server.start(ADDR)); + CHECK(!client.connect(ADDR)); + CHECK(!client.disconnect()); + CHECK(!server.stop()); + + CHECK(!server.start(ADDR+1)); + CHECK(!client.connect(ADDR+1)); + CHECK(!client.disconnect()); + CHECK(!server.stop()); + +} + +/** + * Test connect/disconnect from separate threads + * 1. connect/disconnect from separate threads + * 2. start/stop from separate threads + */ + +void doDisconnect(CommsClientEndpoint* aClient) +{ + CHECK(!aClient->disconnect()); +} +void* disconnectThread(void* aComms) +{ + CommsClientEndpoint* client = reinterpret_cast(aComms); + doDisconnect(client); + return 0; +} + +void doStop(CommsServerEndpoint* aServer) +{ + CHECK(!aServer->stop()); +} +void* stopThread(void* aComms) +{ + CommsServerEndpoint* server = reinterpret_cast(aComms); + doStop(server); + return 0; +} + +TEST(Connect, separateThread) +{ + CommsServerEndpoint server; + CommsClientEndpoint client; + int ADDR = IPC_ADDRESS_COMMS_MODULE_TEST + 1; + + CommsMessage msg; + + // 1. connect/disconnect from separate threads + CHECK(!server.start(ADDR)); + CHECK(!client.connect(ADDR)); + + CHECK(client.send(msg) == 0); + pthread_t threadId = 0; + pthread_create(&threadId, 0, disconnectThread, &client); + pthread_join(threadId, 0); + CHECK(client.send(msg) != 0); + + // 2. start/stop from separate threads + pthread_create(&threadId, 0, stopThread, &server); + pthread_join(threadId, 0); + + CommsServerEndpoint server2; + CHECK(!server2.start(ADDR)); + CHECK(!server2.stop()); +} + +/** + * Check that onStart and onExit callbacks are done + * (ensures that ipc provider implementation is done correctly) + * 1. Callbacks are done after connect/disconnect + * 2. Callbacks are done after start/stop + */ + +class OnStartExitClient : public CommsClientEndpoint +{ +public: + OnStartExitClient() : mOnStart(false), mOnExit(false) {} + + virtual void onStart() + { + mOnStart = true; + } + virtual void onExit() + { + mOnExit = true; + } + + bool mOnStart; + bool mOnExit; +}; + +class OnStartExitServer : public CommsServerEndpoint +{ +public: + OnStartExitServer() : mOnStart(false), mOnExit(false) {} + + virtual void onStart() + { + mOnStart = true; + } + virtual void onExit() + { + mOnExit = true; + } + + bool mOnStart; + bool mOnExit; +}; + +TEST(Connect, onStartExit) +{ + // 1. Callbacks are done after connect/disconnect + OnStartExitClient client; + CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + CHECK(!client.disconnect()); + CHECK(client.mOnStart); + CHECK(client.mOnExit); + + // 2. Callbacks are done after start/stop + OnStartExitServer server; + CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1)); + CHECK(!server.stop()); + CHECK(server.mOnStart); + CHECK(server.mOnExit); +} + + +/** + * Test disconnect/stop while sendReceive is pending + * 1. disconnect while sendReceive is pending in client + * 2. stop while sendReceive is pending in client + * 3. disconnect while sendReceive is pending in server + * 4. stop while sendReceive is pending in server + */ + +void doSendReceive(CommsEndpoint* aComms) +{ + CommsMessage msg; + msg.setModuleId(MODULE_ID_NO_REPLY); + CommsMessage receivedMsg; + + int rc = aComms->sendReceive(msg, receivedMsg, 3); + CHECK(rc != 0); + CHECK(rc != ETIMEDOUT); + + // check that next send fails as other party is disconnected + // (and receive thread may still be running depending on timing) + rc = aComms->send(msg); + CHECK(rc != 0); +} + +void* sendReceiveThread(void* aComms) +{ + CommsEndpoint* comms = reinterpret_cast(aComms); + doSendReceive(comms); + return 0; +} + +class Notifier : public CommsListener +{ +public: + Notifier(Monitor& aMonitor) : mMonitor(aMonitor) {} + virtual void processMessage(CommsMessage&) + { + mMonitor.notify(); + + } +private: + Monitor& mMonitor; +}; + +struct threadData +{ + CommsEndpoint* comms; + int clientAddress; +}; + +void doServer(CommsEndpoint* aComms, int aAddress) +{ + CommsMessage msg; + msg.setReceiver(aAddress); + CommsMessage receivedMsg; + + int rc = aComms->sendReceive(msg, receivedMsg, 3); + CHECK(rc != 0); + CHECK(rc != ETIMEDOUT); +} + +void* serverThread(void* aData) +{ + threadData* data = reinterpret_cast(aData); + doServer(data->comms, data->clientAddress); + delete data; + return 0; +} + +class ServerListener : public CommsListener +{ +public: + ServerListener(CommsEndpoint& aComms) : mComms(aComms) {} + virtual void processMessage(CommsMessage& aMsg) + { + threadData* data = new threadData; + data->comms = &mComms; + data->clientAddress = aMsg.getSender(); + pthread_t threadId = 0; + pthread_create(&threadId, 0, serverThread, data); + } +private: + CommsEndpoint& mComms; +}; + +TEST(Connect, sendReceivePending) +{ + std::auto_ptr monitor(Monitor::createMonitor()); + + Notifier listener(*monitor); + CommsClientEndpoint client; + + // 1. disconnect while sendReceive is pending in client + CHECK(!comms.registerDefaultListener(&listener)); + CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); + + pthread_t threadId = 0; + pthread_create(&threadId, 0, sendReceiveThread, &client); + + monitor->wait(); + CHECK(!client.disconnect()); + + pthread_join(threadId, 0); + CHECK(!comms.unregisterDefaultListener(&listener)); + + // 2. stop while sendReceive is pending in client + CommsServerEndpoint server; + CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1)); + CHECK(!server.registerDefaultListener(&listener)); + + CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+1)); + + threadId = 0; + pthread_create(&threadId, 0, sendReceiveThread, &client); + + monitor->wait(); + CHECK(!server.stop()); + + pthread_join(threadId, 0); + CHECK(!client.disconnect()); + CHECK(!server.unregisterDefaultListener(&listener)); + + // 3. disconnect while sendReceive is pending in server + ServerListener serverListener(server); + + CHECK(!server.registerDefaultListener(&serverListener)); + CHECK(!client.registerDefaultListener(&listener)); + + CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1)); + CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+1)); + + CommsMessage msg; + CHECK(!client.send(msg)); + monitor->wait(); + CHECK(!client.disconnect()); + + CHECK(!server.stop()); + CHECK(!server.unregisterDefaultListener(&serverListener)); + CHECK(!client.unregisterDefaultListener(&listener)); + + // 4. stop while sendReceive is pending in server + CHECK(!server.registerDefaultListener(&serverListener)); + CHECK(!client.registerDefaultListener(&listener)); + + CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1)); + CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+1)); + + CHECK(!client.send(msg)); + monitor->wait(); + CHECK(!server.stop()); + + CHECK(!client.disconnect()); + CHECK(!server.unregisterDefaultListener(&serverListener)); + CHECK(!client.unregisterDefaultListener(&listener)); +} +