Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,267 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_convert_mine_area.h"
#include <QTimer>
#include <QLineF>
#include <nglapplication/nglcoreapplication.h>
#include <LtsCommandLineParser/LtsCommandLineParser.h>
#include <ngldb/dbtransaction.h>
#include <ngldb/nsqlquery.h>
#include <ngldb/dbconnection.h>
#include <ngldb/sql_query_janitor.h>
#include <QtSql/QSqlError>
#include <QVariant>
#include <AreaEffectSimulation/aes_db_structs.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <nglsettings/nglsettings_connections.h>
#include <nglsettings/nglsettings_settings.h>
#include <ngltools/ngltools_filesystem.h>
namespace AreaEffectSimulation
{
ConvertMineArea::ConvertMineArea(QObject *parent)
: QObject(parent)
, m_query(nullptr)
, m_exerciseId(-1)
, m_bEmitMessageOnError(false)
, m_bCanHandleSchemas(true)
, m_ownDatabaseConnection(true)
, m_logger(getLogger(QStringLiteral("ConvertMineArea")))
{}
bool ConvertMineArea::init(int exerciseId)
{
m_exerciseId = exerciseId;
NGL::Settings *s = new NGL::Settings(NGL::findProjectConfigFile());
const QString dbUser(QStringLiteral("ets_exm"));
const QString dbPasswd(QStringLiteral("ets11de"));
const QString hostname(s->databaseHostname());
const QString driver(s->databaseDriver());
const QString dbname(s->databaseName());
bool ok = initDB(dbUser, dbPasswd, driver, hostname, dbname);
if (!ok)
{
ERROR_LOG(m_logger) << "Error opening db, exiting..";
return false;
}
ERROR_LOG(m_logger) << "Database open";
return true;
}
bool ConvertMineArea::initDB(const QString &dbUser,
const QString &dbPasswd,
const QString &dbDriver,
const QString &dbHost,
const QString &dbName)
{
m_ownDatabaseConnection = true;
m_dbConnection = DBConnection::open(m_logger, dbUser, dbPasswd, dbDriver, dbHost, dbName, schemaName());
return initDBInternal();
}
bool ConvertMineArea::initDBInternal()
{
QSqlDriver *driver = m_dbConnection.driver();
if (!driver)
{
WARNING_LOG(m_logger) << "No SQL driver loaded - no database available!";
return false;
}
const QString driverName = m_dbConnection.driverName();
DEBUG_LOG(m_logger) << "Connected to database " << m_dbConnection.databaseName() << "@" << m_dbConnection.hostName()
<< ", schema: " << schemaName() << ", used driver: " << driverName;
if (!m_dbConnection.isOpen())
{
WARNING_LOG(m_logger) << "Database connection is no open - can not initialize database interface";
return false;
}
if (driverName == QLatin1String("QSQLITE"))
m_bCanHandleSchemas = false;
m_query = new NSqlQuery(m_dbConnection, m_logger);
return true;
}
QString ConvertMineArea::schemaName() const
{
if (!m_bCanHandleSchemas)
return QString();
if (m_exerciseId <= 0)
return QStringLiteral("aes");
return DBCommon::getExerciseSchemaName(m_exerciseId);
}
QString ConvertMineArea::dbUser() const
{
if (m_exerciseId > 0)
return QStringLiteral("ets_ex_00");
else
return QStringLiteral("ets_") + schemaName();
}
//
// MineArea
//
QString ConvertMineArea::getTableName(const QString &tableName) const
{
if (!m_bCanHandleSchemas)
return tableName;
if (m_exerciseId > 0)
return DBCommon::getExerciseTableName(tableName, m_exerciseId);
return QStringLiteral("aes.") + tableName;
}
bool ConvertMineArea::tryConvertMineArea()
{
const QString tableName1(getTableName(QStringLiteral("aes_mine_area")));
const QString stmt1(QStringLiteral("SELECT id, density FROM ") + tableName1);
m_query->prepare(stmt1);
if (!m_query->exec(m_bEmitMessageOnError))
{
m_lastError = m_query->lastError();
return false;
}
QMap<int,double> densityMap;
while (m_query->next())
{
int i = 0;
int aesId = m_query->value(i++).toInt();
double density = m_query->value(i++).toInt();
densityMap.insert(aesId, density);
}
const QString tableName(getTableName(QStringLiteral("aes_mine_area_segment")));
const QString stmt(QStringLiteral("SELECT id, mine_area_id, element_number, start_position_x, start_position_y, rotation_angle, mine_count"
" FROM ") + tableName);
m_query->prepare(stmt);
if (!m_query->exec(m_bEmitMessageOnError))
{
m_lastError = m_query->lastError();
return false;
}
Database::AesMineAreaSegment data;
QVector<Database::AesMineAreaSegment> vecMineArea;
while (m_query->next())
{
int i = 0;
data.id = m_query->value(i++).toInt();
data.mineAreaId = m_query->value(i++).toInt();
data.elementNumber = m_query->value(i++).toInt();
data.startPosition.rx() = m_query->value(i++).toDouble();
data.startPosition.ry() = m_query->value(i++).toDouble();
double rotationAngle = m_query->value(i++).toDouble();
int mineCount = m_query->value(i++).toInt();
LtsCoordTrans::UtmCoordinate startPositionUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(data.startPosition);
QLineF line;
line.setP1({startPositionUtm.x, startPositionUtm.y});
line.setLength(mineCount / densityMap.value(data.mineAreaId));
line.setAngle(rotationAngle);
QPointF p2 = line.p2();
LtsCoordTrans::UtmCoordinate endPositionUtm = startPositionUtm;
endPositionUtm.x = p2.x();
endPositionUtm.y = p2.y();
data.endPosition = endPositionUtm.geographic();
DEBUG_LOG(m_logger) << "aesId: " << data.mineAreaId << ", id: " << data.id;
DEBUG_LOG(m_logger) << "EndpositionUtm: x: " << endPositionUtm.x << ", y: " << endPositionUtm.y;
DEBUG_LOG(m_logger) << "Geographic: x: " << data.endPosition.x() << " y: " << data.endPosition.y();
vecMineArea.append(data);
}
const QString stmt3(QStringLiteral("UPDATE ") + tableName +
QStringLiteral(" SET"
" end_position_x = :end_position_x, end_position_y = :end_position_y"
" WHERE id = :id"));
if (!m_query->prepare(stmt3))
{
m_lastError = m_query->lastError();
ERROR_LOG(m_logger) << "lastError: " << m_lastError.text();
return false;
}
for ( const Database::AesMineAreaSegment &mineAreaSegment : vecMineArea)
{
m_query->bindValue(QStringLiteral(":end_position_x"), mineAreaSegment.endPosition.x());
m_query->bindValue(QStringLiteral(":end_position_y"), mineAreaSegment.endPosition.y());
m_query->bindValue(QStringLiteral(":id"), mineAreaSegment.id);
if (!m_query->exec(m_bEmitMessageOnError))
{
m_lastError = m_query->lastError();
ERROR_LOG(m_logger) << "lastError: " << m_lastError.text();
return false;
}
}
return true;
}
} // namespace AreaEffectSimulation
// ------------------------------------------------------------------
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
{
public:
CmdLineParser()
: LtsCommandLineParser()
{
}
int exerciseId() const { return isSet(QLatin1String("e")) ? value(QLatin1String("e")).toInt() : -1; }
};
// ------------------------------------------------------------------
int main(int argc, char **argv)
{
NGLCoreApplication app(argc, argv);
app.createLogger("ConvertMineArea", 0 );
CmdLineParser options;
if (!options.init())
return -1;
AreaEffectSimulation::ConvertMineArea convMa(nullptr);
if (!convMa.init(options.exerciseId()))
{
ERROR_LOG(app.baseLogger()) << "Initialisation failed.";
return -2;
}
if (convMa.tryConvertMineArea())
ERROR_LOG(app.baseLogger()) << "Conversion for Exercise " << options.exerciseId() << " successful!";
else
ERROR_LOG(app.baseLogger()) << "Conversion failed.";
}
@@ -0,0 +1,63 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
#include <QSqlDriver>
#include <QSqlDatabase>
#include <QtSql/QSqlError>
#include <AreaEffectSimulation/aes_enums.hpp>
#include <AreaEffectSimulation/aes_db.h>
#include <AreaEffectSimulation/logger.h>
#include <ngldb/nsqlquery.h>
namespace AreaEffectSimulation
{
class ConvertMineArea : public QObject
{
Q_OBJECT
public:
explicit ConvertMineArea(QObject *parent);
bool init(int exerciseId);
bool tryConvertMineArea();
QString getTableName(const QString &tableName) const;
bool initDB(const QString &dbUser,
const QString &dbPasswd,
const QString &dbDriver,
const QString &dbHost,
const QString &dbName);
bool initDBInternal();
QString schemaName() const;
QString dbUser() const;
const QSqlDatabase &database() const { return m_dbConnection; }
void setEmitMessageOnError(bool bEmit) ;
QSqlError getLastError() const;
private:
QSqlDatabase m_dbConnection;
NSqlQuery *m_query;
QSqlError m_lastError;
int m_exerciseId;
bool m_bEmitMessageOnError;
bool m_bCanHandleSchemas;
bool m_ownDatabaseConnection;
LOGGER_T m_logger;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,227 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_air_support_impact.h"
#include <QCoreApplication>
#include <QTest>
#include <QTimer>
namespace AreaEffectSimulation
{
// must be in pdm.pdm_charge_type
// single fire charge types = area fire
static const int s_ChargeTypeId1 = 471;
static const int s_ChargeTypeId2 = 472;
TestAirSupportImpact::TestAirSupportImpact(QObject *parent)
: TestBase("Test.ExplosionSingle", parent)
{}
bool TestAirSupportImpact::init(int domainId, int exerciseId, int testId)
{
if (!TestBase::init(domainId, exerciseId, testId))
return false;
m_dtc->waitForHistoricalDataExplosionSingle();
m_asData.id(-1);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::airSupportImpactChanged,
this, &TestAirSupportImpact::airSupportImpactChanged);
return true;
}
bool TestAirSupportImpact::checkBaseData(const AreaEffectSimulation::AirSupportImpact &a,
const AreaEffectSimulation::AirSupportImpact &b) const
{
if (!checkAesItem(a, b))
return false;
if (a.impactPosition() != b.impactPosition())
{
WARNING_LOG(m_logger) << "impactPosition does not match: " << a.impactPosition() << " - " << b.impactPosition();
return false;
}
return true;
}
//
// ExplosionSingle
//
void TestAirSupportImpact::tryCreate()
{
m_asData = AreaEffectSimulation::AirSupportImpact();
AreaEffectSimulation::AirSupportImpact asData;
asData.id(0);
asData.name("chris");
asData.effectStart((time(nullptr) + 4) * 1000); // msec
asData.chargeStruct().chargeTypeId(345863487);
asData.impactPosition(Core::GeoPosition2D(0.15525, 0.926080));
asData.partyId(7);
asData.participantId(1234);
asData.externalId(1);
asData.flightTime(123);
INFO_LOG(m_logger) << "trying to send explosionSingleCreateRequest()";
m_replyError = false;
m_bExpectedFailure = true;
m_bIsCreatedRequest = true;
if (!m_ftc->airSupportImpactModifyRequest(
AirSupportImpactModifyRequest(
0,
asData.name(),
asData.effectStart(),
asData.chargeStruct().chargeTypeId(),
asData.impactPosition(),
asData.partyId(),
asData.participantId(),
asData.flightTime(),
asData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error during explosionSingleCreateRequest()";
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 single explosion object (try with error)";
}
// now with correct charge type
m_bExpectedFailure = false;
m_expectedAesId = -1;
asData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
m_bIsCreatedRequest = true;
if (!m_ftc->airSupportImpactModifyRequest(
AirSupportImpactModifyRequest(
0,
asData.name(),
asData.effectStart(),
asData.chargeStruct().chargeTypeId(),
asData.impactPosition(),
asData.partyId(),
asData.participantId(),
asData.flightTime(),
asData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error during explosionSingleCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_asData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating single explosion object";
failExit();
return;
}
if (!checkBaseData(m_asData, asData))
{
ERROR_LOG(m_logger) << "Creation data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestAirSupportImpact::tryModify);
INFO_LOG(m_logger) << "tryCreateExplosionSingle successful";
}
void TestAirSupportImpact::tryModify()
{
INFO_LOG(m_logger) << "trying to send modify request";
m_asData.name("chris2");
m_asData.effectStart(m_asData.effectStart().get() + 2000);
m_asData.chargeStruct().chargeTypeId(s_ChargeTypeId2);
m_asData.impactPosition(Core::GeoPosition2D(0.15525, 0.92607));
m_asData.partyId(8);
m_asData.participantId(1235);
m_asData.flightTime(321);
const AreaEffectSimulation::AirSupportImpact asData(m_asData);
m_asData = AreaEffectSimulation::AirSupportImpact();
m_asData.id(asData.id());
m_bIsCreatedRequest = false;
if (!m_ftc->airSupportImpactModifyRequest(
AirSupportImpactModifyRequest(
asData.id(),
asData.name(),
asData.effectStart(),
asData.chargeStruct().chargeTypeId(),
asData.impactPosition(),
asData.partyId(),
asData.participantId(),
asData.flightTime(),
asData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_asData.chargeStruct().chargeTypeId() == s_ChargeTypeId2;}))
{
ERROR_LOG(m_logger) << "Error updating single explosion object";
failExit();
return;
}
if (!checkBaseData(m_asData, asData))
{
ERROR_LOG(m_logger) << "Modify data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestAirSupportImpact::waitExpire);
INFO_LOG(m_logger) << "tryModifyExplosionSingle successful";
}
void TestAirSupportImpact::waitExpire()
{
INFO_LOG(m_logger) << "waiting until explosion single expires";
if (!waitForData([this]() { return m_asData.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired;}))
{
ERROR_LOG(m_logger) << "Timeout waiting for expiry of explosion single with id " << m_asData.id();
failExit();
return;
}
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
INFO_LOG(m_logger) << "waitExpireExplosionSingle successful";
}
void TestAirSupportImpact::airSupportImpactChanged(const AreaEffectSimulation::AirSupportImpact &data, DataModification modType)
{
if (m_asData.id() == -1)
return;
onAesChanged(data, modType, m_asData);
}
void TestAirSupportImpact::onAirSupportImpactModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestAirSupportImpact::onAirSupportImpactRemoveReply(const Core::FunctionReplyObject &replyObject)
{
onAesRemoveReply(replyObject);
}
} // namespace AreaEffectSimulation
// ------------------------------------------------------------------
int main(int argc, char **argv)
{
return AreaEffectSimulation::mainBase(argc, argv, []() { return new AreaEffectSimulation::TestAirSupportImpact; });
}
@@ -0,0 +1,43 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestAirSupportImpact final : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::AirSupportImpactModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::AirSupportImpactRemoveReplyHandler
{
Q_OBJECT
public:
explicit TestAirSupportImpact(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
public Q_SLOTS:
void startTest() override { tryCreate(); }
private Q_SLOTS:
void tryCreate();
void tryModify();
void waitExpire();
protected Q_SLOTS:
void airSupportImpactChanged(const AreaEffectSimulation::AirSupportImpact &data, DataModification modType);
protected:
void onAirSupportImpactModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onAirSupportImpactRemoveReply(const Core::FunctionReplyObject &replyObject) override;
private:
bool checkBaseData(const AreaEffectSimulation::AirSupportImpact &a,
const AreaEffectSimulation::AirSupportImpact &b) const;
private:
AreaEffectSimulation::AirSupportImpact m_asData;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,206 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_base.h"
#include <nglapplication/nglcoreapplication.h>
#include <LtsCommandLineParser/LtsCommandLineParser.h>
#include <QTimer>
#include <QtTest/QTest>
namespace AreaEffectSimulation
{
TestBase::TestBase(const char *loggerName, QObject *parent)
: QObject(parent)
, m_expectedAesId(-1)
, m_bIsCreatedRequest(false)
, m_bExpectedFailure(false)
, m_replyError(false)
, m_bTestsSuccessful(true)
, m_testId(0)
, m_aesTypeName(QString::fromLatin1(loggerName).splitRef(QLatin1Char('.')).last().toString())
, m_logger(getLogger(loggerName))
{}
bool TestBase::init(int domainId, int exerciseId, int testId)
{
INFO_LOG(m_logger) << "init begin";
m_testId = testId;
// initialize DDS
m_ddsConnector.reset(new DDSConnector::DdsConnector(domainId, IDL::PartitionType::Exercise, exerciseId));
if (!m_ddsConnector->init())
return false;
m_ddsConnector->initPublisherSubscriber();
INFO_LOG(m_logger) << "init create ftc";
m_ftc = AreaEffectSimulation::Interface::Ftc::create(m_ddsConnector);
INFO_LOG(m_logger) << "init init ftc";
bool bRet = m_ftc->enableAll();
m_dtc = AreaEffectSimulation::Interface::Dtc::create(m_ddsConnector);
bRet = bRet && m_dtc->enableAll();
INFO_LOG(m_logger) << "init end - bRet = " << bRet;
return bRet;
}
bool TestBase::waitForData(const std::function<bool()> &func)
{
// wait for data
for (int i = 0; i < 100; i++)
{
if (func())
return true;
QTest::qWait(100);
}
return func();
}
bool TestBase::checkAesItem(const AreaEffectSimulation::AesItem &a,
const AreaEffectSimulation::AesItem &b) const
{
if (a.name() != b.name())
{
WARNING_LOG(m_logger) << "name does not match: " << a.name() << " - " << b.name();
return false;
}
if (a.effectStart() != b.effectStart())
{
WARNING_LOG(m_logger) << "effectStart does not match: " << a.effectStart() << " - " << b.effectStart();
return false;
}
if (a.chargeStruct().chargeTypeId() != b.chargeStruct().chargeTypeId())
{
WARNING_LOG(m_logger) << "chargeTypeId does not match: " << a.chargeStruct().chargeTypeId() << " - " << b.chargeStruct().chargeTypeId();
return false;
}
if (a.partyId() != b.partyId())
{
WARNING_LOG(m_logger) << "partyId does not match: " << a.partyId() << " - " << b.partyId();
return false;
}
if (a.participantId() != b.participantId())
{
WARNING_LOG(m_logger) << "participantId does not match: " << a.participantId() << " - " << b.participantId();
return false;
}
return true;
}
void TestBase::failExit()
{
ERROR_LOG(m_logger) << "fail exit!";
m_bTestsSuccessful = false;
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
}
void TestBase::onAesCreateReply(const Core::FunctionReplyObject &replyObject)
{
INFO_LOG(m_logger) << "Got create " << m_aesTypeName << " reply 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 create " << m_aesTypeName << " reply error: " << replyObject();
else
m_expectedAesId = replyObject.id(); // only works as expected because reply is sent before publishing data occours
}
void TestBase::onAesModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_expectedAesId != replyObject.id())
return;
INFO_LOG(m_logger) << "Got modify " << m_aesTypeName << " reply 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 modify " << m_aesTypeName << " reply error: " << replyObject();
else
m_expectedAesId = replyObject.id();
}
void TestBase::onAesRemoveReply(const Core::FunctionReplyObject &replyObject)
{
INFO_LOG(m_logger) << "Got remove " << m_aesTypeName << " reply with id " << replyObject.id()
<< " and errorString " << replyObject.translated();
m_replyError = replyObject.error();
if (m_replyError && !m_bExpectedFailure)
ERROR_LOG(m_logger) << "Got remove " << m_aesTypeName << " reply error: " << replyObject();
else
m_expectedAesId = replyObject.id();
}
void TestBase::onAesTriggerReply(const Core::FunctionReplyObject &replyObject)
{
INFO_LOG(m_logger) << "Got trigger " << m_aesTypeName << " reply with id " << replyObject.id()
<< " and errorString " << replyObject.translated();
m_replyError = replyObject.error();
if (m_replyError && !m_bExpectedFailure)
ERROR_LOG(m_logger) << "Got remove " << m_aesTypeName << " reply error: " << replyObject();
else
m_expectedAesId = replyObject.id();
}
// ------------------------------------------------------------------
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
{
public:
CmdLineParser()
: LtsCommandLineParser()
{
addOption( { QStringList() << QLatin1String("t") << QLatin1String("testId")
, QLatin1String("TestId.")
, QLatin1String("Default: 0")
, QLatin1String("0")
} );
}
int testId() const { return isSet(QLatin1String("t")) ? value(QLatin1String("t")).toInt() : 0; }
};
// ------------------------------------------------------------------
int mainBase(int argc, char **argv,
const std::function<TestBase*()> &createFunc)
{
NGLCoreApplication app(argc, argv);
app.createLogger("AES", "log4cxx_aes.props");
CmdLineParser options;
if (!options.init())
return -1;
if (options.exerciseId() <= 0)
{
fprintf(stderr, "ExerciseId not set!\n");
return -2;
}
int iRet = -1;
{
std::unique_ptr <TestBase> test(createFunc());
if (!test->init(options.domainId(), options.exerciseId(), options.testId()))
return iRet;
QTimer::singleShot(0, test.get(), &TestBase::startTest);
STARTUP_LOG(app.baseLogger());
app.exec();
iRet = test->testsSuccessful() ? 0 : 1;
fprintf(stderr, "%d\n", iRet);
SHUTDOWN_LOG(app.baseLogger());
}
return iRet;
}
} // namespace AreaEffectSimulation
@@ -0,0 +1,83 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <AreaEffectSimulation/aes_ftc.h>
#include <AreaEffectSimulation/aes_dtc.h>
#include <AreaEffectSimulation/logger.h>
#include <QObject>
#include <DDS/DDSConnector/dds_connector.h>
#include <memory>
#include <AreaEffectSimulation/aes_test_base_export.h>
namespace AreaEffectSimulation
{
class AES_TEST_BASE_EXPORT TestBase : public QObject
{
Q_OBJECT
protected:
explicit TestBase(const char *loggerName, QObject *parent);
public:
bool testsSuccessful() const { return m_bTestsSuccessful; }
virtual bool init(int domainId, int exerciseId, int testId);
public Q_SLOTS:
virtual void startTest() = 0;
protected:
static bool waitForData(const std::function<bool()> &func);
bool checkAesItem(const AreaEffectSimulation::AesItem &a,
const AreaEffectSimulation::AesItem &b) const;
void failExit();
void onAesCreateReply(const Core::FunctionReplyObject &replyObject);
void onAesModifyReply(const Core::FunctionReplyObject &replyObject);
void onAesRemoveReply(const Core::FunctionReplyObject &replyObject);
void onAesTriggerReply(const Core::FunctionReplyObject &replyObject);
template <typename T>
void onAesChanged(const T &dataIn, DataModification modType, T &dataOut)
{
INFO_LOG(m_logger) << "Got " << m_aesTypeName << " with mod type " << (int)modType
<< ", id: " << dataIn.id() << ", chargeType: " << dataIn.chargeStruct().chargeTypeId()
<< ", effectState: " << dataIn.effectStateId();
if (m_expectedAesId == dataIn.id())
{
DEBUG_LOG(m_logger) << "Expected aes id - updating data for " << m_aesTypeName;
dataOut = dataIn;
}
if (modType == DataModification::eRemoved && dataOut.id() == dataIn.id())
{
DEBUG_LOG(m_logger) << "Removed " << m_aesTypeName << " with id " << dataIn.id();
m_expectedAesId = dataIn.id();
}
}
protected:
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
std::shared_ptr<AreaEffectSimulation::Interface::Ftc> m_ftc;
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_dtc;
int m_expectedAesId; //!< contains the id of the created aes
bool m_bIsCreatedRequest;
bool m_bExpectedFailure;
bool m_replyError;
bool m_bTestsSuccessful;
int m_testId;
QString m_aesTypeName;
LOGGER_T m_logger;
};
int AES_TEST_BASE_EXPORT mainBase(int argc, char **argv,
const std::function<TestBase*()> &createFunc);
} // namespace AreaEffectSimulation
@@ -0,0 +1,331 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_bccontamination.h"
#include <QCoreApplication>
#include <QTest>
#include <QTimer>
namespace AreaEffectSimulation
{
// must be in pdm.pdm_charge_type
static const int s_ChargeTypeId1 = 341;
static const int s_ChargeTypeId2 = 342;
TestBCContamination::TestBCContamination(QObject *parent)
: TestBase("Test.BCContamination", parent)
{}
bool TestBCContamination::init(int domainId, int exerciseId, int testId)
{
if (!TestBase::init(domainId, exerciseId, testId))
return false;
m_dtc->waitForHistoricalDataBCContamination();
m_bcData.id(-1);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::bCContaminationChanged,
this, &TestBCContamination::bCContaminationChanged);
return true;
}
bool TestBCContamination::checkBaseData(const AreaEffectSimulation::BCContamination &a,
const AreaEffectSimulation::BCContamination &b) const
{
if (!checkAesItem(a, b))
return false;
if (a.impactPosition() != b.impactPosition())
{
WARNING_LOG(m_logger) << "impactPosition does not match: " << a.impactPosition() << " - " << b.impactPosition();
return false;
}
if (a.impactRadius() != b.impactRadius())
{
WARNING_LOG(m_logger) << "impactRadius does not match: " << a.impactRadius() << " - " << b.impactRadius();
return false;
}
return true;
}
//
// BCContamination
//
void TestBCContamination::tryCreateBCContamination()
{
m_bcData = AreaEffectSimulation::BCContamination();
AreaEffectSimulation::BCContamination bcData;
bcData.id(0);
bcData.name("chris");
bcData.effectStart((time(nullptr) + 4) * 1000); // msec
bcData.effectDuration(10234); // msec
bcData.chargeStruct().chargeTypeId(345863487);
bcData.impactPosition(Core::GeoPosition2D(0.16, 0.92));
bcData.impactRadius(100); // 100m
bcData.partyId(2);
bcData.participantId(1234);
bcData.upperOffset(6.0);
bcData.lowerOffset(-1000.0);
INFO_LOG(m_logger) << "trying to send BCContaminationCreateRequest()";
m_replyError = false;
m_bExpectedFailure = true;
m_bIsCreatedRequest = true;
m_expectedAesId = -1;
if(!m_ftc->bCContaminationModifyRequest(
BCContaminationModifyRequest(
0,
bcData.name(),
bcData.effectStart(),
bcData.effectDuration(),
bcData.chargeStruct().chargeTypeId(),
bcData.impactPosition(),
bcData.impactRadius(),
AesWeatherSource::AwsStatic,
bcData.partyId(),
bcData.participantId(),
dds::core::optional<double>(), // propagationDirection
dds::core::optional<double>(), // windSpeed
dds::core::optional<Core::GeoPosition2D>(), // weatherPosition
dds::core::optional<rti::core::int64>(), // weatherTimestamp
dds::core::optional<long long>(), // externalId
bcData.upperOffset(),
bcData.lowerOffset(),
dds::core::optional<bool>()),
this))
{
ERROR_LOG(m_logger) << "Error during BCContaminationCreateRequest()";
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 bc contamination object (try with error)";
failExit();
return;
}
// now with correct charge type
m_bExpectedFailure = false;
m_bIsCreatedRequest = true;
m_expectedAesId = -1;
bcData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
if (!m_ftc->bCContaminationModifyRequest(
BCContaminationModifyRequest(
0,
bcData.name(),
bcData.effectStart(),
bcData.effectDuration(),
bcData.chargeStruct().chargeTypeId(),
bcData.impactPosition(),
bcData.impactRadius(),
AesWeatherSource::AwsStatic,
bcData.partyId(),
bcData.participantId(),
dds::core::optional<double>(),
dds::core::optional<double>(),
dds::core::optional<Core::GeoPosition2D>(),
dds::core::optional<rti::core::int64>(),
dds::core::optional<long long>(),
bcData.upperOffset(),
bcData.lowerOffset(),
dds::core::optional<bool>()),
this))
{
ERROR_LOG(m_logger) << "Error during BCContaminationCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_bcData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating bc contamination object";
failExit();
return;
}
if (!checkBaseData(m_bcData, bcData))
{
ERROR_LOG(m_logger) << "Creation data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestBCContamination::tryModifyBCContamination);
INFO_LOG(m_logger) << "tryCreateBCContamination successful";
}
void TestBCContamination::tryModifyBCContamination()
{
INFO_LOG(m_logger) << "trying to send modify request";
m_bcData.name("chris2");
m_bcData.effectStart(m_bcData.effectStart().get() + 2000);
m_bcData.effectDuration(3200); // msec
m_bcData.chargeStruct().chargeTypeId(s_ChargeTypeId2);
m_bcData.impactPosition(Core::GeoPosition2D(0.17, 0.93));
m_bcData.partyId(3);
m_bcData.participantId(1235);
m_bcData.upperOffset(6.0);
m_bcData.lowerOffset(false);
const AreaEffectSimulation::BCContamination bcData(m_bcData);
m_bcData = AreaEffectSimulation::BCContamination();
m_bcData.id(bcData.id());
m_bIsCreatedRequest = false;
if (!m_ftc->bCContaminationModifyRequest(
BCContaminationModifyRequest(
bcData.id(),
bcData.name(),
bcData.effectStart(),
bcData.effectDuration(),
bcData.chargeStruct().chargeTypeId(),
bcData.impactPosition(),
bcData.impactRadius(),
AesWeatherSource::AwsStatic,
bcData.partyId(),
bcData.participantId(),
dds::core::optional<double>(),
dds::core::optional<double>(),
dds::core::optional<Core::GeoPosition2D>(),
dds::core::optional<rti::core::int64>(),
dds::core::optional<rti::core::int64>(),
bcData.upperOffset(),
bcData.lowerOffset(),
dds::core::optional<bool>()),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_bcData.chargeStruct().chargeTypeId() == s_ChargeTypeId2;}))
{
ERROR_LOG(m_logger) << "Error updating bc contamination object";
failExit();
return;
}
if (!checkBaseData(m_bcData, bcData))
{
ERROR_LOG(m_logger) << "Modify data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestBCContamination::waitExpireBCContamination);
INFO_LOG(m_logger) << "tryModifyBCContamination successful";
}
void TestBCContamination::waitExpireBCContamination()
{
INFO_LOG(m_logger) << "waiting until bc contamination expires";
if (!waitForData([this]() { return m_bcData.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired;}))
{
ERROR_LOG(m_logger) << "Timeout waiting for expiry of bc contamination with id " << m_bcData.id();
failExit();
return;
}
QTimer::singleShot(0, this, &TestBCContamination::tryRemoveBCContamination);
INFO_LOG(m_logger) << "waitExpireBCContamination successful";
}
void TestBCContamination::tryRemoveBCContamination()
{
INFO_LOG(m_logger) << "tryRemoveBCContamination start";
AreaEffectSimulation::BCContamination bcData(m_bcData);
bcData.name("RemoveTest");
bcData.effectStart(0); // not set
m_bcData = AreaEffectSimulation::BCContamination();
m_expectedAesId = -1;
m_bIsCreatedRequest = true;
bcData.upperOffset(6.0);
bcData.lowerOffset(false);
if (!m_ftc->bCContaminationModifyRequest(
BCContaminationModifyRequest(
0,
bcData.name(),
bcData.effectStart(),
bcData.effectDuration(),
bcData.chargeStruct().chargeTypeId(),
bcData.impactPosition(),
bcData.impactRadius(),
AesWeatherSource::AwsStatic,
bcData.partyId(),
bcData.participantId(),
dds::core::optional<double>(),
dds::core::optional<double>(),
dds::core::optional<Core::GeoPosition2D>(),
dds::core::optional<rti::core::int64>(),
dds::core::optional<rti::core::int64>(),
bcData.upperOffset(),
bcData.lowerOffset(),
dds::core::optional<bool>()),
this))
{
ERROR_LOG(m_logger) << "Error during bCContaminationModifyRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_bcData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating bc contamination object";
failExit();
return;
}
m_expectedAesId = -1;
if (!m_ftc->bCContaminationRemoveRequest(Core::RemoveElementRequest(m_bcData.id()), this))
{
ERROR_LOG(m_logger) << "Error during BCContaminationRemoveRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_bcData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error removing bc contamination object";
failExit();
return;
}
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
INFO_LOG(m_logger) << "tryRemoveBCContamination successful";
}
void TestBCContamination::bCContaminationChanged(const AreaEffectSimulation::BCContamination &data, DataModification modType)
{
if (m_bcData.id() == -1)
return;
onAesChanged(data, modType, m_bcData);
}
void TestBCContamination::onBCContaminationModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestBCContamination::onBCContaminationRemoveReply(const Core::FunctionReplyObject &replyObject)
{
onAesRemoveReply(replyObject);
}
} // namespace AreaEffectSimulation
// ------------------------------------------------------------------
int main(int argc, char **argv)
{
return AreaEffectSimulation::mainBase(argc, argv, []() { return new AreaEffectSimulation::TestBCContamination; });
}
@@ -0,0 +1,44 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestBCContamination final : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::BCContaminationModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::BCContaminationRemoveReplyHandler
{
Q_OBJECT
public:
explicit TestBCContamination(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
public Q_SLOTS:
void startTest() override { tryCreateBCContamination(); }
private Q_SLOTS:
void tryCreateBCContamination();
void tryModifyBCContamination();
void waitExpireBCContamination();
void tryRemoveBCContamination();
protected Q_SLOTS:
void bCContaminationChanged(const AreaEffectSimulation::BCContamination &data, DataModification modType);
protected:
void onBCContaminationModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onBCContaminationRemoveReply(const Core::FunctionReplyObject &replyObject) override;
private:
bool checkBaseData(const AreaEffectSimulation::BCContamination &a,
const AreaEffectSimulation::BCContamination &b) const;
private:
AreaEffectSimulation::BCContamination m_bcData;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,323 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_booby_trap.h"
#include <QCoreApplication>
#include <QTest>
#include <QTimer>
namespace AreaEffectSimulation
{
// must be in pdm.pdm_charge_type
static const int s_ChargeTypeId1 = 251;
static const int s_ChargeTypeId2 = 252;
TestBoobyTrap::TestBoobyTrap(QObject *parent)
: TestBase("Test.BoobyTrap", parent)
{}
bool TestBoobyTrap::init(int domainId, int exerciseId, int testId)
{
if (!TestBase::init(domainId, exerciseId, testId))
return false;
m_dtc->waitForHistoricalDataBoobyTrap();
m_btData.id(-1);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::boobyTrapChanged,
this, &TestBoobyTrap::boobyTrapChanged);
return true;
}
bool TestBoobyTrap::checkBaseData(const AreaEffectSimulation::BoobyTrap &a,
const AreaEffectSimulation::BoobyTrap &b) const
{
if (!checkAesItem(a, b))
return false;
if (a.impactPosition() != b.impactPosition())
{
WARNING_LOG(m_logger) << "impactPosition does not match: " << a.impactPosition() << " - " << b.impactPosition();
return false;
}
if (a.impactRadius() != b.impactRadius())
{
WARNING_LOG(m_logger) << "impactRadius does not match: " << a.impactRadius() << " - " << b.impactRadius();
return false;
}
return true;
}
//
// BoobyTrap
//
void TestBoobyTrap::tryCreateBoobyTrap()
{
m_btData = AreaEffectSimulation::BoobyTrap();
AreaEffectSimulation::BoobyTrap btData;
btData.id(0);
btData.name("BoobyTrap1");
btData.effectStart((time(nullptr) + 4) * 1000); // msec
btData.effectDuration(10234); // msec
btData.chargeStruct().chargeTypeId(3456789);
btData.impactPosition(Core::GeoPosition2D(0.1547, 0.926));
btData.impactRadius(800); // 100m
btData.triggerRadius(200);
btData.rotationAngle(45);
btData.centralAngle(90);
btData.partyId(2);
//btData.participantId(1234);
INFO_LOG(m_logger) << "trying to send BoobyTrapCreateRequest()";
m_replyError = false;
m_bExpectedFailure = true;
m_bIsCreatedRequest = true;
m_expectedAesId = -1;
if (!m_ftc->boobyTrapModifyRequest(
BoobyTrapModifyRequest(
0,
btData.name(),
btData.effectDuration(),
btData.chargeStruct().chargeTypeId(),
btData.impactPosition(),
btData.impactRadius(),
btData.triggerRadius(),
btData.rotationAngle().get(),
btData.centralAngle().get(),
btData.effectStart().get(),
btData.partyId().get()),
this))
{
ERROR_LOG(m_logger) << "Error during BoobyTrapCreateRequest()";
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 booby trap object (try with error)";
failExit();
return;
}
// now with correct charge type
m_bExpectedFailure = false;
m_bIsCreatedRequest = true;
m_expectedAesId = -1;
btData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
if (!m_ftc->boobyTrapModifyRequest(
BoobyTrapModifyRequest(
0,
btData.name(),
btData.effectDuration(),
btData.chargeStruct().chargeTypeId(),
btData.impactPosition(),
btData.impactRadius(),
btData.triggerRadius(),
btData.rotationAngle().get(),
btData.centralAngle().get(),
btData.effectStart().get(),
btData.partyId().get()),
this))
{
ERROR_LOG(m_logger) << "Error during BoobyTrapCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_btData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating booby trap object";
failExit();
return;
}
if (!checkBaseData(m_btData, btData))
{
ERROR_LOG(m_logger) << "Creation data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestBoobyTrap::tryModifyBoobyTrap);
INFO_LOG(m_logger) << "tryCreateBoobyTrap successful";
}
void TestBoobyTrap::tryModifyBoobyTrap()
{
INFO_LOG(m_logger) << "trying to send modify request";
m_btData.name("Booby Trap 2");
m_btData.effectStart(m_btData.effectStart().get() + 2000);
m_btData.effectDuration(3200); // msec
m_btData.chargeStruct().chargeTypeId(s_ChargeTypeId2);
m_btData.impactPosition(Core::GeoPosition2D(0.1547, 0.926));
m_btData.partyId(3);
//m_btData.participantId(1235);
const AreaEffectSimulation::BoobyTrap btData(m_btData);
m_btData = AreaEffectSimulation::BoobyTrap();
m_btData.id(btData.id());
m_bIsCreatedRequest = false;
if (!m_ftc->boobyTrapModifyRequest(
BoobyTrapModifyRequest(
btData.id(),
btData.name(),
btData.effectDuration(),
btData.chargeStruct().chargeTypeId(),
btData.impactPosition(),
btData.impactRadius(),
btData.triggerRadius(),
btData.rotationAngle().get(),
btData.centralAngle().get(),
btData.effectStart().get(),
btData.partyId().get()),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_btData.chargeStruct().chargeTypeId() == s_ChargeTypeId2;}))
{
ERROR_LOG(m_logger) << "Error updating booby trap object";
failExit();
return;
}
if (!checkBaseData(m_btData, btData))
{
ERROR_LOG(m_logger) << "Modify data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestBoobyTrap::tryTriggerBoobyTrap);
INFO_LOG(m_logger) << "tryModifyBoobyTrap successful";
}
void TestBoobyTrap::tryTriggerBoobyTrap()
{
INFO_LOG(m_logger) << "trigger booby trap -> expires";
BoobyTrapTriggerRequest req;
req.id(m_btData.id());
req.triggered(true);
if (!m_ftc->boobyTrapTriggerRequest(req, this))
{
ERROR_LOG(m_logger) << "Error requesting trigger data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestBoobyTrap::waitExpireBoobyTrap);
INFO_LOG(m_logger) << "waitExpireBoobyTrap successful";
}
void TestBoobyTrap::waitExpireBoobyTrap()
{
INFO_LOG(m_logger) << "waiting until booby trap expires";
if (!waitForData([this]() { return m_btData.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired;}))
{
ERROR_LOG(m_logger) << "Timeout waiting for expiry of booby trap with id " << m_btData.id();
failExit();
return;
}
//QTimer::singleShot(0, this, &TestBoobyTrap::tryRemoveBoobyTrap);
INFO_LOG(m_logger) << "waitExpireBoobyTrap successful";
}
void TestBoobyTrap::tryRemoveBoobyTrap()
{
INFO_LOG(m_logger) << "tryRemoveBoobyTrap start";
AreaEffectSimulation::BoobyTrap btData(m_btData);
btData.name("RemoveTest");
btData.effectStart(0); // not set
m_btData = AreaEffectSimulation::BoobyTrap();
m_expectedAesId = -1;
m_bIsCreatedRequest = true;
if (!m_ftc->boobyTrapModifyRequest(
BoobyTrapModifyRequest(
0,
btData.name(),
btData.effectDuration(),
btData.chargeStruct().chargeTypeId(),
btData.impactPosition(),
btData.impactRadius(),
btData.triggerRadius(),
btData.rotationAngle().get(),
btData.centralAngle().get(),
btData.effectStart().get(),
btData.partyId().get()),
this))
{
ERROR_LOG(m_logger) << "Error during BoobyTrapModifyRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_btData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating booby trap object";
failExit();
return;
}
m_expectedAesId = -1;
if (!m_ftc->boobyTrapRemoveRequest(Core::RemoveElementRequest(m_btData.id()), this))
{
ERROR_LOG(m_logger) << "Error during BoobyTrapRemoveRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_btData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error removing booby trap object";
failExit();
return;
}
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
INFO_LOG(m_logger) << "tryRemoveBoobyTrap successful";
}
void TestBoobyTrap::boobyTrapChanged(const AreaEffectSimulation::BoobyTrap &data, DataModification modType)
{
if (m_btData.id() == -1)
return;
onAesChanged(data, modType, m_btData);
}
void TestBoobyTrap::onBoobyTrapModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestBoobyTrap::onBoobyTrapRemoveReply(const Core::FunctionReplyObject &replyObject)
{
onAesRemoveReply(replyObject);
}
void TestBoobyTrap::onBoobyTrapTriggerReply(const Core::FunctionReplyObject &replyObject)
{
onAesTriggerReply(replyObject);
}
} // namespace AreaEffectSimulation
// ------------------------------------------------------------------
int main(int argc, char **argv)
{
return AreaEffectSimulation::mainBase(argc, argv, []() { return new AreaEffectSimulation::TestBoobyTrap; });
}
@@ -0,0 +1,47 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestBoobyTrap final : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::BoobyTrapModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::BoobyTrapRemoveReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::BoobyTrapTriggerReplyHandler
{
Q_OBJECT
public:
explicit TestBoobyTrap(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
public Q_SLOTS:
void startTest() override { tryCreateBoobyTrap(); }
private Q_SLOTS:
void tryCreateBoobyTrap();
void tryModifyBoobyTrap();
void tryTriggerBoobyTrap();
void waitExpireBoobyTrap();
void tryRemoveBoobyTrap();
protected Q_SLOTS:
void boobyTrapChanged(const AreaEffectSimulation::BoobyTrap &data, DataModification modType);
protected:
void onBoobyTrapModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onBoobyTrapRemoveReply(const Core::FunctionReplyObject &replyObject) override;
void onBoobyTrapTriggerReply(const Core::FunctionReplyObject &replyObject) override;
private:
bool checkBaseData(const AreaEffectSimulation::BoobyTrap &a,
const AreaEffectSimulation::BoobyTrap &b) const;
private:
AreaEffectSimulation::BoobyTrap m_btData;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,241 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_charge_administration.h"
#include <QCoreApplication>
#include <QTest>
#include <QTimer>
namespace AreaEffectSimulation
{
static const int s_ChargeAmount = 600;
TestChargeAdministration::TestChargeAdministration(QObject *parent)
: TestBase("Test.ChargeAdministration", parent)
{
}
bool TestChargeAdministration::init(int domainId, int exerciseId, int testId)
{
if (!TestBase::init(domainId, exerciseId, testId))
return false;
m_testId = testId;
m_caData.id(-1);
DEBUG_LOG(m_logger) << "Test Id = " << m_testId;
m_dtc->waitForHistoricalDataChargeAdministration();
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::chargeAdministrationChanged, this, &TestChargeAdministration::chargeAdministrationChanged);
return true;
}
bool TestChargeAdministration::checkBaseData(const AreaEffectSimulation::ChargeAdministration &a, const AreaEffectSimulation::ChargeAdministration &b) const
{
if (a.amount() != b.amount())
{
WARNING_LOG(m_logger) << "Amount does not match: " << a.amount() << " - " << b.amount();
return false;
}
if (a.planned() != b.planned())
{
WARNING_LOG(m_logger) << "Planned does not match: " << a.planned() << " - " << b.planned();
return false;
}
if (a.chargeTypeId() != b.chargeTypeId())
{
WARNING_LOG(m_logger) << "ChargeTypeId does not match: " << a.chargeTypeId() << " - " << b.chargeTypeId();
return false;
}
if (a.partyId() != b.partyId())
{
WARNING_LOG(m_logger) << "PartyId does not match: " << a.partyId() << " - " << b.partyId();
return false;
}
if (a.used() != b.used())
{
WARNING_LOG(m_logger) << "Used does not match: " << a.used() << " - " << b.used();
return false;
}
return true;
}
//
// ChargeAdministration
//
void TestChargeAdministration::tryCreateChargeAdministration()
{
m_caData = AreaEffectSimulation::ChargeAdministration();
m_expectedAesId = -1;
AreaEffectSimulation::ChargeAdministration esData;
esData.chargeTypeId(471);
esData.partyId(2);
esData.amount(450);
esData.effectSourceId(ProjectDataManagement::EffectSource::ES_Internal);
INFO_LOG(m_logger) << "trying to send ChargeAdministrationCreateRequest()";
m_replyError = false;
m_bIsCreatedRequest = true;
// amountChangedByOperator=true
if (!m_ftc->chargeAdministrationModifyRequest(ChargeAdministrationModifyRequest(0,
esData.chargeTypeId(),
esData.partyId(),
esData.effectSourceId(),
esData.amount(),
true),
this))
{
ERROR_LOG(m_logger) << "Error during ChargeAdministrationCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_caData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating charge admin object";
failExit();
return;
}
if (!checkBaseData(m_caData, esData))
{
ERROR_LOG(m_logger) << "Creation data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestChargeAdministration::tryModifyChargeAdministration);
INFO_LOG(m_logger) << "tryCreateChargeAdministration successful";
}
void TestChargeAdministration::tryModifyChargeAdministration()
{
INFO_LOG(m_logger) << "trying to send modify request";
m_caData.chargeTypeId(471);
m_caData.partyId(2);
m_caData.amount(600);
const AreaEffectSimulation::ChargeAdministration esData(m_caData);
m_caData = AreaEffectSimulation::ChargeAdministration();
m_caData.id(esData.id());
m_bIsCreatedRequest = false;
// amountChangedByOperator=true
if (!m_ftc->chargeAdministrationModifyRequest(ChargeAdministrationModifyRequest(esData.id(),
esData.chargeTypeId(),
esData.partyId(),
esData.effectSourceId(),
esData.amount(),
true),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_caData.amount() == s_ChargeAmount; }))
{
ERROR_LOG(m_logger) << "Error updating charge admin object";
failExit();
return;
}
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
INFO_LOG(m_logger) << "tryModifyChargeAdministration successful";
}
//
// ChargeAdministration
//
void TestChargeAdministration::chargeAdministrationChanged(const AreaEffectSimulation::ChargeAdministration &data, DataModification modType)
{
if (m_caData.id() < 0)
return;
INFO_LOG(m_logger) << "Got ChargeAdministrationData with mod type " << (int)modType << ", id: " << data.id() << ", name: " << data.chargeTypeId()
<< ", amount: " << data.amount();
if ((modType == DataModification::eAdded && m_caData.id() == 0) || (modType == DataModification::eModified && m_caData.id() == data.id()))
{
DEBUG_LOG(m_logger) << "** Updating m_caData";
m_caData = data;
}
}
void TestChargeAdministration::onChargeAdministrationModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestChargeAdministration::tryCreateCA()
{
tryCreateChargeAdministration(371, 3, 1383);
tryCreateChargeAdministration(371, 2, 1382);
tryCreateChargeAdministration(372, 3, 1393);
tryCreateChargeAdministration(372, 2, 1392);
tryCreateChargeAdministration(381, 3, 9999);
tryCreateChargeAdministration(382, 3, 9999);
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
}
void TestChargeAdministration::tryCreateChargeAdministration(int chargeTypeId, int partyId, int amount)
{
m_caData = AreaEffectSimulation::ChargeAdministration();
AreaEffectSimulation::ChargeAdministration esData;
esData.chargeTypeId(chargeTypeId);
esData.partyId(partyId);
esData.amount(amount);
esData.amountChangedByOperator(true);
INFO_LOG(m_logger) << "trying to send ChargeAdministrationCreateRequest(int,int,int)";
m_replyError = false;
m_bIsCreatedRequest = true;
// amountChangedByOperator=true
if (!m_ftc->chargeAdministrationModifyRequest(ChargeAdministrationModifyRequest(0,
esData.chargeTypeId(),
esData.partyId(),
esData.effectSourceId(),
esData.amount(),
true),
this))
{
ERROR_LOG(m_logger) << "Error during ChargeAdministrationCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_caData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating charge admin object";
failExit();
return;
}
if (!checkBaseData(m_caData, esData))
{
ERROR_LOG(m_logger) << "Creation data does not match published data";
failExit();
return;
}
INFO_LOG(m_logger) << "tryCreateChargeAdministration successful";
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
}
} // namespace AreaEffectSimulation
// ------------------------------------------------------------------
int main(int argc, char **argv)
{
return AreaEffectSimulation::mainBase(argc, argv, []() { return new AreaEffectSimulation::TestChargeAdministration; });
}
@@ -0,0 +1,41 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestChargeAdministration final : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::ChargeAdministrationModifyReplyHandler
{
Q_OBJECT
public:
explicit TestChargeAdministration(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
bool checkBaseData(const AreaEffectSimulation::ChargeAdministration &a,
const AreaEffectSimulation::ChargeAdministration &b) const;
public Q_SLOTS:
void startTest() override { if (m_testId == 0) tryCreateChargeAdministration(); else tryCreateCA();}
private Q_SLOTS:
void tryCreateChargeAdministration();
void tryCreateCA();
void tryCreateChargeAdministration(int, int, int);
void tryModifyChargeAdministration();
protected Q_SLOTS:
void chargeAdministrationChanged(const AreaEffectSimulation::ChargeAdministration &data, DataModification modType);
protected:
void onChargeAdministrationModifyReply(const Core::FunctionReplyObject &replyObject) override;
private:
AreaEffectSimulation::ChargeAdministration m_caData;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,245 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_danger_area.h"
#include <QCoreApplication>
#include <QTest>
#include <QTimer>
namespace AreaEffectSimulation
{
const std::string TestDangerArea::s_name = "chris2";
TestDangerArea::TestDangerArea(QObject *parent)
: TestBase("Test.DangerArea", parent)
{}
bool TestDangerArea::init(int domainId, int exerciseId, int testId)
{
if (!TestBase::init(domainId, exerciseId, testId))
return false;
m_dtc->waitForHistoricalDataDangerArea();
m_daData.id(-1);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::dangerAreaChanged,
this, &TestDangerArea::dangerAreaChanged);
return true;
}
bool TestDangerArea::checkBaseData(const AreaEffectSimulation::DangerArea &a,
const AreaEffectSimulation::DangerArea &b) const
{
if (a.name() != b.name())
{
WARNING_LOG(m_logger) << "Name does not macht: " << a.name() << " - " << b.name();
return false;
}
if (a.effectStart() != b.effectStart())
{
WARNING_LOG(m_logger) << "StartTime does not match: " << a.effectStart() << " - " << b.effectStart();
return false;
}
for (size_t i = 0; i<a.segments().size() && i<b.segments().size(); ++i)
{
if (a.segments()[i] != b.segments()[i])
{
WARNING_LOG(m_logger) << "impactPosition does not match: " << a.segments()[i] << " - " << b.segments()[i];
return false;
}
}
return true;
}
//
// DangerArea
//
void TestDangerArea::tryCreateDangerArea()
{
m_daData = AreaEffectSimulation::DangerArea();
AreaEffectSimulation::DangerArea esData;
esData.id(0);
esData.name("chris");
esData.effectStart((time(nullptr) + 4) * 1000); // msec
esData.sampleTime(time(nullptr) *1000);
std::vector<Core::GeoPosition2D> segments;
segments.emplace_back(Core::GeoPosition2D(0.17001, 0.93001));
segments.emplace_back(Core::GeoPosition2D(0.17002, 0.93002));
segments.emplace_back(Core::GeoPosition2D(0.17003, 0.93003));
INFO_LOG(m_logger) << "trying to send dangerAreaCreateRequest()";
m_replyError = false;
m_bIsCreatedRequest = true;
if (!m_ftc->dangerAreaModifyRequest(
DangerAreaModifyRequest(
0,
esData.name(),
0, // Effect Duration
311, // Charge Type Id -> 311 = Danger Area Dummy
esData.effectStart(),
segments,
dds::core::optional<int32_t>(), // Party Id
dds::core::optional<int32_t>(), // Player Id
dds::core::optional<int32_t>() // associatedAesId
),
this))
{
ERROR_LOG(m_logger) << "Error during dangerAreaCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_daData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating danger area object";
failExit();
return;
}
if (!checkBaseData(m_daData, esData))
{
ERROR_LOG(m_logger) << "Creation data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestDangerArea::tryModifyDangerArea);
INFO_LOG(m_logger) << "tryCreateDangerArea successful";
}
void TestDangerArea::tryModifyDangerArea()
{
INFO_LOG(m_logger) << "trying to send modify request";
m_daData.name(s_name);
m_daData.effectStart(time(nullptr)+ 6 * 1000);
const AreaEffectSimulation::DangerArea esData(m_daData);
m_daData = AreaEffectSimulation::DangerArea();
m_daData.id(esData.id());
// resize to 2 elements
std::vector<Core::GeoPosition2D> segments;
segments.emplace_back(Core::GeoPosition2D(0.17004, 0.93004));
segments.emplace_back(Core::GeoPosition2D(0.17004, 0.93005));
m_bIsCreatedRequest = false;
if (!m_ftc->dangerAreaModifyRequest(
DangerAreaModifyRequest(
esData.id(),
esData.name(),
0, // Effect Duration
311, // Charge Type Id -> 311 = Danger Area Dummy
esData.effectStart(),
segments,
dds::core::optional<int32_t>(), // Party Id
dds::core::optional<int32_t>(), // Player Id
dds::core::optional<int32_t>() // associatedAesId
),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_daData.segments().size() == 2;}))
{
ERROR_LOG(m_logger) << "Error updating danger area object";
failExit();
return;
}
// increase to 4 elements
segments.resize(4);
segments[0] = Core::GeoPosition2D(0.17004, 0.93004);
segments[1] = Core::GeoPosition2D(0.17004, 0.93005);
segments[2] = Core::GeoPosition2D(0.17005, 0.93006);
segments[3] = Core::GeoPosition2D(0.17006, 0.93007);
if (!m_ftc->dangerAreaModifyRequest(
DangerAreaModifyRequest(
esData.id(),
esData.name(),
0, // Effect Duration
311, // Charge Type Id -> 311 = Danger Area Dummy
esData.effectStart(),
segments,
dds::core::optional<int32_t>(), // Party Id
dds::core::optional<int32_t>(), // Player Id
dds::core::optional<int32_t>() // associatedAesId
),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_daData.segments().size() == 4;}))
{
ERROR_LOG(m_logger) << "Error updating danger area object";
failExit();
return;
}
QTimer::singleShot(0, this, &TestDangerArea::tryRemoveDangerArea);
INFO_LOG(m_logger) << "tryModifyDangerArea successful";
}
void TestDangerArea::tryRemoveDangerArea()
{
m_expectedAesId = -1;
if (!m_ftc->dangerAreaRemoveRequest(
Core::RemoveElementRequest( m_daData.id()),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_daData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error removing bc contamination object " << m_daData.id() << " != " << m_expectedAesId;
failExit();
return;
}
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
INFO_LOG(m_logger) << "tryRemoveDangerArea successful";
}
//
// DangerArea
//
void TestDangerArea::dangerAreaChanged(const AreaEffectSimulation::DangerArea &data, DataModification modType)
{
if (m_daData.id() == -1)
return;
onAesChanged(data, modType, m_daData);
}
void TestDangerArea::onDangerAreaModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestDangerArea::onDangerAreaRemoveReply(const Core::FunctionReplyObject &replyObject)
{
onAesRemoveReply(replyObject);
}
} // namespace AreaEffectSimulation
// ------------------------------------------------------------------
int main(int argc, char **argv)
{
return AreaEffectSimulation::mainBase(argc, argv, []() { return new AreaEffectSimulation::TestDangerArea; });
}
@@ -0,0 +1,44 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestDangerArea final : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::DangerAreaModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::DangerAreaRemoveReplyHandler
{
Q_OBJECT
public:
explicit TestDangerArea(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
bool checkBaseData(const AreaEffectSimulation::DangerArea &a,
const AreaEffectSimulation::DangerArea &b) const;
public Q_SLOTS:
void startTest() override { tryCreateDangerArea(); }
private Q_SLOTS:
void tryCreateDangerArea();
void tryModifyDangerArea();
void tryRemoveDangerArea();
protected Q_SLOTS:
void dangerAreaChanged(const AreaEffectSimulation::DangerArea &data, DataModification modType);
protected:
void onDangerAreaModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onDangerAreaRemoveReply(const Core::FunctionReplyObject &replyObject) override;
private:
AreaEffectSimulation::DangerArea m_daData;
static const std::string s_name;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,428 @@
/**
* 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; });
}
@@ -0,0 +1,48 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestExplosionArea final : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::ExplosionAreaModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::ExplosionAreaPauseResumeReplyHandler
{
Q_OBJECT
public:
explicit TestExplosionArea(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
public Q_SLOTS:
void startTest() override { tryCreateExplosionArea(); }
private Q_SLOTS:
void tryCreateExplosionArea();
void tryModifyExplosionArea();
void tryWaitForActivationExplosionArea();
void tryPauseResumeExplosionArea();
void checkTriggeredExplosions();
void checkTriggeredExplosionsHelper(int bitfield);
protected Q_SLOTS:
void explosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, DataModification modType);
void triggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType);
protected:
void onExplosionAreaModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onExplosionAreaPauseResumeReply(const Core::FunctionReplyObject &replyObject) override;
private:
bool checkBaseData(const AreaEffectSimulation::ExplosionArea &a,
const AreaEffectSimulation::ExplosionArea &b) const;
private:
AreaEffectSimulation::ExplosionArea m_eaData;
AreaEffectSimulation::TriggeredImpacts m_tiData;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,411 @@
/**
* @RDE_HEADER@
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_explosion_area_bulk.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;
TestExplosionAreaBulk::TestExplosionAreaBulk(QObject *parent)
: TestBase("Test.ExplosionAreaBulk", parent)
{}
bool TestExplosionAreaBulk::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, &TestExplosionAreaBulk::explosionAreaChanged);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::triggeredImpactsChanged,
this, &TestExplosionAreaBulk::triggeredImpactsChanged);
return true;
}
bool TestExplosionAreaBulk::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 TestExplosionAreaBulk::tryCreateExplosionArea()
{
const int count = 100;
const int effectDurationMesc = 60 * 1000; // 10 seconds
const double lonOffset = 0.0001;
for (int i=0; i<count;++i)
{
QString objName = QString(QStringLiteral("af_bulk_%1")).arg(i);
INFO_LOG(m_logger) << "tryCreateExplosionArea start, objName=" << objName;
m_eaData = AreaEffectSimulation::ExplosionArea();
AreaEffectSimulation::ExplosionArea eaData;
eaData.id(0);
eaData.name(objName.toStdString().c_str());
eaData.effectStart((time(nullptr) + 4) * 1000); // msec
eaData.effectDuration(effectDurationMesc); // 10 seconds
eaData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
// Bremen : 0.155 ; 0.926
eaData.area(AreaEffectSimulation::Area(Core::GeoPosition2D(0.15 + (lonOffset*i), 0.926), 500, 600, 70));
eaData.partyId((i%3) + 2);
eaData.participantId(1234);
eaData.cannonCount(10);
eaData.cannonRounds(10);
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;
}
// 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;
// }
INFO_LOG(m_logger) << "tryCreateExplosionArea successful objName=" << objName;
} //for
QTimer::singleShot(0, this, &TestExplosionAreaBulk::tryWaitForActivationExplosionArea);
}
void TestExplosionAreaBulk::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, &TestExplosionAreaBulk::tryWaitForActivationExplosionArea);
INFO_LOG(m_logger) << "tryModifyExplosionArea successful";
}
void TestExplosionAreaBulk::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, &TestExplosionAreaBulk::tryPauseResumeExplosionArea);
INFO_LOG(m_logger) << "tryWaitForActivationExplosionArea end";
}
void TestExplosionAreaBulk::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, &TestExplosionAreaBulk::checkTriggeredExplosions);
}
void TestExplosionAreaBulk::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 TestExplosionAreaBulk::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 TestExplosionAreaBulk::explosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, DataModification modType)
{
if (m_eaData.id() == -1)
return;
onAesChanged(data, modType, m_eaData);
}
void TestExplosionAreaBulk::triggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType)
{
if (m_eaData.id() != data.aesItemId() || modType == DataModification::eRemoved)
return;
if (data.bitfield().size() > 0)
INFO_LOG(m_logger) << "Got TriggeredImpacts data - bitfield[0] = 0x" << QByteArray::number(static_cast<int>(data.bitfield()[0]), 16);
m_tiData = data;
}
void TestExplosionAreaBulk::onExplosionAreaModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestExplosionAreaBulk::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::TestExplosionAreaBulk; });
}
@@ -0,0 +1,49 @@
/**
* @RDE_HEADER@
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestExplosionAreaBulk final : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::ExplosionAreaModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::ExplosionAreaPauseResumeReplyHandler
{
Q_OBJECT
public:
explicit TestExplosionAreaBulk(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
public Q_SLOTS:
void startTest() override { tryCreateExplosionArea(); }
private Q_SLOTS:
void tryCreateExplosionArea();
void tryModifyExplosionArea();
void tryWaitForActivationExplosionArea();
void tryPauseResumeExplosionArea();
void checkTriggeredExplosions();
void checkTriggeredExplosionsHelper(int bitfield);
protected Q_SLOTS:
void explosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, DataModification modType);
void triggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType);
protected:
void onExplosionAreaModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onExplosionAreaPauseResumeReply(const Core::FunctionReplyObject &replyObject) override;
private:
bool checkBaseData(const AreaEffectSimulation::ExplosionArea &a,
const AreaEffectSimulation::ExplosionArea &b) const;
private:
AreaEffectSimulation::ExplosionArea m_eaData;
AreaEffectSimulation::TriggeredImpacts m_tiData;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,479 @@
/**
* @RDE_HEADER@
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_explosion_cluster.h"
#include <ProjectDataManagement/pdm.hpp>
#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;
static const int s_IgniterTypeProximity = 101;
static const int s_IgniterTypeImpact = 102;
TestExplosionCluster::TestExplosionCluster(QObject *parent)
: TestBase("Test.ExplosionCluster", parent)
{}
bool TestExplosionCluster::init(int domainId, int exerciseId, int testId)
{
if (!TestBase::init(domainId, exerciseId, testId))
return false;
m_dtc->waitForHistoricalDataExplosionCluster();
m_ecData.id(-1);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionClusterChanged,
this, &TestExplosionCluster::explosionClusterChanged);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::triggeredImpactsChanged,
this, &TestExplosionCluster::triggeredImpactsChanged);
return true;
}
bool TestExplosionCluster::checkBaseData(const AreaEffectSimulation::ExplosionCluster &a,
const AreaEffectSimulation::ExplosionCluster &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;
}
return true;
}
void TestExplosionCluster::tryCreateExplosionCluster()
{
INFO_LOG(m_logger) << "tryCreateExplosionCluster start";
m_ecData = AreaEffectSimulation::ExplosionCluster();
AreaEffectSimulation::ExplosionCluster eaData;
eaData.id(0);
eaData.effectStart((time(nullptr) + 30) * 1000); // msec
QString name(QStringLiteral("ec__"));
name += QString::number(eaData.effectStart().get());
eaData.name(name.toStdString());
eaData.effectDuration(10000); // 10 seconds
eaData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
eaData.chargeStruct().igniterTypeId(s_IgniterTypeImpact);
// 32 U MD 93860 79903 -> 0.155484041, 0.92622146
// eaData.area(AreaEffectSimulation::Area(Core::GeoPosition2D(0.202560, 0.91611), 200, 50, 20)); // width, height, rotation
// eaData.area(AreaEffectSimulation::Area(Core::GeoPosition2D(0.202561, 0.916111), 200, 50, 20)); // width, height, rotation
// eaData.area(AreaEffectSimulation::Area(Core::GeoPosition2D(0.202562, 0.916112), 200, 50, 20)); // width, height, rotation
// eaData.area(AreaEffectSimulation::Area(Core::GeoPosition2D(0.202564, 0.916112), 200, 50, 20)); // width, height, rotation
// eaData.area(AreaEffectSimulation::Area(Core::GeoPosition2D(0.202562, 0.916115), 200, 50, 20)); // width, height, rotation
eaData.area(AreaEffectSimulation::Area(Core::GeoPosition2D(0.202562, 0.916114), 30, 20, 20)); // width, height, rotation
eaData.mhPoints({{0.2025611, 0.9161111}, {0.2025611, 0.9161111}, {0.2025611, 0.9161111}}); // 3
eaData.partyId(3);
eaData.participantId(5);
eaData.externalId(0);
INFO_LOG(m_logger) << "trying to send explosionClusterCreateRequest()";
m_replyError = false;
m_bExpectedFailure = true;
m_bIsCreatedRequest = true;
int igniterTypeId = s_IgniterTypeImpact;
if ((m_testId >= 0) && (m_testId <= 2) )
igniterTypeId = m_testId;
INFO_LOG(m_logger) << "m_testId " << m_testId << ", igniterType = " << igniterTypeId;
const std::string& properties = "{}";
if (!m_ftc->explosionClusterModifyRequest(
ExplosionClusterModifyRequest(
0,
eaData.name(),
eaData.element(),
eaData.effectStart(),
eaData.effectDuration(),
eaData.effectSourceId(),
eaData.area(),
AreaEffectSimulation::AesExplosionGeometry_def::EgArea,
0, // zog
eaData.mhPoints().size(), // mhpCount;
dds::core::optional<double>(), // mhpRotation for ExplosionClusterOcModify only
3, // impactCount
{ 12345, // eaData.chargeTypeId(),
igniterTypeId, // eaData.igniterTypeId(),
0 // eaData.igniterFunctionId()
},
3, // firePurpose 3=Blenden mit Wirkung
// 25, // firing_elevation_angle
123, // peakHeight,
10 * 1000, // flightDuration [msec],
eaData.partyId(),
eaData.participantId(),
{}, // esmParticipantIds
eaData.externalId(),
-1, // eaData.launchVelocity(),
-1, // eaData.launchAngleDeg(),
-1, // eaData.dropAngle(),
-1, // eaData.tapTime(), // msec since epoch
-1, // eaData.lcAttack(), // fka lcPrf
-1, // eaData.lcTermination(),
-1, // eaData.cloudBase(), // Wolkenuntergrenze
eaData.effectMarkingInTa(),
properties),
this))
{
ERROR_LOG(m_logger) << "Error during explosionClusterCreateRequest()";
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;
}
failExit();
/*
// now with correct charge type
m_bExpectedFailure = false;
m_expectedAesId = -1;
eaData.chargeTypeId(s_ChargeTypeId1);
m_bIsCreatedRequest = true;
if (!m_ftc->explosionClusterModifyRequest(
ExplosionClusterModifyRequest(
0,
eaData.name(),
eaData.effectStart(),
eaData.effectDuration(),
eaData.chargeTypeId(),
eaData.area(),
eaData.partyId(),
eaData.participantId(),
1, // eaData.cannonCount(),
1, // eaData.cannonRounds(),
123,// eaData.fireRequestTime(),
// eaData.altitude(),
// eaData.purpose(),
// eaData.effectMarkingInTa(),
eaData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error during explosionClusterCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_ecData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating area explosion object";
failExit();
return;
}
if (!checkBaseData(m_ecData, eaData))
{
ERROR_LOG(m_logger) << "Creation data does not match published data";
failExit();
return;
}
// QTimer::singleShot(0, this, &TestExplosionCluster::tryModifyExplosionCluster);
INFO_LOG(m_logger) << "tryCreateExplosionCluster successful";
*/
}
/*
void TestExplosionCluster::tryModifyExplosionCluster()
{
INFO_LOG(m_logger) << "tryModifyExplosionCluster start";
m_ecData.name("af2");
m_ecData.effectStart(m_ecData.effectStart().get() + 3000);
m_ecData.effectDuration(9000); // 9 sec
m_ecData.chargeTypeId(s_ChargeTypeId2);
// 32 U MD 93860 79903 -> 0.155484041, 0.92622146
m_ecData.area(AreaEffectSimulation::Area(Core::GeoPosition2D(0.155484041, 0.92622146), 50, 60, 70));
waitForData
m_ecData.partyId(3);
m_ecData.participantId(5);
// m_ecData.cannonCount(2);
// m_ecData.cannonRounds(2);
m_ecData.effectMarkingInTa(true);
const AreaEffectSimulation::ExplosionCluster eaData(m_ecData);
m_ecData = AreaEffectSimulation::ExplosionCluster();
m_ecData.id(eaData.id());
m_bIsCreatedRequest = false;
if (!m_ftc->explosionClusterModifyRequest(
ExplosionClusterModifyRequest(
eaData.id(),
eaData.name(),
eaData.effectStart(),
eaData.effectDuration(),
eaData.chargeTypeId(),
eaData.area(),
eaData.partyId(),
eaData.participantId(),
1,// eaData.cannonCount(),
1, // eaData.cannonRounds(),
123,// eaData.fireRequestTime(),
123,// eaData.fireRequestTime(),
eaData.subAreaCount(),
// eaData.altitude(),
// eaData.purpose(),
// eaData.effectMarkingInTa(),
eaData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_ecData.chargeTypeId() == s_ChargeTypeId2; }))
{
ERROR_LOG(m_logger) << "Error updating area explosion object";
failExit();
return;
}
if (!checkBaseData(m_ecData, eaData))
{
ERROR_LOG(m_logger) << "Modify data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestExplosionCluster::tryWaitForActivationExplosionCluster);
INFO_LOG(m_logger) << "tryModifyExplosionCluster successful";
}
*/
void TestExplosionCluster::tryWaitForActivationExplosionCluster()
{
INFO_LOG(m_logger) << "tryWaitForActivationExplosionCluster start";
if (!waitForData([this]() { return m_ecData.effectStateId() == AreaEffectSimulation::AesEffectState::EsActivated; }))
{
DEBUG_LOG(m_logger) << "Effect State = " << m_ecData.effectStateId();
ERROR_LOG(m_logger) << "Error while waiting for activation of area explosion";
failExit();
return;
}
QTimer::singleShot(0, this, &TestExplosionCluster::tryPauseResumeExplosionCluster);
INFO_LOG(m_logger) << "tryWaitForActivationExplosionCluster end";
}
void TestExplosionCluster::tryPauseResumeExplosionCluster()
{
INFO_LOG(m_logger) << "tryPauseResumeExplosionCluster start";
// try to resume but is already active -> expected error
m_replyError = false;
m_bExpectedFailure = true;
if (!m_ftc->explosionClusterPauseResumeRequest(
ExplosionClusterPauseResumeRequest(
m_ecData.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 explosionClusterPauseResumeRequest(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->explosionClusterPauseResumeRequest(
ExplosionClusterPauseResumeRequest(
m_ecData.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 explosionClusterPauseResumeRequest(false)";
failExit();
return;
}
if (!waitForData([this]() { return m_ecData.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->explosionClusterPauseResumeRequest(
ExplosionClusterPauseResumeRequest(
m_ecData.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 explosionClusterPauseResumeRequest(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->explosionClusterPauseResumeRequest(
ExplosionClusterPauseResumeRequest(
m_ecData.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 explosionClusterPauseResumeRequest(true)";
failExit();
return;
}
if (!waitForData([this]() { return m_ecData.effectStateId() == AreaEffectSimulation::AesEffectState::EsActivated; }))
{
ERROR_LOG(m_logger) << "Error while waiting for activation of area explosion";
failExit();
return;
}
INFO_LOG(m_logger) << "tryPauseResumeExplosionCluster end";
QTimer::singleShot(0, this, &TestExplosionCluster::checkTriggeredExplosions);
}
void TestExplosionCluster::checkTriggeredExplosions()
{
INFO_LOG(m_logger) << "checkTriggeredExplosions start";
// first we should wait for Activation
if (!waitForData([this]() { return m_ecData.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_ecData.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 TestExplosionCluster::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 TestExplosionCluster::explosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &data, DataModification modType)
{
if (m_ecData.id() == -1)
return;
onAesChanged(data, modType, m_ecData);
}
void TestExplosionCluster::triggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType)
{
if (m_ecData.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 TestExplosionCluster::onExplosionClusterModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestExplosionCluster::onExplosionClusterPauseResumeReply(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::TestExplosionCluster; });
}
@@ -0,0 +1,51 @@
/**
* @RDE_HEADER@
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestExplosionCluster final : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::ExplosionClusterModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::ExplosionClusterPauseResumeReplyHandler
{
Q_OBJECT
public:
explicit TestExplosionCluster(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
public Q_SLOTS:
void startTest() override { tryCreateExplosionCluster(); }
private Q_SLOTS:
void tryCreateExplosionCluster();
// void tryModifyExplosionCluster();
void tryWaitForActivationExplosionCluster();
void tryPauseResumeExplosionCluster();
void checkTriggeredExplosions();
void checkTriggeredExplosionsHelper(int bitfield);
protected Q_SLOTS:
void explosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &data, DataModification modType);
void triggeredImpactsChanged(const AreaEffectSimulation::TriggeredImpacts &data, DataModification modType);
protected:
void onExplosionClusterModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onExplosionClusterPauseResumeReply(const Core::FunctionReplyObject &replyObject) override;
private:
bool checkBaseData(const AreaEffectSimulation::ExplosionCluster &a,
const AreaEffectSimulation::ExplosionCluster &b) const;
private:
AreaEffectSimulation::ExplosionCluster m_ecData;
AreaEffectSimulation::TriggeredImpacts m_tiData;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,357 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_explosion_single.h"
#include <QCoreApplication>
#include <QTest>
#include <QTimer>
namespace AreaEffectSimulation
{
// must be in pdm.pdm_charge_type
// single fire charge types = area fire
static const int s_ChargeTypeId1 = 371;
static const int s_ChargeTypeId2 = 372;
TestExplosionSingle::TestExplosionSingle(QObject *parent)
: TestBase("Test.ExplosionSingle", parent)
{}
bool TestExplosionSingle::init(int domainId, int exerciseId, int testId)
{
if (!TestBase::init(domainId, exerciseId, testId))
return false;
m_dtc->waitForHistoricalDataExplosionSingle();
m_esData.id(-1);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionSingleChanged,
this, &TestExplosionSingle::explosionSingleChanged);
return true;
}
bool TestExplosionSingle::checkBaseData(const AreaEffectSimulation::ExplosionSingle &a,
const AreaEffectSimulation::ExplosionSingle &b) const
{
if (!checkAesItem(a, b))
return false;
if (a.impactPosition() != b.impactPosition())
{
WARNING_LOG(m_logger) << "impactPosition does not match: " << a.impactPosition() << " - " << b.impactPosition();
return false;
}
return true;
}
//
// ExplosionSingle
//
void TestExplosionSingle::tryCreateExplosionSingle()
{
m_esData = AreaEffectSimulation::ExplosionSingle();
AreaEffectSimulation::ExplosionSingle esData;
esData.id(0);
esData.name("chris");
esData.effectStart((time(nullptr) + 4) * 1000); // msec
esData.chargeStruct().chargeTypeId(345863487);
esData.impactPosition(Core::GeoPosition2D(0.16, 0.92));
esData.partyId(7);
esData.participantId(1234);
esData.externalId(1);
esData.effectMarkingInTa(false);
INFO_LOG(m_logger) << "trying to send explosionSingleCreateRequest()";
m_replyError = false;
m_bExpectedFailure = true;
m_bIsCreatedRequest = true;
if (!m_ftc->explosionSingleModifyRequest(
ExplosionSingleModifyRequest(
0,
esData.name(),
esData.effectStart(),
esData.effectSourceId(),
esData.chargeStruct().chargeTypeId(),
esData.impactPosition(),
esData.partyId(),
esData.participantId(),
esData.fireRequestTime(),
esData.altitude(),
esData.purpose(),
esData.effectMarkingInTa(),
esData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error during explosionSingleCreateRequest()";
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 single explosion object (try with error)";
}
// now with correct charge type
m_bExpectedFailure = false;
m_expectedAesId = -1;
esData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
esData.partyId(2);
m_bIsCreatedRequest = true;
if (!m_ftc->explosionSingleModifyRequest(
ExplosionSingleModifyRequest(
0,
esData.name(),
esData.effectStart(),
esData.effectSourceId(),
esData.chargeStruct().chargeTypeId(),
esData.impactPosition(),
esData.partyId(),
esData.participantId(),
esData.fireRequestTime(),
esData.altitude(),
esData.purpose(),
esData.effectMarkingInTa(),
esData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error during explosionSingleCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_esData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating single explosion object";
failExit();
return;
}
if (!checkBaseData(m_esData, esData))
{
ERROR_LOG(m_logger) << "Creation data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestExplosionSingle::tryModifyExplosionSingle);
INFO_LOG(m_logger) << "tryCreateExplosionSingle successful";
}
void TestExplosionSingle::tryModifyExplosionSingle()
{
INFO_LOG(m_logger) << "trying to send modify request";
m_esData.name("chris2");
m_esData.effectStart(m_esData.effectStart().get() + 2000);
m_esData.chargeStruct().chargeTypeId(s_ChargeTypeId2);
m_esData.impactPosition(Core::GeoPosition2D(0.17, 0.93));
m_esData.partyId(3);
m_esData.participantId(1235);
const AreaEffectSimulation::ExplosionSingle esData(m_esData);
m_esData = AreaEffectSimulation::ExplosionSingle();
m_esData.id(esData.id());
m_bIsCreatedRequest = false;
if (!m_ftc->explosionSingleModifyRequest(
ExplosionSingleModifyRequest(
esData.id(),
esData.name(),
esData.effectStart(),
esData.effectSourceId(),
esData.chargeStruct().chargeTypeId(),
esData.impactPosition(),
esData.partyId(),
esData.participantId(),
esData.fireRequestTime(),
esData.altitude(),
esData.purpose(),
esData.effectMarkingInTa(),
esData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_esData.chargeStruct().chargeTypeId() == s_ChargeTypeId2;}))
{
ERROR_LOG(m_logger) << "Error updating single explosion object";
failExit();
return;
}
if (!checkBaseData(m_esData, esData))
{
ERROR_LOG(m_logger) << "Modify data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestExplosionSingle::waitExpireExplosionSingle);
INFO_LOG(m_logger) << "tryModifyExplosionSingle successful";
}
void TestExplosionSingle::waitExpireExplosionSingle()
{
INFO_LOG(m_logger) << "waiting until explosion single expires";
if (!waitForData([this]() { return m_esData.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired;}))
{
ERROR_LOG(m_logger) << "Timeout waiting for expiry of explosion single with id " << m_esData.id();
failExit();
return;
}
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
INFO_LOG(m_logger) << "waitExpireExplosionSingle successful";
}
void TestExplosionSingle::explosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType)
{
if (m_esData.id() == -1)
return;
onAesChanged(data, modType, m_esData);
}
void TestExplosionSingle::onExplosionSingleModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestExplosionSingle::onExplosionSingleRemoveReply(const Core::FunctionReplyObject &replyObject)
{
onAesRemoveReply(replyObject);
}
//
// TestExplosionSingleTestVWM
//
TestExplosionSingleTestVWM::TestExplosionSingleTestVWM(QObject *parent)
: TestExplosionSingle(parent)
{
}
void TestExplosionSingleTestVWM::tryCreateExplosionSingleVWM(const std::string &esName,
int ammoId,
const Core::GeoPosition2D & position)
{
INFO_LOG(m_logger) << "tryCreateExplosionSingleVWM"
<< " name ='" << esName << "'"
<< " ammoId = " << ammoId
<< " position = " << position;
m_esData = AreaEffectSimulation::ExplosionSingle();
AreaEffectSimulation::ExplosionSingle esData;
esData.id(0);
esData.name(esName);
esData.effectStart((time(nullptr) + 4) * 1000); // msec
esData.chargeStruct().chargeTypeId(ammoId);
esData.impactPosition(position);
esData.partyId(3); // 3 -> blau
esData.participantId(1234);
esData.externalId(1);
esData.effectMarkingInTa(false);
INFO_LOG(m_logger) << "trying to send explosionSingleCreateRequest()";
m_replyError = false;
m_bIsCreatedRequest = true;
m_bExpectedFailure = false;
m_expectedAesId = -1;
if (!m_ftc->explosionSingleModifyRequest(
ExplosionSingleModifyRequest(
0,
esData.name(),
esData.effectStart(),
esData.effectSourceId(),
esData.chargeStruct().chargeTypeId(),
esData.impactPosition(),
esData.partyId(),
esData.participantId(),
esData.fireRequestTime(),
esData.altitude(),
esData.purpose(),
esData.effectMarkingInTa(),
esData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error during explosionSingleCreateRequest()";
failExit();
return;
}
// TestBase::onAesCreateReply should update m_expectedAesId:
if (!waitForData([this]() { return m_esData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating single explosion object (try with error)";
}
INFO_LOG(m_logger) << "got answer, m_replyError=" << m_replyError
<< " m_expectedAesId=" << m_expectedAesId;
std::cerr << "got answer, m_replyError=" << m_replyError
<< " m_expectedAesId=" << m_expectedAesId << std::endl;
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
}
void TestExplosionSingleTestVWM::onExplosionSingleCreateReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
} // namespace AreaEffectSimulation
// ------------------------------------------------------------------
int main(int argc, char **argv)
{
// LOGGING: log4cxx_aes.props -> ctc_aes.log
// find name, ammoId, position
std::string name;
int ammoId = -1;
Core::GeoPosition2D position;
{
for (int i=1; i<argc; ++i)
{
if (strcmp(argv[i], "name") == 0)
name = argv[i+1];
if (strcmp(argv[i], "ammoId") == 0)
ammoId = atoi(argv[i+1]);
if (strcmp(argv[i], "x") == 0)
position.lon(atof(argv[i+1]));
if (strcmp(argv[i], "y") == 0)
position.lat(atof(argv[i+1]));
}
}
if (!name.empty())
{
std::cerr << " name = '" << name << "'"
<< " ammoId = '" << ammoId
<< " position = '" << position << std::endl;
std::function<AreaEffectSimulation::TestBase*()> createFunc = [name, ammoId, position]() {
auto ptr = new AreaEffectSimulation::TestExplosionSingleTestVWM;
ptr->setName(name);
ptr->setAmmoId(ammoId);
ptr->setPosition(position);
return ptr;
};
return AreaEffectSimulation::mainBase(argc, argv, createFunc);
} else {
return AreaEffectSimulation::mainBase(argc, argv, []() { return new AreaEffectSimulation::TestExplosionSingle; });
}
}
@@ -0,0 +1,78 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestExplosionSingle : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::ExplosionSingleModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::ExplosionSingleRemoveReplyHandler
{
Q_OBJECT
public:
explicit TestExplosionSingle(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
public Q_SLOTS:
void startTest() override { tryCreateExplosionSingle(); }
private Q_SLOTS:
void tryCreateExplosionSingle();
void tryModifyExplosionSingle();
void waitExpireExplosionSingle();
protected Q_SLOTS:
void explosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType);
protected:
void onExplosionSingleModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onExplosionSingleRemoveReply(const Core::FunctionReplyObject &replyObject) override;
private:
bool checkBaseData(const AreaEffectSimulation::ExplosionSingle &a,
const AreaEffectSimulation::ExplosionSingle &b) const;
protected:
AreaEffectSimulation::ExplosionSingle m_esData;
};
class TestExplosionSingleTestVWM final : public TestExplosionSingle
{
Q_OBJECT
public:
explicit TestExplosionSingleTestVWM(QObject *parent = nullptr);
void setName(const std::string &name) { m_name = name; }
void setAmmoId(int ammoId) { m_ammoId = ammoId; }
void setPosition(const Core::GeoPosition2D &position) { m_position = position; }
public Q_SLOTS:
void startTest() override
{
tryCreateExplosionSingleVWM(m_name, m_ammoId, m_position);
}
private Q_SLOTS:
void tryCreateExplosionSingleVWM(const std::string &esName = "Norbert",
int ammoId = 371,
const Core::GeoPosition2D &position = Core::GeoPosition2D(0.202603, 0.916049)
);
void onExplosionSingleCreateReply(const Core::FunctionReplyObject &replyObject);
private:
std::string m_name;
int m_ammoId{-1};
Core::GeoPosition2D m_position;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,128 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_gas_pipe.h"
#include <QCoreApplication>
#include <QTest>
#include <QTimer>
namespace AreaEffectSimulation
{
TestGasPipe::TestGasPipe(QObject *parent)
: TestBase("Test.GasPipe", parent)
, m_refPos(LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32UMD8000090000")))
{}
bool TestGasPipe::init(int domainId, int exerciseId, int testId)
{
if (!TestBase::init(domainId, exerciseId, testId))
return false;
tryCreateGasPipe();
m_dtc->waitForHistoricalDataGasPipe();
m_esData.id(-1);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::gasPipeChanged,
this, &TestGasPipe::gasPipeChanged);
return true;
}
bool TestGasPipe::checkBaseData(const AreaEffectSimulation::GasPipe &a,
const AreaEffectSimulation::GasPipe &b) const
{
if (!checkAesItem(a, b))
return false;
/*if (a.impactPosition() != b.impactPosition())
{
WARNING_LOG(m_logger) << "impactPosition does not match: " << a.impactPosition() << " - " << b.impactPosition();
return false;
}*/
return true;
}
static inline void setPos(std::vector<Core::GeoPosition2D> &cont, const QPointF &pos)
{
cont.emplace_back(Core::GeoPosition2D(pos.x(), pos.y()));
}
//
// GasPipe
//
void TestGasPipe::tryCreateGasPipe()
{
AreaEffectSimulation::GasPipeModifyRequest gp;
//AreaEffectSimulation::GasPipe gp;
gp.id(0);
gp.name("GasPipe");
gp.partyId(1);
setPos(gp.segments(), m_refPos.geographic(3, 3));
setPos(gp.segments(), m_refPos.geographic(4, 4));
setPos(gp.segments(), m_refPos.geographic(5, 3));
DEBUG_LOG(m_logger) << LOGFUNCTION << " GasPipe created. id: " << gp.id();
DEBUG_LOG(m_logger) << "request GasPipe";
if (!m_ftc->gasPipeModifyRequest( gp, this))
{
ERROR_LOG(m_logger) << "Error during explosionSingleCreateRequest()";
failExit();
return;
}
}
void TestGasPipe::tryModifyGasPipe()
{
INFO_LOG(m_logger) << "tryModifyGasPipe successful";
}
void TestGasPipe::waitExpireGasPipe()
{
INFO_LOG(m_logger) << "waiting until explosion single expires";
if (!waitForData([this]() { return m_esData.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired;}))
{
ERROR_LOG(m_logger) << "Timeout waiting for expiry of explosion single with id " << m_esData.id();
failExit();
return;
}
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
INFO_LOG(m_logger) << "waitExpireGasPipe successful";
}
void TestGasPipe::gasPipeChanged(const AreaEffectSimulation::GasPipe &data, DataModification modType)
{
if (m_esData.id() == -1)
return;
onAesChanged(data, modType, m_esData);
}
void TestGasPipe::onGasPipeModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestGasPipe::onGasPipeRemoveReply(const Core::FunctionReplyObject &replyObject)
{
onAesRemoveReply(replyObject);
}
} // namespace AreaEffectSimulation
// ------------------------------------------------------------------
int main(int argc, char **argv)
{
return AreaEffectSimulation::mainBase(argc, argv, []() { return new AreaEffectSimulation::TestGasPipe; });
}
@@ -0,0 +1,46 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
#include <LtsCoordTrans/lts_coord_trans.h>
#include <QPointF>
namespace AreaEffectSimulation
{
class TestGasPipe final : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::GasPipeModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::GasPipeRemoveReplyHandler
{
Q_OBJECT
public:
explicit TestGasPipe(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
public Q_SLOTS:
void startTest() override { tryCreateGasPipe(); }
private Q_SLOTS:
void tryCreateGasPipe();
void tryModifyGasPipe();
void waitExpireGasPipe();
protected Q_SLOTS:
void gasPipeChanged(const AreaEffectSimulation::GasPipe &data, DataModification modType);
protected:
void onGasPipeModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onGasPipeRemoveReply(const Core::FunctionReplyObject &replyObject) override;
private:
bool checkBaseData(const AreaEffectSimulation::GasPipe &a,
const AreaEffectSimulation::GasPipe &b) const;
private:
AreaEffectSimulation::GasPipe m_esData;
LtsCoordTrans::UtmCoordinate m_refPos;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,734 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_mine_area.h"
#include "Utils/polygons.h"
#include "qjsonobject.h"
#include <QCoreApplication>
#include <QJsonDocument>
#include <QTest>
#include <QTimer>
#include <LtsCoordTrans/lts_coord_trans.h>
namespace AreaEffectSimulation
{
// must be in pdm.pdm_charge_type
static const int s_ChargeTypeId1 = 53; // Virtual AP
static const int s_ChargeTypeId2 = 40; // DUS AP
static const int s_ChargeTypeId3 = 213; // DUS-Mine
static const int s_ChargeTypeId4 = 240; // Concrete-Mine
TestMineArea::TestMineArea(QObject *parent)
: TestBase("Test.MineArea", parent)
{
}
bool TestMineArea::init(int domainId, int exerciseId, int testId)
{
if (!TestBase::init(domainId, exerciseId, testId))
return false;
m_dtc->waitForHistoricalDataMineArea();
m_maData.id(-1);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::mineAreaChanged, this, &TestMineArea::mineAreaChanged);
return true;
}
void TestMineArea::startTest()
{
setSegmentForTesMineData();
const auto effectClusterList = m_dtc->effectClusters();
m_referencedAesItemId = 0;
for (const auto &ec : effectClusterList)
{
m_referencedAesItemId = ec.id();
}
if (m_testId <= 0)
tryCreateMineArea();
else
{
m_currentMineId = 12;
// Dus Mine Test
if (m_testId == 10)
tryCreateMineArea2(s_ChargeTypeId3);
// Concrete Mine
if (m_testId == 11)
tryCreateMineArea2(s_ChargeTypeId4);
if (m_testId == 12)
tryCreateMineArea2(215, 0.109); // Virt. Mine
if (m_testId == 15)
testMineData_11(); // Virt. Mine
if (m_testId == 16)
testAddMineData_11(); // Virt. Mine
if (m_testId == 17)
testMineData_21(); // Virt. Mine
if (m_testId == 18)
testAddMineData_21(); // Virt. Mine
}
}
bool TestMineArea::checkBaseData(const AreaEffectSimulation::MineArea &a, const AreaEffectSimulation::MineArea &b) const
{
if (!checkAesItem(a, b))
return false;
for (size_t i = 0; i < a.segments().size() && i < b.segments().size(); ++i)
{
if (a.segments()[i] != b.segments()[i])
{
WARNING_LOG(m_logger) << "impactPosition does not match: " << a.segments()[i] << " - " << b.segments()[i];
return false;
}
}
return true;
}
//
// MineArea
//
void TestMineArea::tryCreateMineArea()
{
ERROR_LOG(m_logger) << " >>>> create Mine Area...";
m_maData = AreaEffectSimulation::MineArea();
AreaEffectSimulation::MineArea esData;
esData.id(0);
esData.name("chris");
esData.effectStart((time(nullptr) + 4) * 1000); // msec
esData.chargeStruct().chargeTypeId(345863487); // Todo: Is this intended?
esData.effectDuration(400 * 1000);
esData.density(0.2);
esData.width(7.0);
esData.partyId(7);
esData.participantId(1234);
esData.layingProcedureType(AreaEffectSimulation::AesMaLayingProcedureType_def::LptArtillery);
esData.isLaidHidden(true);
std::vector<Core::GeoPosition2D> segments;
segments.emplace_back(Core::GeoPosition2D(0.17001, 0.93001));
segments.emplace_back(Core::GeoPosition2D(0.17002, 0.93002));
segments.emplace_back(Core::GeoPosition2D(0.17003, 0.93003));
const double distance = 100.0;
INFO_LOG(m_logger) << "trying to send mineAreaCreateRequest()";
m_replyError = false;
m_bExpectedFailure = true;
m_bIsCreatedRequest = true;
if (!m_ftc->mineAreaModifyRequest(MineAreaModifyRequest(0,
esData.name(),
esData.effectStart(),
esData.effectDuration(),
esData.effectSourceId(),
esData.density(),
esData.width(),
{esData.chargeStruct().chargeTypeId(), 0, 0},
segments,
esData.partyId(),
esData.participantId(),
esData.layingProcedureType(),
esData.isLaidHidden(),
esData.effectMarkingInTa(),
true,
distance,
esData.externalId(),
true),
this))
{
ERROR_LOG(m_logger) << "Error during mineAreaCreateRequest()";
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 mine area object (try with error)";
failExit();
return;
}
// now with correct charge type
m_bExpectedFailure = false;
m_expectedAesId = -1;
m_bIsCreatedRequest = true;
esData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
if (!m_ftc->mineAreaModifyRequest(MineAreaModifyRequest(esData.id(),
esData.name(),
esData.effectStart(),
esData.effectDuration(),
esData.effectSourceId(),
esData.density(),
esData.width(),
{esData.chargeStruct().chargeTypeId(), 0, 0},
segments,
esData.partyId(),
esData.participantId(),
esData.layingProcedureType(),
esData.isLaidHidden(),
esData.effectMarkingInTa(),
true,
distance,
esData.externalId(),
true),
this))
{
ERROR_LOG(m_logger) << "Error during mineAreaCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_maData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating mine area object";
failExit();
return;
}
if (!checkBaseData(m_maData, esData))
{
ERROR_LOG(m_logger) << "Creation data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestMineArea::tryModifyMineArea);
INFO_LOG(m_logger) << "tryCreateMineArea successful";
}
// test Mine Data
void TestMineArea::testMineData_11()
{
if (m_referencedAesItemId == 0)
{
ERROR_LOG(m_logger) << " TESTING ADD MINE DATA WILL NOT BE POSSIBLE. CREATE A EFFECT CLUSTER BEFORE STARTING THIS TEST";
return;
}
if (!m_ftc->isMineAreaReferenceModifyEnabled())
{
if (!m_ftc->enableMineAreaReferenceModify())
{
ERROR_LOG(m_logger) << "Error updating mine area object";
failExit();
return;
}
}
QVector<Database::AesMineAreaSegment> dbsegments;
int count = 0;
std::vector<Core::GeoPosition2D> addVec;
addVec.push_back({0.154111, 0.925984});
addVec.push_back({0.154111, 0.925937});
addVec.push_back({0.154137, 0.925984});
addVec.push_back({0.154137, 0.925937});
qCritical() << " ---> newSegments Pos count: " << addVec.size();
std::vector<MineData> mineData;
count = 60;
QDateTime date = QDateTime::currentDateTime().addDays(7);
for (const auto &pos : addVec)
{
MineData m;
// auto dt = QDateTime::fromMSecsSinceEpoch(date.toMSecsSinceEpoch());
m.appearenceTime(date.toMSecsSinceEpoch());
m.armingTime(date.addDays(count).toMSecsSinceEpoch());
m.position() = pos;
count += 6;
mineData.push_back(m);
}
qCritical() << " ---> final mineAreaReferenceModifyRequest ";
m_replyError = false;
m_bExpectedFailure = false;
m_bIsCreatedRequest = true;
if (!m_ftc->mineAreaReferenceModifyRequest(MineAreaReferenceModifyRequest(m_referencedAesItemId, 216, m_wirkzeitMsec, mineData)))
{
ERROR_LOG(m_logger) << "Error during mineAreaReferenceModifyRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_replyError == false; }))
{
ERROR_LOG(m_logger) << "Error creating mine area from mine data with referenced Id: " << m_referencedAesItemId;
failExit();
return;
}
// QTimer::singleShot(3000, this, &TestMineArea::testAddMineData_11);
}
void TestMineArea::testAddMineData_11()
{
if (m_referencedAesItemId == 0)
{
ERROR_LOG(m_logger) << " TESTING ADD MINE DATA WILL NOT BE POSSIBLE. CREATE A EFFECT CLUSTER BEFORE STARTING THIS TEST";
return;
}
if (!m_ftc->enableMineAreaReferenceModify())
{
ERROR_LOG(m_logger) << "Error updating mine area object";
failExit();
return;
}
QVector<Database::AesMineAreaSegment> dbsegments;
int count = 0;
std::vector<Core::GeoPosition2D> addVec;
addVec.push_back({0.154111, 0.925937});
addVec.push_back({0.154111, 0.925900});
addVec.push_back({0.154137, 0.925937});
addVec.push_back({0.154137, 0.925900});
qCritical() << " ---> newSegments Pos count: " << addVec.size();
std::vector<MineData> mineData;
count = 60;
QDateTime date = QDateTime::currentDateTime().addDays(7);
for (const auto &pos : addVec)
{
MineData m;
// auto dt = QDateTime::fromMSecsSinceEpoch(date.toMSecsSinceEpoch());
m.appearenceTime(date.toMSecsSinceEpoch());
m.armingTime(date.addDays(count).toMSecsSinceEpoch());
m.position() = pos;
count += 6;
mineData.push_back(m);
}
qCritical() << " ---> final mineAreaReferenceModifyRequest ";
if (!m_ftc->mineAreaReferenceModifyRequest(MineAreaReferenceModifyRequest(m_referencedAesItemId, 216, m_wirkzeitMsec, mineData)))
{
ERROR_LOG(m_logger) << "Error during mineAreaReferenceModifyRequest()";
failExit();
return;
}
}
void TestMineArea::testMineData_21()
{
if (m_referencedAesItemId == 0)
{
ERROR_LOG(m_logger) << " TESTING ADD MINE DATA WILL NOT BE POSSIBLE. CREATE A EFFECT CLUSTER BEFORE STARTING THIS TEST";
return;
}
if (!m_ftc->enableMineAreaReferenceModify())
{
ERROR_LOG(m_logger) << "Error updating mine area object";
failExit();
return;
}
QVector<Database::AesMineAreaSegment> dbsegments;
int count = 0;
std::vector<Core::GeoPosition2D> addVec;
addVec.push_back({0.153900, 0.925950});
addVec.push_back({0.153825, 0.925905});
addVec.push_back({0.153850, 0.925890});
addVec.push_back({0.153929, 0.925937});
qCritical() << " ---> newSegments Pos count: " << addVec.size();
std::vector<MineData> mineData;
count = 60;
QDateTime date = QDateTime::currentDateTime().addDays(7);
for (const auto &pos : addVec)
{
MineData m;
// auto dt = QDateTime::fromMSecsSinceEpoch(date.toMSecsSinceEpoch());
m.appearenceTime(date.toMSecsSinceEpoch());
m.armingTime(date.addDays(count).toMSecsSinceEpoch());
m.position() = pos;
count += 6;
mineData.push_back(m);
}
qCritical() << " ---> final mineAreaReferenceModifyRequest ";
if (!m_ftc->mineAreaReferenceModifyRequest(MineAreaReferenceModifyRequest(m_referencedAesItemId, 216, m_wirkzeitMsec, mineData)))
{
ERROR_LOG(m_logger) << "Error during mineAreaReferenceModifyRequest()";
failExit();
return;
}
// QTimer::singleShot(3000, this, &TestMineArea::testAddMineData_21);
}
void TestMineArea::testAddMineData_21()
{
if (m_referencedAesItemId == 0)
{
ERROR_LOG(m_logger) << " TESTING ADD MINE DATA WILL NOT BE POSSIBLE. CREATE A EFFECT CLUSTER BEFORE STARTING THIS TEST";
return;
}
if (!m_ftc->enableMineAreaReferenceModify())
{
ERROR_LOG(m_logger) << "Error updating mine area object";
failExit();
return;
}
QVector<Database::AesMineAreaSegment> dbsegments;
int count = 0;
std::vector<Core::GeoPosition2D> addVec;
addVec.push_back({0.153900, 0.925937});
addVec.push_back({0.153955, 0.925937});
addVec.push_back({0.153955, 0.925920});
addVec.push_back({0.153900, 0.925920});
qCritical() << " ---> newSegments Pos count: " << addVec.size();
std::vector<MineData> mineData;
count = 60;
QDateTime date = QDateTime::currentDateTime().addDays(7);
for (const auto &pos : addVec)
{
MineData m;
// auto dt = QDateTime::fromMSecsSinceEpoch(date.toMSecsSinceEpoch());
m.appearenceTime(date.toMSecsSinceEpoch());
m.armingTime(date.addDays(count).toMSecsSinceEpoch());
m.position() = pos;
count += 6;
mineData.push_back(m);
}
qCritical() << " ---> final mineAreaReferenceModifyRequest ";
if (!m_ftc->mineAreaReferenceModifyRequest(MineAreaReferenceModifyRequest(m_referencedAesItemId, 216, m_wirkzeitMsec, mineData)))
{
ERROR_LOG(m_logger) << "Error during mineAreaReferenceModifyRequest()";
failExit();
return;
}
}
void TestMineArea::setSegmentForTesMineData()
{
std::vector<Core::GeoPosition2D> segments;
// (form == 1)
{
std::vector<Core::GeoPosition2D> segments;
segments.emplace_back(Core::GeoPosition2D(0.154136, 0.926118));
segments.emplace_back(Core::GeoPosition2D(0.154136, 0.926231));
m_mapSegmentForm.insert(1, segments);
}
// (form == 2)
{
std::vector<Core::GeoPosition2D> segments;
segments.emplace_back(Core::GeoPosition2D(0.154215, 0.926000));
segments.emplace_back(Core::GeoPosition2D(0.15345, 0.926231));
m_mapSegmentForm.insert(1, segments);
}
// (form == 3)
{
std::vector<Core::GeoPosition2D> segments;
segments.emplace_back(Core::GeoPosition2D(0.153581, 0.926173));
segments.emplace_back(Core::GeoPosition2D(0.154500, 0.926126));
m_mapSegmentForm.insert(3, segments);
}
}
void TestMineArea::tryModifyMineArea()
{
INFO_LOG(m_logger) << "trying to send modify request";
m_maData.name("chris2");
m_maData.effectStart(m_maData.effectStart().get() + 2000);
m_maData.chargeStruct().chargeTypeId(s_ChargeTypeId2);
m_maData.effectDuration(4 * 1000);
m_maData.density(0.2);
m_maData.width(7.0);
m_maData.partyId(8);
m_maData.participantId(1235);
m_maData.layingProcedureType(AreaEffectSimulation::AesMaLayingProcedureType_def::LptArtillery);
m_maData.isLaidHidden(false);
const AreaEffectSimulation::MineArea esData(m_maData);
m_maData = AreaEffectSimulation::MineArea();
m_maData.id(esData.id());
m_maData.effectMarkingInTa(true);
std::vector<Core::GeoPosition2D> segments;
segments.emplace_back(Core::GeoPosition2D(0.17004, 0.93004));
segments.emplace_back(Core::GeoPosition2D(0.17004, 0.93005));
const double distance = 100.0;
m_bIsCreatedRequest = false;
if (!m_ftc->mineAreaModifyRequest(MineAreaModifyRequest(esData.id(),
esData.name(),
esData.effectStart(),
esData.effectDuration(),
esData.effectSourceId(),
esData.density(),
esData.width(),
{esData.chargeStruct().chargeTypeId(), 0, 0},
segments,
esData.partyId(),
esData.participantId(),
esData.layingProcedureType(),
esData.isLaidHidden(),
esData.effectMarkingInTa(),
true,
distance,
esData.externalId(),
true),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_maData.chargeStruct().chargeTypeId() == s_ChargeTypeId2; }))
{
ERROR_LOG(m_logger) << "Error updating mine area object";
failExit();
return;
}
// No testing, segments won't match!
// if (!checkBaseData(m_maData, esData))
// {
// ERROR_LOG(m_logger) << "Modify data does not match published data";
// failExit();
// return;
// }
QTimer::singleShot(0, this, &TestMineArea::tryCreateAnotherMineArea);
INFO_LOG(m_logger) << "tryModifyMineArea successful";
}
//
// MineArea
//
void TestMineArea::tryCreateAnotherMineArea()
{
INFO_LOG(m_logger) << "trying to create another area request";
AreaEffectSimulation::MineArea esData;
esData.id(0);
esData.name("chris");
esData.effectStart((time(nullptr) + 4) * 1000); // msec
esData.chargeStruct().chargeTypeId(s_ChargeTypeId2);
esData.effectDuration(4 * 1000);
esData.density(0.2);
esData.width(7.0);
esData.partyId(7);
esData.participantId(1234);
esData.layingProcedureType(AreaEffectSimulation::AesMaLayingProcedureType_def::LptArtillery);
esData.isLaidHidden(false);
std::vector<Core::GeoPosition2D> segments;
segments.emplace_back(Core::GeoPosition2D(0.17004, 0.93004));
segments.emplace_back(Core::GeoPosition2D(0.17005, 0.93004));
const double distance = 100.0;
INFO_LOG(m_logger) << "trying to send mineAreaCreateRequest()";
m_replyError = true;
m_bIsCreatedRequest = true;
if (!m_ftc->mineAreaModifyRequest(MineAreaModifyRequest(0,
esData.name(),
esData.effectStart(),
esData.effectDuration(),
esData.effectSourceId(),
esData.density(),
esData.width(),
{esData.chargeStruct().chargeTypeId(), 0, 0},
segments,
esData.partyId(),
esData.participantId(),
esData.layingProcedureType(),
esData.isLaidHidden(),
esData.effectMarkingInTa(),
true,
distance,
esData.externalId(),
true),
this))
{
ERROR_LOG(m_logger) << "Modify data does not match published data";
failExit();
return;
}
if (!waitForData([this]() { return m_replyError == false; }))
{
ERROR_LOG(m_logger) << "Error creating mine area object (try with error)";
failExit();
return;
}
QTimer::singleShot(0, this, &TestMineArea::tryTriggerDusMineInBoth);
INFO_LOG(m_logger) << "tryCreateMineArea successful";
}
void TestMineArea::tryCreateMineArea2(int chargeTypeId, double density)
{
m_maData = AreaEffectSimulation::MineArea();
AreaEffectSimulation::MineArea esData;
esData.id(0);
esData.name("1337Test");
esData.effectStart((time(nullptr) + 4) * 1000); // msec
esData.chargeStruct().chargeTypeId(chargeTypeId);
esData.effectDuration(400 * 1000);
esData.density(density);
esData.width(7.0);
esData.partyId(7);
esData.participantId(1234);
esData.layingProcedureType(AreaEffectSimulation::AesMaLayingProcedureType_def::LptArtillery);
esData.isLaidHidden(false);
std::vector<Core::GeoPosition2D> segments;
/* Erzeugung der GeoKoordinaten fuer den guez-spezifischen zentralen Bereich (Sueden)
QPointF pos = LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UPD 74600 14100"));
ERROR_LOG(m_logger) << "pos x: " << pos.x() << ", pos y: " << pos.y();
segments.emplace_back(Core::GeoPosition2D(pos.x(), pos.y()));
pos = LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UPD 77500 14200"));
ERROR_LOG(m_logger) << "pos x: " << pos.x() << ", pos y: " << pos.y();
segments.emplace_back(Core::GeoPosition2D(pos.x(), pos.y()));
pos = LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UPD 76100 09150"));
ERROR_LOG(m_logger) << "pos x: " << pos.x() << ", pos y: " << pos.y();
segments.emplace_back(Core::GeoPosition2D(pos.x(), pos.y()));
pos = LtsCoordTrans::geographicFromMgrs(QStringLiteral("32UPD 73550 09450"));
ERROR_LOG(m_logger) << "pos x: " << pos.x() << ", pos y: " << pos.y();
segments.emplace_back(Core::GeoPosition2D(pos.x(), pos.y()));
*/
segments.emplace_back(Core::GeoPosition2D(0.15401, 0.92501));
segments.emplace_back(Core::GeoPosition2D(0.15502, 0.92702));
segments.emplace_back(Core::GeoPosition2D(0.15603, 0.93003));
const double distance = 100.0;
INFO_LOG(m_logger) << "trying to send mineAreaCreateRequest()";
m_replyError = false;
m_bExpectedFailure = false;
m_bIsCreatedRequest = true;
if (!m_ftc->mineAreaModifyRequest(MineAreaModifyRequest(0,
esData.name(),
esData.effectStart(),
esData.effectDuration(),
esData.effectSourceId(),
esData.density(),
esData.width(),
{esData.chargeStruct().chargeTypeId(), 0, 0},
segments,
esData.partyId(),
esData.participantId(),
esData.layingProcedureType(),
esData.isLaidHidden(),
esData.effectMarkingInTa(),
true,
distance,
esData.externalId(),
true),
this))
{
ERROR_LOG(m_logger) << "Error during mineAreaCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_replyError == false; }))
{
ERROR_LOG(m_logger) << "Error creating mine area object with chargeTypeId " << chargeTypeId;
failExit();
return;
}
}
void TestMineArea::tryTriggerDusMineInBoth()
{
AreaEffectSimulation::MineTriggeredRequest mtr;
mtr.mineAreaId(0); // DUS does not send mine area ID!
mtr.mineId(123);
mtr.position(Core::GeoPosition2D(0.170041, 0.930041));
mtr.chargeTypeId(48);
INFO_LOG(m_logger) << "trying to send mineTriggeredRequest()";
m_replyError = true;
if (!m_ftc->mineTriggeredRequest(MineTriggeredRequest(mtr.mineAreaId(), mtr.mineId(), mtr.position().get(), mtr.chargeTypeId().get()), this))
{
ERROR_LOG(m_logger) << "Error during mineTriggeredRequest()";
failExit();
return;
}
// since the chargeTypeId is not valid, we should get an error
if (!waitForData([this]() { return m_replyError == false; }))
{
ERROR_LOG(m_logger) << "Error triggering mine (try with error)";
failExit();
return;
}
QTimer::singleShot(0, this, &TestMineArea::waitExpireMineArea);
INFO_LOG(m_logger) << "tryTriggerDusMineInBoth successful";
}
void TestMineArea::waitExpireMineArea()
{
INFO_LOG(m_logger) << "waiting until mine area expires";
if (!waitForData([this]() { return m_maData.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired; }))
{
ERROR_LOG(m_logger) << "Timeout waiting for expiry of mine area with id " << m_maData.id();
failExit();
return;
}
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
INFO_LOG(m_logger) << "waitExpireMineArea successful";
}
void TestMineArea::mineAreaChanged(const AreaEffectSimulation::MineArea &data, DataModification modType)
{
if (m_maData.id() == -1)
return;
onAesChanged(data, modType, m_maData);
}
void TestMineArea::onMineAreaModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestMineArea::onMineAreaRemoveReply(const Core::FunctionReplyObject &replyObject) { onAesRemoveReply(replyObject); }
void TestMineArea::onMineResetReply(const Core::FunctionReplyObject &replyObject)
{
INFO_LOG(m_logger) << "Got mine reset with id " << replyObject.id() << " and errorString " << replyObject.translated();
m_replyError = replyObject.error();
if (m_replyError)
{
ERROR_LOG(m_logger) << "Got mine reset reply error: " << replyObject();
}
}
void TestMineArea::onMineTriggeredReply(const Core::FunctionReplyObject &replyObject)
{
INFO_LOG(m_logger) << "Got mine triggered with id " << replyObject.id() << " and errorString " << replyObject.translated();
m_replyError = replyObject.error();
if (m_replyError)
{
ERROR_LOG(m_logger) << "Got mine triggered reply error: " << replyObject();
}
}
void TestMineArea::onMineAreaReferenceModifyReply(const Core::FunctionReplyObject &replyObject)
{
INFO_LOG(m_logger) << "Modify Mine Area with reference replyObj.id: " << replyObject.id() << " and errorString " << replyObject.translated();
m_replyError = replyObject.error();
if (m_replyError)
{
ERROR_LOG(m_logger) << "Got mine modify reply error: " << replyObject();
}
}
} // namespace AreaEffectSimulation
// ------------------------------------------------------------------
int main(int argc, char **argv)
{
return AreaEffectSimulation::mainBase(argc, argv, []() { return new AreaEffectSimulation::TestMineArea; });
}
@@ -0,0 +1,64 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestMineArea final
: public TestBase
, protected AreaEffectSimulation::Interface::Ftc::MineAreaModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::MineAreaRemoveReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::MineResetReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::MineTriggeredReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::MineAreaReferenceModifyReplyHandler
{
Q_OBJECT
public:
explicit TestMineArea(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
public Q_SLOTS:
void startTest() override;
private Q_SLOTS:
void tryCreateMineArea();
void testMineData_11();
void testAddMineData_11();
void testMineData_21();
void testAddMineData_21();
void setSegmentForTesMineData();
void tryModifyMineArea();
void waitExpireMineArea();
void tryTriggerDusMineInBoth();
void tryCreateAnotherMineArea();
void tryCreateMineArea2(int chargeTypeId, double density = 0.2);
protected Q_SLOTS:
void mineAreaChanged(const AreaEffectSimulation::MineArea &data, DataModification modType);
protected:
void onMineAreaModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onMineAreaRemoveReply(const Core::FunctionReplyObject &replyObject) override;
void onMineResetReply(const Core::FunctionReplyObject &replyObject) override;
void onMineTriggeredReply(const Core::FunctionReplyObject &replyObject) override;
void onMineAreaReferenceModifyReply(const Core::FunctionReplyObject &replyObject) override;
private:
bool checkBaseData(const AreaEffectSimulation::MineArea &a, const AreaEffectSimulation::MineArea &b) const;
private:
AreaEffectSimulation::MineArea m_maData;
QMap<int, std::vector<Core::GeoPosition2D>> m_mapSegmentForm;
int m_referencedAesItemId = 0;
int32_t m_wirkzeitMsec = 3 * 10 * 1000; // 30 sec
int m_currentMineId = 0;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,320 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_ncontamination.h"
#include <QCoreApplication>
#include <QTest>
#include <QTimer>
namespace AreaEffectSimulation
{
// must be in pdm.pdm_charge_type
static const int s_ChargeTypeId1 = 321;
TestNContamination::TestNContamination(QObject *parent)
: TestBase("Test.NContamination", parent)
{}
bool TestNContamination::init(int domainId, int exerciseId, int testId)
{
if (!TestBase::init(domainId, exerciseId, testId))
return false;
m_dtc->waitForHistoricalDataNContamination();
m_ncData.id(-1);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::nContaminationChanged,
this, &TestNContamination::nContaminationChanged);
return true;
}
bool TestNContamination::checkBaseData(const AreaEffectSimulation::NContamination &a,
const AreaEffectSimulation::NContamination &b) const
{
if (!checkAesItem(a, b))
return false;
if (a.impactPosition() != b.impactPosition())
{
WARNING_LOG(m_logger) << "impactPosition does not match: " << a.impactPosition() << " - " << b.impactPosition();
return false;
}
return true;
}
//
// NContamination
//
void TestNContamination::tryCreateNContamination()
{
m_ncData = AreaEffectSimulation::NContamination();
AreaEffectSimulation::NContamination ncData;
ncData.id(0);
ncData.name("ncont1");
ncData.effectStart((time(nullptr) + 4) * 1000); // msec
ncData.effectDuration(10000); // 10 sec
ncData.chargeStruct().chargeTypeId(345863487);
ncData.impactPosition(Core::GeoPosition2D(0.16, 0.92));
ncData.borderLengthInner(1000); // 1km
ncData.borderLengthOuter(2000); // 2km
ncData.impactRadius(500); // 500m
ncData.spanAngle(31);
ncData.rotationAngle(57);
ncData.detonationValue(1000); // kt, only cosmetical
ncData.partyId(7);
ncData.participantId(1234);
INFO_LOG(m_logger) << "trying to send NContaminationCreateRequest()";
m_replyError = false;
m_bExpectedFailure = true;
m_bIsCreatedRequest = true;
if (!m_ftc->nContaminationModifyRequest(
NContaminationModifyRequest(
0,
ncData.name(),
ncData.effectStart(),
ncData.effectDuration(),
ncData.chargeStruct().chargeTypeId(),
ncData.impactPosition(),
ncData.borderLengthInner(),
ncData.borderLengthOuter(),
ncData.impactRadius(),
ncData.spanAngle(),
ncData.rotationAngle(),
ncData.detonationValue(),
ncData.weatherSource(),
ncData.partyId(),
ncData.participantId(),
ncData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error during NContaminationCreateRequest()";
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 ncontamination object (try with error)";
failExit();
return;
}
m_bExpectedFailure = false;
m_expectedAesId = -1;
m_bIsCreatedRequest = true;
// now with correct charge type
ncData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
if (!m_ftc->nContaminationModifyRequest(
NContaminationModifyRequest(
0,
ncData.name(),
ncData.effectStart(),
ncData.effectDuration(),
ncData.chargeStruct().chargeTypeId(),
ncData.impactPosition(),
ncData.borderLengthInner(),
ncData.borderLengthOuter(),
ncData.impactRadius(),
ncData.spanAngle(),
ncData.rotationAngle(),
ncData.detonationValue(),
ncData.weatherSource(),
ncData.partyId(),
ncData.participantId(),
ncData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error during NContaminationCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_ncData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating ncontamination object";
failExit();
return;
}
if (!checkBaseData(m_ncData, ncData))
{
ERROR_LOG(m_logger) << "Creation data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestNContamination::tryModifyNContamination);
INFO_LOG(m_logger) << "tryCreateNContamination successful";
}
void TestNContamination::tryModifyNContamination()
{
INFO_LOG(m_logger) << "trying to send modify request";
m_ncData.name("ncont2");
m_ncData.effectStart((time(nullptr) + 4) * 1000); // msec
m_ncData.effectDuration(3000); // 3 sec
m_ncData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
m_ncData.impactPosition(Core::GeoPosition2D(0.162, 0.925));
m_ncData.borderLengthInner(1100); // 1.1km
m_ncData.borderLengthOuter(1800); // 1.8km
m_ncData.impactRadius(600); // 600m
m_ncData.spanAngle(14);
m_ncData.rotationAngle(187);
m_ncData.detonationValue(2000); // kt, only cosmetical
m_ncData.partyId(3);
m_ncData.participantId(1235);
const AreaEffectSimulation::NContamination ncData(m_ncData);
m_ncData = AreaEffectSimulation::NContamination();
m_ncData.id(ncData.id());
m_bIsCreatedRequest = false;
if (!m_ftc->nContaminationModifyRequest(
NContaminationModifyRequest(
ncData.id(),
ncData.name(),
ncData.effectStart(),
ncData.effectDuration(),
ncData.chargeStruct().chargeTypeId(),
ncData.impactPosition(),
ncData.borderLengthInner(),
ncData.borderLengthOuter(),
ncData.impactRadius(),
ncData.spanAngle(),
ncData.rotationAngle(),
ncData.detonationValue(),
ncData.weatherSource(),
ncData.partyId(),
ncData.participantId(),
ncData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_ncData.partyId() == 3;}))
{
ERROR_LOG(m_logger) << "Error updating ncontamination object";
failExit();
return;
}
if (!checkBaseData(m_ncData, ncData))
{
ERROR_LOG(m_logger) << "Modify data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestNContamination::waitExpireNContamination);
INFO_LOG(m_logger) << "tryModifyNContamination successful";
}
void TestNContamination::waitExpireNContamination()
{
INFO_LOG(m_logger) << "waiting until ncontamination expires";
if (!waitForData([this]() { return m_ncData.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired;}))
{
ERROR_LOG(m_logger) << "Timeout waiting for expiry of ncontamination with id " << m_ncData.id();
failExit();
return;
}
QTimer::singleShot(0, this, &TestNContamination::tryRemoveNContamination);
INFO_LOG(m_logger) << "waitExpireNContamination successful";
}
void TestNContamination::tryRemoveNContamination()
{
INFO_LOG(m_logger) << "tryRemoveNContamination start";
AreaEffectSimulation::NContamination ncData(m_ncData);
ncData.name("RemoveTest");
ncData.effectStart(0); // not set
m_ncData = AreaEffectSimulation::NContamination();
m_expectedAesId = -1;
m_bIsCreatedRequest = true;
if (!m_ftc->nContaminationModifyRequest(
NContaminationModifyRequest(
0,
ncData.name(),
ncData.effectStart(),
ncData.effectDuration(),
ncData.chargeStruct().chargeTypeId(),
ncData.impactPosition(),
ncData.borderLengthInner(),
ncData.borderLengthOuter(),
ncData.impactRadius(),
ncData.spanAngle(),
ncData.rotationAngle(),
ncData.detonationValue(),
ncData.weatherSource(),
ncData.partyId(),
ncData.participantId(),
ncData.externalId()),
this))
{
ERROR_LOG(m_logger) << "Error during NContaminationCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_ncData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating ncontamination object";
failExit();
return;
}
m_expectedAesId = -1;
if (!m_ftc->nContaminationRemoveRequest(Core::RemoveElementRequest(m_ncData.id()), this))
{
ERROR_LOG(m_logger) << "Error during NContaminationRemoveRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_ncData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error removing ncontamination object";
failExit();
return;
}
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
INFO_LOG(m_logger) << "tryRemoveNContamination successful";
}
void TestNContamination::nContaminationChanged(const AreaEffectSimulation::NContamination &data, DataModification modType)
{
if (m_ncData.id() == -1)
return;
onAesChanged(data, modType, m_ncData);
}
void TestNContamination::onNContaminationModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestNContamination::onNContaminationRemoveReply(const Core::FunctionReplyObject &replyObject)
{
onAesRemoveReply(replyObject);
}
} // namespace AreaEffectSimulation
// ------------------------------------------------------------------
int main(int argc, char **argv)
{
return AreaEffectSimulation::mainBase(argc, argv, []() { return new AreaEffectSimulation::TestNContamination; });
}
@@ -0,0 +1,44 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestNContamination final : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::NContaminationModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::NContaminationRemoveReplyHandler
{
Q_OBJECT
public:
explicit TestNContamination(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
public Q_SLOTS:
void startTest() override { tryCreateNContamination(); }
private Q_SLOTS:
void tryCreateNContamination();
void tryModifyNContamination();
void waitExpireNContamination();
void tryRemoveNContamination();
protected Q_SLOTS:
void nContaminationChanged(const AreaEffectSimulation::NContamination &data, DataModification modType);
protected:
void onNContaminationModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onNContaminationRemoveReply(const Core::FunctionReplyObject &replyObject) override;
private:
bool checkBaseData(const AreaEffectSimulation::NContamination &a,
const AreaEffectSimulation::NContamination &b) const;
private:
AreaEffectSimulation::NContamination m_ncData;
};
} // namespace AreaEffectSimulation
@@ -0,0 +1,313 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#include "aes_test_off_route_mine.h"
#include <QCoreApplication>
#include <QTest>
#include <QTimer>
namespace AreaEffectSimulation
{
// must be in pdm.pdm_charge_type
static const int s_ChargeTypeId1 = 253;
static const int s_ChargeTypeId2 = 254;
TestOffRouteMine::TestOffRouteMine(QObject *parent)
: TestBase("Test.OffRouteMine", parent)
{}
bool TestOffRouteMine::init(int domainId, int exerciseId, int testId)
{
if (!TestBase::init(domainId, exerciseId, testId))
return false;
m_dtc->waitForHistoricalDataOffRouteMine();
m_ormData.id(-1);
connect(m_dtc.get(), &AreaEffectSimulation::Interface::Dtc::offRouteMineChanged,
this, &TestOffRouteMine::offRouteMineChanged);
return true;
}
bool TestOffRouteMine::checkBaseData(const AreaEffectSimulation::OffRouteMine &a,
const AreaEffectSimulation::OffRouteMine &b) const
{
if (!checkAesItem(a, b))
return false;
if (a.area().cornerBottomLeft() != b.area().cornerBottomLeft())
{
WARNING_LOG(m_logger) << "cornerBottomLeft does not match: " << a.area().cornerBottomLeft() << " - " << b.area().cornerBottomLeft();
return false;
}
if (a.impactRadius() != b.impactRadius())
{
WARNING_LOG(m_logger) << "impactRadius does not match: " << a.impactRadius() << " - " << b.impactRadius();
return false;
}
return true;
}
//
// OffRouteMine
//
void TestOffRouteMine::tryCreateOffRouteMine()
{
m_ormData = AreaEffectSimulation::OffRouteMine();
AreaEffectSimulation::OffRouteMine ormData;
ormData.id(0);
ormData.name("OffRouteMine1");
ormData.effectStart((time(nullptr) + 4) * 1000); // msec
ormData.effectDuration(10234); // msec
ormData.chargeStruct().chargeTypeId(3456789);
ormData.area().cornerBottomLeft(Core::GeoPosition2D(0.154, 0.926));
ormData.area().width(1000);//(20);
ormData.area().height(200);//(15);
ormData.area().rotation(0.0);//(20.5);
ormData.impactRadius(100); // 100m
ormData.partyId(2);
//ormData.participantId(1234);
INFO_LOG(m_logger) << "trying to send OffRouteMineCreateRequest()";
m_replyError = false;
m_bExpectedFailure = true;
m_bIsCreatedRequest = true;
m_expectedAesId = -1;
if (!m_ftc->offRouteMineModifyRequest(
OffRouteMineModifyRequest(
0,
ormData.name(),
ormData.effectDuration(),
ormData.chargeStruct().chargeTypeId(),
ormData.area(),
ormData.impactRadius().get(),
ormData.effectStart().get(),
ormData.partyId().get()),
this))
{
ERROR_LOG(m_logger) << "Error during OffRouteMineCreateRequest()";
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 off route mine object (try with error)";
failExit();
return;
}
// now with correct charge type
m_bExpectedFailure = false;
m_bIsCreatedRequest = true;
m_expectedAesId = -1;
ormData.chargeStruct().chargeTypeId(s_ChargeTypeId1);
if (!m_ftc->offRouteMineModifyRequest(
OffRouteMineModifyRequest(
0,
ormData.name(),
ormData.effectDuration(),
ormData.chargeStruct().chargeTypeId(),
ormData.area(),
ormData.impactRadius().get(),
ormData.effectStart().get(),
ormData.partyId().get()),
this))
{
ERROR_LOG(m_logger) << "Error during OffRouteMineCreateRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_ormData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating off route mine object";
failExit();
return;
}
if (!checkBaseData(m_ormData, ormData))
{
ERROR_LOG(m_logger) << "Creation data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestOffRouteMine::tryModifyOffRouteMine);
INFO_LOG(m_logger) << "tryCreateOffRouteMine successful";
}
void TestOffRouteMine::tryModifyOffRouteMine()
{
INFO_LOG(m_logger) << "trying to send modify request";
m_ormData.name("OffRouteMine 2");
m_ormData.effectStart(m_ormData.effectStart().get() + 2000);
m_ormData.effectDuration(3200); // msec
m_ormData.chargeStruct().chargeTypeId(s_ChargeTypeId2);
m_ormData.area().cornerBottomLeft(Core::GeoPosition2D(0.154, 0.926));
m_ormData.area().width(1000);//(50);
m_ormData.area().height(200);//(25);
m_ormData.area().rotation(90);//(20.5);
m_ormData.partyId(3);
//m_ormData.participantId(1235);
const AreaEffectSimulation::OffRouteMine ormData(m_ormData);
m_ormData = AreaEffectSimulation::OffRouteMine();
m_ormData.id(ormData.id());
m_bIsCreatedRequest = false;
if (!m_ftc->offRouteMineModifyRequest(
OffRouteMineModifyRequest(
ormData.id(),
ormData.name(),
ormData.effectDuration(),
ormData.chargeStruct().chargeTypeId(),
ormData.area(),
ormData.impactRadius().get(),
ormData.effectStart().get(),
ormData.partyId().get()),
this))
{
ERROR_LOG(m_logger) << "Error requesting modify data";
failExit();
return;
}
if (!waitForData([this]() { return m_ormData.chargeStruct().chargeTypeId() == s_ChargeTypeId2;}))
{
ERROR_LOG(m_logger) << "Error updating off route mine object";
failExit();
return;
}
if (!checkBaseData(m_ormData, ormData))
{
ERROR_LOG(m_logger) << "Modify data does not match published data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestOffRouteMine::tryTriggerOffRouteMine);
INFO_LOG(m_logger) << "tryModifyOffRouteMine successful";
}
void TestOffRouteMine::tryTriggerOffRouteMine()
{
INFO_LOG(m_logger) << "trigger off route mine -> expires";
OffRouteMineTriggerRequest req;
req.id(m_ormData.id());
req.triggered(true);
if (!m_ftc->offRouteMineTriggerRequest(req, this))
{
ERROR_LOG(m_logger) << "Error requesting trigger data";
failExit();
return;
}
QTimer::singleShot(0, this, &TestOffRouteMine::waitExpireOffRouteMine);
INFO_LOG(m_logger) << "waitExpireBoobyTrap successful";
}
void TestOffRouteMine::waitExpireOffRouteMine()
{
INFO_LOG(m_logger) << "waiting until off route mine expires";
if (!waitForData([this]() { return m_ormData.effectStateId() == AreaEffectSimulation::AesEffectState::EsExpired;}))
{
ERROR_LOG(m_logger) << "Timeout waiting for expiry of off route mine with id " << m_ormData.id();
failExit();
return;
}
//QTimer::singleShot(0, this, &TestOffRouteMine::tryRemoveOffRouteMine);
INFO_LOG(m_logger) << "waitExpireOffRouteMine successful";
}
void TestOffRouteMine::tryRemoveOffRouteMine()
{
INFO_LOG(m_logger) << "tryRemoveOffRouteMine start";
AreaEffectSimulation::OffRouteMine ormData(m_ormData);
ormData.name("RemoveTest");
ormData.effectStart(0); // not set
m_ormData = AreaEffectSimulation::OffRouteMine();
m_expectedAesId = -1;
m_bIsCreatedRequest = true;
if (!m_ftc->offRouteMineModifyRequest(
OffRouteMineModifyRequest(
0,
ormData.name(),
ormData.effectDuration(),
ormData.chargeStruct().chargeTypeId(),
ormData.area(),
ormData.impactRadius().get(),
ormData.effectStart().get(),
ormData.partyId().get()),
this))
{
ERROR_LOG(m_logger) << "Error during OffRouteMineModifyRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_ormData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error creating off route mine object";
failExit();
return;
}
m_expectedAesId = -1;
if (!m_ftc->offRouteMineRemoveRequest(Core::RemoveElementRequest(m_ormData.id()), this))
{
ERROR_LOG(m_logger) << "Error during OffRouteMineRemoveRequest()";
failExit();
return;
}
if (!waitForData([this]() { return m_ormData.id() == m_expectedAesId; }))
{
ERROR_LOG(m_logger) << "Error removing off route mine object";
failExit();
return;
}
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
INFO_LOG(m_logger) << "tryRemoveOffRouteMine successful";
}
void TestOffRouteMine::offRouteMineChanged(const AreaEffectSimulation::OffRouteMine &data, DataModification modType)
{
if (m_ormData.id() == -1)
return;
onAesChanged(data, modType, m_ormData);
}
void TestOffRouteMine::onOffRouteMineModifyReply(const Core::FunctionReplyObject &replyObject)
{
if (m_bIsCreatedRequest)
onAesCreateReply(replyObject);
else
onAesModifyReply(replyObject);
}
void TestOffRouteMine::onOffRouteMineRemoveReply(const Core::FunctionReplyObject &replyObject)
{
onAesRemoveReply(replyObject);
}
void TestOffRouteMine::onOffRouteMineTriggerReply(const Core::FunctionReplyObject &replyObject)
{
onAesTriggerReply(replyObject);
}
} // namespace AreaEffectSimulation
// ------------------------------------------------------------------
int main(int argc, char **argv)
{
return AreaEffectSimulation::mainBase(argc, argv, []() { return new AreaEffectSimulation::TestOffRouteMine; });
}
@@ -0,0 +1,47 @@
/**
* AES Function Topic Client test executable
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "aes_test_base.h"
namespace AreaEffectSimulation
{
class TestOffRouteMine final : public TestBase
, protected AreaEffectSimulation::Interface::Ftc::OffRouteMineModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::OffRouteMineRemoveReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::OffRouteMineTriggerReplyHandler
{
Q_OBJECT
public:
explicit TestOffRouteMine(QObject *parent = nullptr);
bool init(int domainId, int exerciseId, int testId) override;
public Q_SLOTS:
void startTest() override { tryCreateOffRouteMine(); }
private Q_SLOTS:
void tryCreateOffRouteMine();
void tryModifyOffRouteMine();
void tryTriggerOffRouteMine();
void waitExpireOffRouteMine();
void tryRemoveOffRouteMine();
protected Q_SLOTS:
void offRouteMineChanged(const AreaEffectSimulation::OffRouteMine &data, DataModification modType);
protected:
void onOffRouteMineModifyReply(const Core::FunctionReplyObject &replyObject) override;
void onOffRouteMineRemoveReply(const Core::FunctionReplyObject &replyObject) override;
void onOffRouteMineTriggerReply(const Core::FunctionReplyObject &replyObject) override;
private:
bool checkBaseData(const AreaEffectSimulation::OffRouteMine &a,
const AreaEffectSimulation::OffRouteMine &b) const;
private:
AreaEffectSimulation::OffRouteMine m_ormData;
};
} // namespace AreaEffectSimulation
Binary file not shown.