TcpTransportFactoryTest.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2006-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #include "Qt.h"
00024 #include "../TcpTransportFactory.h"
00025 #include "../Transport.h"
00026 #include "generated/TcpTransportFactoryDriver.h"
00027 #include "generated/TransportFactoryStatusMock.h"
00028 #include "generated/TransportStatusMock.h"
00029 #include "TcpTester.h"
00030 #include "Imports.cpp"
00031 
00032 namespace Protocols {
00033 namespace Generics {
00034 namespace Testing {
00035 
00036 class TransportCreatedChecker
00037 {
00038     Uri uri_;
00039     TransportStatus *status_;
00040 
00041 public:
00042     static Transport *checkedTransport;
00043 
00044     TransportCreatedChecker (const Uri &uri, TransportStatus *status)
00045     : uri_ (uri), status_ (status) {}
00046 
00047     typedef void (Function) (const Uri &, Transport *);
00048 
00049     bool check (const Uri &uri, Transport *transport)
00050     {
00051         checkedTransport = transport;
00052         checkedTransport->setTransportStatus (status_);
00053         CPPUNIT_ASSERT (uri_ == uri);
00054         CPPUNIT_ASSERT (transport != 0);
00055 /*      CPPUNIT_ASSERT (dynamic_cast <SocketTransport *>
00056                             (transport) != 0);*/
00057         return true;
00058     }
00059 };
00060 
00061 Transport * TransportCreatedChecker::checkedTransport = 0;
00062 
00064 
00071 class TcpTransportFactoryTest : public CppUnit::TestFixture
00072 {
00073     CPPUNIT_TEST_SUITE (TcpTransportFactoryTest);
00074     CPPUNIT_TEST (testCreateTcpTransportForIpFails);
00075     CPPUNIT_TEST (testCreateTcpTransportForIpSucceeds);
00076     CPPUNIT_TEST (testDestroyTcpTransport);
00077     CPPUNIT_TEST (testReadBufferIs40Bytes);
00078     CPPUNIT_TEST (testWriteBufferIs40Bytes);
00079     CPPUNIT_TEST (testReadBufferIs800Bytes);
00080     CPPUNIT_TEST (testWriteBufferIs800Bytes);
00081     CPPUNIT_TEST_SUITE_END();
00082 
00083     auto_ptr <TcpTester>                    tcpTester;
00084     auto_ptr <TransportStatusMock>          transportStatus;
00085     auto_ptr <TransportFactoryStatusMock>   status;
00086     auto_ptr <TcpTransportFactory>          factoryReal;
00087     auto_ptr <TcpTransportFactoryDriver>    factory;
00088 
00089     Uri                                     tcpUri40ByteBuffers;
00090     Uri                                     tcpUri800ByteBuffers;
00091 
00092 public:
00093     void setUp()
00094     {
00095         tcpTester.reset (new TcpTester);
00096         transportStatus.reset (new TransportStatusMock);
00097         status.reset (new TransportFactoryStatusMock);
00098         factoryReal.reset (new TcpTransportFactory);
00099         factory.reset (new TcpTransportFactoryDriver (*factoryReal));
00100 
00101         tcpUri40ByteBuffers = Uri::fromUnencoded (
00102             "tcp://" + tcpTester->connectAddress() + "?rb=40&wb=40");
00103         tcpUri800ByteBuffers = Uri::fromUnencoded (
00104             "tcp://" + tcpTester->connectAddress() + "?rb=800&wb=800");
00105     }
00106 
00107     void tearDown()
00108     {
00109         factory.reset();
00110         factoryReal.reset();
00111         status.reset();
00112         transportStatus.reset();
00113         tcpTester.reset();
00114     }
00115 
00116     void refCreatingTransport (const Uri &uri)
00117     {
00118         call (factory->createTransport (uri, *status))
00119         .returns();
00120     }
00121 
00122     void refWaitForTransportCreationToFail (const Uri &uri)
00123     {
00124         waitFor (10000)
00125             .willCall (status->transportFactoryFailed (uri))
00126             .returns()
00127         .returns();
00128     }
00129 
00130     void testCreateTcpTransportForIpFails()
00131     {
00132         tcpTester->rejectConnections();
00133         refCreatingTransport (tcpUri40ByteBuffers);
00134         refWaitForTransportCreationToFail (tcpUri40ByteBuffers);
00135     }
00136 
00137     void refWaitForTransportCreationToSucceed (const Uri &uri)
00138     {
00139         waitFor (10000)
00140             .willCall (status->transportFactorySucceeded (checker (
00141                             TransportCreatedChecker(uri, *transportStatus))))
00142             .returns()
00143         .returns();
00144     }
00145 
00146     void stateTransportCreated (const Uri &uri)
00147     {
00148         refCreatingTransport (uri);
00149         tcpTester->acceptConnection();
00150         refWaitForTransportCreationToSucceed (uri);
00151     }
00152 
00153     void testCreateTcpTransportForIpSucceeds()
00154     {
00155         stateTransportCreated (tcpUri40ByteBuffers);
00156         // The TcpTransportFactory dtor would delete the created transport
00157         // object, however the caller should explicitly destroy it (see
00158         // testDestroyTcpTransport()).
00159     }
00160 
00161     void testDestroyTcpTransport()
00162     {
00163         testCreateTcpTransportForIpSucceeds();
00164 
00165         call (factory->destroyTransport (
00166                             TransportCreatedChecker::checkedTransport))
00167         .returns();
00168     }
00169 
00170     void refReadBufferSize (Transport *transport, int size)
00171     {
00172         CPPUNIT_ASSERT (transport != 0);
00173 
00174         tcpTester->bytesToWrite = QByteArray (size + 1, '1');
00175         tcpTester->writeBytes();
00176 
00177         // \note \a size is supposed to be small enough, so that it is
00178         // enough to run the event loop until the first notification is sent
00179         // (default waitFor() behavior):
00180         waitFor (2000)
00181             .willCall (transportStatus->transportReadyRead (transport))
00182             .returns()
00183         .returns();
00184 
00185         CPPUNIT_ASSERT (transport->canRead (size) == true);
00186         CPPUNIT_ASSERT (transport->canRead (size + 1) == false);
00187     }
00188 
00189     void refWriteBufferSize (Transport *transport, int size)
00190     {
00191         CPPUNIT_ASSERT (transport != 0);
00192         CPPUNIT_ASSERT (transport->canWrite (size) == true);
00193         CPPUNIT_ASSERT (transport->canWrite (size + 1) == false);
00194     }
00195 
00196     void testReadBufferIs40Bytes()
00197     {
00198         stateTransportCreated (tcpUri40ByteBuffers);
00199         refReadBufferSize (TransportCreatedChecker::checkedTransport, 40);
00200     }
00201 
00202     void testWriteBufferIs40Bytes()
00203     {
00204         stateTransportCreated (tcpUri40ByteBuffers);
00205         refWriteBufferSize (TransportCreatedChecker::checkedTransport, 40);
00206     }
00207 
00208     void testReadBufferIs800Bytes()
00209     {
00210         stateTransportCreated (tcpUri800ByteBuffers);
00211         refReadBufferSize (TransportCreatedChecker::checkedTransport, 800);
00212     }
00213 
00214     void testWriteBufferIs800Bytes()
00215     {
00216         stateTransportCreated (tcpUri800ByteBuffers);
00217         refWriteBufferSize (TransportCreatedChecker::checkedTransport, 800);
00218     }
00219 };
00220 
00221 CPPUNIT_TEST_SUITE_REGISTRATION (TcpTransportFactoryTest);
00222 
00223 } // namespace Testing
00224 } // namespace Generics
00225 } // namespace Protocols