429 lines
13 KiB
C++
Executable File
429 lines
13 KiB
C++
Executable File
/**
|
|
* AES Function Topic Client test executable
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
#include "aes_test_explosion_area.h"
|
|
#include <QCoreApplication>
|
|
#include <QTimer>
|
|
#include <QTest>
|
|
|
|
namespace AreaEffectSimulation
|
|
{
|
|
|
|
// must be in pdm.pdm_charge_type
|
|
static const int s_ChargeTypeId1 = 371;
|
|
static const int s_ChargeTypeId2 = 372;
|
|
|
|
TestExplosionArea::TestExplosionArea(QObject *parent)
|
|
: TestBase("Test.ExplosionArea", parent)
|
|
{}
|
|
|
|
bool TestExplosionArea::init(int domainId, int exerciseId, int testId)
|
|
{
|
|
if (!TestBase::init(domainId, exerciseId, testId))
|
|
return false;
|
|
|
|
m_dtc->waitForHistoricalDataExplosionArea();
|
|
m_eaData.id(-1);
|
|
|
|
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionAreaChanged,
|
|
this, &TestExplosionArea::explosionAreaChanged);
|
|
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::triggeredImpactsChanged,
|
|
this, &TestExplosionArea::triggeredImpactsChanged);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TestExplosionArea::checkBaseData(const AreaEffectSimulation::ExplosionArea &a,
|
|
const AreaEffectSimulation::ExplosionArea &b) const
|
|
{
|
|
if (!checkAesItem(a, b))
|
|
return false;
|
|
|
|
if (a.area() != b.area())
|
|
{
|
|
WARNING_LOG(m_logger) << "area does not match: " << a.area() << " - " << b.area();
|
|
return false;
|
|
}
|
|
if (a.cannonCount() != b.cannonCount())
|
|
{
|
|
WARNING_LOG(m_logger) << "cannonCount does not match: " << a.cannonCount() << " - " << b.cannonCount();
|
|
return false;
|
|
}
|
|
if (a.cannonRounds() != b.cannonRounds())
|
|
{
|
|
WARNING_LOG(m_logger) << "cannonCount does not match: " << a.cannonCount() << " - " << b.cannonCount();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void TestExplosionArea::tryCreateExplosionArea()
|
|
{
|
|
INFO_LOG(m_logger) << "tryCreateExplosionArea start";
|
|
m_eaData = AreaEffectSimulation::ExplosionArea();
|
|
AreaEffectSimulation::ExplosionArea eaData;
|
|
eaData.id(0);
|
|
eaData.name("af1");
|
|
eaData.effectStart((time(nullptr) + 4) * 1000); // msec
|
|
eaData.effectDuration(10000); // 10 seconds
|
|
eaData.chargeStruct().chargeTypeId(345863487);
|
|
eaData.area(AreaEffectSimulation::Area(Core::GeoPosition2D(0.16, 0.92), 50, 60, 70));
|
|
eaData.partyId(2);
|
|
eaData.participantId(1234);
|
|
eaData.cannonCount(1);
|
|
eaData.cannonRounds(2);
|
|
eaData.externalId(2);
|
|
|
|
INFO_LOG(m_logger) << "trying to send explosionAreaCreateRequest()";
|
|
m_replyError = false;
|
|
m_bExpectedFailure = true;
|
|
m_bIsCreatedRequest = true;
|
|
if (!m_ftc->explosionAreaModifyRequest(
|
|
ExplosionAreaModifyRequest(
|
|
0,
|
|
eaData.name(),
|
|
eaData.effectStart(),
|
|
eaData.effectDuration(),
|
|
eaData.effectSourceId(),
|
|
eaData.chargeStruct().chargeTypeId(),
|
|
eaData.area(),
|
|
eaData.partyId(),
|
|
eaData.participantId(),
|
|
eaData.cannonCount(),
|
|
eaData.cannonRounds(),
|
|
eaData.fireRequestTime(),
|
|
eaData.altitude(),
|
|
eaData.purpose(),
|
|
eaData.effectMarkingInTa(),
|
|
eaData.externalId()
|
|
),
|
|
this))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error during explosionAreaCreateRequest()";
|
|
failExit();
|
|
return;
|
|
}
|
|
// since the chargeTypeId is not valid, we should get an error
|
|
if (!waitForData([this]() { return m_replyError == true; }))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error creating area explosion object (try with error)";
|
|
failExit();
|
|
return;
|
|
}
|
|
|
|
// now with correct charge type
|
|
m_bExpectedFailure = false;
|
|
m_expectedAesId = -1;
|
|
|
|
eaData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
|
|
m_bIsCreatedRequest = true;
|
|
if (!m_ftc->explosionAreaModifyRequest(
|
|
ExplosionAreaModifyRequest(
|
|
0,
|
|
eaData.name(),
|
|
eaData.effectStart(),
|
|
eaData.effectDuration(),
|
|
eaData.effectSourceId(),
|
|
eaData.chargeStruct().chargeTypeId(),
|
|
eaData.area(),
|
|
eaData.partyId(),
|
|
eaData.participantId(),
|
|
eaData.cannonCount(),
|
|
eaData.cannonRounds(),
|
|
eaData.fireRequestTime(),
|
|
eaData.altitude(),
|
|
eaData.purpose(),
|
|
eaData.effectMarkingInTa(),
|
|
eaData.externalId()),
|
|
this))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error during explosionAreaCreateRequest()";
|
|
failExit();
|
|
return;
|
|
}
|
|
|
|
if (!waitForData([this]() { return m_eaData.id() == m_expectedAesId; }))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error creating area explosion object";
|
|
failExit();
|
|
return;
|
|
}
|
|
if (!checkBaseData(m_eaData, eaData))
|
|
{
|
|
ERROR_LOG(m_logger) << "Creation data does not match published data";
|
|
failExit();
|
|
return;
|
|
}
|
|
QTimer::singleShot(0, this, &TestExplosionArea::tryModifyExplosionArea);
|
|
INFO_LOG(m_logger) << "tryCreateExplosionArea successful";
|
|
}
|
|
|
|
|
|
void TestExplosionArea::tryModifyExplosionArea()
|
|
{
|
|
INFO_LOG(m_logger) << "tryModifyExplosionArea start";
|
|
m_eaData.name("af2");
|
|
m_eaData.effectStart(m_eaData.effectStart().get() + 3000);
|
|
m_eaData.effectDuration(9000); // 9 sec
|
|
m_eaData.chargeStruct().chargeTypeId(s_ChargeTypeId2);
|
|
m_eaData.area(AreaEffectSimulation::Area(Core::GeoPosition2D(0.165, 0.921), 50, 60, 70));
|
|
m_eaData.partyId(3);
|
|
m_eaData.participantId(1235);
|
|
m_eaData.cannonCount(2);
|
|
m_eaData.cannonRounds(2);
|
|
m_eaData.effectMarkingInTa(true);
|
|
|
|
const AreaEffectSimulation::ExplosionArea eaData(m_eaData);
|
|
m_eaData = AreaEffectSimulation::ExplosionArea();
|
|
m_eaData.id(eaData.id());
|
|
m_bIsCreatedRequest = false;
|
|
|
|
if (!m_ftc->explosionAreaModifyRequest(
|
|
ExplosionAreaModifyRequest(
|
|
eaData.id(),
|
|
eaData.name(),
|
|
eaData.effectStart(),
|
|
eaData.effectDuration(),
|
|
eaData.effectSourceId(),
|
|
eaData.chargeStruct().chargeTypeId(),
|
|
eaData.area(),
|
|
eaData.partyId(),
|
|
eaData.participantId(),
|
|
eaData.cannonCount(),
|
|
eaData.cannonRounds(),
|
|
eaData.fireRequestTime(),
|
|
eaData.altitude(),
|
|
eaData.purpose(),
|
|
eaData.effectMarkingInTa(),
|
|
eaData.externalId()),
|
|
this))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error requesting modify data";
|
|
failExit();
|
|
return;
|
|
}
|
|
if (!waitForData([this]() { return m_eaData.chargeStruct().chargeTypeId() == s_ChargeTypeId2; }))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error updating area explosion object";
|
|
failExit();
|
|
return;
|
|
}
|
|
if (!checkBaseData(m_eaData, eaData))
|
|
{
|
|
ERROR_LOG(m_logger) << "Modify data does not match published data";
|
|
failExit();
|
|
return;
|
|
}
|
|
QTimer::singleShot(0, this, &TestExplosionArea::tryWaitForActivationExplosionArea);
|
|
INFO_LOG(m_logger) << "tryModifyExplosionArea successful";
|
|
}
|
|
|
|
|
|
void TestExplosionArea::tryWaitForActivationExplosionArea()
|
|
{
|
|
INFO_LOG(m_logger) << "tryWaitForActivationExplosionArea start";
|
|
|
|
if (!waitForData([this]() { return m_eaData.effectStateId() == AreaEffectSimulation::AesEffectState::EsActivated; }))
|
|
{
|
|
DEBUG_LOG(m_logger) << "Effect State = " << m_eaData.effectStateId();
|
|
ERROR_LOG(m_logger) << "Error while waiting for activation of area explosion";
|
|
failExit();
|
|
return;
|
|
}
|
|
QTimer::singleShot(0, this, &TestExplosionArea::tryPauseResumeExplosionArea);
|
|
INFO_LOG(m_logger) << "tryWaitForActivationExplosionArea end";
|
|
}
|
|
|
|
void TestExplosionArea::tryPauseResumeExplosionArea()
|
|
{
|
|
INFO_LOG(m_logger) << "tryPauseResumeExplosionArea start";
|
|
// try to resume but is already active -> expected error
|
|
m_replyError = false;
|
|
m_bExpectedFailure = true;
|
|
if (!m_ftc->explosionAreaPauseResumeRequest(
|
|
ExplosionAreaPauseResumeRequest(
|
|
m_eaData.id(),
|
|
true,
|
|
dds::core::optional<rti::core::int64>(),
|
|
dds::core::optional<int32_t>(),
|
|
dds::core::optional<int32_t>()),
|
|
this))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error calling explosionAreaPauseResumeRequest(true)";
|
|
failExit();
|
|
return;
|
|
}
|
|
if (!waitForData([this]() { return m_replyError == true; }))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error waiting for reply error while switching to pause of area explosion";
|
|
failExit();
|
|
return;
|
|
}
|
|
|
|
// and now pause
|
|
m_bExpectedFailure = false;
|
|
if (!m_ftc->explosionAreaPauseResumeRequest(
|
|
ExplosionAreaPauseResumeRequest(
|
|
m_eaData.id(),
|
|
false,
|
|
dds::core::optional<rti::core::int64>(),
|
|
dds::core::optional<int32_t>(),
|
|
dds::core::optional<int32_t>()),
|
|
this))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error calling explosionAreaPauseResumeRequest(false)";
|
|
failExit();
|
|
return;
|
|
}
|
|
if (!waitForData([this]() { return m_eaData.effectStateId() == AreaEffectSimulation::AesEffectState::EsPaused; }))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error while waiting for pause of area explosion";
|
|
failExit();
|
|
return;
|
|
}
|
|
|
|
// pause again -> expected error
|
|
m_replyError = false;
|
|
m_bExpectedFailure = true;
|
|
if (!m_ftc->explosionAreaPauseResumeRequest(
|
|
ExplosionAreaPauseResumeRequest(
|
|
m_eaData.id(),
|
|
false,
|
|
dds::core::optional<rti::core::int64>(),
|
|
dds::core::optional<int32_t>(),
|
|
dds::core::optional<int32_t>()),
|
|
this))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error calling explosionAreaPauseResumeRequest(false)";
|
|
failExit();
|
|
return;
|
|
}
|
|
if (!waitForData([this]() { return m_replyError == true; }))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error creating single explosion object (try with error)";
|
|
failExit();
|
|
return;
|
|
}
|
|
|
|
// and resume execution
|
|
m_bExpectedFailure = false;
|
|
if (!m_ftc->explosionAreaPauseResumeRequest(
|
|
ExplosionAreaPauseResumeRequest(
|
|
m_eaData.id(),
|
|
true,
|
|
dds::core::optional<rti::core::int64>(),
|
|
dds::core::optional<int32_t>(),
|
|
dds::core::optional<int32_t>()),
|
|
this))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error calling explosionAreaPauseResumeRequest(true)";
|
|
failExit();
|
|
return;
|
|
}
|
|
if (!waitForData([this]() { return m_eaData.effectStateId() == AreaEffectSimulation::AesEffectState::EsActivated; }))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error while waiting for activation of area explosion";
|
|
failExit();
|
|
return;
|
|
}
|
|
INFO_LOG(m_logger) << "tryPauseResumeExplosionArea end";
|
|
QTimer::singleShot(0, this, &TestExplosionArea::checkTriggeredExplosions);
|
|
}
|
|
|
|
void TestExplosionArea::checkTriggeredExplosions()
|
|
{
|
|
INFO_LOG(m_logger) << "checkTriggeredExplosions start";
|
|
|
|
// first we should wait for Activation
|
|
if (!waitForData([this]() { return m_eaData.effectStateId() == AreaEffectSimulation::AesEffectState::EsActivated; }))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error while waiting for activation of area explosion";
|
|
failExit();
|
|
return;
|
|
}
|
|
|
|
// attn: msb is bit 7
|
|
checkTriggeredExplosionsHelper(0x70); // 0b01110000
|
|
checkTriggeredExplosionsHelper(0x30); // 0b00110000
|
|
checkTriggeredExplosionsHelper(0x10); // 0b00010000
|
|
checkTriggeredExplosionsHelper(0x00); // 0b00000000
|
|
|
|
// last step: wait for expiry
|
|
if (!waitForData([this]() { return m_eaData.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired; }))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error while waiting for expiring of area explosion";
|
|
failExit();
|
|
return;
|
|
}
|
|
|
|
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
|
INFO_LOG(m_logger) << "checkTriggeredExplosions end";
|
|
}
|
|
|
|
void TestExplosionArea::checkTriggeredExplosionsHelper(int bitfield)
|
|
{
|
|
// since we've 9 seconds duration and the first hit is at 0, every 2.5sec should be a new TriggeredExplosions telegram
|
|
QElapsedTimer et;
|
|
et.start();
|
|
if (!waitForData([this, bitfield]() { return m_tiData.bitfield()[0] == bitfield; }))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error while waiting for triggered explosison telegram with bitfield 0x" << QByteArray::number(bitfield, 16);
|
|
failExit();
|
|
return;
|
|
}
|
|
// 500ms delay through dds allowed :)
|
|
if (et.elapsed() > 3000)
|
|
{
|
|
ERROR_LOG(m_logger) << "Something went wrong - waited more than 3 seconds for next impact trigger";
|
|
failExit();
|
|
}
|
|
}
|
|
|
|
|
|
void TestExplosionArea::explosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, DataModification modType)
|
|
{
|
|
if (m_eaData.id() == -1)
|
|
return;
|
|
onAesChanged(data, modType, m_eaData);
|
|
}
|
|
|
|
void TestExplosionArea::triggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType)
|
|
{
|
|
if (m_eaData.id() != data.aesItemId() || modType == DataModification::eRemoved)
|
|
return;
|
|
INFO_LOG(m_logger) << "Got TriggeredImpacts data - bitfield[0] = 0x" << QByteArray::number(static_cast<int>(data.bitfield()[0]), 16);
|
|
m_tiData = data;
|
|
}
|
|
|
|
void TestExplosionArea::onExplosionAreaModifyReply(const Core::FunctionReplyObject &replyObject)
|
|
{
|
|
if (m_bIsCreatedRequest)
|
|
onAesCreateReply(replyObject);
|
|
else
|
|
onAesModifyReply(replyObject);
|
|
}
|
|
|
|
void TestExplosionArea::onExplosionAreaPauseResumeReply(const Core::FunctionReplyObject &replyObject)
|
|
{
|
|
INFO_LOG(m_logger) << "Got pause/resume reply explosion area with id " << replyObject.id()
|
|
<< ", error = " << replyObject.error()
|
|
<< " and errorString = '" << replyObject.translated() << "'";
|
|
m_replyError = replyObject.error();
|
|
if (m_replyError && !m_bExpectedFailure)
|
|
ERROR_LOG(m_logger) << "Got pause/resume reply explosion area error: " << replyObject();
|
|
}
|
|
|
|
} // namespace AreaEffectSimulation
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
int main(int argc, char **argv)
|
|
{
|
|
return AreaEffectSimulation::mainBase(argc, argv, []() { return new AreaEffectSimulation::TestExplosionArea; });
|
|
}
|
|
|