* -------------------------------------------------------------------------
* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*/
#include <gtest/gtest.h>
#include "MemScopeProtocolRequest.h"
#include "DataBaseManager.h"
#include "MemScopeParser.h"
#include "MemScopeDatabase.h"
#include "MemScopeService.h"
#include "MemScopeTableColumn.h"
#include "../../TestSuit.h"
using namespace Dic::Module::Timeline;
using namespace Dic::Module::FullDb;
using namespace Dic;
class MemScopeDatabaseTest : public ::testing::Test {
public:
static void SetUpTestSuite() {
std::string dbPath = TestSuit::GetTestDataFile("full_db", "leaks_dump_20250806.dat");
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
ASSERT_TRUE(memoryDatabase->OpenDb(dbPath, false));
ASSERT_TRUE(memoryDatabase->DropMemoryAllocationAndBlockTable());
ASSERT_TRUE(MemScopeParser::ParseMemoryMemScopeDumpEventsAndPythonTraces("0"));
}
static void TearDownTestSuite() {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
memoryDatabase->CloseDb();
DataBaseManager::Instance().Clear();
}
};
TEST_F(MemScopeDatabaseTest, QueryEntireEventsTable) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
std::vector<MemScopeEvent> events;
memoryDatabase->QueryEntireEventsTable(events);
size_t expectSize = 33882;
EXPECT_EQ(events.size(), expectSize);
}
TEST_F(MemScopeDatabaseTest, QueryDeviceIds) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
std::set<std::string> deviceIds;
memoryDatabase->QueryDeviceIds(deviceIds);
size_t expectSize = 1;
EXPECT_EQ(deviceIds.size(), expectSize);
}
TEST_F(MemScopeDatabaseTest, QueryDeviceEventTypeMap) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
std::unordered_map<std::string, std::vector<std::string>> resultMap;
memoryDatabase->QueryMallocOrFreeEventTypeWithDeviceId(resultMap);
std::vector<std::string> eventTypes = resultMap["1"];
auto it = std::find(eventTypes.begin(), eventTypes.end(), "HAL");
EXPECT_TRUE(it != eventTypes.end());
it = std::find(eventTypes.begin(), eventTypes.end(), "PTA");
EXPECT_TRUE(it != eventTypes.end());
}
TEST_F(MemScopeDatabaseTest, QueryMinAndMaxTimestamp) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
uint64_t minTimestamp = memoryDatabase->GetGlobalMinTimestamp();
uint64_t maxTimestamp = memoryDatabase->GetGlobalMaxTimestamp();
const uint64_t expectMin = 1754448083902750070;
const uint64_t expectMax = 1754448132413582150;
EXPECT_EQ(minTimestamp, expectMin);
EXPECT_EQ(maxTimestamp, expectMax);
}
TEST_F(MemScopeDatabaseTest, QueryMemoryBlockWithNoTimeAndSizeCondition) {
std::vector<MemScopeEvent> events;
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
MemScopeMemoryBlockParams params;
params.deviceId = "1";
params.relativeTime = false;
params.eventType = "PTA";
std::vector<MemoryBlock> blocks;
memoryDatabase->QueryMemoryBlocks(params, false, blocks);
const size_t expectSize = 3267;
EXPECT_EQ(blocks.size(), expectSize);
}
TEST_F(MemScopeDatabaseTest, QueryMemoryBlockWithTimeAndSizeConditionAndRelativeTime) {
MemScopeMemoryBlockParams params;
params.deviceId = "1";
params.relativeTime = true;
const uint64_t endTimestamp = 20000000000;
const uint64_t maxSize = 60000;
params.endTimestamp = endTimestamp;
params.maxSize = maxSize;
params.eventType = "PTA";
params.orderBy = std::string(MemoryBlockTableColumn::START_TIMESTAMP);
std::vector<MemoryBlock> blocks;
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
memoryDatabase->QueryMemoryBlocks(params, false, blocks);
const size_t expectSize = 269;
EXPECT_EQ(blocks.size(), expectSize);
MemoryBlock &firstBlock = blocks[0];
const uint64_t expectStartTime = 13350166480;
const uint64_t expectEndTime = 45422237070;
EXPECT_EQ(firstBlock.startTimestamp, expectStartTime);
EXPECT_EQ(firstBlock.endTimestamp, expectEndTime);
EXPECT_TRUE(firstBlock.size > 0 and firstBlock.size < params.maxSize);
}
TEST_F(MemScopeDatabaseTest, QueryAllocationWithNoTimeCondition) {
MemScopeMemoryAllocationParams params;
params.deviceId = "1";
params.optimized = false;
params.eventType = "PTA";
std::vector<MemoryAllocation> allocations;
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
memoryDatabase->QueryMemoryAllocations(params, allocations);
size_t expectSize = 6534;
EXPECT_EQ(allocations.size(), expectSize);
}
TEST_F(MemScopeDatabaseTest, QueryAllocationWithTimeAndRelativeCondition) {
MemScopeMemoryAllocationParams params;
params.deviceId = "1";
params.optimized = false;
const uint64_t endTimestamp = 20000000000;
params.endTimestamp = endTimestamp;
params.relativeTime = true;
params.eventType = "PTA";
std::vector<MemoryAllocation> allocations;
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
memoryDatabase->QueryMemoryAllocations(params, allocations);
const size_t expectSize = 324;
EXPECT_EQ(allocations.size(), expectSize);
MemoryAllocation &firstAllocation = allocations[0];
const uint64_t expectTimestamp = 13350166480;
EXPECT_EQ(firstAllocation.timestamp, expectTimestamp);
uint64_t totalSize = 37888;
EXPECT_EQ(firstAllocation.totalSize, totalSize);
}
TEST_F(MemScopeDatabaseTest, QueryLatestAllocationWithinTimestamp) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
const std::string deviceId = "1";
const std::string eventType = "HAL";
const uint64_t expectDuration = 20000000000;
const uint64_t timestamp = memoryDatabase->GetGlobalMinTimestamp() + expectDuration;
auto alloc = memoryDatabase->QueryLatestAllocationWithinTimestamp(deviceId, eventType, timestamp);
EXPECT_TRUE(alloc.has_value());
const uint64_t expectTotalSize = 187076614;
EXPECT_EQ(alloc->totalSize, expectTotalSize);
}
TEST_F(MemScopeDatabaseTest, QueryNextAllocationAfterTimestamp) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
const std::string deviceId = "1";
const std::string eventType = "PTA";
const uint64_t expectDuration = 10000000;
const uint64_t timestamp = memoryDatabase->GetGlobalMinTimestamp() + expectDuration;
auto alloc = memoryDatabase->QueryNextAllocationAfterTimestamp(deviceId, eventType, timestamp);
EXPECT_TRUE(alloc.has_value());
const uint64_t expectTotalSize = 37888;
EXPECT_EQ(alloc->totalSize, expectTotalSize);
}
TEST_F(MemScopeDatabaseTest, QueryMemoryBlocksOwnersReleasedAfterTimestamp) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
const std::string deviceId = "1";
const std::string eventType = "PTA";
const uint64_t expectDuration = 20000000000;
const uint64_t timestamp = memoryDatabase->GetGlobalMinTimestamp() + expectDuration;
std::set<std::string> owners;
memoryDatabase->QueryMemoryBlocksOwnersReleasedAfterTimestamp(deviceId, eventType, timestamp, owners);
EXPECT_FALSE(owners.empty());
std::set<std::string> expectOwners = {"PTA@model@weight", "PTA@ops@aten", "PTA@ops@aten@leaks_mem"};
EXPECT_EQ(owners, expectOwners);
}
TEST_F(MemScopeDatabaseTest, QueryTotalSizeUtilTimestampUsingOwner) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
const std::string deviceId = "1";
const uint64_t expectDuration = 20000000000;
const std::string eventType = "HAL";
const uint64_t timestamp = memoryDatabase->GetGlobalMinTimestamp() + expectDuration;
auto allocation = memoryDatabase->QueryLatestAllocationWithinTimestamp(deviceId, eventType, timestamp);
uint64_t cannTotalSize = memoryDatabase->QueryTotalSizeUntilTimestampUsingOwner(deviceId, timestamp, "CANN");
uint64_t ptaTotalSize = memoryDatabase->QueryTotalSizeUntilTimestampUsingOwner(deviceId, timestamp, "PTA");
uint64_t ptaModelTotalSize =
memoryDatabase->QueryTotalSizeUntilTimestampUsingOwner(deviceId, timestamp, "PTA@model");
uint64_t ptaOpTotalSize = memoryDatabase->QueryTotalSizeUntilTimestampUsingOwner(deviceId, timestamp, "PTA@ops");
const uint64_t expectCANNTotalSize = 187076614;
const uint64_t expectPTATotalSize = 142264320;
const uint64_t expectPTAModelTotalSize = 95234560;
const uint64_t expectPTAOpTotalSize = 47029760;
EXPECT_TRUE(allocation.has_value());
EXPECT_EQ(allocation->totalSize, cannTotalSize);
EXPECT_EQ(cannTotalSize, expectCANNTotalSize);
EXPECT_EQ(ptaTotalSize, expectPTATotalSize);
EXPECT_EQ(ptaModelTotalSize, expectPTAModelTotalSize);
EXPECT_EQ(ptaOpTotalSize, expectPTAOpTotalSize);
}
TEST_F(MemScopeDatabaseTest, QueryPythonTraces) {
const uint64_t startTimestamp = 1000000;
const uint64_t endTimestamp = 20000000000;
MemScopeThreadPythonTraceParams params;
params.startTimestamp = startTimestamp;
params.endTimestamp = endTimestamp;
params.relativeTime = true;
params.deviceId = "1";
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
ASSERT_TRUE(memoryDatabase != nullptr);
std::vector<uint64_t> threadIds;
const int expectThreadIdSize = 2;
memoryDatabase->QueryThreadIds(threadIds);
EXPECT_EQ(threadIds.size(), expectThreadIdSize);
params.threadId = threadIds[0];
MemScopePythonTrace trace;
memoryDatabase->QueryPythonTrace(params, trace);
EXPECT_FALSE(trace.slices.empty());
}
* 测试通过简易请求(仅deviceId)查询内存事件 应返回该deviceId下的所有事件
*/
TEST_F(MemScopeDatabaseTest, QueryMemoryEventsTableWithSimpleParams) {
MemScopeEventParams simpleQueryParams;
simpleQueryParams.deviceId = "1";
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
ASSERT_TRUE(memoryDatabase != nullptr);
std::vector<MemScopeEvent> events;
int64_t totalSize = memoryDatabase->QueryEventsByRequestParams(simpleQueryParams, events);
int64_t expectTotalSize = 33882;
EXPECT_EQ(totalSize, expectTotalSize);
EXPECT_EQ(events.size(), totalSize);
}
* 测试通过时间范围、字段、分页、排序参数请求内存事件
*/
TEST_F(MemScopeDatabaseTest, QueryMemoryEventsTableWithComplexParams) {
MemScopeEventParams complexParams;
complexParams.deviceId = "1";
complexParams.endTimestamp = 20000000000;
complexParams.relativeTime = true;
complexParams.currentPage = 1;
complexParams.pageSize = 10;
complexParams.orderBy = std::string(EventTableColumn::TIMESTAMP);
int64_t expectTotalSize = 2927;
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
ASSERT_TRUE(memoryDatabase != nullptr);
std::vector<MemScopeEvent> events;
int64_t totalSize = memoryDatabase->QueryEventsByRequestParams(complexParams, events);
EXPECT_EQ(totalSize, expectTotalSize);
EXPECT_EQ(events.size(), complexParams.pageSize);
EXPECT_EQ(events[0].timestamp, 4454383900);
complexParams.pageSize = 3000;
complexParams.orderBy = std::string(EventTableColumn::PTR);
complexParams.desc = true;
expectTotalSize = 2927;
uint64_t expectFirstEventTimestamp = 12318467490;
events.clear();
totalSize = memoryDatabase->QueryEventsByRequestParams(complexParams, events);
EXPECT_EQ(totalSize, expectTotalSize);
EXPECT_EQ(events.size(), expectTotalSize);
EXPECT_EQ(events[0].timestamp, expectFirstEventTimestamp);
complexParams.pageSize = 10;
complexParams.filters.emplace(std::string(EventTableColumn::ATTR), "PTA");
expectTotalSize = 649;
events.clear();
totalSize = memoryDatabase->QueryEventsByRequestParams(complexParams, events);
EXPECT_EQ(totalSize, expectTotalSize);
EXPECT_EQ(events.size(), complexParams.pageSize);
expectFirstEventTimestamp = 14011016610;
EXPECT_EQ(events[0].timestamp, expectFirstEventTimestamp);
}
* 测试查询某个deviceId+eventType下的全部数据
*/
TEST_F(MemScopeDatabaseTest, QueryMemoryBlockTablesWithTimeRangeParams) {
MemScopeMemoryBlockParams simpleQueryParams;
simpleQueryParams.deviceId = "1";
simpleQueryParams.eventType = "PTA";
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
ASSERT_TRUE(memoryDatabase != nullptr);
std::vector<MemoryBlock> blocks;
int64_t totalSize = memoryDatabase->QueryMemoryBlocks(simpleQueryParams, true, blocks);
int64_t expectTotalSize = 3267;
EXPECT_EQ(totalSize, expectTotalSize);
EXPECT_EQ(blocks.size(), totalSize);
blocks.clear();
simpleQueryParams.deviceId = "1";
simpleQueryParams.eventType = "HAL";
expectTotalSize = 96;
totalSize = memoryDatabase->QueryMemoryBlocks(simpleQueryParams, true, blocks);
EXPECT_EQ(totalSize, expectTotalSize);
EXPECT_EQ(blocks.size(), totalSize);
}
* 测试通过时间范围、字段、分页、排序参数请求内存事件
*/
TEST_F(MemScopeDatabaseTest, QueryMemoryEventsTableWithPaginationParams) {
MemScopeEventParams complexParams;
complexParams.deviceId = "1";
complexParams.endTimestamp = 100000000000;
complexParams.relativeTime = true;
complexParams.currentPage = 1;
complexParams.pageSize = 20;
complexParams.orderBy = std::string(EventTableColumn::TIMESTAMP);
int64_t expectTotalSize = 33882;
uint64_t expectFirstEventStartTimestamp = 4454383900;
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
EXPECT_TRUE(memoryDatabase != nullptr);
std::vector<MemScopeEvent> events;
int64_t totalSize = memoryDatabase->QueryEventsByRequestParams(complexParams, events);
EXPECT_EQ(totalSize, expectTotalSize);
EXPECT_EQ(events.size(), complexParams.pageSize);
EXPECT_EQ(events[0].timestamp, expectFirstEventStartTimestamp);
complexParams.endTimestamp = expectFirstEventStartTimestamp + 1;
complexParams.orderBy = std::string(EventTableColumn::PTR);
complexParams.desc = true;
expectTotalSize = 1;
expectFirstEventStartTimestamp = 4454383900;
events.clear();
totalSize = memoryDatabase->QueryEventsByRequestParams(complexParams, events);
EXPECT_EQ(totalSize, expectTotalSize);
EXPECT_EQ(events.size(), expectTotalSize);
EXPECT_EQ(events[0].timestamp, expectFirstEventStartTimestamp);
complexParams.endTimestamp = 100000000000;
complexParams.filters.emplace(std::string(EventTableColumn::PTR), "24");
expectTotalSize = 1167;
expectFirstEventStartTimestamp = 4473763530;
events.clear();
totalSize = memoryDatabase->QueryEventsByRequestParams(complexParams, events);
EXPECT_EQ(totalSize, expectTotalSize);
EXPECT_EQ(events.size(), complexParams.pageSize);
EXPECT_EQ(events[0].timestamp, expectFirstEventStartTimestamp);
}
TEST_F(MemScopeDatabaseTest, QueryAllDeviceExtreumTimestampMap) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
EXPECT_TRUE(memoryDatabase != nullptr);
const uint64_t expectMin = 1754448088357133970;
const uint64_t expectMax = 1754448132413582150;
const std::string deviceId = "1";
std::unordered_map<std::string, std::pair<uint64_t, uint64_t>> extreTsMap;
memoryDatabase->QueryAllDeviceExtremumTimestamp(extreTsMap);
EXPECT_EQ(extreTsMap.size(), 1);
EXPECT_EQ(extreTsMap["1"].first, expectMin);
EXPECT_EQ(extreTsMap["1"].second, expectMax);
}
TEST_F(MemScopeDatabaseTest, QueryEventsByGroupId) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
EXPECT_TRUE(memoryDatabase != nullptr);
const uint64_t groupId = 1910;
std::vector<MemScopeEvent> events;
memoryDatabase->QueryEventsByGroupId(groupId, "1", false, events);
const uint64_t expectTotalSize = 5;
EXPECT_EQ(events.size(), expectTotalSize);
MemScopeEvent &firstEvent = events[0];
MemScopeEvent &lastEvent = events[expectTotalSize - 1];
EXPECT_EQ(firstEvent.event, MEM_SCOPE_DUMP_EVENT::MALLOC);
EXPECT_EQ(lastEvent.event, MEM_SCOPE_DUMP_EVENT::FREE);
}
* 测试低效显存识别
*/
TEST_F(MemScopeDatabaseTest, QueryBlocksTableWithInefficientThreshold) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
ASSERT_TRUE(memoryDatabase != nullptr);
MemScopeMemoryBlockParams queryParams;
queryParams.deviceId = "1";
queryParams.relativeTime = true;
queryParams.eventType = "PTA";
queryParams.onlyInefficient = true;
queryParams.currentPage = 1;
queryParams.pageSize = 10;
queryParams.lazyUsedThreshold.perT = 10;
std::vector<MemoryBlock> blocks;
memoryDatabase->QueryMemoryBlocks(queryParams, true, blocks);
EXPECT_FALSE(blocks.empty());
for (auto &block : blocks) {
EXPECT_TRUE(block.lazyUsed);
uint64_t firstAccessInterval = block.firstAccessTimestamp - block.startTimestamp;
uint64_t duration = block.endTimestamp - block.startTimestamp;
EXPECT_GT(firstAccessInterval, duration * 0.1);
}
queryParams.lazyUsedThreshold.perT = 0;
blocks.clear();
queryParams.delayedFreeThreshold.perT = 10;
queryParams.delayedFreeThreshold.valueT = 100000000;
memoryDatabase->QueryMemoryBlocks(queryParams, true, blocks);
EXPECT_FALSE(blocks.empty());
for (auto &block : blocks) {
EXPECT_TRUE(block.delayedFree);
uint64_t freeInterval = block.endTimestamp - block.lastAccessTimestamp;
uint64_t duration = block.endTimestamp - block.startTimestamp;
EXPECT_TRUE(freeInterval > 100000000 || freeInterval > duration * 0.1);
}
queryParams.delayedFreeThreshold.perT = 0;
queryParams.delayedFreeThreshold.valueT = 0;
blocks.clear();
queryParams.longIdleThreshold.perT = 10;
memoryDatabase->QueryMemoryBlocks(queryParams, true, blocks);
EXPECT_FALSE(blocks.empty());
for (auto &block : blocks) {
EXPECT_TRUE(block.longIdle);
uint64_t maxInterval = block.maxAccessInterval;
uint64_t duration = block.endTimestamp - block.startTimestamp;
EXPECT_TRUE(maxInterval > duration * 0.1);
}
}
* 该测试专用于针对以下场景:
* 1. msleaks新增了某固化标签(如在进程占用下新增了Workspace内存池,其标签为PTA_WORKSPACE)
* 2. 新增的标签 以原某固化标签为前缀,却并原固化标签分类的子分类(如新增的PTA_WORKSPACE, 与原固化标签PTA存在前缀关系,却并非PTA子类)
* 3. 测试统计标签分类总Size时是否可能误将上述新增固化标签误统计入内
*/
TEST_F(MemScopeDatabaseTest, QueryTotalSizeUtilTimestampUsingOwnerWhenWorkspaceExists) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
const std::string deviceId = "1";
const uint64_t expectDuration = 20000000000;
const uint64_t timestamp = memoryDatabase->GetGlobalMinTimestamp() + expectDuration;
uint64_t originPtaTotalSize = memoryDatabase->QueryTotalSizeUntilTimestampUsingOwner(deviceId, timestamp, "PTA");
uint64_t originPtaWorkspaceTotalSize = memoryDatabase->QueryTotalSizeUntilTimestampUsingOwner(
deviceId, timestamp, MEM_SCOPE_ALLOC_OWNER_PTA_WORKSPACE);
EXPECT_EQ(originPtaWorkspaceTotalSize, 0);
EXPECT_GT(originPtaTotalSize, 0);
std::string testFlag = "DT-TEST";
MemoryBlock mockPTAWorkspaceBlock(testFlag, deviceId, 1, 0, timestamp + 1, MEM_SCOPE_ALLOC_OWNER_PTA_WORKSPACE,
MEM_SCOPE_ALLOC_OWNER_PTA_WORKSPACE, "", 0, 0);
memoryDatabase->InsertMemoryBlock(mockPTAWorkspaceBlock);
memoryDatabase->FlushMemoryBlocksCache();
uint64_t newPtaTotalSize =
memoryDatabase->QueryTotalSizeUntilTimestampUsingOwner(deviceId, timestamp, MEM_SCOPE_ALLOC_OWNER_PTA);
uint64_t newPtaWorkspaceTotalSize = memoryDatabase->QueryTotalSizeUntilTimestampUsingOwner(
deviceId, timestamp, MEM_SCOPE_ALLOC_OWNER_PTA_WORKSPACE);
EXPECT_EQ(newPtaTotalSize, originPtaTotalSize);
EXPECT_EQ(newPtaWorkspaceTotalSize, 1);
std::string clearSql = StringUtil::FormatString("DELETE FROM {} WHERE {} = '{}' AND {} = '{}'", TABLE_LEAKS_DUMP,
EventTableColumn::PTR, testFlag, EventTableColumn::EVENT_TYPE, MEM_SCOPE_ALLOC_OWNER_PTA_WORKSPACE);
EXPECT_TRUE(memoryDatabase->ExecSql(clearSql));
}
* 该DT用于测试msleaks采集时开启CallStack的场景
*/
TEST_F(MemScopeDatabaseTest, TestCompatibilityOfCallStack) {
auto memoryDatabase = DataBaseManager::Instance().GetMemScopeDatabase("0");
std::string addCallStackSql = StringUtil::FormatString(
"ALTER TABLE {} ADD {} TEXT DEFAULT 'N/A'", TABLE_LEAKS_DUMP, EventTableColumn::CALL_STACK_C);
EXPECT_TRUE(memoryDatabase->ExecSql(addCallStackSql));
std::string path = memoryDatabase->GetDbPath();
memoryDatabase->CloseDb();
EXPECT_TRUE(memoryDatabase->OpenDb(path, false));
EXPECT_TRUE(memoryDatabase->withCallStackC);
EXPECT_FALSE(memoryDatabase->withCallStackPython);
MemScopeEventParams queryParams;
queryParams.deviceId = "1";
queryParams.currentPage = 1;
queryParams.pageSize = 10;
std::vector<MemScopeEvent> events;
int64_t total = memoryDatabase->QueryEventsByRequestParams(queryParams, events);
EXPECT_TRUE(total > 0 && !events.empty());
EXPECT_EQ(events.front().callStackC, "N/A");
std::string clearCallStackSql =
StringUtil::FormatString("ALTER TABLE {} DROP COLUMN {}", TABLE_LEAKS_DUMP, EventTableColumn::CALL_STACK_C);
EXPECT_TRUE(memoryDatabase->ExecSql(clearCallStackSql));
}