//======================================================================= // SqliteTest(gtest): 验证 SQLite 封装 10 个 insertData 写入正确。 // 不改动 SQLite 封装;用裸 sqlite3 打开同一文件读回验证。 //======================================================================= #include #include #include #include #include "sqlit3/SQLite.h" #include "sqlit3/sqlite3.h" static std::string tmpPath(const char* name) { return std::string("/tmp/pmsqlite_") + name + "_" + std::to_string(::getpid()) + ".db"; } static bool rawQueryInt(const std::string& path, const std::string& sql, long long& out) { sqlite3* db = nullptr; if (sqlite3_open(path.c_str(), &db) != SQLITE_OK) return false; sqlite3_stmt* stmt = nullptr; bool ok = false; if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) == SQLITE_OK) { if (sqlite3_step(stmt) == SQLITE_ROW) { out = sqlite3_column_int64(stmt, 0); ok = true; } } if (stmt) sqlite3_finalize(stmt); sqlite3_close(db); return ok; } static bool rawCount(const std::string& path, const std::string& table, long long& out) { return rawQueryInt(path, "SELECT COUNT(*) FROM " + table, out); } static bool rawQueryText(const std::string& path, const std::string& sql, std::string& out) { sqlite3* db = nullptr; if (sqlite3_open(path.c_str(), &db) != SQLITE_OK) return false; sqlite3_stmt* stmt = nullptr; bool ok = false; if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) == SQLITE_OK) { if (sqlite3_step(stmt) == SQLITE_ROW) { const unsigned char* t = sqlite3_column_text(stmt, 0); if (t) { out = reinterpret_cast(t); ok = true; } } } if (stmt) sqlite3_finalize(stmt); sqlite3_close(db); return ok; } TEST(SqliteTest, InsertCcuStateReadBack) { std::string path = tmpPath("ccu"); { SQLite db(path); ASSERT_TRUE(db.createTable()); ccuState c{}; c.ins_soc = 42; c.dyn_soc = 66; c.fc_status = 4; EXPECT_TRUE(db.insertData(c)); } long long v = 0; EXPECT_TRUE(rawQueryInt(path, "SELECT ins_soc FROM ccuState ORDER BY id DESC LIMIT 1", v)); EXPECT_EQ(v, 42); EXPECT_TRUE(rawQueryInt(path, "SELECT dyn_soc FROM ccuState ORDER BY id DESC LIMIT 1", v)); EXPECT_EQ(v, 66); EXPECT_TRUE(rawQueryInt(path, "SELECT fc_status FROM ccuState ORDER BY id DESC LIMIT 1", v)); EXPECT_EQ(v, 4); std::remove(path.c_str()); } TEST(SqliteTest, InsertDisHighVolBusStateReadBack) { std::string path = tmpPath("dihv"); { SQLite db(path); ASSERT_TRUE(db.createTable()); disHighVolBusState s{}; s.fuelCellCircuitBreaker = 1; s.powerBusVoltage = 5200; EXPECT_TRUE(db.insertData(s)); } long long v = 0; EXPECT_TRUE(rawQueryInt(path, "SELECT fuelCellCircuitBreaker FROM disHighVolBusState ORDER BY id DESC LIMIT 1", v)); EXPECT_EQ(v, 1); EXPECT_TRUE(rawQueryInt(path, "SELECT powerBusVoltage FROM disHighVolBusState ORDER BY id DESC LIMIT 1", v)); EXPECT_EQ(v, 5200); std::remove(path.c_str()); } TEST(SqliteTest, InsertDisHighAVolBusStateReadBack) { std::string path = tmpPath("dihva"); { SQLite db(path); ASSERT_TRUE(db.createTable()); disHighAVolBusState s{}; s.bowFTDevice123CircuitBreaker = 1; s.busbarBVoltage = 100; EXPECT_TRUE(db.insertData(s)); } long long v = 0; EXPECT_TRUE(rawQueryInt(path, "SELECT bowFTDevice123CircuitBreaker FROM disHighAVolBusState", v)); EXPECT_EQ(v, 1); EXPECT_TRUE(rawQueryInt(path, "SELECT busbarBVoltage FROM disHighAVolBusState", v)); EXPECT_EQ(v, 100); std::remove(path.c_str()); } TEST(SqliteTest, InsertDisLowMainBusStateReadBack) { std::string path = tmpPath("dilmb"); { SQLite db(path); ASSERT_TRUE(db.createTable()); disLowMainBusState s{}; s.unit4InstrumentDC48VCircuitBreaker = 1; EXPECT_TRUE(db.insertData(s)); } long long v = 0; EXPECT_TRUE(rawQueryInt(path, "SELECT unit4InstrumentDC48VCircuitBreaker FROM disLowMainBusState", v)); EXPECT_EQ(v, 1); std::remove(path.c_str()); } TEST(SqliteTest, InsertDisLowBusStateReadBack) { std::string path = tmpPath("dilb"); { SQLite db(path); ASSERT_TRUE(db.createTable()); disLowBusState s{}; s.unit1CircuitBreaker = 1; EXPECT_TRUE(db.insertData(s)); } long long v = 0; EXPECT_TRUE(rawQueryInt(path, "SELECT unit1CircuitBreaker FROM disLowBusState", v)); EXPECT_EQ(v, 1); std::remove(path.c_str()); } TEST(SqliteTest, InsertCommandsReadBack) { std::string path = tmpPath("cmd"); { SQLite db(path); ASSERT_TRUE(db.createTable()); ccuColCmd cc{}; cc.heartbeat = 5; EXPECT_TRUE(db.insertData(cc)); disHighVolBusCmd c1{}; c1.dcdc5Module = 1; c1.coolingSystem = 1; EXPECT_TRUE(db.insertData(c1)); disHighAVolBusCmd c2{}; c2.xczCircuitBreaker = 1; EXPECT_TRUE(db.insertData(c2)); disLowMainBusCmd c3{}; c3.dcC1DCDistributionPanelCircuitBreaker = 1; EXPECT_TRUE(db.insertData(c3)); disLowBusCmd c4{}; c4.unit2CircuitBreaker = 1; EXPECT_TRUE(db.insertData(c4)); } long long v = 0; EXPECT_TRUE(rawQueryInt(path, "SELECT heartbeat FROM ccuColCmd", v)); EXPECT_EQ(v, 5); EXPECT_TRUE(rawQueryInt(path, "SELECT dcdc5Module FROM disHighVolBusCmd", v)); EXPECT_EQ(v, 1); EXPECT_TRUE(rawQueryInt(path, "SELECT xczCircuitBreaker FROM disHighAVolBusCmd", v)); EXPECT_EQ(v, 1); EXPECT_TRUE(rawQueryInt(path, "SELECT dcC1DCDistributionPanelCircuitBreaker FROM disLowMainBusCmd", v)); EXPECT_EQ(v, 1); EXPECT_TRUE(rawQueryInt(path, "SELECT unit2CircuitBreaker FROM disLowBusCmd", v)); EXPECT_EQ(v, 1); std::remove(path.c_str()); } TEST(SqliteTest, MultipleInsertsCount) { std::string path = tmpPath("multi"); { SQLite db(path); ASSERT_TRUE(db.createTable()); ccuState c{}; c.ins_soc = 10; EXPECT_TRUE(db.insertData(c)); EXPECT_TRUE(db.insertData(c)); EXPECT_TRUE(db.insertData(c)); } long long n = 0; EXPECT_TRUE(rawCount(path, "ccuState", n)); EXPECT_EQ(n, 3); std::remove(path.c_str()); } TEST(SqliteTest, InsertCcuSetParmCmdReadBack) { std::string path = tmpPath("setparmcmd"); { SQLite db(path); ASSERT_TRUE(db.createTable()); ccuSetParmCmd c{}; c.insSocHold1 = 7; c.powerSocHold2 = 88; EXPECT_TRUE(db.insertData(c)); } long long v = 0; EXPECT_TRUE(rawQueryInt(path, "SELECT insSocHold1 FROM ccuSetParmCmd", v)); EXPECT_EQ(v, 7); EXPECT_TRUE(rawQueryInt(path, "SELECT powerSocHold2 FROM ccuSetParmCmd", v)); EXPECT_EQ(v, 88); std::remove(path.c_str()); } TEST(SqliteTest, InsertCcuSetParmFbReadBack) { std::string path = tmpPath("setparmfb"); { SQLite db(path); ASSERT_TRUE(db.createTable()); msg_CcuSetParmFbMsg fb{}; fb.flag = 1; fb.failureCode = 2; EXPECT_TRUE(db.insertData(fb)); } long long v = 0; EXPECT_TRUE(rawQueryInt(path, "SELECT flag FROM ccuSetParmFb", v)); EXPECT_EQ(v, 1); EXPECT_TRUE(rawQueryInt(path, "SELECT failureCode FROM ccuSetParmFb", v)); EXPECT_EQ(v, 2); std::remove(path.c_str()); } TEST(SqliteTest, LogRawFrameReadBack) { std::string path = tmpPath("raw"); { SQLite db(path); ASSERT_TRUE(db.createTable()); const unsigned char frame[] = {0x20, 0x20, 0x51, 0x00, 0x01, 0x02, 0x03}; db.onFrame(0, 0x0051, "ccuState", frame, sizeof(frame), true); db.onFrame(1, 0x0001, "disHighVolBusCmd", frame, sizeof(frame), true); } long long n = 0; EXPECT_TRUE(rawCount(path, "msg_log", n)); EXPECT_EQ(n, 2); std::string hex; EXPECT_TRUE(rawQueryText(path, "SELECT payload_hex FROM msg_log ORDER BY id LIMIT 1", hex)); EXPECT_EQ(hex, "20205100010203"); long long dir = 0; EXPECT_TRUE(rawQueryInt(path, "SELECT direction FROM msg_log ORDER BY id DESC LIMIT 1", dir)); EXPECT_EQ(dir, 1); std::remove(path.c_str()); } TEST(SqliteTest, InvalidPathIsFailOpen) { SQLite db("/invalid/path/nonexistent_dir/test.db"); EXPECT_EQ(db.status(), SQLite::Status::Disabled); EXPECT_FALSE(db.isConnected()); ccuState c{}; c.ins_soc = 1; EXPECT_FALSE(db.insertData(c)); // 不抛异常,返回 false ccuColCmd cmd{}; EXPECT_FALSE(db.insertData(cmd)); const unsigned char frame[] = {0x20, 0x20}; db.onFrame(0, 0x0051, "ccuState", frame, sizeof(frame), true); // 不崩溃 } TEST(SqliteTest, CorruptDatabaseRecovered) { std::string path = tmpPath("corrupt"); { // 写入非 SQLite 内容,模拟损坏的库文件 FILE* f = fopen(path.c_str(), "wb"); ASSERT_TRUE(f != nullptr); for (int i = 0; i < 4096; ++i) fputc((i * 7 + 3) & 0xFF, f); fclose(f); SQLite db(path); // 应能备份损坏文件并重建,恢复可用 EXPECT_EQ(db.status(), SQLite::Status::OK); EXPECT_TRUE(db.isConnected()); ccuState c{}; c.ins_soc = 99; EXPECT_TRUE(db.insertData(c)); } long long v = 0; EXPECT_TRUE(rawQueryInt(path, "SELECT ins_soc FROM ccuState", v)); EXPECT_EQ(v, 99); std::remove(path.c_str()); std::remove((path + ".corrupt").c_str()); }