mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-27 17:28:41 +00:00
Use a database for mod storage (#11763)
This commit is contained in:
parent
b81948a14c
commit
bf22569019
21 changed files with 798 additions and 127 deletions
|
@ -14,6 +14,7 @@ set (UNITTEST_SRCS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/test_map_settings_manager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_mapnode.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_modchannels.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_modmetadatadatabase.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_nodedef.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_noderesolver.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_noise.cpp
|
||||
|
|
|
@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "gamedef.h"
|
||||
#include "modchannels.h"
|
||||
#include "content/mods.h"
|
||||
#include "database/database-dummy.h"
|
||||
#include "util/numeric.h"
|
||||
#include "porting.h"
|
||||
|
||||
|
@ -55,6 +56,7 @@ public:
|
|||
scene::ISceneManager *getSceneManager() { return m_scenemgr; }
|
||||
IRollbackManager *getRollbackManager() { return m_rollbackmgr; }
|
||||
EmergeManager *getEmergeManager() { return m_emergemgr; }
|
||||
ModMetadataDatabase *getModStorageDatabase() { return m_mod_storage_database; }
|
||||
|
||||
scene::IAnimatedMesh *getMesh(const std::string &filename) { return NULL; }
|
||||
bool checkLocalPrivilege(const std::string &priv) { return false; }
|
||||
|
@ -68,7 +70,6 @@ public:
|
|||
return testmodspec;
|
||||
}
|
||||
virtual const ModSpec* getModSpec(const std::string &modname) const { return NULL; }
|
||||
virtual std::string getModStoragePath() const { return "."; }
|
||||
virtual bool registerModStorage(ModMetadata *meta) { return true; }
|
||||
virtual void unregisterModStorage(const std::string &name) {}
|
||||
bool joinModChannel(const std::string &channel);
|
||||
|
@ -89,11 +90,13 @@ private:
|
|||
scene::ISceneManager *m_scenemgr = nullptr;
|
||||
IRollbackManager *m_rollbackmgr = nullptr;
|
||||
EmergeManager *m_emergemgr = nullptr;
|
||||
ModMetadataDatabase *m_mod_storage_database = nullptr;
|
||||
std::unique_ptr<ModChannelMgr> m_modchannel_mgr;
|
||||
};
|
||||
|
||||
|
||||
TestGameDef::TestGameDef() :
|
||||
m_mod_storage_database(new Database_Dummy()),
|
||||
m_modchannel_mgr(new ModChannelMgr())
|
||||
{
|
||||
m_itemdef = createItemDefManager();
|
||||
|
@ -107,6 +110,7 @@ TestGameDef::~TestGameDef()
|
|||
{
|
||||
delete m_itemdef;
|
||||
delete m_nodedef;
|
||||
delete m_mod_storage_database;
|
||||
}
|
||||
|
||||
|
||||
|
|
253
src/unittest/test_modmetadatadatabase.cpp
Normal file
253
src/unittest/test_modmetadatadatabase.cpp
Normal file
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2018 bendeutsch, Ben Deutsch <ben@bendeutsch.de>
|
||||
Copyright (C) 2021 TurkeyMcMac, Jude Melton-Houghton <jwmhjwmh@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
// This file is an edited copy of test_authdatabase.cpp
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "database/database-files.h"
|
||||
#include "database/database-sqlite3.h"
|
||||
#include "filesys.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// Anonymous namespace to create classes that are only
|
||||
// visible to this file
|
||||
//
|
||||
// These are helpers that return a *ModMetadataDatabase and
|
||||
// allow us to run the same tests on different databases and
|
||||
// database acquisition strategies.
|
||||
|
||||
class ModMetadataDatabaseProvider
|
||||
{
|
||||
public:
|
||||
virtual ~ModMetadataDatabaseProvider() = default;
|
||||
virtual ModMetadataDatabase *getModMetadataDatabase() = 0;
|
||||
};
|
||||
|
||||
class FixedProvider : public ModMetadataDatabaseProvider
|
||||
{
|
||||
public:
|
||||
FixedProvider(ModMetadataDatabase *mod_meta_db) : mod_meta_db(mod_meta_db){};
|
||||
virtual ~FixedProvider(){};
|
||||
virtual ModMetadataDatabase *getModMetadataDatabase() { return mod_meta_db; };
|
||||
|
||||
private:
|
||||
ModMetadataDatabase *mod_meta_db;
|
||||
};
|
||||
|
||||
class FilesProvider : public ModMetadataDatabaseProvider
|
||||
{
|
||||
public:
|
||||
FilesProvider(const std::string &dir) : dir(dir){};
|
||||
virtual ~FilesProvider()
|
||||
{
|
||||
if (mod_meta_db)
|
||||
mod_meta_db->endSave();
|
||||
delete mod_meta_db;
|
||||
}
|
||||
virtual ModMetadataDatabase *getModMetadataDatabase()
|
||||
{
|
||||
if (mod_meta_db)
|
||||
mod_meta_db->endSave();
|
||||
delete mod_meta_db;
|
||||
mod_meta_db = new ModMetadataDatabaseFiles(dir);
|
||||
mod_meta_db->beginSave();
|
||||
return mod_meta_db;
|
||||
};
|
||||
|
||||
private:
|
||||
std::string dir;
|
||||
ModMetadataDatabase *mod_meta_db = nullptr;
|
||||
};
|
||||
|
||||
class SQLite3Provider : public ModMetadataDatabaseProvider
|
||||
{
|
||||
public:
|
||||
SQLite3Provider(const std::string &dir) : dir(dir){};
|
||||
virtual ~SQLite3Provider()
|
||||
{
|
||||
if (mod_meta_db)
|
||||
mod_meta_db->endSave();
|
||||
delete mod_meta_db;
|
||||
}
|
||||
virtual ModMetadataDatabase *getModMetadataDatabase()
|
||||
{
|
||||
if (mod_meta_db)
|
||||
mod_meta_db->endSave();
|
||||
delete mod_meta_db;
|
||||
mod_meta_db = new ModMetadataDatabaseSQLite3(dir);
|
||||
mod_meta_db->beginSave();
|
||||
return mod_meta_db;
|
||||
};
|
||||
|
||||
private:
|
||||
std::string dir;
|
||||
ModMetadataDatabase *mod_meta_db = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
class TestModMetadataDatabase : public TestBase
|
||||
{
|
||||
public:
|
||||
TestModMetadataDatabase() { TestManager::registerTestModule(this); }
|
||||
const char *getName() { return "TestModMetadataDatabase"; }
|
||||
|
||||
void runTests(IGameDef *gamedef);
|
||||
void runTestsForCurrentDB();
|
||||
|
||||
void testRecallFail();
|
||||
void testCreate();
|
||||
void testRecall();
|
||||
void testChange();
|
||||
void testRecallChanged();
|
||||
void testListMods();
|
||||
void testRemove();
|
||||
|
||||
private:
|
||||
ModMetadataDatabaseProvider *mod_meta_provider;
|
||||
};
|
||||
|
||||
static TestModMetadataDatabase g_test_instance;
|
||||
|
||||
void TestModMetadataDatabase::runTests(IGameDef *gamedef)
|
||||
{
|
||||
// fixed directory, for persistence
|
||||
thread_local const std::string test_dir = getTestTempDirectory();
|
||||
|
||||
// Each set of tests is run twice for each database type:
|
||||
// one where we reuse the same ModMetadataDatabase object (to test local caching),
|
||||
// and one where we create a new ModMetadataDatabase object for each call
|
||||
// (to test actual persistence).
|
||||
|
||||
rawstream << "-------- Files database (same object)" << std::endl;
|
||||
|
||||
ModMetadataDatabase *mod_meta_db = new ModMetadataDatabaseFiles(test_dir);
|
||||
mod_meta_provider = new FixedProvider(mod_meta_db);
|
||||
|
||||
runTestsForCurrentDB();
|
||||
|
||||
delete mod_meta_db;
|
||||
delete mod_meta_provider;
|
||||
|
||||
// reset database
|
||||
fs::RecursiveDelete(test_dir + DIR_DELIM + "mod_storage");
|
||||
|
||||
rawstream << "-------- Files database (new objects)" << std::endl;
|
||||
|
||||
mod_meta_provider = new FilesProvider(test_dir);
|
||||
|
||||
runTestsForCurrentDB();
|
||||
|
||||
delete mod_meta_provider;
|
||||
|
||||
rawstream << "-------- SQLite3 database (same object)" << std::endl;
|
||||
|
||||
mod_meta_db = new ModMetadataDatabaseSQLite3(test_dir);
|
||||
mod_meta_provider = new FixedProvider(mod_meta_db);
|
||||
|
||||
runTestsForCurrentDB();
|
||||
|
||||
delete mod_meta_db;
|
||||
delete mod_meta_provider;
|
||||
|
||||
// reset database
|
||||
fs::DeleteSingleFileOrEmptyDirectory(test_dir + DIR_DELIM + "mod_storage.sqlite");
|
||||
|
||||
rawstream << "-------- SQLite3 database (new objects)" << std::endl;
|
||||
|
||||
mod_meta_provider = new SQLite3Provider(test_dir);
|
||||
|
||||
runTestsForCurrentDB();
|
||||
|
||||
delete mod_meta_provider;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TestModMetadataDatabase::runTestsForCurrentDB()
|
||||
{
|
||||
TEST(testRecallFail);
|
||||
TEST(testCreate);
|
||||
TEST(testRecall);
|
||||
TEST(testChange);
|
||||
TEST(testRecallChanged);
|
||||
TEST(testListMods);
|
||||
TEST(testRemove);
|
||||
TEST(testRecallFail);
|
||||
}
|
||||
|
||||
void TestModMetadataDatabase::testRecallFail()
|
||||
{
|
||||
ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
|
||||
StringMap recalled;
|
||||
mod_meta_db->getModEntries("mod1", &recalled);
|
||||
UASSERT(recalled.empty());
|
||||
}
|
||||
|
||||
void TestModMetadataDatabase::testCreate()
|
||||
{
|
||||
ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
|
||||
StringMap recalled;
|
||||
UASSERT(mod_meta_db->setModEntry("mod1", "key1", "value1"));
|
||||
}
|
||||
|
||||
void TestModMetadataDatabase::testRecall()
|
||||
{
|
||||
ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
|
||||
StringMap recalled;
|
||||
mod_meta_db->getModEntries("mod1", &recalled);
|
||||
UASSERT(recalled.size() == 1);
|
||||
UASSERT(recalled["key1"] == "value1");
|
||||
}
|
||||
|
||||
void TestModMetadataDatabase::testChange()
|
||||
{
|
||||
ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
|
||||
StringMap recalled;
|
||||
UASSERT(mod_meta_db->setModEntry("mod1", "key1", "value2"));
|
||||
}
|
||||
|
||||
void TestModMetadataDatabase::testRecallChanged()
|
||||
{
|
||||
ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
|
||||
StringMap recalled;
|
||||
mod_meta_db->getModEntries("mod1", &recalled);
|
||||
UASSERT(recalled.size() == 1);
|
||||
UASSERT(recalled["key1"] == "value2");
|
||||
}
|
||||
|
||||
void TestModMetadataDatabase::testListMods()
|
||||
{
|
||||
ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
|
||||
UASSERT(mod_meta_db->setModEntry("mod2", "key1", "value1"));
|
||||
std::vector<std::string> mod_list;
|
||||
mod_meta_db->listMods(&mod_list);
|
||||
UASSERT(mod_list.size() == 2);
|
||||
UASSERT(std::find(mod_list.cbegin(), mod_list.cend(), "mod1") != mod_list.cend());
|
||||
UASSERT(std::find(mod_list.cbegin(), mod_list.cend(), "mod2") != mod_list.cend());
|
||||
}
|
||||
|
||||
void TestModMetadataDatabase::testRemove()
|
||||
{
|
||||
ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
|
||||
UASSERT(mod_meta_db->removeModEntry("mod1", "key1"));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue