summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <randomdan@akira.random.lan>2014-11-29 14:27:05 +0000
committerDan Goodliffe <randomdan@akira.random.lan>2014-11-29 14:27:05 +0000
commit14a84d8a3f827516addca698b4d88de580188126 (patch)
tree418c9d94b9b57d71ccb99949d14a6233d169d70a
parentRename library test to conform with others (diff)
parentUnit tests for daemon and fixes for highlighted issues (diff)
downloadproject2-14a84d8a3f827516addca698b4d88de580188126.tar.bz2
project2-14a84d8a3f827516addca698b4d88de580188126.tar.xz
project2-14a84d8a3f827516addca698b4d88de580188126.zip
Merge remote-tracking branch 'origin/slicer'
-rw-r--r--project2/Jamfile.jam2
-rw-r--r--project2/common/commonObjects.cpp1
-rw-r--r--project2/ice/.ycm_extra_conf.py119
-rw-r--r--project2/ice/Jamfile.jam12
-rw-r--r--project2/ice/buildComms.cpp18
-rw-r--r--project2/ice/buildComms.h4
-rw-r--r--project2/ice/buildDaemon.cpp4
-rw-r--r--project2/ice/buildShared.cpp30
-rw-r--r--project2/ice/buildShared.h20
-rw-r--r--project2/ice/iceBase.cpp43
-rw-r--r--project2/ice/iceBase.h23
-rw-r--r--project2/ice/iceCompile.cpp10
-rw-r--r--project2/ice/iceCompile.h2
-rw-r--r--project2/ice/iceDaemon.cpp82
-rw-r--r--project2/ice/iceDaemon.h16
-rw-r--r--project2/ice/iceDataSource.cpp66
-rw-r--r--project2/ice/iceDataSource.h18
-rw-r--r--project2/ice/iceModule.cpp4
-rw-r--r--project2/ice/iceModule.h39
-rw-r--r--project2/ice/iceRows.cpp108
-rw-r--r--project2/ice/iceRows.h67
-rw-r--r--project2/ice/iceViewSerializer.cpp65
-rw-r--r--project2/ice/iceViewSerializer.h21
-rw-r--r--project2/ice/pch.hpp2
-rw-r--r--project2/ice/slice2Common.cpp71
-rw-r--r--project2/ice/slice2Common.h23
-rw-r--r--project2/ice/slice2Daemon.cpp4
-rw-r--r--project2/ice/slice2Presenter.cpp60
-rw-r--r--project2/ice/slice2Presenter.h23
-rw-r--r--project2/ice/slice2Rows.cpp51
-rw-r--r--project2/ice/slice2Rows.h10
-rw-r--r--project2/ice/slice2Task.cpp38
-rw-r--r--project2/ice/slice2Task.h10
-rw-r--r--project2/ice/slice2Type.cpp110
-rw-r--r--project2/ice/slice2Type.h25
-rw-r--r--project2/ice/tests/Jamfile.jam25
-rw-r--r--project2/ice/tests/test.ice9
-rw-r--r--project2/ice/tests/testClient.cpp34
-rw-r--r--project2/ice/unittests/Jamfile.jam100
-rw-r--r--project2/ice/unittests/data/unittest-data.xml19
-rw-r--r--project2/ice/unittests/expected/clientPresenter.log29
-rw-r--r--project2/ice/unittests/lib/testrows.xml19
-rw-r--r--project2/ice/unittests/tasks/UnitTest/SimpleInterface/SomeTask.xml4
-rw-r--r--project2/ice/unittests/tasks/UnitTest/SimpleInterface/SomeTaskParams.xml7
-rw-r--r--project2/ice/unittests/testClient.cpp122
-rw-r--r--project2/ice/unittests/testClient.xml10
-rw-r--r--project2/ice/unittests/testClientCompile.cpp104
-rw-r--r--project2/ice/unittests/testDaemon.cpp156
-rw-r--r--project2/ice/unittests/testDaemonCompile.cpp83
-rw-r--r--project2/ice/unittests/unittest-ice-datasource.xml4
-rw-r--r--project2/ice/unittests/unittest.ice22
-rw-r--r--project2/ice/unittests/views/UnitTest/SimpleInterface/SomeRows.xml5
-rw-r--r--project2/ice/unittests/views/UnitTest/SimpleInterface/SomeRowsParams.xml5
-rw-r--r--project2/ut/testScriptHost.cpp130
-rw-r--r--project2/ut/testScriptHost.h42
55 files changed, 1493 insertions, 637 deletions
diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam
index ce45007..ca057b4 100644
--- a/project2/Jamfile.jam
+++ b/project2/Jamfile.jam
@@ -32,7 +32,7 @@ build-project daemon ;
# Ensure tests are run (final targets don't reference projects, but specific libraries)
build-project common//unittests ;
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 <pch.hpp>
#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 67e9eab..2a531cb 100644
--- a/project2/ice/Jamfile.jam
+++ b/project2/ice/Jamfile.jam
@@ -9,18 +9,20 @@ lib Ice ;
lib IceUtil ;
lib pthread ;
lib boost_filesystem ;
+lib slicer : : <name>slicer : : <include>/usr/include/slicer ;
-build-project tests ;
+build-project unittests ;
cpp-pch pch : pch.hpp :
<include>../../libmisc
<library>../lib//p2lib
<library>../common//p2common
<library>glibmm
+ <library>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
:
<include>../../libmisc
<library>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
:
<include>../../libmisc
<library>glibmm
@@ -57,10 +59,11 @@ lib p2icedaemon :
: :
<library>../daemon/lib//p2daemonlib
<library>p2ice
+ <include>.
;
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
:
<include>../../libmisc
<library>glibmm
@@ -69,6 +72,7 @@ lib p2ice :
<library>dl
<library>Ice
<library>Slice
+ <library>slicer
<library>IceUtil
<library>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 <logger.h>
#include <misc.h>
+#include <boost/filesystem/operations.hpp>
-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 <pch.hpp>
#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 <pch.hpp>
-#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 <iceConvert.h>\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 <string>
-
-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<std::string>();
+ 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 <boost/tuple/tuple.hpp>
+#include <thread>
+#include "iceCompile.h"
+#include <variableType.h>
+
+class IceBase {
+ public:
+ typedef boost::tuple<IceCompile::CPtr, std::thread *> LibCompile;
+ typedef boost::variant<LibCompile, IceCompile::LibHandle> LibPromise;
+ typedef std::vector<LibPromise> Libs;
+ typedef boost::function<IceCompile::CPtr(const std::string &, const IceCompile::Deps &)> 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<CPtr> 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..7f506d4 100644
--- a/project2/ice/iceDaemon.cpp
+++ b/project2/ice/iceDaemon.cpp
@@ -1,8 +1,8 @@
#include <pch.hpp>
#include "iceDaemon.h"
#include "buildComms.h"
-#include "buildShared.h"
#include "buildDaemon.h"
+#include "iceViewSerializer.h"
#include <scriptLoader.h>
#include <options.h>
#include <sys/stat.h>
@@ -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<IceDaemon> {
+ 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,29 @@ 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();
+ Logger()->messagebf(LOG_DEBUG, " %s creating adapter %s [%s]...", __PRETTY_FUNCTION__, adapterName, adapterEndpoint);
+ Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithEndpoints(adapterName, adapterEndpoint);
- auto library = bd->Open();
+ Logger()->messagebf(LOG_DEBUG, " %s installing servants...", __PRETTY_FUNCTION__);
+ std::set<IceDaemonAdapterHandlerPtr> interfaces;
+ InstanceSet<IceDaemonAdapterHandlerLoader>::OnAll([this, adapter, &interfaces](IceDaemonAdapterHandlerLoader * loader) {
+ IceDaemonAdapterHandlerPtr interfacePtr = loader->create();
+ interfacePtr->add(adapter, this, ic);
+ interfaces.insert(interfacePtr);
+ });
- 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);
+ Logger()->messagebf(LOG_DEBUG, " %s starting...", __PRETTY_FUNCTION__);
adapter->activate();
+
Logger()->messagebf(LOG_INFO, " %s running...", __PRETTY_FUNCTION__);
- 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 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 +99,9 @@ class IceDaemonFlatViewHost : public virtual CommonObjects, public virtual Check
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) {
@@ -127,25 +136,28 @@ 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);
+ boost::intrusive_ptr<IceDaemonViewHost> v = new IceDaemonViewHost(s);
IceCallContext icc(pm);
- f.executeView(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);
}
};
@@ -154,8 +166,20 @@ 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<IceDaemonTaskHost> t = new IceDaemonTaskHost(s);
IceCallContext icc(pm);
- t.executeTask(&icc);
+ 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 <daemon.h>
#include "iceModule.h"
+#include "iceBase.h"
-class IceDaemon : public Daemon {
+class IceDaemon : public Daemon, IceBase {
public:
+ typedef boost::tuple<IceCompile::CPtr, std::thread *> LibCompile;
+ typedef boost::variant<LibCompile, IceCompile::LibHandle> LibPromise;
+ typedef std::vector<LibPromise> 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 <pch.hpp>
-#include "iceDataSource.h"
-#include "buildComms.h"
-#include "buildShared.h"
#include "buildClient.h"
+#include "iceDataSource.h"
#include <Ice/Ice.h>
-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<std::string>();
- 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<std::string>();
- 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<IceDataSource> {
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 <dataSource.h>
#include <options.h>
-#include <variables.h>
-#include "iceCompile.h"
#include <Ice/Communicator.h>
-#include <thread>
-#include <boost/tuple/tuple.hpp>
+#include "iceBase.h"
-class IceDataSource : public DataSource {
+class IceDataSource : public DataSource, IceBase {
public:
INITOPTIONS;
- typedef boost::tuple<IceCompile::CPtr, std::thread *> LibCompile;
- typedef boost::variant<LibCompile, IceCompile::LibHandle> LibPromise;
- typedef std::vector<LibPromise> Libs;
-
IceDataSource(ScriptNodePtr p);
template <typename Interface>
@@ -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 <presenter.h>
#include <safeMapFind.h>
#include <boost/function.hpp>
+#include <slicer/modelParts.h>
typedef std::map<std::string, VariableType> 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<IceDaemonAdapterHandler> IceDaemonAdapterHandlerPtr;
typedef GenLoader<IceDaemonAdapterHandler, std::string> IceDaemonAdapterHandlerLoader;
-template <typename IC>
-class IcePresenter : public RowSetPresenter {
- public:
- typedef boost::function<void (typename IC::value_type *, const VariableType &)> TargetAssigner;
- typedef std::map<Glib::ustring, TargetAssigner> MemberTargets;
- SimpleMessageException(NoSuchMember);
-
- IcePresenter(IC & t);
- virtual void addNamedValue(const Glib::ustring & member, const VariableType & value) const
- {
- safeMapLookup<NoSuchMember>(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 <typename T, typename M> static void memberAssign(T * t, M T::*m, const VariableType & v) {
- t->*m = v.as<M>();
- }
-};
-
-
#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 <pch.hpp>
+#include "iceRows.h"
+
+using namespace Slicer;
+
+class IceRowState : public RowState {
+ public:
+ class Assign : public ValueTarget,
+ public TValueTarget<boost::posix_time::ptime> {
+ 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 <rowSet.h>
#include "iceConvert.h"
#include "iceClient.h"
+#include <slicer/modelParts.h>
+#include <slicer/serializer.h>
-template <typename Type>
-class IceRowState : public RowState {
- public:
- IceRowState()
- {
- unsigned int idx = 0;
- IceType<Type>::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<Type>::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 <typename Type>
-class IceRowState<std::vector<Type> > : public RowState {
+class RowProcSerializer : public Slicer::Serializer {
public:
- typedef std::vector<Type> RangeType;
- IceRowState()
- {
- unsigned int idx = 0;
- IceType<Type>::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<Type>::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 <typename Interface>
diff --git a/project2/ice/iceViewSerializer.cpp b/project2/ice/iceViewSerializer.cpp
new file mode 100644
index 0000000..b690224
--- /dev/null
+++ b/project2/ice/iceViewSerializer.cpp
@@ -0,0 +1,65 @@
+#include "iceViewSerializer.h"
+#include <slicer/serializer.h>
+#include <logger.h>
+
+using namespace Slicer;
+
+class Assign : public ValueSource,
+ public TValueSource<boost::posix_time::ptime> {
+ 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<Ice::Byte>(vt.as<int>()); }
+ void set(Ice::Short & v) const override { v = boost::numeric_cast<Ice::Byte>(vt.as<int>()); }
+ 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<double>(); }
+ void set(Ice::Double & v) const override { v = vt; }
+ void set(std::string & v) const override { v = vt.as<std::string>(); }
+
+ 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));
+ }
+ else {
+ Logger()->messagebf(LOG_INFO, "%s: Field not found", __PRETTY_FUNCTION__);
+ }
+ }
+ else {
+ Logger()->messagebf(LOG_WARNING, "%s: No active row", __PRETTY_FUNCTION__);
+ }
+}
+
+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/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 <slicer/modelParts.h>
+#include <presenter.h>
+
+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 <Slice/Parser.h>
#include <string>
#include <variables.h>
+#include <slicer/modelParts.h>
+#include <slicer/serializer.h>
#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 <Slice/CPlusPlusUtil.h>
+#include <boost/foreach.hpp>
+
+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 <Slice/Parser.h>
+
+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 <pch.hpp>
-#include "slice2Presenter.h"
-#include <Slice/CPlusPlusUtil.h>
-
-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<std::vector< %s::%s >>::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<std::vector< %s::%s >>::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<std::vector<P2TV::Recording>>::memberAssign<P2TV::Recording, int>, 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 <Slice/Parser.h>
-
-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 <Slice/CPlusPlusUtil.h>
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<decltype(service->%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<decltype(result)>(&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 <Slice/Parser.h>
+#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 <Slice/CPlusPlusUtil.h>
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 <Slice/Parser.h>
+#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 <pch.hpp>
-#include "slice2Type.h"
-#include <Slice/CPlusPlusUtil.h>
-#include <boost/foreach.hpp>
-
-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 <Slice/Parser.h>
-
-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/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
- :
- <library>..//Ice
- <library>..//IceUtil
- <library>..//pthread
- ;
-
-path-constant me : . ;
-
-unit-test testClient :
- [ glob testClient.cpp ]
- :
- <define>ROOT=\"$(me)\"
- <dependency>test.ice
- <library>..//p2iceclient
- <library>../../ut//p2ut
- <library>../../basics//p2basics
- <library>..//Ice
- <library>..//IceUtil
- <library>..//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 <boost/test/unit_test.hpp>
-#include <boost/filesystem/operations.hpp>
-#include "iceClient.h"
-#include <testOptionsSource.h>
-
-#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..b23579d
--- /dev/null
+++ b/project2/ice/unittests/Jamfile.jam
@@ -0,0 +1,100 @@
+import testing ;
+
+lib unittest :
+ unittest.ice
+ :
+ <slicer>no
+ <library>..//Ice
+ <library>..//IceUtil
+ <library>..//pthread
+ : :
+ <include>.
+ <library>..//pthread
+ ;
+
+lib unittestr :
+ unittest.ice
+ :
+ <slicer>yes
+ <library>..//Ice
+ <library>..//slicer
+ <library>..//IceUtil
+ <library>..//pthread
+ : :
+ <include>.
+ <library>..//pthread
+ ;
+
+path-constant me : . ;
+
+unit-test testClientCompile :
+ [ glob testClientCompile.cpp ]
+ :
+ <define>ROOT=\"$(me)\"
+ <dependency>unittest.ice
+ <dependency>unittest
+ <dependency>unittestr
+ <library>..//p2iceclient
+ <library>../../ut//p2ut
+ <library>../../xml//p2xml
+ <library>../../basics//p2basics
+ <library>..//Ice
+ <library>..//IceUtil
+ <library>..//boost_filesystem
+ <dependency>testClient.xml
+ ;
+
+unit-test testClient :
+ [ glob testClient.cpp ]
+ :
+ <define>ROOT=\"$(me)\"
+ <dependency>unittest.ice
+ <library>unittestr
+ <implicit-dependency>unittestr
+ <library>..//p2iceclient
+ <library>../../ut//p2ut
+ <library>../../xml//p2xml
+ <library>../../basics//p2basics
+ <library>..//Ice
+ <library>..//IceUtil
+ <library>..//boost_filesystem
+ <dependency>testClient.xml
+ ;
+
+unit-test testDaemonCompile :
+ [ glob testDaemonCompile.cpp ]
+ :
+ <define>ROOT=\"$(me)\"
+ <dependency>unittest.ice
+ <dependency>unittest
+ <dependency>unittestr
+ <library>..//p2icedaemon
+ <library>../../ut//p2ut
+ <library>../../basics//p2basics
+ <library>..//Ice
+ <library>..//IceUtil
+ <library>..//boost_filesystem
+ ;
+
+unit-test testDaemon :
+ [ glob testDaemon.cpp ]
+ :
+ <define>ROOT=\"$(me)\"
+ <dependency>unittest.ice
+ <library>unittestr
+ <implicit-dependency>unittestr
+ <library>..//p2icedaemon
+ <library>../../ut//p2ut
+ <library>../../xml//p2xml
+ <library>../../basics//p2basics
+ <library>..//Ice
+ <library>..//IceUtil
+ <library>..//boost_filesystem
+ <dependency>data/unittest-data.xml
+ <dependency>lib/testrows.xml
+ <dependency>tasks/UnitTest/SimpleInterface/SomeTask.xml
+ <dependency>tasks/UnitTest/SimpleInterface/SomeTaskParams.xml
+ <dependency>views/UnitTest/SimpleInterface/SomeRows.xml
+ <dependency>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 @@
+<?xml version="1.0"?>
+<root>
+ <record>
+ <a>1</a>
+ <b>first</b>
+ </record>
+ <record>
+ <a>2</a>
+ <b>second</b>
+ </record>
+ <record>
+ <a>1</a>
+ <b>third</b>
+ </record>
+ <record>
+ <a>2</a>
+ <b>first</b>
+ </record>
+</root>
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/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 @@
+<?xml version="1.0"?>
+<p2:xpathrows xmlns:p2="http://project2.randomdan.homeip.net" name="filelist">
+ <url><root source="config" name="dataroot"/>/unittest-data.xml</url>
+ <filterviews>
+ <default root="/root/record">
+ <fields>
+ <a xpath="a"/>
+ <b xpath="b"/>
+ </fields>
+ </default>
+ <params>
+ <root>/root/record[a=<a source="param" name="a"/> or b='<b source="param" name="b"/>']</root>
+ <fields>
+ <a xpath="a"/>
+ <b xpath="b"/>
+ </fields>
+ </params>
+ </filterviews>
+</p2:xpathrows>
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 @@
+<?xml version="1.0"?>
+<block xmlns:p2="http://project2.randomdan.homeip.net" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <p2:DummyTask />
+</block>
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 @@
+<?xml version="1.0"?>
+<block xmlns:p2="http://project2.randomdan.homeip.net" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <p2:DummyParamTask>
+ <a source="param" name="a"/>
+ <b source="param" name="b"/>
+ </p2:DummyParamTask>
+</block>
diff --git a/project2/ice/unittests/testClient.cpp b/project2/ice/unittests/testClient.cpp
new file mode 100644
index 0000000..e5d45b7
--- /dev/null
+++ b/project2/ice/unittests/testClient.cpp
@@ -0,0 +1,122 @@
+#define BOOST_TEST_MODULE Client
+#include <boost/test/unit_test.hpp>
+#include <boost/filesystem/operations.hpp>
+#include "iceClient.h"
+#include <testOptionsSource.h>
+#include <task.h>
+#include <exceptions.h>
+#include <scripts.h>
+#include <xmlScriptParser.h>
+#include <testScriptHost.h>
+#include <scopeObject.h>
+#include <unittest.h>
+
+#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 {
+ new UnitTest::Simple { 1, "test a" },
+ new UnitTest::Simple { 2, "test b" }
+ };
+ execCount += 1;
+ return rtn;
+ }
+
+ UnitTest::Simples SomeRowsParams(Ice::Int pi, const std::string & ps, const Ice::Current&)
+ {
+ UnitTest::Simples rtn {
+ new UnitTest::Simple { 0, "before" },
+ new UnitTest::Simple { pi, ps },
+ new UnitTest::Simple { 2, "after" }
+ };
+ 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> dummy = new Dummy();
+ adapter->add(dummy, ic->stringToIdentity("testObject"));
+ adapter->activate();
+ ScopeObject _([&ic]{ ic->destroy(); });
+
+ BOOST_TEST_CHECKPOINT("Execute test script");
+ boost::intrusive_ptr<TestScriptHost> sr = new TestScriptHost(r);
+ 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
+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( test_client )
+{
+ const std::string tmpdir = "/tmp/ut/project2.slice-client";
+ 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 @@
+<?xml version="1.0"?>
+<test xmlns:xi="http://www.w3.org/2001/XInclude"
+ xmlns:p2="http://project2.randomdan.homeip.net">
+ <p2:UnitTest-SimpleInterface-SomeTask datasource="unittest-ice-datasource" objectId="testObject" />
+ <p2:UnitTest-SimpleInterface-SomeTaskParams datasource="unittest-ice-datasource" objectId="testObject" a="1" b="first" />
+ <p2:UnitTest-SimpleInterface-SomeRows name="rows" datasource="unittest-ice-datasource" objectId="testObject" />
+ <p2:UnitTest-SimpleInterface-SomeRowsParams name="rowsParams" datasource="unittest-ice-datasource" objectId="testObject" a="2" b="second" />
+ <p2:view source="rows" recordname="rec" rootname="somerows" />
+ <p2:view source="rowsParams" recordname="rec" rootname="somerowsparams" />
+</test>
diff --git a/project2/ice/unittests/testClientCompile.cpp b/project2/ice/unittests/testClientCompile.cpp
new file mode 100644
index 0000000..c86b826
--- /dev/null
+++ b/project2/ice/unittests/testClientCompile.cpp
@@ -0,0 +1,104 @@
+#define BOOST_TEST_MODULE ClientCompile
+#include <boost/test/unit_test.hpp>
+#include <boost/filesystem/operations.hpp>
+#include "iceClient.h"
+#include <testOptionsSource.h>
+#include <task.h>
+#include <exceptions.h>
+#include <scripts.h>
+#include <xmlScriptParser.h>
+#include <testScriptHost.h>
+#include <scopeObject.h>
+
+#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(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<TestScriptHost> 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-clientCompile/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-clientCompile/clientOnly";
+ BOOST_TEST_CHECKPOINT("Clean up");
+ boost::filesystem::remove_all(tmpdir);
+
+ BOOST_TEST_CHECKPOINT("Configure, compile, link, load");
+ TestOptionsSource::LoadTestOptions({
+ { "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_slicer )
+{
+ const std::string tmpdir = "/tmp/ut/project2.slice-clientCompile/slicer";
+ 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/testDaemon.cpp b/project2/ice/unittests/testDaemon.cpp
new file mode 100644
index 0000000..9e86a03
--- /dev/null
+++ b/project2/ice/unittests/testDaemon.cpp
@@ -0,0 +1,156 @@
+#define BOOST_TEST_MODULE Daemon
+#include <boost/test/unit_test.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <testOptionsSource.h>
+#include <unittest.h>
+#include <iceDaemon.h>
+#include <task.h>
+#include <logger.h>
+#include <variables.h>
+
+#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 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<int>());
+ BOOST_REQUIRE_EQUAL("first", DummyParamTask::execB.as<std::string>());
+ si->SomeTaskParams(2, "second");
+ BOOST_REQUIRE_EQUAL(2, DummyParamTask::execCount);
+ BOOST_REQUIRE_EQUAL(2, DummyParamTask::execA.as<int>());
+ BOOST_REQUIRE_EQUAL("second", DummyParamTask::execB.as<std::string>());
+
+ id->shutdown();
+ run.join();
+}
+
+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({ });
+ 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() }
+ });
+ commonTests();
+
+ TestOptionsSource::LoadTestOptions({ });
+ unloadTests();
+}
+
diff --git a/project2/ice/unittests/testDaemonCompile.cpp b/project2/ice/unittests/testDaemonCompile.cpp
new file mode 100644
index 0000000..7bda6dd
--- /dev/null
+++ b/project2/ice/unittests/testDaemonCompile.cpp
@@ -0,0 +1,83 @@
+#define BOOST_TEST_MODULE DaemonCompile
+#include <boost/test/unit_test.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <testOptionsSource.h>
+#include <exceptions.h>
+#include <iceDaemon.h>
+
+#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_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.slice-daemonCompile/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_daemonOnly )
+{
+ const std::string tmpdir = "/tmp/ut/project2.slice-daemonCompile/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_slicer )
+{
+ const std::string tmpdir = "/tmp/ut/project2.slice-daemonCompile/slicer";
+ 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 @@
+<?xml version="1.0"?>
+<p2:icedatasource xmlns:p2="http://project2.randomdan.homeip.net" name="unittest-ice-datasource">
+ <endpoint>tcp -p 12000</endpoint>
+</p2:icedatasource>
diff --git a/project2/ice/unittests/unittest.ice b/project2/ice/unittests/unittest.ice
new file mode 100644
index 0000000..60e44bb
--- /dev/null
+++ b/project2/ice/unittests/unittest.ice
@@ -0,0 +1,22 @@
+module UnitTest {
+ ["project2:type"]
+ class Simple {
+ int a;
+ string b;
+ };
+
+ sequence<Simple> Simples;
+
+ interface SimpleInterface
+ {
+ ["project2:rows"]
+ Simples SomeRows();
+ ["project2:rows"]
+ Simples SomeRowsParams(int a, string b);
+ ["project2:task"]
+ void SomeTask();
+ ["project2:task"]
+ void SomeTaskParams(int a, string b);
+ };
+};
+
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 @@
+<?xml version="1.0"?>
+<block xmlns:p2="http://project2.randomdan.homeip.net" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="../../../lib/testrows.xml"/>
+ <p2:flatview source="filelist" recordname="element" filter="default"/>
+</block>
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 @@
+<?xml version="1.0"?>
+<block xmlns:p2="http://project2.randomdan.homeip.net" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="../../../lib/testrows.xml"/>
+ <p2:flatview source="filelist" recordname="element" filter="params"/>
+</block>
diff --git a/project2/ut/testScriptHost.cpp b/project2/ut/testScriptHost.cpp
new file mode 100644
index 0000000..dfdb6ed
--- /dev/null
+++ b/project2/ut/testScriptHost.cpp
@@ -0,0 +1,130 @@
+#include "testScriptHost.h"
+#include <glibmm/exception.h>
+#include <cxxabi.h>
+#include <logger.h>
+#include <fstream>
+
+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<TestScriptHost *>(this);
+}
+
+void TestScriptHost::process(ExecContext * ec)
+{
+ runChecks(ec);
+ execute(ec);
+ executeViews(ec);
+}
+
+void
+TestScriptHost::addNamedValue(const Glib::ustring & name, const VariableType & value) const
+{
+ presenterData.push_back(stringbf("%s: %s=%s", __FUNCTION__, name, value));
+}
+
+void
+TestScriptHost::addNewRow(const Glib::ustring & name) const
+{
+ 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
+{
+ presenterData.push_back(stringbf("%s: %s", __FUNCTION__, name));
+}
+
+void
+TestScriptHost::addNewRowSet(const Glib::ustring & name, const Glib::ustring & ns) const
+{
+ 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
+{
+ presenterData.push_back(stringbf("%s: %s(%s)", __FUNCTION__, name, objects));
+}
+
+void
+TestScriptHost::finishArray(bool objects) const
+{
+ 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
new file mode 100644
index 0000000..a843a4a
--- /dev/null
+++ b/project2/ut/testScriptHost.h
@@ -0,0 +1,42 @@
+#ifndef TESTSCRIPTHOST_H
+#define TESTSCRIPTHOST_H
+
+#include <taskHost.h>
+#include <viewHost.h>
+#include <presenter.h>
+#include <boost/filesystem/path.hpp>
+
+typedef std::vector<std::string> PresenterData;
+
+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;
+
+ 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
+