void TestUpdater::updaterIsManaged() { Updater u; u.setLocalRepository(testOutputIsManaged); QVERIFY(u.isManaged(testOutputIsManaged + "/status.json")); QVERIFY(u.isManaged(testOutputIsManaged + "/path_diff.txt")); QVERIFY(u.isManaged(testOutputIsManaged + "/dirs/empty_dir2/")); QVERIFY(u.isManaged(testOutputIsManaged + "/dirs/")); QVERIFY(!u.isManaged(testOutputIsManaged + "/dirs/empty_dir1/")); QVERIFY(!u.isManaged(testOutputIsManaged + "/unmanaged.json")); }
void TestUpdater::updaterCopy() { Updater u; u.setLocalRepository(dataCopy + "/local_repo"); u.copy(testOutputCopy); QSignalSpy spy(&u, SIGNAL(copyFinished(bool))); QVERIFY(spy.wait()); try { (TestUtils::assertFileEquals(dataCopy + "/local_repo/patch_same.txt", testOutputCopy + "/patch_same.txt")); (TestUtils::assertFileEquals(dataCopy + "/local_repo/path_diff.txt", testOutputCopy + "/path_diff.txt")); (TestUtils::assertFileEquals(dataCopy + "/local_repo/path_diff2.txt", testOutputCopy + "/path_diff2.txt")); (TestUtils::assertFileEquals(dataCopy + "/local_repo/rmfile.txt", testOutputCopy + "/rmfile.txt")); } catch(QString &msg) { QFAIL(msg.toLatin1()); } QVERIFY(!QFile::exists(testOutputCopy + "/add.txt")); }
void TestUpdater::updaterRemoveOtherFiles() { Updater u; u.setLocalRepository(testOutputIsManaged); QVERIFY(QFile::exists(testOutputIsManaged + "/status.json")); QVERIFY(QFile::exists(testOutputIsManaged + "/unmanaged.json")); QVERIFY(QDir(testOutputIsManaged + "/dirs/empty_dir1").exists()); u.removeOtherFiles([](QFileInfo file) { return file.fileName() != "unmanaged.json"; }); QVERIFY(QFile::exists(testOutputIsManaged + "/status.json")); QVERIFY(QFile::exists(testOutputIsManaged + "/unmanaged.json")); QVERIFY(!QDir(testOutputIsManaged + "/dirs/empty_dir1").exists()); u.removeOtherFiles(); QVERIFY(QFile::exists(testOutputIsManaged + "/status.json")); QVERIFY(!QFile::exists(testOutputIsManaged + "/unmanaged.json")); QVERIFY(!QDir(testOutputIsManaged + "/dirs/empty_dir1").exists()); }
void TestUpdater::updateToV2() { Updater u; u.setLocalRepository(testOutputUpdate); QCOMPARE(u.localRevision(), QString("1")); u.setTmpDirectory(testOutputUpdateTmp); u.setRemoteRepository("file:///" + dataRepoToV2 + "/"); { QSignalSpy spy(&u, SIGNAL(checkForUpdatesFinished(bool))); u.checkForUpdates(); QVERIFY(spy.wait()); QVERIFY2(u.state() == Updater::UpdateRequired, u.errorString().toLatin1()); } { QSignalSpy spyWarnings(&u, SIGNAL(warning(Warning))); QSignalSpy spy(&u, SIGNAL(updateFinished(bool))); u.update(); QVERIFY(spy.wait()); QCOMPARE(spy.size(), 1); QCOMPARE(spy[0].size(), 1); QCOMPARE(spy[0][0].toBool(), true); QVERIFY2(u.state() == Updater::Uptodate, u.errorString().toLatin1()); QCOMPARE(u.localRevision(), QString("2")); QCOMPARE(spyWarnings.size(), 0); } try{ (TestUtils::assertFileEquals(testOutputUpdate + "/dir2/patch_same.txt", dataDir + "/rev2/dir2/patch_same.txt")); (TestUtils::assertFileEquals(testOutputUpdate + "/path_diff.txt", dataDir + "/rev2/path_diff.txt")); (TestUtils::assertFileEquals(testOutputUpdate + "/path_diff2.txt", dataDir + "/rev2/path_diff2.txt")); (TestUtils::assertFileEquals(testOutputUpdate + "/add.txt", dataDir + "/rev2/add.txt")); (TestUtils::assertFileEquals(testOutputUpdate + "/empty_dir", dataDir + "/rev2/empty_dir")); } catch(std::exception &msg) { QFAIL(msg.what()); } QVERIFY(!QFile::exists(testOutputUpdate + "/rmfile.txt")); QVERIFY(!QFileInfo(testOutputUpdate + "/dirs/empty_dir2").isDir()); QCOMPARE(QDir(testOutputUpdateTmp).entryList(QDir::NoDotAndDotDot).count(), 0); }
int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QCommandLineParser parser; parser.setApplicationDescription(QCoreApplication::tr("manage a local repository (check for updates, update, check integrity)")); parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption checkonly(QStringList() << "c" << "checkonly" , QCoreApplication::tr("Only check for updates.")); QCommandLineOption verbose(QStringList() << "verbose" , QCoreApplication::tr("Run in verbose mode.")); QCommandLineOption force(QStringList() << "f" << "force" , QCoreApplication::tr("Force integrity checks if the local repository is uptodate.")); QCommandLineOption tmpDirectoryPath(QStringList() << "t" << "tmp" , QCoreApplication::tr("Path to use for temporary files.") , "tmp_directory"); parser.addOption(checkonly); parser.addOption(force); parser.addOption(tmpDirectoryPath); parser.addOption(verbose); parser.addPositionalArgument("local_repository", QCoreApplication::tr("Path to the local repository."), "<local_repository>"); parser.addPositionalArgument("remote_repository", QCoreApplication::tr("Path to the remote repository."), "<remote_repository>"); parser.addPositionalArgument("username", QCoreApplication::tr("Username for the remote repository."), "[<username>"); parser.addPositionalArgument("password", QCoreApplication::tr("Password for the remote repository."), "<password>]"); parser.process(app); QLoggingCategory::setFilterRules(QStringLiteral("updatesystem.*.debug=%1").arg(parser.isSet(verbose) ? "true" : "false")); const QStringList args = parser.positionalArguments(); if(args.size() < 1) qWarning() << "Error : local_repository argument is missing"; else if(args.size() < 2) qWarning() << "Error : remote_repository argument is missing"; else if(args.size() > 2 && args.size() < 4) qWarning() << "Error : password argument is missing"; else if(args.size() > 4) qWarning() << "Error : too much arguments"; else { Updater updater; updater.setLocalRepository(args[0]); updater.setRemoteRepository(args[1]); if(parser.isSet(tmpDirectoryPath)) updater.setTmpDirectory(parser.value(tmpDirectoryPath)); if(args.size() == 4) updater.setCredentials(args[2], args[3]); if(parser.isSet(checkonly)) { updater.checkForUpdates(); QEventLoop loop; QObject::connect(&updater, &Updater::checkForUpdatesFinished, &loop, &QEventLoop::quit); loop.exec(); if(!updater.errorString().isEmpty()) { fprintf(stderr, "Failure : %s\n", qPrintable(updater.errorString())); return 2; } if(updater.isUpdateAvailable()) { printf("An update is available\n"); } else { printf("Already up-to-date\n"); } } else { updater.checkForUpdates(); QEventLoop loop; QObject::connect(&updater, &Updater::checkForUpdatesFinished, &loop, &QEventLoop::quit); loop.exec(); printf("Checking for updates...\n"); if(!updater.errorString().isEmpty()) { fprintf(stderr, "Failure : %s\n", qPrintable(updater.errorString())); } else if(updater.isUpdateAvailable() || parser.isSet(force)) { printf("Updating...\n"); printf("Download 0%%, Apply 0%%"); fflush(stdout); updater.update(); QObject::connect(&updater, &Updater::updateFinished, &loop, &QEventLoop::quit); qint64 downloaded = 0, applied = 0; QObject::connect(&updater, &Updater::updateDownloadProgress, [&downloaded, &applied](qint64 bytesReceived, qint64 bytesTotal) { downloaded = (bytesReceived*100)/bytesTotal; printf("\rDownload %3lld%%, Apply %3lld%%", downloaded, applied); fflush(stdout); }); QObject::connect(&updater, &Updater::updateApplyProgress, [&downloaded, &applied](qint64 bytesReceived, qint64 bytesTotal) { applied = (bytesReceived*100)/bytesTotal; printf("\rDownload %3lld%%, Apply %3lld%%", downloaded, applied); fflush(stdout); }); loop.exec(); if(updater.state() != Updater::Uptodate) { fprintf(stderr, "Failure : %s\n", qPrintable(updater.errorString())); return 2; } printf("\nUpdated\n"); } else { printf("Already up-to-date\n"); } } return 0; } parser.showHelp(1); return 1; }