Heart/HeartTests/units/multiversiontest.cpp

361 lines
11 KiB
C++
Raw Normal View History

2023-05-25 23:24:48 +02:00
/*
2023-12-31 09:39:11 +01:00
* Copyright (C) 2023-2024 QuasarApp.
2023-05-25 23:24:48 +02:00
* Distributed under the lgplv3 software license, see the accompanying
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
#include "multiversiontest.h"
2023-05-28 12:33:55 +02:00
#define LOCAL_TEST_PORT TEST_PORT + 6
2023-05-27 21:40:43 +02:00
class MultiVersionPkg {
2023-05-25 23:24:48 +02:00
public:
2023-05-27 21:40:43 +02:00
int v2;
int v1;
2023-05-28 12:33:55 +02:00
bool responce = false;
2023-05-27 21:40:43 +02:00
int lastSerializedFrom = 0;
int lastSerializedto = 0;
};
2023-05-25 23:24:48 +02:00
2023-05-27 21:40:43 +02:00
class MultiVersionPkg1: public QH::PKG::MultiversionData, public MultiVersionPkg {
QH_PACKAGE("MultiVersionPkg")
2023-05-25 23:24:48 +02:00
2023-05-27 21:40:43 +02:00
public:
MultiVersionPkg1(): QH::PKG::MultiversionData(
{
2023-05-28 12:33:55 +02:00
{0, // version 0
{
[this](QDataStream& stream) -> QDataStream&{ // from
lastSerializedFrom = 0;
stream >> v1;
stream >> responce;
return stream;
},
[this](QDataStream& stream) -> QDataStream&{ // to
lastSerializedto = 0;
stream << v1;
stream << responce;
return stream;
}
}
},
{1, // version 1
{
[this](QDataStream& stream) -> QDataStream&{ // from
lastSerializedFrom = 1;
stream >> v1;
stream >> responce;
stream >> v2;
return stream;
},
[this](QDataStream& stream) -> QDataStream&{ // to
lastSerializedto = 1;
stream << v1;
stream << responce;
stream << v2;
return stream;
}
}
},
}
) {};
};
2023-05-25 23:24:48 +02:00
2023-05-28 12:33:55 +02:00
class SingleVersionPkg: public QH::PKG::AbstractData, public MultiVersionPkg {
QH_PACKAGE("MultiVersionPkg")
2023-05-27 21:40:43 +02:00
2023-05-28 12:33:55 +02:00
// StreamBase interface
protected:
QDataStream &fromStream(QDataStream &stream) override {
lastSerializedFrom = 0;
stream >> v1;
stream >> responce;
return stream;
};
QDataStream &toStream(QDataStream &stream) const override {
stream << v1;
stream << responce;
return stream;
};
2023-05-25 23:24:48 +02:00
};
2023-05-27 21:40:43 +02:00
class MultiVersionPkg2: public QH::PKG::MultiversionData, public MultiVersionPkg {
2023-05-25 23:24:48 +02:00
QH_PACKAGE("MultiVersionPkg")
public:
2023-05-27 21:40:43 +02:00
MultiVersionPkg2(): QH::PKG::MultiversionData(
2023-05-26 22:39:28 +02:00
{
{0, // version 0
{
2023-05-27 21:40:43 +02:00
[this](QDataStream& stream) -> QDataStream&{ // from
lastSerializedFrom = 0;
2023-05-26 22:39:28 +02:00
stream >> v1;
2023-05-28 12:33:55 +02:00
stream >> responce;
2023-05-26 22:39:28 +02:00
return stream;
},
2023-05-27 21:40:43 +02:00
[this](QDataStream& stream) -> QDataStream&{ // to
lastSerializedto = 0;
2023-05-26 22:39:28 +02:00
stream << v1;
2023-05-28 12:33:55 +02:00
stream << responce;
2023-05-25 23:24:48 +02:00
2023-05-26 22:39:28 +02:00
return stream;
}
}
},
{1, // version 1
{
2023-05-27 21:40:43 +02:00
[this](QDataStream& stream) -> QDataStream&{ // from
2023-05-28 12:33:55 +02:00
lastSerializedFrom = 1;
2023-05-27 21:40:43 +02:00
2023-05-26 22:39:28 +02:00
stream >> v1;
2023-05-28 12:33:55 +02:00
stream >> responce;
2023-05-26 22:39:28 +02:00
stream >> v2;
2023-05-25 23:24:48 +02:00
2023-05-26 22:39:28 +02:00
return stream;
},
2023-05-27 21:40:43 +02:00
[this](QDataStream& stream) -> QDataStream&{ // to
lastSerializedto = 1;
2023-05-26 22:39:28 +02:00
stream << v1;
2023-05-28 12:33:55 +02:00
stream << responce;
2023-05-27 21:40:43 +02:00
stream << v2;
return stream;
}
}
},
{2, // version 2
{
[this](QDataStream& stream) -> QDataStream&{ // from
lastSerializedFrom = 2;
stream >> v2;
2023-05-28 12:33:55 +02:00
stream >> responce;
2023-05-27 21:40:43 +02:00
return stream;
},
[this](QDataStream& stream) -> QDataStream&{ // to
lastSerializedto = 2;
2023-05-26 22:39:28 +02:00
stream << v2;
2023-05-28 12:33:55 +02:00
stream << responce;
2023-05-26 22:39:28 +02:00
return stream;
}
}
}
}
) {};
2023-05-27 21:40:43 +02:00
};
template <class Base>
class TestAPI: public QH::iParser {
public:
TestAPI(QH::AbstractNode* parentNode): QH::iParser(parentNode) {
registerPackageType<Base>();
}
// iParser interface
public:
QH::ParserResult parsePackage(const QSharedPointer<QH::PKG::AbstractData> &pkg,
2023-05-28 12:33:55 +02:00
const QH::Header &hdr,
QH::AbstractNodeInfo *sender) override {
2023-05-27 21:40:43 +02:00
if (pkg->cmd() == Base::command()) {
data = pkg;
2023-05-28 12:33:55 +02:00
if (!data.dynamicCast<MultiVersionPkg>()->responce) {
data.dynamicCast<MultiVersionPkg>()->responce = true;
if (!sendData(pkg.data(), sender, &hdr)) {
return QH::ParserResult::Error;
}
}
2023-05-27 21:40:43 +02:00
return QH::ParserResult::Processed;
}
return QH::ParserResult::NotProcessed;
};
int version() const override {return 0;};
QString parserId() const override {return "BigDataTestParser";};
QSharedPointer<QH::PKG::AbstractData> getData() const{
return data;
};
2023-05-28 12:33:55 +02:00
void dropData() {
data = nullptr;
};
2023-05-27 21:40:43 +02:00
private:
QSharedPointer<QH::PKG::AbstractData> data = nullptr;
};
template <class Base>
class TestingClient: public QH::AbstractNode {
// AbstractNode interface
public:
TestingClient() {
_parser = addApiParser<TestAPI<Base>>();
}
2023-05-25 23:24:48 +02:00
2023-05-27 21:40:43 +02:00
bool sendRequest(const Base& data, int port) {
return sendData(&data, QH::HostAddress(TEST_LOCAL_HOST, port));
}
NodeType nodeType() const override {
return NodeType::Node;
};
const QSharedPointer<QH::iParser>& parser() const {
return _parser;
}
private:
QSharedPointer<QH::iParser> _parser;
2023-05-25 23:24:48 +02:00
};
MultiVersionTest::MultiVersionTest() {
2023-05-28 12:33:55 +02:00
_nodeV1 = new TestingClient<MultiVersionPkg1>;
_nodeV2 = new TestingClient<MultiVersionPkg2>;
_nodeOld = new TestingClient<SingleVersionPkg>;
}
MultiVersionTest::~MultiVersionTest() {
_nodeV1->softDelete();
_nodeV2->softDelete();
_nodeOld->softDelete();
2023-05-25 23:24:48 +02:00
}
void MultiVersionTest::test() {
2023-05-28 12:33:55 +02:00
QVERIFY(_nodeV1->run(TEST_LOCAL_HOST, LOCAL_TEST_PORT));
2023-05-25 23:24:48 +02:00
2023-05-28 12:33:55 +02:00
QVERIFY(connectFunc(_nodeV2, TEST_LOCAL_HOST, LOCAL_TEST_PORT));
QVERIFY(connectFunc(_nodeOld, TEST_LOCAL_HOST, LOCAL_TEST_PORT));
2023-05-27 21:40:43 +02:00
2023-05-28 12:33:55 +02:00
testMultipacakges();
testSinglePackages();
}
2023-05-27 21:40:43 +02:00
2023-05-28 12:33:55 +02:00
void MultiVersionTest::testMultipacakges() {
auto nodeWithV1 = dynamic_cast<TestingClient<MultiVersionPkg1>*>(_nodeV1);
auto nodeWithV2 = dynamic_cast<TestingClient<MultiVersionPkg2>*>(_nodeV2);
// clean old data;
nodeWithV1->parser().staticCast<TestAPI<MultiVersionPkg1>>()->dropData();
nodeWithV2->parser().staticCast<TestAPI<MultiVersionPkg2>>()->dropData();
2023-05-27 21:40:43 +02:00
// from new to old
{
2023-05-28 12:33:55 +02:00
// initialize test values.
2023-05-27 21:40:43 +02:00
MultiVersionPkg2 pkg;
pkg.v1 = 10;
pkg.v2 = 20;
2023-05-28 12:33:55 +02:00
// send test values into dist node
QVERIFY(nodeWithV2->sendRequest(pkg, LOCAL_TEST_PORT));
2023-05-27 21:40:43 +02:00
// should use the maximum available serialization. it is 1
QVERIFY(pkg.lastSerializedto == 1);
2023-05-28 12:33:55 +02:00
// wait for receive packge on distanation node
QVERIFY(wait([&nodeWithV1]() {
if (auto data = nodeWithV1->parser().staticCast<TestAPI<MultiVersionPkg1>>()->
getData().staticCast<MultiVersionPkg1>()) {
return data->lastSerializedFrom == 1;
}
return false;
2023-05-27 21:40:43 +02:00
}, WAIT_RESPOCE_TIME));
2023-05-28 12:33:55 +02:00
// wait for package on sender node.
QVERIFY(wait([&nodeWithV2]() {
if (auto data = nodeWithV2->parser().staticCast<TestAPI<MultiVersionPkg1>>()->
getData().staticCast<MultiVersionPkg1>()) {
return data->responce == true;
}
return false;
}, WAIT_RESPOCE_TIME));
// chec data all data should not be changed.
auto data = nodeWithV2->parser().staticCast<TestAPI<MultiVersionPkg2>>()->
getData().staticCast<MultiVersionPkg2>();
2023-05-27 21:40:43 +02:00
QVERIFY(data->v1 == pkg.v1);
QVERIFY(data->v2 == pkg.v2);
}
2023-05-28 12:33:55 +02:00
}
void MultiVersionTest::testSinglePackages() {
auto nodeWithSingle = dynamic_cast<TestingClient<SingleVersionPkg>*>(_nodeOld);
auto nodeWithV1 = dynamic_cast<TestingClient<MultiVersionPkg1>*>(_nodeV1);
2023-05-27 21:40:43 +02:00
2023-05-28 12:33:55 +02:00
// clean old data;
nodeWithSingle->parser().staticCast<TestAPI<SingleVersionPkg>>()->dropData();
nodeWithV1->parser().staticCast<TestAPI<MultiVersionPkg1>>()->dropData();
// from single package to new
2023-05-27 21:40:43 +02:00
{
2023-05-28 12:33:55 +02:00
// initialize test values.
SingleVersionPkg pkg;
2023-05-27 21:40:43 +02:00
pkg.v1 = 10;
pkg.v2 = 20;
2023-05-28 12:33:55 +02:00
// send test values into dist node
QVERIFY(nodeWithSingle->sendRequest(pkg, LOCAL_TEST_PORT));
2023-05-27 21:40:43 +02:00
2023-05-28 12:33:55 +02:00
// should use the maximum available serialization. it is 0
QVERIFY(pkg.lastSerializedto == 0);
// wait for receive packge on distanation node
QVERIFY(wait([&nodeWithV1]() {
if (auto data = nodeWithV1->parser().staticCast<TestAPI<MultiVersionPkg1>>()->
getData().staticCast<MultiVersionPkg1>()) {
return data->lastSerializedFrom == 0;
}
return false;
2023-05-27 21:40:43 +02:00
}, WAIT_RESPOCE_TIME));
2023-05-28 12:33:55 +02:00
// wait for package on sender node.
QVERIFY(wait([&nodeWithSingle]() {
if (auto data = nodeWithSingle->parser().staticCast<TestAPI<SingleVersionPkg>>()->
getData().staticCast<SingleVersionPkg>()) {
return data->responce == true;
}
return false;
}, WAIT_RESPOCE_TIME));
// chec data all data should not be changed.
auto data = nodeWithSingle->parser().staticCast<TestAPI<SingleVersionPkg>>()->
getData().staticCast<SingleVersionPkg>();
2023-05-27 21:40:43 +02:00
QVERIFY(data->v1 == pkg.v1);
2023-05-28 12:33:55 +02:00
// v2 is not supported on the v0 parser
QVERIFY(data->v2 == 0);
2023-05-27 21:40:43 +02:00
}
2023-05-25 23:24:48 +02:00
}