2009-04-18 19:00:33 +02:00
|
|
|
/* Copyright (C) 2009 Wildfire Games.
|
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 0 A.D. 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2006-12-20 04:22:24 +01:00
|
|
|
#include "lib/self_test.h"
|
|
|
|
|
2008-01-08 01:09:52 +01:00
|
|
|
#include "lib/file/vfs/vfs.h"
|
2007-12-20 21:21:45 +01:00
|
|
|
#include "lib/file/io/io.h"
|
2006-12-20 04:22:24 +01:00
|
|
|
|
2007-03-01 19:52:53 +01:00
|
|
|
#include "graphics/ColladaManager.h"
|
2006-12-20 04:22:24 +01:00
|
|
|
#include "graphics/MeshManager.h"
|
|
|
|
#include "graphics/ModelDef.h"
|
|
|
|
|
2007-03-17 00:32:10 +01:00
|
|
|
#include "ps/CLogger.h"
|
2010-04-18 18:35:06 +02:00
|
|
|
#include "ps/XML/RelaxNG.h"
|
2007-03-17 00:32:10 +01:00
|
|
|
|
2009-11-03 22:46:35 +01:00
|
|
|
static fs::wpath MOD_PATH(DataDir()/L"mods/_test.mesh");
|
|
|
|
static fs::wpath CACHE_PATH(DataDir()/L"_testcache");
|
2006-12-20 04:22:24 +01:00
|
|
|
|
2009-11-03 22:46:35 +01:00
|
|
|
const wchar_t* srcDAE = L"collada/sphere.dae";
|
|
|
|
const wchar_t* srcPMD = L"collada/sphere.pmd";
|
|
|
|
const wchar_t* testDAE = L"art/skeletons/test.dae";
|
|
|
|
const wchar_t* testPMD = L"art/skeletons/test.pmd";
|
|
|
|
const wchar_t* testBase = L"art/skeletons/test";
|
2006-12-20 04:22:24 +01:00
|
|
|
|
2009-11-03 22:46:35 +01:00
|
|
|
const wchar_t* srcSkeletonDefs = L"collada/skeletons.xml";
|
|
|
|
const wchar_t* testSkeletonDefs = L"art/skeletons/skeletons.xml";
|
2007-03-17 00:32:10 +01:00
|
|
|
|
2008-01-07 21:03:19 +01:00
|
|
|
extern PIVFS g_VFS;
|
|
|
|
|
2006-12-20 04:22:24 +01:00
|
|
|
class TestMeshManager : public CxxTest::TestSuite
|
|
|
|
{
|
|
|
|
void initVfs()
|
|
|
|
{
|
|
|
|
// Initialise VFS:
|
|
|
|
|
|
|
|
// Set up a mod directory to work in:
|
|
|
|
|
|
|
|
// Make sure the required directories doesn't exist when we start,
|
|
|
|
// in case the previous test aborted and left them full of junk
|
2008-04-05 21:47:57 +02:00
|
|
|
if(exists(MOD_PATH))
|
2009-08-04 21:57:53 +02:00
|
|
|
DeleteDirectory(MOD_PATH);
|
2008-04-05 21:47:57 +02:00
|
|
|
if(exists(CACHE_PATH))
|
2009-08-04 21:57:53 +02:00
|
|
|
DeleteDirectory(CACHE_PATH);
|
2006-12-20 04:22:24 +01:00
|
|
|
|
2008-05-13 21:43:02 +02:00
|
|
|
g_VFS = CreateVfs(20*MiB);
|
2006-12-20 04:22:24 +01:00
|
|
|
|
2009-11-03 22:46:35 +01:00
|
|
|
TS_ASSERT_OK(g_VFS->Mount(L"", MOD_PATH));
|
|
|
|
TS_ASSERT_OK(g_VFS->Mount(L"collada/", DataDir()/L"tests/collada"));
|
2006-12-20 04:22:24 +01:00
|
|
|
|
|
|
|
// Mount _testcache onto virtual /cache - don't use the normal cache
|
|
|
|
// directory because that's full of loads of cached files from the
|
|
|
|
// proper game and takes a long time to load.
|
2009-11-03 22:46:35 +01:00
|
|
|
TS_ASSERT_OK(g_VFS->Mount(L"cache/", CACHE_PATH));
|
2006-12-20 04:22:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void deinitVfs()
|
|
|
|
{
|
2009-08-08 13:10:56 +02:00
|
|
|
DeleteDirectory(MOD_PATH);
|
|
|
|
DeleteDirectory(CACHE_PATH);
|
2008-01-07 21:03:19 +01:00
|
|
|
g_VFS.reset();
|
2006-12-20 04:22:24 +01:00
|
|
|
}
|
|
|
|
|
2009-11-03 22:46:35 +01:00
|
|
|
void copyFile(const VfsPath& src, const VfsPath& dst)
|
2006-12-20 04:22:24 +01:00
|
|
|
{
|
|
|
|
// Copy a file into the mod directory, so we can work on it:
|
2007-12-20 21:21:45 +01:00
|
|
|
shared_ptr<u8> data; size_t size = 0;
|
2008-01-07 21:03:19 +01:00
|
|
|
TS_ASSERT_OK(g_VFS->LoadFile(src, data, size));
|
|
|
|
TS_ASSERT_OK(g_VFS->CreateFile(dst, data, size));
|
2006-12-20 04:22:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void buildArchive()
|
|
|
|
{
|
|
|
|
// Create a junk trace file first, because vfs_opt_auto_build requires one
|
2007-12-20 21:21:45 +01:00
|
|
|
// std::string trace = "000.000000: L \"-\" 0 0000\n";
|
|
|
|
// vfs_store("trace.txt", (const u8*)trace.c_str(), trace.size(), FILE_NO_AIO);
|
2006-12-20 04:22:24 +01:00
|
|
|
|
|
|
|
// then make the archive
|
2007-12-20 21:21:45 +01:00
|
|
|
// TS_ASSERT_OK(vfs_opt_rebuild_main_archive(MOD_PATH"/trace.txt", MOD_PATH"/test%02d.zip"));
|
2006-12-20 04:22:24 +01:00
|
|
|
}
|
|
|
|
|
2007-03-01 19:52:53 +01:00
|
|
|
CColladaManager* colladaManager;
|
2006-12-20 04:22:24 +01:00
|
|
|
CMeshManager* meshManager;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
void setUp()
|
|
|
|
{
|
|
|
|
initVfs();
|
2007-03-01 19:52:53 +01:00
|
|
|
colladaManager = new CColladaManager();
|
|
|
|
meshManager = new CMeshManager(*colladaManager);
|
2006-12-20 04:22:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void tearDown()
|
|
|
|
{
|
|
|
|
delete meshManager;
|
2007-03-01 19:52:53 +01:00
|
|
|
delete colladaManager;
|
2006-12-20 04:22:24 +01:00
|
|
|
deinitVfs();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IRRELEVANT_test_archived()
|
|
|
|
{
|
|
|
|
copyFile(srcDAE, testDAE);
|
2007-12-20 21:21:45 +01:00
|
|
|
//buildArchive();
|
|
|
|
shared_ptr<u8> buf = io_Allocate(100);
|
2010-01-01 16:33:07 +01:00
|
|
|
strcpy_s((char*)buf.get(), 5, "Test");
|
2008-01-07 21:03:19 +01:00
|
|
|
g_VFS->CreateFile(testDAE, buf, 4);
|
2006-12-20 04:22:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void test_load_pmd_with_extension()
|
|
|
|
{
|
|
|
|
copyFile(srcPMD, testPMD);
|
|
|
|
|
|
|
|
CModelDefPtr modeldef = meshManager->GetMesh(testPMD);
|
|
|
|
TS_ASSERT(modeldef);
|
2009-11-03 22:46:35 +01:00
|
|
|
if (modeldef) TS_ASSERT_WSTR_EQUALS(modeldef->GetName().string(), testBase);
|
2006-12-20 04:22:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void test_load_pmd_without_extension()
|
|
|
|
{
|
|
|
|
copyFile(srcPMD, testPMD);
|
|
|
|
|
|
|
|
CModelDefPtr modeldef = meshManager->GetMesh(testBase);
|
|
|
|
TS_ASSERT(modeldef);
|
2009-11-03 22:46:35 +01:00
|
|
|
if (modeldef) TS_ASSERT_WSTR_EQUALS(modeldef->GetName().string(), testBase);
|
2006-12-20 04:22:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void test_caching()
|
|
|
|
{
|
|
|
|
copyFile(srcPMD, testPMD);
|
|
|
|
|
|
|
|
CModelDefPtr modeldef1 = meshManager->GetMesh(testPMD);
|
|
|
|
CModelDefPtr modeldef2 = meshManager->GetMesh(testPMD);
|
|
|
|
TS_ASSERT(modeldef1 && modeldef2);
|
2007-01-26 19:26:45 +01:00
|
|
|
if (modeldef1 && modeldef2) TS_ASSERT_EQUALS(modeldef1.get(), modeldef2.get());
|
2006-12-20 04:22:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void test_load_dae()
|
|
|
|
{
|
|
|
|
copyFile(srcDAE, testDAE);
|
2007-03-17 00:32:10 +01:00
|
|
|
copyFile(srcSkeletonDefs, testSkeletonDefs);
|
2006-12-20 04:22:24 +01:00
|
|
|
|
|
|
|
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
|
|
|
|
TS_ASSERT(modeldef);
|
2009-11-03 22:46:35 +01:00
|
|
|
if (modeldef) TS_ASSERT_WSTR_EQUALS(modeldef->GetName().string(), testBase);
|
2006-12-20 04:22:24 +01:00
|
|
|
}
|
|
|
|
|
2007-03-01 19:52:53 +01:00
|
|
|
void test_load_dae_caching()
|
|
|
|
{
|
|
|
|
copyFile(srcDAE, testDAE);
|
2007-03-17 00:32:10 +01:00
|
|
|
copyFile(srcSkeletonDefs, testSkeletonDefs);
|
2007-03-01 19:52:53 +01:00
|
|
|
|
2008-01-07 21:03:19 +01:00
|
|
|
VfsPath daeName1 = colladaManager->GetLoadableFilename(testBase, CColladaManager::PMD);
|
|
|
|
VfsPath daeName2 = colladaManager->GetLoadableFilename(testBase, CColladaManager::PMD);
|
|
|
|
TS_ASSERT(!daeName1.empty());
|
2009-11-03 22:46:35 +01:00
|
|
|
TS_ASSERT_WSTR_EQUALS(daeName1.string(), daeName2.string());
|
2007-03-17 00:32:10 +01:00
|
|
|
// TODO: it'd be nice to test that it really isn't doing the DAE->PMD
|
|
|
|
// conversion a second time, but there doesn't seem to be an easy way
|
|
|
|
// to check that
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_invalid_skeletons()
|
|
|
|
{
|
|
|
|
TestLogger logger;
|
|
|
|
|
|
|
|
copyFile(srcDAE, testDAE);
|
2007-12-20 21:21:45 +01:00
|
|
|
shared_ptr<u8> buf = io_Allocate(100);
|
2010-01-01 16:33:07 +01:00
|
|
|
strcpy_s((char*)buf.get(), 100, "Not valid XML");
|
2008-01-07 21:03:19 +01:00
|
|
|
g_VFS->CreateFile(testSkeletonDefs, buf, 13);
|
2007-03-17 00:32:10 +01:00
|
|
|
|
|
|
|
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
|
|
|
|
TS_ASSERT(! modeldef);
|
2009-11-03 22:46:35 +01:00
|
|
|
TS_ASSERT_WSTR_CONTAINS(logger.GetOutput(), L"parser error");
|
2007-03-17 00:32:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void test_invalid_dae()
|
|
|
|
{
|
|
|
|
TestLogger logger;
|
|
|
|
|
|
|
|
copyFile(srcSkeletonDefs, testSkeletonDefs);
|
2007-12-20 21:21:45 +01:00
|
|
|
shared_ptr<u8> buf = io_Allocate(100);
|
2010-01-01 16:33:07 +01:00
|
|
|
strcpy_s((char*)buf.get(), 100, "Not valid XML");
|
2008-01-07 21:03:19 +01:00
|
|
|
g_VFS->CreateFile(testDAE, buf, 13);
|
2007-03-17 00:32:10 +01:00
|
|
|
|
|
|
|
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
|
|
|
|
TS_ASSERT(! modeldef);
|
2009-11-03 22:46:35 +01:00
|
|
|
TS_ASSERT_WSTR_CONTAINS(logger.GetOutput(), L"parser error");
|
2007-03-01 19:52:53 +01:00
|
|
|
}
|
|
|
|
|
2006-12-20 04:22:24 +01:00
|
|
|
void test_load_nonexistent_pmd()
|
|
|
|
{
|
2008-07-19 21:02:27 +02:00
|
|
|
TestLogger logger;
|
|
|
|
|
2006-12-20 04:22:24 +01:00
|
|
|
CModelDefPtr modeldef = meshManager->GetMesh(testPMD);
|
|
|
|
TS_ASSERT(! modeldef);
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_load_nonexistent_dae()
|
|
|
|
{
|
2008-07-19 21:02:27 +02:00
|
|
|
TestLogger logger;
|
|
|
|
|
2006-12-20 04:22:24 +01:00
|
|
|
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
|
|
|
|
TS_ASSERT(! modeldef);
|
|
|
|
}
|
2009-06-23 19:47:37 +02:00
|
|
|
|
2010-04-18 18:35:06 +02:00
|
|
|
void test_load_across_relaxng()
|
|
|
|
{
|
|
|
|
// Verify that loading meshes doesn't invalidate other users of libxml2 by calling xmlCleanupParser
|
|
|
|
// (Run this in Valgrind and check for use-of-freed-memory errors)
|
|
|
|
|
|
|
|
RelaxNGValidator v;
|
|
|
|
TS_ASSERT(v.LoadGrammar("<element xmlns='http://relaxng.org/ns/structure/1.0' datatypeLibrary='http://www.w3.org/2001/XMLSchema-datatypes' name='test'><data type='decimal'/></element>"));
|
|
|
|
TS_ASSERT(v.Validate(L"doc", L"<test>2.0</test>"));
|
|
|
|
|
|
|
|
copyFile(srcDAE, testDAE);
|
|
|
|
copyFile(srcSkeletonDefs, testSkeletonDefs);
|
|
|
|
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
|
|
|
|
TS_ASSERT(modeldef);
|
|
|
|
if (modeldef) TS_ASSERT_WSTR_EQUALS(modeldef->GetName().string(), testBase);
|
|
|
|
|
|
|
|
TS_ASSERT(v.Validate(L"doc", L"<test>2.0</test>"));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-06-23 19:47:37 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// Tests based on real DAE files:
|
|
|
|
|
|
|
|
void test_load_dae_bogus_material_target()
|
|
|
|
{
|
2009-11-03 22:46:35 +01:00
|
|
|
copyFile(L"collada/bogus_material_target.dae", testDAE);
|
2009-06-23 19:47:37 +02:00
|
|
|
copyFile(srcSkeletonDefs, testSkeletonDefs);
|
|
|
|
|
|
|
|
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
|
|
|
|
TS_ASSERT(modeldef);
|
|
|
|
}
|
|
|
|
|
2006-12-20 04:22:24 +01:00
|
|
|
};
|