diff options
| author | Dan Goodliffe <randomdan@akira.random.lan> | 2014-11-29 14:27:05 +0000 | 
|---|---|---|
| committer | Dan Goodliffe <randomdan@akira.random.lan> | 2014-11-29 14:27:05 +0000 | 
| commit | 02b3b9655a273aee62bf50f592919e3f6b2f4e2b (patch) | |
| tree | 418c9d94b9b57d71ccb99949d14a6233d169d70a | |
| parent | Rename library test to conform with others (diff) | |
| parent | Unit tests for daemon and fixes for highlighted issues (diff) | |
| download | project2-02b3b9655a273aee62bf50f592919e3f6b2f4e2b.tar.bz2 project2-02b3b9655a273aee62bf50f592919e3f6b2f4e2b.tar.xz project2-02b3b9655a273aee62bf50f592919e3f6b2f4e2b.zip | |
Merge remote-tracking branch 'origin/slicer'
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 + | 
