summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2014-12-17 16:19:17 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2015-06-13 17:29:36 +0100
commit281bb0299f9c23b7ffaff9b1eeb311dc66621c40 (patch)
treec9446ad7a743bfdf17fb8f91d8ac898096a0341d
parentCentralize boost_utf declaration (diff)
downloadp2pvr-281bb0299f9c23b7ffaff9b1eeb311dc66621c40.tar.bz2
p2pvr-281bb0299f9c23b7ffaff9b1eeb311dc66621c40.tar.xz
p2pvr-281bb0299f9c23b7ffaff9b1eeb311dc66621c40.zip
Add tool for creating samples of SI data
-rw-r--r--p2pvr/dvb/Jamfile.jam2
-rw-r--r--p2pvr/dvb/unittests/.ycm_extra_conf.py119
-rw-r--r--p2pvr/dvb/unittests/Jamfile.jam23
-rw-r--r--p2pvr/dvb/unittests/createSamples.cpp126
4 files changed, 269 insertions, 1 deletions
diff --git a/p2pvr/dvb/Jamfile.jam b/p2pvr/dvb/Jamfile.jam
index c8f2fe0..2dbbbda 100644
--- a/p2pvr/dvb/Jamfile.jam
+++ b/p2pvr/dvb/Jamfile.jam
@@ -4,7 +4,7 @@ cpp-pch pch : pch.hpp :
lib p2pvrdvb :
pch
- [ glob-tree *.cpp ]
+ [ glob-tree *.cpp : unittests ]
:
<library>../ice//p2pvrice
<implicit-dependency>../ice//p2pvrice
diff --git a/p2pvr/dvb/unittests/.ycm_extra_conf.py b/p2pvr/dvb/unittests/.ycm_extra_conf.py
new file mode 100644
index 0000000..06d416d
--- /dev/null
+++ b/p2pvr/dvb/unittests/.ycm_extra_conf.py
@@ -0,0 +1,119 @@
+import os
+import ycm_core
+
+flags = [
+'-Wall',
+'-Wextra',
+'-Werror',
+'-Wc++98-compat',
+'-Wno-long-long',
+'-Wno-variadic-macros',
+'-fexceptions',
+'-DNDEBUG',
+'-std=c++11',
+'-x',
+'c++',
+'-I',
+'.',
+'-isystem',
+'../../ice',
+'-isystem',
+'../../ice/bin/gcc-4.8.3/debug/slicer-yes',
+'-isystem',
+'../siParsers',
+'-isystem',
+'/usr/include',
+'-isystem',
+'/usr/include/glibmm-2.4',
+]
+
+# Set this to the absolute path to the folder (NOT the file!) containing the
+# compile_commands.json file to use that instead of 'flags'. See here for
+# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
+#
+# Most projects will NOT need to set this to anything; you can just change the
+# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
+compilation_database_folder = ''
+
+if os.path.exists( compilation_database_folder ):
+ database = ycm_core.CompilationDatabase( compilation_database_folder )
+else:
+ database = None
+
+SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
+
+def DirectoryOfThisScript():
+ return os.path.dirname( os.path.abspath( __file__ ) )
+
+
+def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
+ if not working_directory:
+ return list( flags )
+ new_flags = []
+ make_next_absolute = False
+ path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
+ for flag in flags:
+ new_flag = flag
+
+ if make_next_absolute:
+ make_next_absolute = False
+ if not flag.startswith( '/' ):
+ new_flag = os.path.join( working_directory, flag )
+
+ for path_flag in path_flags:
+ if flag == path_flag:
+ make_next_absolute = True
+ break
+
+ if flag.startswith( path_flag ):
+ path = flag[ len( path_flag ): ]
+ new_flag = path_flag + os.path.join( working_directory, path )
+ break
+
+ if new_flag:
+ new_flags.append( new_flag )
+ return new_flags
+
+
+def IsHeaderFile( filename ):
+ extension = os.path.splitext( filename )[ 1 ]
+ return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
+
+
+def GetCompilationInfoForFile( filename ):
+ # The compilation_commands.json file generated by CMake does not have entries
+ # for header files. So we do our best by asking the db for flags for a
+ # corresponding source file, if any. If one exists, the flags for that file
+ # should be good enough.
+ if IsHeaderFile( filename ):
+ basename = os.path.splitext( filename )[ 0 ]
+ for extension in SOURCE_EXTENSIONS:
+ replacement_file = basename + extension
+ if os.path.exists( replacement_file ):
+ compilation_info = database.GetCompilationInfoForFile(
+ replacement_file )
+ if compilation_info.compiler_flags_:
+ return compilation_info
+ return None
+ return database.GetCompilationInfoForFile( filename )
+
+
+def FlagsForFile( filename, **kwargs ):
+ if database:
+ # Bear in mind that compilation_info.compiler_flags_ does NOT return a
+ # python list, but a "list-like" StringVec object
+ compilation_info = GetCompilationInfoForFile( filename )
+ if not compilation_info:
+ return None
+
+ final_flags = MakeRelativePathsInFlagsAbsolute(
+ compilation_info.compiler_flags_,
+ compilation_info.compiler_working_dir_ )
+ else:
+ relative_to = DirectoryOfThisScript()
+ final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
+
+ return {
+ 'flags': final_flags,
+ 'do_cache': True
+ }
diff --git a/p2pvr/dvb/unittests/Jamfile.jam b/p2pvr/dvb/unittests/Jamfile.jam
new file mode 100644
index 0000000..6e8cfbf
--- /dev/null
+++ b/p2pvr/dvb/unittests/Jamfile.jam
@@ -0,0 +1,23 @@
+import testing ;
+
+lib boost_system ;
+lib boost_filesystem ;
+lib IceUtil ;
+lib Ice ;
+
+path-constant me : . ;
+
+exe createSamples :
+ createSamples.cpp
+ :
+ <define>BOOST_TEST_DYN_LINK
+ <library>..//p2pvrdvb
+ <library>../../ice//p2pvrice
+ <library>IceUtil
+ <library>Ice
+ <library>boost_system
+ <library>boost_filesystem
+ <library>../..//boost_utf
+ <define>ROOT=\"$(me)\"
+ ;
+
diff --git a/p2pvr/dvb/unittests/createSamples.cpp b/p2pvr/dvb/unittests/createSamples.cpp
new file mode 100644
index 0000000..affa123
--- /dev/null
+++ b/p2pvr/dvb/unittests/createSamples.cpp
@@ -0,0 +1,126 @@
+#define BOOST_TEST_MODULE CreateSamples
+#include <boost/test/unit_test.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <Ice/ObjectAdapter.h>
+#include <Ice/Service.h>
+#include <scopeObject.h>
+#include <linux/dvb/frontend.h>
+#include <siParsers/network.h>
+#include <siParsers/service.h>
+#include <siParsers/event.h>
+
+#define XSTR(s) STR(s)
+#define STR(s) #s
+const boost::filesystem::path root(XSTR(ROOT));
+
+template <class Parser>
+static
+boost::tuple<Ice::CommunicatorPtr, Ice::ObjectAdapterPtr, Parser *>
+standardConfig()
+{
+ Ice::StringSeq params {
+ "--Ice.ThreadPool.Client.Size=5",
+ "--Ice.ThreadPool.Client.SizeMax=10",
+ "--Ice.ThreadPool.Server.Size=5",
+ "--Ice.ThreadPool.Server.SizeMax=10"
+ };
+ Ice::CommunicatorPtr ic = Ice::initialize(params);
+ auto adapter = ic->createObjectAdapterWithEndpoints("Adp", "tcp -p 12000");
+ auto parser = new Parser();
+ adapter->add(parser, ic->stringToIdentity("parser"));
+ adapter->activate();
+ return { ic, adapter, parser };
+}
+
+template <class Base, class Object>
+class SiSampleCollector : public Base {
+ public:
+ SiSampleCollector() :
+ packets(0)
+ {
+ }
+
+ bool HandleTable(Object) override
+ {
+ return false;
+ }
+
+ bool NewData(const P2PVR::Data & bytes, const Ice::Current & ice) override
+ {
+ packets.push_back(bytes);
+ return SiTableParserBase::NewData(bytes, ice);
+ }
+
+ std::list<P2PVR::Data> packets;
+};
+
+template <class Base, class Object>
+static
+void
+CaptureAndSave(const boost::filesystem::path & fileName, const boost::function<void(P2PVR::TunerPrx, P2PVR::RawDataClientPrx)> & method)
+{
+ auto icp = standardConfig<SiSampleCollector<Base, Object>>();
+ auto ic = boost::get<0>(icp);
+ auto adap = boost::get<1>(icp);
+ auto p = boost::get<2>(icp);
+ ScopeObject _([&ic]{ ic->destroy(); });
+
+ auto devs = P2PVR::DevicesPrx::checkedCast(ic->stringToProxy("Devices:tcp -h defiant -p 10000"));
+ auto parser = P2PVR::RawDataClientPrx::checkedCast(adap->createProxy(ic->stringToIdentity("parser")));
+ BOOST_REQUIRE(devs);
+ devs->ice_ping();
+ BOOST_REQUIRE(parser);
+ parser->ice_ping();
+
+ DVBSI::TerrestrialDeliveryPtr transport = new DVBSI::TerrestrialDelivery {
+ 4170, 682000000, 0, true, true, true, 3, 0, 2, 1, 0, 1, true
+ };
+ BOOST_REQUIRE_EQUAL(transport->Frequency, 682000000);
+ BOOST_REQUIRE_EQUAL(transport->TransmissionMode, 1);
+
+ BOOST_CHECKPOINT("Acquire device");
+ P2PVR::TunerPrx tuner = devs->GetTunerAny(FE_OFDM, transport);
+ BOOST_REQUIRE(tuner);
+ tuner->ice_ping();
+
+ BOOST_CHECKPOINT("Get data");
+ method(tuner, parser);
+
+ BOOST_CHECKPOINT("Release device");
+ devs->ReleaseTuner(tuner);
+
+ BOOST_MESSAGE("Total packets: " << p->packets.size());
+ BOOST_REQUIRE(p->packets.size() > 0);
+
+ auto out = Ice::createOutputStream(ic);
+ out->write(p->packets);
+ Ice::ByteSeq buf;
+ out->finished(buf);
+ BOOST_MESSAGE(root);
+ auto outFile = fopen((root / fileName).string().c_str(), "w");
+ BOOST_REQUIRE(outFile);
+ BOOST_REQUIRE_EQUAL(1, fwrite(&buf.front(), buf.size(), 1, outFile));
+ BOOST_REQUIRE_EQUAL(0, fclose(outFile));
+}
+
+BOOST_AUTO_TEST_CASE( network_sample )
+{
+ CaptureAndSave<SiNetworkInformationParser, DVBSI::NetworkPtr>("network.dat",
+ [](P2PVR::TunerPrx t, P2PVR::RawDataClientPrx rdc) { t->SendNetworkInformation(rdc); });
+}
+
+BOOST_AUTO_TEST_CASE( services_sample )
+{
+ CaptureAndSave<SiServicesParser, DVBSI::TransportStreamPtr>("services.dat",
+ [](P2PVR::TunerPrx t, P2PVR::RawDataClientPrx rdc) { t->SendServiceDescriptions(rdc); });
+}
+
+BOOST_AUTO_TEST_CASE( events_sample )
+{
+ CaptureAndSave<SiEpgParser, DVBSI::EventPtr>("events.dat",
+ [](P2PVR::TunerPrx t, P2PVR::RawDataClientPrx rdc) { t->SendEventInformation(rdc); });
+}
+