Files
H100PowerManger/test/until/DriverTest.cpp
T

261 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//=======================================================================
// DriverTest: Driver 类的设备表生成(覆盖全部 10 个工况)、设备状态读写、
// JSON 序列化/反序列化。
// 不改动生产代码;仅链接 src/pPowerManger/driver.cpp。
//
// 测试目的:
// 1. 验证每种工况模式下,驱动表生成是否符合预期的设备开关状态
// 2. 验证设备状态的读写操作(setDeviceState / getDeviceState)
// 3. 验证驱动表的 JSON 序列化/反序列化是否能正确往返
// 4. 验证 JSON 解析为设备命令的逻辑
// 5. 验证安全读取无符号整数的边界处理
//=======================================================================
#include <gtest/gtest.h>
#include <cstring>
#include "driver.h"
#include "pmSysvariable.h"
// ----------------------------------------------------------------------
// 全字段比较宏(62 个设备字段)
// 用于比较两个 DriverTable 结构体的所有字段是否完全相等
// ----------------------------------------------------------------------
#define EXPECT_TABLE_EQ(a, b) do { \
EXPECT_EQ((a).depth1,(b).depth1); EXPECT_EQ((a).depth2,(b).depth2); \
EXPECT_EQ((a).depth3,(b).depth3); EXPECT_EQ((a).overDeep1,(b).overDeep1); \
EXPECT_EQ((a).overDeep2,(b).overDeep2); EXPECT_EQ((a).ctd1,(b).ctd1); \
EXPECT_EQ((a).ctd2,(b).ctd2); EXPECT_EQ((a).soundVeloc,(b).soundVeloc); \
EXPECT_EQ((a).commMast,(b).commMast); EXPECT_EQ((a).ins,(b).ins); \
EXPECT_EQ((a).ntp,(b).ntp); \
EXPECT_EQ((a).inputWaterSensor1,(b).inputWaterSensor1); \
EXPECT_EQ((a).inputWaterSensor2,(b).inputWaterSensor2); \
EXPECT_EQ((a).inputWaterSensor3,(b).inputWaterSensor3); \
EXPECT_EQ((a).singleBeamSonar1,(b).singleBeamSonar1); \
EXPECT_EQ((a).singleBeamSonar2,(b).singleBeamSonar2); \
EXPECT_EQ((a).singleBeamSonar3,(b).singleBeamSonar3); \
EXPECT_EQ((a).singleBeamSonar4,(b).singleBeamSonar4); \
EXPECT_EQ((a).singleBeamSonar5,(b).singleBeamSonar5); \
EXPECT_EQ((a).singleBeamSonar6,(b).singleBeamSonar6); \
EXPECT_EQ((a).singleBeamSonar7,(b).singleBeamSonar7); \
EXPECT_EQ((a).singleBeamSonar8,(b).singleBeamSonar8); \
EXPECT_EQ((a).forwardSonar,(b).forwardSonar); EXPECT_EQ((a).DVL,(b).DVL); \
EXPECT_EQ((a).lowFreqSonar,(b).lowFreqSonar); EXPECT_EQ((a).USBL,(b).USBL); \
EXPECT_EQ((a).bowWaterInet1,(b).bowWaterInet1); \
EXPECT_EQ((a).bowWaterInet2,(b).bowWaterInet2); \
EXPECT_EQ((a).bowWaterInet3,(b).bowWaterInet3); \
EXPECT_EQ((a).bowWaterInet4,(b).bowWaterInet4); \
EXPECT_EQ((a).bowWaterInet5,(b).bowWaterInet5); \
EXPECT_EQ((a).bowWaterInet6,(b).bowWaterInet6); \
EXPECT_EQ((a).bowWaterInet7,(b).bowWaterInet7); \
EXPECT_EQ((a).bowWaterInet8,(b).bowWaterInet8); \
EXPECT_EQ((a).bowRudderDeploy,(b).bowRudderDeploy); \
EXPECT_EQ((a).bowRudderServo1,(b).bowRudderServo1); \
EXPECT_EQ((a).bowRudderServo2,(b).bowRudderServo2); \
EXPECT_EQ((a).bowCover1,(b).bowCover1); EXPECT_EQ((a).bowCover2,(b).bowCover2); \
EXPECT_EQ((a).bowCover3,(b).bowCover3); EXPECT_EQ((a).bowCover4,(b).bowCover4); \
EXPECT_EQ((a).bowCover5,(b).bowCover5); EXPECT_EQ((a).bowCover6,(b).bowCover6); \
EXPECT_EQ((a).waterInject,(b).waterInject); \
EXPECT_EQ((a).mastLiftingServo,(b).mastLiftingServo); \
EXPECT_EQ((a).buoyancyAdjust1,(b).buoyancyAdjust1); \
EXPECT_EQ((a).buoyancyAdjust2,(b).buoyancyAdjust2); \
EXPECT_EQ((a).buoyancyAdjust3,(b).buoyancyAdjust3); \
EXPECT_EQ((a).buoyancyAdjust4,(b).buoyancyAdjust4); \
EXPECT_EQ((a).buoyancyAdjust5,(b).buoyancyAdjust5); \
EXPECT_EQ((a).sternRudderServo1,(b).sternRudderServo1); \
EXPECT_EQ((a).sternRudderServo2,(b).sternRudderServo2); \
EXPECT_EQ((a).sternRudderServo3,(b).sternRudderServo3); \
EXPECT_EQ((a).sternRudderServo4,(b).sternRudderServo4); \
EXPECT_EQ((a).thruster,(b).thruster); EXPECT_EQ((a).bowThrow,(b).bowThrow); \
EXPECT_EQ((a).sternThrow,(b).sternThrow); \
EXPECT_EQ((a).photoSensor,(b).photoSensor); \
EXPECT_EQ((a).electSensor,(b).electSensor); \
EXPECT_EQ((a).launchControler,(b).launchControler); \
EXPECT_EQ((a).sideSonar,(b).sideSonar); EXPECT_EQ((a).buoyage,(b).buoyage); \
} while (0)
// 传感器统一全开
static void setSensors(DriverTable& t) {
t.depth1 = t.depth2 = t.depth3 = 1;
t.overDeep1 = t.overDeep2 = 1;
t.ctd1 = t.ctd2 = 1;
t.soundVeloc = 1;
t.commMast = 1;
t.ins = 1;
t.ntp = 1;
t.inputWaterSensor1 = t.inputWaterSensor2 = t.inputWaterSensor3 = 1;
}
// 执行机构(舵/浮调/推进/抛载)全开
static void setActuatorsOn(DriverTable& t) {
t.bowRudderDeploy = t.bowRudderServo1 = t.bowRudderServo2 = 1;
t.buoyancyAdjust1 = t.buoyancyAdjust2 = t.buoyancyAdjust3 = 1;
t.buoyancyAdjust4 = t.buoyancyAdjust5 = 1;
t.sternRudderServo1 = t.sternRudderServo2 = t.sternRudderServo3 = t.sternRudderServo4 = 1;
t.thruster = 1;
t.bowThrow = t.sternThrow = 1;
}
static DriverTable makeSTANDBY() {
DriverTable t{}; setSensors(t); /* 其余全 0 */ return t;
}
static DriverTable makeSHORE_WATER() {
DriverTable t{}; setSensors(t); setActuatorsOn(t);
t.mastLiftingServo = 1;
t.bowCover1 = t.bowCover2 = t.bowCover3 = 1;
t.bowCover4 = t.bowCover5 = t.bowCover6 = 1;
t.bowWaterInet1 = t.bowWaterInet2 = t.bowWaterInet3 = t.bowWaterInet4 = 1;
t.bowWaterInet5 = t.bowWaterInet6 = t.bowWaterInet7 = t.bowWaterInet8 = 1;
t.waterInject = 1;
return t;
}
static DriverTable makeCRUISE() {
DriverTable t{}; setSensors(t); setActuatorsOn(t);
t.mastLiftingServo = 1;
return t; // 水声设备不设置(保持 0)
}
static DriverTable makeHIGH_SPEED() {
DriverTable t{}; setSensors(t);
t.bowRudderDeploy = t.bowRudderServo1 = t.bowRudderServo2 = 1;
t.sternRudderServo1 = t.sternRudderServo2 = t.sternRudderServo3 = t.sternRudderServo4 = 1;
t.thruster = 1; t.bowThrow = t.sternThrow = 1;
/* mastLiftingServo / buoyancyAdjust 全 0 */
return t;
}
static DriverTable makeASCEND_BUOYANCY() {
DriverTable t{}; setSensors(t); setActuatorsOn(t);
t.mastLiftingServo = 1;
return t;
}
static DriverTable makeUNDERWATER() {
DriverTable t{}; setSensors(t); setActuatorsOn(t);
t.sideSonar = DRIVER_STANDBY; /* mastLiftingServo = 0 */
return t;
}
static DriverTable makeSURFACE() {
DriverTable t{}; setSensors(t); setActuatorsOn(t);
t.mastLiftingServo = 1;
t.photoSensor = t.electSensor = DRIVER_STANDBY;
return t;
}
static DriverTable makeDJ() {
DriverTable t{}; setSensors(t); setActuatorsOn(t);
t.mastLiftingServo = 1;
t.launchControler = 1;
t.buoyage = DRIVER_STANDBY;
t.bowCover1 = t.bowCover2 = t.bowCover3 = 1;
t.bowCover4 = t.bowCover5 = t.bowCover6 = 1;
t.bowWaterInet1 = t.bowWaterInet2 = t.bowWaterInet3 = t.bowWaterInet4 = 1;
t.bowWaterInet5 = t.bowWaterInet6 = t.bowWaterInet7 = t.bowWaterInet8 = 1;
return t;
}
using TableFn = void (Driver::*)(DriverTable*);
TEST(DriverTest, StandbyTable) {
DriverTable e = makeSTANDBY(); DriverTable a{}; Driver d; d.getSTANDBYTable(&a);
EXPECT_TABLE_EQ(a, e);
}
TEST(DriverTest, ShoreBasedReadyTable) {
DriverTable e = makeSHORE_WATER(); DriverTable a{}; Driver d; d.getSHORE_BASED_READYable(&a);
EXPECT_TABLE_EQ(a, e);
}
TEST(DriverTest, WaterBasedReadyTable) {
DriverTable e = makeSHORE_WATER(); DriverTable a{}; Driver d; d.getWATER_BASED_READYable(&a);
EXPECT_TABLE_EQ(a, e);
}
TEST(DriverTest, CruiseModeTable) {
DriverTable e = makeCRUISE(); DriverTable a{}; Driver d; d.getCRUISE_MODEable(&a);
EXPECT_TABLE_EQ(a, e);
}
TEST(DriverTest, HighSpeedModeTable) {
DriverTable e = makeHIGH_SPEED(); DriverTable a{}; Driver d; d.getHIGH_SPEED_MODEable(&a);
EXPECT_TABLE_EQ(a, e);
}
TEST(DriverTest, AscendDescendTable) {
DriverTable e = makeASCEND_BUOYANCY(); DriverTable a{}; Driver d; d.getASCEND_DESCENDable(&a);
EXPECT_TABLE_EQ(a, e);
}
TEST(DriverTest, BuoyancyAdjustTable) {
DriverTable e = makeASCEND_BUOYANCY(); DriverTable a{}; Driver d; d.getBUOYANCY_ADJUSTable(&a);
EXPECT_TABLE_EQ(a, e);
}
TEST(DriverTest, UnderwaterReconTable) {
DriverTable e = makeUNDERWATER(); DriverTable a{}; Driver d; d.getUNDERWATER_RECONable(&a);
EXPECT_TABLE_EQ(a, e);
}
TEST(DriverTest, SurfaceReconTable) {
DriverTable e = makeSURFACE(); DriverTable a{}; Driver d; d.getSURFACE_RECONable(&a);
EXPECT_TABLE_EQ(a, e);
}
TEST(DriverTest, DjModeTable) {
DriverTable e = makeDJ(); DriverTable a{}; Driver d; d.getDJ_MODEable(&a);
EXPECT_TABLE_EQ(a, e);
}
// ----------------------------------------------------------------------
// setDeviceState / getDeviceState
// ----------------------------------------------------------------------
TEST(DriverTest, SetGetDeviceState)
{
Driver d;
DriverTable t{};
d.setDeviceState(t, DeviceId::thruster, DRIVER_FULL_POWER_ON);
EXPECT_EQ(d.getDeviceState(t, DeviceId::thruster), 1u);
d.setDeviceState(t, DeviceId::thruster, DRIVER_POWER_OFF);
EXPECT_EQ(d.getDeviceState(t, DeviceId::thruster), 0u);
d.setDeviceState(t, DeviceId::sideSonar, DRIVER_STANDBY);
EXPECT_EQ(d.getDeviceState(t, DeviceId::sideSonar), 4u);
d.setDeviceState(t, DeviceId::bowCover1, DRIVER_FULL_POWER_ON);
EXPECT_EQ(d.getDeviceState(t, DeviceId::bowCover1), 1u);
}
// ----------------------------------------------------------------------
// JSON 序列化/反序列化往返
// ----------------------------------------------------------------------
TEST(DriverTest, JsonRoundTrip)
{
Driver d;
DriverTable t{};
d.setDeviceState(t, DeviceId::thruster, DRIVER_FULL_POWER_ON);
d.setDeviceState(t, DeviceId::sideSonar, DRIVER_STANDBY);
d.setDeviceState(t, DeviceId::bowCover3, DRIVER_FULL_POWER_ON);
std::string json = d.saveDriverTableToJson(&t);
ASSERT_FALSE(json.empty());
DriverTable out{};
EXPECT_EQ(d.loadDriverTableFromJson(json, out), 0);
EXPECT_EQ(out.thruster, 1u);
EXPECT_EQ(out.sideSonar, 4u);
EXPECT_EQ(out.bowCover3, 1u);
EXPECT_EQ(out.depth1, 0u); // 未设置字段为 0
}
TEST(DriverTest, LoadDriverIdFromJson)
{
Driver d;
std::string json = R"({"thruster_uint8":1,"sideSonar_uint8":4})";
auto cmds = d.loadDriverIdFromJson(json);
ASSERT_EQ(cmds.size(), 2u);
bool hasThruster = false, hasSide = false;
for (auto& c : cmds) {
if (c.id == DeviceId::thruster) { EXPECT_EQ(c.cmd, 1); hasThruster = true; }
if (c.id == DeviceId::sideSonar) { EXPECT_EQ(c.cmd, 4); hasSide = true; }
}
EXPECT_TRUE(hasThruster);
EXPECT_TRUE(hasSide);
}
TEST(DriverTest, SafeReadUInt)
{
Driver d;
Json::Value root;
root["a"] = 5u;
root["b"] = -3;
unsigned char v = 0;
EXPECT_EQ(d.SafeReadUInt(root, "a", v), 0);
EXPECT_EQ(v, 5u);
// 缺字段
EXPECT_EQ(d.SafeReadUInt(root, "missing", v), -1);
// 类型错误(有符号负数)
EXPECT_EQ(d.SafeReadUInt(root, "b", v), -2);
}