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 "PacketStub.h" 00025 #include "Imports.cpp" 00026 00027 namespace Protocols { 00028 namespace Generics { 00029 namespace Testing { 00030 00032 00086 class PacketTest : public CppUnit::TestFixture 00087 { 00088 CPPUNIT_TEST_SUITE (PacketTest); 00089 CPPUNIT_TEST (testReadPacket); 00090 CPPUNIT_TEST (testWritePacket); 00091 CPPUNIT_TEST (testReferenceCountIncreaseCopyPacket); 00092 CPPUNIT_TEST (testReferenceCountIncreaseAssignPacket); 00093 CPPUNIT_TEST (testReferenceCountDecreaseAssignPacket); 00094 CPPUNIT_TEST (testReferenceCountDecreaseDestroyPacket); 00095 CPPUNIT_TEST (testReferenceCountDecreaseModifyPacketCopyPrivateData); 00096 CPPUNIT_TEST (testCtorNoRawDataCached); 00097 CPPUNIT_TEST (testParseRawDataCached); 00098 CPPUNIT_TEST (testInvalidateHeader); 00099 CPPUNIT_TEST (testInvalidatePayload); 00100 CPPUNIT_TEST (testRawHeaderUsingCachedHeader); 00101 CPPUNIT_TEST (testRawHeaderRebuildingAndCachingHeader); 00102 CPPUNIT_TEST (testRawPayloadUsingCachedPayload); 00103 CPPUNIT_TEST (testRawPayloadRebuildingAndCachingPayload); 00104 CPPUNIT_TEST (testRebuildPacketNotModifyingReferenceCount); 00105 CPPUNIT_TEST_SUITE_END(); 00106 00107 public: 00109 void testReadPacket() 00110 { 00111 PacketStub packet; 00112 CPPUNIT_ASSERT (packet.parse ("myHeader", "myPayload")); 00113 CPPUNIT_ASSERT ("myHeader" == packet.header()); 00114 CPPUNIT_ASSERT ("myPayload" == packet.payload()); 00115 00116 /* That's how I wish I were able to write the WHITEBOX version of it: 00117 packet->parse (rawHeader, rawPayload, rawTrailer) 00118 .willReturn (true); 00119 packet->rawHeader() 00120 .willNotCall (packet->writeHeader()) 00121 .willReturn (rawHeader); 00122 packet->rawPayload() 00123 .willNotCall (packet->writePayload()) 00124 .willReturn (rawPayload); 00125 */ 00126 } 00127 00129 void testWritePacket() 00130 { 00131 PacketStub packet ("rawHeader", "rawPayload"); 00132 CPPUNIT_ASSERT ("rawHeader" == packet.rawHeader()); 00133 CPPUNIT_ASSERT ("rawPayload" == packet.rawPayload()); 00134 } 00135 00137 void testReferenceCountIncreaseCopyPacket() 00138 { 00139 PacketStub packet1; 00140 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 1); 00141 PacketStub packet2 (packet1); 00142 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 2); 00143 // Make sure the private data is indeed the same: 00144 CPPUNIT_ASSERT (packet1.d_ptr.constData() == packet2.d_ptr.constData()); 00145 } 00146 00148 void testReferenceCountIncreaseAssignPacket() 00149 { 00150 PacketStub packet1; 00151 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 1); 00152 PacketStub packet2; 00153 CPPUNIT_ASSERT (packet2.d_ptr.constData()->ref == 1); 00154 // Do the assignment: 00155 packet2 = packet1; 00156 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 2); 00157 // Make sure the private data is indeed the same: 00158 CPPUNIT_ASSERT (packet1.d_ptr.constData() == packet2.d_ptr.constData()); 00159 } 00160 00162 void testReferenceCountDecreaseAssignPacket() 00163 { 00164 PacketStub packet1, packet2, packet3; 00165 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 1); 00166 CPPUNIT_ASSERT (packet2.d_ptr.constData()->ref == 1); 00167 CPPUNIT_ASSERT (packet3.d_ptr.constData()->ref == 1); 00168 packet3 = packet1; 00169 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 2); 00170 CPPUNIT_ASSERT (packet2.d_ptr.constData()->ref == 1); 00171 CPPUNIT_ASSERT (packet3.d_ptr.constData()->ref == 2); 00172 packet3 = packet2; 00173 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 1); 00174 CPPUNIT_ASSERT (packet2.d_ptr.constData()->ref == 2); 00175 CPPUNIT_ASSERT (packet3.d_ptr.constData()->ref == 2); 00176 packet3 = PacketStub(); 00177 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 1); 00178 CPPUNIT_ASSERT (packet2.d_ptr.constData()->ref == 1); 00179 CPPUNIT_ASSERT (packet3.d_ptr.constData()->ref == 1); 00180 } 00181 00183 void testReferenceCountDecreaseDestroyPacket() 00184 { 00185 PacketStub packet1; 00186 { 00187 PacketStub packet2 (packet1); 00188 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 2); 00189 } 00190 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 1); 00191 } 00192 00194 void testReferenceCountDecreaseModifyPacketCopyPrivateData() 00195 { 00196 PacketStub packet1; 00197 PacketStub packet2 (packet1); 00198 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 2); 00199 CPPUNIT_ASSERT (packet1.d_ptr.constData() == packet2.d_ptr.constData()); 00200 packet2.invalidateHeader(); // is called by setter for header fields 00201 CPPUNIT_ASSERT (packet1.d_ptr.constData()->ref == 1); 00202 CPPUNIT_ASSERT (packet1.d_ptr.constData() != packet2.d_ptr.constData()); 00203 } 00204 00206 void testCtorNoRawDataCached() 00207 { 00208 PacketStub packet; 00209 CPPUNIT_ASSERT (true == packet.PacketBase::d_func()->rewriteHeader); 00210 CPPUNIT_ASSERT (true == packet.PacketBase::d_func()->rewritePayload); 00211 } 00212 00214 00220 void testParseRawDataCached() 00221 { 00222 PacketStub packet; 00223 CPPUNIT_ASSERT (packet.parse ("myHeader", "myPayload")); 00224 // Check rewrite* flags: 00225 CPPUNIT_ASSERT (false == packet.PacketBase::d_func()->rewriteHeader); 00226 CPPUNIT_ASSERT (false == packet.PacketBase::d_func()->rewritePayload); 00227 // Check the cached bytes are correct: 00228 CPPUNIT_ASSERT ("myHeader" == packet.rawHeader()); 00229 CPPUNIT_ASSERT ("myPayload" == packet.rawPayload()); 00230 } 00231 00233 void testInvalidateHeader() 00234 { 00235 PacketStub packet; 00236 packet.PacketBase::d_func()->rewriteHeader = false; 00237 packet.invalidateHeader(); 00238 CPPUNIT_ASSERT (true == packet.PacketBase::d_func()->rewriteHeader); 00239 } 00240 00242 void testInvalidatePayload() 00243 { 00244 PacketStub packet; 00245 packet.PacketBase::d_func()->rewritePayload = false; 00246 packet.invalidatePayload(); 00247 CPPUNIT_ASSERT (true == packet.PacketBase::d_func()->rewritePayload); 00248 } 00249 00251 void testRawHeaderUsingCachedHeader() 00252 { 00253 PacketStub packet ("rawHeader"); 00254 CPPUNIT_ASSERT (packet.rawHeader() == "rawHeader"); 00255 // Set internal state to have cached "blah" for header raw bytes: 00256 packet.PacketBase::d_func()->rewriteHeader = false; 00257 packet.PacketBase::d_func()->rawHeader = "blah"; 00258 // Verify that the new cached bytes are returned: 00259 CPPUNIT_ASSERT (packet.rawHeader() == "blah"); 00260 } 00261 00263 void testRawHeaderRebuildingAndCachingHeader() 00264 { 00265 PacketStub packet ("rawHeader"); 00266 CPPUNIT_ASSERT (packet.PacketBase::d_func()->rewriteHeader == true); 00267 CPPUNIT_ASSERT (packet.PacketBase::d_func()->rawHeader == QByteArray()); 00268 CPPUNIT_ASSERT (packet.rawHeader() == "rawHeader"); 00269 CPPUNIT_ASSERT (packet.PacketBase::d_func()->rewriteHeader == false); 00270 CPPUNIT_ASSERT (packet.PacketBase::d_func()->rawHeader == "rawHeader"); 00271 } 00272 00274 void testRawPayloadUsingCachedPayload() 00275 { 00276 PacketStub packet ("", "rawPayload"); 00277 CPPUNIT_ASSERT (packet.rawPayload() == "rawPayload"); 00278 // Set internal state to have cached "blah" for payload raw bytes: 00279 packet.PacketBase::d_func()->rewritePayload = false; 00280 packet.PacketBase::d_func()->rawPayload = "blah"; 00281 // Verify that the new cached bytes are returned: 00282 CPPUNIT_ASSERT (packet.rawPayload() == "blah"); 00283 } 00284 00286 void testRawPayloadRebuildingAndCachingPayload() 00287 { 00288 PacketStub packet ("", "rawPayload"); 00289 CPPUNIT_ASSERT (packet.PacketBase::d_func()->rewritePayload == true); 00290 CPPUNIT_ASSERT (packet.PacketBase::d_func()->rawPayload == QByteArray()); 00291 CPPUNIT_ASSERT (packet.rawPayload() == "rawPayload"); 00292 CPPUNIT_ASSERT (packet.PacketBase::d_func()->rewritePayload == false); 00293 CPPUNIT_ASSERT (packet.PacketBase::d_func()->rawPayload == "rawPayload"); 00294 } 00295 00310 void testRebuildPacketNotModifyingReferenceCount() 00311 { 00312 // Construct a packet that does not cache raw bytes: 00313 PacketStub packet1 ("rawHeader", "rawPayload"); 00314 CPPUNIT_ASSERT (packet1.PacketBase::d_func()->rewriteHeader == true); 00315 CPPUNIT_ASSERT (packet1.PacketBase::d_func()->rewritePayload == true); 00316 // Copy the packet and verify that both share the same private data: 00317 PacketStub packet2 (packet1); 00318 CPPUNIT_ASSERT (packet1.d_ptr.constData() == packet2.d_ptr.constData()); 00319 // Force packet1 to be rebuilt and verify private data is still shared: 00320 // Header first: 00321 CPPUNIT_ASSERT (packet1.rawHeader() == "rawHeader"); 00322 CPPUNIT_ASSERT (packet1.d_ptr.constData() == packet2.d_ptr.constData()); 00323 CPPUNIT_ASSERT (packet2.rawHeader() == "rawHeader"); 00324 // Payload next: 00325 CPPUNIT_ASSERT (packet1.rawPayload() == "rawPayload"); 00326 CPPUNIT_ASSERT (packet1.d_ptr.constData() == packet2.d_ptr.constData()); 00327 CPPUNIT_ASSERT (packet2.rawPayload() == "rawPayload"); 00328 } 00329 }; 00330 00331 CPPUNIT_TEST_SUITE_REGISTRATION(PacketTest); 00332 00333 } // namespace Testing 00334 } // namespace Generics 00335 } // namespace Protocols