File indexing completed on 2025-01-05 04:37:32
0001 /* 0002 SPDX-FileCopyrightText: 2009 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <QObject> 0008 #include <QtTest> 0009 #include <util/log.h> 0010 #include <utp/localwindow.h> 0011 #include <utp/utpprotocol.h> 0012 0013 using namespace utp; 0014 using namespace bt; 0015 0016 class LocalWindowTest : public QObject 0017 { 0018 Q_OBJECT 0019 public: 0020 private Q_SLOTS: 0021 void initTestCase() 0022 { 0023 bt::InitLog("localwindowtest.log"); 0024 } 0025 0026 void testSeqNr() 0027 { 0028 Out(SYS_UTP | LOG_DEBUG) << "testSeqNr" << endl; 0029 QVERIFY(SeqNrCmpSE(4, 8)); 0030 QVERIFY(SeqNrCmpSE(4, 4)); 0031 QVERIFY(!SeqNrCmpSE(4, 2)); 0032 0033 QVERIFY(SeqNrCmpS(4, 8)); 0034 QVERIFY(!SeqNrCmpS(4, 4)); 0035 QVERIFY(!SeqNrCmpS(4, 2)); 0036 0037 QVERIFY(!SeqNrCmpSE(1, 65000)); 0038 QVERIFY(SeqNrCmpSE(65000, 1)); 0039 QVERIFY(!SeqNrCmpS(1, 65000)); 0040 QVERIFY(SeqNrCmpS(65000, 1)); 0041 0042 QVERIFY(SeqNrDiff(65535, 0) == 1); 0043 QVERIFY(SeqNrDiff(0, 65535) == 1); 0044 QVERIFY(SeqNrDiff(65535, 6) == 7); 0045 QVERIFY(SeqNrDiff(6, 65535) == 7); 0046 QVERIFY(SeqNrDiff(65530, 5) == 11); 0047 QVERIFY(SeqNrDiff(5, 65530) == 11); 0048 } 0049 0050 void testLocalWindow() 0051 { 0052 Out(SYS_UTP | LOG_DEBUG) << "testLocalWindow" << endl; 0053 bt::BufferPool pool; 0054 bt::Uint8 wdata[1000]; 0055 memset(wdata, 0, 1000); 0056 0057 utp::Header hdr; 0058 utp::LocalWindow wnd(1000); 0059 wnd.setLastSeqNr(1); 0060 0061 // write 500 bytes to it 0062 hdr.seq_nr = 2; 0063 QVERIFY(wnd.packetReceived(&hdr, pool.get(500), 0) == true); 0064 QVERIFY(wnd.availableSpace() == 500); 0065 QVERIFY(wnd.currentWindow() == 500); 0066 0067 // write another 100 to it 0068 hdr.seq_nr++; 0069 QVERIFY(wnd.packetReceived(&hdr, pool.get(100), 0) == true); 0070 QVERIFY(wnd.availableSpace() == 400); 0071 QVERIFY(wnd.currentWindow() == 600); 0072 0073 // read 300 from it 0074 QVERIFY(wnd.read(wdata, 300) == 300); 0075 QVERIFY(wnd.availableSpace() == 700); 0076 QVERIFY(wnd.currentWindow() == 300); 0077 } 0078 0079 void testPacketLoss() 0080 { 0081 Out(SYS_UTP | LOG_DEBUG) << "testPacketLoss" << endl; 0082 bt::BufferPool pool; 0083 bt::Uint8 wdata[1000]; 0084 0085 utp::Header hdr; 0086 utp::LocalWindow wnd(1000); 0087 wnd.setLastSeqNr(1); 0088 0089 // write 500 bytes to it 0090 hdr.seq_nr = 2; 0091 QVERIFY(wnd.packetReceived(&hdr, pool.get(500), 0) == true); 0092 QVERIFY(wnd.availableSpace() == 500); 0093 QVERIFY(wnd.currentWindow() == 500); 0094 0095 // write 100 bytes to it bit with the wrong sequence number 0096 hdr.seq_nr = 4; 0097 QVERIFY(wnd.packetReceived(&hdr, pool.get(100), 0) == true); 0098 QVERIFY(wnd.availableSpace() == 400); 0099 QVERIFY(wnd.currentWindow() == 600); 0100 QVERIFY(wnd.bytesAvailable() == 500); 0101 0102 // Try to read all of it, but we should only get back 500 0103 QVERIFY(wnd.read(wdata, 600) == 500); 0104 QVERIFY(wnd.availableSpace() == 900); 0105 QVERIFY(wnd.currentWindow() == 100); 0106 QVERIFY(wnd.bytesAvailable() == 0); 0107 0108 // write the missing packet 0109 hdr.seq_nr = 3; 0110 QVERIFY(wnd.packetReceived(&hdr, pool.get(100), 0) == true); 0111 QVERIFY(wnd.availableSpace() == 800); 0112 QVERIFY(wnd.currentWindow() == 200); 0113 QVERIFY(wnd.bytesAvailable() == 200); 0114 } 0115 0116 void testPacketLoss2() 0117 { 0118 Out(SYS_UTP | LOG_DEBUG) << "testPacketLoss2" << endl; 0119 bt::Uint8 wdata[1000]; 0120 memset(wdata, 0, 1000); 0121 0122 bt::BufferPool pool; 0123 0124 utp::Header hdr; 0125 utp::LocalWindow wnd(1000); 0126 wnd.setLastSeqNr(0); 0127 0128 // first write first and last packet 0129 bt::Uint32 step = 200; 0130 hdr.seq_nr = 1; 0131 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0132 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - step); 0133 QVERIFY(wnd.currentWindow() == step); 0134 hdr.seq_nr = 5; 0135 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0136 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 2 * step); 0137 QVERIFY(wnd.currentWindow() == 2 * step); 0138 QVERIFY(wnd.bytesAvailable() == step); 0139 0140 // Now write 4 0141 hdr.seq_nr = 4; 0142 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0143 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 3 * step); 0144 QVERIFY(wnd.currentWindow() == 3 * step); 0145 QVERIFY(wnd.bytesAvailable() == step); 0146 0147 // And then 3 0148 hdr.seq_nr = 3; 0149 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0150 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 4 * step); 0151 QVERIFY(wnd.currentWindow() == 4 * step); 0152 QVERIFY(wnd.bytesAvailable() == step); 0153 0154 // And then 2 0155 hdr.seq_nr = 2; 0156 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0157 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 5 * step); 0158 QVERIFY(wnd.currentWindow() == 5 * step); 0159 QVERIFY(wnd.bytesAvailable() == 5 * step); 0160 } 0161 0162 void testToMuchData() 0163 { 0164 Out(SYS_UTP | LOG_DEBUG) << "testToMuchData" << endl; 0165 bt::BufferPool pool; 0166 bt::Uint8 wdata[1000]; 0167 memset(wdata, 0, 1000); 0168 0169 utp::Header hdr; 0170 utp::LocalWindow wnd(500); 0171 wnd.setLastSeqNr(1); 0172 0173 // write 500 bytes to it 0174 hdr.seq_nr = 2; 0175 QVERIFY(wnd.packetReceived(&hdr, pool.get(500), 0) == true); 0176 QVERIFY(wnd.availableSpace() == 0); 0177 QVERIFY(wnd.currentWindow() == 500); 0178 0179 // writing more data should now have no effect at all 0180 hdr.seq_nr = 3; 0181 QVERIFY(wnd.packetReceived(&hdr, pool.get(500), 0) == false); 0182 QVERIFY(wnd.availableSpace() == 0); 0183 QVERIFY(wnd.currentWindow() == 500); 0184 } 0185 0186 void testSelectiveAck() 0187 { 0188 Out(SYS_UTP | LOG_DEBUG) << "testSelectiveAck" << endl; 0189 bt::BufferPool pool; 0190 bt::Uint8 wdata[1000]; 0191 memset(wdata, 0, 1000); 0192 0193 utp::Header hdr; 0194 utp::LocalWindow wnd(1000); 0195 wnd.setLastSeqNr(0); 0196 0197 // first write first and last packet 0198 bt::Uint32 step = 200; 0199 hdr.seq_nr = 1; 0200 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0201 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - step); 0202 QVERIFY(wnd.currentWindow() == step); 0203 hdr.seq_nr = 5; 0204 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0205 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 2 * step); 0206 QVERIFY(wnd.currentWindow() == 2 * step); 0207 QVERIFY(wnd.bytesAvailable() == step); 0208 0209 // Check SelectiveAck generation 0210 QVERIFY(wnd.selectiveAckBits() == 3); 0211 bt::Uint8 sack_data[6]; 0212 SelectiveAck sack; 0213 sack.length = 4; 0214 sack.extension = 0; 0215 sack.bitmask = sack_data + 2; 0216 wnd.fillSelectiveAck(&sack); 0217 QVERIFY(sack_data[2] == 0x4); 0218 QVERIFY(sack_data[3] == 0x0); 0219 QVERIFY(sack_data[4] == 0x0); 0220 QVERIFY(sack_data[5] == 0x0); 0221 0222 // Now write 4 0223 hdr.seq_nr = 4; 0224 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0225 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 3 * step); 0226 QVERIFY(wnd.currentWindow() == 3 * step); 0227 QVERIFY(wnd.bytesAvailable() == step); 0228 0229 // Check selective ack again 0230 QVERIFY(wnd.selectiveAckBits() == 3); 0231 sack.length = 4; 0232 sack.extension = 0; 0233 wnd.fillSelectiveAck(&sack); 0234 QVERIFY(sack_data[2] == 0x6); 0235 QVERIFY(sack_data[3] == 0x0); 0236 QVERIFY(sack_data[4] == 0x0); 0237 QVERIFY(sack_data[5] == 0x0); 0238 0239 // Now write 3 0240 hdr.seq_nr = 3; 0241 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0242 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 4 * step); 0243 QVERIFY(wnd.currentWindow() == 4 * step); 0244 QVERIFY(wnd.bytesAvailable() == step); 0245 0246 // Check selective ack again 0247 QVERIFY(wnd.selectiveAckBits() == 3); 0248 sack.length = 4; 0249 sack.extension = 0; 0250 wnd.fillSelectiveAck(&sack); 0251 QVERIFY(sack_data[2] == 0x7); 0252 QVERIFY(sack_data[3] == 0x0); 0253 QVERIFY(sack_data[4] == 0x0); 0254 QVERIFY(sack_data[5] == 0x0); 0255 0256 // And then 2 0257 hdr.seq_nr = 2; 0258 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0259 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 5 * step); 0260 QVERIFY(wnd.currentWindow() == 5 * step); 0261 QVERIFY(wnd.bytesAvailable() == 5 * step); 0262 // selective ack should now be unnecessary 0263 QVERIFY(wnd.selectiveAckBits() == 0); 0264 } 0265 0266 void testSeqNrWrapAround() 0267 { 0268 Out(SYS_UTP | LOG_DEBUG) << "testSeqNrWrapAround" << endl; 0269 bt::BufferPool pool; 0270 bt::Uint8 wdata[1000]; 0271 memset(wdata, 0, 1000); 0272 0273 utp::Header hdr; 0274 utp::LocalWindow wnd(1000); 0275 wnd.setLastSeqNr(65535); 0276 0277 // write 500 bytes to it 0278 hdr.seq_nr = 0; 0279 QVERIFY(wnd.packetReceived(&hdr, pool.get(500), 0) == true); 0280 QVERIFY(wnd.availableSpace() == 500); 0281 QVERIFY(wnd.currentWindow() == 500); 0282 0283 // write another 100 to it 0284 hdr.seq_nr++; 0285 QVERIFY(wnd.packetReceived(&hdr, pool.get(100), 0) == true); 0286 QVERIFY(wnd.availableSpace() == 400); 0287 QVERIFY(wnd.currentWindow() == 600); 0288 0289 // read 300 from it 0290 QVERIFY(wnd.read(wdata, 300) == 300); 0291 QVERIFY(wnd.availableSpace() == 700); 0292 QVERIFY(wnd.currentWindow() == 300); 0293 } 0294 0295 void testSeqNrWrapAroundSelectiveAck() 0296 { 0297 Out(SYS_UTP | LOG_DEBUG) << "testSeqNrWrapAroundSelectiveAck" << endl; 0298 bt::BufferPool pool; 0299 bt::Uint8 wdata[1000]; 0300 memset(wdata, 0, 1000); 0301 0302 utp::Header hdr; 0303 utp::LocalWindow wnd(1000); 0304 wnd.setLastSeqNr(65535); 0305 0306 // first write first and last packet 0307 bt::Uint32 step = 200; 0308 hdr.seq_nr = 0; 0309 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0310 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - step); 0311 QVERIFY(wnd.currentWindow() == step); 0312 hdr.seq_nr = 4; 0313 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0314 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 2 * step); 0315 QVERIFY(wnd.currentWindow() == 2 * step); 0316 QVERIFY(wnd.bytesAvailable() == step); 0317 0318 // Check SelectiveAck generation 0319 QVERIFY(wnd.selectiveAckBits() == 3); 0320 bt::Uint8 sack_data[6]; 0321 SelectiveAck sack; 0322 sack.length = 4; 0323 sack.extension = 0; 0324 sack.bitmask = sack_data + 2; 0325 wnd.fillSelectiveAck(&sack); 0326 QVERIFY(sack_data[2] == 0x4); 0327 QVERIFY(sack_data[3] == 0x0); 0328 QVERIFY(sack_data[4] == 0x0); 0329 QVERIFY(sack_data[5] == 0x0); 0330 0331 // Now write 4 0332 hdr.seq_nr = 3; 0333 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0334 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 3 * step); 0335 QVERIFY(wnd.currentWindow() == 3 * step); 0336 QVERIFY(wnd.bytesAvailable() == step); 0337 0338 // Check selective ack again 0339 QVERIFY(wnd.selectiveAckBits() == 3); 0340 sack.length = 4; 0341 sack.extension = 0; 0342 wnd.fillSelectiveAck(&sack); 0343 QVERIFY(sack_data[2] == 0x6); 0344 QVERIFY(sack_data[3] == 0x0); 0345 QVERIFY(sack_data[4] == 0x0); 0346 QVERIFY(sack_data[5] == 0x0); 0347 0348 // Now write 3 0349 hdr.seq_nr = 2; 0350 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0351 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 4 * step); 0352 QVERIFY(wnd.currentWindow() == 4 * step); 0353 QVERIFY(wnd.bytesAvailable() == step); 0354 0355 // Check selective ack again 0356 QVERIFY(wnd.selectiveAckBits() == 3); 0357 sack.length = 4; 0358 sack.extension = 0; 0359 wnd.fillSelectiveAck(&sack); 0360 QVERIFY(sack_data[2] == 0x7); 0361 QVERIFY(sack_data[3] == 0x0); 0362 QVERIFY(sack_data[4] == 0x0); 0363 QVERIFY(sack_data[5] == 0x0); 0364 0365 // And then 2 0366 hdr.seq_nr = 1; 0367 QVERIFY(wnd.packetReceived(&hdr, pool.get(step), 0) == true); 0368 QVERIFY(wnd.availableSpace() == wnd.windowCapacity() - 5 * step); 0369 QVERIFY(wnd.currentWindow() == 5 * step); 0370 QVERIFY(wnd.bytesAvailable() == 5 * step); 0371 // selective ack should now be unnecessary 0372 QVERIFY(wnd.selectiveAckBits() == 0); 0373 } 0374 0375 private: 0376 // bt::Uint8 data[13]; 0377 // bt::Uint8 data2[6]; 0378 }; 0379 0380 QTEST_MAIN(LocalWindowTest) 0381 0382 #include "localwindowtest.moc"