265 lines
8.5 KiB
C++
Executable File
265 lines
8.5 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* AvaControl
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Christian Fröbel, SLSE, 2017-06-29
|
|
*/
|
|
|
|
#include "ava_control_test.h"
|
|
#include "ava_test_server.h"
|
|
#include <AudioVideoManagement/ava_types.h>
|
|
#include <AudioVideoManagement/ava_comm.h>
|
|
#include <AudioVideoManagement/ava_control.h>
|
|
#include <AudioVideoManagement/stream_name_mapping.h>
|
|
#include <AudioVideoManagement/avs_dialog.h>
|
|
#include <AudioVideoManagement/list_response_collector.h>
|
|
#include <QVector>
|
|
#include <QtGlobal>
|
|
#include <QDateTime>
|
|
#include <QSignalSpy>
|
|
#include <boost/optional.hpp>
|
|
|
|
using namespace AudioVideoManagement;
|
|
|
|
AvaControlTest::AvaControlTest() = default;
|
|
AvaControlTest::~AvaControlTest() = default;
|
|
|
|
class AvaControlTest::SignalSpy : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
SignalSpy(AvaControl *signalSource)
|
|
{
|
|
Q_ASSERT(signalSource);
|
|
connect(signalSource->comm(), &IAvaComm::connected, this, &SignalSpy::onConnected);
|
|
connect(signalSource, &AvaControl::chooseStreamResponse, this, &SignalSpy::onChooseStreamResponse);
|
|
connect(signalSource, &AvaControl::getStreamListResponse, this, &SignalSpy::onGetStreamListResponse);
|
|
connect(signalSource, &AvaControl::queryTimelineResponse, this, &SignalSpy::onQueryTimelineResponse);
|
|
connect(signalSource, &AvaControl::getElokaListResponse, this, &SignalSpy::onGetElokaListResponse);
|
|
connect(signalSource, &AvaControl::queryElokaResponse, this, &SignalSpy::onQueryElokaResponse);
|
|
connect(signalSource, &AvaControl::setScriptResponse, this, &SignalSpy::onSetScriptResponse);
|
|
}
|
|
|
|
void reset()
|
|
{
|
|
m_connected = false;
|
|
m_streamInfo.clear();
|
|
m_streamState.clear();
|
|
m_streamList.reset();
|
|
m_timeline.reset();
|
|
m_elokaList.reset();
|
|
m_queryElokaResponse.reset();
|
|
m_scriptInfo.clear();
|
|
m_scriptState.clear();
|
|
}
|
|
|
|
public slots:
|
|
void onConnected() { m_connected = true; }
|
|
void onChooseStreamResponse(const AvaStreamInfo &streamInfo, AvaStreamState streamState)
|
|
{
|
|
m_streamInfo.append(streamInfo);
|
|
m_streamState.append(streamState);
|
|
}
|
|
|
|
void onGetStreamListResponse(const QVector<AvaStream> &streams) { m_streamList = streams; }
|
|
void onQueryTimelineResponse(const AvaTimeline &timeline) { m_timeline = timeline; }
|
|
void onGetElokaListResponse(const QVector<QString> &elokaSignals) { m_elokaList = elokaSignals; }
|
|
void onQueryElokaResponse(const QVector<AvaEloka> &eloka) { m_queryElokaResponse = eloka; }
|
|
|
|
void onSetScriptResponse(const AvaStreamInfo &scriptInfo, AvaStreamState scriptState)
|
|
{
|
|
m_scriptInfo.append(scriptInfo);
|
|
m_scriptState.append(scriptState);
|
|
}
|
|
|
|
public:
|
|
bool m_connected{false};
|
|
QVector<AvaStreamInfo> m_streamInfo;
|
|
QVector<AvaStreamState> m_streamState;
|
|
boost::optional<QVector<AvaStream>> m_streamList;
|
|
boost::optional<AvaTimeline> m_timeline;
|
|
boost::optional<QVector<QString>> m_elokaList;
|
|
boost::optional<QVector<AvaEloka>> m_queryElokaResponse;
|
|
QVector<AvaStreamInfo> m_scriptInfo;
|
|
QVector<AvaStreamState> m_scriptState;
|
|
};
|
|
|
|
namespace
|
|
{
|
|
|
|
const QString &DIALOG()
|
|
{
|
|
return AvsDialog::VIDEO_1;
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
void AvaControlTest::initTestCase()
|
|
{
|
|
m_fakeAvaServer.reset(new AvaTestServer);
|
|
}
|
|
|
|
void AvaControlTest::cleanupTestCase()
|
|
{
|
|
m_fakeAvaServer.reset();
|
|
}
|
|
|
|
void AvaControlTest::init()
|
|
{
|
|
m_streamNameMapping.reset(new StreamNameMapping);
|
|
m_avaComm.reset(new AvaComm(QStringLiteral("localhost"), 6370));
|
|
m_avaCtrl.reset(new AvaControl(m_avaComm.get(), m_streamNameMapping.get(), std::chrono::seconds(3)));
|
|
m_spy.reset(new SignalSpy(m_avaCtrl.get()));
|
|
m_avaComm->start();
|
|
}
|
|
|
|
void AvaControlTest::cleanup()
|
|
{
|
|
m_spy.reset();
|
|
m_avaCtrl.reset();
|
|
m_avaComm.reset();
|
|
m_streamNameMapping.reset();
|
|
}
|
|
|
|
void AvaControlTest::testChooseStream()
|
|
{
|
|
QTRY_VERIFY(m_spy->m_connected);
|
|
|
|
m_avaCtrl->chooseStream(DIALOG(), QStringLiteral("Video 52-1(S)"));
|
|
QTRY_VERIFY(m_spy->m_streamInfo.size() == 1 && m_spy->m_streamState.size() == 1);
|
|
QCOMPARE(m_spy->m_streamState.front(), AvaStreamState::Stop);
|
|
QCOMPARE(m_spy->m_streamInfo.front().start, AvaTimePoint(AvaDuration{125551541486}));
|
|
QCOMPARE(m_spy->m_streamInfo.front().end, AvaTimePoint(AvaDuration{125563407789}));
|
|
QCOMPARE(m_spy->m_streamInfo.front().duration, AvaDuration{11866303});
|
|
}
|
|
|
|
/**
|
|
* A use case where the user quickly changes the selected stream
|
|
* before the response of the first chooseStream was received.
|
|
*/
|
|
void AvaControlTest::testChooseStreamCascade()
|
|
{
|
|
QTRY_VERIFY(m_spy->m_connected);
|
|
|
|
m_avaCtrl->chooseStream(DIALOG(), QStringLiteral("Video 52-1(S)"));
|
|
m_avaCtrl->chooseStream(DIALOG(), QStringLiteral("Video 3"));
|
|
QTRY_VERIFY(m_spy->m_streamInfo.size() == 2 && m_spy->m_streamState.size() == 2);
|
|
}
|
|
|
|
/**
|
|
* Test issuing several commands in quick succession.
|
|
* Such a sequence could be sent during application startup.
|
|
* AvaControl is responsible for serializing the commands:
|
|
* the next command must not be sent before the prior command finished.
|
|
*/
|
|
void AvaControlTest::testInitialSequence()
|
|
{
|
|
QTRY_VERIFY(m_spy->m_connected);
|
|
|
|
const int EXERCISE = 42;
|
|
m_avaCtrl->switchContext(EXERCISE);
|
|
m_avaCtrl->setUserProfile(QStringLiteral("ctc"), QStringLiteral("en_US"), AvaAudioPrio(1), AvaGuiStyle::Light);
|
|
m_avaCtrl->getStreamList(AvaStreamType::Video, AvaStreamSource::Server);
|
|
m_avaCtrl->chooseStream(DIALOG(), QStringLiteral("Video 52-1(S)"));
|
|
QTRY_VERIFY(m_spy->m_streamInfo.size() == 1 && m_spy->m_streamState.size() == 1);
|
|
}
|
|
|
|
void AvaControlTest::testGetStreamList()
|
|
{
|
|
QTRY_VERIFY(m_spy->m_connected);
|
|
|
|
m_avaCtrl->getStreamList(AvaStreamType::Video, AvaStreamSource::Server);
|
|
QTRY_VERIFY(m_spy->m_streamList);
|
|
|
|
// sample check
|
|
const AvaStream &sample = m_spy->m_streamList->at(1);
|
|
AvaStream expected{AvaStreamType::Video, AvaStreamSource::Server, QStringLiteral("Videöäü 50-5"), QStringLiteral("Videöäü 50-5")};
|
|
QCOMPARE(sample.type, expected.type);
|
|
QCOMPARE(sample.source, expected.source);
|
|
QCOMPARE(sample.internalName, expected.internalName);
|
|
}
|
|
|
|
void AvaControlTest::testQueryTimeline()
|
|
{
|
|
QTRY_VERIFY(m_spy->m_connected);
|
|
|
|
m_avaCtrl->queryTimeline(QStringLiteral("Video 52-1(S)"));
|
|
QTRY_VERIFY(m_spy->m_timeline);
|
|
|
|
AvaTimeline expected
|
|
({
|
|
{ AvaTimePoint(AvaDuration{149941542177}), AvaTimePoint(AvaDuration{149941665903}) },
|
|
{ AvaTimePoint(AvaDuration{149941737377}), AvaTimePoint(AvaDuration{149941784206}) }
|
|
});
|
|
|
|
QCOMPARE(*m_spy->m_timeline, expected);
|
|
}
|
|
|
|
void AvaControlTest::testGetElokaList()
|
|
{
|
|
QTRY_VERIFY(m_spy->m_connected);
|
|
|
|
m_avaCtrl->getElokaList(QStringLiteral("TrSpFuKr12"));
|
|
QTRY_VERIFY(m_spy->m_elokaList);
|
|
|
|
QVector<QString> expected = {QStringLiteral("ELOKA 1"), QStringLiteral("Eloka 2")};
|
|
QCOMPARE(*m_spy->m_elokaList, expected);
|
|
}
|
|
|
|
void AvaControlTest::testQueryEloka()
|
|
{
|
|
QTRY_VERIFY(m_spy->m_connected);
|
|
|
|
m_avaCtrl->queryEloka(AvaQueryElokaMode::Poll);
|
|
QTRY_VERIFY(m_spy->m_queryElokaResponse);
|
|
|
|
QVector<AvaEloka> expected = { {QStringLiteral("Eloka1"), QStringLiteral("Funk1"), 1, AvaTimePoint(AvaDuration{125551541400})} };
|
|
QCOMPARE(*m_spy->m_queryElokaResponse, expected);
|
|
}
|
|
|
|
void AvaControlTest::testQueryElokaStop()
|
|
{
|
|
QTRY_VERIFY(m_spy->m_connected);
|
|
|
|
QSignalSpy commandQueueEmptySpy(m_avaCtrl.get(), &AvaControl::commandQueueEmpty);
|
|
|
|
m_avaCtrl->queryEloka(AvaQueryElokaMode::Stop);
|
|
|
|
commandQueueEmptySpy.wait();
|
|
QVERIFY(!m_spy->m_queryElokaResponse);
|
|
}
|
|
|
|
/**
|
|
* When queryEloka is used in Push-Mode, we must handle asynchronous QueryElokaLists.
|
|
* This is what we simulate here.
|
|
*/
|
|
void AvaControlTest::testAsyncQueryElokaList()
|
|
{
|
|
QTRY_VERIFY(m_spy->m_connected);
|
|
|
|
boost::optional<QVector<AvaEloka>> queryElokaResponse;
|
|
auto doneCallback = [&queryElokaResponse] (QVector<AvaEloka> &&response) { queryElokaResponse = std::move(response); };
|
|
QueryElokaListCollector collector(m_avaComm.get(), doneCallback);
|
|
|
|
collector.start();
|
|
// We use Poll here as we want to control how many responses the AvaTestServer sends.
|
|
// Also, the Push-mode is not implemented in AvaTestServer.
|
|
m_avaCtrl->queryEloka(AvaQueryElokaMode::Poll);
|
|
QTRY_VERIFY(queryElokaResponse);
|
|
|
|
QVector<AvaEloka> expected = { {QStringLiteral("Eloka1"), QStringLiteral("Funk1"), 1, AvaTimePoint(AvaDuration{125551541400})} };
|
|
QCOMPARE(*queryElokaResponse, expected);
|
|
|
|
queryElokaResponse.reset();
|
|
collector.start();
|
|
m_avaCtrl->queryEloka(AvaQueryElokaMode::Poll);
|
|
QTRY_VERIFY(queryElokaResponse);
|
|
QCOMPARE(*queryElokaResponse, expected);
|
|
}
|
|
|
|
#include "ava_control_test.moc"
|