/** * @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 #include #include #include #include #include #include #include #include #include #include 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 &streams) { m_streamList = streams; } void onQueryTimelineResponse(const AvaTimeline &timeline) { m_timeline = timeline; } void onGetElokaListResponse(const QVector &elokaSignals) { m_elokaList = elokaSignals; } void onQueryElokaResponse(const QVector &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 m_streamInfo; QVector m_streamState; boost::optional> m_streamList; boost::optional m_timeline; boost::optional> m_elokaList; boost::optional> m_queryElokaResponse; QVector m_scriptInfo; QVector 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 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 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> queryElokaResponse; auto doneCallback = [&queryElokaResponse] (QVector &&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 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"