308 lines
7.7 KiB
C++
308 lines
7.7 KiB
C++
/**
|
|
* @file test_asset_cache.cpp
|
|
* @brief AssetCache 单元测试
|
|
*
|
|
* 测试资源缓存的添加、获取、淘汰等功能。
|
|
*/
|
|
|
|
#include "test_framework.h"
|
|
#include <extra2d/asset/asset_cache.h>
|
|
#include <extra2d/asset/asset.h>
|
|
|
|
using namespace extra2d;
|
|
using namespace extra2d::test;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试辅助类
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* @brief 测试用资源类
|
|
*/
|
|
class TestAsset : public Asset {
|
|
public:
|
|
AssetType type() const override { return AssetType::Data; }
|
|
|
|
bool loaded() const override {
|
|
return state_.load(std::memory_order_acquire) == AssetState::Loaded;
|
|
}
|
|
|
|
size_t memSize() const override { return dataSize_; }
|
|
|
|
void setData(size_t size) {
|
|
dataSize_ = size;
|
|
setState(AssetState::Loaded);
|
|
}
|
|
|
|
static Ref<TestAsset> create(const std::string& path, size_t size = 100) {
|
|
auto asset = std::make_shared<TestAsset>();
|
|
asset->setId(AssetID(path));
|
|
asset->setPath(path);
|
|
asset->setData(size);
|
|
return asset;
|
|
}
|
|
|
|
private:
|
|
size_t dataSize_ = 0;
|
|
};
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 基本功能测试
|
|
// ---------------------------------------------------------------------------
|
|
|
|
TEST(AssetCache, Create) {
|
|
AssetCache cache;
|
|
|
|
TEST_ASSERT_EQ(0u, cache.count());
|
|
TEST_ASSERT_EQ(0u, cache.bytes());
|
|
TEST_ASSERT_EQ(0u, cache.limit());
|
|
}
|
|
|
|
TEST(AssetCache, CreateWithLimit) {
|
|
AssetCache cache(1024 * 1024);
|
|
|
|
TEST_ASSERT_EQ(1024 * 1024, cache.limit());
|
|
}
|
|
|
|
TEST(AssetCache, AddAsset) {
|
|
AssetCache cache;
|
|
|
|
auto asset = TestAsset::create("test.asset", 100);
|
|
auto handle = cache.add(asset);
|
|
|
|
TEST_ASSERT_TRUE(handle.valid());
|
|
TEST_ASSERT_EQ(1u, cache.count());
|
|
TEST_ASSERT_EQ(100u, cache.bytes());
|
|
}
|
|
|
|
TEST(AssetCache, AddNullAsset) {
|
|
AssetCache cache;
|
|
|
|
Ref<TestAsset> nullAsset;
|
|
auto handle = cache.add(nullAsset);
|
|
|
|
TEST_ASSERT_FALSE(handle.valid());
|
|
TEST_ASSERT_EQ(0u, cache.count());
|
|
}
|
|
|
|
TEST(AssetCache, GetAsset) {
|
|
AssetCache cache;
|
|
|
|
auto asset = TestAsset::create("test.asset", 200);
|
|
cache.add(asset);
|
|
|
|
auto handle = cache.get<TestAsset>(AssetID("test.asset"));
|
|
|
|
TEST_ASSERT_TRUE(handle.valid());
|
|
TEST_ASSERT_TRUE(handle.get() != nullptr);
|
|
TEST_ASSERT_EQ(asset.get(), handle.get().get());
|
|
}
|
|
|
|
TEST(AssetCache, GetNonExistent) {
|
|
AssetCache cache;
|
|
|
|
auto handle = cache.get<TestAsset>(AssetID("nonexistent.asset"));
|
|
|
|
TEST_ASSERT_FALSE(handle.valid());
|
|
}
|
|
|
|
TEST(AssetCache, HasAsset) {
|
|
AssetCache cache;
|
|
|
|
auto asset = TestAsset::create("test.asset", 100);
|
|
cache.add(asset);
|
|
|
|
TEST_ASSERT_TRUE(cache.has(AssetID("test.asset")));
|
|
TEST_ASSERT_FALSE(cache.has(AssetID("other.asset")));
|
|
}
|
|
|
|
TEST(AssetCache, RemoveAsset) {
|
|
AssetCache cache;
|
|
|
|
auto asset = TestAsset::create("test.asset", 100);
|
|
cache.add(asset);
|
|
|
|
TEST_ASSERT_TRUE(cache.remove(AssetID("test.asset")));
|
|
TEST_ASSERT_EQ(0u, cache.count());
|
|
TEST_ASSERT_FALSE(cache.has(AssetID("test.asset")));
|
|
}
|
|
|
|
TEST(AssetCache, RemoveNonExistent) {
|
|
AssetCache cache;
|
|
|
|
TEST_ASSERT_FALSE(cache.remove(AssetID("nonexistent.asset")));
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 缓存统计测试
|
|
// ---------------------------------------------------------------------------
|
|
|
|
TEST(AssetCache, Stats_Initial) {
|
|
AssetCache cache;
|
|
|
|
auto stats = cache.stats();
|
|
|
|
TEST_ASSERT_EQ(0u, stats.hits);
|
|
TEST_ASSERT_EQ(0u, stats.misses);
|
|
TEST_ASSERT_EQ(0u, stats.count);
|
|
}
|
|
|
|
TEST(AssetCache, Stats_HitMiss) {
|
|
AssetCache cache;
|
|
|
|
auto asset = TestAsset::create("test.asset", 100);
|
|
cache.add(asset);
|
|
|
|
cache.get<TestAsset>(AssetID("test.asset"));
|
|
cache.get<TestAsset>(AssetID("nonexistent.asset"));
|
|
|
|
auto stats = cache.stats();
|
|
|
|
TEST_ASSERT_EQ(1u, stats.hits);
|
|
TEST_ASSERT_EQ(1u, stats.misses);
|
|
}
|
|
|
|
TEST(AssetCache, Stats_Reset) {
|
|
AssetCache cache;
|
|
|
|
auto asset = TestAsset::create("test.asset", 100);
|
|
cache.add(asset);
|
|
|
|
cache.get<TestAsset>(AssetID("test.asset"));
|
|
cache.get<TestAsset>(AssetID("nonexistent.asset"));
|
|
|
|
cache.resetStats();
|
|
|
|
auto stats = cache.stats();
|
|
|
|
TEST_ASSERT_EQ(0u, stats.hits);
|
|
TEST_ASSERT_EQ(0u, stats.misses);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 内存限制测试
|
|
// ---------------------------------------------------------------------------
|
|
|
|
TEST(AssetCache, SetLimit) {
|
|
AssetCache cache;
|
|
|
|
cache.setLimit(500);
|
|
|
|
TEST_ASSERT_EQ(500u, cache.limit());
|
|
}
|
|
|
|
TEST(AssetCache, MemoryTracking) {
|
|
AssetCache cache;
|
|
|
|
auto asset1 = TestAsset::create("asset1", 100);
|
|
auto asset2 = TestAsset::create("asset2", 200);
|
|
|
|
cache.add(asset1);
|
|
cache.add(asset2);
|
|
|
|
TEST_ASSERT_EQ(300u, cache.bytes());
|
|
}
|
|
|
|
TEST(AssetCache, Clear) {
|
|
AssetCache cache;
|
|
|
|
auto asset1 = TestAsset::create("asset1", 100);
|
|
auto asset2 = TestAsset::create("asset2", 200);
|
|
|
|
cache.add(asset1);
|
|
cache.add(asset2);
|
|
|
|
cache.clear();
|
|
|
|
TEST_ASSERT_EQ(0u, cache.count());
|
|
TEST_ASSERT_EQ(0u, cache.bytes());
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// LRU 测试
|
|
// ---------------------------------------------------------------------------
|
|
|
|
TEST(AssetCache, LRU_AccessOrder) {
|
|
AssetCache cache;
|
|
|
|
auto asset1 = TestAsset::create("asset1", 100);
|
|
auto asset2 = TestAsset::create("asset2", 100);
|
|
auto asset3 = TestAsset::create("asset3", 100);
|
|
|
|
cache.add(asset1);
|
|
cache.add(asset2);
|
|
cache.add(asset3);
|
|
|
|
cache.get<TestAsset>(AssetID("asset1"));
|
|
|
|
TEST_ASSERT_TRUE(cache.has(AssetID("asset1")));
|
|
TEST_ASSERT_TRUE(cache.has(AssetID("asset2")));
|
|
TEST_ASSERT_TRUE(cache.has(AssetID("asset3")));
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Purge 测试
|
|
// ---------------------------------------------------------------------------
|
|
|
|
TEST(AssetCache, Purge_NoReferences) {
|
|
AssetCache cache;
|
|
|
|
{
|
|
auto asset = TestAsset::create("test.asset", 100);
|
|
cache.add(asset);
|
|
}
|
|
|
|
size_t purged = cache.purge();
|
|
|
|
TEST_ASSERT_EQ(1u, purged);
|
|
TEST_ASSERT_EQ(0u, cache.count());
|
|
}
|
|
|
|
TEST(AssetCache, Purge_WithReferences) {
|
|
AssetCache cache;
|
|
|
|
auto asset = TestAsset::create("test.asset", 100);
|
|
auto handle = cache.add(asset);
|
|
|
|
size_t purged = cache.purge();
|
|
|
|
TEST_ASSERT_EQ(0u, purged);
|
|
TEST_ASSERT_EQ(1u, cache.count());
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 多资源测试
|
|
// ---------------------------------------------------------------------------
|
|
|
|
TEST(AssetCache, MultipleAssets) {
|
|
AssetCache cache;
|
|
|
|
for (int i = 0; i < 10; ++i) {
|
|
auto asset = TestAsset::create("asset" + std::to_string(i), 100);
|
|
cache.add(asset);
|
|
}
|
|
|
|
TEST_ASSERT_EQ(10u, cache.count());
|
|
TEST_ASSERT_EQ(1000u, cache.bytes());
|
|
|
|
for (int i = 0; i < 10; ++i) {
|
|
TEST_ASSERT_TRUE(cache.has(AssetID("asset" + std::to_string(i))));
|
|
}
|
|
}
|
|
|
|
TEST(AssetCache, RemoveMultiple) {
|
|
AssetCache cache;
|
|
|
|
for (int i = 0; i < 5; ++i) {
|
|
auto asset = TestAsset::create("asset" + std::to_string(i), 100);
|
|
cache.add(asset);
|
|
}
|
|
|
|
for (int i = 0; i < 3; ++i) {
|
|
cache.remove(AssetID("asset" + std::to_string(i)));
|
|
}
|
|
|
|
TEST_ASSERT_EQ(2u, cache.count());
|
|
TEST_ASSERT_EQ(200u, cache.bytes());
|
|
}
|