//======================================================================= // DriverTest: Driver 类的设备表生成(覆盖全部 10 个工况)、设备状态读写、 // JSON 序列化/反序列化。 // 不改动生产代码;仅链接 src/pPowerManger/driver.cpp。 // // 测试目的: // 1. 验证每种工况模式下,驱动表生成是否符合预期的设备开关状态 // 2. 验证设备状态的读写操作(setDeviceState / getDeviceState) // 3. 验证驱动表的 JSON 序列化/反序列化是否能正确往返 // 4. 验证 JSON 解析为设备命令的逻辑 // 5. 验证安全读取无符号整数的边界处理 //======================================================================= #include #include #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); }