From e04b96abc912184031dc93e8302069a0cae2b1a8 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Nov 2014 00:39:04 +0000 Subject: Renamed things to avoid conflicts of names --- project2/ice/Jamfile.jam | 2 +- project2/ice/tests/Jamfile.jam | 25 -------------------- project2/ice/tests/test.ice | 9 -------- project2/ice/tests/testClient.cpp | 34 ---------------------------- project2/ice/unittests/Jamfile.jam | 25 ++++++++++++++++++++ project2/ice/unittests/testClientCompile.cpp | 34 ++++++++++++++++++++++++++++ project2/ice/unittests/unittest.ice | 9 ++++++++ 7 files changed, 69 insertions(+), 69 deletions(-) delete mode 100644 project2/ice/tests/Jamfile.jam delete mode 100644 project2/ice/tests/test.ice delete mode 100644 project2/ice/tests/testClient.cpp create mode 100644 project2/ice/unittests/Jamfile.jam create mode 100644 project2/ice/unittests/testClientCompile.cpp create mode 100644 project2/ice/unittests/unittest.ice diff --git a/project2/ice/Jamfile.jam b/project2/ice/Jamfile.jam index 67e9eab..811b5d9 100644 --- a/project2/ice/Jamfile.jam +++ b/project2/ice/Jamfile.jam @@ -10,7 +10,7 @@ lib IceUtil ; lib pthread ; lib boost_filesystem ; -build-project tests ; +build-project unittests ; cpp-pch pch : pch.hpp : ../../libmisc diff --git a/project2/ice/tests/Jamfile.jam b/project2/ice/tests/Jamfile.jam deleted file mode 100644 index 976f34d..0000000 --- a/project2/ice/tests/Jamfile.jam +++ /dev/null @@ -1,25 +0,0 @@ -import testing ; - -lib test : - test.ice - : - ..//Ice - ..//IceUtil - ..//pthread - ; - -path-constant me : . ; - -unit-test testClient : - [ glob testClient.cpp ] - : - ROOT=\"$(me)\" - test.ice - ..//p2iceclient - ../../ut//p2ut - ../../basics//p2basics - ..//Ice - ..//IceUtil - ..//boost_filesystem - ; - diff --git a/project2/ice/tests/test.ice b/project2/ice/tests/test.ice deleted file mode 100644 index 3c18999..0000000 --- a/project2/ice/tests/test.ice +++ /dev/null @@ -1,9 +0,0 @@ -module test { - interface a - { - ["project2:task"] - void someTask(); - - }; -}; - diff --git a/project2/ice/tests/testClient.cpp b/project2/ice/tests/testClient.cpp deleted file mode 100644 index 7cd960f..0000000 --- a/project2/ice/tests/testClient.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#define BOOST_TEST_MODULE Client -#include -#include -#include "iceClient.h" -#include - -#define XSTR(s) STR(s) -#define STR(s) #s -const auto self = boost::filesystem::canonical("/proc/self/exe"); -const boost::filesystem::path iceroot(XSTR(ROOT)); - -BOOST_AUTO_TEST_CASE( compile_client_full ) -{ - const std::string tmpdir = "/tmp/ut/project2.slice/full"; - boost::filesystem::remove_all(tmpdir); - - TestOptionsSource::LoadTestOptions({ - { "ice.compile.tmpdir", tmpdir }, - { "ice.client.slice", (iceroot / "test.ice").string() } - }); -} - -BOOST_AUTO_TEST_CASE( compile_client_clientOnly ) -{ - const std::string tmpdir = "/tmp/ut/project2.slice/clientOnly"; - boost::filesystem::remove_all(tmpdir); - - TestOptionsSource::LoadTestOptions({ - { "library", (self.parent_path() / "libtest.so").string() }, - { "ice.compile.tmpdir", tmpdir }, - { "ice.client.sliceclient", (iceroot / "test.ice").string() } - }); -} - diff --git a/project2/ice/unittests/Jamfile.jam b/project2/ice/unittests/Jamfile.jam new file mode 100644 index 0000000..4c75205 --- /dev/null +++ b/project2/ice/unittests/Jamfile.jam @@ -0,0 +1,25 @@ +import testing ; + +lib unittest : + unittest.ice + : + ..//Ice + ..//IceUtil + ..//pthread + ; + +path-constant me : . ; + +unit-test testClientCompile : + [ glob testClientCompile.cpp ] + : + ROOT=\"$(me)\" + unittest.ice + ..//p2iceclient + ../../ut//p2ut + ../../basics//p2basics + ..//Ice + ..//IceUtil + ..//boost_filesystem + ; + diff --git a/project2/ice/unittests/testClientCompile.cpp b/project2/ice/unittests/testClientCompile.cpp new file mode 100644 index 0000000..4ae32d0 --- /dev/null +++ b/project2/ice/unittests/testClientCompile.cpp @@ -0,0 +1,34 @@ +#define BOOST_TEST_MODULE Client +#include +#include +#include "iceClient.h" +#include + +#define XSTR(s) STR(s) +#define STR(s) #s +const auto self = boost::filesystem::canonical("/proc/self/exe"); +const boost::filesystem::path iceroot(XSTR(ROOT)); + +BOOST_AUTO_TEST_CASE( compile_client_full ) +{ + const std::string tmpdir = "/tmp/ut/project2.slice/full"; + boost::filesystem::remove_all(tmpdir); + + TestOptionsSource::LoadTestOptions({ + { "ice.compile.tmpdir", tmpdir }, + { "ice.client.slice", (iceroot / "unittest.ice").string() } + }); +} + +BOOST_AUTO_TEST_CASE( compile_client_clientOnly ) +{ + const std::string tmpdir = "/tmp/ut/project2.slice/clientOnly"; + boost::filesystem::remove_all(tmpdir); + + TestOptionsSource::LoadTestOptions({ + { "library", (self.parent_path() / "libunittest.so").string() }, + { "ice.compile.tmpdir", tmpdir }, + { "ice.client.sliceclient", (iceroot / "unittest.ice").string() } + }); +} + diff --git a/project2/ice/unittests/unittest.ice b/project2/ice/unittests/unittest.ice new file mode 100644 index 0000000..3c18999 --- /dev/null +++ b/project2/ice/unittests/unittest.ice @@ -0,0 +1,9 @@ +module test { + interface a + { + ["project2:task"] + void someTask(); + + }; +}; + -- cgit v1.2.3 From ca76d111a640c4818d702f69632b059b0fc1f276 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Nov 2014 00:58:45 +0000 Subject: Switched to slicer internals, added more tests --- project2/Jamfile.jam | 2 +- project2/common/commonObjects.cpp | 1 - project2/ice/.ycm_extra_conf.py | 119 +++++++++++++++++++++ project2/ice/Jamfile.jam | 9 +- project2/ice/buildComms.cpp | 18 +++- project2/ice/buildComms.h | 4 +- project2/ice/buildDaemon.cpp | 4 - project2/ice/buildShared.cpp | 30 ------ project2/ice/buildShared.h | 20 ---- project2/ice/iceBase.cpp | 43 ++++++++ project2/ice/iceBase.h | 23 ++++ project2/ice/iceCompile.cpp | 10 +- project2/ice/iceCompile.h | 2 + project2/ice/iceDaemon.cpp | 68 +++++++----- project2/ice/iceDaemon.h | 16 ++- project2/ice/iceDataSource.cpp | 66 ++---------- project2/ice/iceDataSource.h | 18 +--- project2/ice/iceModule.cpp | 4 +- project2/ice/iceModule.h | 39 +------ project2/ice/iceRows.cpp | 108 +++++++++++++++++++ project2/ice/iceRows.h | 67 ++---------- project2/ice/iceViewSerializer.cpp | 54 ++++++++++ project2/ice/iceViewSerializer.h | 21 ++++ project2/ice/pch.hpp | 2 + project2/ice/slice2Common.cpp | 71 ++++++++++++ project2/ice/slice2Common.h | 23 ++++ project2/ice/slice2Daemon.cpp | 4 +- project2/ice/slice2Presenter.cpp | 60 ----------- project2/ice/slice2Presenter.h | 23 ---- project2/ice/slice2Rows.cpp | 51 ++------- project2/ice/slice2Rows.h | 10 +- project2/ice/slice2Task.cpp | 38 ++----- project2/ice/slice2Task.h | 10 +- project2/ice/slice2Type.cpp | 110 ------------------- project2/ice/slice2Type.h | 25 ----- project2/ice/unittests/Jamfile.jam | 49 +++++++++ project2/ice/unittests/testClient.cpp | 114 ++++++++++++++++++++ project2/ice/unittests/testClient.xml | 10 ++ project2/ice/unittests/testClientCompile.cpp | 74 ++++++++++++- project2/ice/unittests/testDaemonCompile.cpp | 80 ++++++++++++++ project2/ice/unittests/unittest-ice-datasource.xml | 4 + project2/ice/unittests/unittest.ice | 21 +++- project2/ut/testScriptHost.cpp | 107 ++++++++++++++++++ project2/ut/testScriptHost.h | 29 +++++ 44 files changed, 1091 insertions(+), 570 deletions(-) create mode 100644 project2/ice/.ycm_extra_conf.py delete mode 100644 project2/ice/buildShared.cpp delete mode 100644 project2/ice/buildShared.h create mode 100644 project2/ice/iceBase.cpp create mode 100644 project2/ice/iceBase.h create mode 100644 project2/ice/iceRows.cpp create mode 100644 project2/ice/iceViewSerializer.cpp create mode 100644 project2/ice/iceViewSerializer.h create mode 100644 project2/ice/slice2Common.cpp create mode 100644 project2/ice/slice2Common.h delete mode 100644 project2/ice/slice2Presenter.cpp delete mode 100644 project2/ice/slice2Presenter.h delete mode 100644 project2/ice/slice2Type.cpp delete mode 100644 project2/ice/slice2Type.h create mode 100644 project2/ice/unittests/testClient.cpp create mode 100644 project2/ice/unittests/testClient.xml create mode 100644 project2/ice/unittests/testDaemonCompile.cpp create mode 100644 project2/ice/unittests/unittest-ice-datasource.xml create mode 100644 project2/ut/testScriptHost.cpp create mode 100644 project2/ut/testScriptHost.h diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam index 8b17299..881b6ff 100644 --- a/project2/Jamfile.jam +++ b/project2/Jamfile.jam @@ -31,7 +31,7 @@ build-project daemon ; # Ensure tests are run (final targets don't reference projects, but specific libraries) build-project basics//unittests ; -build-project ice//tests ; +build-project ice//unittests ; explicit install installp2con installp2cgi installp2fcgi ; package.install install : : console//p2console cgi//p2cgi cgi//p2fcgi daemon//p2daemon ; diff --git a/project2/common/commonObjects.cpp b/project2/common/commonObjects.cpp index cb973cc..a25bb9f 100644 --- a/project2/common/commonObjects.cpp +++ b/project2/common/commonObjects.cpp @@ -1,6 +1,5 @@ #include #include "commonObjects.h" -#include "logger.h" #include "safeMapFind.h" #include "scriptLoader.h" diff --git a/project2/ice/.ycm_extra_conf.py b/project2/ice/.ycm_extra_conf.py new file mode 100644 index 0000000..ffb537b --- /dev/null +++ b/project2/ice/.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', +'.', +'-I', +'../common', +'-I', +'../lib', +'-isystem', +'/usr/include/slicer', +'-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/project2/ice/Jamfile.jam b/project2/ice/Jamfile.jam index 811b5d9..1f418af 100644 --- a/project2/ice/Jamfile.jam +++ b/project2/ice/Jamfile.jam @@ -9,6 +9,7 @@ lib Ice ; lib IceUtil ; lib pthread ; lib boost_filesystem ; +lib slicer : : slicer : : /usr/include/slicer ; build-project unittests ; @@ -17,10 +18,11 @@ cpp-pch pch : pch.hpp : ../lib//p2lib ../common//p2common glibmm + slicer ; lib p2iceclient : - pch iceDataSource.cpp iceClient.cpp buildClient.cpp slice2Task.cpp slice2Rows.cpp + pch iceDataSource.cpp iceClient.cpp buildClient.cpp slice2Task.cpp slice2Rows.cpp iceRows.cpp : ../../libmisc glibmm @@ -40,7 +42,7 @@ lib p2iceclient : ; lib p2icedaemon : - pch iceDaemon.cpp iceModule.cpp buildDaemon.cpp slice2Daemon.cpp slice2DaemonLoader.cpp slice2Presenter.cpp + pch iceDaemon.cpp iceModule.cpp buildDaemon.cpp slice2Daemon.cpp slice2DaemonLoader.cpp iceViewSerializer.cpp : ../../libmisc glibmm @@ -60,7 +62,7 @@ lib p2icedaemon : ; lib p2ice : - pch iceConvert.cpp iceCompile.cpp sliceCompile.cpp buildComms.cpp buildShared.cpp slice2Type.cpp + pch iceConvert.cpp iceCompile.cpp sliceCompile.cpp buildComms.cpp slice2Common.cpp iceBase.cpp : ../../libmisc glibmm @@ -69,6 +71,7 @@ lib p2ice : dl Ice Slice + slicer IceUtil boost_filesystem ; diff --git a/project2/ice/buildComms.cpp b/project2/ice/buildComms.cpp index 4add6c7..bdba5e9 100644 --- a/project2/ice/buildComms.cpp +++ b/project2/ice/buildComms.cpp @@ -2,9 +2,13 @@ #include "buildComms.h" #include #include +#include -BuildComms::BuildComms(const boost::filesystem::path & slice) : - IceCompile(slice) +namespace fs = boost::filesystem; + +BuildComms::BuildComms(const boost::filesystem::path & slice, bool ip) : + IceCompile(slice), + iceParts(ip) { } @@ -16,6 +20,16 @@ BuildComms::Build(const boost::filesystem::path & in, const boost::filesystem::p if (system(slicecmd.c_str())) { throw std::runtime_error("slice2cpp failed"); } + if (!iceParts) { + // We always need to the header, but we can truncate the cpp if we don't need the ice bits + boost::filesystem::resize_file(out, 0); + } + + const auto slicercmd = stringbf("%s %s %s", slicer, in, out); + Logger()->messagebf(LOG_DEBUG, "%s: slicer command: %s", __PRETTY_FUNCTION__, slicercmd); + if (system(slicercmd.c_str())) { + throw std::runtime_error("slicer failed"); + } } boost::filesystem::path diff --git a/project2/ice/buildComms.h b/project2/ice/buildComms.h index 31e7590..116051e 100644 --- a/project2/ice/buildComms.h +++ b/project2/ice/buildComms.h @@ -6,11 +6,13 @@ class BuildComms : public IceCompile { public: - BuildComms(const boost::filesystem::path & slice); + BuildComms(const boost::filesystem::path & slice, bool iceParts); void Build(const boost::filesystem::path & in, const boost::filesystem::path & out) const; boost::filesystem::path InputPath() const; boost::filesystem::path OutputName(const std::string & type) const; + + const bool iceParts; }; #endif diff --git a/project2/ice/buildDaemon.cpp b/project2/ice/buildDaemon.cpp index 83976b0..a6579c9 100644 --- a/project2/ice/buildDaemon.cpp +++ b/project2/ice/buildDaemon.cpp @@ -1,6 +1,5 @@ #include #include "buildDaemon.h" -#include "slice2Presenter.h" #include "slice2Daemon.h" #include "slice2DaemonLoader.h" @@ -18,9 +17,6 @@ BuildDaemon::Headers(FILE * out) const void BuildDaemon::Body(FILE * out, Slice::UnitPtr u) const { - Slice2Presenter presenterBuilder(out); - u->visit(&presenterBuilder, false); - Slice2Daemon daemonBuilder(out); u->visit(&daemonBuilder, false); diff --git a/project2/ice/buildShared.cpp b/project2/ice/buildShared.cpp deleted file mode 100644 index 61450c8..0000000 --- a/project2/ice/buildShared.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include "buildShared.h" -#include "slice2Type.h" - -BuildShared::BuildShared(const boost::filesystem::path & slice, const IceCompile::Deps & dep) : - SliceCompile(slice, dep) -{ -} - -void -BuildShared::Headers(FILE * out) const -{ - fprintf(out, "#include \n"); -} - -void -BuildShared::Body(FILE * out, Slice::UnitPtr u) const -{ - Slice2Type typeBuilder(out); - u->visit(&typeBuilder, false); -} - -boost::filesystem::path -BuildShared::OutputName(const std::string & type) const -{ - return slice.filename().replace_extension(".shared" + type); -} - - - diff --git a/project2/ice/buildShared.h b/project2/ice/buildShared.h deleted file mode 100644 index cf0e5d5..0000000 --- a/project2/ice/buildShared.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef BUILDSHARED_H -#define BUILDSHARED_H - -#include "sliceCompile.h" -#include - -class BuildShared : public SliceCompile { - public: - BuildShared(const boost::filesystem::path & slice, const IceCompile::Deps & dep); - - virtual void Headers(FILE *) const; - virtual void Body(FILE *, Slice::UnitPtr) const; - - boost::filesystem::path OutputName(const std::string & type) const; -}; - -#endif - - - diff --git a/project2/ice/iceBase.cpp b/project2/ice/iceBase.cpp new file mode 100644 index 0000000..0171f1b --- /dev/null +++ b/project2/ice/iceBase.cpp @@ -0,0 +1,43 @@ +#include "iceBase.h" +#include "buildComms.h" + +void +IceBase::SetSlice(Libs & libs, const GetComponentCompiler & gcc, const VariableType & vslice, bool iceParts, bool slicerParts) +{ + auto slice = vslice.as(); + IceCompile::CPtr bc(new BuildComms(slice, iceParts)); + bc->Update(IceCompile::UpdateBuild); + IceCompile::CPtr bcl(( !iceParts && !slicerParts ) ? + gcc(slice, { }) : + gcc(slice, { bc })); + libs.push_back(LibCompile(bcl, new std::thread(&IceCompile::Update, bcl.get(), + IceCompile::UpdateBuild | IceCompile::UpdateCompile | IceCompile::UpdateLink))); +} + +class WaitAndLoad : public boost::static_visitor<> { + public: + WaitAndLoad(IceBase::LibPromise & l) : lib(l) { } + + void operator()(IceBase::LibCompile & th) const + { + boost::get<1>(th)->join(); + delete boost::get<1>(th); + lib = boost::get<0>(th)->Open(); + } + + void operator()(IceCompile::LibHandle) const + { + } + + private: + IceBase::LibPromise & lib; +}; + +void +IceBase::FinaliseLoad(Libs & libs) +{ + BOOST_FOREACH(auto & lib, libs) { + boost::apply_visitor(WaitAndLoad(lib), lib); + } +} + diff --git a/project2/ice/iceBase.h b/project2/ice/iceBase.h new file mode 100644 index 0000000..06d8994 --- /dev/null +++ b/project2/ice/iceBase.h @@ -0,0 +1,23 @@ +#ifndef ICEBASE_H +#define ICEBASE_H + +#include +#include +#include "iceCompile.h" +#include + +class IceBase { + public: + typedef boost::tuple LibCompile; + typedef boost::variant LibPromise; + typedef std::vector Libs; + typedef boost::function GetComponentCompiler; + + static void FinaliseLoad(Libs & libs); + + protected: + static void SetSlice(Libs &, const GetComponentCompiler &, const VariableType &, bool iceParts, bool slicerParts); +}; + +#endif + diff --git a/project2/ice/iceCompile.cpp b/project2/ice/iceCompile.cpp index 3df8dbd..74b0b45 100644 --- a/project2/ice/iceCompile.cpp +++ b/project2/ice/iceCompile.cpp @@ -8,12 +8,14 @@ namespace fs = boost::filesystem; std::string IceCompile::slice2cpp; +std::string IceCompile::slicer; std::string IceCompile::cxx; std::string IceCompile::linker; std::string IceCompile::cxxopts; std::string IceCompile::linkeropts; fs::path IceCompile::tmpdir; fs::path IceCompile::headerdir; +fs::path IceCompile::slicerheaderdir; DECLARE_OPTIONS(IceCompile, "ICE Compile Options") ("ice.compile.cxx", Options::value(&cxx, "g++"), @@ -26,10 +28,14 @@ DECLARE_OPTIONS(IceCompile, "ICE Compile Options") "The extra arguments to pass to linker") ("ice.compile.slice2cpp", Options::value(&slice2cpp, "slice2cpp"), "The ICE Slice to CPP processor to use") +("ice.compile.slicer", Options::value(&slicer, "slicer"), + "The Slicer to CPP processor to use") ("ice.compile.tmpdir", Options::value(&tmpdir, "/tmp/project2.slice"), "The temporary directory used when compiling") ("ice.compile.headers", Options::value(&headerdir, "/usr/include/project2"), "The root folder where Project2 header files are found") +("ice.compile.slicerheaders", Options::value(&slicerheaderdir, "/usr/include/slicer"), + "The root folder where Slicer header files are found") END_OPTIONS(IceCompile); IceCompile::IceCompile(const boost::filesystem::path & s) : @@ -81,8 +87,10 @@ void IceCompile::Compile(const fs::path & in, const fs::path & out) const { const auto compile = stringbf( - "%s %s -o %s -x c++ -c -I %s -I %s -I ../libmisc/ -I %s -I %s -I %s `pkg-config --cflags glibmm-2.4` %s", + "%s %s -o %s -x c++ -c -I %s -I %s -I ../libmisc/ -I %s -I %s -I %s -I %s -I %s `pkg-config --cflags glibmm-2.4` %s", cxx, cxxopts, out, tmpdir, + slicerheaderdir, + headerdir.parent_path() / "libmisc", headerdir / "lib", headerdir / "common", headerdir / "ice", diff --git a/project2/ice/iceCompile.h b/project2/ice/iceCompile.h index d849ac6..5e6873a 100644 --- a/project2/ice/iceCompile.h +++ b/project2/ice/iceCompile.h @@ -15,12 +15,14 @@ class IceCompile { typedef std::vector Deps; static std::string slice2cpp; + static std::string slicer; static std::string cxx; static std::string linker; static std::string cxxopts; static std::string linkeropts; static boost::filesystem::path tmpdir; static boost::filesystem::path headerdir; + static boost::filesystem::path slicerheaderdir; IceCompile(const boost::filesystem::path & slice); IceCompile(const boost::filesystem::path & slice, const Deps & deps); diff --git a/project2/ice/iceDaemon.cpp b/project2/ice/iceDaemon.cpp index 04d6fdb..a8fb8c2 100644 --- a/project2/ice/iceDaemon.cpp +++ b/project2/ice/iceDaemon.cpp @@ -1,8 +1,8 @@ #include #include "iceDaemon.h" #include "buildComms.h" -#include "buildShared.h" #include "buildDaemon.h" +#include "iceViewSerializer.h" #include #include #include @@ -20,12 +20,18 @@ std::string IceDaemon::adapterName; std::string IceDaemon::adapterEndpoint; -std::string IceDaemon::interface; -std::string IceDaemon::slice; std::string IceDaemon::viewRoot; std::string IceDaemon::taskRoot; +IceBase::Libs IceDaemon::libs; -DECLARE_GENERIC_LOADER("ice", DaemonLoader, IceDaemon); +class IceDaemonLoader : public DaemonLoader::For { + public: + void onConfigLoad() override { + IceBase::FinaliseLoad(IceDaemon::libs); + } +}; + +DECLARE_CUSTOM_COMPONENT_LOADER("ice", IceDaemon, IceDaemonLoader, DaemonLoader); DECLARE_OPTIONS(IceDaemon, "ICE Daemon Options") ("ice.daemon.viewRoot", Options::value(&viewRoot, "views"), "The folder in which to find view scripts") @@ -35,10 +41,12 @@ DECLARE_OPTIONS(IceDaemon, "ICE Daemon Options") "The name of the ICE adapter created") ("ice.daemon.adapterEndpoint", Options::value(&adapterEndpoint), "The ICE endpoint string for the ICE adapter") -("ice.daemon.slice", Options::value(&slice), - "The ICE Slice file to compile") -("ice.daemon.interface", Options::value(&interface), - "The ICE interface to wrap") +("ice.daemon.slice", Options::functions(boost::bind(&IceBase::SetSlice, boost::ref(IceDaemon::libs), &IceDaemon::GetComponentCompiler, _1, true, true), boost::bind(&IceDaemon::ClearSlice)), + "The ICE Slice file(s) to compile") +("ice.daemon.slicedaemon", Options::functions(boost::bind(&IceDaemon::SetSlice, boost::ref(IceDaemon::libs), &IceDaemon::GetComponentCompiler, _1, false, true), boost::bind(&IceDaemon::ClearSlice)), + "The ICE Slice file(s) to compile (daemon only, assumes comms library referenced)") +("ice.daemon.slicerdaemon", Options::functions(boost::bind(&IceDaemon::SetSlice, boost::ref(IceDaemon::libs), &IceDaemon::GetComponentCompiler, _1, false, false), boost::bind(&IceDaemon::ClearSlice)), + "The ICE Slice file(s) to compile (daemon only, assumes comms library referenced and built with Slicer support)") END_OPTIONS(IceDaemon); IceDaemon::IceDaemon(int & argc, char ** argv) : @@ -60,31 +68,28 @@ IceDaemon::shutdown() const void IceDaemon::run() const { - Logger()->messagebf(LOG_INFO, ">>> %s compiling slice '%s'...", __PRETTY_FUNCTION__, slice); - - IceCompile::CPtr bc(new BuildComms(slice)); - IceCompile::CPtr bds(new BuildShared(slice, { bc })); - IceCompile::CPtr bd(new BuildDaemon(slice, { bds })); - bd->Update(); - - auto library = bd->Open(); - Logger()->messagebf(LOG_INFO, " %s starting...", __PRETTY_FUNCTION__); Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithEndpoints(adapterName, adapterEndpoint); - IceDaemonAdapterHandlerPtr interfacePtr = IceDaemonAdapterHandlerLoader::createNew(interface); - interfacePtr->add(adapter, this, ic); + std::set interfaces; + InstanceSet::OnAll([this, adapter, &interfaces](IceDaemonAdapterHandlerLoader * loader) { + IceDaemonAdapterHandlerPtr interfacePtr = loader->create(); + interfacePtr->add(adapter, this, ic); + interfaces.insert(interfacePtr); + }); adapter->activate(); Logger()->messagebf(LOG_INFO, " %s running...", __PRETTY_FUNCTION__); - interfacePtr->remove(adapter, ic); + BOOST_FOREACH(const auto & interfacePtr, interfaces) { + interfacePtr->remove(adapter, ic); + } ic->waitForShutdown(); Logger()->messagebf(LOG_INFO, " %s stopped...", __PRETTY_FUNCTION__); Logger()->messagebf(LOG_INFO, "<<< %s", __PRETTY_FUNCTION__); } -class IceDaemonFlatViewHost : public virtual CommonObjects, public virtual CheckHost { +class IceDaemonViewHost : public virtual CommonObjects, public virtual CheckHost { public: - IceDaemonFlatViewHost(ScriptNodePtr s) : + IceDaemonViewHost(ScriptNodePtr s) : CommonObjects(s), CheckHost(s) { @@ -93,6 +98,7 @@ class IceDaemonFlatViewHost : public virtual CommonObjects, public virtual Check void executeView(RowSetPresenterPtr presenter, ExecContext * ec) const { loadScriptComponents(); + runChecks(ec); view->execute(presenter.get(), ec); // Caches might open transactions BOOST_FOREACH(const CommonObjects::DataSources::value_type & ds, CommonObjects::datasources) { @@ -127,12 +133,12 @@ class IceCallContext : public ExecContext { }; void -IceDaemon::executeView(const std::string & name, RowSetPresenterPtr p, const ParamMap & pm) const +IceDaemon::executeView(const std::string & name, Slicer::ModelPartPtr p, const ParamMap & pm) const { ScriptNodePtr s = ScriptReader::resolveScript(IceDaemon::viewRoot, name, false)->root(); - IceDaemonFlatViewHost f(s); + IceDaemonViewHost f(s); IceCallContext icc(pm); - f.executeView(p, &icc); + f.executeView(new IceViewSerializer(p), &icc); } class IceDaemonTaskHost : public TaskHost { @@ -159,3 +165,15 @@ IceDaemon::executeTask(const std::string & name, const ParamMap & pm) const t.executeTask(&icc); } +IceCompile::CPtr +IceDaemon::GetComponentCompiler(const std::string & slice, const IceCompile::Deps & deps) +{ + return IceCompile::CPtr(new BuildDaemon(slice, deps)); +} + +void +IceDaemon::ClearSlice() +{ + libs.clear(); +} + diff --git a/project2/ice/iceDaemon.h b/project2/ice/iceDaemon.h index 49af50b..623da11 100644 --- a/project2/ice/iceDaemon.h +++ b/project2/ice/iceDaemon.h @@ -3,9 +3,14 @@ #include #include "iceModule.h" +#include "iceBase.h" -class IceDaemon : public Daemon { +class IceDaemon : public Daemon, IceBase { public: + typedef boost::tuple LibCompile; + typedef boost::variant LibPromise; + typedef std::vector Libs; + IceDaemon(int & argc, char ** argv); virtual ~IceDaemon(); @@ -13,18 +18,21 @@ class IceDaemon : public Daemon { void shutdown() const; void executeTask(const std::string & name, const ParamMap & params) const; - void executeView(const std::string & name, RowSetPresenterPtr p, const ParamMap & params) const; + void executeView(const std::string & name, Slicer::ModelPartPtr p, const ParamMap & params) const; INITOPTIONS; static std::string adapterName; static std::string adapterEndpoint; - static std::string interface; - static std::string slice; static std::string viewRoot; static std::string taskRoot; + static Libs libs; + + static IceCompile::CPtr GetComponentCompiler(const std::string & slice, const IceCompile::Deps &); private: Ice::CommunicatorPtr ic; + + static void ClearSlice(); }; #endif diff --git a/project2/ice/iceDataSource.cpp b/project2/ice/iceDataSource.cpp index 064a69f..c3d5b36 100644 --- a/project2/ice/iceDataSource.cpp +++ b/project2/ice/iceDataSource.cpp @@ -1,18 +1,18 @@ #include -#include "iceDataSource.h" -#include "buildComms.h" -#include "buildShared.h" #include "buildClient.h" +#include "iceDataSource.h" #include -IceDataSource::Libs IceDataSource::libs; +IceBase::Libs IceDataSource::libs; IceDataSource::Proxies IceDataSource::proxies; DECLARE_OPTIONS(IceDataSource, "ICE Data Source") -("ice.client.slice", Options::functions(boost::bind(&IceDataSource::SetSlice, _1), boost::bind(&IceDataSource::ClearSlice)), +("ice.client.slice", Options::functions(boost::bind(&IceBase::SetSlice, boost::ref(IceDataSource::libs), &IceDataSource::GetComponentCompiler, _1, true, true), boost::bind(&IceDataSource::ClearSlice)), "The ICE Slice file(s) to compile") -("ice.client.sliceclient", Options::functions(boost::bind(&IceDataSource::SetSliceClient, _1), boost::bind(&IceDataSource::ClearSlice)), +("ice.client.sliceclient", Options::functions(boost::bind(&IceBase::SetSlice, boost::ref(IceDataSource::libs), &IceDataSource::GetComponentCompiler, _1, false, true), boost::bind(&IceDataSource::ClearSlice)), "The ICE Slice file(s) to compile (client only, assumes comms library referenced)") +("ice.client.slicerclient", Options::functions(boost::bind(&IceBase::SetSlice, boost::ref(IceDataSource::libs), &IceDataSource::GetComponentCompiler, _1, false, false), boost::bind(&IceDataSource::ClearSlice)), + "The ICE Slice file(s) to compile (client only, assumes comms library referenced and built with Slicer support)") END_OPTIONS(IceDataSource); int dummy = 0; @@ -21,57 +21,13 @@ IceDataSource::IceDataSource(ScriptNodePtr p) : endpoint(p, "endpoint"), ic(Ice::initialize(dummy, NULL)) { + Logger()->messagebf(LOG_DEBUG, "%s: endpoint: %s", __PRETTY_FUNCTION__, endpoint(NULL)); } -void -IceDataSource::SetSlice(const VariableType & vslice) -{ - auto slice = vslice.as(); - IceCompile::CPtr bc(new BuildComms(slice)); - bc->Update(IceCompile::UpdateBuild); - IceCompile::CPtr bcs(new BuildShared(slice, { bc })); - IceCompile::CPtr bcl(new BuildClient(slice, { bcs })); - libs.push_back(LibCompile(bcl, new std::thread(&IceCompile::Update, bcl.get(), - IceCompile::UpdateBuild | IceCompile::UpdateCompile | IceCompile::UpdateLink))); -} - -void -IceDataSource::SetSliceClient(const VariableType & vslice) -{ - auto slice = vslice.as(); - IceCompile::CPtr bc(new BuildComms(slice)); - bc->Update(IceCompile::UpdateBuild); - IceCompile::CPtr bcs(new BuildShared(slice, { })); - IceCompile::CPtr bcl(new BuildClient(slice, { bcs })); - libs.push_back(LibCompile(bcl, new std::thread(&IceCompile::Update, bcl.get(), - IceCompile::UpdateBuild | IceCompile::UpdateCompile | IceCompile::UpdateLink))); -} - -class WaitAndLoad : public boost::static_visitor<> { - public: - WaitAndLoad(IceDataSource::LibPromise & l) : lib(l) { } - - void operator()(IceDataSource::LibCompile & th) const - { - boost::get<1>(th)->join(); - delete boost::get<1>(th); - lib = boost::get<0>(th)->Open(); - } - - void operator()(IceCompile::LibHandle) const - { - } - - private: - IceDataSource::LibPromise & lib; -}; - -void -IceDataSource::FinaliseLoad() +IceCompile::CPtr +IceDataSource::GetComponentCompiler(const std::string & slice, const IceCompile::Deps & deps) { - BOOST_FOREACH(auto & lib, libs) { - boost::apply_visitor(WaitAndLoad(lib), lib); - } + return IceCompile::CPtr(new BuildClient(slice, deps)); } void @@ -84,7 +40,7 @@ IceDataSource::ClearSlice() class IceDataSourceLoader : public ElementLoader::For { public: void onConfigLoad() override { - IceDataSource::FinaliseLoad(); + IceBase::FinaliseLoad(IceDataSource::libs); } }; diff --git a/project2/ice/iceDataSource.h b/project2/ice/iceDataSource.h index 47af13b..9881a41 100644 --- a/project2/ice/iceDataSource.h +++ b/project2/ice/iceDataSource.h @@ -3,20 +3,13 @@ #include #include -#include -#include "iceCompile.h" #include -#include -#include +#include "iceBase.h" -class IceDataSource : public DataSource { +class IceDataSource : public DataSource, IceBase { public: INITOPTIONS; - typedef boost::tuple LibCompile; - typedef boost::variant LibPromise; - typedef std::vector Libs; - IceDataSource(ScriptNodePtr p); template @@ -32,14 +25,11 @@ class IceDataSource : public DataSource { } const Ice::CommunicatorPtr GetCommunicator() const { return ic; } - static void FinaliseLoad(); + static IceCompile::CPtr GetComponentCompiler(const std::string & slice, const IceCompile::Deps &); - private: - static void SetSlice(const VariableType &); - static void SetSliceClient(const VariableType &); static void ClearSlice(); static Libs libs; - + private: const Variable endpoint; const Ice::CommunicatorPtr ic; diff --git a/project2/ice/iceModule.cpp b/project2/ice/iceModule.cpp index 1738bef..c1e035e 100644 --- a/project2/ice/iceModule.cpp +++ b/project2/ice/iceModule.cpp @@ -9,8 +9,8 @@ IceDaemonModule::IceDaemonModule(const IceDaemon * id) : } void -IceDaemonModule::executeView(const std::string & name, RowSetPresenterPtr p, const ParamMap & params) const { - iceDaemon->executeView(name, p, params); +IceDaemonModule::executeView(const std::string & name, Slicer::ModelPartPtr mpp, const ParamMap & params) const { + iceDaemon->executeView(name, mpp, params); } void diff --git a/project2/ice/iceModule.h b/project2/ice/iceModule.h index 246c9b8..3886aef 100644 --- a/project2/ice/iceModule.h +++ b/project2/ice/iceModule.h @@ -7,6 +7,7 @@ #include #include #include +#include typedef std::map ParamMap; class IceDaemon; @@ -15,8 +16,9 @@ class IceDaemonModule { protected: IceDaemonModule(const IceDaemon *); + protected: void executeTask(const std::string & name, const ParamMap & params) const; - void executeView(const std::string & name, RowSetPresenterPtr p, const ParamMap & params) const; + void executeView(const std::string & name, Slicer::ModelPartPtr p, const ParamMap & params) const; private: const IceDaemon * const iceDaemon; @@ -31,40 +33,5 @@ class IceDaemonAdapterHandler : public IntrusivePtrBase { typedef boost::intrusive_ptr IceDaemonAdapterHandlerPtr; typedef GenLoader IceDaemonAdapterHandlerLoader; -template -class IcePresenter : public RowSetPresenter { - public: - typedef boost::function TargetAssigner; - typedef std::map MemberTargets; - SimpleMessageException(NoSuchMember); - - IcePresenter(IC & t); - virtual void addNamedValue(const Glib::ustring & member, const VariableType & value) const - { - safeMapLookup(memberTargets, member)(&*current, value); - } - virtual void addNewRow(const Glib::ustring&) const - { - target.push_back(typename IC::value_type()); - } - virtual void finishRow() const - { - current = target.end(); - } - // The target array already exists, so these need not do anything - virtual void addNewArray(const Glib::ustring&, bool) const { } - virtual void finishArray(bool) const { } - virtual void init() { } - private: - IC & target; - mutable typename IC::iterator current; - const MemberTargets memberTargets; - - template static void memberAssign(T * t, M T::*m, const VariableType & v) { - t->*m = v.as(); - } -}; - - #endif diff --git a/project2/ice/iceRows.cpp b/project2/ice/iceRows.cpp new file mode 100644 index 0000000..77519cd --- /dev/null +++ b/project2/ice/iceRows.cpp @@ -0,0 +1,108 @@ +#include +#include "iceRows.h" + +using namespace Slicer; + +class IceRowState : public RowState { + public: + class Assign : public ValueTarget, + public TValueTarget { + public: + Assign(VariableType & v) : vt(v) + { + } + + void get(const boost::posix_time::ptime & v) const override { vt = v; } + void get(const bool & v) const override { vt = v; } + void get(const Ice::Byte & v) const override { vt = v; } + void get(const Ice::Short & v) const override { vt = v; } + void get(const Ice::Int & v) const override { vt = v; } + void get(const Ice::Long & v) const override { vt = v; } + void get(const Ice::Float & v) const override { vt = v; } + void get(const Ice::Double & v) const override { vt = v; } + void get(const std::string & v) const override { vt = v; } + + private: + VariableType & vt; + }; + + IceRowState(ModelPartPtr mp) + { + unsigned int idx = 0; + mp->OnEachChild(boost::bind(&IceRowState::AddColumn, this, boost::ref(idx), _1)); + fields.resize(columns.size()); + } + + void AddColumn(unsigned int & c, const std::string & name) + { + columns.insert(new Column(c++, name)); + } + + const Columns & getColumns() const { return columns; } + + void IterateOver(ModelPartPtr mp, const RowProcessorCallback & rp) + { + auto field = fields.begin(); + mp->OnEachChild(boost::bind(&IceRowState::AssignFieldValue, this, boost::ref(field), _2)); + this->process(rp); + } + + void AssignFieldValue(FieldValues::iterator & field, ModelPartPtr domp) + { + domp->GetValue(new Assign(*field++)); + } + + Columns columns; +}; + +RowProcSerializer::RowProcSerializer(const RowProcessorCallback & r) : + rpc(r) +{ +} + +void +RowProcSerializer::Serialize(ModelPartPtr mp) +{ + if (mp) { + switch (mp->GetType()) { + case mpt_Null: + return; + case mpt_Simple: + case mpt_Complex: + case mpt_Dictionary: + throw std::runtime_error("Not a sequence of things"); + case mpt_Sequence: + IceRowState * irs = NULL; + mp->OnEachChild(boost::bind(&RowProcSerializer::SerializeRow, this, boost::ref(irs), _2)); + if (irs) { + delete irs; + } + break; + } + } + +} + +void +RowProcSerializer::SerializeRow(IceRowState * & irs, ModelPartPtr mp) +{ + if (mp) { + switch (mp->GetType()) { + case mpt_Null: + return; + case mpt_Sequence: + case mpt_Dictionary: + case mpt_Simple: + throw std::runtime_error("Not a complex object"); + break; + case mpt_Complex: + if (!irs) { + irs = new IceRowState(mp); + } + irs->IterateOver(mp, rpc); + break; + } + } + +} + diff --git a/project2/ice/iceRows.h b/project2/ice/iceRows.h index 654de50..4c15217 100644 --- a/project2/ice/iceRows.h +++ b/project2/ice/iceRows.h @@ -4,70 +4,21 @@ #include #include "iceConvert.h" #include "iceClient.h" +#include +#include -template -class IceRowState : public RowState { - public: - IceRowState() - { - unsigned int idx = 0; - IceType::CreateColumns(boost::bind(&IceRowState::AddColumn, this, boost::ref(idx), _1)); - fields.resize(columns.size()); - } - - void AddColumn(unsigned int & c, const std::string & name) - { - columns.insert(new Column(c++, name)); - } - - const Columns & getColumns() const { return columns; } - - void IterateOver(const Type & record, const RowProcessorCallback & rp) { - auto field = fields.begin(); - IceType::ForEachDataMember(record, boost::bind(&IceRowState::AssignFieldValue, this, boost::ref(field), _1)); - this->process(rp); - } - - void AssignFieldValue(FieldValues::iterator & field, const VariableType & vt) - { - *field++ = vt; - } +class IceRowState; - Columns columns; -}; - -template -class IceRowState > : public RowState { +class RowProcSerializer : public Slicer::Serializer { public: - typedef std::vector RangeType; - IceRowState() - { - unsigned int idx = 0; - IceType::CreateColumns(boost::bind(&IceRowState::AddColumn, this, boost::ref(idx), _1)); - fields.resize(columns.size()); - } + RowProcSerializer(const RowProcessorCallback &); - void AddColumn(unsigned int & c, const std::string & name) - { - columns.insert(new Column(c++, name)); - } + void Serialize(Slicer::ModelPartPtr) override; - const Columns & getColumns() const { return columns; } - - void IterateOver(const RangeType & records, const RowProcessorCallback & rp) { - BOOST_FOREACH(const auto & record, records) { - auto field = fields.begin(); - IceType::ForEachDataMember(record, boost::bind(&IceRowState::AssignFieldValue, this, boost::ref(field), _1)); - this->process(rp); - } - } - - void AssignFieldValue(FieldValues::iterator & field, const VariableType & vt) - { - *field++ = vt; - } + private: + void SerializeRow(IceRowState * &, Slicer::ModelPartPtr); - Columns columns; + const RowProcessorCallback & rpc; }; template diff --git a/project2/ice/iceViewSerializer.cpp b/project2/ice/iceViewSerializer.cpp new file mode 100644 index 0000000..2a95f9f --- /dev/null +++ b/project2/ice/iceViewSerializer.cpp @@ -0,0 +1,54 @@ +#include "iceViewSerializer.h" +#include + +using namespace Slicer; + +class Assign : public ValueSource, + public TValueSource { + public: + Assign(const VariableType & v) : vt(v) + { + } + + void set(boost::posix_time::ptime & v) const override { v = vt; } + void set(bool & v) const override { v = vt; } + void set(Ice::Byte & v) const override { v = boost::numeric_cast(vt.as()); } + void set(Ice::Short & v) const override { v = boost::numeric_cast(vt.as()); } + void set(Ice::Int & v) const override { v = vt; } + void set(Ice::Long & v) const override { v = vt; } + void set(Ice::Float & v) const override { v = vt.as(); } + void set(Ice::Double & v) const override { v = vt; } + void set(std::string & v) const override { v = vt.as(); } + + private: + const VariableType & vt; +}; + +IceViewSerializer::IceViewSerializer(ModelPartPtr m) : + mpp(m) +{ +} + +void +IceViewSerializer::addNamedValue(const Glib::ustring & name, const VariableType & vt) const +{ + if (rowmpp) { + ModelPartPtr field = rowmpp->GetChild(name); + if (field) { + field->SetValue(new Assign(vt)); + } + } +} + +void +IceViewSerializer::addNewRow(const Glib::ustring & name) const +{ + rowmpp = mpp->GetChild(name); +} + +void +IceViewSerializer::finishRow() const +{ + rowmpp = NULL; +} + diff --git a/project2/ice/iceViewSerializer.h b/project2/ice/iceViewSerializer.h new file mode 100644 index 0000000..ff4188d --- /dev/null +++ b/project2/ice/iceViewSerializer.h @@ -0,0 +1,21 @@ +#ifndef ICEVIEWSERIALIZER_H +#define ICEVIEWSERIALIZER_H + +#include +#include + +class IceViewSerializer : public RowSetPresenter { + public: + IceViewSerializer(Slicer::ModelPartPtr mpp); + + void addNamedValue(const Glib::ustring & name, const VariableType & value) const override; + void addNewRow(const Glib::ustring & name) const override; + void finishRow() const override; + + private: + Slicer::ModelPartPtr mpp; + mutable Slicer::ModelPartPtr rowmpp; +}; + +#endif + diff --git a/project2/ice/pch.hpp b/project2/ice/pch.hpp index c74eebf..21f44dc 100644 --- a/project2/ice/pch.hpp +++ b/project2/ice/pch.hpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #endif #endif diff --git a/project2/ice/slice2Common.cpp b/project2/ice/slice2Common.cpp new file mode 100644 index 0000000..5088120 --- /dev/null +++ b/project2/ice/slice2Common.cpp @@ -0,0 +1,71 @@ +#include "slice2Common.h" +#include +#include + +Slice2Common::Slice2Common(FILE * c) : + code(c) +{ +} + +void +Slice2Common::FunctionBegin(Slice::OperationPtr o) +{ + // Create typed variables for call + BOOST_FOREACH(const auto & p, o->parameters()) { + if (p->optional()) { + fprintf(code, "\t\t\t\t\t\tconst auto _%s = IceConvert< ::IceUtil::Optional< %s > >::FromVariable(%s(ec));\n", + p->name().c_str(), + Slice::typeToString(p->type()).c_str(), + p->name().c_str()); + } + else { + fprintf(code, "\t\t\t\t\t\tconst auto _%s = IceConvert< %s >::FromVariable(%s(ec));\n", + p->name().c_str(), + Slice::typeToString(p->type()).c_str(), + p->name().c_str()); + } + } + fprintf(code, "\n"); + + // Log call and parameters + fprintf(code, "\t\t\t\t\t\tLogger()->messagebf(LOG_DEBUG, \"%%s: "); + BOOST_FOREACH(const auto & p, o->parameters()) { + fprintf(code, "%s = %%s, ", p->name().c_str()); + } + fprintf(code, "ice @ %%p\", \n"); + fprintf(code, "\t\t\t\t\t\t\t\t__PRETTY_FUNCTION__, "); + BOOST_FOREACH(const auto & p, o->parameters()) { + fprintf(code, "_%s, ", p->name().c_str()); + } + fprintf(code, "ice);\n"); + + // Create default Ice context + fprintf(code, "\n"); + fprintf(code, "\t\t\t\t\t\tIce::Context ctx;\n"); +} + +void +Slice2Common::ParameterVariables(Slice::OperationPtr o) +{ + BOOST_FOREACH(const auto & p, o->parameters()) { + fprintf(code, "\t\t\t\t\tconst Variable %s;\n", p->name().c_str()); + } +} + +void +Slice2Common::Declaration(Slice::OperationPtr o) +{ + fprintf(code, "\t\t\tDECLARE_LOADER(\"%s-%s-%s\", %s);\n\n", + module.c_str(), interface.c_str(), o->name().c_str(), o->name().c_str()); +} + +void +Slice2Common::CallOperation(Slice::OperationPtr o) +{ + fprintf(code, "service->%s(", o->name().c_str()); + BOOST_FOREACH(const auto & p, o->parameters()) { + fprintf(code, "_%s, ", p->name().c_str()); + } + fprintf(code, "ctx)"); +} + diff --git a/project2/ice/slice2Common.h b/project2/ice/slice2Common.h new file mode 100644 index 0000000..bb4719b --- /dev/null +++ b/project2/ice/slice2Common.h @@ -0,0 +1,23 @@ +#ifndef SLICE2COMMON_H +#define SLICE2COMMON_H + +#include + +class Slice2Common : public Slice::ParserVisitor { + public: + Slice2Common(FILE * c); + + void FunctionBegin(Slice::OperationPtr o); + void ParameterVariables(Slice::OperationPtr o); + void Declaration(Slice::OperationPtr o); + void CallOperation(Slice::OperationPtr o); + + protected: + FILE * code; + + std::string interface; + std::string module; +}; + +#endif + diff --git a/project2/ice/slice2Daemon.cpp b/project2/ice/slice2Daemon.cpp index 6a8e5fa..3e66339 100644 --- a/project2/ice/slice2Daemon.cpp +++ b/project2/ice/slice2Daemon.cpp @@ -44,8 +44,8 @@ Slice2Daemon::visitOperation(const Slice::OperationPtr & o) visitParameterMap(o); if (o->returnType()) { fprintf(code, "\t\t\t\t%s rtn;\n", o->returnType()->typeId().c_str()); - fprintf(code, "\t\t\t\tRowSetPresenterPtr ipp = new IcePresenter< %s >(rtn);\n", o->returnType()->typeId().c_str()); - fprintf(code, "\t\t\t\texecuteView(\"%s/%s/%s\", ipp, params);\n", module.c_str(), interface.c_str(), o->name().c_str()); + fprintf(code, "\t\t\t\tSlicer::ModelPartPtr mpp = new Slicer::ModelPartForSequence< %s >(rtn);\n", o->returnType()->typeId().c_str()); + fprintf(code, "\t\t\t\texecuteView(\"%s/%s/%s\", mpp, params);\n", module.c_str(), interface.c_str(), o->name().c_str()); fprintf(code, "\t\t\t\treturn rtn;\n"); } else { diff --git a/project2/ice/slice2Presenter.cpp b/project2/ice/slice2Presenter.cpp deleted file mode 100644 index 3cfb422..0000000 --- a/project2/ice/slice2Presenter.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include "slice2Presenter.h" -#include - -Slice2Presenter::Slice2Presenter(FILE * c) : - code(c) -{ -} - -bool -Slice2Presenter::visitModuleStart(const Slice::ModulePtr & m) -{ - module = m->name(); - fprintf(code, "// Specialized functions for IcePresenters in module %s\n\n", module.c_str()); - return true; -} - -void -Slice2Presenter::visitModuleEnd(const Slice::ModulePtr &) -{ - fprintf(code, "// End Specialized functions for IcePresenters in module %s\n\n", module.c_str()); - module.clear(); -} - -bool -Slice2Presenter::visitStructStart(const Slice::StructPtr & s) -{ - strct = s->name(); - fprintf(code, "template <>\nIcePresenter>::IcePresenter(std::vector< %s::%s > & t) :\n", - module.c_str(), s->name().c_str(), - module.c_str(), s->name().c_str()); - fprintf(code, "\ttarget(t),\n\tcurrent(target.end()),\n"); - fprintf(code, "\tmemberTargets({\n"); - return true; -} - -void -Slice2Presenter::visitDataMember(const Slice::DataMemberPtr & m) -{ - fprintf(code, "\t\t{\"%s\", boost::bind(&IcePresenter>::memberAssign< %s::%s, %s >, _1, &%s::%s::%s, _2)},\n", - m->name().c_str(), - module.c_str(), strct.c_str(), - module.c_str(), strct.c_str(), - typeToString(m->type()).c_str(), - module.c_str(), strct.c_str(), m->name().c_str() - - ); -} - -void -Slice2Presenter::visitStructEnd(const Slice::StructPtr&) -{ - fprintf(code, "\t})\n{\n"); - - //fprintf(code, "boost::bind(&IcePresenter>::memberAssign, NULL, &P2TV::Recording::recordingId, 1);\n"); - - fprintf(code, "}\n\n"); - strct.clear(); -} - diff --git a/project2/ice/slice2Presenter.h b/project2/ice/slice2Presenter.h deleted file mode 100644 index 892f2c1..0000000 --- a/project2/ice/slice2Presenter.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef ICEBUILDPRESENTER_H -#define ICEBUILDPRESENTER_H - -#include - -class Slice2Presenter : public Slice::ParserVisitor { - public: - Slice2Presenter(FILE * c); - virtual bool visitModuleStart(const Slice::ModulePtr & m); - virtual void visitModuleEnd(const Slice::ModulePtr & m); - virtual bool visitStructStart(const Slice::StructPtr&); - virtual void visitStructEnd(const Slice::StructPtr&); - virtual void visitDataMember(const Slice::DataMemberPtr&); - - private: - FILE * code; - std::string module; - std::string strct; -}; - -#endif - - diff --git a/project2/ice/slice2Rows.cpp b/project2/ice/slice2Rows.cpp index a90b643..3534aff 100644 --- a/project2/ice/slice2Rows.cpp +++ b/project2/ice/slice2Rows.cpp @@ -4,7 +4,7 @@ #include Slice2Rows::Slice2Rows(FILE * c) : - code(c) + Slice2Common(c) { } @@ -42,48 +42,17 @@ Slice2Rows::visitOperation(const Slice::OperationPtr & o) // Execute fprintf(code, "\t\t\t\t\tvoid execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const\n"); fprintf(code, "\t\t\t\t\t{\n"); - fprintf(code, "\t\t\t\t\t\tLogger()->messagebf(LOG_DEBUG, \"%%s: "); - BOOST_FOREACH(const auto & p, o->parameters()) { - fprintf(code, "%s = %%s, ", p->name().c_str()); - } - fprintf(code, "ice @ %%p\", \n"); - fprintf(code, "\t\t\t\t\t\t\t\t__PRETTY_FUNCTION__, "); - BOOST_FOREACH(const auto & p, o->parameters()) { - fprintf(code, "%s(ec), ", p->name().c_str()); - } - fprintf(code, "ice);\n"); - fprintf(code, "\t\t\t\t\t\tIce::Context ctx;\n"); - BOOST_FOREACH(const auto & p, o->parameters()) { - if (p->optional()) { - fprintf(code, "\t\t\t\t\t\tauto _%s = IceConvert< ::IceUtil::Optional< %s > >::FromVariable(%s(ec));\n", - p->name().c_str(), - Slice::typeToString(p->type()).c_str(), - p->name().c_str()); - } - else { - fprintf(code, "\t\t\t\t\t\tauto _%s = IceConvert< %s >::FromVariable(%s(ec));\n", - p->name().c_str(), - Slice::typeToString(p->type()).c_str(), - p->name().c_str()); - } - } - fprintf(code, "\t\t\t\t\t\tIceRowState%s(", o->name().c_str()); - BOOST_FOREACH(const auto & p, o->parameters()) { - fprintf(code, "_%s, ", p->name().c_str()); - } - fprintf(code, "ctx))> irs;\n"); - fprintf(code, "\t\t\t\t\t\tirs.IterateOver(service->%s(", o->name().c_str()); - BOOST_FOREACH(const auto & p, o->parameters()) { - fprintf(code, "_%s, ", p->name().c_str()); - } - fprintf(code, "ctx), rp);\n"); + FunctionBegin(o); + fprintf(code, "\t\t\t\t\t\tSlicer::SerializerPtr toRpc = new RowProcSerializer(rp);\n"); + fprintf(code, "\t\t\t\t\t\tauto result = "); + CallOperation(o); + fprintf(code, ";\n"); + fprintf(code, "\t\t\t\t\t\tSlicer::ModelPartPtr mp = new Slicer::ModelPartForSequence(&result);\n"); + fprintf(code, "\t\t\t\t\t\ttoRpc->Serialize(mp);\n"); fprintf(code, "\t\t\t\t\t}\n\n"); - // Parameter variables - BOOST_FOREACH(const auto & p, o->parameters()) { - fprintf(code, "\t\t\t\t\tconst Variable %s;\n", p->name().c_str()); - } + ParameterVariables(o); fprintf(code, "\t\t\t};\n"); - fprintf(code, "\t\t\tDECLARE_LOADER(\"%s-%s-%s\", %s);\n\n", module.c_str(), interface.c_str(), o->name().c_str(), o->name().c_str()); + Declaration(o); } } diff --git a/project2/ice/slice2Rows.h b/project2/ice/slice2Rows.h index b97f009..c85e4b8 100644 --- a/project2/ice/slice2Rows.h +++ b/project2/ice/slice2Rows.h @@ -1,21 +1,17 @@ #ifndef ICEBUILDVIEW_H #define ICEBUILDVIEW_H -#include +#include "slice2Common.h" -class Slice2Rows : public Slice::ParserVisitor { +class Slice2Rows : public Slice2Common { public: Slice2Rows(FILE * c); + virtual bool visitModuleStart(const Slice::ModulePtr & m); virtual bool visitClassDefStart(const Slice::ClassDefPtr & c); virtual void visitOperation(const Slice::OperationPtr & o); virtual void visitClassDefEnd(const Slice::ClassDefPtr & c); virtual void visitModuleEnd(const Slice::ModulePtr & m); - - private: - FILE * code; - std::string interface; - std::string module; }; #endif diff --git a/project2/ice/slice2Task.cpp b/project2/ice/slice2Task.cpp index 54f05a8..1fbacaf 100644 --- a/project2/ice/slice2Task.cpp +++ b/project2/ice/slice2Task.cpp @@ -4,7 +4,7 @@ #include Slice2Task::Slice2Task(FILE * c) : - code(c) + Slice2Common(c) { } @@ -43,38 +43,14 @@ Slice2Task::visitOperation(const Slice::OperationPtr & o) // Execute fprintf(code, "\t\t\t\t\tvoid execute(ExecContext * ec) const\n"); fprintf(code, "\t\t\t\t\t{\n"); - fprintf(code, "\t\t\t\t\t\tLogger()->messagebf(LOG_DEBUG, \"%%s: "); - BOOST_FOREACH(const auto & p, o->parameters()) { - fprintf(code, "%s = %%s, ", p->name().c_str()); - } - fprintf(code, "ice @ %%p\", \n"); - fprintf(code, "\t\t\t\t\t\t\t\t__PRETTY_FUNCTION__, "); - BOOST_FOREACH(const auto & p, o->parameters()) { - fprintf(code, "%s(ec), ", p->name().c_str()); - } - fprintf(code, "ice);\n"); - fprintf(code, "\t\t\t\t\t\tIce::Context ctx;\n"); - fprintf(code, "\t\t\t\t\t\tservice->%s(", o->name().c_str()); - BOOST_FOREACH(const auto & p, o->parameters()) { - if (p->optional()) { - fprintf(code, "IceConvert< ::IceUtil::Optional< %s > >::FromVariable(%s(ec)), ", - Slice::typeToString(p->type()).c_str(), - p->name().c_str()); - } - else { - fprintf(code, "IceConvert< %s >::FromVariable(%s(ec)), ", - Slice::typeToString(p->type()).c_str(), - p->name().c_str()); - } - } - fprintf(code, "ctx);\n"); + FunctionBegin(o); + fprintf(code, "\t\t\t\t\t\t"); + CallOperation(o); + fprintf(code, ";\n"); fprintf(code, "\t\t\t\t\t}\n\n"); - // Parameter variables - BOOST_FOREACH(const auto & p, o->parameters()) { - fprintf(code, "\t\t\t\t\tconst Variable %s;\n", p->name().c_str()); - } + ParameterVariables(o); fprintf(code, "\t\t\t};\n"); - fprintf(code, "\t\t\tDECLARE_LOADER(\"%s-%s-%s\", %s);\n\n", module.c_str(), interface.c_str(), o->name().c_str(), o->name().c_str()); + Declaration(o); } } diff --git a/project2/ice/slice2Task.h b/project2/ice/slice2Task.h index d3bd0fe..20287cb 100644 --- a/project2/ice/slice2Task.h +++ b/project2/ice/slice2Task.h @@ -1,9 +1,9 @@ #ifndef SLICE2TASK_H #define SLICE2TASK_H -#include +#include "slice2Common.h" -class Slice2Task : public Slice::ParserVisitor { +class Slice2Task : public Slice2Common { public: Slice2Task(FILE * c); @@ -12,13 +12,7 @@ class Slice2Task : public Slice::ParserVisitor { virtual void visitOperation(const Slice::OperationPtr & o); virtual void visitClassDefEnd(const Slice::ClassDefPtr & c); virtual void visitModuleEnd(const Slice::ModulePtr & m); - - private: - FILE * code; - std::string interface; - std::string module; }; #endif - diff --git a/project2/ice/slice2Type.cpp b/project2/ice/slice2Type.cpp deleted file mode 100644 index 9c3404e..0000000 --- a/project2/ice/slice2Type.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include "slice2Type.h" -#include -#include - -Slice2Type::Slice2Type(FILE * c) : - code(c) -{ -} - -bool -Slice2Type::visitModuleStart(const Slice::ModulePtr & m) -{ - module = m->name(); - return true; -} - -void -Slice2Type::visitModuleEnd(const Slice::ModulePtr &) -{ - module.clear(); -} - -void -Slice2Type::visitClassDecl(const Slice::ClassDeclPtr&) -{ -} - -bool -Slice2Type::visitExceptionStart(const Slice::ExceptionPtr & e) -{ - if (e->hasMetaData("project2:type")) { - fprintf(code, "template <>\nvoid IceType< %s::%s >::ForEachDataMember(const %s::%s & obj, const IceEachDataMemberValue & func)\n{\n", - module.c_str(), e->name().c_str(), - module.c_str(), e->name().c_str()); - membersToVariables(e->dataMembers(), "obj."); - fprintf(code, "}\n\n"); - - fprintf(code, "template <>\nvoid IceType< %s::%s >::CreateColumns(const IceEachDataMemberName & func)\n{\n", - module.c_str(), e->name().c_str()); - membersToColumns(e->dataMembers()); - fprintf(code, "}\n\n"); - } - return false; -} - -bool -Slice2Type::visitClassDefStart(const Slice::ClassDefPtr & c) -{ - if (c->hasMetaData("project2:type")) { - fprintf(code, "template <>\nvoid IceType< IceInternal::Handle< %s::%s > >::ForEachDataMember(const IceInternal::Handle< %s::%s > & ptr, const IceEachDataMemberValue & func)\n{\n", - module.c_str(), c->name().c_str(), - module.c_str(), c->name().c_str()); - membersToVariables(c->dataMembers(), "ptr->"); - fprintf(code, "}\n\n"); - - fprintf(code, "template <>\nvoid IceType< IceInternal::Handle< %s::%s > >::CreateColumns(const IceEachDataMemberName & func)\n{\n", - module.c_str(), c->name().c_str()); - membersToColumns(c->dataMembers()); - fprintf(code, "}\n\n"); - } - return false; -} - -bool -Slice2Type::visitStructStart(const Slice::StructPtr & s) -{ - if (s->hasMetaData("project2:type")) { - fprintf(code, "template <>\nvoid IceType< %s::%s >::ForEachDataMember(const %s::%s & obj, const IceEachDataMemberValue & func)\n{\n", - module.c_str(), s->name().c_str(), - module.c_str(), s->name().c_str()); - membersToVariables(s->dataMembers(), "obj."); - fprintf(code, "}\n\n"); - - fprintf(code, "template <>\nvoid IceType< %s::%s >::CreateColumns(const IceEachDataMemberName & func)\n{\n", - module.c_str(), s->name().c_str()); - membersToColumns(s->dataMembers()); - fprintf(code, "}\n\n"); - } - return false; -} - -void -Slice2Type::membersToVariables(const Slice::DataMemberList & members, const std::string & access) const -{ - BOOST_FOREACH(const auto & m, members) { - if (m->optional()) { - fprintf(code, "\tfunc(IceConvert< IceUtil::Optional< %s> >::ToVariable(%s%s));\n", - Slice::typeToString(m->type()).c_str(), - access.c_str(), - m->name().c_str()); - } - else { - fprintf(code, "\tfunc(IceConvert< %s >::ToVariable(%s%s));\n", - Slice::typeToString(m->type()).c_str(), - access.c_str(), - m->name().c_str()); - } - } -} - -void -Slice2Type::membersToColumns(const Slice::DataMemberList & members) const -{ - BOOST_FOREACH(const auto & m, members) { - fprintf(code, "\tfunc(\"%s\");\n", - m->name().c_str()); - } -} - diff --git a/project2/ice/slice2Type.h b/project2/ice/slice2Type.h deleted file mode 100644 index e2b94fc..0000000 --- a/project2/ice/slice2Type.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef ICEBUILDPRESENTER_H -#define ICEBUILDPRESENTER_H - -#include - -class Slice2Type : public Slice::ParserVisitor { - public: - Slice2Type(FILE * c); - virtual bool visitModuleStart(const Slice::ModulePtr & m); - virtual void visitModuleEnd(const Slice::ModulePtr & m); - virtual void visitClassDecl(const Slice::ClassDeclPtr&); - virtual bool visitExceptionStart(const Slice::ExceptionPtr&); - virtual bool visitClassDefStart(const Slice::ClassDefPtr&); - virtual bool visitStructStart(const Slice::StructPtr&); - - private: - void membersToVariables(const Slice::DataMemberList &, const std::string &) const; - void membersToColumns(const Slice::DataMemberList &) const; - FILE * code; - std::string module; -}; - -#endif - - diff --git a/project2/ice/unittests/Jamfile.jam b/project2/ice/unittests/Jamfile.jam index 4c75205..5ae9e28 100644 --- a/project2/ice/unittests/Jamfile.jam +++ b/project2/ice/unittests/Jamfile.jam @@ -3,11 +3,24 @@ import testing ; lib unittest : unittest.ice : + no ..//Ice ..//IceUtil ..//pthread ; +lib unittestr : + unittest.ice + : + yes + ..//Ice + ..//slicer + ..//IceUtil + ..//pthread + : : + . + ; + path-constant me : . ; unit-test testClientCompile : @@ -15,8 +28,44 @@ unit-test testClientCompile : : ROOT=\"$(me)\" unittest.ice + unittest + unittestr + ..//p2iceclient + ../../ut//p2ut + ../../xml//p2xml + ../../basics//p2basics + ..//Ice + ..//IceUtil + ..//boost_filesystem + testClient.xml + ; + +unit-test testClient : + [ glob testClient.cpp ] + : + ROOT=\"$(me)\" + unittest.ice + unittestr + unittestr ..//p2iceclient ../../ut//p2ut + ../../xml//p2xml + ../../basics//p2basics + ..//Ice + ..//IceUtil + ..//boost_filesystem + testClient.xml + ; + +unit-test testDaemonCompile : + [ glob testDaemonCompile.cpp ] + : + ROOT=\"$(me)\" + unittest.ice + unittest + unittestr + ..//p2icedaemon + ../../ut//p2ut ../../basics//p2basics ..//Ice ..//IceUtil diff --git a/project2/ice/unittests/testClient.cpp b/project2/ice/unittests/testClient.cpp new file mode 100644 index 0000000..ee87f1b --- /dev/null +++ b/project2/ice/unittests/testClient.cpp @@ -0,0 +1,114 @@ +#define BOOST_TEST_MODULE Client +#include +#include +#include "iceClient.h" +#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 boost::filesystem::path iceroot(XSTR(ROOT)); +const auto headers = iceroot.parent_path().parent_path(); + +class Dummy : public UnitTest::SimpleInterface { + public: + Dummy() : + execCount(0) + { + } + + UnitTest::Simples SomeRows(const Ice::Current&) + { + UnitTest::Simples rtn; + execCount += 1; + return rtn; + } + + UnitTest::Simples SomeRowsParams(Ice::Int, const std::string&, const Ice::Current&) + { + UnitTest::Simples rtn; + execCount += 1; + return rtn; + } + + void SomeTask(const Ice::Current&) + { + execCount += 1; + } + + void SomeTaskParams(Ice::Int, const std::string&, const Ice::Current&) + { + execCount += 1; + } + + unsigned int execCount; +}; + + +static +void +commonTests() +{ + BOOST_TEST_CHECKPOINT("Verify loaded"); + BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTask")); + BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTaskParams")); + BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRows")); + BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRowsParams")); + + BOOST_TEST_CHECKPOINT("Load test script"); + ScriptReaderPtr r = new XmlScriptParser(iceroot / "testClient.xml"); + + BOOST_TEST_CHECKPOINT("Initialize ICE service"); + int paramCount = 0; + Ice::CommunicatorPtr ic = Ice::initialize(paramCount, NULL); + auto adapter = ic->createObjectAdapterWithEndpoints("Adp", "tcp -p 12000"); + IceUtil::Handle dummy = new Dummy(); + adapter->add(dummy, ic->stringToIdentity("testObject")); + adapter->activate(); + ScopeObject _([&ic]{ ic->destroy(); }); + + BOOST_TEST_CHECKPOINT("Execute test script"); + boost::intrusive_ptr sr = new TestScriptHost(r); + BOOST_REQUIRE_EQUAL(dummy->execCount, 0); + sr->process(NULL); + BOOST_REQUIRE_EQUAL(dummy->execCount, 4); +} + +static +void +unloadTests() +{ + BOOST_TEST_CHECKPOINT("Verify unloaded"); + BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTask"), NotSupported); + BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTaskParams"), NotSupported); + BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRows"), NotSupported); + BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRowsParams"), NotSupported); +} + +BOOST_AUTO_TEST_CASE( compile_client_clientOnlySlicer ) +{ + const std::string tmpdir = "/tmp/ut/project2.slice/clientOnlySlicer"; + BOOST_TEST_CHECKPOINT("Clean up"); + boost::filesystem::remove_all(tmpdir); + + BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); + TestOptionsSource::LoadTestOptions({ + { "library", (bindir / "slicer-yes" / "libunittestr.so").string() }, + { "common.datasourceRoot", iceroot.string() }, + { "ice.compile.tmpdir", tmpdir }, + { "ice.compile.headers", headers.string() }, + { "ice.client.slicerclient", (iceroot / "unittest.ice").string() } + }); + commonTests(); + + TestOptionsSource::LoadTestOptions({ }); + unloadTests(); +} + diff --git a/project2/ice/unittests/testClient.xml b/project2/ice/unittests/testClient.xml new file mode 100644 index 0000000..4ae33b1 --- /dev/null +++ b/project2/ice/unittests/testClient.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/project2/ice/unittests/testClientCompile.cpp b/project2/ice/unittests/testClientCompile.cpp index 4ae32d0..9e75d1b 100644 --- a/project2/ice/unittests/testClientCompile.cpp +++ b/project2/ice/unittests/testClientCompile.cpp @@ -3,32 +3,102 @@ #include #include "iceClient.h" #include +#include +#include +#include +#include +#include +#include #define XSTR(s) STR(s) #define STR(s) #s -const auto self = boost::filesystem::canonical("/proc/self/exe"); +const auto bindir = boost::filesystem::canonical("/proc/self/exe").parent_path(); const boost::filesystem::path iceroot(XSTR(ROOT)); +const auto headers = iceroot.parent_path().parent_path(); + +static +void +commonTests() +{ + BOOST_TEST_CHECKPOINT("Verify loaded"); + BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTask")); + BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTaskParams")); + BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRows")); + BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRowsParams")); + + BOOST_TEST_CHECKPOINT("Load test script"); + ScriptReaderPtr r = new XmlScriptParser(iceroot / "testClient.xml"); + BOOST_TEST_CHECKPOINT("Execute test script"); + boost::intrusive_ptr sr = new TestScriptHost(r); +} + +static +void +unloadTests() +{ + BOOST_TEST_CHECKPOINT("Verify unloaded"); + BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTask"), NotSupported); + BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTaskParams"), NotSupported); + BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRows"), NotSupported); + BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRowsParams"), NotSupported); +} BOOST_AUTO_TEST_CASE( compile_client_full ) { const std::string tmpdir = "/tmp/ut/project2.slice/full"; + BOOST_TEST_CHECKPOINT("Clean up"); boost::filesystem::remove_all(tmpdir); + BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); TestOptionsSource::LoadTestOptions({ + { "common.datasourceRoot", iceroot.string() }, { "ice.compile.tmpdir", tmpdir }, + { "ice.compile.headers", headers.string() }, { "ice.client.slice", (iceroot / "unittest.ice").string() } }); + commonTests(); + + TestOptionsSource::LoadTestOptions({ }); + unloadTests(); } BOOST_AUTO_TEST_CASE( compile_client_clientOnly ) { const std::string tmpdir = "/tmp/ut/project2.slice/clientOnly"; + BOOST_TEST_CHECKPOINT("Clean up"); boost::filesystem::remove_all(tmpdir); + BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); TestOptionsSource::LoadTestOptions({ - { "library", (self.parent_path() / "libunittest.so").string() }, + { "library", (bindir / "libunittest.so").string() }, + { "common.datasourceRoot", iceroot.string() }, { "ice.compile.tmpdir", tmpdir }, + { "ice.compile.headers", headers.string() }, { "ice.client.sliceclient", (iceroot / "unittest.ice").string() } }); + commonTests(); + + TestOptionsSource::LoadTestOptions({ }); + unloadTests(); +} + +BOOST_AUTO_TEST_CASE( compile_client_clientOnlySlicer ) +{ + const std::string tmpdir = "/tmp/ut/project2.slice/clientOnlySlicer"; + BOOST_TEST_CHECKPOINT("Clean up"); + boost::filesystem::remove_all(tmpdir); + + BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); + TestOptionsSource::LoadTestOptions({ + { "library", (bindir / "slicer-yes" / "libunittestr.so").string() }, + { "common.datasourceRoot", iceroot.string() }, + { "ice.compile.tmpdir", tmpdir }, + { "ice.compile.headers", headers.string() }, + { "ice.client.slicerclient", (iceroot / "unittest.ice").string() } + }); + commonTests(); + + TestOptionsSource::LoadTestOptions({ }); + unloadTests(); } diff --git a/project2/ice/unittests/testDaemonCompile.cpp b/project2/ice/unittests/testDaemonCompile.cpp new file mode 100644 index 0000000..b92159b --- /dev/null +++ b/project2/ice/unittests/testDaemonCompile.cpp @@ -0,0 +1,80 @@ +#define BOOST_TEST_MODULE Daemon +#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 boost::filesystem::path iceroot(XSTR(ROOT)); +const auto headers = iceroot.parent_path().parent_path(); + +static +void +commonTests() +{ +} + +static +void +unloadTests() +{ +} + +BOOST_AUTO_TEST_CASE( compile_daemon_full ) +{ + const std::string tmpdir = "/tmp/ut/project2.sliced/full"; + BOOST_TEST_CHECKPOINT("Clean up"); + boost::filesystem::remove_all(tmpdir); + + BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); + TestOptionsSource::LoadTestOptions({ + { "ice.compile.tmpdir", tmpdir }, + { "ice.compile.headers", headers.string() }, + { "ice.daemon.slice", (iceroot / "unittest.ice").string() } + }); + commonTests(); + + TestOptionsSource::LoadTestOptions({ }); + unloadTests(); +} + +BOOST_AUTO_TEST_CASE( compile_daemon_clientOnly ) +{ + const std::string tmpdir = "/tmp/ut/project2.sliced/daemonOnly"; + BOOST_TEST_CHECKPOINT("Clean up"); + boost::filesystem::remove_all(tmpdir); + + BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); + TestOptionsSource::LoadTestOptions({ + { "library", (bindir / "libunittest.so").string() }, + { "ice.compile.tmpdir", tmpdir }, + { "ice.compile.headers", headers.string() }, + { "ice.daemon.slicedaemon", (iceroot / "unittest.ice").string() } + }); + commonTests(); + + TestOptionsSource::LoadTestOptions({ }); + unloadTests(); +} + +BOOST_AUTO_TEST_CASE( compile_daemon_clientOnlySlicer ) +{ + const std::string tmpdir = "/tmp/ut/project2.sliced/clientOnlySlicer"; + BOOST_TEST_CHECKPOINT("Clean up"); + boost::filesystem::remove_all(tmpdir); + + BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); + TestOptionsSource::LoadTestOptions({ + { "library", (bindir / "slicer-yes" / "libunittestr.so").string() }, + { "ice.compile.tmpdir", tmpdir }, + { "ice.compile.headers", headers.string() }, + { "ice.daemon.slicerdaemon", (iceroot / "unittest.ice").string() } + }); + commonTests(); + + TestOptionsSource::LoadTestOptions({ }); + unloadTests(); +} + diff --git a/project2/ice/unittests/unittest-ice-datasource.xml b/project2/ice/unittests/unittest-ice-datasource.xml new file mode 100644 index 0000000..0d067d9 --- /dev/null +++ b/project2/ice/unittests/unittest-ice-datasource.xml @@ -0,0 +1,4 @@ + + + tcp -p 12000 + diff --git a/project2/ice/unittests/unittest.ice b/project2/ice/unittests/unittest.ice index 3c18999..60e44bb 100644 --- a/project2/ice/unittests/unittest.ice +++ b/project2/ice/unittests/unittest.ice @@ -1,9 +1,22 @@ -module test { - interface a +module UnitTest { + ["project2:type"] + class Simple { + int a; + string b; + }; + + sequence Simples; + + interface SimpleInterface { + ["project2:rows"] + Simples SomeRows(); + ["project2:rows"] + Simples SomeRowsParams(int a, string b); ["project2:task"] - void someTask(); - + void SomeTask(); + ["project2:task"] + void SomeTaskParams(int a, string b); }; }; diff --git a/project2/ut/testScriptHost.cpp b/project2/ut/testScriptHost.cpp new file mode 100644 index 0000000..1161ba6 --- /dev/null +++ b/project2/ut/testScriptHost.cpp @@ -0,0 +1,107 @@ +#include "testScriptHost.h" +#include +#include +#include + +TestScriptHost::TestScriptHost(ScriptReaderPtr script) : + SourceObject(script->root()), + CommonObjects(script->root()), + CheckHost(script->root()), + TaskHost(script->root()), + ViewHost(script->root()), + MultiRowSetPresenter(Default) +{ + Logger()->message(LOG_DEBUG, __PRETTY_FUNCTION__); +} + +TestScriptHost::~TestScriptHost() +{ + Logger()->message(LOG_DEBUG, __PRETTY_FUNCTION__); +} + +MultiRowSetPresenterPtr TestScriptHost::getPresenter(ExecContext *) const +{ + return const_cast(this); +} + +void TestScriptHost::process(ExecContext * ec) +{ + Logger()->messagef(LOG_DEBUG, "> %s", __PRETTY_FUNCTION__); + try { + runChecks(ec); + execute(ec); + executeViews(ec); + } + catch (const std::exception & e) { + char * buf = __cxxabiv1::__cxa_demangle(typeid(e).name(), NULL, NULL, NULL); + Logger()->messagef(LOG_ERR, "%s: Script errored: %s: %s", __FUNCTION__, buf, e.what()); + free(buf); + throw; + } + catch (const Glib::Exception & e) { + char * buf = __cxxabiv1::__cxa_demangle(typeid(e).name(), NULL, NULL, NULL); + Logger()->messagebf(LOG_ERR, "%s: Script errored: %s: %s", __FUNCTION__, buf, e.what()); + free(buf); + throw; + } + catch (...) { + Logger()->messagebf(LOG_ERR, "%s: Script errored (nobody knows why!)", __FUNCTION__); + throw; + } + Logger()->messagef(LOG_DEBUG, "< %s", __PRETTY_FUNCTION__); +} + +void +TestScriptHost::addNamedValue(const Glib::ustring & name, const VariableType & value) const +{ + (void)name; + (void)value; +} + +void +TestScriptHost::addNewRow(const Glib::ustring & name) const +{ + (void)name; +} + +void +TestScriptHost::finishRow() const +{ +} + +void +TestScriptHost::addNewRowSet(const Glib::ustring & name) const +{ + (void)name; +} + +void +TestScriptHost::addNewRowSet(const Glib::ustring & name, const Glib::ustring & ns) const +{ + (void)name; + (void)ns; +} + +void +TestScriptHost::finishRowSet() const +{ +} + +void +TestScriptHost::addNewArray(const Glib::ustring & name, bool objects) const +{ + (void)name; + (void)objects; +} + +void +TestScriptHost::finishArray(bool objects) const +{ + (void)objects; +} + +void +TestScriptHost::init(ExecContext *) +{ +} + diff --git a/project2/ut/testScriptHost.h b/project2/ut/testScriptHost.h new file mode 100644 index 0000000..43dcd90 --- /dev/null +++ b/project2/ut/testScriptHost.h @@ -0,0 +1,29 @@ +#ifndef TESTSCRIPTHOST_H +#define TESTSCRIPTHOST_H + +#include +#include +#include + +class TestScriptHost : public TaskHost, public ViewHost, public MultiRowSetPresenter { + public: + TestScriptHost(ScriptReaderPtr script); + ~TestScriptHost(); + + MultiRowSetPresenterPtr getPresenter(ExecContext *) const override; + + void process(ExecContext * ec); + void addNamedValue(const Glib::ustring & name, const VariableType & value) const override; + void addNewRow(const Glib::ustring & name) const override; + void finishRow() const override; + void addNewRowSet(const Glib::ustring & name) const override; + void addNewRowSet(const Glib::ustring & name, const Glib::ustring & ns) const override; + void finishRowSet() const override; + void addNewArray(const Glib::ustring & name, bool objects) const override; + void finishArray(bool objects) const override; + void init(ExecContext *) override; +}; + + +#endif + -- cgit v1.2.3 From cbc65388e19ab91584f9548dd7ffc55aea456223 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 25 Nov 2014 23:13:05 +0000 Subject: Add assertions that the correct data is passed to the presenter --- .../ice/unittests/expected/clientPresenter.log | 29 ++++++++ project2/ice/unittests/testClient.cpp | 14 +++- project2/ut/testScriptHost.cpp | 87 ++++++++++++++-------- project2/ut/testScriptHost.h | 13 ++++ 4 files changed, 108 insertions(+), 35 deletions(-) create mode 100644 project2/ice/unittests/expected/clientPresenter.log diff --git a/project2/ice/unittests/expected/clientPresenter.log b/project2/ice/unittests/expected/clientPresenter.log new file mode 100644 index 0000000..cda61fc --- /dev/null +++ b/project2/ice/unittests/expected/clientPresenter.log @@ -0,0 +1,29 @@ +init +addNewRowSet: somerows +addNewArray: rec(1) +addNewRow: rec +addNamedValue: a=1 +addNamedValue: b=test a +finishRow +addNewRow: rec +addNamedValue: a=2 +addNamedValue: b=test b +finishRow +finishArray: (1) +finishRowSet +addNewRowSet: somerowsparams +addNewArray: rec(1) +addNewRow: rec +addNamedValue: a=0 +addNamedValue: b=before +finishRow +addNewRow: rec +addNamedValue: a=2 +addNamedValue: b=second +finishRow +addNewRow: rec +addNamedValue: a=2 +addNamedValue: b=after +finishRow +finishArray: (1) +finishRowSet diff --git a/project2/ice/unittests/testClient.cpp b/project2/ice/unittests/testClient.cpp index ee87f1b..bade1b2 100644 --- a/project2/ice/unittests/testClient.cpp +++ b/project2/ice/unittests/testClient.cpp @@ -26,14 +26,21 @@ class Dummy : public UnitTest::SimpleInterface { UnitTest::Simples SomeRows(const Ice::Current&) { - UnitTest::Simples rtn; + UnitTest::Simples rtn { + new UnitTest::Simple { 1, "test a" }, + new UnitTest::Simple { 2, "test b" } + }; execCount += 1; return rtn; } - UnitTest::Simples SomeRowsParams(Ice::Int, const std::string&, const Ice::Current&) + UnitTest::Simples SomeRowsParams(Ice::Int pi, const std::string & ps, const Ice::Current&) { - UnitTest::Simples rtn; + UnitTest::Simples rtn { + new UnitTest::Simple { 0, "before" }, + new UnitTest::Simple { pi, ps }, + new UnitTest::Simple { 2, "after" } + }; execCount += 1; return rtn; } @@ -79,6 +86,7 @@ commonTests() BOOST_REQUIRE_EQUAL(dummy->execCount, 0); sr->process(NULL); BOOST_REQUIRE_EQUAL(dummy->execCount, 4); + BOOST_REQUIRE_EQUAL(sr->GetPresenterData(), iceroot / "expected" / "clientPresenter.log"); } static diff --git a/project2/ut/testScriptHost.cpp b/project2/ut/testScriptHost.cpp index 1161ba6..dfdb6ed 100644 --- a/project2/ut/testScriptHost.cpp +++ b/project2/ut/testScriptHost.cpp @@ -2,6 +2,7 @@ #include #include #include +#include TestScriptHost::TestScriptHost(ScriptReaderPtr script) : SourceObject(script->root()), @@ -26,82 +27,104 @@ MultiRowSetPresenterPtr TestScriptHost::getPresenter(ExecContext *) const void TestScriptHost::process(ExecContext * ec) { - Logger()->messagef(LOG_DEBUG, "> %s", __PRETTY_FUNCTION__); - try { - runChecks(ec); - execute(ec); - executeViews(ec); - } - catch (const std::exception & e) { - char * buf = __cxxabiv1::__cxa_demangle(typeid(e).name(), NULL, NULL, NULL); - Logger()->messagef(LOG_ERR, "%s: Script errored: %s: %s", __FUNCTION__, buf, e.what()); - free(buf); - throw; - } - catch (const Glib::Exception & e) { - char * buf = __cxxabiv1::__cxa_demangle(typeid(e).name(), NULL, NULL, NULL); - Logger()->messagebf(LOG_ERR, "%s: Script errored: %s: %s", __FUNCTION__, buf, e.what()); - free(buf); - throw; - } - catch (...) { - Logger()->messagebf(LOG_ERR, "%s: Script errored (nobody knows why!)", __FUNCTION__); - throw; - } - Logger()->messagef(LOG_DEBUG, "< %s", __PRETTY_FUNCTION__); + runChecks(ec); + execute(ec); + executeViews(ec); } void TestScriptHost::addNamedValue(const Glib::ustring & name, const VariableType & value) const { - (void)name; - (void)value; + presenterData.push_back(stringbf("%s: %s=%s", __FUNCTION__, name, value)); } void TestScriptHost::addNewRow(const Glib::ustring & name) const { - (void)name; + presenterData.push_back(stringbf("%s: %s", __FUNCTION__, name)); } void TestScriptHost::finishRow() const { + presenterData.push_back(stringbf("%s", __FUNCTION__)); } void TestScriptHost::addNewRowSet(const Glib::ustring & name) const { - (void)name; + presenterData.push_back(stringbf("%s: %s", __FUNCTION__, name)); } void TestScriptHost::addNewRowSet(const Glib::ustring & name, const Glib::ustring & ns) const { - (void)name; - (void)ns; + presenterData.push_back(stringbf("%s: %s:%s", __FUNCTION__, ns, name)); } void TestScriptHost::finishRowSet() const { + presenterData.push_back(stringbf("%s", __FUNCTION__)); } void TestScriptHost::addNewArray(const Glib::ustring & name, bool objects) const { - (void)name; - (void)objects; + presenterData.push_back(stringbf("%s: %s(%s)", __FUNCTION__, name, objects)); } void TestScriptHost::finishArray(bool objects) const { - (void)objects; + presenterData.push_back(stringbf("%s: (%s)", __FUNCTION__, objects)); } void TestScriptHost::init(ExecContext *) { + presenterData.push_back(stringbf("%s", __FUNCTION__)); +} + +const PresenterData & +TestScriptHost::GetPresenterData() const +{ + return presenterData; +} + +namespace std { + std::istream & + operator>>(std::istream & s, PresenterData & v) + { + while (true) { + char buf[BUFSIZ]; + s.getline(buf, sizeof(buf)); + if (!s.eof()) { + v.push_back(buf); + } + else { + break; + } + } + return s; + } + + std::ostream & + operator<<(std::ostream & s, const PresenterData & v) + { + BOOST_FOREACH(const auto & e, v) { + s << "[" << e << "]" << std::endl; + } + return s; + } + + bool + operator==(const PresenterData & left, const boost::filesystem::path & rightPath) + { + PresenterData right; + fstream strm(rightPath.string()); + strm >> right; + return (left == right); + } } diff --git a/project2/ut/testScriptHost.h b/project2/ut/testScriptHost.h index 43dcd90..a843a4a 100644 --- a/project2/ut/testScriptHost.h +++ b/project2/ut/testScriptHost.h @@ -4,6 +4,9 @@ #include #include #include +#include + +typedef std::vector PresenterData; class TestScriptHost : public TaskHost, public ViewHost, public MultiRowSetPresenter { public: @@ -22,8 +25,18 @@ class TestScriptHost : public TaskHost, public ViewHost, public MultiRowSetPrese void addNewArray(const Glib::ustring & name, bool objects) const override; void finishArray(bool objects) const override; void init(ExecContext *) override; + + const PresenterData & GetPresenterData() const; + + private: + mutable PresenterData presenterData; }; +namespace std { + bool operator==(const PresenterData &, const boost::filesystem::path &); + std::ostream & operator<<(std::ostream & s, const PresenterData & v); + std::istream & operator>>(std::istream & s, PresenterData & v); +} #endif -- cgit v1.2.3 From 7dbfe09c29254f0532234c4b19c33544d4e479ce Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 26 Nov 2014 21:06:25 +0000 Subject: Sorts out unique paths for tests, fixes test names, adds basics of daemon test --- project2/ice/Jamfile.jam | 1 + project2/ice/unittests/Jamfile.jam | 20 ++++++++++++ project2/ice/unittests/testClient.cpp | 4 +-- project2/ice/unittests/testClientCompile.cpp | 10 +++--- project2/ice/unittests/testDaemon.cpp | 48 ++++++++++++++++++++++++++++ project2/ice/unittests/testDaemonCompile.cpp | 15 +++++---- 6 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 project2/ice/unittests/testDaemon.cpp diff --git a/project2/ice/Jamfile.jam b/project2/ice/Jamfile.jam index 1f418af..2a531cb 100644 --- a/project2/ice/Jamfile.jam +++ b/project2/ice/Jamfile.jam @@ -59,6 +59,7 @@ lib p2icedaemon : : : ../daemon/lib//p2daemonlib p2ice + . ; lib p2ice : diff --git a/project2/ice/unittests/Jamfile.jam b/project2/ice/unittests/Jamfile.jam index 5ae9e28..a793918 100644 --- a/project2/ice/unittests/Jamfile.jam +++ b/project2/ice/unittests/Jamfile.jam @@ -72,3 +72,23 @@ unit-test testDaemonCompile : ..//boost_filesystem ; +unit-test testDaemon : + [ glob testDaemon.cpp ] + : + ROOT=\"$(me)\" + unittest.ice + unittestr + unittestr + ..//p2icedaemon + ../../ut//p2ut + ../../xml//p2xml + ../../basics//p2basics + ..//Ice + ..//IceUtil + ..//boost_filesystem +#testDaemon/task.xml +#testDaemon/taskParams.xml +#testDaemon/view.xml +#testDaemon/viewParams.xml + ; + diff --git a/project2/ice/unittests/testClient.cpp b/project2/ice/unittests/testClient.cpp index bade1b2..e5d45b7 100644 --- a/project2/ice/unittests/testClient.cpp +++ b/project2/ice/unittests/testClient.cpp @@ -100,9 +100,9 @@ unloadTests() BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRowsParams"), NotSupported); } -BOOST_AUTO_TEST_CASE( compile_client_clientOnlySlicer ) +BOOST_AUTO_TEST_CASE( test_client ) { - const std::string tmpdir = "/tmp/ut/project2.slice/clientOnlySlicer"; + const std::string tmpdir = "/tmp/ut/project2.slice-client"; BOOST_TEST_CHECKPOINT("Clean up"); boost::filesystem::remove_all(tmpdir); diff --git a/project2/ice/unittests/testClientCompile.cpp b/project2/ice/unittests/testClientCompile.cpp index 9e75d1b..c86b826 100644 --- a/project2/ice/unittests/testClientCompile.cpp +++ b/project2/ice/unittests/testClientCompile.cpp @@ -1,4 +1,4 @@ -#define BOOST_TEST_MODULE Client +#define BOOST_TEST_MODULE ClientCompile #include #include #include "iceClient.h" @@ -45,7 +45,7 @@ unloadTests() BOOST_AUTO_TEST_CASE( compile_client_full ) { - const std::string tmpdir = "/tmp/ut/project2.slice/full"; + const std::string tmpdir = "/tmp/ut/project2.slice-clientCompile/full"; BOOST_TEST_CHECKPOINT("Clean up"); boost::filesystem::remove_all(tmpdir); @@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE( compile_client_full ) BOOST_AUTO_TEST_CASE( compile_client_clientOnly ) { - const std::string tmpdir = "/tmp/ut/project2.slice/clientOnly"; + const std::string tmpdir = "/tmp/ut/project2.slice-clientCompile/clientOnly"; BOOST_TEST_CHECKPOINT("Clean up"); boost::filesystem::remove_all(tmpdir); @@ -82,9 +82,9 @@ BOOST_AUTO_TEST_CASE( compile_client_clientOnly ) unloadTests(); } -BOOST_AUTO_TEST_CASE( compile_client_clientOnlySlicer ) +BOOST_AUTO_TEST_CASE( compile_client_slicer ) { - const std::string tmpdir = "/tmp/ut/project2.slice/clientOnlySlicer"; + const std::string tmpdir = "/tmp/ut/project2.slice-clientCompile/slicer"; BOOST_TEST_CHECKPOINT("Clean up"); boost::filesystem::remove_all(tmpdir); diff --git a/project2/ice/unittests/testDaemon.cpp b/project2/ice/unittests/testDaemon.cpp new file mode 100644 index 0000000..ce2630c --- /dev/null +++ b/project2/ice/unittests/testDaemon.cpp @@ -0,0 +1,48 @@ +#define BOOST_TEST_MODULE Daemon +#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 boost::filesystem::path iceroot(XSTR(ROOT)); +const auto headers = iceroot.parent_path().parent_path(); + +static +void +commonTests() +{ + BOOST_TEST_CHECKPOINT("Verify loaded"); + BOOST_REQUIRE(IceDaemonAdapterHandlerLoader::getFor("UnitTest")); +} + +static +void +unloadTests() +{ + BOOST_TEST_CHECKPOINT("Verify unloaded"); + BOOST_REQUIRE_THROW(IceDaemonAdapterHandlerLoader::createNew("UnitTest"), NotSupported); +} + +BOOST_AUTO_TEST_CASE( test_daemon ) +{ + const std::string tmpdir = "/tmp/ut/project2.slice-daemon"; + BOOST_TEST_CHECKPOINT("Clean up"); + boost::filesystem::remove_all(tmpdir); + + BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); + TestOptionsSource::LoadTestOptions({ + { "library", (bindir / "slicer-yes" / "libunittestr.so").string() }, + { "ice.compile.tmpdir", tmpdir }, + { "ice.compile.headers", headers.string() }, + { "ice.daemon.slicerdaemon", (iceroot / "unittest.ice").string() } + }); + commonTests(); + + TestOptionsSource::LoadTestOptions({ }); + unloadTests(); +} + diff --git a/project2/ice/unittests/testDaemonCompile.cpp b/project2/ice/unittests/testDaemonCompile.cpp index b92159b..7bda6dd 100644 --- a/project2/ice/unittests/testDaemonCompile.cpp +++ b/project2/ice/unittests/testDaemonCompile.cpp @@ -1,8 +1,9 @@ -#define BOOST_TEST_MODULE Daemon +#define BOOST_TEST_MODULE DaemonCompile #include #include #include #include +#include #define XSTR(s) STR(s) #define STR(s) #s @@ -14,17 +15,19 @@ static void commonTests() { + BOOST_REQUIRE(IceDaemonAdapterHandlerLoader::getFor("UnitTest")); } static void unloadTests() { + BOOST_REQUIRE_THROW(IceDaemonAdapterHandlerLoader::createNew("UnitTest"), NotSupported); } BOOST_AUTO_TEST_CASE( compile_daemon_full ) { - const std::string tmpdir = "/tmp/ut/project2.sliced/full"; + const std::string tmpdir = "/tmp/ut/project2.slice-daemonCompile/full"; BOOST_TEST_CHECKPOINT("Clean up"); boost::filesystem::remove_all(tmpdir); @@ -40,9 +43,9 @@ BOOST_AUTO_TEST_CASE( compile_daemon_full ) unloadTests(); } -BOOST_AUTO_TEST_CASE( compile_daemon_clientOnly ) +BOOST_AUTO_TEST_CASE( compile_daemon_daemonOnly ) { - const std::string tmpdir = "/tmp/ut/project2.sliced/daemonOnly"; + const std::string tmpdir = "/tmp/ut/project2.slice-daemonCompile/daemonOnly"; BOOST_TEST_CHECKPOINT("Clean up"); boost::filesystem::remove_all(tmpdir); @@ -59,9 +62,9 @@ BOOST_AUTO_TEST_CASE( compile_daemon_clientOnly ) unloadTests(); } -BOOST_AUTO_TEST_CASE( compile_daemon_clientOnlySlicer ) +BOOST_AUTO_TEST_CASE( compile_daemon_slicer ) { - const std::string tmpdir = "/tmp/ut/project2.sliced/clientOnlySlicer"; + const std::string tmpdir = "/tmp/ut/project2.slice-daemonCompile/slicer"; BOOST_TEST_CHECKPOINT("Clean up"); boost::filesystem::remove_all(tmpdir); -- cgit v1.2.3 From 1d5bf41b6ecad150d76a98e6138b796c91f542df Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 29 Nov 2014 01:38:17 +0000 Subject: Unit tests for daemon and fixes for highlighted issues --- project2/ice/iceDaemon.cpp | 26 +++-- project2/ice/iceViewSerializer.cpp | 15 ++- project2/ice/unittests/Jamfile.jam | 14 ++- project2/ice/unittests/data/unittest-data.xml | 19 ++++ project2/ice/unittests/lib/testrows.xml | 19 ++++ .../tasks/UnitTest/SimpleInterface/SomeTask.xml | 4 + .../UnitTest/SimpleInterface/SomeTaskParams.xml | 7 ++ project2/ice/unittests/testDaemon.cpp | 108 +++++++++++++++++++++ .../views/UnitTest/SimpleInterface/SomeRows.xml | 5 + .../UnitTest/SimpleInterface/SomeRowsParams.xml | 5 + 10 files changed, 206 insertions(+), 16 deletions(-) create mode 100644 project2/ice/unittests/data/unittest-data.xml create mode 100644 project2/ice/unittests/lib/testrows.xml create mode 100644 project2/ice/unittests/tasks/UnitTest/SimpleInterface/SomeTask.xml create mode 100644 project2/ice/unittests/tasks/UnitTest/SimpleInterface/SomeTaskParams.xml create mode 100644 project2/ice/unittests/views/UnitTest/SimpleInterface/SomeRows.xml create mode 100644 project2/ice/unittests/views/UnitTest/SimpleInterface/SomeRowsParams.xml diff --git a/project2/ice/iceDaemon.cpp b/project2/ice/iceDaemon.cpp index a8fb8c2..7f506d4 100644 --- a/project2/ice/iceDaemon.cpp +++ b/project2/ice/iceDaemon.cpp @@ -68,23 +68,24 @@ IceDaemon::shutdown() const void IceDaemon::run() const { - Logger()->messagebf(LOG_INFO, " %s starting...", __PRETTY_FUNCTION__); + Logger()->messagebf(LOG_DEBUG, " %s creating adapter %s [%s]...", __PRETTY_FUNCTION__, adapterName, adapterEndpoint); Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithEndpoints(adapterName, adapterEndpoint); + + Logger()->messagebf(LOG_DEBUG, " %s installing servants...", __PRETTY_FUNCTION__); std::set interfaces; InstanceSet::OnAll([this, adapter, &interfaces](IceDaemonAdapterHandlerLoader * loader) { IceDaemonAdapterHandlerPtr interfacePtr = loader->create(); interfacePtr->add(adapter, this, ic); interfaces.insert(interfacePtr); }); + + Logger()->messagebf(LOG_DEBUG, " %s starting...", __PRETTY_FUNCTION__); adapter->activate(); + Logger()->messagebf(LOG_INFO, " %s running...", __PRETTY_FUNCTION__); - BOOST_FOREACH(const auto & interfacePtr, interfaces) { - interfacePtr->remove(adapter, ic); - } ic->waitForShutdown(); - Logger()->messagebf(LOG_INFO, " %s stopped...", __PRETTY_FUNCTION__); - Logger()->messagebf(LOG_INFO, "<<< %s", __PRETTY_FUNCTION__); + Logger()->messagebf(LOG_INFO, " %s stopped", __PRETTY_FUNCTION__); } class IceDaemonViewHost : public virtual CommonObjects, public virtual CheckHost { @@ -98,7 +99,9 @@ class IceDaemonViewHost : public virtual CommonObjects, public virtual CheckHost void executeView(RowSetPresenterPtr presenter, ExecContext * ec) const { loadScriptComponents(); + Logger()->messagebf(LOG_DEBUG, "%s: run %d checks", __PRETTY_FUNCTION__, CheckHost::checks.size()); runChecks(ec); + Logger()->messagebf(LOG_DEBUG, "%s: execute view", __PRETTY_FUNCTION__); view->execute(presenter.get(), ec); // Caches might open transactions BOOST_FOREACH(const CommonObjects::DataSources::value_type & ds, CommonObjects::datasources) { @@ -136,22 +139,25 @@ void IceDaemon::executeView(const std::string & name, Slicer::ModelPartPtr p, const ParamMap & pm) const { ScriptNodePtr s = ScriptReader::resolveScript(IceDaemon::viewRoot, name, false)->root(); - IceDaemonViewHost f(s); + boost::intrusive_ptr v = new IceDaemonViewHost(s); IceCallContext icc(pm); - f.executeView(new IceViewSerializer(p), &icc); + v->executeView(new IceViewSerializer(p), &icc); } class IceDaemonTaskHost : public TaskHost { public: IceDaemonTaskHost(ScriptNodePtr s) : SourceObject(s), + CommonObjects(s), CheckHost(s), TaskHost(s) { } void executeTask(ExecContext * ec) const { + Logger()->messagebf(LOG_DEBUG, "%s: run %d checks", __PRETTY_FUNCTION__, CheckHost::checks.size()); runChecks(ec); + Logger()->messagebf(LOG_DEBUG, "%s: execute %d tasks", __PRETTY_FUNCTION__, TaskHost::tasks.size()); execute(ec); } }; @@ -160,9 +166,9 @@ void IceDaemon::executeTask(const std::string & name, const ParamMap & pm) const { ScriptNodePtr s = ScriptReader::resolveScript(IceDaemon::taskRoot, name, false)->root(); - IceDaemonTaskHost t(s); + boost::intrusive_ptr t = new IceDaemonTaskHost(s); IceCallContext icc(pm); - t.executeTask(&icc); + t->executeTask(&icc); } IceCompile::CPtr diff --git a/project2/ice/iceViewSerializer.cpp b/project2/ice/iceViewSerializer.cpp index 2a95f9f..b690224 100644 --- a/project2/ice/iceViewSerializer.cpp +++ b/project2/ice/iceViewSerializer.cpp @@ -1,5 +1,6 @@ #include "iceViewSerializer.h" #include +#include using namespace Slicer; @@ -7,8 +8,8 @@ class Assign : public ValueSource, public TValueSource { public: Assign(const VariableType & v) : vt(v) - { - } + { + } void set(boost::posix_time::ptime & v) const override { v = vt; } void set(bool & v) const override { v = vt; } @@ -37,6 +38,12 @@ IceViewSerializer::addNamedValue(const Glib::ustring & name, const VariableType if (field) { field->SetValue(new Assign(vt)); } + else { + Logger()->messagebf(LOG_INFO, "%s: Field not found", __PRETTY_FUNCTION__); + } + } + else { + Logger()->messagebf(LOG_WARNING, "%s: No active row", __PRETTY_FUNCTION__); } } @@ -44,11 +51,15 @@ void IceViewSerializer::addNewRow(const Glib::ustring & name) const { rowmpp = mpp->GetChild(name); + if (rowmpp) { + rowmpp->Create(); + } } void IceViewSerializer::finishRow() const { + rowmpp->Complete(); rowmpp = NULL; } diff --git a/project2/ice/unittests/Jamfile.jam b/project2/ice/unittests/Jamfile.jam index a793918..b23579d 100644 --- a/project2/ice/unittests/Jamfile.jam +++ b/project2/ice/unittests/Jamfile.jam @@ -7,6 +7,9 @@ lib unittest : ..//Ice ..//IceUtil ..//pthread + : : + . + ..//pthread ; lib unittestr : @@ -19,6 +22,7 @@ lib unittestr : ..//pthread : : . + ..//pthread ; path-constant me : . ; @@ -86,9 +90,11 @@ unit-test testDaemon : ..//Ice ..//IceUtil ..//boost_filesystem -#testDaemon/task.xml -#testDaemon/taskParams.xml -#testDaemon/view.xml -#testDaemon/viewParams.xml + data/unittest-data.xml + lib/testrows.xml + tasks/UnitTest/SimpleInterface/SomeTask.xml + tasks/UnitTest/SimpleInterface/SomeTaskParams.xml + views/UnitTest/SimpleInterface/SomeRows.xml + views/UnitTest/SimpleInterface/SomeRowsParams.xml ; diff --git a/project2/ice/unittests/data/unittest-data.xml b/project2/ice/unittests/data/unittest-data.xml new file mode 100644 index 0000000..d4b76df --- /dev/null +++ b/project2/ice/unittests/data/unittest-data.xml @@ -0,0 +1,19 @@ + + + + 1 + first + + + 2 + second + + + 1 + third + + + 2 + first + + diff --git a/project2/ice/unittests/lib/testrows.xml b/project2/ice/unittests/lib/testrows.xml new file mode 100644 index 0000000..876e311 --- /dev/null +++ b/project2/ice/unittests/lib/testrows.xml @@ -0,0 +1,19 @@ + + + /unittest-data.xml + + + + + + + + + /root/record[a= or b=''] + + + + + + + diff --git a/project2/ice/unittests/tasks/UnitTest/SimpleInterface/SomeTask.xml b/project2/ice/unittests/tasks/UnitTest/SimpleInterface/SomeTask.xml new file mode 100644 index 0000000..e042d7b --- /dev/null +++ b/project2/ice/unittests/tasks/UnitTest/SimpleInterface/SomeTask.xml @@ -0,0 +1,4 @@ + + + + diff --git a/project2/ice/unittests/tasks/UnitTest/SimpleInterface/SomeTaskParams.xml b/project2/ice/unittests/tasks/UnitTest/SimpleInterface/SomeTaskParams.xml new file mode 100644 index 0000000..67f1cc8 --- /dev/null +++ b/project2/ice/unittests/tasks/UnitTest/SimpleInterface/SomeTaskParams.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/project2/ice/unittests/testDaemon.cpp b/project2/ice/unittests/testDaemon.cpp index ce2630c..9e86a03 100644 --- a/project2/ice/unittests/testDaemon.cpp +++ b/project2/ice/unittests/testDaemon.cpp @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #define XSTR(s) STR(s) #define STR(s) #s @@ -11,12 +14,112 @@ const auto bindir = boost::filesystem::canonical("/proc/self/exe").parent_path() const boost::filesystem::path iceroot(XSTR(ROOT)); const auto headers = iceroot.parent_path().parent_path(); +class DummyTask : public Task { + public: + DummyTask(ScriptNodePtr n) : SourceObject(n), Task(n) { } + void execute(ExecContext *) const + { + Logger()->messagebf(LOG_DEBUG, "%s: %d", __PRETTY_FUNCTION__, __LINE__); + execCount += 1; + } + + static unsigned int execCount; +}; +DECLARE_LOADER("DummyTask", DummyTask); +unsigned int DummyTask::execCount = 0; + +class DummyParamTask : public Task { + public: + DummyParamTask(ScriptNodePtr n) : + SourceObject(n), + Task(n), + a(n, "a"), + b(n, "b") + { } + void execute(ExecContext * ec) const + { + Logger()->messagebf(LOG_DEBUG, "%s: %d", __PRETTY_FUNCTION__, __LINE__); + execCount += 1; + execA = a(ec); + execB = b(ec); + } + + const Variable a; + const Variable b; + + static unsigned int execCount; + static VariableType execA; + static VariableType execB; +}; +DECLARE_LOADER("DummyParamTask", DummyParamTask); +unsigned int DummyParamTask::execCount = 0; +VariableType DummyParamTask::execA; +VariableType DummyParamTask::execB; + static void commonTests() { BOOST_TEST_CHECKPOINT("Verify loaded"); BOOST_REQUIRE(IceDaemonAdapterHandlerLoader::getFor("UnitTest")); + + int dummy = 0; + BOOST_TEST_CHECKPOINT("Run daemon"); + DaemonPtr id = new IceDaemon(dummy, NULL); + std::thread run(&Daemon::run, id.get()); + + BOOST_TEST_CHECKPOINT("Create and verify proxy"); + Ice::CommunicatorPtr ic = Ice::initialize(dummy, NULL); + UnitTest::SimpleInterfacePrx si = UnitTest::SimpleInterfacePrx::checkedCast(ic->stringToProxy("UnitTestSimpleInterface:tcp -p 12024")); + BOOST_REQUIRE(si); + si->ice_ping(); + + BOOST_TEST_CHECKPOINT("Call view (no parameters)"); + auto rows = si->SomeRows(); + BOOST_REQUIRE_EQUAL(4, rows.size()); + BOOST_REQUIRE(rows[0]); + BOOST_REQUIRE(rows[1]); + BOOST_REQUIRE(rows[2]); + BOOST_REQUIRE(rows[3]); + BOOST_REQUIRE_EQUAL(1, rows[0]->a); + BOOST_REQUIRE_EQUAL("first", rows[0]->b); + BOOST_REQUIRE_EQUAL(2, rows[1]->a); + BOOST_REQUIRE_EQUAL("second", rows[1]->b); + BOOST_REQUIRE_EQUAL(1, rows[2]->a); + BOOST_REQUIRE_EQUAL("third", rows[2]->b); + BOOST_REQUIRE_EQUAL(2, rows[3]->a); + BOOST_REQUIRE_EQUAL("first", rows[3]->b); + + BOOST_TEST_CHECKPOINT("Call view (parameters)"); + auto paramRows = si->SomeRowsParams(1, "first"); + BOOST_REQUIRE_EQUAL(3, paramRows.size()); + BOOST_REQUIRE_EQUAL(1, paramRows[0]->a); + BOOST_REQUIRE_EQUAL("first", paramRows[0]->b); + BOOST_REQUIRE_EQUAL(1, paramRows[1]->a); + BOOST_REQUIRE_EQUAL("third", paramRows[1]->b); + BOOST_REQUIRE_EQUAL(2, paramRows[2]->a); + BOOST_REQUIRE_EQUAL("first", paramRows[2]->b); + + BOOST_TEST_CHECKPOINT("Call task (no parameters)"); + BOOST_REQUIRE_EQUAL(0, DummyTask::execCount); + si->SomeTask(); + BOOST_REQUIRE_EQUAL(1, DummyTask::execCount); + si->SomeTask(); + BOOST_REQUIRE_EQUAL(2, DummyTask::execCount); + + BOOST_TEST_CHECKPOINT("Call task (parameters)"); + BOOST_REQUIRE_EQUAL(0, DummyParamTask::execCount); + si->SomeTaskParams(1, "first"); + BOOST_REQUIRE_EQUAL(1, DummyParamTask::execCount); + BOOST_REQUIRE_EQUAL(1, DummyParamTask::execA.as()); + BOOST_REQUIRE_EQUAL("first", DummyParamTask::execB.as()); + si->SomeTaskParams(2, "second"); + BOOST_REQUIRE_EQUAL(2, DummyParamTask::execCount); + BOOST_REQUIRE_EQUAL(2, DummyParamTask::execA.as()); + BOOST_REQUIRE_EQUAL("second", DummyParamTask::execB.as()); + + id->shutdown(); + run.join(); } static @@ -34,8 +137,13 @@ BOOST_AUTO_TEST_CASE( test_daemon ) boost::filesystem::remove_all(tmpdir); BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); + TestOptionsSource::LoadTestOptions({ }); TestOptionsSource::LoadTestOptions({ + { "application.dataroot", "file://" + (iceroot / "data").string() }, { "library", (bindir / "slicer-yes" / "libunittestr.so").string() }, + { "ice.daemon.adapterEndpoint", "tcp -p 12024" }, + { "ice.daemon.viewRoot", (iceroot / "views").string() }, + { "ice.daemon.taskRoot", (iceroot / "tasks").string() }, { "ice.compile.tmpdir", tmpdir }, { "ice.compile.headers", headers.string() }, { "ice.daemon.slicerdaemon", (iceroot / "unittest.ice").string() } diff --git a/project2/ice/unittests/views/UnitTest/SimpleInterface/SomeRows.xml b/project2/ice/unittests/views/UnitTest/SimpleInterface/SomeRows.xml new file mode 100644 index 0000000..b4950e3 --- /dev/null +++ b/project2/ice/unittests/views/UnitTest/SimpleInterface/SomeRows.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/project2/ice/unittests/views/UnitTest/SimpleInterface/SomeRowsParams.xml b/project2/ice/unittests/views/UnitTest/SimpleInterface/SomeRowsParams.xml new file mode 100644 index 0000000..d8a3f21 --- /dev/null +++ b/project2/ice/unittests/views/UnitTest/SimpleInterface/SomeRowsParams.xml @@ -0,0 +1,5 @@ + + + + + -- cgit v1.2.3