261 lines
12 KiB
C++
261 lines
12 KiB
C++
//=======================================================================
|
||
// 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);
|
||
}
|