From 45c2eba650bb7f9eba43b4f7fcdd3bbccc03747a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 17 Dec 2014 20:26:42 +0000 Subject: Add mock tuner with sample SI data Add test suite for running maintenance jobs --- p2pvr/Jamfile.jam | 6 +- p2pvr/daemon/Jamfile.jam | 3 + p2pvr/daemon/maintenance.cpp | 4 +- p2pvr/daemon/si.cpp | 2 +- p2pvr/daemon/unittests/Jamfile.jam | 22 +++++ p2pvr/daemon/unittests/datasources/postgres.xml | 4 + p2pvr/daemon/unittests/testMaint.cpp | 106 +++++++++++++++++++++ p2pvr/devices/Jamfile.jam | 39 +++++++- p2pvr/devices/mockTuner.cpp | 121 ++++++++++++++++++++++++ p2pvr/devices/mockTuner.h | 32 +++++++ p2pvr/devices/sampleSiData/events.datxz | Bin 0 -> 1112856 bytes p2pvr/devices/sampleSiData/network.datxz | Bin 0 -> 1244 bytes p2pvr/devices/sampleSiData/services.datxz | Bin 0 -> 2392 bytes p2pvr/embed.m4 | 19 ++++ p2pvr/embedSql.m4 | 19 ---- 15 files changed, 354 insertions(+), 23 deletions(-) create mode 100644 p2pvr/daemon/unittests/datasources/postgres.xml create mode 100644 p2pvr/daemon/unittests/testMaint.cpp create mode 100644 p2pvr/devices/mockTuner.cpp create mode 100644 p2pvr/devices/mockTuner.h create mode 100644 p2pvr/devices/sampleSiData/events.datxz create mode 100644 p2pvr/devices/sampleSiData/network.datxz create mode 100644 p2pvr/devices/sampleSiData/services.datxz create mode 100644 p2pvr/embed.m4 delete mode 100644 p2pvr/embedSql.m4 diff --git a/p2pvr/Jamfile.jam b/p2pvr/Jamfile.jam index 7b4df03..b86cf37 100644 --- a/p2pvr/Jamfile.jam +++ b/p2pvr/Jamfile.jam @@ -17,6 +17,10 @@ alias p2cgi : glibmm : : : /usr/include/project2/cgi "-lp2cgicommon" ; +alias p2xml : glibmm : : : + /usr/include/project2/xml + "-lp2xml" +; alias p2sql : glibmm : : : /usr/include/project2/sql "-lp2sql" @@ -59,7 +63,7 @@ path-constant root : . ; actions sql.embed.asm { - m4 -DNAME="sql_$(2:B)" -DPATH="$(2)" "$(root)/embedSql.m4" > "$(1)" + m4 -DNAME="sql_$(2:B)" -DPATH="$(2)" "$(root)/embed.m4" > "$(1)" } IMPORT $(__name__) : sql.embed.asm : : sql.embed.asm ; diff --git a/p2pvr/daemon/Jamfile.jam b/p2pvr/daemon/Jamfile.jam index 43465df..ac3ed58 100644 --- a/p2pvr/daemon/Jamfile.jam +++ b/p2pvr/daemon/Jamfile.jam @@ -21,6 +21,9 @@ lib p2pvrdaemon : ../devices//p2pvrdevices ../daemonbase//p2pvrdaemonbase ../../libtmdb//tmdb + : : + . + ../ice//p2pvrice ; unit-test testEmbedding : diff --git a/p2pvr/daemon/maintenance.cpp b/p2pvr/daemon/maintenance.cpp index 8e204f7..05c4094 100644 --- a/p2pvr/daemon/maintenance.cpp +++ b/p2pvr/daemon/maintenance.cpp @@ -29,7 +29,9 @@ Maintenance::Maintenance(Ice::ObjectAdapterPtr a, IceUtil::TimerPtr t) : lastUpdateEvents(0), updateRunning(false) { - timer->scheduleRepeated(clientCheck, IceUtil::Time::seconds(5 * 60)); + if (timer) { + timer->scheduleRepeated(clientCheck, IceUtil::Time::seconds(5 * 60)); + } #ifdef NDEBUG ScheduledUpdate(); #endif diff --git a/p2pvr/daemon/si.cpp b/p2pvr/daemon/si.cpp index 3259888..571c6b0 100644 --- a/p2pvr/daemon/si.cpp +++ b/p2pvr/daemon/si.cpp @@ -65,7 +65,7 @@ SI::GetDeliveryForSi(const Ice::Current&) P2PVR::Deliveries rtn; SqlContainerCreator cct(rtn); cct.populate(Select(SI_serviceNextUsed).second); - return rtn.front(); + return rtn.empty() ? DVBSI::DeliveryPtr() : rtn.front(); } DVBSI::DeliveryPtr diff --git a/p2pvr/daemon/unittests/Jamfile.jam b/p2pvr/daemon/unittests/Jamfile.jam index 794248a..d0d704d 100644 --- a/p2pvr/daemon/unittests/Jamfile.jam +++ b/p2pvr/daemon/unittests/Jamfile.jam @@ -2,6 +2,8 @@ import testing ; lib boost_system ; lib boost_filesystem ; +lib IceUtil ; +lib Ice ; path-constant me : . ; @@ -21,4 +23,24 @@ unit-test testp2ice : ROOT=\"$(me)\" ; +unit-test testMaint : + testMaint.cpp + : + BOOST_TEST_DYN_LINK + ../..//p2common + ../..//p2basics + ../..//p2lib + ../..//p2ice + ../..//p2xml + ../..//p2ut + ..//p2pvrdaemon + ../../devices//p2pvrMockTuner + IceUtil + Ice + boost_system + boost_filesystem + ../..//boost_utf + ROOT=\"$(me)\" + ; + diff --git a/p2pvr/daemon/unittests/datasources/postgres.xml b/p2pvr/daemon/unittests/datasources/postgres.xml new file mode 100644 index 0000000..c538a8c --- /dev/null +++ b/p2pvr/daemon/unittests/datasources/postgres.xml @@ -0,0 +1,4 @@ + + + + diff --git a/p2pvr/daemon/unittests/testMaint.cpp b/p2pvr/daemon/unittests/testMaint.cpp new file mode 100644 index 0000000..139284c --- /dev/null +++ b/p2pvr/daemon/unittests/testMaint.cpp @@ -0,0 +1,106 @@ +#define BOOST_TEST_MODULE Maintenance +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define XSTR(s) STR(s) +#define STR(s) #s +const auto bindir = boost::filesystem::canonical("/proc/self/exe").parent_path(); +const auto componentdir = bindir.parent_path() / "component"; +const boost::filesystem::path root(XSTR(ROOT)); + +class MockDevices : public P2PVR::Devices { + public: + P2PVR::TunerPrx GetTunerSpecific(const DVBSI::DeliveryPtr&, const Ice::Current & ice) override + { + return P2PVR::PrivateTunerPrx::checkedCast(ice.adapter->addWithUUID(new MockTuner())); + } + P2PVR::TunerPrx GetTunerAny(Ice::Short, const DVBSI::DeliveryPtr&, const Ice::Current & ice) override + { + return P2PVR::PrivateTunerPrx::checkedCast(ice.adapter->addWithUUID(new MockTuner())); + } + P2PVR::PrivateTunerPrx GetPrivateTuner(Ice::Short, const Ice::Current & ice) override + { + return P2PVR::PrivateTunerPrx::checkedCast(ice.adapter->addWithUUID(new MockTuner())); + } + void ReleaseTuner(const P2PVR::TunerPrx & tuner, const Ice::Current & ice) override + { + ice.adapter->remove(tuner->ice_getIdentity()); + } + Ice::Int TunerCount(const Ice::Current&) override + { + return 1; + } +}; + +class MockScheduler : public P2PVR::Schedules { + public: + void DoReschedule(const ::Ice::Current&) { } + void DeleteSchedule(Ice::Int, const Ice::Current&) { } + P2PVR::SchedulePtr GetSchedule(::Ice::Int, const ::Ice::Current&) { return P2PVR::SchedulePtr(); } + P2PVR::ScheduleList GetSchedules(const ::Ice::Current&) { return P2PVR::ScheduleList(); } + P2PVR::ScheduledToRecordList GetScheduledToRecord(const ::Ice::Current&) { return P2PVR::ScheduledToRecordList(); } + Ice::Int UpdateSchedule(const ::P2PVR::SchedulePtr&, const ::Ice::Current&) { return 0; } +}; + +static +Ice::CommunicatorPtr +standardConfig() +{ + int paramCount = 0; + Ice::CommunicatorPtr ic = Ice::initialize(paramCount, NULL); + auto adapter = ic->createObjectAdapterWithEndpoints("Adp", "tcp -p 12000"); + TestOptionsSource::LoadTestOptions({ + { "common.datasourceRoot", (root / "datasources").string() }, + }); + adapter->add(new MockDevices(), ic->stringToIdentity("GlobalDevices")); + adapter->add(new MockScheduler(), ic->stringToIdentity("Schedules")); + adapter->add(new SI(), ic->stringToIdentity("SI")); + adapter->add(new Maintenance(adapter, NULL), ic->stringToIdentity("Maintenance")); + adapter->activate(); + return ic; +} + +BOOST_AUTO_TEST_CASE( update_network ) +{ + auto ic = standardConfig(); + ScopeObject _([&ic]{ ic->destroy(); }); + + auto m = P2PVR::MaintenancePrx::checkedCast(ic->stringToProxy("Maintenance")); + BOOST_REQUIRE(m); + m->ice_ping(); + + m->UpdateNetwork(FE_OFDM); +} + +BOOST_AUTO_TEST_CASE( update_services ) +{ + auto ic = standardConfig(); + ScopeObject _([&ic]{ ic->destroy(); }); + + auto m = P2PVR::MaintenancePrx::checkedCast(ic->stringToProxy("Maintenance")); + BOOST_REQUIRE(m); + m->ice_ping(); + + m->UpdateServices(FE_OFDM); +} + +BOOST_AUTO_TEST_CASE( update_events ) +{ + auto ic = standardConfig(); + ScopeObject _([&ic]{ ic->destroy(); }); + + auto m = P2PVR::MaintenancePrx::checkedCast(ic->stringToProxy("Maintenance")); + BOOST_REQUIRE(m); + m->ice_ping(); + + m->UpdateEvents(FE_OFDM); +} + diff --git a/p2pvr/devices/Jamfile.jam b/p2pvr/devices/Jamfile.jam index a3452a4..365fbbd 100644 --- a/p2pvr/devices/Jamfile.jam +++ b/p2pvr/devices/Jamfile.jam @@ -1,5 +1,9 @@ +import type ; +import generators ; + lib boost_system ; lib boost_filesystem ; +lib lzma ; cpp-pch pch : pch.hpp : boost_system @@ -10,7 +14,7 @@ cpp-pch pch : pch.hpp : lib p2pvrdevices : pch - [ glob-tree *.cpp ] + [ glob-tree *.cpp : mockTuner.cpp ] : boost_system boost_filesystem @@ -25,3 +29,36 @@ lib p2pvrdevices : boost_system . ; + +type.register DATXZ : datxz ; + +generators.register-standard datxz.embed.asm : DATXZ : ASM ; + +actions datxz.embed.asm +{ + m4 -DNAME="$(2:B)" -DPATH="$(2)" "$(root)/embed.m4" > "$(1)" +} + +IMPORT $(__name__) : datxz.embed.asm : : datxz.embed.asm ; + + +lib p2pvrMockTuner : + pch + mockTuner.cpp + [ glob-tree *.datxz ] + : + lzma + boost_system + boost_filesystem + ../dvb//p2pvrdvb + ../ice//p2pvrice + ../lib//p2pvrlib + ..//p2common + ../ice//p2pvrice + : : + boost_filesystem + ../ice//p2pvrice + boost_system + . + ; + diff --git a/p2pvr/devices/mockTuner.cpp b/p2pvr/devices/mockTuner.cpp new file mode 100644 index 0000000..10e77b7 --- /dev/null +++ b/p2pvr/devices/mockTuner.cpp @@ -0,0 +1,121 @@ +#include "mockTuner.h" +#include +#include +#include +#include +#include + +#define ResourceFile(resource) \ +extern "C" { \ + extern char resource##_start, resource##_end;\ + extern unsigned int resource##_len; \ +} \ +static const Ice::ByteSeq resource(&resource##_start, &resource##_end); + +#define LZMA_ASSERT(ret_xz) \ + if (ret_xz != LZMA_OK) { \ + Logger()->messagebf(LOG_ERR, "%s: LZMA error (%d)", __PRETTY_FUNCTION__, ret_xz); \ + throw P2PVR::DeviceError("LZMA", "Decompressor error", ret_xz); \ + } + +ResourceFile(network); +ResourceFile(services); +ResourceFile(events); + +void MockTuner::TuneTo(const DVBSI::DeliveryPtr &, const Ice::Current&) +{ +} + +int MockTuner::GetStatus(const Ice::Current&) +{ + return 0; +} + +void MockTuner::DecompressAndSendPackets(const Ice::ByteSeq & dataxz, const P2PVR::RawDataClientPrx & client, const Ice::Current & ice) const +{ + Logger()->messagebf(LOG_DEBUG, "%s: setup", __PRETTY_FUNCTION__); + lzma_stream strm = LZMA_STREAM_INIT; + const uint32_t flags = LZMA_TELL_UNSUPPORTED_CHECK | LZMA_CONCATENATED; + const uint64_t memory_limit = UINT64_MAX; + LZMA_ASSERT(lzma_stream_decoder(&strm, memory_limit, flags)); + strm.next_in = &dataxz.front(); + strm.avail_in = dataxz.size(); + uint8_t buf[BUFSIZ]; + + Logger()->messagebf(LOG_DEBUG, "%s: decompress", __PRETTY_FUNCTION__); + Ice::ByteSeq data; + data.reserve(dataxz.size() * 20); + do { + strm.next_out = buf; + strm.avail_out = BUFSIZ; + LZMA_ASSERT(lzma_code(&strm, LZMA_RUN)); + for (auto idx = 0u; idx < BUFSIZ - strm.avail_out; idx += 1) { + data.push_back(buf[idx]); + } + } while (strm.avail_out == 0); + data.shrink_to_fit(); + + Logger()->messagebf(LOG_DEBUG, "%s: deserialize", __PRETTY_FUNCTION__); + std::list packets; + auto istrm = Ice::createInputStream(ice.adapter->getCommunicator(), data); + istrm->read(packets); + + Logger()->messagebf(LOG_DEBUG, "%s: send", __PRETTY_FUNCTION__); + BOOST_FOREACH(const auto & packet, packets) { + client->NewData(packet); + } + + Logger()->messagebf(LOG_DEBUG, "%s: complete", __PRETTY_FUNCTION__); +} + +void MockTuner::ScanAndSendNetworkInformation(const P2PVR::RawDataClientPrx & client, const Ice::Current & ice) +{ + DecompressAndSendPackets(network, client, ice); +} + +void MockTuner::SendNetworkInformation(const P2PVR::RawDataClientPrx & client, const Ice::Current & ice) +{ + DecompressAndSendPackets(network, client, ice); +} + +void MockTuner::SendBouquetAssociations(const P2PVR::RawDataClientPrx &, const Ice::Current&) +{ +} + +void MockTuner::SendServiceDescriptions(const P2PVR::RawDataClientPrx & client, const Ice::Current & ice) +{ + DecompressAndSendPackets(services, client, ice); +} + +void MockTuner::SendProgramMap(Ice::Int, const P2PVR::RawDataClientPrx &, const Ice::Current&) +{ +} + +void MockTuner::SendProgramAssociationTable(const P2PVR::RawDataClientPrx &, const Ice::Current&) +{ +} + +void MockTuner::SendEventInformation(const P2PVR::RawDataClientPrx & client, const Ice::Current & ice) +{ + DecompressAndSendPackets(events, client, ice); +} + +int MockTuner::StartSendingTS(const P2PVR::PacketIds &, const P2PVR::RawDataClientPrx &, const Ice::Current &) +{ + return 0; +} + +int MockTuner::StartSendingSection(Ice::Int, const P2PVR::RawDataClientPrx &, const Ice::Current &) +{ + return 0; +} + +void MockTuner::StopSending(int, const Ice::Current &) +{ +} + +Ice::Long MockTuner::GetLastUsedTime(const Ice::Current&) +{ + return time(NULL); +} + diff --git a/p2pvr/devices/mockTuner.h b/p2pvr/devices/mockTuner.h new file mode 100644 index 0000000..220b535 --- /dev/null +++ b/p2pvr/devices/mockTuner.h @@ -0,0 +1,32 @@ +#ifndef P2PVR_MOCKTUNER_H +#define P2PVR_MOCKTUNER_H + +#include +#include + +class MockTuner : public P2PVR::PrivateTuner { + public: + + void TuneTo(const DVBSI::DeliveryPtr &, const Ice::Current&); + int GetStatus(const Ice::Current&); + + void ScanAndSendNetworkInformation(const P2PVR::RawDataClientPrx & client, const Ice::Current&); + void SendNetworkInformation(const P2PVR::RawDataClientPrx & client, const Ice::Current&); + void SendBouquetAssociations(const P2PVR::RawDataClientPrx & client, const Ice::Current&); + void SendServiceDescriptions(const P2PVR::RawDataClientPrx & client, const Ice::Current&); + void SendProgramMap(Ice::Int pid, const P2PVR::RawDataClientPrx & client, const Ice::Current&); + void SendProgramAssociationTable(const P2PVR::RawDataClientPrx & client, const Ice::Current&); + void SendEventInformation(const P2PVR::RawDataClientPrx & client, const Ice::Current&); + + int StartSendingTS(const P2PVR::PacketIds & pids, const P2PVR::RawDataClientPrx & client, const Ice::Current &); + int StartSendingSection(Ice::Int pid, const P2PVR::RawDataClientPrx & client, const Ice::Current &); + void StopSending(int handle, const Ice::Current &); + + Ice::Long GetLastUsedTime(const Ice::Current&); + + protected: + void DecompressAndSendPackets(const Ice::ByteSeq &, const P2PVR::RawDataClientPrx &, const Ice::Current&) const; +}; + +#endif + diff --git a/p2pvr/devices/sampleSiData/events.datxz b/p2pvr/devices/sampleSiData/events.datxz new file mode 100644 index 0000000..a84d777 Binary files /dev/null and b/p2pvr/devices/sampleSiData/events.datxz differ diff --git a/p2pvr/devices/sampleSiData/network.datxz b/p2pvr/devices/sampleSiData/network.datxz new file mode 100644 index 0000000..f2e74cd Binary files /dev/null and b/p2pvr/devices/sampleSiData/network.datxz differ diff --git a/p2pvr/devices/sampleSiData/services.datxz b/p2pvr/devices/sampleSiData/services.datxz new file mode 100644 index 0000000..0961e92 Binary files /dev/null and b/p2pvr/devices/sampleSiData/services.datxz differ diff --git a/p2pvr/embed.m4 b/p2pvr/embed.m4 new file mode 100644 index 0000000..d94ee7c --- /dev/null +++ b/p2pvr/embed.m4 @@ -0,0 +1,19 @@ +define(`start', NAME`_start') +define(`end', NAME`_end') +define(`len', NAME`_len') +.section .rodata + .global start + .type start, @object +start: + .incbin "PATH" + + .global end + .type end, @object +end: + .byte 0 + + .global len + .type len, @object +len: + .int end - start + diff --git a/p2pvr/embedSql.m4 b/p2pvr/embedSql.m4 deleted file mode 100644 index d94ee7c..0000000 --- a/p2pvr/embedSql.m4 +++ /dev/null @@ -1,19 +0,0 @@ -define(`start', NAME`_start') -define(`end', NAME`_end') -define(`len', NAME`_len') -.section .rodata - .global start - .type start, @object -start: - .incbin "PATH" - - .global end - .type end, @object -end: - .byte 0 - - .global len - .type len, @object -len: - .int end - start - -- cgit v1.2.3