* -------------------------------------------------------------------------
* 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 <iostream>
#include <fstream>
#include <cstdio>
#include <string>
#include "FileParser.h"
#include "JsonFileProcess.h"
class JsonFileProcessTest : public ::testing::Test {
protected:
class JsonFileProcessMock : protected Dic::Module::JsonFileProcess {
public:
static std::vector<std::pair<int64_t, int64_t>> SplitFileMock(
const std::string &filePath, std::optional<std::pair<int64_t, int64_t>> position = std::nullopt) {
return SplitFile(filePath, position);
}
};
const std::string tempFileName = "temp_test_file.json";
void TearDown() { DeleteTempFile(tempFileName); }
std::string GenerateLargeJsonArray(size_t sizeInBytes) {
const uint64_t offset = 10;
std::string jsonArray = "[";
while (jsonArray.size() < sizeInBytes - offset) {
jsonArray += "{\"ph\": \"Xvalue\"},";
}
if (jsonArray.back() == ',') {
jsonArray.back() = ']';
} else {
jsonArray += ']';
}
return jsonArray;
}
std::string GenerateLargeJsonDocument(size_t sizeInBytes) {
const uint64_t offset = 2;
std::string jsonDocument = "{\"traceEvents\":[";
std::string jsonObject = "{\"id\": 1, \"ph\": \"XXtest\"}";
size_t jsonObjectSize = jsonObject.size();
while (jsonDocument.size() + jsonObjectSize < sizeInBytes - offset) {
jsonDocument += jsonObject + ",";
}
if (jsonDocument.back() == ',') {
jsonDocument.back() = ']';
} else {
jsonDocument += ']';
}
jsonDocument += "}";
return jsonDocument;
}
std::string GenerateWrongEndJsonDocument(size_t sizeInBytes) {
const uint64_t offset = 2;
std::string jsonDocument = "{}]}\"traceEvents\":[";
std::string jsonObject = "{\"id\": 1, \"name\": \"test\"}";
size_t jsonObjectSize = jsonObject.size();
while (jsonDocument.size() + jsonObjectSize < sizeInBytes - offset) {
jsonDocument += jsonObject + ",";
}
jsonDocument += "}";
return jsonDocument;
}
std::string GenerateWrongStartJsonDocument(size_t sizeInBytes) {
const uint64_t offset = 2;
std::string jsonDocument = "{\"traceEvents\":@@@";
std::string jsonObject = "{\"id\": 1, \"name\": \"test\"}";
size_t jsonObjectSize = jsonObject.size();
while (jsonDocument.size() + jsonObjectSize < sizeInBytes - offset) {
jsonDocument += jsonObject + ",";
}
if (jsonDocument.back() == ',') {
jsonDocument.back() = ']';
} else {
jsonDocument += ']';
}
jsonDocument += "}";
return jsonDocument;
}
std::string WriteTempJsonFile(const std::string &data) {
std::ofstream tempFile(tempFileName, std::ios::out | std::ios::trunc);
if (tempFile.is_open()) {
tempFile << data;
tempFile.close();
} else {
throw std::runtime_error("Failed to create temporary file.");
}
return tempFileName;
}
void DeleteTempFile(const std::string &fileName) {
if (std::remove(fileName.c_str()) != 0) {
std::cerr << "Error deleting temporary file." << std::endl;
}
}
};
* 测试文件打开失败的情况
*/
TEST_F(JsonFileProcessTest, TestSplitFileWhenFileIsNotOpen) {
std::vector<std::pair<int64_t, int64_t>> res = JsonFileProcessMock::SplitFileMock(tempFileName);
const uint64_t expectSize = 0;
EXPECT_EQ(res.size(), expectSize);
}
* 测试0.5kb的json数组
*/
TEST_F(JsonFileProcessTest, TestSplitFileWhenJsonArrayFileIs500ByteThenReturn0and0) {
size_t sizeInBytes = 1024 / 2;
std::string json = GenerateLargeJsonArray(sizeInBytes);
WriteTempJsonFile(json);
std::vector<std::pair<int64_t, int64_t>> res = JsonFileProcessMock::SplitFileMock(tempFileName);
const uint64_t expectSize = 1;
const uint64_t expectStart = 0;
const uint64_t expectEnd = 0;
const uint64_t first = 0;
EXPECT_EQ(res.size(), expectSize);
EXPECT_EQ(res[first].first, expectStart);
EXPECT_EQ(res[first].second, expectEnd);
}
* 测试0.5kb的json对象
*/
TEST_F(JsonFileProcessTest, TestSplitFileWhenJsonObjectFileIs500ByteThenReturnOneSplit) {
size_t sizeInBytes = 1024 / 2;
std::string json = GenerateLargeJsonDocument(sizeInBytes);
WriteTempJsonFile(json);
std::vector<std::pair<int64_t, int64_t>> res = JsonFileProcessMock::SplitFileMock(tempFileName);
const uint64_t expectSize = 1;
const uint64_t expectStart = 16;
const uint64_t expectEnd = 508;
const uint64_t first = 0;
EXPECT_EQ(res.size(), expectSize);
EXPECT_EQ(res[first].first, expectStart);
EXPECT_EQ(res[first].second, expectEnd);
}
* 测试0.5kb的json对象没有开始位置
*/
TEST_F(JsonFileProcessTest, TestSplitFileWhenJsonObjectFileWithOutStartMarkThenReturnZeroSplit) {
size_t sizeInBytes = 1024 / 2;
std::string json = GenerateWrongStartJsonDocument(sizeInBytes);
WriteTempJsonFile(json);
std::vector<std::pair<int64_t, int64_t>> res = JsonFileProcessMock::SplitFileMock(tempFileName);
const uint64_t expectSize = 0;
EXPECT_EQ(res.size(), expectSize);
}
* 测试0.5kb的json对象没有开始位置
*/
TEST_F(JsonFileProcessTest, TestSplitFileWhenJsonObjectFileWithWrongEndMarkThenReturnZeroSplit) {
size_t sizeInBytes = 1024 / 2;
std::string json = GenerateWrongEndJsonDocument(sizeInBytes);
WriteTempJsonFile(json);
std::vector<std::pair<int64_t, int64_t>> res = JsonFileProcessMock::SplitFileMock(tempFileName);
const uint64_t expectSize = 0;
EXPECT_EQ(res.size(), expectSize);
}
* 测试9kb的json数组
*/
TEST_F(JsonFileProcessTest, TestSplitFileWhenJsonArrayFileIs9KBThenReturn0and0) {
size_t sizeInBytes = 1024 * 9;
std::string json = GenerateLargeJsonArray(sizeInBytes);
WriteTempJsonFile(json);
std::vector<std::pair<int64_t, int64_t>> res = JsonFileProcessMock::SplitFileMock(tempFileName);
const uint64_t expectSize = 1;
const uint64_t expectStart = 0;
const uint64_t expectEnd = 0;
const uint64_t first = 0;
EXPECT_EQ(res.size(), expectSize);
EXPECT_EQ(res[first].first, expectStart);
EXPECT_EQ(res[first].second, expectEnd);
}
* 测试9kb的json对象
*/
TEST_F(JsonFileProcessTest, TestSplitFileWhenJsonObjectFileIs9KBThenReturnReturnOneSplit) {
size_t sizeInBytes = 1024 * 9;
std::string json = GenerateLargeJsonDocument(sizeInBytes);
WriteTempJsonFile(json);
std::vector<std::pair<int64_t, int64_t>> res = JsonFileProcessMock::SplitFileMock(tempFileName);
const uint64_t expectSize = 1;
const uint64_t expectStart = 16;
const uint64_t expectEnd = 9192;
const uint64_t first = 0;
EXPECT_EQ(res.size(), expectSize);
EXPECT_EQ(res[first].first, expectStart);
EXPECT_EQ(res[first].second, expectEnd);
}
* 文件内有两块9kb的数据
*/
TEST_F(JsonFileProcessTest, TestSplitFileWhenTwoBlock9kbInFile) {
size_t sizeInBytes = 1024 * 9;
const std::string buffer = "llllllllll";
std::string json = GenerateLargeJsonDocument(sizeInBytes);
const std::string content = buffer + json + buffer + json + buffer;
WriteTempJsonFile(content);
std::pair<int64_t, int64_t> pos = {buffer.size(), sizeInBytes + buffer.size()};
std::vector<std::pair<int64_t, int64_t>> res = JsonFileProcessMock::SplitFileMock(tempFileName, pos);
const uint64_t expectSize = 1;
const uint64_t expectStart = 26;
const uint64_t expectEnd = 9202;
const uint64_t first = 0;
EXPECT_EQ(res.size(), expectSize);
EXPECT_EQ(res[first].first, expectStart);
EXPECT_EQ(res[first].second, expectEnd);
const int offset = 2;
pos = {expectEnd + buffer.size() + offset, content.size() - buffer.size()};
res = JsonFileProcessMock::SplitFileMock(tempFileName, pos);
const uint64_t secondExpectStart = 9231;
const uint64_t secondExpectEnd = 18407;
EXPECT_EQ(res.size(), expectSize);
EXPECT_EQ(res[first].first, secondExpectStart);
EXPECT_EQ(res[first].second, secondExpectEnd);
}
* 测试52MB的json对象
*/
TEST_F(JsonFileProcessTest, TestSplitFileWhenJsonObjectFileIs52MBThenReturnReturnTwoSplit) {
size_t sizeInBytes = 1024 * 1024 * 52;
std::string json = GenerateLargeJsonDocument(sizeInBytes);
WriteTempJsonFile(json);
std::vector<std::pair<int64_t, int64_t>> res = JsonFileProcessMock::SplitFileMock(tempFileName);
const uint64_t expectSize = 2;
const uint64_t expectStart = 16;
const uint64_t expectEnd = 52428832;
const uint64_t expectSecondStart = 52428834;
const uint64_t expectSecondEnd = 54525940;
const uint64_t first = 0;
const uint64_t second = 1;
EXPECT_EQ(res.size(), expectSize);
EXPECT_EQ(res[first].first, expectStart);
EXPECT_EQ(res[first].second, expectEnd);
EXPECT_EQ(res[second].first, expectSecondStart);
EXPECT_EQ(res[second].second, expectSecondEnd);
}
* 测试52MB的json数组
*/
TEST_F(JsonFileProcessTest, TestSplitFileWhenJsonArrayFileIs52MBThenReturnReturnTwoSplit) {
size_t sizeInBytes = 1024 * 1024 * 52;
std::string json = GenerateLargeJsonArray(sizeInBytes);
WriteTempJsonFile(json);
std::vector<std::pair<int64_t, int64_t>> res = JsonFileProcessMock::SplitFileMock(tempFileName);
const uint64_t expectSize = 2;
const uint64_t expectStart = 1;
const uint64_t expectEnd = 52428815;
const uint64_t expectSecondStart = 52428817;
const uint64_t expectSecondEnd = 54525952;
const uint64_t first = 0;
const uint64_t second = 1;
EXPECT_EQ(res.size(), expectSize);
EXPECT_EQ(res[first].first, expectStart);
EXPECT_EQ(res[first].second, expectEnd);
EXPECT_EQ(res[second].first, expectSecondStart);
EXPECT_EQ(res[second].second, expectSecondEnd);
}