javacommons/comms/tsrc/src/connect.cpp
changeset 21 2a9601315dfc
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  ?Description
       
    15 *
       
    16 */
       
    17 
       
    18 #include <errno.h>
       
    19 #include "monitor.h"
       
    20 #include "TestHarness.h"
       
    21 #include "logger.h"
       
    22 
       
    23 #include "commsserverendpoint.h"
       
    24 #include "commsclientendpoint.h"
       
    25 #include "commsmessage.h"
       
    26 #include "echoserver.h"
       
    27 
       
    28 using namespace java::comms;
       
    29 using java::util::Monitor;
       
    30 
       
    31 TEST_GROUP(Connect)
       
    32 {
       
    33     CommsServerEndpoint comms;
       
    34 
       
    35     TEST_SETUP()
       
    36     {
       
    37         comms.start(IPC_ADDRESS_COMMS_MODULE_TEST);
       
    38     }
       
    39 
       
    40     TEST_TEARDOWN()
       
    41     {
       
    42         comms.stop();
       
    43     }
       
    44 };
       
    45 
       
    46 /**
       
    47  * Test open connection
       
    48  * 1. Normal connect, disconnect
       
    49  * 2. Multiple connect calls without disconnect
       
    50  * 3. Disconnect before connect
       
    51  * 4. Connect to non-existing host
       
    52  */
       
    53 
       
    54 TEST(Connect, OpenConnection)
       
    55 {
       
    56     CommsClientEndpoint client;
       
    57 
       
    58     // 1. Normal connect, disconnect
       
    59     CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
    60     CHECK(!client.disconnect());
       
    61 
       
    62     // 2. Multiple connect calls without disconnect
       
    63     CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
    64     CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
    65     CHECK(!client.disconnect());
       
    66 
       
    67     // 3. Disconnect before connect
       
    68     CHECK(!client.disconnect());
       
    69     CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
    70     CHECK(!client.disconnect());
       
    71 
       
    72     // 4. Connect to non-existing host
       
    73     CHECK(client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+666));
       
    74     CHECK(!client.disconnect());
       
    75 }
       
    76 
       
    77 /**
       
    78  * Test open connection with multiple clients
       
    79  * 1. Normal connect, disconnect
       
    80  * 2. Multiple connect/disconnects
       
    81  */
       
    82 
       
    83 TEST(Connect, MultiClient)
       
    84 {
       
    85     CommsClientEndpoint a, b, c, d, e;
       
    86 
       
    87     // 1. Normal connect, disconnect
       
    88     CHECK(!a.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
    89     CHECK(!b.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
    90     CHECK(!c.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
    91     CHECK(!d.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
    92     CHECK(!e.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
    93     CHECK(!e.disconnect());
       
    94     CHECK(!d.disconnect());
       
    95     CHECK(!c.disconnect());
       
    96     CHECK(!b.disconnect());
       
    97     CHECK(!a.disconnect());
       
    98 
       
    99     // 2. Multiple connect/disconnects
       
   100     for (int i=0; i<10; i++)
       
   101     {
       
   102         CHECK(!a.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
   103         CHECK(!b.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
   104         CHECK(!c.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
   105         CHECK(!d.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
   106         CHECK(!e.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
   107         CHECK(!e.disconnect());
       
   108         CHECK(!d.disconnect());
       
   109         CHECK(!c.disconnect());
       
   110         CHECK(!b.disconnect());
       
   111         CHECK(!a.disconnect());
       
   112     }
       
   113 }
       
   114 
       
   115 /**
       
   116  * Test server cases
       
   117  * 1. Server exits while client is connected
       
   118  * 2. Address is already in use
       
   119  * 3. Start/Connect using different addresses
       
   120  */
       
   121 
       
   122 TEST(Connect, Server)
       
   123 {
       
   124     CommsServerEndpoint server;
       
   125     CommsClientEndpoint client;
       
   126     int ADDR = IPC_ADDRESS_COMMS_MODULE_TEST + 1;
       
   127 
       
   128     // 1. Server exits while client is connected
       
   129     CHECK(!server.start(ADDR));
       
   130     CHECK(!client.connect(ADDR));
       
   131     CHECK(!server.stop());
       
   132     CHECK(!client.disconnect());
       
   133 
       
   134     // 2. Address is already in use
       
   135     CHECK(server.start(IPC_ADDRESS_COMMS_MODULE_TEST)!=0);
       
   136     CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
   137     CHECK(!server.stop());
       
   138     CHECK(!client.disconnect());
       
   139 
       
   140     // 3. Start/Connect using different addresses
       
   141     CHECK(!server.start(ADDR));
       
   142     CHECK(!client.connect(ADDR));
       
   143     CHECK(!client.disconnect());
       
   144     CHECK(!server.stop());
       
   145 
       
   146     CHECK(!server.start(ADDR+1));
       
   147     CHECK(!client.connect(ADDR+1));
       
   148     CHECK(!client.disconnect());
       
   149     CHECK(!server.stop());
       
   150 
       
   151 }
       
   152 
       
   153 /**
       
   154  * Test connect/disconnect from separate threads
       
   155  * 1. connect/disconnect from separate threads
       
   156  * 2. start/stop from separate threads
       
   157  */
       
   158 
       
   159 void doDisconnect(CommsClientEndpoint* aClient)
       
   160 {
       
   161     CHECK(!aClient->disconnect());
       
   162 }
       
   163 void* disconnectThread(void* aComms)
       
   164 {
       
   165     CommsClientEndpoint* client = reinterpret_cast<CommsClientEndpoint*>(aComms);
       
   166     doDisconnect(client);
       
   167     return 0;
       
   168 }
       
   169 
       
   170 void doStop(CommsServerEndpoint* aServer)
       
   171 {
       
   172     CHECK(!aServer->stop());
       
   173 }
       
   174 void* stopThread(void* aComms)
       
   175 {
       
   176     CommsServerEndpoint* server = reinterpret_cast<CommsServerEndpoint*>(aComms);
       
   177     doStop(server);
       
   178     return 0;
       
   179 }
       
   180 
       
   181 TEST(Connect, separateThread)
       
   182 {
       
   183     CommsServerEndpoint server;
       
   184     CommsClientEndpoint client;
       
   185     int ADDR = IPC_ADDRESS_COMMS_MODULE_TEST + 1;
       
   186 
       
   187     CommsMessage msg;
       
   188 
       
   189     // 1. connect/disconnect from separate threads
       
   190     CHECK(!server.start(ADDR));
       
   191     CHECK(!client.connect(ADDR));
       
   192 
       
   193     CHECK(client.send(msg) == 0);
       
   194     pthread_t threadId = 0;
       
   195     pthread_create(&threadId, 0, disconnectThread, &client);
       
   196     pthread_join(threadId, 0);
       
   197     CHECK(client.send(msg) != 0);
       
   198 
       
   199     // 2. start/stop from separate threads
       
   200     pthread_create(&threadId, 0, stopThread, &server);
       
   201     pthread_join(threadId, 0);
       
   202 
       
   203     CommsServerEndpoint server2;
       
   204     CHECK(!server2.start(ADDR));
       
   205     CHECK(!server2.stop());
       
   206 }
       
   207 
       
   208 /**
       
   209  * Check that onStart and onExit callbacks are done
       
   210  * (ensures that ipc provider implementation is done correctly)
       
   211  * 1. Callbacks are done after connect/disconnect
       
   212  * 2. Callbacks are done after start/stop
       
   213  */
       
   214 
       
   215 class OnStartExitClient : public CommsClientEndpoint
       
   216 {
       
   217 public:
       
   218     OnStartExitClient() : mOnStart(false), mOnExit(false) {}
       
   219 
       
   220     virtual void onStart()
       
   221     {
       
   222         mOnStart = true;
       
   223     }
       
   224     virtual void onExit()
       
   225     {
       
   226         mOnExit = true;
       
   227     }
       
   228 
       
   229     bool mOnStart;
       
   230     bool mOnExit;
       
   231 };
       
   232 
       
   233 class OnStartExitServer : public CommsServerEndpoint
       
   234 {
       
   235 public:
       
   236     OnStartExitServer() : mOnStart(false), mOnExit(false) {}
       
   237 
       
   238     virtual void onStart()
       
   239     {
       
   240         mOnStart = true;
       
   241     }
       
   242     virtual void onExit()
       
   243     {
       
   244         mOnExit = true;
       
   245     }
       
   246 
       
   247     bool mOnStart;
       
   248     bool mOnExit;
       
   249 };
       
   250 
       
   251 TEST(Connect, onStartExit)
       
   252 {
       
   253     // 1. Callbacks are done after connect/disconnect
       
   254     OnStartExitClient client;
       
   255     CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
   256     CHECK(!client.disconnect());
       
   257     CHECK(client.mOnStart);
       
   258     CHECK(client.mOnExit);
       
   259 
       
   260     // 2. Callbacks are done after start/stop
       
   261     OnStartExitServer server;
       
   262     CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1));
       
   263     CHECK(!server.stop());
       
   264     CHECK(server.mOnStart);
       
   265     CHECK(server.mOnExit);
       
   266 }
       
   267 
       
   268 
       
   269 /**
       
   270  * Test disconnect/stop while sendReceive is pending
       
   271  * 1. disconnect while sendReceive is pending in client
       
   272  * 2. stop while sendReceive is pending in client
       
   273  * 3. disconnect while sendReceive is pending in server
       
   274  * 4. stop while sendReceive is pending in server
       
   275  */
       
   276 
       
   277 void doSendReceive(CommsEndpoint* aComms)
       
   278 {
       
   279     CommsMessage msg;
       
   280     msg.setModuleId(MODULE_ID_NO_REPLY);
       
   281     CommsMessage receivedMsg;
       
   282 
       
   283     int rc = aComms->sendReceive(msg, receivedMsg, 3);
       
   284     CHECK(rc != 0);
       
   285     CHECK(rc != ETIMEDOUT);
       
   286 
       
   287     // check that next send fails as other party is disconnected
       
   288     // (and receive thread may still be running depending on timing)
       
   289     rc = aComms->send(msg);
       
   290     CHECK(rc != 0);
       
   291 }
       
   292 
       
   293 void* sendReceiveThread(void* aComms)
       
   294 {
       
   295     CommsEndpoint* comms = reinterpret_cast<CommsEndpoint*>(aComms);
       
   296     doSendReceive(comms);
       
   297     return 0;
       
   298 }
       
   299 
       
   300 class Notifier : public CommsListener
       
   301 {
       
   302 public:
       
   303     Notifier(Monitor& aMonitor) : mMonitor(aMonitor) {}
       
   304     virtual void processMessage(CommsMessage&)
       
   305     {
       
   306         mMonitor.notify();
       
   307 
       
   308     }
       
   309 private:
       
   310     Monitor& mMonitor;
       
   311 };
       
   312 
       
   313 struct threadData
       
   314 {
       
   315     CommsEndpoint* comms;
       
   316     int clientAddress;
       
   317 };
       
   318 
       
   319 void doServer(CommsEndpoint* aComms, int aAddress)
       
   320 {
       
   321     CommsMessage msg;
       
   322     msg.setReceiver(aAddress);
       
   323     CommsMessage receivedMsg;
       
   324 
       
   325     int rc = aComms->sendReceive(msg, receivedMsg, 3);
       
   326     CHECK(rc != 0);
       
   327     CHECK(rc != ETIMEDOUT);
       
   328 }
       
   329 
       
   330 void* serverThread(void* aData)
       
   331 {
       
   332     threadData* data = reinterpret_cast<threadData*>(aData);
       
   333     doServer(data->comms, data->clientAddress);
       
   334     delete data;
       
   335     return 0;
       
   336 }
       
   337 
       
   338 class ServerListener : public CommsListener
       
   339 {
       
   340 public:
       
   341     ServerListener(CommsEndpoint& aComms) : mComms(aComms) {}
       
   342     virtual void processMessage(CommsMessage& aMsg)
       
   343     {
       
   344         threadData* data = new threadData;
       
   345         data->comms = &mComms;
       
   346         data->clientAddress = aMsg.getSender();
       
   347         pthread_t threadId = 0;
       
   348         pthread_create(&threadId, 0, serverThread, data);
       
   349     }
       
   350 private:
       
   351     CommsEndpoint& mComms;
       
   352 };
       
   353 
       
   354 TEST(Connect, sendReceivePending)
       
   355 {
       
   356     std::auto_ptr<Monitor> monitor(Monitor::createMonitor());
       
   357 
       
   358     Notifier listener(*monitor);
       
   359     CommsClientEndpoint client;
       
   360 
       
   361     // 1. disconnect while sendReceive is pending in client
       
   362     CHECK(!comms.registerDefaultListener(&listener));
       
   363     CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST));
       
   364 
       
   365     pthread_t threadId = 0;
       
   366     pthread_create(&threadId, 0, sendReceiveThread, &client);
       
   367 
       
   368     monitor->wait();
       
   369     CHECK(!client.disconnect());
       
   370 
       
   371     pthread_join(threadId, 0);
       
   372     CHECK(!comms.unregisterDefaultListener(&listener));
       
   373 
       
   374     // 2. stop while sendReceive is pending in client
       
   375     CommsServerEndpoint server;
       
   376     CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1));
       
   377     CHECK(!server.registerDefaultListener(&listener));
       
   378 
       
   379     CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+1));
       
   380 
       
   381     threadId = 0;
       
   382     pthread_create(&threadId, 0, sendReceiveThread, &client);
       
   383 
       
   384     monitor->wait();
       
   385     CHECK(!server.stop());
       
   386 
       
   387     pthread_join(threadId, 0);
       
   388     CHECK(!client.disconnect());
       
   389     CHECK(!server.unregisterDefaultListener(&listener));
       
   390 
       
   391     // 3. disconnect while sendReceive is pending in server
       
   392     ServerListener serverListener(server);
       
   393 
       
   394     CHECK(!server.registerDefaultListener(&serverListener));
       
   395     CHECK(!client.registerDefaultListener(&listener));
       
   396 
       
   397     CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1));
       
   398     CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+1));
       
   399 
       
   400     CommsMessage msg;
       
   401     CHECK(!client.send(msg));
       
   402     monitor->wait();
       
   403     CHECK(!client.disconnect());
       
   404 
       
   405     CHECK(!server.stop());
       
   406     CHECK(!server.unregisterDefaultListener(&serverListener));
       
   407     CHECK(!client.unregisterDefaultListener(&listener));
       
   408 
       
   409     // 4. stop while sendReceive is pending in server
       
   410     CHECK(!server.registerDefaultListener(&serverListener));
       
   411     CHECK(!client.registerDefaultListener(&listener));
       
   412 
       
   413     CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1));
       
   414     CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+1));
       
   415 
       
   416     CHECK(!client.send(msg));
       
   417     monitor->wait();
       
   418     CHECK(!server.stop());
       
   419 
       
   420     CHECK(!client.disconnect());
       
   421     CHECK(!server.unregisterDefaultListener(&serverListener));
       
   422     CHECK(!client.unregisterDefaultListener(&listener));
       
   423 }
       
   424