Merge lp:~michihenning/unity-scopes-api/set-env-vars into lp:unity-scopes-api/devel

Proposed by Michi Henning
Status: Merged
Approved by: Pete Woods
Approved revision: 424
Merged at revision: 429
Proposed branch: lp:~michihenning/unity-scopes-api/set-env-vars
Merge into: lp:unity-scopes-api/devel
Prerequisite: lp:~michihenning/unity-scopes-api/scope-cache-dir
Diff against target: 932 lines (+332/-81)
33 files modified
HACKING (+1/-1)
RELEASE_NOTES.md (+4/-2)
debian/libunity-scopes2.symbols (+2/-1)
include/unity/scopes/AbstractScopeBase.h (+1/-0)
include/unity/scopes/ScopeBase.h (+17/-2)
include/unity/scopes/internal/DynamicLoader.h (+1/-1)
include/unity/scopes/internal/RuntimeImpl.h (+4/-3)
include/unity/scopes/internal/ScopeBaseImpl.h (+6/-0)
scoperunner/scoperunner.cpp (+25/-7)
src/scopes/ScopeBase.cpp (+5/-0)
src/scopes/internal/RegistryObject.cpp (+22/-7)
src/scopes/internal/RuntimeImpl.cpp (+36/-13)
src/scopes/internal/ScopeBaseImpl.cpp (+21/-0)
src/scopes/internal/zmq_middleware/ZmqConfig.cpp (+5/-1)
test/gtest/scopes/IdleShutdown/SlowSearchScope.h (+7/-7)
test/gtest/scopes/Invocation/EmptyScope.h (+5/-6)
test/gtest/scopes/Invocation/TestScope.cpp (+1/-1)
test/gtest/scopes/Invocation/TestScope.h (+5/-6)
test/gtest/scopes/Registry/scopes/testscopeA/CMakeLists.txt (+5/-1)
test/gtest/scopes/Registry/scopes/testscopeA/testscopeA.cpp (+10/-1)
test/gtest/scopes/Runtime/TestScope.h (+5/-6)
test/gtest/scopes/internal/DynamicLoader/DynamicLoader_test.cpp (+3/-3)
test/gtest/scopes/internal/RegistryObject/CMakeLists.txt (+2/-0)
test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp (+3/-3)
test/gtest/scopes/internal/RuntimeImpl/CMakeLists.txt (+3/-2)
test/gtest/scopes/internal/RuntimeImpl/Registry.ini.in (+1/-1)
test/gtest/scopes/internal/RuntimeImpl/Runtime.ini.in (+2/-1)
test/gtest/scopes/internal/RuntimeImpl/RuntimeImpl_test.cpp (+43/-5)
test/gtest/scopes/internal/RuntimeImpl/TestScope.cpp (+40/-0)
test/gtest/scopes/internal/RuntimeImpl/TestScope.h (+36/-0)
test/gtest/scopes/internal/RuntimeImpl/TestScope.ini.in (+4/-0)
test/gtest/scopes/testing/IsolatedScope/scope.cpp (+5/-0)
test/gtest/scopes/testing/IsolatedScope/scope.h (+2/-0)
To merge this branch: bzr merge lp:~michihenning/unity-scopes-api/set-env-vars
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Pete Woods (community) Approve
Michal Hruby (community) Needs Information
Review via email: mp+225782@code.launchpad.net

Commit message

Added setting of LD_LIBRARY_PATH to scoperunner and scoperegistry to include <scope_install_dir> and <scope_install_dir>/lib.

Added tmp_directory() method to ScopeBase that returns path under $XDG_RUNTIME_DIR.

Description of the change

Added setting of LD_LIBRARY_PATH to scoperunner and scoperegistry to include <scope_install_dir> and <scope_install_dir>/lib.

Added tmp_directory() method to ScopeBase that returns path under $XDG_RUNTIME_DIR.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michal Hruby (mhr3) wrote :

8 + {

Am I reading this right that all these envvars are set after the scope module is loaded and the scope itself instantiated? I think that's too late, should be done in the exec call (exec being done by the registry that is).

review: Needs Information
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

TMPDIR is currently set to:
setenv("TMPDIR", cache_dir_.c_str(), 1);

Based on what you set XDG_DATA_HOME and that my recommendation was to set it to 'XDG_DATA_HOME=$HOME/.local/share', it seems that cache_dir_.c_str() is '~/.local/share/' which is not a writable path. TMPDIR should be set like so:

TMPDIR=$XDG_RUNTIME_DIR/confined-scopes/leaf-net/<'name' from click manifest>

We want to have TMPDIR be set to something in /run because if a scope doesn't clean up after itself, at least a reboot will remove the files (this is what we do for apps).

Also, PATH and LD_LIBRARY_PATH are being unconditionally set. They should only be set in the manner you are setting them if they are not already set. If they are set at the time you are setting up the environment, then you should prepend these values to existing values. Example pseudo code:
  if PATH is empty:
     PATH=scope_base->scope_directory().c_str():scope_base->scope_directory().c_str() + "/bin"
  else:
     PATH=scope_base->scope_directory().c_str():scope_base->scope_directory().c_str() + "/bin":$PATH

Revision history for this message
Michi Henning (michihenning) wrote :

> Am I reading this right that all these envvars are set after the scope module
> is loaded and the scope itself instantiated? I think that's too late, should
> be done in the exec call (exec being done by the registry that is).

The setup is done after the scope's create function is called, but before start() is called (which initialises the scope). It may be possible to do the setup before the create function is called. (I'll have a look at that.)

Note that scopes aren't just run by the registry, but may be started by hand and, with the Go binding, may use their own scoperunner. In other words, there may not be any exec call at all. (That's the case for many of the tests too.)

Revision history for this message
Michi Henning (michihenning) wrote :

> TMPDIR is currently set to:
> setenv("TMPDIR", cache_dir_.c_str(), 1);
>
> Based on what you set XDG_DATA_HOME and that my recommendation was to set it
> to 'XDG_DATA_HOME=$HOME/.local/share', it seems that cache_dir_.c_str() is
> '~/.local/share/' which is not a writable path.

Not quite. cache_dir_ is $HOME/.local/share/unity-scopes/<scope_type>/<scope_id>

For example: /home/michi/.local/share/unity-scopes/leaf-net/com.triodia.scopes.michiscope

In other words, I was setting TMPDIR to the same location as cache_dir_, which is the scope's writable data directory.

> TMPDIR should be set like so:
>
> TMPDIR=$XDG_RUNTIME_DIR/confined-scopes/leaf-net/<'name' from click manifest>

I can't get at the click manifest. All I have is the scope ID. I *think* that's always the same as the click manifest name?

> We want to have TMPDIR be set to something in /run because if a scope doesn't
> clean up after itself, at least a reboot will remove the files (this is what
> we do for apps).

Yes, I agree with that, something under /run/user/<uid> is better, so it gets cleaned up eventually.

So, I could do:

/run/user/<uid>/confined-scopes/<scope_type>/<scope_id>

For example, TMPDIR would be:

/run/user/1000/confined-scopes/leaf-net/com.triodia.scopes.michiscope

Whether to substitute "leaf-net", "leaf-fs", or "aggregator" (or "unconfined", if we prefer that) would depend on what cache directory I found earlier: if the cache directory contains "leaf-fs", TMPDIR would contain "leaf-fs" too.

One other thing though… Does it makes sense to have XDG_RUNTIME_DIR set to /run/user/<uid>?
Considering that this is not a location the scope can write to, wouldn't it be better to set
XDG_RUNTIME_DIR to /run/user/1000/confined-scopes/leaf-net/com.triodia.scopes.michiscope,
and TMPDIR to /run/user/1000/confined-scopes/leaf-net/com.triodia.scopes.michiscope/tmp?

Aargh… What should an *unconfined* scope have in that path? Surely not "confined-scopes"?
Would it be better to use just "scopes" whether a scope is confined or not? E.g, for a leaf-net scope:

/run/user/1000/scopes/leaf-net/com.triodia.scopes.michiscope

And for an aggregator:

/run/user/1000/scopes/aggregator/com.triodia.scopes.michiscope (or possibly "unconfined" instead of "aggregator")

Would that work?

There is also the issue with deeply-nested paths under /run/user/<uid>. As you say, things under /run/user/<uid> may be periodically removed. I assume this means that I should create the directory hierarchy (whichever one we settle on) under /run/user/<uid> if it does not exist? (For now, I'll be creating the directories, with permission 0700.)

> Also, PATH and LD_LIBRARY_PATH are being unconditionally set. They should only
> be set in the manner you are setting them if they are not already set.

I wasn't sure whether it's a good idea to rely on the environment that is inherited by the scoperunner, which is why I smashed these two variables. I'll change the code to prepend to LD_LIBRARY_PATH and PATH instead.

Revision history for this message
Michi Henning (michihenning) wrote :

The scope's tmp dir is now available via ScopeBase::tmp_directory().

I've removed the environment variable settings, except for LD_LIBRARY_PATH,
which is set by the registry and the scoperunner.

The scope loader uses immediate binding, so we get a sensible error message
if a symbol cannot be resolved when the run time is created, rather than
having the scope fall over after it has been started due to a library
it depends on not being found.

I'm not setting LD_LIBRARY_PATH in RuntimeImpl::run_scope().

It's not impossible to do this, but hard:
getenv()/setenv() are not thread-safe. To do this properly, I'd have
to read the current LD_LIBRARY_PATH setting, modify it for the scope about
to be run and, once the scope has launched (or not), restore the previous
setting again, all while holding a lock. Otherwise, if more than
one run time instance is created in the same process, each for a different
scope, LD_LIBRARY_PATH would grow by two directories for each scope.

What this means is that a custom scope runner will have to set LD_LIBRARY_PATH
to include <scope_config_dir> and <scope_config_dir>/lib before instantiating
the run time. Seeing that we won't write scope runners by the dozen, I suspect
this is the more sensible course of action.

There is no need to set PATH. The scope *knows* what it has installed and where,
so there is no need to add anything special to the PATH just for the scope.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michal Hruby (mhr3) wrote :

23 - (c++)"unity::scopes::Category::Category(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unity::scopes::CategoryRenderer const&)@Base" 0.4.0+14.04.20140312.1
24 + (c++)"unity::scopes::Category::Category(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unity::scopes::CategoryRenderer const&)@Base" 0replaceme

Something wrong here, it just replaced the version with 0replaceme, revert pls.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michi Henning (michihenning) wrote :

The latest version uses the "try-and-see-what-you-get" approach.

If the scope is unconfined, the two directories below data_dir (unconfined/<scope_id>) are created automatically (if possible). If the directory exists, an attempt is made to create a tmp file. If that succeeds, the scope is unconfined. Otherwise, the scope is confined (leaf-net).

The click installation will have to create <data_dir>/leaf-net. If the scope's profile allows the scope to create <data_dir>/leaf-net/<scope_id>, it will do so. Otherwise, the click installation will have to create that directory for the scope.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michi Henning (michihenning) wrote :

Could someone review this please?

Revision history for this message
Pete Woods (pete-woods) :
review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Pete Woods (pete-woods) wrote :

D'oh! Merge fail!

424. By Michi Henning

Merged devel and resolved conflicts.

Revision history for this message
Michal Hruby (mhr3) wrote :

Could you also update the description and commit message please? Seems like this isn't doing much with environment variables anymore.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'HACKING'
--- HACKING 2014-07-10 00:24:33 +0000
+++ HACKING 2014-07-30 20:39:51 +0000
@@ -125,7 +125,7 @@
125 $ make formatcode125 $ make formatcode
126126
127Thread and address sanitizer127Thread and address sanitizer
128----------------128----------------------------
129129
130Set SANITIZER to "thread" or "address" to build with the130Set SANITIZER to "thread" or "address" to build with the
131corresponding sanitizer enabled.131corresponding sanitizer enabled.
132132
=== modified file 'RELEASE_NOTES.md'
--- RELEASE_NOTES.md 2014-07-28 13:45:38 +0000
+++ RELEASE_NOTES.md 2014-07-30 20:39:51 +0000
@@ -3,10 +3,12 @@
33
4Changes in version 0.6.04Changes in version 0.6.0
5========================5========================
6 - Added tmp_directory() method to ScopeBase, so a scope can find out where it can write temporary files.
7
8 - Added cache_directory() method to ScopeBase, so a scope can find out where it can write its files.
9
6 - Upgraded finished() callback to be more flexible and expandable.10 - Upgraded finished() callback to be more flexible and expandable.
711
8 - Added cache_directory() method to ScopeBase, so a scope can find out where it can write its files.
9
10 - Refactored scoperunner and ScopeLoader. ScopeLoader no longer knows about the registry and12 - Refactored scoperunner and ScopeLoader. ScopeLoader no longer knows about the registry and
11 scoperunner now calls RuntimeImpl::run_scope() to set the scope running, instead of duplicating13 scoperunner now calls RuntimeImpl::run_scope() to set the scope running, instead of duplicating
12 lots of functionality.14 lots of functionality.
1315
=== modified file 'debian/libunity-scopes2.symbols'
--- debian/libunity-scopes2.symbols 2014-07-29 10:22:45 +0000
+++ debian/libunity-scopes2.symbols 2014-07-30 20:39:51 +0000
@@ -753,7 +753,7 @@
753 (c++)"unity::scopes::internal::RuntimeImpl::reply_reaper() const@Base" 0.4.0+14.04.20140312.1753 (c++)"unity::scopes::internal::RuntimeImpl::reply_reaper() const@Base" 0.4.0+14.04.20140312.1
754 (c++)"unity::scopes::internal::RuntimeImpl::ss_configfile() const@Base" 0.4.4+14.10.20140508754 (c++)"unity::scopes::internal::RuntimeImpl::ss_configfile() const@Base" 0.4.4+14.10.20140508
755 (c++)"unity::scopes::internal::RuntimeImpl::waiter_thread(std::shared_ptr<unity::scopes::internal::ThreadSafeQueue<std::future<void> > > const&) const@Base" 0.4.3+14.10.20140428755 (c++)"unity::scopes::internal::RuntimeImpl::waiter_thread(std::shared_ptr<unity::scopes::internal::ThreadSafeQueue<std::future<void> > > const&) const@Base" 0.4.3+14.10.20140428
756 (c++)"unity::scopes::internal::RuntimeImpl::find_cache_dir() const@Base" 0replaceme756 (c++)"unity::scopes::internal::RuntimeImpl::find_cache_dir(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) const@Base" 0replaceme
757 (c++)"unity::scopes::internal::RuntimeImpl::proxy_to_string(std::shared_ptr<unity::scopes::Object> const&) const@Base" 0.4.0+14.04.20140312.1757 (c++)"unity::scopes::internal::RuntimeImpl::proxy_to_string(std::shared_ptr<unity::scopes::Object> const&) const@Base" 0.4.0+14.04.20140312.1
758 (c++)"unity::scopes::internal::RuntimeImpl::string_to_proxy(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const@Base" 0.4.0+14.04.20140312.1758 (c++)"unity::scopes::internal::RuntimeImpl::string_to_proxy(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const@Base" 0.4.0+14.04.20140312.1
759 (c++)"unity::scopes::internal::RuntimeImpl::registry_identity() const@Base" 0.4.0+14.04.20140312.1759 (c++)"unity::scopes::internal::RuntimeImpl::registry_identity() const@Base" 0.4.0+14.04.20140312.1
@@ -837,6 +837,7 @@
837 (c++)"unity::scopes::internal::StateReceiverObject::state_received() const@Base" 0.4.2+14.04.20140404.2837 (c++)"unity::scopes::internal::StateReceiverObject::state_received() const@Base" 0.4.2+14.04.20140404.2
838 (c++)"unity::scopes::QueryBase::valid() const@Base" 0.4.3+14.10.20140428838 (c++)"unity::scopes::QueryBase::valid() const@Base" 0.4.3+14.10.20140428
839 (c++)"unity::scopes::QueryBase::settings() const@Base" 0replaceme839 (c++)"unity::scopes::QueryBase::settings() const@Base" 0replaceme
840 (c++)"unity::scopes::ScopeBase::tmp_directory() const@Base" 0replaceme
840 (c++)"unity::scopes::ScopeBase::cache_directory() const@Base" 0replaceme841 (c++)"unity::scopes::ScopeBase::cache_directory() const@Base" 0replaceme
841 (c++)"unity::scopes::ScopeBase::scope_directory() const@Base" 0.4.2+14.04.20140404.2842 (c++)"unity::scopes::ScopeBase::scope_directory() const@Base" 0.4.2+14.04.20140404.2
842 (c++)"unity::scopes::ScopeBase::registry() const@Base" 0replaceme843 (c++)"unity::scopes::ScopeBase::registry() const@Base" 0replaceme
843844
=== modified file 'include/unity/scopes/AbstractScopeBase.h'
--- include/unity/scopes/AbstractScopeBase.h 2014-07-10 02:22:23 +0000
+++ include/unity/scopes/AbstractScopeBase.h 2014-07-30 20:39:51 +0000
@@ -53,6 +53,7 @@
53 virtual PreviewQueryBase::UPtr preview(Result const& result, ActionMetadata const& metadata) = 0;53 virtual PreviewQueryBase::UPtr preview(Result const& result, ActionMetadata const& metadata) = 0;
54 virtual std::string scope_directory() const = 0;54 virtual std::string scope_directory() const = 0;
55 virtual std::string cache_directory() const = 0;55 virtual std::string cache_directory() const = 0;
56 virtual std::string tmp_directory() const = 0;
56 virtual unity::scopes::RegistryProxy registry() const = 0;57 virtual unity::scopes::RegistryProxy registry() const = 0;
57 virtual VariantMap settings() const = 0;58 virtual VariantMap settings() const = 0;
58/// @endcond59/// @endcond
5960
=== modified file 'include/unity/scopes/ScopeBase.h'
--- include/unity/scopes/ScopeBase.h 2014-07-10 22:53:35 +0000
+++ include/unity/scopes/ScopeBase.h 2014-07-30 20:39:51 +0000
@@ -90,6 +90,7 @@
90 virtual void start(std::string const& scope_id); // Optional90 virtual void start(std::string const& scope_id); // Optional
91 virtual void stop(); // Optional91 virtual void stop(); // Optional
92 virtual void run(); // Optional92 virtual void run(); // Optional
93 // ...
93};94};
94~~~95~~~
9596
@@ -261,15 +262,29 @@
261 \note The cache directory is available only after this ScopeBase is instantiated; do not262 \note The cache directory is available only after this ScopeBase is instantiated; do not
262 call this method from the constructor!263 call this method from the constructor!
263264
264 \return The root directory of the filesystem sub-tree that is writable for the scope.265 \return The root directory of a filesystem sub-tree that is writable for the scope.
265 \throws LogicException if called from the constructor of this instance.266 \throws LogicException if called from the constructor of this instance.
266 */267 */
267 virtual std::string cache_directory() const final;268 virtual std::string cache_directory() const final;
268269
269 /**270 /**
271 \brief Returns a tmp directory that is (exclusively) writable for the scope.
272
273 This directory is periodically cleaned of unused files. The exact amount of time
274 may vary, but is on the order of a few hours.
275
276 \note The tmp directory is available only after this ScopeBase is instantiated; do not
277 call this method from the constructor!
278
279 \return A directory for temporary files.
280 \throws LogicException if called from the constructor of this instance.
281 */
282 virtual std::string tmp_directory() const final;
283
284 /**
270 \brief Returns the proxy to the registry.285 \brief Returns the proxy to the registry.
271286
272 \note The registr proxy is available only after this ScopeBase is instantiated; do not287 \note The registry proxy is available only after this ScopeBase is instantiated; do not
273 call this method from the constructor!288 call this method from the constructor!
274289
275 \return The proxy to the registry.290 \return The proxy to the registry.
276291
=== modified file 'include/unity/scopes/internal/DynamicLoader.h'
--- include/unity/scopes/internal/DynamicLoader.h 2014-02-18 05:04:01 +0000
+++ include/unity/scopes/internal/DynamicLoader.h 2014-07-30 20:39:51 +0000
@@ -86,7 +86,7 @@
86 automatic, noclose86 automatic, noclose
87 };87 };
8888
89 static UPtr create(std::string const& path, Binding b = Binding::lazy, Unload ul = Unload::automatic);89 static UPtr create(std::string const& path, Binding b = Binding::now, Unload ul = Unload::automatic);
9090
91 typedef void (*VoidFunc)();91 typedef void (*VoidFunc)();
92 VoidFunc find_function(std::string const& symbol);92 VoidFunc find_function(std::string const& symbol);
9393
=== modified file 'include/unity/scopes/internal/RuntimeImpl.h'
--- include/unity/scopes/internal/RuntimeImpl.h 2014-07-22 08:02:32 +0000
+++ include/unity/scopes/internal/RuntimeImpl.h 2014-07-30 20:39:51 +0000
@@ -53,8 +53,8 @@
53 Reaper::SPtr reply_reaper() const;53 Reaper::SPtr reply_reaper() const;
54 ThreadPool::SPtr async_pool() const;54 ThreadPool::SPtr async_pool() const;
55 ThreadSafeQueue<std::future<void>>::SPtr future_queue() const;55 ThreadSafeQueue<std::future<void>>::SPtr future_queue() const;
56 void run_scope(ScopeBase* const scope_base, std::string const& scope_ini_file);56 void run_scope(ScopeBase* scope_base, std::string const& scope_ini_file);
57 void run_scope(ScopeBase* const scope_base, std::string const& runtime_ini_file, std::string const& scope_ini_file);57 void run_scope(ScopeBase* scope_base, std::string const& runtime_ini_file, std::string const& scope_ini_file);
5858
59 ObjectProxy string_to_proxy(std::string const& s) const;59 ObjectProxy string_to_proxy(std::string const& s) const;
60 std::string proxy_to_string(ObjectProxy const& proxy) const;60 std::string proxy_to_string(ObjectProxy const& proxy) const;
@@ -64,7 +64,7 @@
64private:64private:
65 RuntimeImpl(std::string const& scope_id, std::string const& configfile);65 RuntimeImpl(std::string const& scope_id, std::string const& configfile);
66 void waiter_thread(ThreadSafeQueue<std::future<void>>::SPtr const& queue) const noexcept;66 void waiter_thread(ThreadSafeQueue<std::future<void>>::SPtr const& queue) const noexcept;
67 std::string find_cache_dir() const;67 std::string find_cache_dir(std::string& confinement_type) const;
6868
69 bool destroyed_;69 bool destroyed_;
70 std::string scope_id_;70 std::string scope_id_;
@@ -78,6 +78,7 @@
78 int reap_expiry_;78 int reap_expiry_;
79 int reap_interval_;79 int reap_interval_;
80 std::string data_dir_;80 std::string data_dir_;
81 std::string tmp_dir_;
81 mutable Reaper::SPtr reply_reaper_;82 mutable Reaper::SPtr reply_reaper_;
82 mutable ThreadPool::SPtr async_pool_; // Pool of invocation threads for async query creation83 mutable ThreadPool::SPtr async_pool_; // Pool of invocation threads for async query creation
83 mutable ThreadSafeQueue<std::future<void>>::SPtr future_queue_;84 mutable ThreadSafeQueue<std::future<void>>::SPtr future_queue_;
8485
=== modified file 'include/unity/scopes/internal/ScopeBaseImpl.h'
--- include/unity/scopes/internal/ScopeBaseImpl.h 2014-07-04 05:50:16 +0000
+++ include/unity/scopes/internal/ScopeBaseImpl.h 2014-07-30 20:39:51 +0000
@@ -48,6 +48,9 @@
48 void set_cache_directory(std::string const& path);48 void set_cache_directory(std::string const& path);
49 std::string cache_directory() const;49 std::string cache_directory() const;
5050
51 void set_tmp_directory(std::string const& path);
52 std::string tmp_directory() const;
53
51 void set_registry(RegistryProxy const& registry);54 void set_registry(RegistryProxy const& registry);
52 RegistryProxy registry() const;55 RegistryProxy registry() const;
5356
@@ -62,6 +65,9 @@
62 std::string cache_directory_;65 std::string cache_directory_;
63 bool cache_dir_initialized_;66 bool cache_dir_initialized_;
6467
68 std::string tmp_directory_;
69 bool tmp_dir_initialized_;
70
65 unity::scopes::RegistryProxy registry_;71 unity::scopes::RegistryProxy registry_;
66 bool registry_initialized_;72 bool registry_initialized_;
6773
6874
=== modified file 'scoperunner/scoperunner.cpp'
--- scoperunner/scoperunner.cpp 2014-07-29 10:22:45 +0000
+++ scoperunner/scoperunner.cpp 2014-07-30 20:39:51 +0000
@@ -29,8 +29,10 @@
29#include <unity/UnityExceptions.h>29#include <unity/UnityExceptions.h>
3030
31#include <unity/scopes/internal/max_align_clang_bug.h> // TODO: remove this once clang 3.5.2 is released31#include <unity/scopes/internal/max_align_clang_bug.h> // TODO: remove this once clang 3.5.2 is released
32#include <boost/filesystem/path.hpp>32#include <boost/algorithm/string.hpp>
33#include <boost/filesystem.hpp>
33#include <core/posix/signal.h>34#include <core/posix/signal.h>
35#include <core/posix/this_process.h>
3436
35#include <cassert>37#include <cassert>
36#include <future>38#include <future>
@@ -69,13 +71,29 @@
69 std::thread trap_worker([trap]() { trap->run(); });71 std::thread trap_worker([trap]() { trap->run(); });
7072
71 // Figure out what the scope ID is from the name of the scope config file.73 // Figure out what the scope ID is from the name of the scope config file.
72 filesystem::path scope_config_path(scope_config);74 auto scope_config_path = filesystem::canonical(scope_config);
73 string lib_dir = scope_config_path.parent_path().native();75 string lib_dir = scope_config_path.parent_path().native();
74 string scope_id = scope_config_path.stem().native();76 string scope_id = scope_config_path.stem().native();
7577
76 if (!lib_dir.empty())
77 {78 {
78 lib_dir += '/';79 // Make sure we set LD_LIBRARY_PATH to include <lib_dir> and <lib_dir>/lib
80 // before loading the scope's .so.
81 string scope_ld_lib_path = lib_dir + ":" + lib_dir + "/lib";
82 string ld_lib_path = core::posix::this_process::env::get("LD_LIBRARY_PATH", "");
83 if (!starts_with(ld_lib_path, lib_dir))
84 {
85 scope_ld_lib_path = scope_ld_lib_path + (ld_lib_path.empty() ? "" : (":" + ld_lib_path));
86 try
87 {
88 // No overwrite option for this_process::env::set(), need to unset first
89 core::posix::this_process::env::unset_or_throw("LD_LIBRARY_PATH");
90 core::posix::this_process::env::set_or_throw("LD_LIBRARY_PATH", scope_ld_lib_path);
91 }
92 catch (std::exception const&)
93 {
94 throw unity::ResourceException("cannot set LD_LIBRARY_PATH for scope " + scope_id);
95 }
96 }
79 }97 }
8098
81 int exit_status = 1;99 int exit_status = 1;
@@ -83,9 +101,9 @@
83 {101 {
84 // For a scope_id "Fred", we look for the library as "libFred.so", "Fred.so", and "scope.so".102 // For a scope_id "Fred", we look for the library as "libFred.so", "Fred.so", and "scope.so".
85 vector<string> libs;103 vector<string> libs;
86 libs.push_back(lib_dir + "lib" + scope_id + ".so");104 libs.push_back(lib_dir + "/lib" + scope_id + ".so");
87 libs.push_back(lib_dir + scope_id + ".so");105 libs.push_back(lib_dir + "/" + scope_id + ".so");
88 libs.push_back(lib_dir + "scope.so");106 libs.push_back(lib_dir + "/scope.so");
89 string failed_libs;107 string failed_libs;
90 ScopeLoader::SPtr loader;108 ScopeLoader::SPtr loader;
91 exception_ptr ep;109 exception_ptr ep;
92110
=== modified file 'src/scopes/ScopeBase.cpp'
--- src/scopes/ScopeBase.cpp 2014-07-10 22:53:35 +0000
+++ src/scopes/ScopeBase.cpp 2014-07-30 20:39:51 +0000
@@ -82,6 +82,11 @@
82 return p->cache_directory();82 return p->cache_directory();
83}83}
8484
85std::string ScopeBase::tmp_directory() const
86{
87 return p->tmp_directory();
88}
89
85RegistryProxy ScopeBase::registry() const90RegistryProxy ScopeBase::registry() const
86{91{
87 return p->registry();92 return p->registry();
8893
=== modified file 'src/scopes/internal/RegistryObject.cpp'
--- src/scopes/internal/RegistryObject.cpp 2014-07-28 03:51:36 +0000
+++ src/scopes/internal/RegistryObject.cpp 2014-07-30 20:39:51 +0000
@@ -24,6 +24,8 @@
24#include <unity/UnityExceptions.h>24#include <unity/UnityExceptions.h>
25#include <unity/util/ResourcePtr.h>25#include <unity/util/ResourcePtr.h>
2626
27#include <boost/algorithm/string.hpp>
28#include <boost/filesystem.hpp>
27#include <core/posix/child_process.h>29#include <core/posix/child_process.h>
28#include <core/posix/exec.h>30#include <core/posix/exec.h>
2931
@@ -413,13 +415,26 @@
413 argv.insert(argv.end(), {exec_data_.runtime_config, exec_data_.scope_config});415 argv.insert(argv.end(), {exec_data_.runtime_config, exec_data_.scope_config});
414 }416 }
415417
416 std::map<std::string, std::string> env;418 {
417 core::posix::this_process::env::for_each([&env](const std::string& key, const std::string& value)419 // Copy current env vars into env.
418 {420 std::map<std::string, std::string> env;
419 env.insert(std::make_pair(key, value));421 core::posix::this_process::env::for_each([&env](const std::string& key, const std::string& value)
420 });422 {
421423 env.insert(std::make_pair(key, value));
422 {424 });
425
426 // Make sure we set LD_LIBRARY_PATH to include <lib_dir> and <lib_dir>/lib
427 // before exec'ing the scope.
428 auto scope_config_path = boost::filesystem::canonical(exec_data_.scope_config);
429 string lib_dir = scope_config_path.parent_path().native();
430 string scope_ld_lib_path = lib_dir + ":" + lib_dir + "/lib";
431 string ld_lib_path = core::posix::this_process::env::get("LD_LIBRARY_PATH", "");
432 if (!boost::algorithm::starts_with(ld_lib_path, lib_dir))
433 {
434 scope_ld_lib_path = scope_ld_lib_path + (ld_lib_path.empty() ? "" : (":" + ld_lib_path));
435 }
436 env["LD_LIBRARY_PATH"] = scope_ld_lib_path; // Overwrite any LD_LIBRARY_PATH entry that may already be there.
437
423 process_ = executor->exec(program, argv, env,438 process_ = executor->exec(program, argv, env,
424 core::posix::StandardStream::stdin | core::posix::StandardStream::stdout,439 core::posix::StandardStream::stdin | core::posix::StandardStream::stdout,
425 exec_data_.confinement_profile);440 exec_data_.confinement_profile);
426441
=== modified file 'src/scopes/internal/RuntimeImpl.cpp'
--- src/scopes/internal/RuntimeImpl.cpp 2014-07-29 10:22:45 +0000
+++ src/scopes/internal/RuntimeImpl.cpp 2014-07-30 20:39:51 +0000
@@ -280,12 +280,12 @@
280 return future_queue_; // Immutable280 return future_queue_; // Immutable
281}281}
282282
283void RuntimeImpl::run_scope(ScopeBase *const scope_base, string const& scope_ini_file)283void RuntimeImpl::run_scope(ScopeBase* scope_base, string const& scope_ini_file)
284{284{
285 run_scope(scope_base, "", scope_ini_file);285 run_scope(scope_base, "", scope_ini_file);
286}286}
287287
288void RuntimeImpl::run_scope(ScopeBase *const scope_base, string const& runtime_ini_file, string const& scope_ini_file)288void RuntimeImpl::run_scope(ScopeBase* scope_base, string const& runtime_ini_file, string const& scope_ini_file)
289{289{
290 if (!scope_base)290 if (!scope_base)
291 {291 {
@@ -301,7 +301,7 @@
301 auto mw = factory()->create(scope_id_, reg_conf.mw_kind(), reg_conf.mw_configfile());301 auto mw = factory()->create(scope_id_, reg_conf.mw_kind(), reg_conf.mw_configfile());
302302
303 {303 {
304 boost::filesystem::path dir = boost::filesystem::path(scope_ini_file).parent_path();304 boost::filesystem::path dir = boost::filesystem::canonical(scope_ini_file).parent_path();
305 scope_base->p->set_scope_directory(dir.native());305 scope_base->p->set_scope_directory(dir.native());
306 }306 }
307307
@@ -328,7 +328,23 @@
328328
329 scope_base->p->set_registry(registry_);329 scope_base->p->set_registry(registry_);
330330
331 scope_base->p->set_cache_directory(find_cache_dir());331 string confinement_type;
332 scope_base->p->set_cache_directory(find_cache_dir(confinement_type));
333
334 {
335 // Set tmp dir.
336 // We need to create any directories under /run/user/<uid> because they might not
337 // exist. (/run/user/<uid> gets cleaned out periodically.)
338 string path = string("/run/user/") + std::to_string(geteuid());
339 path += "/scopes";
340 ::mkdir(path.c_str(), 0700);
341 path += "/" + confinement_type;
342 ::mkdir(path.c_str(), 0700);
343 path += "/" + scope_id_;
344 ::mkdir(path.c_str(), 0700);
345
346 scope_base->p->set_tmp_directory(path);
347 }
332348
333 scope_base->start(scope_id_);349 scope_base->start(scope_id_);
334350
@@ -391,7 +407,7 @@
391 }407 }
392}408}
393409
394string RuntimeImpl::find_cache_dir() const410string RuntimeImpl::find_cache_dir(string& confinement_type) const
395{411{
396 // TODO: HACK: Until we get a fancier Apparmor query API, we try412 // TODO: HACK: Until we get a fancier Apparmor query API, we try
397 // to create the scope cache dir and figure out whether413 // to create the scope cache dir and figure out whether
@@ -403,13 +419,18 @@
403 // Otherwise, the scope must be confined, in which case419 // Otherwise, the scope must be confined, in which case
404 // we create <data_dir>/leaf-net and <data_dir>/leaf-net/<scope_id_>.420 // we create <data_dir>/leaf-net and <data_dir>/leaf-net/<scope_id_>.
405421
406 string cache_dir = data_dir_ + "/unconfined/" + scope_id_;422 ::mkdir(data_dir_.c_str(), 0700); // We don't care if this fails.
423
424 // Assume we are unconfined initially.
425 confinement_type = "unconfined";
426 string dir = data_dir_ + "/" + confinement_type;
407427
408 // The following two mkdir() calls will fail if the scope is confined or428 // The following two mkdir() calls will fail if the scope is confined or
409 // the directories exist already.429 // the directories exist already.
410 ::mkdir((data_dir_ + "/unconfined").c_str(), 0700);430 ::mkdir(dir.c_str(), 0700);
411 ::mkdir(cache_dir.c_str(), 0700);431 dir += "/" + scope_id_;
412 string tmp = cache_dir + "/.unconfined_scope_XXXXXX";432 ::mkdir(dir.c_str(), 0700);
433 string tmp = dir + "/.scope_tmp_XXXXXX";
413 int fd = mkstemp(const_cast<char*>(tmp.c_str())); // mkstemp() modifies its argument434 int fd = mkstemp(const_cast<char*>(tmp.c_str())); // mkstemp() modifies its argument
414 if (fd != -1)435 if (fd != -1)
415 {436 {
@@ -420,11 +441,13 @@
420 else441 else
421 {442 {
422 // mkstemp() failed, the scope must be confined.443 // mkstemp() failed, the scope must be confined.
423 ::mkdir((data_dir_ + "/leaf-net").c_str(), 0700);444 confinement_type = "leaf-net";
424 ::mkdir(cache_dir.c_str(), 0700);445 dir = data_dir_ + "/" + confinement_type;
425 cache_dir = data_dir_ + "/leaf-net/" + scope_id_;446 ::mkdir(dir.c_str(), 0700);
447 dir += "/" + scope_id_;
448 ::mkdir(dir.c_str(), 0700);
426 }449 }
427 return cache_dir;450 return dir;
428}451}
429452
430} // namespace internal453} // namespace internal
431454
=== modified file 'src/scopes/internal/ScopeBaseImpl.cpp'
--- src/scopes/internal/ScopeBaseImpl.cpp 2014-07-04 05:50:16 +0000
+++ src/scopes/internal/ScopeBaseImpl.cpp 2014-07-30 20:39:51 +0000
@@ -82,6 +82,27 @@
82 return cache_directory_;82 return cache_directory_;
83}83}
8484
85void ScopeBaseImpl::set_tmp_directory(std::string const& path)
86{
87 lock_guard<mutex> lock(mutex_);
88 tmp_directory_ = path;
89 tmp_dir_initialized_ = true;
90}
91
92std::string ScopeBaseImpl::tmp_directory() const
93{
94 lock_guard<mutex> lock(mutex_);
95 if (!tmp_dir_initialized_)
96 {
97 throw LogicException("ScopeBase::tmp_directory() cannot be called from constructor");
98 }
99 if (tmp_directory_.empty())
100 {
101 throw ConfigException("ScopeBase::tmp_directory(): no tmp directory available");
102 }
103 return tmp_directory_;
104}
105
85void ScopeBaseImpl::set_registry(RegistryProxy const& registry)106void ScopeBaseImpl::set_registry(RegistryProxy const& registry)
86{107{
87 lock_guard<mutex> lock(mutex_);108 lock_guard<mutex> lock(mutex_);
88109
=== modified file 'src/scopes/internal/zmq_middleware/ZmqConfig.cpp'
--- src/scopes/internal/zmq_middleware/ZmqConfig.cpp 2014-07-25 01:23:02 +0000
+++ src/scopes/internal/zmq_middleware/ZmqConfig.cpp 2014-07-30 20:39:51 +0000
@@ -55,7 +55,7 @@
5555
56 // Set the endpoint directory if it was not set explicitly.56 // Set the endpoint directory if it was not set explicitly.
57 // We look for the XDG_RUNTIME_DIR env variable. If that is not57 // We look for the XDG_RUNTIME_DIR env variable. If that is not
58 // set, we give up.58 // set correctly, we give up.
59 if (endpoint_dir_.empty())59 if (endpoint_dir_.empty())
60 {60 {
61 char* xdg_runtime_dir = secure_getenv("XDG_RUNTIME_DIR");61 char* xdg_runtime_dir = secure_getenv("XDG_RUNTIME_DIR");
@@ -64,6 +64,10 @@
64 throw ConfigException("No endpoint directories specified, and XDG_RUNTIME_DIR "64 throw ConfigException("No endpoint directories specified, and XDG_RUNTIME_DIR "
65 "environment variable not set");65 "environment variable not set");
66 }66 }
67 if (*xdg_runtime_dir != '/')
68 {
69 throw ConfigException("Invalid XDG_RUNTIME_DIR: path must be absolute");
70 }
67 endpoint_dir_ = string(xdg_runtime_dir) + "/zmq";71 endpoint_dir_ = string(xdg_runtime_dir) + "/zmq";
68 }72 }
6973
7074
=== modified file 'test/gtest/scopes/IdleShutdown/SlowSearchScope.h'
--- test/gtest/scopes/IdleShutdown/SlowSearchScope.h 2014-07-04 03:26:15 +0000
+++ test/gtest/scopes/IdleShutdown/SlowSearchScope.h 2014-07-30 20:39:51 +0000
@@ -21,20 +21,20 @@
2121
22#include <unity/scopes/ScopeBase.h>22#include <unity/scopes/ScopeBase.h>
2323
24using namespace std;24class SlowSearchScope : public unity::scopes::ScopeBase
25using namespace unity::scopes;
26
27class SlowSearchScope : public ScopeBase
28{25{
29public:26public:
30 virtual void start(string const&) override;27 virtual void start(std::string const&) override;
3128
32 virtual void stop() override;29 virtual void stop() override;
3330
34 virtual void run() override;31 virtual void run() override;
3532
36 virtual SearchQueryBase::UPtr search(CannedQuery const &, SearchMetadata const &) override;33 virtual unity::scopes::SearchQueryBase::UPtr search(unity::scopes::CannedQuery const &,
37 virtual PreviewQueryBase::UPtr preview(Result const&, ActionMetadata const &) override;34 unity::scopes::SearchMetadata const &) override;
35
36 virtual unity::scopes::PreviewQueryBase::UPtr preview(unity::scopes::Result const&,
37 unity::scopes::ActionMetadata const &) override;
38};38};
3939
40#endif40#endif
4141
=== modified file 'test/gtest/scopes/Invocation/EmptyScope.h'
--- test/gtest/scopes/Invocation/EmptyScope.h 2014-07-24 13:51:38 +0000
+++ test/gtest/scopes/Invocation/EmptyScope.h 2014-07-30 20:39:51 +0000
@@ -21,14 +21,13 @@
2121
22#include <unity/scopes/ScopeBase.h>22#include <unity/scopes/ScopeBase.h>
2323
24using namespace std;24class EmptyScope : public unity::scopes::ScopeBase
25using namespace unity::scopes;
26
27class EmptyScope : public ScopeBase
28{25{
29public:26public:
30 virtual SearchQueryBase::UPtr search(CannedQuery const &, SearchMetadata const &) override;27 virtual unity::scopes::SearchQueryBase::UPtr search(unity::scopes::CannedQuery const&,
31 virtual PreviewQueryBase::UPtr preview(Result const&, ActionMetadata const &) override;28 unity::scopes::SearchMetadata const&) override;
29 virtual unity::scopes::PreviewQueryBase::UPtr preview(unity::scopes::Result const&,
30 unity::scopes::ActionMetadata const&) override;
32};31};
3332
34#endif33#endif
3534
=== modified file 'test/gtest/scopes/Invocation/TestScope.cpp'
--- test/gtest/scopes/Invocation/TestScope.cpp 2014-07-24 15:00:18 +0000
+++ test/gtest/scopes/Invocation/TestScope.cpp 2014-07-30 20:39:51 +0000
@@ -76,7 +76,7 @@
76 return SearchQueryBase::UPtr(new TestQuery(query, metadata));76 return SearchQueryBase::UPtr(new TestQuery(query, metadata));
77}77}
7878
79PreviewQueryBase::UPtr TestScope::preview(Result const&, ActionMetadata const &)79PreviewQueryBase::UPtr TestScope::preview(Result const&, ActionMetadata const&)
80{80{
81 return nullptr; // unused81 return nullptr; // unused
82}82}
8383
=== modified file 'test/gtest/scopes/Invocation/TestScope.h'
--- test/gtest/scopes/Invocation/TestScope.h 2014-07-24 13:51:38 +0000
+++ test/gtest/scopes/Invocation/TestScope.h 2014-07-30 20:39:51 +0000
@@ -21,14 +21,13 @@
2121
22#include <unity/scopes/ScopeBase.h>22#include <unity/scopes/ScopeBase.h>
2323
24using namespace std;24class TestScope : public unity::scopes::ScopeBase
25using namespace unity::scopes;
26
27class TestScope : public ScopeBase
28{25{
29public:26public:
30 virtual SearchQueryBase::UPtr search(CannedQuery const &, SearchMetadata const &) override;27 virtual unity::scopes::SearchQueryBase::UPtr search(unity::scopes::CannedQuery const&,
31 virtual PreviewQueryBase::UPtr preview(Result const&, ActionMetadata const &) override;28 unity::scopes::SearchMetadata const&) override;
29 virtual unity::scopes::PreviewQueryBase::UPtr preview(unity::scopes::Result const&,
30 unity::scopes::ActionMetadata const&) override;
32};31};
3332
34#endif33#endif
3534
=== modified file 'test/gtest/scopes/Registry/scopes/testscopeA/CMakeLists.txt'
--- test/gtest/scopes/Registry/scopes/testscopeA/CMakeLists.txt 2014-07-01 08:39:17 +0000
+++ test/gtest/scopes/Registry/scopes/testscopeA/CMakeLists.txt 2014-07-30 20:39:51 +0000
@@ -1,3 +1,7 @@
1add_library(testscopeA MODULE testscopeA.cpp)
2configure_file(testscopeA.ini.in testscopeA.ini)1configure_file(testscopeA.ini.in testscopeA.ini)
3configure_file(testscopeA-settings.ini.in testscopeA-settings.ini)2configure_file(testscopeA-settings.ini.in testscopeA-settings.ini)
3
4add_definitions(-DSCOPE_CONFIG_PATH="${CMAKE_CURRENT_BINARY_DIR}")
5
6add_library(testscopeA MODULE testscopeA.cpp)
7target_link_libraries(testscopeA ${LIBGTEST})
48
=== modified file 'test/gtest/scopes/Registry/scopes/testscopeA/testscopeA.cpp'
--- test/gtest/scopes/Registry/scopes/testscopeA/testscopeA.cpp 2014-07-04 03:26:15 +0000
+++ test/gtest/scopes/Registry/scopes/testscopeA/testscopeA.cpp 2014-07-30 20:39:51 +0000
@@ -22,6 +22,8 @@
22#include <unity/scopes/PreviewWidget.h>22#include <unity/scopes/PreviewWidget.h>
23#include <unity/scopes/SearchReply.h>23#include <unity/scopes/SearchReply.h>
2424
25#include <boost/algorithm/string.hpp>
26
25#define EXPORT __attribute__ ((visibility ("default")))27#define EXPORT __attribute__ ((visibility ("default")))
2628
27using namespace std;29using namespace std;
@@ -64,7 +66,14 @@
64class MyScope : public ScopeBase66class MyScope : public ScopeBase
65{67{
66public:68public:
67 virtual void start(string const&) override {}69 virtual void start(string const&) override
70 {
71 string ld_lib_path = getenv("LD_LIBRARY_PATH");
72 string expected_path_prefix = string(SCOPE_CONFIG_PATH) + ":" + SCOPE_CONFIG_PATH + "/lib";
73 // We don't use gtest here because then the scope would have to link against it,
74 // but libgtest.a isn't compiled with -fPIC.
75 assert(boost::algorithm::starts_with(ld_lib_path, expected_path_prefix));
76 }
6877
69 virtual void stop() override {}78 virtual void stop() override {}
7079
7180
=== modified file 'test/gtest/scopes/Runtime/TestScope.h'
--- test/gtest/scopes/Runtime/TestScope.h 2014-07-24 13:51:38 +0000
+++ test/gtest/scopes/Runtime/TestScope.h 2014-07-30 20:39:51 +0000
@@ -21,14 +21,13 @@
2121
22#include <unity/scopes/ScopeBase.h>22#include <unity/scopes/ScopeBase.h>
2323
24using namespace std;24class TestScope : public unity::scopes::ScopeBase
25using namespace unity::scopes;
26
27class TestScope : public ScopeBase
28{25{
29public:26public:
30 virtual SearchQueryBase::UPtr search(CannedQuery const&, SearchMetadata const&) override;27 virtual unity::scopes::SearchQueryBase::UPtr search(unity::scopes::CannedQuery const&,
31 virtual PreviewQueryBase::UPtr preview(Result const&, ActionMetadata const&) override;28 unity::scopes::SearchMetadata const&) override;
29 virtual unity::scopes::PreviewQueryBase::UPtr preview(unity::scopes::Result const&,
30 unity::scopes::ActionMetadata const&) override;
32};31};
3332
34#endif33#endif
3534
=== modified file 'test/gtest/scopes/internal/DynamicLoader/DynamicLoader_test.cpp'
--- test/gtest/scopes/internal/DynamicLoader/DynamicLoader_test.cpp 2014-07-25 07:29:19 +0000
+++ test/gtest/scopes/internal/DynamicLoader/DynamicLoader_test.cpp 2014-07-30 20:39:51 +0000
@@ -61,15 +61,15 @@
61TEST(DynamicLoader, flags)61TEST(DynamicLoader, flags)
62{62{
63 {63 {
64 DynamicLoader::UPtr dl = DynamicLoader::create(badlib);64 DynamicLoader::UPtr dl = DynamicLoader::create(badlib, DynamicLoader::Binding::lazy);
65 DynamicLoader::VoidFunc f = dl->find_function("test_function"); // Must work despite unreslved().65 DynamicLoader::VoidFunc f = dl->find_function("test_function"); // Must work despite unresolved().
66 EXPECT_NE(nullptr, f);66 EXPECT_NE(nullptr, f);
67 }67 }
6868
69 try69 try
70 {70 {
71 // Must fail because of unresolved symbol.71 // Must fail because of unresolved symbol.
72 DynamicLoader::UPtr dl = DynamicLoader::create(badlib, DynamicLoader::Binding::now);72 DynamicLoader::UPtr dl = DynamicLoader::create(badlib);
73 }73 }
74 catch (unity::ResourceException const& e)74 catch (unity::ResourceException const& e)
75 {75 {
7676
=== modified file 'test/gtest/scopes/internal/RegistryObject/CMakeLists.txt'
--- test/gtest/scopes/internal/RegistryObject/CMakeLists.txt 2014-05-07 04:48:26 +0000
+++ test/gtest/scopes/internal/RegistryObject/CMakeLists.txt 2014-07-30 20:39:51 +0000
@@ -1,3 +1,5 @@
1configure_file(scope.ini.in scope.ini)
2
1add_executable(RegistryObject_test RegistryObject_test.cpp)3add_executable(RegistryObject_test RegistryObject_test.cpp)
2target_link_libraries(RegistryObject_test ${TESTLIBS})4target_link_libraries(RegistryObject_test ${TESTLIBS})
35
46
=== modified file 'test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp'
--- test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp 2014-06-04 17:49:34 +0000
+++ test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp 2014-07-30 20:39:51 +0000
@@ -160,7 +160,7 @@
160 exec_data.scope_id = "scope-id";160 exec_data.scope_id = "scope-id";
161 exec_data.scoperunner_path = "/path/scoperunner";161 exec_data.scoperunner_path = "/path/scoperunner";
162 exec_data.runtime_config = "/path/runtime.ini";162 exec_data.runtime_config = "/path/runtime.ini";
163 exec_data.scope_config = "/path/scope.ini";163 exec_data.scope_config = "scope.ini";
164 exec_data.confinement_profile = confinement_profile;164 exec_data.confinement_profile = confinement_profile;
165 exec_data.timeout_ms = 1500;165 exec_data.timeout_ms = 1500;
166166
@@ -188,7 +188,7 @@
188{188{
189 EXPECT_CALL(*executor,189 EXPECT_CALL(*executor,
190 exec("/path/scoperunner", vector<string>190 exec("/path/scoperunner", vector<string>
191 { "/path/runtime.ini", "/path/scope.ini"}, _,191 { "/path/runtime.ini", "scope.ini"}, _,
192 StandardStream::stdin | StandardStream::stdout,192 StandardStream::stdin | StandardStream::stdout,
193 string())).WillOnce(193 string())).WillOnce(
194 Invoke(this, &TestRegistryObject::mock_exec));194 Invoke(this, &TestRegistryObject::mock_exec));
@@ -200,7 +200,7 @@
200{200{
201 EXPECT_CALL(*executor,201 EXPECT_CALL(*executor,
202 exec("/path/scoperunner", vector<string>202 exec("/path/scoperunner", vector<string>
203 { "/path/runtime.ini", "/path/scope.ini"}, _,203 { "/path/runtime.ini", "scope.ini"}, _,
204 StandardStream::stdin | StandardStream::stdout,204 StandardStream::stdin | StandardStream::stdout,
205 "confinement profile")).WillOnce(205 "confinement profile")).WillOnce(
206 Invoke(this, &TestRegistryObject::mock_exec));206 Invoke(this, &TestRegistryObject::mock_exec));
207207
=== added file 'test/gtest/scopes/internal/RegistryObject/scope.ini.in'
=== modified file 'test/gtest/scopes/internal/RuntimeImpl/CMakeLists.txt'
--- test/gtest/scopes/internal/RuntimeImpl/CMakeLists.txt 2014-07-07 23:53:36 +0000
+++ test/gtest/scopes/internal/RuntimeImpl/CMakeLists.txt 2014-07-30 20:39:51 +0000
@@ -1,9 +1,10 @@
1configure_file(Zmq.ini.in Zmq.ini)
2configure_file(Registry.ini.in Registry.ini)1configure_file(Registry.ini.in Registry.ini)
3configure_file(Runtime.ini.in Runtime.ini)2configure_file(Runtime.ini.in Runtime.ini)
3configure_file(TestScope.ini.in TestScope.ini)
4configure_file(Zmq.ini.in Zmq.ini)
45
5add_definitions(-DTEST_DIR="${CMAKE_CURRENT_BINARY_DIR}")6add_definitions(-DTEST_DIR="${CMAKE_CURRENT_BINARY_DIR}")
6add_executable(RuntimeImpl_test RuntimeImpl_test.cpp)7add_executable(RuntimeImpl_test RuntimeImpl_test.cpp TestScope.cpp)
7target_link_libraries(RuntimeImpl_test ${TESTLIBS})8target_link_libraries(RuntimeImpl_test ${TESTLIBS})
89
9add_test(RuntimeImpl RuntimeImpl_test)10add_test(RuntimeImpl RuntimeImpl_test)
1011
=== modified file 'test/gtest/scopes/internal/RuntimeImpl/Registry.ini.in'
--- test/gtest/scopes/internal/RuntimeImpl/Registry.ini.in 2014-05-01 02:58:33 +0000
+++ test/gtest/scopes/internal/RuntimeImpl/Registry.ini.in 2014-07-30 20:39:51 +0000
@@ -1,6 +1,6 @@
1[Registry]1[Registry]
2Middleware = Zmq2Middleware = Zmq
3Zmq.ConfigFile = Zmq.ini3Zmq.ConfigFile = @CMAKE_CURRENT_BINARY_DIR@/Zmq.ini
4Scoperunner.Path = /SomePath4Scoperunner.Path = /SomePath
5Scope.InstallDir = /tmp5Scope.InstallDir = /tmp
6Scope.InstallDir = /tmp6Scope.InstallDir = /tmp
77
=== modified file 'test/gtest/scopes/internal/RuntimeImpl/Runtime.ini.in'
--- test/gtest/scopes/internal/RuntimeImpl/Runtime.ini.in 2014-02-03 11:30:02 +0000
+++ test/gtest/scopes/internal/RuntimeImpl/Runtime.ini.in 2014-07-30 20:39:51 +0000
@@ -2,4 +2,5 @@
2Registry.Identity = Registry2Registry.Identity = Registry
3Registry.ConfigFile = @CMAKE_CURRENT_BINARY_DIR@/Registry.ini3Registry.ConfigFile = @CMAKE_CURRENT_BINARY_DIR@/Registry.ini
4Default.Middleware = Zmq4Default.Middleware = Zmq
5Zmq.ConfigFile = Zmq.ini5Zmq.ConfigFile = @CMAKE_CURRENT_BINARY_DIR@/Zmq.ini
6DataDir = @CMAKE_CURRENT_BINARY_DIR@/cache_dir
67
=== modified file 'test/gtest/scopes/internal/RuntimeImpl/RuntimeImpl_test.cpp'
--- test/gtest/scopes/internal/RuntimeImpl/RuntimeImpl_test.cpp 2014-07-10 00:37:18 +0000
+++ test/gtest/scopes/internal/RuntimeImpl/RuntimeImpl_test.cpp 2014-07-30 20:39:51 +0000
@@ -17,11 +17,17 @@
17 */17 */
1818
19#include <unity/scopes/internal/RuntimeImpl.h>19#include <unity/scopes/internal/RuntimeImpl.h>
20#include <unity/scopes/ScopeExceptions.h>
20#include <unity/UnityExceptions.h>21#include <unity/UnityExceptions.h>
21#include <unity/scopes/ScopeExceptions.h>22
2223#include "TestScope.h"
24
25#include <boost/algorithm/string.hpp>
26#include <boost/filesystem.hpp>
23#include <gtest/gtest.h>27#include <gtest/gtest.h>
2428
29#include <fcntl.h>
30
25using namespace std;31using namespace std;
26using namespace unity;32using namespace unity;
27using namespace unity::scopes;33using namespace unity::scopes;
@@ -29,9 +35,13 @@
2935
30TEST(RuntimeImpl, basic)36TEST(RuntimeImpl, basic)
31{37{
32 RuntimeImpl::UPtr rt = RuntimeImpl::create("testscope", TEST_DIR "/Runtime.ini");38 // Make sure we start out with a clean slate.
39 boost::filesystem::remove_all(TEST_DIR "/cache_dir");
40
41 RuntimeImpl::UPtr rt = RuntimeImpl::create("TestScope", TEST_DIR "/Runtime.ini");
3342
34 EXPECT_TRUE(rt->registry().get() != nullptr);43 EXPECT_TRUE(rt->registry().get() != nullptr);
44 EXPECT_TRUE(rt->registry()->identity() == "Registry");
35 EXPECT_TRUE(rt->factory());45 EXPECT_TRUE(rt->factory());
36 EXPECT_EQ(TEST_DIR "/Registry.ini", rt->registry_configfile());46 EXPECT_EQ(TEST_DIR "/Registry.ini", rt->registry_configfile());
3747
@@ -65,13 +75,41 @@
65{75{
66 try76 try
67 {77 {
68 RuntimeImpl::UPtr rt = RuntimeImpl::create("testscope", "NoSuchFile.ini");78 RuntimeImpl::UPtr rt = RuntimeImpl::create("TestScope", "NoSuchFile.ini");
69 }79 }
70 catch (ConfigException const& e)80 catch (ConfigException const& e)
71 {81 {
72 EXPECT_STREQ("unity::scopes::ConfigException: Cannot instantiate run time for testscope, "82 EXPECT_STREQ("unity::scopes::ConfigException: Cannot instantiate run time for TestScope, "
73 "config file: NoSuchFile.ini:\n"83 "config file: NoSuchFile.ini:\n"
74 " unity::FileException: Could not load ini file NoSuchFile.ini: No such file or directory (errno = 4)",84 " unity::FileException: Could not load ini file NoSuchFile.ini: No such file or directory (errno = 4)",
75 e.what());85 e.what());
76 }86 }
77}87}
88
89void testscope_thread(Runtime::SPtr const& rt, TestScope* testscope, string const& runtime_ini_file)
90{
91 rt->run_scope(testscope, runtime_ini_file, TEST_DIR "/TestScope.ini");
92}
93
94TEST(RuntimeImpl, directories)
95{
96
97 {
98 Runtime::SPtr rt = move(Runtime::create_scope_runtime("TestScope", TEST_DIR "/Runtime.ini"));
99 TestScope testscope;
100 std::thread testscope_t(testscope_thread, rt, &testscope, TEST_DIR "/Runtime.ini");
101
102 // Give thread some time to start up.
103 this_thread::sleep_for(chrono::milliseconds(200));
104
105 EXPECT_EQ(TEST_DIR, testscope.scope_directory());
106
107 string tmpdir = "/run/user/" + to_string(geteuid()) + "/scopes/unconfined/TestScope";
108 EXPECT_EQ(tmpdir, testscope.tmp_directory());
109
110 EXPECT_EQ(TEST_DIR "/cache_dir/unconfined/TestScope", testscope.cache_directory());
111
112 rt->destroy();
113 testscope_t.join();
114 }
115}
78116
=== added file 'test/gtest/scopes/internal/RuntimeImpl/TestScope.cpp'
--- test/gtest/scopes/internal/RuntimeImpl/TestScope.cpp 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/internal/RuntimeImpl/TestScope.cpp 2014-07-30 20:39:51 +0000
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Michi Henning <michi.henning@canonical.com>
17 */
18
19#include "TestScope.h"
20
21using namespace std;
22using namespace unity::scopes;
23
24void TestScope::start(string const&)
25{
26}
27
28SearchQueryBase::UPtr TestScope::search(CannedQuery const&, SearchMetadata const&)
29{
30 // Never called
31 abort();
32 return nullptr;
33}
34
35PreviewQueryBase::UPtr TestScope::preview(Result const&, ActionMetadata const&)
36{
37 // Never called
38 abort();
39 return nullptr;
40}
041
=== added file 'test/gtest/scopes/internal/RuntimeImpl/TestScope.h'
--- test/gtest/scopes/internal/RuntimeImpl/TestScope.h 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/internal/RuntimeImpl/TestScope.h 2014-07-30 20:39:51 +0000
@@ -0,0 +1,36 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Michi Henning <michi.henning@canonical.com>
17 */
18
19#ifndef TEST_TESTSCOPE_H
20#define TEST_TESTSCOPE_H
21
22#include <unity/scopes/ScopeBase.h>
23
24class TestScope : public unity::scopes::ScopeBase
25{
26public:
27 virtual void start(std::string const&);
28
29 virtual unity::scopes::SearchQueryBase::UPtr search(unity::scopes::CannedQuery const&,
30 unity::scopes::SearchMetadata const&) override;
31
32 virtual unity::scopes::PreviewQueryBase::UPtr preview(unity::scopes::Result const&,
33 unity::scopes::ActionMetadata const&) override;
34};
35
36#endif
037
=== added file 'test/gtest/scopes/internal/RuntimeImpl/TestScope.ini.in'
--- test/gtest/scopes/internal/RuntimeImpl/TestScope.ini.in 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/internal/RuntimeImpl/TestScope.ini.in 2014-07-30 20:39:51 +0000
@@ -0,0 +1,4 @@
1[ScopeConfig]
2DisplayName = TestScope
3Description = Scope to test environment variable settings
4Author = Michi Henning
05
=== modified file 'test/gtest/scopes/testing/IsolatedScope/scope.cpp'
--- test/gtest/scopes/testing/IsolatedScope/scope.cpp 2014-07-28 13:38:58 +0000
+++ test/gtest/scopes/testing/IsolatedScope/scope.cpp 2014-07-30 20:39:51 +0000
@@ -227,6 +227,11 @@
227 return "";227 return "";
228}228}
229229
230std::string testing::Scope::tmp_directory() const
231{
232 return "";
233}
234
230unity::scopes::RegistryProxy testing::Scope::registry() const235unity::scopes::RegistryProxy testing::Scope::registry() const
231{236{
232 return registry_;237 return registry_;
233238
=== modified file 'test/gtest/scopes/testing/IsolatedScope/scope.h'
--- test/gtest/scopes/testing/IsolatedScope/scope.h 2014-07-10 02:22:23 +0000
+++ test/gtest/scopes/testing/IsolatedScope/scope.h 2014-07-30 20:39:51 +0000
@@ -57,6 +57,8 @@
5757
58 std::string cache_directory() const override;58 std::string cache_directory() const override;
5959
60 std::string tmp_directory() const override;
61
60 unity::scopes::RegistryProxy registry() const override;62 unity::scopes::RegistryProxy registry() const override;
6163
62 unity::scopes::VariantMap settings() const override;64 unity::scopes::VariantMap settings() const override;

Subscribers

People subscribed via source and target branches

to all changes: