File indexing completed on 2025-01-05 03:58:03

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-06-21
0007  * Description : unit test to switch digiKam database from sqlite to mysql
0008  *
0009  * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "databaseswitch_utest.h"
0016 
0017 // Qt includes
0018 
0019 #include <QApplication>
0020 #include <QFileInfo>
0021 #include <QSqlDatabase>
0022 #include <QTimer>
0023 #include <QCommandLineParser>
0024 
0025 // KDE includes
0026 
0027 #include <kaboutdata.h>
0028 
0029 // Local includes
0030 
0031 #include "digikam_debug.h"
0032 #include "daboutdata.h"
0033 #include "albummanager.h"
0034 #include "coredbaccess.h"
0035 #include "thumbsdbaccess.h"
0036 #include "facedbaccess.h"
0037 #include "similaritydbaccess.h"
0038 #include "dbengineparameters.h"
0039 #include "scancontroller.h"
0040 #include "digikam_version.h"
0041 #include "dtestdatadir.h"
0042 #include "wstoolutils.h"
0043 #include "mysqlupgradebinary.h"
0044 #include "mysqlserverbinary.h"
0045 #include "mysqladminbinary.h"
0046 #include "mysqlinitbinary.h"
0047 #include "databaseserverstarter.h"
0048 
0049 using namespace Digikam;
0050 
0051 QTEST_MAIN(DatabaseSwitchTest)
0052 
0053 void DatabaseSwitchTest::cleanupTestCase()
0054 {
0055     WSToolUtils::removeTemporaryDir(m_db1Path.toLatin1().data());
0056     WSToolUtils::removeTemporaryDir(m_db2Path.toLatin1().data());
0057 }
0058 
0059 void DatabaseSwitchTest::initTestCase()
0060 {
0061     m_db1Path   = QString::fromLatin1(QTest::currentAppName());
0062     m_db1Path.replace(QLatin1String("./"), QString());
0063     m_db1Dir    = WSToolUtils::makeTemporaryDir(m_db1Path.toLatin1().data());
0064     qCDebug(DIGIKAM_TESTS_LOG) << "Database Dir Source:" << m_db1Dir.path();
0065 
0066     m_db2Path   = QString::fromLatin1(QTest::currentAppName());
0067     m_db2Path.replace(QLatin1String("./"), QString());
0068     m_db2Dir    = WSToolUtils::makeTemporaryDir(m_db2Path.toLatin1().data());
0069     qCDebug(DIGIKAM_TESTS_LOG) << "Database Dir Target:" << m_db2Dir.path();
0070 
0071     m_filesPath = DTestDataDir::TestData(QString::fromUtf8("core/tests/database/testimages"))
0072                            .root().path() + QLatin1Char('/');
0073     qCDebug(DIGIKAM_TESTS_LOG) << "Test Images Dir:" << m_filesPath;
0074 
0075     m_sqlitePath = DTestDataDir::TestData(QString::fromUtf8("core/tests/database/testimages-sqlite"))
0076                            .root().path() + QLatin1Char('/');
0077     qCDebug(DIGIKAM_TESTS_LOG) << "Test Sqlite Dir:" << m_sqlitePath;
0078 
0079     KAboutData aboutData(QLatin1String("digikam"),
0080                          QLatin1String("digiKam"), // No need i18n here.
0081                          digiKamVersion());
0082 
0083     QCommandLineParser parser;
0084     KAboutData::setApplicationData(aboutData);
0085     parser.addVersionOption();
0086     parser.addHelpOption();
0087     aboutData.setupCommandLine(&parser);
0088     parser.process(*QCoreApplication::instance());
0089     aboutData.processCommandLine(&parser);
0090 }
0091 
0092 void DatabaseSwitchTest::startStopSqlite(const QDir& dbDir)
0093 {
0094     qCDebug(DIGIKAM_TESTS_LOG) << "Setup Sqlite Database...";
0095 
0096     if (!QSqlDatabase::isDriverAvailable(DbEngineParameters::SQLiteDatabaseType()))
0097     {
0098         QWARN("Qt SQlite plugin is missing.");
0099         return;
0100     }
0101 
0102     DbEngineParameters params;
0103     params.databaseType = DbEngineParameters::SQLiteDatabaseType();
0104     params.setCoreDatabasePath(dbDir.path() + QLatin1String("/digikam-core-test.db"));
0105     params.setThumbsDatabasePath(dbDir.path() + QLatin1String("/digikam-thumbs-test.db"));
0106     params.setFaceDatabasePath(dbDir.path() + QLatin1String("/digikam-faces-test.db"));
0107     params.setSimilarityDatabasePath(dbDir.path() + QLatin1String("/digikam-similarity-test.db"));
0108     params.legacyAndDefaultChecks();
0109 
0110     // ------------------------------------------------------------------------------------
0111 
0112     qCDebug(DIGIKAM_TESTS_LOG) << "Initializing SQlite database...";
0113     QVERIFY2(AlbumManager::instance()->setDatabase(params, false, m_filesPath),
0114              "Cannot initialize Sqlite database");
0115 
0116     QTest::qWait(3000);
0117 
0118     qCDebug(DIGIKAM_TESTS_LOG) << "Shutting down SQlite database";
0119     ScanController::instance()->shutDown();
0120     AlbumManager::instance()->cleanUp();
0121 
0122     qCDebug(DIGIKAM_TESTS_LOG) << "Cleaning Sqlite database";
0123     CoreDbAccess::cleanUpDatabase();
0124     ThumbsDbAccess::cleanUpDatabase();
0125     FaceDbAccess::cleanUpDatabase();
0126 }
0127 
0128 void DatabaseSwitchTest::startStopMysql(const QDir& dbDir)
0129 {
0130     qCDebug(DIGIKAM_TESTS_LOG) << "Setup Mysql Database...";
0131 
0132     MysqlUpgradeBinary mysqlUpgradeBin;
0133 
0134     if (!mysqlUpgradeBin.recheckDirectories())
0135     {
0136         QWARN("Not able to found the Mysql Upgrade binary program. Test is aborted...");
0137         return;
0138     }
0139 
0140     MysqlServerBinary  mysqlServerBin;
0141     mysqlServerBin.slotAddPossibleSearchDirectory(QLatin1String("/usr/sbin"));
0142 
0143     if (!mysqlServerBin.recheckDirectories())
0144     {
0145         QWARN("Not able to found the Mysql Server binary program. Test is aborted...");
0146         return;
0147     }
0148 
0149     MysqlAdminBinary   mysqlAdminBin;
0150 
0151     if (!mysqlAdminBin.recheckDirectories())
0152     {
0153         QWARN("Not able to found the Mysql Admin binary program. Test is aborted...");
0154         return;
0155     }
0156 
0157     MysqlInitBinary    mysqlInitBin;
0158 
0159     if (!mysqlInitBin.recheckDirectories())
0160     {
0161         QWARN("Not able to found the Mysql Init binary program. Test is aborted...");
0162         return;
0163     }
0164 
0165     if (!QSqlDatabase::isDriverAvailable(DbEngineParameters::MySQLDatabaseType()))
0166     {
0167         QWARN("Qt MySQL plugin is missing.");
0168         return;
0169     }
0170 
0171     DbEngineParameters params;
0172     QString defaultAkDir                 = DbEngineParameters::serverPrivatePath();
0173     QString miscDir                      = QDir(defaultAkDir).absoluteFilePath(QLatin1String("db_misc"));
0174     params.databaseType                  = DbEngineParameters::MySQLDatabaseType();
0175     params.databaseNameCore              = QLatin1String("digikam");
0176     params.databaseNameThumbnails        = QLatin1String("digikam");
0177     params.databaseNameFace              = QLatin1String("digikam");
0178     params.databaseNameSimilarity        = QLatin1String("digikam");
0179     params.userName                      = QLatin1String("root");
0180     params.password                      = QString();
0181     params.internalServer                = true;
0182     params.internalServerDBPath          = dbDir.path();
0183     params.internalServerMysqlUpgradeCmd = mysqlUpgradeBin.path();
0184     params.internalServerMysqlServerCmd  = mysqlServerBin.path();
0185     params.internalServerMysqlAdminCmd   = mysqlAdminBin.path();
0186     params.internalServerMysqlInitCmd    = mysqlInitBin.path();
0187     params.hostName                      = QString();
0188     params.port                          = -1;
0189     params.connectOptions                = QString::fromLatin1("UNIX_SOCKET=%1/mysql.socket").arg(miscDir);
0190 
0191     // ------------------------------------------------------------------------------------
0192 
0193     qCDebug(DIGIKAM_TESTS_LOG) << "Initializing Mysql database...";
0194     QVERIFY2(AlbumManager::instance()->setDatabase(params, false, m_filesPath),
0195              "Cannot initialize Mysql database");
0196 
0197     QTest::qWait(3000);
0198 
0199     qCDebug(DIGIKAM_TESTS_LOG) << "Shutting down Mysql database";
0200     ScanController::instance()->shutDown();
0201 
0202     qCDebug(DIGIKAM_TESTS_LOG) << "Cleaning Mysql database";
0203 
0204     CoreDbAccess::cleanUpDatabase();
0205     ThumbsDbAccess::cleanUpDatabase();
0206     FaceDbAccess::cleanUpDatabase();
0207     SimilarityDbAccess::cleanUpDatabase();
0208 
0209     DatabaseServerStarter::instance()->stopServerManagerProcess();
0210 }
0211 
0212 void DatabaseSwitchTest::testFromSqliteToMysql()
0213 {
0214     // TODO: Not implemented.
0215 }
0216 
0217 void DatabaseSwitchTest::testFromMysqlToSqlite()
0218 {
0219     startStopMysql(m_db1Dir);
0220 
0221     QTest::qWait(3000);
0222 
0223     // ---
0224 
0225     qCDebug(DIGIKAM_TESTS_LOG) << "Copy Sqlite database files to a temporary dir...";
0226 
0227     QDir sqliteDir(m_sqlitePath);
0228     sqliteDir.setFilter(QDir::Files | QDir::NoSymLinks);
0229 
0230     QFileInfoList list = sqliteDir.entryInfoList();
0231 
0232     for (int i = 0 ; i < list.size() ; ++i)
0233     {
0234         QString path = m_db2Dir.filePath(list.at(i).fileName().trimmed());
0235 
0236         QFile file(list.at(i).filePath());
0237         QVERIFY2(file.copy(path),
0238                  QString::fromLatin1("Cannot copy sqlite file %1 to %2")
0239                     .arg(file.fileName())
0240                     .arg(path)
0241                  .toLatin1().constData());
0242     }
0243 
0244     // ---
0245 
0246     DbEngineParameters params;
0247     params.databaseType = DbEngineParameters::SQLiteDatabaseType();
0248     params.setCoreDatabasePath(m_db2Dir.path() + QLatin1String("/digikam-core-test.db"));
0249     params.setThumbsDatabasePath(m_db2Dir.path() + QLatin1String("/digikam-thumbs-test.db"));
0250     params.setFaceDatabasePath(m_db2Dir.path() + QLatin1String("/digikam-faces-test.db"));
0251     params.setSimilarityDatabasePath(m_db2Dir.path() + QLatin1String("/digikam-similarity-test.db"));
0252     params.legacyAndDefaultChecks();
0253 
0254     qCDebug(DIGIKAM_TESTS_LOG) << "Initializing Sqlite database and switch...";
0255     AlbumManager::instance()->changeDatabase(params);
0256     qCDebug(DIGIKAM_TESTS_LOG) << "Database switch done";
0257 
0258     QTest::qWait(3000);
0259 
0260     qCDebug(DIGIKAM_TESTS_LOG) << "Shutting down Sqlite database";
0261     ScanController::instance()->shutDown();
0262     AlbumManager::instance()->cleanUp();
0263 
0264     qCDebug(DIGIKAM_TESTS_LOG) << "Cleaning Sqlite database";
0265     CoreDbAccess::cleanUpDatabase();
0266     ThumbsDbAccess::cleanUpDatabase();
0267     FaceDbAccess::cleanUpDatabase();
0268     SimilarityDbAccess::cleanUpDatabase();
0269 }
0270 
0271 #include "moc_databaseswitch_utest.cpp"