DataSerializerTest.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Qt.h"
00024 #include "../DataSerializer.h"
00025 #include "../BodyEnd.h"
00026 #include "generated/BodyReaderMock.h"
00027 #include "generated/BodyWriterMock.h"
00028 #include "generated/DataSerializerDriver.h"
00029 #include "generated/ProtocolMock.h"
00030 #include "Imports.cpp"
00031
00032 namespace Protocols {
00033 namespace Http {
00034 namespace Testing {
00035
00037
00073 class DataSerializerTest : public CppUnit::TestFixture
00074 {
00075 CPPUNIT_TEST_SUITE (DataSerializerTest);
00076 CPPUNIT_TEST (testReadHeaderFails);
00077 CPPUNIT_TEST (testReadHeader);
00078 CPPUNIT_TEST (testReadHeaderLfLfTerminated);
00079 CPPUNIT_TEST (testReadBodyOfOneChunk);
00080 CPPUNIT_TEST (testReadTwoMessages);
00081 CPPUNIT_TEST (testReadMessageWithInterrupts);
00082 CPPUNIT_TEST (testWriteHeaderFails);
00083 CPPUNIT_TEST (testWriteHeaderOK);
00084 CPPUNIT_TEST (testWriteBodyOfOneChunk);
00085 CPPUNIT_TEST (testWriteBodyOfMultipleChunksWithDelays);
00086 CPPUNIT_TEST (writeTwoMessages);
00087 CPPUNIT_TEST_SUITE_END();
00088
00089 auto_ptr <TransportMock> transport;
00090 auto_ptr <ProtocolMock> protocol;
00091 auto_ptr <BodyReaderMock> bodyReader;
00092 auto_ptr <BodyWriterMock> bodyWriter;
00093 auto_ptr <DataSerializer> serializerReal;
00094 auto_ptr <DataSerializerDriver> serializer;
00095
00096 HeaderBase header;
00097 BodyEnd bodyEnd;
00098 QList <Data> chunks;
00099
00100 public:
00101 void setUp()
00102 {
00103 transport.reset (new TransportMock);
00104 protocol.reset (new ProtocolMock);
00105 bodyReader.reset (new BodyReaderMock);
00106 bodyWriter.reset (new BodyWriterMock);
00107 serializerReal.reset (new DataSerializer (*protocol));
00108 serializer.reset (new DataSerializerDriver (*serializerReal));
00109
00110 header = HeaderBase();
00111 header.setFieldValue ("Transfer-Encoding", "identity");
00112 header.setFieldValue ("Content-Length", "10");
00113 bodyEnd = BodyEnd();
00114 bodyEnd.setFieldValue ("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ==");
00115 chunks = QList <Data>();
00116 }
00117
00118 void tearDown()
00119 {
00120 serializer.reset();
00121 serializerReal.reset();
00122 bodyWriter.reset();
00123 bodyReader.reset();
00124 protocol.reset();
00125 transport.reset();
00126 }
00127
00129
00134 void refReadHeaderFails()
00135 {
00136 Data readHeader;
00137 call (serializer->read (readHeader, *transport))
00138 .willCall (transport->readTo ("\r\n\r\n"))
00139 .willReturn (QByteArray())
00140 .willCall (transport->readTo ("\n\n"))
00141 .willReturn (QByteArray())
00142 .willReturn (false);
00143
00144 willBeEqual (readHeader, Data());
00145 }
00146
00148 void refReadHeaderOK (const Header &header)
00149 {
00150 Data readHeader;
00151 call (serializer->read (readHeader, *transport))
00152 .willCall (transport->readTo ("\r\n\r\n"))
00153 .willReturn (header->toRawBytes())
00154 .willCall (protocol->createHeader (header->toRawBytes()))
00155 .willReturn (header)
00156 .willCall (protocol->createBodyReader (header))
00157 .willReturn (*bodyReader)
00158 .willReturn (true);
00159
00160 willBeEqual (readHeader, Data (header));
00161 }
00162
00164 void refReadLfTerminatedHeaderOK (const Header &header)
00165 {
00166 QByteArray rawHeader = header->toRawBytes().replace ("\r\n", "\n");
00167 Data readHeader;
00168 call (serializer->read (readHeader, *transport))
00169 .willCall (transport->readTo ("\r\n\r\n"))
00170 .willReturn (QByteArray())
00171 .willCall (transport->readTo ("\n\n"))
00172 .willReturn (rawHeader)
00173 .willCall (protocol->createHeader (rawHeader))
00174 .willReturn (header)
00175 .willCall (protocol->createBodyReader (header))
00176 .willReturn (*bodyReader)
00177 .willReturn (true);
00178
00179 willBeEqual (readHeader, Data (header));
00180 }
00181
00183 void refReadBodyChunk (const Data &chunk)
00184 {
00185 Data readBodyChunk;
00186 call (serializer->read (readBodyChunk, *transport))
00187 .willCall (bodyReader->read (*transport))
00188 .willReturn (chunk)
00189 .willReturn (true);
00190
00191 willBeEqual (chunk, readBodyChunk);
00192 }
00193
00195 void refReadBodyChunkFails()
00196 {
00197 Data readBodyChunk;
00198 call (serializer->read (readBodyChunk, *transport))
00199 .willCall (bodyReader->read (*transport))
00200 .willReturn (Data())
00201 .willReturn (false);
00202
00203 willBeEqual (Data(), readBodyChunk);
00204 }
00205
00207 void refReadBodyEnd()
00208 {
00209 Data readBodyChunk;
00210 call (serializer->read (readBodyChunk, *transport))
00211 .willCall (bodyReader->read (*transport))
00212 .willReturn (bodyEnd)
00213 .willCall (protocol->destroyBodyReader (*bodyReader))
00214 .returns()
00215 .willReturn (true);
00216
00217 willBeEqual (Data (bodyEnd), readBodyChunk);
00218 }
00219
00220 void stateReadingHeader()
00221 {
00222 refReadHeaderFails();
00223 }
00224
00225 void stateReadingBody (const Header &header)
00226 {
00227 refReadHeaderOK (header);
00228 }
00229
00230 void postStateReadingHeader()
00231 {
00232 refReadHeaderFails();
00233 }
00234
00235 void postStateReadingBody()
00236 {
00237 refReadBodyChunkFails();
00238 }
00239
00241 void scenarioReadHeaderFails()
00242 {
00243 stateReadingHeader();
00244 refReadHeaderFails();
00245 postStateReadingHeader();
00246 }
00247
00249 void scenarioReadHeaderOK (const Header &header, bool lfTerminated = false)
00250 {
00251 stateReadingHeader();
00252 if (!lfTerminated)
00253 refReadHeaderOK (header);
00254 else
00255 refReadLfTerminatedHeaderOK (header);
00256 postStateReadingBody();
00257 }
00258
00260 void scenarioReadBody (const Header &header,
00261 const QList <Data> &bodyChunks)
00262 {
00263 stateReadingBody (header);
00264
00265 foreach (Data bodyChunk, bodyChunks) {
00266 if (bodyChunk != Data())
00267 refReadBodyChunk (bodyChunk);
00268 else
00269 refReadBodyChunkFails();
00270 }
00271 refReadBodyEnd();
00272
00273 postStateReadingHeader();
00274 }
00275
00276 void testReadHeaderFails()
00277 {
00278 scenarioReadHeaderFails();
00279 }
00280
00281 void testReadHeader()
00282 {
00283 scenarioReadHeaderOK (header);
00284 }
00285
00286 void testReadHeaderLfLfTerminated()
00287 {
00288 scenarioReadHeaderOK (header, true);
00289 }
00290
00291 void testReadBodyOfOneChunk()
00292 {
00293 chunks += RawData (QByteArray (40, '1'));
00294 scenarioReadBody (header, chunks);
00295 }
00296
00297 void testReadTwoMessages()
00298 {
00299 testReadBodyOfOneChunk();
00300 testReadBodyOfOneChunk();
00301 }
00302
00303 void testReadMessageWithInterrupts()
00304 {
00305 chunks += RawData (QByteArray (40, '1'));
00306 chunks += Data();
00307 chunks += RawData (QByteArray (10, '2'));
00308 scenarioReadBody (header, chunks);
00309 }
00310
00312 void refWriteHeaderSucceeds (const Header &header)
00313 {
00314 call (serializer->write (header, *transport))
00315 .willCall (transport->write (header->toRawBytes()))
00316 .willReturn (true)
00317 .willCall (protocol->createBodyWriter (header))
00318 .willReturn (*bodyWriter)
00319 .willReturn (true);
00320 }
00321
00323 void refWriteHeaderFails (const Header &header)
00324 {
00325 call (serializer->write (header, *transport))
00326 .willCall (transport->write (header->toRawBytes()))
00327 .willReturn (false)
00328 .willReturn (false);
00329 }
00330
00332 void refWriteBodyChunk (const Data &chunk, bool willSucceed)
00333 {
00334 call (serializer->write (chunk, *transport))
00335 .willCall (bodyWriter->write (chunk, *transport))
00336 .willReturn (willSucceed)
00337 .willReturn (willSucceed);
00338 }
00339
00340 void stateWritingHeader()
00341 {
00342 refWriteHeaderFails (Header());
00343 }
00344
00345 void stateWritingBody (const Header &header)
00346 {
00347 refWriteHeaderSucceeds (header);
00348 }
00349
00350 void postStateWritingHeader()
00351 {
00352 refWriteHeaderFails (Header());
00353 }
00354
00355 void postStateWritingBody()
00356 {
00357 refWriteBodyChunk (RawData(), true);
00358 }
00359
00361
00366 void scenarioWriteHeaderFails (const Header &header)
00367 {
00368 stateWritingHeader();
00369 refWriteHeaderFails (header);
00370 postStateWritingHeader();
00371 }
00372
00374
00379 void scenarioWriteHeaderOK (const Header &header)
00380 {
00381 stateWritingHeader();
00382 refWriteHeaderSucceeds (header);
00383 postStateWritingBody();
00384 }
00385
00387
00397 void scenarioWriteBody (const Header &header, const QList <Data> &chunks)
00398 {
00399 stateWritingBody (header);
00400
00401 foreach (Data chunk, chunks) {
00402 refWriteBodyChunk (chunk, false);
00403 refWriteBodyChunk (chunk, true);
00404 }
00405 refWriteBodyChunk (bodyEnd, false);
00406 call (serializer->write (bodyEnd, *transport))
00407 .willCall (bodyWriter->write (bodyEnd, *transport))
00408 .willReturn (true)
00409 .willCall (protocol->destroyBodyWriter (*bodyWriter))
00410 .returns()
00411 .willReturn (true);
00412
00413 postStateWritingHeader();
00414 }
00415
00416 void testWriteHeaderFails()
00417 {
00418 scenarioWriteHeaderFails (header);
00419 }
00420
00421 void testWriteHeaderOK()
00422 {
00423 scenarioWriteHeaderOK (header);
00424 }
00425
00426 void testWriteBodyOfOneChunk()
00427 {
00428 chunks += RawData (QByteArray (20, '2'));
00429 scenarioWriteBody (header, chunks);
00430 }
00431
00432 void testWriteBodyOfMultipleChunksWithDelays()
00433 {
00434 chunks += RawData (QByteArray (20, '1'));
00435 chunks += Data();
00436 chunks += RawData (QByteArray (20, '3'));
00437 scenarioWriteBody (header, chunks);
00438 }
00439
00440 void writeTwoMessages()
00441 {
00442 testWriteBodyOfMultipleChunksWithDelays();
00443 testWriteBodyOfMultipleChunksWithDelays();
00444 }
00445 };
00446
00447 CPPUNIT_TEST_SUITE_REGISTRATION (DataSerializerTest);
00448
00449 }
00450 }
00451 }