Cleanup sound manager class (#7158)
[oweals/minetest.git] / src / unittest / test.cpp
index 6fea0b8a02c1936b12bc9167a3efa96bf18adfa3..18215a94749558164d1ce262d0a3526c84ef8bfe 100644 (file)
@@ -19,15 +19,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "test.h"
 
-#include "debug.h"
-#include "log.h"
+#include "client/sound.h"
 #include "nodedef.h"
 #include "itemdef.h"
 #include "gamedef.h"
+#include "modchannels.h"
+#include "mods.h"
+#include "util/numeric.h"
 
-content_t CONTENT_STONE;
-content_t CONTENT_GRASS;
-content_t CONTENT_TORCH;
+content_t t_CONTENT_STONE;
+content_t t_CONTENT_GRASS;
+content_t t_CONTENT_TORCH;
+content_t t_CONTENT_WATER;
+content_t t_CONTENT_LAVA;
+content_t t_CONTENT_BRICK;
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -41,7 +46,7 @@ public:
        ~TestGameDef();
 
        IItemDefManager *getItemDefManager() { return m_itemdef; }
-       INodeDefManager *getNodeDefManager() { return m_nodedef; }
+       const NodeDefManager *getNodeDefManager() { return m_nodedef; }
        ICraftDefManager *getCraftDefManager() { return m_craftdef; }
        ITextureSource *getTextureSource() { return m_texturesrc; }
        IShaderSource *getShaderSource() { return m_shadersrc; }
@@ -57,21 +62,40 @@ public:
 
        void defineSomeNodes();
 
+       virtual const std::vector<ModSpec> &getMods() const
+       {
+               static std::vector<ModSpec> testmodspec;
+               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);
+       bool leaveModChannel(const std::string &channel);
+       bool sendModChannelMessage(const std::string &channel, const std::string &message);
+       ModChannel *getModChannel(const std::string &channel)
+       {
+               return m_modchannel_mgr->getModChannel(channel);
+       }
+
 private:
-       IItemDefManager *m_itemdef;
-       INodeDefManager *m_nodedef;
-       ICraftDefManager *m_craftdef;
-       ITextureSource *m_texturesrc;
-       IShaderSource *m_shadersrc;
-       ISoundManager *m_soundmgr;
-       MtEventManager *m_eventmgr;
-       scene::ISceneManager *m_scenemgr;
-       IRollbackManager *m_rollbackmgr;
-       EmergeManager *m_emergemgr;
+       IItemDefManager *m_itemdef = nullptr;
+       const NodeDefManager *m_nodedef = nullptr;
+       ICraftDefManager *m_craftdef = nullptr;
+       ITextureSource *m_texturesrc = nullptr;
+       IShaderSource *m_shadersrc = nullptr;
+       ISoundManager *m_soundmgr = nullptr;
+       MtEventManager *m_eventmgr = nullptr;
+       scene::ISceneManager *m_scenemgr = nullptr;
+       IRollbackManager *m_rollbackmgr = nullptr;
+       EmergeManager *m_emergemgr = nullptr;
+       std::unique_ptr<ModChannelMgr> m_modchannel_mgr;
 };
 
 
-TestGameDef::TestGameDef()
+TestGameDef::TestGameDef() :
+       m_modchannel_mgr(new ModChannelMgr())
 {
        m_itemdef = createItemDefManager();
        m_nodedef = createNodeDefManager();
@@ -90,7 +114,7 @@ TestGameDef::~TestGameDef()
 void TestGameDef::defineSomeNodes()
 {
        IWritableItemDefManager *idef = (IWritableItemDefManager *)m_itemdef;
-       IWritableNodeDefManager *ndef = (IWritableNodeDefManager *)m_nodedef;
+       NodeDefManager *ndef = (NodeDefManager *)m_nodedef;
 
        ItemDefinition itemdef;
        ContentFeatures f;
@@ -107,11 +131,11 @@ void TestGameDef::defineSomeNodes()
                "{default_stone.png";
        f = ContentFeatures();
        f.name = itemdef.name;
-       for(int i = 0; i < 6; i++)
-               f.tiledef[i].name = "default_stone.png";
+       for (TileDef &tiledef : f.tiledef)
+               tiledef.name = "default_stone.png";
        f.is_ground_content = true;
        idef->registerItem(itemdef);
-       CONTENT_STONE = ndef->set(f.name, f);
+       t_CONTENT_STONE = ndef->set(f.name, f);
 
        //// Grass
        itemdef = ItemDefinition();
@@ -131,7 +155,7 @@ void TestGameDef::defineSomeNodes()
                f.tiledef[i].name = "default_dirt.png^default_grass_side.png";
        f.is_ground_content = true;
        idef->registerItem(itemdef);
-       CONTENT_GRASS = ndef->set(f.name, f);
+       t_CONTENT_GRASS = ndef->set(f.name, f);
 
        //// Torch (minimal definition for lighting tests)
        itemdef = ItemDefinition();
@@ -144,21 +168,100 @@ void TestGameDef::defineSomeNodes()
        f.sunlight_propagates = true;
        f.light_source = LIGHT_MAX-1;
        idef->registerItem(itemdef);
-       CONTENT_TORCH = ndef->set(f.name, f);
+       t_CONTENT_TORCH = ndef->set(f.name, f);
+
+       //// Water
+       itemdef = ItemDefinition();
+       itemdef.type = ITEM_NODE;
+       itemdef.name = "default:water";
+       itemdef.description = "Water";
+       itemdef.inventory_image = "[inventorycube"
+               "{default_water.png"
+               "{default_water.png"
+               "{default_water.png";
+       f = ContentFeatures();
+       f.name = itemdef.name;
+       f.alpha = 128;
+       f.liquid_type = LIQUID_SOURCE;
+       f.liquid_viscosity = 4;
+       f.is_ground_content = true;
+       f.groups["liquids"] = 3;
+       for (TileDef &tiledef : f.tiledef)
+               tiledef.name = "default_water.png";
+       idef->registerItem(itemdef);
+       t_CONTENT_WATER = ndef->set(f.name, f);
+
+       //// Lava
+       itemdef = ItemDefinition();
+       itemdef.type = ITEM_NODE;
+       itemdef.name = "default:lava";
+       itemdef.description = "Lava";
+       itemdef.inventory_image = "[inventorycube"
+               "{default_lava.png"
+               "{default_lava.png"
+               "{default_lava.png";
+       f = ContentFeatures();
+       f.name = itemdef.name;
+       f.alpha = 128;
+       f.liquid_type = LIQUID_SOURCE;
+       f.liquid_viscosity = 7;
+       f.light_source = LIGHT_MAX-1;
+       f.is_ground_content = true;
+       f.groups["liquids"] = 3;
+       for (TileDef &tiledef : f.tiledef)
+               tiledef.name = "default_lava.png";
+       idef->registerItem(itemdef);
+       t_CONTENT_LAVA = ndef->set(f.name, f);
+
+
+       //// Brick
+       itemdef = ItemDefinition();
+       itemdef.type = ITEM_NODE;
+       itemdef.name = "default:brick";
+       itemdef.description = "Brick";
+       itemdef.groups["cracky"] = 3;
+       itemdef.inventory_image = "[inventorycube"
+               "{default_brick.png"
+               "{default_brick.png"
+               "{default_brick.png";
+       f = ContentFeatures();
+       f.name = itemdef.name;
+       for (TileDef &tiledef : f.tiledef)
+               tiledef.name = "default_brick.png";
+       f.is_ground_content = true;
+       idef->registerItem(itemdef);
+       t_CONTENT_BRICK = ndef->set(f.name, f);
+}
+
+bool TestGameDef::joinModChannel(const std::string &channel)
+{
+       return m_modchannel_mgr->joinChannel(channel, PEER_ID_SERVER);
+}
+
+bool TestGameDef::leaveModChannel(const std::string &channel)
+{
+       return m_modchannel_mgr->leaveChannel(channel, PEER_ID_SERVER);
+}
+
+bool TestGameDef::sendModChannelMessage(const std::string &channel,
+       const std::string &message)
+{
+       if (!m_modchannel_mgr->channelRegistered(channel))
+               return false;
+
+       return true;
 }
 
 ////
 //// run_tests
 ////
 
-void run_tests()
+bool run_tests()
 {
-       DSTACK(__FUNCTION_NAME);
-
-       u32 t1 = porting::getTime(PRECISION_MILLI);
+       u64 t1 = porting::getTimeMs();
        TestGameDef gamedef;
 
-       log_set_lev_silence(LMT_ERROR, true);
+       g_logger.setLevelSilenced(LL_ERROR, true);
 
        u32 num_modules_failed     = 0;
        u32 num_total_tests_failed = 0;
@@ -172,13 +275,13 @@ void run_tests()
                num_total_tests_run += testmods[i]->num_tests_run;
        }
 
-       u32 tdiff = porting::getTime(PRECISION_MILLI) - t1;
+       u64 tdiff = porting::getTimeMs() - t1;
 
-       log_set_lev_silence(LMT_ERROR, false);
+       g_logger.setLevelSilenced(LL_ERROR, false);
 
        const char *overall_status = (num_modules_failed == 0) ? "PASSED" : "FAILED";
 
-       dstream
+       rawstream
                << "++++++++++++++++++++++++++++++++++++++++"
                << "++++++++++++++++++++++++++++++++++++++++" << std::endl
                << "Unit Test Results: " << overall_status << std::endl
@@ -189,8 +292,7 @@ void run_tests()
                << "++++++++++++++++++++++++++++++++++++++++"
                << "++++++++++++++++++++++++++++++++++++++++" << std::endl;
 
-       if (num_modules_failed)
-               abort();
+       return num_modules_failed;
 }
 
 ////
@@ -199,21 +301,47 @@ void run_tests()
 
 bool TestBase::testModule(IGameDef *gamedef)
 {
-       dstream << "======== Testing module " << getName() << std::endl;
-       u32 t1 = porting::getTime(PRECISION_MILLI);
+       rawstream << "======== Testing module " << getName() << std::endl;
+       u64 t1 = porting::getTimeMs();
 
 
        runTests(gamedef);
 
-       u32 tdiff = porting::getTime(PRECISION_MILLI) - t1;
-       dstream << "======== Module " << getName() << " "
+       u64 tdiff = porting::getTimeMs() - t1;
+       rawstream << "======== Module " << getName() << " "
                << (num_tests_failed ? "failed" : "passed") << " (" << num_tests_failed
                << " failures / " << num_tests_run << " tests) - " << tdiff
                << "ms" << std::endl;
 
+       if (!m_test_dir.empty())
+               fs::RecursiveDelete(m_test_dir);
+
        return num_tests_failed == 0;
 }
 
+std::string TestBase::getTestTempDirectory()
+{
+       if (!m_test_dir.empty())
+               return m_test_dir;
+
+       char buf[32];
+       snprintf(buf, sizeof(buf), "%08X", myrand());
+
+       m_test_dir = fs::TempPath() + DIR_DELIM "mttest_" + buf;
+       if (!fs::CreateDir(m_test_dir))
+               throw TestFailedException();
+
+       return m_test_dir;
+}
+
+std::string TestBase::getTestTempFile()
+{
+       char buf[32];
+       snprintf(buf, sizeof(buf), "%08X", myrand());
+
+       return getTestTempDirectory() + DIR_DELIM + buf + ".tmp";
+}
+
 
 /*
        NOTE: These tests became non-working then NodeContainer was removed.