testchecksumvalidator.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*
  2. * This software is in the public domain, furnished "as is", without technical
  3. * support, and with no warranty, express or implied, as to its usefulness for
  4. * any purpose.
  5. *
  6. */
  7. #include <QtTest>
  8. #include <QDir>
  9. #include <QString>
  10. #include "common/checksums.h"
  11. #include "networkjobs.h"
  12. #include "common/utility.h"
  13. #include "filesystem.h"
  14. #include "propagatorjobs.h"
  15. using namespace OCC;
  16. using namespace OCC::Utility;
  17. class TestChecksumValidator : public QObject
  18. {
  19. Q_OBJECT
  20. private:
  21. QTemporaryDir _root;
  22. QString _testfile;
  23. QString _expectedError;
  24. ValidateChecksumHeader::FailureReason _expectedFailureReason = ValidateChecksumHeader::FailureReason::Success;
  25. QByteArray _expected;
  26. QByteArray _expectedType;
  27. bool _successDown;
  28. bool _errorSeen;
  29. public slots:
  30. void slotUpValidated(const QByteArray& type, const QByteArray& checksum) {
  31. qDebug() << "Checksum: " << checksum;
  32. QVERIFY(_expected == checksum );
  33. QVERIFY(_expectedType == type );
  34. }
  35. void slotDownValidated() {
  36. _successDown = true;
  37. }
  38. void slotDownError(const QString &errMsg, ValidateChecksumHeader::FailureReason reason)
  39. {
  40. QCOMPARE(_expectedError, errMsg);
  41. QCOMPARE(_expectedFailureReason, reason);
  42. _errorSeen = true;
  43. }
  44. static QByteArray shellSum( const QByteArray& cmd, const QString& file )
  45. {
  46. QProcess md5;
  47. QStringList args;
  48. args.append(file);
  49. md5.start(cmd, args);
  50. QByteArray sumShell;
  51. qDebug() << "File: "<< file;
  52. if( md5.waitForFinished() ) {
  53. sumShell = md5.readAll();
  54. sumShell = sumShell.left( sumShell.indexOf(' '));
  55. }
  56. return sumShell;
  57. }
  58. private slots:
  59. void initTestCase() {
  60. _testfile = _root.path()+"/csFile";
  61. Utility::writeRandomFile( _testfile);
  62. }
  63. void testMd5Calc()
  64. {
  65. QString file( _root.path() + "/file_a.bin");
  66. QVERIFY(writeRandomFile(file));
  67. QFileInfo fi(file);
  68. QVERIFY(fi.exists());
  69. QFile fileDevice(file);
  70. fileDevice.open(QIODevice::ReadOnly);
  71. QByteArray sum = calcMd5(&fileDevice);
  72. fileDevice.close();
  73. QByteArray sSum = shellSum("md5sum", file);
  74. if (sSum.isEmpty())
  75. QSKIP("Couldn't execute md5sum to calculate checksum, executable missing?", SkipSingle);
  76. QVERIFY(!sum.isEmpty());
  77. QCOMPARE(sSum, sum);
  78. }
  79. void testSha1Calc()
  80. {
  81. QString file( _root.path() + "/file_b.bin");
  82. writeRandomFile(file);
  83. QFileInfo fi(file);
  84. QVERIFY(fi.exists());
  85. QFile fileDevice(file);
  86. fileDevice.open(QIODevice::ReadOnly);
  87. QByteArray sum = calcSha1(&fileDevice);
  88. fileDevice.close();
  89. QByteArray sSum = shellSum("sha1sum", file);
  90. if (sSum.isEmpty())
  91. QSKIP("Couldn't execute sha1sum to calculate checksum, executable missing?", SkipSingle);
  92. QVERIFY(!sum.isEmpty());
  93. QCOMPARE(sSum, sum);
  94. }
  95. void testUploadChecksummingAdler() {
  96. #ifndef ZLIB_FOUND
  97. QSKIP("ZLIB not found.", SkipSingle);
  98. #else
  99. auto *vali = new ComputeChecksum(this);
  100. _expectedType = "Adler32";
  101. vali->setChecksumType(_expectedType);
  102. connect(vali, SIGNAL(done(QByteArray,QByteArray)), SLOT(slotUpValidated(QByteArray,QByteArray)));
  103. auto file = new QFile(_testfile, vali);
  104. file->open(QIODevice::ReadOnly);
  105. _expected = calcAdler32(file);
  106. qDebug() << "XX Expected Checksum: " << _expected;
  107. vali->start(_testfile);
  108. QEventLoop loop;
  109. connect(vali, SIGNAL(done(QByteArray,QByteArray)), &loop, SLOT(quit()), Qt::QueuedConnection);
  110. loop.exec();
  111. delete vali;
  112. #endif
  113. }
  114. void testUploadChecksummingMd5() {
  115. auto *vali = new ComputeChecksum(this);
  116. _expectedType = OCC::checkSumMD5C;
  117. vali->setChecksumType(_expectedType);
  118. connect(vali, SIGNAL(done(QByteArray,QByteArray)), this, SLOT(slotUpValidated(QByteArray,QByteArray)));
  119. auto file = new QFile(_testfile, vali);
  120. file->open(QIODevice::ReadOnly);
  121. _expected = calcMd5(file);
  122. vali->start(_testfile);
  123. QEventLoop loop;
  124. connect(vali, SIGNAL(done(QByteArray,QByteArray)), &loop, SLOT(quit()), Qt::QueuedConnection);
  125. loop.exec();
  126. delete vali;
  127. }
  128. void testUploadChecksummingSha1() {
  129. auto *vali = new ComputeChecksum(this);
  130. _expectedType = OCC::checkSumSHA1C;
  131. vali->setChecksumType(_expectedType);
  132. connect(vali, SIGNAL(done(QByteArray,QByteArray)), this, SLOT(slotUpValidated(QByteArray,QByteArray)));
  133. auto file = new QFile(_testfile, vali);
  134. file->open(QIODevice::ReadOnly);
  135. _expected = calcSha1(file);
  136. vali->start(_testfile);
  137. QEventLoop loop;
  138. connect(vali, SIGNAL(done(QByteArray,QByteArray)), &loop, SLOT(quit()), Qt::QueuedConnection);
  139. loop.exec();
  140. delete vali;
  141. }
  142. void testDownloadChecksummingAdler() {
  143. #ifndef ZLIB_FOUND
  144. QSKIP("ZLIB not found.", SkipSingle);
  145. #else
  146. auto *vali = new ValidateChecksumHeader(this);
  147. connect(vali, &ValidateChecksumHeader::validated, this, &TestChecksumValidator::slotDownValidated);
  148. connect(vali, &ValidateChecksumHeader::validationFailed, this, &TestChecksumValidator::slotDownError);
  149. auto file = new QFile(_testfile, vali);
  150. file->open(QIODevice::ReadOnly);
  151. _expected = calcAdler32(file);
  152. QByteArray adler = checkSumAdlerC;
  153. adler.append(":");
  154. adler.append(_expected);
  155. file->seek(0);
  156. _successDown = false;
  157. vali->start(_testfile, adler);
  158. QTRY_VERIFY(_successDown);
  159. _expectedError = QStringLiteral("The downloaded file does not match the checksum, it will be resumed. \"543345\" != \"%1\"").arg(QString::fromUtf8(_expected));
  160. _expectedFailureReason = ValidateChecksumHeader::FailureReason::ChecksumMismatch;
  161. _errorSeen = false;
  162. file->seek(0);
  163. vali->start(_testfile, "Adler32:543345");
  164. QTRY_VERIFY(_errorSeen);
  165. _expectedError = QLatin1String("The checksum header contained an unknown checksum type \"Klaas32\"");
  166. _expectedFailureReason = ValidateChecksumHeader::FailureReason::ChecksumTypeUnknown;
  167. _errorSeen = false;
  168. file->seek(0);
  169. vali->start(_testfile, "Klaas32:543345");
  170. QTRY_VERIFY(_errorSeen);
  171. delete vali;
  172. #endif
  173. }
  174. void cleanupTestCase() {
  175. }
  176. };
  177. QTEST_GUILESS_MAIN(TestChecksumValidator)
  178. #include "testchecksumvalidator.moc"