Merge lp:~marcustomlinson/unity-scopes-api/scope_debug_mode into lp:unity-scopes-api/devel
- scope_debug_mode
- Merge into devel
Status: | Superseded |
---|---|
Proposed branch: | lp:~marcustomlinson/unity-scopes-api/scope_debug_mode |
Merge into: | lp:unity-scopes-api/devel |
Diff against target: |
1429 lines (+613/-99) 46 files modified
include/unity/scopes/internal/ActivationReplyObject.h (+2/-1) include/unity/scopes/internal/DfltConfig.h.in (+3/-3) include/unity/scopes/internal/MWRegistry.h (+1/-0) include/unity/scopes/internal/MWScope.h (+1/-0) include/unity/scopes/internal/PreviewReplyObject.h (+2/-1) include/unity/scopes/internal/ReplyObject.h (+2/-1) include/unity/scopes/internal/ResultReplyObject.h (+2/-4) include/unity/scopes/internal/ScopeConfig.h (+2/-0) include/unity/scopes/internal/ScopeObject.h (+4/-1) include/unity/scopes/internal/ScopeObjectBase.h (+2/-0) include/unity/scopes/internal/smartscopes/SSScopeObject.h (+2/-0) include/unity/scopes/internal/zmq_middleware/ScopeI.h (+5/-2) include/unity/scopes/internal/zmq_middleware/ZmqObjectProxy.h (+1/-1) include/unity/scopes/internal/zmq_middleware/ZmqRegistry.h (+1/-0) include/unity/scopes/internal/zmq_middleware/ZmqScope.h (+6/-0) scoperegistry/scoperegistry.cpp (+9/-1) src/scopes/internal/ActivationReplyObject.cpp (+3/-2) src/scopes/internal/PreviewReplyObject.cpp (+3/-2) src/scopes/internal/RegistryObject.cpp (+16/-11) src/scopes/internal/ReplyObject.cpp (+22/-8) src/scopes/internal/ResultReplyObject.cpp (+3/-5) src/scopes/internal/RuntimeImpl.cpp (+5/-2) src/scopes/internal/ScopeConfig.cpp (+49/-33) src/scopes/internal/ScopeImpl.cpp (+4/-4) src/scopes/internal/ScopeObject.cpp (+8/-2) src/scopes/internal/smartscopes/SSScopeObject.cpp (+5/-0) src/scopes/internal/zmq_middleware/ScopeI.cpp (+19/-5) src/scopes/internal/zmq_middleware/ZmqObject.cpp (+11/-3) src/scopes/internal/zmq_middleware/ZmqRegistry.cpp (+6/-2) src/scopes/internal/zmq_middleware/ZmqScope.cpp (+38/-4) src/scopes/internal/zmq_middleware/capnproto/Scope.capnp (+5/-0) test/gtest/scopes/Invocation/CMakeLists.txt (+2/-1) test/gtest/scopes/Invocation/DebugTestScope.cpp (+59/-0) test/gtest/scopes/Invocation/DebugTestScope.h (+33/-0) test/gtest/scopes/Invocation/DebugTestScope.ini.in (+5/-0) test/gtest/scopes/Invocation/Invocation_test.cpp (+34/-0) test/gtest/scopes/Registry/Registry_test.cpp (+58/-0) test/gtest/scopes/Registry/other_scopes/testscopeC/CMakeLists.txt (+2/-0) test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.cpp (+99/-0) test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.ini.in (+2/-0) test/gtest/scopes/ReplyReaper/CMakeLists.txt (+1/-0) test/gtest/scopes/ReplyReaper/DebugScope.ini.in (+5/-0) test/gtest/scopes/ReplyReaper/ReplyReaper_test.cpp (+63/-0) test/gtest/scopes/internal/ScopeConfig/ScopeConfig_test.cpp (+2/-0) test/gtest/scopes/internal/ScopeConfig/complete_config.ini.in (+1/-0) test/gtest/scopes/internal/zmq_middleware/ZmqMiddleware/ZmqMiddleware_test.cpp (+5/-0) |
To merge this branch: | bzr merge lp:~marcustomlinson/unity-scopes-api/scope_debug_mode |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity Team | Pending | ||
Review via email: mp+230574@code.launchpad.net |
Commit message
Added "DebugMode" parameter to scope config in order to enable more lenient operation timeouts when debugging that particular scope.
Description of the change
If a scope config file contains the line "DebugMode = true" the following debug timeouts are applied (only) to comms with that particular scope:
* Registry process timeout upped to 15s
* Scope idle timeout disabled
* Runtime reply reaper disabled
* Middleware two-way invocation timeout disabled
* Middleware locate() timeout upped to 15s
*** Summary of changes: ***
* Added "DebugMode" parameter to ScopeConfig (not to ScopeMetadata).
* A new debug_mode() method on ScopeObject (propagated through middleware to MWScope but not expose to the public ScopeProxy).
* An additional "dont_reap" boolean argument for ReplyObject constructor (provided via ScopeImpl from the result of fwd()->
* An additional "locate_timeout" argument for ZmqObjectProxy:
* Updated RuntimeImpl:
* Updated scoperegistry to use scope_config.
* Added tests.
*** Other changes: ***
* Fixed remove_
* Some cleaning up of API code in general.
* Invocation.
- 465. By Marcus Tomlinson
-
Updated symbols
- 466. By Marcus Tomlinson
-
Make sure scope_processes_ map operations are under mutex protection
- 467. By Marcus Tomlinson
-
Return false from remove_
local_scope( ) if not found (as before) - 468. By Marcus Tomlinson
-
Added interlock in ZmqScope:
:debug_ mode() for accessing debug_mode_ from parallel threads - 469. By Marcus Tomlinson
-
Hopefully fixes "terminate called without an active exception"
Unmerged revisions
Preview Diff
1 | === modified file 'include/unity/scopes/internal/ActivationReplyObject.h' |
2 | --- include/unity/scopes/internal/ActivationReplyObject.h 2014-03-07 04:19:32 +0000 |
3 | +++ include/unity/scopes/internal/ActivationReplyObject.h 2014-08-13 04:58:30 +0000 |
4 | @@ -34,7 +34,8 @@ |
5 | class ActivationReplyObject : public ReplyObject |
6 | { |
7 | public: |
8 | - ActivationReplyObject(ActivationListenerBase::SPtr const& receiver, RuntimeImpl const* runtime, std::string const& scope_id); |
9 | + ActivationReplyObject(ActivationListenerBase::SPtr const& receiver, RuntimeImpl const* runtime, |
10 | + std::string const& scope_id, bool dont_reap = false); |
11 | virtual bool process_data(VariantMap const& data) override; |
12 | |
13 | private: |
14 | |
15 | === modified file 'include/unity/scopes/internal/DfltConfig.h.in' |
16 | --- include/unity/scopes/internal/DfltConfig.h.in 2014-07-25 01:23:02 +0000 |
17 | +++ include/unity/scopes/internal/DfltConfig.h.in 2014-08-13 04:58:30 +0000 |
18 | @@ -28,10 +28,10 @@ |
19 | namespace internal |
20 | { |
21 | |
22 | -static constexpr const char* DFLT_RUNTIME_INI = "@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_PREFIX@/@UNITY_SCOPES_LIB@/Runtime.ini"; |
23 | -static constexpr const char* DFLT_REGISTRY_INI = "@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_PREFIX@/@UNITY_SCOPES_LIB@/Registry.ini"; |
24 | +static constexpr char const* DFLT_RUNTIME_INI = "@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_PREFIX@/@UNITY_SCOPES_LIB@/Runtime.ini"; |
25 | +static constexpr char const* DFLT_REGISTRY_INI = "@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_PREFIX@/@UNITY_SCOPES_LIB@/Registry.ini"; |
26 | static constexpr char const* DFLT_REGISTRY_ID = "Registry"; |
27 | -static constexpr const char* DFLT_SS_REGISTRY_INI = "@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_PREFIX@/@UNITY_SCOPES_LIB@/Smartscopes.ini"; |
28 | +static constexpr char const* DFLT_SS_REGISTRY_INI = "@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_PREFIX@/@UNITY_SCOPES_LIB@/Smartscopes.ini"; |
29 | static constexpr char const* DFLT_SS_REGISTRY_ID = "SSRegistry"; |
30 | static constexpr char const* DFLT_SCOPERUNNER_PATH = "@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_PREFIX@/@UNITY_SCOPES_LIB@/scoperunner"; |
31 | static constexpr char const* DFLT_MIDDLEWARE = "Zmq"; |
32 | |
33 | === modified file 'include/unity/scopes/internal/MWRegistry.h' |
34 | --- include/unity/scopes/internal/MWRegistry.h 2014-06-04 17:49:34 +0000 |
35 | +++ include/unity/scopes/internal/MWRegistry.h 2014-08-13 04:58:30 +0000 |
36 | @@ -39,6 +39,7 @@ |
37 | // Remote operations |
38 | virtual ScopeMetadata get_metadata(std::string const& scope_id) = 0; |
39 | virtual MetadataMap list() = 0; |
40 | + virtual ObjectProxy locate(std::string const& identity, int64_t timeout) = 0; |
41 | virtual ObjectProxy locate(std::string const& identity) = 0; |
42 | virtual bool is_scope_running(std::string const& scope_id) = 0; |
43 | |
44 | |
45 | === modified file 'include/unity/scopes/internal/MWScope.h' |
46 | --- include/unity/scopes/internal/MWScope.h 2014-02-27 16:58:50 +0000 |
47 | +++ include/unity/scopes/internal/MWScope.h 2014-08-13 04:58:30 +0000 |
48 | @@ -44,6 +44,7 @@ |
49 | virtual QueryCtrlProxy activate(VariantMap const& result, VariantMap const& hints, MWReplyProxy const& reply) = 0; |
50 | virtual QueryCtrlProxy perform_action(VariantMap const& result, VariantMap const& hints, std::string const& widget_id, std::string const& action_id, MWReplyProxy const& reply) = 0; |
51 | virtual QueryCtrlProxy preview(VariantMap const& result, VariantMap const& hints, MWReplyProxy const& reply) = 0; |
52 | + virtual bool debug_mode() = 0; |
53 | |
54 | protected: |
55 | MWScope(MiddlewareBase* mw_base); |
56 | |
57 | === modified file 'include/unity/scopes/internal/PreviewReplyObject.h' |
58 | --- include/unity/scopes/internal/PreviewReplyObject.h 2014-03-07 04:19:32 +0000 |
59 | +++ include/unity/scopes/internal/PreviewReplyObject.h 2014-08-13 04:58:30 +0000 |
60 | @@ -37,7 +37,8 @@ |
61 | class PreviewReplyObject : public ReplyObject |
62 | { |
63 | public: |
64 | - PreviewReplyObject(PreviewListenerBase::SPtr const& receiver, RuntimeImpl const* runtime, std::string const& scope_id); |
65 | + PreviewReplyObject(PreviewListenerBase::SPtr const& receiver, RuntimeImpl const* runtime, |
66 | + std::string const& scope_id, bool dont_reap = false); |
67 | virtual ~PreviewReplyObject(); |
68 | |
69 | virtual bool process_data(VariantMap const& data) override; |
70 | |
71 | === modified file 'include/unity/scopes/internal/ReplyObject.h' |
72 | --- include/unity/scopes/internal/ReplyObject.h 2014-07-28 09:55:08 +0000 |
73 | +++ include/unity/scopes/internal/ReplyObject.h 2014-08-13 04:58:30 +0000 |
74 | @@ -47,7 +47,8 @@ |
75 | public: |
76 | UNITY_DEFINES_PTRS(ReplyObject); |
77 | |
78 | - ReplyObject(ListenerBase::SPtr const& receiver_base, RuntimeImpl const* runtime, std::string const& scope_proxy); |
79 | + ReplyObject(ListenerBase::SPtr const& receiver_base, RuntimeImpl const* runtime, |
80 | + std::string const& scope_proxy, bool dont_reap); |
81 | virtual ~ReplyObject(); |
82 | |
83 | virtual bool process_data(VariantMap const& data) = 0; |
84 | |
85 | === modified file 'include/unity/scopes/internal/ResultReplyObject.h' |
86 | --- include/unity/scopes/internal/ResultReplyObject.h 2014-04-09 09:36:50 +0000 |
87 | +++ include/unity/scopes/internal/ResultReplyObject.h 2014-08-13 04:58:30 +0000 |
88 | @@ -37,10 +37,8 @@ |
89 | class ResultReplyObject : public ReplyObject |
90 | { |
91 | public: |
92 | - ResultReplyObject(SearchListenerBase::SPtr const& receiver, |
93 | - RuntimeImpl const* runtime, |
94 | - std::string const& scope_id, |
95 | - int cardinality); |
96 | + ResultReplyObject(SearchListenerBase::SPtr const& receiver, RuntimeImpl const* runtime, |
97 | + std::string const& scope_id, int cardinality, bool dont_reap = false); |
98 | virtual ~ResultReplyObject(); |
99 | |
100 | virtual bool process_data(VariantMap const& data) override; |
101 | |
102 | === modified file 'include/unity/scopes/internal/ScopeConfig.h' |
103 | --- include/unity/scopes/internal/ScopeConfig.h 2014-07-22 08:02:32 +0000 |
104 | +++ include/unity/scopes/internal/ScopeConfig.h 2014-08-13 04:58:30 +0000 |
105 | @@ -52,6 +52,7 @@ |
106 | std::string scope_runner() const; // Optional, throws NotFoundException if not present |
107 | int idle_timeout() const; // Optional, returns default value if not present |
108 | ScopeMetadata::ResultsTtlType results_ttl_type() const; // Optional, returns none if not present |
109 | + bool debug_mode() const; // Optional, returns false if not present |
110 | |
111 | VariantMap appearance_attributes() const; // Optional, returns empty map if no attributes are present |
112 | |
113 | @@ -71,6 +72,7 @@ |
114 | std::unique_ptr<std::string> scope_runner_; |
115 | int idle_timeout_; |
116 | ScopeMetadata::ResultsTtlType results_ttl_type_; |
117 | + bool debug_mode_; |
118 | |
119 | VariantMap appearance_attributes_; |
120 | }; |
121 | |
122 | === modified file 'include/unity/scopes/internal/ScopeObject.h' |
123 | --- include/unity/scopes/internal/ScopeObject.h 2014-02-27 16:58:50 +0000 |
124 | +++ include/unity/scopes/internal/ScopeObject.h 2014-08-13 04:58:30 +0000 |
125 | @@ -52,7 +52,7 @@ |
126 | public: |
127 | UNITY_DEFINES_PTRS(ScopeObject); |
128 | |
129 | - ScopeObject(RuntimeImpl* runtime, ScopeBase* scope_base_); |
130 | + ScopeObject(RuntimeImpl* runtime, ScopeBase* scope_base, bool debug_mode = false); |
131 | virtual ~ScopeObject(); |
132 | |
133 | // Remote operation implementations |
134 | @@ -78,12 +78,15 @@ |
135 | MWReplyProxy const& reply, |
136 | InvokeInfo const& info) override; |
137 | |
138 | + virtual bool debug_mode() const override; |
139 | + |
140 | private: |
141 | MWQueryCtrlProxy query(MWReplyProxy const& reply, MiddlewareBase* mw_base, |
142 | std::function<QueryBase::SPtr(void)> const& query_factory_fun, |
143 | std::function<QueryObjectBase::SPtr(QueryBase::SPtr, MWQueryCtrlProxy)> const& query_object_factory_fun); |
144 | RuntimeImpl* const runtime_; |
145 | ScopeBase* const scope_base_; |
146 | + bool const debug_mode_; |
147 | }; |
148 | |
149 | } // namespace internal |
150 | |
151 | === modified file 'include/unity/scopes/internal/ScopeObjectBase.h' |
152 | --- include/unity/scopes/internal/ScopeObjectBase.h 2014-05-15 00:34:39 +0000 |
153 | +++ include/unity/scopes/internal/ScopeObjectBase.h 2014-08-13 04:58:30 +0000 |
154 | @@ -69,6 +69,8 @@ |
155 | ActionMetadata const& hints, |
156 | MWReplyProxy const& reply, |
157 | InvokeInfo const& info) = 0; |
158 | + |
159 | + virtual bool debug_mode() const = 0; |
160 | }; |
161 | |
162 | } // namespace internal |
163 | |
164 | === modified file 'include/unity/scopes/internal/smartscopes/SSScopeObject.h' |
165 | --- include/unity/scopes/internal/smartscopes/SSScopeObject.h 2014-02-27 16:58:50 +0000 |
166 | +++ include/unity/scopes/internal/smartscopes/SSScopeObject.h 2014-08-13 04:58:30 +0000 |
167 | @@ -74,6 +74,8 @@ |
168 | MWReplyProxy const& reply, |
169 | InvokeInfo const& info) override; |
170 | |
171 | + bool debug_mode() const override; |
172 | + |
173 | private: |
174 | MWQueryCtrlProxy query(InvokeInfo const& info, |
175 | MWReplyProxy const& reply, |
176 | |
177 | === modified file 'include/unity/scopes/internal/zmq_middleware/ScopeI.h' |
178 | --- include/unity/scopes/internal/zmq_middleware/ScopeI.h 2014-02-27 15:46:44 +0000 |
179 | +++ include/unity/scopes/internal/zmq_middleware/ScopeI.h 2014-08-13 04:58:30 +0000 |
180 | @@ -43,8 +43,8 @@ |
181 | |
182 | private: |
183 | virtual void search_(Current const& current, |
184 | - capnp::AnyPointer::Reader& in_params, |
185 | - capnproto::Response::Builder& r); |
186 | + capnp::AnyPointer::Reader& in_params, |
187 | + capnproto::Response::Builder& r); |
188 | virtual void activate_(Current const& current, |
189 | capnp::AnyPointer::Reader& in_params, |
190 | capnproto::Response::Builder& r); |
191 | @@ -54,6 +54,9 @@ |
192 | virtual void preview_(Current const& current, |
193 | capnp::AnyPointer::Reader& in_params, |
194 | capnproto::Response::Builder& r); |
195 | + virtual void debug_mode_(Current const& current, |
196 | + capnp::AnyPointer::Reader& in_params, |
197 | + capnproto::Response::Builder& r); |
198 | }; |
199 | |
200 | } // namespace zmq_middleware |
201 | |
202 | === modified file 'include/unity/scopes/internal/zmq_middleware/ZmqObjectProxy.h' |
203 | --- include/unity/scopes/internal/zmq_middleware/ZmqObjectProxy.h 2014-05-29 15:41:42 +0000 |
204 | +++ include/unity/scopes/internal/zmq_middleware/ZmqObjectProxy.h 2014-08-13 04:58:30 +0000 |
205 | @@ -77,7 +77,7 @@ |
206 | void invoke_oneway_(capnp::MessageBuilder& out_params); |
207 | |
208 | ZmqReceiver invoke_twoway_(capnp::MessageBuilder& out_params); |
209 | - ZmqReceiver invoke_twoway_(capnp::MessageBuilder& out_params, int64_t timeout); |
210 | + ZmqReceiver invoke_twoway_(capnp::MessageBuilder& out_params, int64_t twoway_timeout, int64_t locate_timeout = -1); |
211 | |
212 | private: |
213 | ZmqReceiver invoke_twoway__(capnp::MessageBuilder& out_params, int64_t timeout); |
214 | |
215 | === modified file 'include/unity/scopes/internal/zmq_middleware/ZmqRegistry.h' |
216 | --- include/unity/scopes/internal/zmq_middleware/ZmqRegistry.h 2014-06-04 17:49:34 +0000 |
217 | +++ include/unity/scopes/internal/zmq_middleware/ZmqRegistry.h 2014-08-13 04:58:30 +0000 |
218 | @@ -51,6 +51,7 @@ |
219 | // Remote operations. |
220 | virtual ScopeMetadata get_metadata(std::string const& scope_id) override; |
221 | virtual MetadataMap list() override; |
222 | + virtual ObjectProxy locate(std::string const& identity, int64_t timeout) override; |
223 | virtual ObjectProxy locate(std::string const& identity) override; |
224 | virtual bool is_scope_running(std::string const& scope_id) override; |
225 | }; |
226 | |
227 | === modified file 'include/unity/scopes/internal/zmq_middleware/ZmqScope.h' |
228 | --- include/unity/scopes/internal/zmq_middleware/ZmqScope.h 2014-02-27 16:58:50 +0000 |
229 | +++ include/unity/scopes/internal/zmq_middleware/ZmqScope.h 2014-08-13 04:58:30 +0000 |
230 | @@ -62,6 +62,12 @@ |
231 | virtual QueryCtrlProxy preview(VariantMap const& result, |
232 | VariantMap const& hints, |
233 | MWReplyProxy const& reply) override; |
234 | + |
235 | + virtual bool debug_mode() override; |
236 | + |
237 | +private: |
238 | + ZmqReceiver invoke_scope_(capnp::MessageBuilder& out_params); |
239 | + std::unique_ptr<bool> debug_mode_; |
240 | }; |
241 | |
242 | } // namespace zmq_middleware |
243 | |
244 | === modified file 'scoperegistry/scoperegistry.cpp' |
245 | --- scoperegistry/scoperegistry.cpp 2014-07-29 10:22:45 +0000 |
246 | +++ scoperegistry/scoperegistry.cpp 2014-08-13 04:58:30 +0000 |
247 | @@ -389,7 +389,15 @@ |
248 | scope_dir.filename().native(); |
249 | } |
250 | |
251 | - exec_data.timeout_ms = timeout_ms; |
252 | + // Check if this scope has requested debug mode, if so, set the process timeout to 15s |
253 | + if (sc.debug_mode()) |
254 | + { |
255 | + exec_data.timeout_ms = 15000; |
256 | + } |
257 | + else |
258 | + { |
259 | + exec_data.timeout_ms = timeout_ms; |
260 | + } |
261 | |
262 | try |
263 | { |
264 | |
265 | === modified file 'src/scopes/internal/ActivationReplyObject.cpp' |
266 | --- src/scopes/internal/ActivationReplyObject.cpp 2014-03-07 04:19:32 +0000 |
267 | +++ src/scopes/internal/ActivationReplyObject.cpp 2014-08-13 04:58:30 +0000 |
268 | @@ -30,8 +30,9 @@ |
269 | namespace internal |
270 | { |
271 | |
272 | -ActivationReplyObject::ActivationReplyObject(ActivationListenerBase::SPtr const& receiver, RuntimeImpl const* runtime, std::string const& scope_id) : |
273 | - ReplyObject(std::static_pointer_cast<ListenerBase>(receiver), runtime, scope_id), |
274 | +ActivationReplyObject::ActivationReplyObject(ActivationListenerBase::SPtr const& receiver, RuntimeImpl const* runtime, |
275 | + std::string const& scope_id, bool dont_reap) : |
276 | + ReplyObject(std::static_pointer_cast<ListenerBase>(receiver), runtime, scope_id, dont_reap), |
277 | receiver_(receiver) |
278 | { |
279 | assert(receiver_); |
280 | |
281 | === modified file 'src/scopes/internal/PreviewReplyObject.cpp' |
282 | --- src/scopes/internal/PreviewReplyObject.cpp 2014-03-07 04:19:32 +0000 |
283 | +++ src/scopes/internal/PreviewReplyObject.cpp 2014-08-13 04:58:30 +0000 |
284 | @@ -40,8 +40,9 @@ |
285 | namespace internal |
286 | { |
287 | |
288 | -PreviewReplyObject::PreviewReplyObject(PreviewListenerBase::SPtr const& receiver, RuntimeImpl const* runtime, std::string const& scope_id) : |
289 | - ReplyObject(std::static_pointer_cast<ListenerBase>(receiver), runtime, scope_id), |
290 | +PreviewReplyObject::PreviewReplyObject(PreviewListenerBase::SPtr const& receiver, RuntimeImpl const* runtime, |
291 | + std::string const& scope_id, bool dont_reap) : |
292 | + ReplyObject(std::static_pointer_cast<ListenerBase>(receiver), runtime, scope_id, dont_reap), |
293 | receiver_(receiver) |
294 | { |
295 | assert(receiver_); |
296 | |
297 | === modified file 'src/scopes/internal/RegistryObject.cpp' |
298 | --- src/scopes/internal/RegistryObject.cpp 2014-08-06 04:54:06 +0000 |
299 | +++ src/scopes/internal/RegistryObject.cpp 2014-08-13 04:58:30 +0000 |
300 | @@ -261,18 +261,24 @@ |
301 | "with empty id"); |
302 | } |
303 | |
304 | - lock_guard<decltype(mutex_)> lock(mutex_); |
305 | - |
306 | - scope_processes_.erase(scope_id); |
307 | - |
308 | - if (scopes_.erase(scope_id) == 1) |
309 | + unique_lock<decltype(mutex_)> lock(mutex_); |
310 | + if (scopes_.find(scope_id) != scopes_.end()) |
311 | { |
312 | - if (publisher_) |
313 | + // Unlock here so that we can handle on_process_death |
314 | + lock.unlock(); |
315 | + scope_processes_.at(scope_id).kill(); |
316 | + lock.lock(); |
317 | + scope_processes_.erase(scope_id); |
318 | + |
319 | + if (scopes_.erase(scope_id) == 1) |
320 | { |
321 | - // Send a blank message to subscribers to inform them that the registry has been updated |
322 | - publisher_->send_message(""); |
323 | + if (publisher_) |
324 | + { |
325 | + // Send a blank message to subscribers to inform them that the registry has been updated |
326 | + publisher_->send_message(""); |
327 | + } |
328 | + return true; |
329 | } |
330 | - return true; |
331 | } |
332 | |
333 | return false; |
334 | @@ -335,8 +341,7 @@ |
335 | } |
336 | |
337 | RegistryObject::ScopeProcess::ScopeProcess(ScopeProcess const& other) |
338 | - : exec_data_(other.exec_data_) |
339 | - , reg_publisher_(other.reg_publisher_) |
340 | + : ScopeProcess(other.exec_data_, other.reg_publisher_) |
341 | { |
342 | } |
343 | |
344 | |
345 | === modified file 'src/scopes/internal/ReplyObject.cpp' |
346 | --- src/scopes/internal/ReplyObject.cpp 2014-07-30 21:34:13 +0000 |
347 | +++ src/scopes/internal/ReplyObject.cpp 2014-08-13 04:58:30 +0000 |
348 | @@ -41,7 +41,8 @@ |
349 | namespace internal |
350 | { |
351 | |
352 | -ReplyObject::ReplyObject(ListenerBase::SPtr const& receiver_base, RuntimeImpl const* runtime, std::string const& scope_proxy) : |
353 | +ReplyObject::ReplyObject(ListenerBase::SPtr const& receiver_base, RuntimeImpl const* runtime, |
354 | + std::string const& scope_proxy, bool dont_reap) : |
355 | listener_base_(receiver_base), |
356 | finished_(false), |
357 | origin_proxy_(scope_proxy), |
358 | @@ -50,10 +51,14 @@ |
359 | { |
360 | assert(receiver_base); |
361 | assert(runtime); |
362 | - reap_item_ = runtime->reply_reaper()->add([this] { |
363 | - string msg = "No activity on ReplyObject for scope " + this->origin_proxy_ + ": ReplyObject destroyed"; |
364 | - this->finished(CompletionDetails(CompletionDetails::Error, msg)); |
365 | - }); |
366 | + |
367 | + if (dont_reap == false) |
368 | + { |
369 | + reap_item_ = runtime->reply_reaper()->add([this] { |
370 | + string msg = "No activity on ReplyObject for scope " + this->origin_proxy_ + ": ReplyObject destroyed"; |
371 | + this->finished(CompletionDetails(CompletionDetails::Error, msg)); |
372 | + }); |
373 | + } |
374 | } |
375 | |
376 | ReplyObject::~ReplyObject() |
377 | @@ -89,7 +94,10 @@ |
378 | return; // Ignore replies that arrive after finished(). |
379 | } |
380 | |
381 | - reap_item_->refresh(); |
382 | + if (reap_item_) |
383 | + { |
384 | + reap_item_->refresh(); |
385 | + } |
386 | |
387 | { |
388 | unique_lock<mutex> lock(mutex_); |
389 | @@ -148,7 +156,10 @@ |
390 | |
391 | // Only one thread can reach this point, any others were thrown out above. |
392 | |
393 | - reap_item_->destroy(); |
394 | + if (reap_item_) |
395 | + { |
396 | + reap_item_->destroy(); |
397 | + } |
398 | |
399 | // Wait until all currently executing calls to push() have completed. |
400 | unique_lock<mutex> lock(mutex_); |
401 | @@ -189,7 +200,10 @@ |
402 | return; // Ignore info messages that arrive after finished(). |
403 | } |
404 | |
405 | - reap_item_->refresh(); |
406 | + if (reap_item_) |
407 | + { |
408 | + reap_item_->refresh(); |
409 | + } |
410 | info_occurred_.exchange(true); |
411 | |
412 | try |
413 | |
414 | === modified file 'src/scopes/internal/ResultReplyObject.cpp' |
415 | --- src/scopes/internal/ResultReplyObject.cpp 2014-05-29 10:03:56 +0000 |
416 | +++ src/scopes/internal/ResultReplyObject.cpp 2014-08-13 04:58:30 +0000 |
417 | @@ -43,11 +43,9 @@ |
418 | namespace internal |
419 | { |
420 | |
421 | -ResultReplyObject::ResultReplyObject(SearchListenerBase::SPtr const& receiver, |
422 | - RuntimeImpl const* runtime, |
423 | - std::string const& scope_id, |
424 | - int cardinality) : |
425 | - ReplyObject(std::static_pointer_cast<ListenerBase>(receiver), runtime, scope_id), |
426 | +ResultReplyObject::ResultReplyObject(SearchListenerBase::SPtr const& receiver, RuntimeImpl const* runtime, |
427 | + std::string const& scope_id, int cardinality, bool dont_reap) : |
428 | + ReplyObject(std::static_pointer_cast<ListenerBase>(receiver), runtime, scope_id, dont_reap), |
429 | receiver_(receiver), |
430 | cat_registry_(new CategoryRegistry()), |
431 | runtime_(runtime), |
432 | |
433 | === modified file 'src/scopes/internal/RuntimeImpl.cpp' |
434 | --- src/scopes/internal/RuntimeImpl.cpp 2014-08-08 14:06:59 +0000 |
435 | +++ src/scopes/internal/RuntimeImpl.cpp 2014-08-13 04:58:30 +0000 |
436 | @@ -357,15 +357,18 @@ |
437 | auto run_future = std::async(launch::async, [scope_base] { scope_base->run(); }); |
438 | |
439 | // Create a servant for the scope and register the servant. |
440 | - auto scope = unique_ptr<internal::ScopeObject>(new internal::ScopeObject(this, scope_base)); |
441 | if (!scope_ini_file.empty()) |
442 | { |
443 | + // Check if this scope has requested debug mode, if so, disable the idle timeout |
444 | ScopeConfig scope_config(scope_ini_file); |
445 | - int idle_timeout_ms = scope_config.idle_timeout() * 1000; |
446 | + int idle_timeout_ms = scope_config.debug_mode() ? -1 : scope_config.idle_timeout() * 1000; |
447 | + |
448 | + auto scope = unique_ptr<internal::ScopeObject>(new internal::ScopeObject(this, scope_base, scope_config.debug_mode())); |
449 | mw->add_scope_object(scope_id_, move(scope), idle_timeout_ms); |
450 | } |
451 | else |
452 | { |
453 | + auto scope = unique_ptr<internal::ScopeObject>(new internal::ScopeObject(this, scope_base)); |
454 | mw->add_scope_object(scope_id_, move(scope)); |
455 | } |
456 | |
457 | |
458 | === modified file 'src/scopes/internal/ScopeConfig.cpp' |
459 | --- src/scopes/internal/ScopeConfig.cpp 2014-08-08 12:31:23 +0000 |
460 | +++ src/scopes/internal/ScopeConfig.cpp 2014-08-13 04:58:30 +0000 |
461 | @@ -55,6 +55,7 @@ |
462 | const string scoperunner_key = "ScopeRunner"; |
463 | const string idle_timeout_key = "IdleTimeout"; |
464 | const string results_ttl_key = "ResultsTtlType"; |
465 | + const string debug_mode_key = "DebugMode"; |
466 | |
467 | const string scope_appearance_group = "Appearance"; |
468 | const string fg_color_key = "ForegroundColor"; |
469 | @@ -189,6 +190,15 @@ |
470 | { |
471 | } |
472 | |
473 | + try |
474 | + { |
475 | + debug_mode_ = parser()->get_boolean(scope_config_group, debug_mode_key); |
476 | + } |
477 | + catch (LogicException const&) |
478 | + { |
479 | + debug_mode_ = false; |
480 | + } |
481 | + |
482 | // read all display attributes from scope_appearance_group |
483 | try |
484 | { |
485 | @@ -202,39 +212,40 @@ |
486 | } |
487 | |
488 | KnownEntries const known_entries = { |
489 | - { scope_config_group, |
490 | - { |
491 | - overrideable_key, |
492 | - scope_name_key, |
493 | - description_key, |
494 | - author_key, |
495 | - art_key, |
496 | - icon_key, |
497 | - search_hint_key, |
498 | - hot_key_key, |
499 | - invisible_key, |
500 | - location_data_needed_key, |
501 | - scoperunner_key, |
502 | - idle_timeout_key, |
503 | - results_ttl_key |
504 | - } |
505 | - }, |
506 | - { scope_appearance_group, |
507 | - { |
508 | - fg_color_key, |
509 | - bg_color_key, |
510 | - shape_images_key, |
511 | - category_header_bg_key, |
512 | - preview_button_color_key, |
513 | - logo_overlay_color_key, |
514 | - pageheader_logo_key, |
515 | - pageheader_fg_color_key, |
516 | - pageheader_background_key, |
517 | - pageheader_div_color_key, |
518 | - pageheader_nav_bg_key |
519 | - } |
520 | - } |
521 | - }; |
522 | + { scope_config_group, |
523 | + { |
524 | + overrideable_key, |
525 | + scope_name_key, |
526 | + description_key, |
527 | + author_key, |
528 | + art_key, |
529 | + icon_key, |
530 | + search_hint_key, |
531 | + hot_key_key, |
532 | + invisible_key, |
533 | + location_data_needed_key, |
534 | + scoperunner_key, |
535 | + idle_timeout_key, |
536 | + results_ttl_key, |
537 | + debug_mode_key |
538 | + } |
539 | + }, |
540 | + { scope_appearance_group, |
541 | + { |
542 | + fg_color_key, |
543 | + bg_color_key, |
544 | + shape_images_key, |
545 | + category_header_bg_key, |
546 | + preview_button_color_key, |
547 | + logo_overlay_color_key, |
548 | + pageheader_logo_key, |
549 | + pageheader_fg_color_key, |
550 | + pageheader_background_key, |
551 | + pageheader_div_color_key, |
552 | + pageheader_nav_bg_key |
553 | + } |
554 | + } |
555 | + }; |
556 | check_unknown_entries(known_entries); |
557 | } |
558 | |
559 | @@ -380,6 +391,11 @@ |
560 | return results_ttl_type_; |
561 | } |
562 | |
563 | +bool ScopeConfig::debug_mode() const |
564 | +{ |
565 | + return debug_mode_; |
566 | +} |
567 | + |
568 | VariantMap ScopeConfig::appearance_attributes() const |
569 | { |
570 | return appearance_attributes_; |
571 | |
572 | === modified file 'src/scopes/internal/ScopeImpl.cpp' |
573 | --- src/scopes/internal/ScopeImpl.cpp 2014-07-28 08:30:35 +0000 |
574 | +++ src/scopes/internal/ScopeImpl.cpp 2014-08-13 04:58:30 +0000 |
575 | @@ -95,7 +95,7 @@ |
576 | throw unity::InvalidArgumentException("Scope::search(): invalid SearchListenerBase (nullptr)"); |
577 | } |
578 | |
579 | - ReplyObject::SPtr ro(make_shared<ResultReplyObject>(reply, runtime_, to_string(), metadata.cardinality())); |
580 | + ReplyObject::SPtr ro(make_shared<ResultReplyObject>(reply, runtime_, to_string(), metadata.cardinality(), fwd()->debug_mode())); |
581 | MWReplyProxy rp = fwd()->mw_base()->add_reply_object(ro); |
582 | |
583 | // "Fake" QueryCtrlProxy that doesn't have a real MWQueryCtrlProxy yet. |
584 | @@ -149,7 +149,7 @@ |
585 | throw unity::InvalidArgumentException("Scope::activate(): invalid ActivationListenerBase (nullptr)"); |
586 | } |
587 | |
588 | - ActivationReplyObject::SPtr ro(make_shared<ActivationReplyObject>(reply, runtime_, to_string())); |
589 | + ReplyObject::SPtr ro(make_shared<ActivationReplyObject>(reply, runtime_, to_string(), fwd()->debug_mode())); |
590 | MWReplyProxy rp = fwd()->mw_base()->add_reply_object(ro); |
591 | |
592 | shared_ptr<QueryCtrlImpl> ctrl = make_shared<QueryCtrlImpl>(nullptr, rp); |
593 | @@ -197,7 +197,7 @@ |
594 | throw unity::InvalidArgumentException("Scope::perform_action(): invalid ActivationListenerBase (nullptr)"); |
595 | } |
596 | |
597 | - ActivationReplyObject::SPtr ro(make_shared<ActivationReplyObject>(reply, runtime_, to_string())); |
598 | + ReplyObject::SPtr ro(make_shared<ActivationReplyObject>(reply, runtime_, to_string(), fwd()->debug_mode())); |
599 | MWReplyProxy rp = fwd()->mw_base()->add_reply_object(ro); |
600 | |
601 | shared_ptr<QueryCtrlImpl> ctrl = make_shared<QueryCtrlImpl>(nullptr, rp); |
602 | @@ -246,7 +246,7 @@ |
603 | throw unity::InvalidArgumentException("Scope::preview(): invalid PreviewListenerBase (nullptr)"); |
604 | } |
605 | |
606 | - PreviewReplyObject::SPtr ro(make_shared<PreviewReplyObject>(reply, runtime_, to_string())); |
607 | + ReplyObject::SPtr ro(make_shared<PreviewReplyObject>(reply, runtime_, to_string(), fwd()->debug_mode())); |
608 | MWReplyProxy rp = fwd()->mw_base()->add_reply_object(ro); |
609 | |
610 | shared_ptr<QueryCtrlImpl> ctrl = make_shared<QueryCtrlImpl>(nullptr, rp); |
611 | |
612 | === modified file 'src/scopes/internal/ScopeObject.cpp' |
613 | --- src/scopes/internal/ScopeObject.cpp 2014-08-05 05:29:56 +0000 |
614 | +++ src/scopes/internal/ScopeObject.cpp 2014-08-13 04:58:30 +0000 |
615 | @@ -47,9 +47,10 @@ |
616 | namespace internal |
617 | { |
618 | |
619 | -ScopeObject::ScopeObject(RuntimeImpl* runtime, ScopeBase* scope_base) : |
620 | +ScopeObject::ScopeObject(RuntimeImpl* runtime, ScopeBase* scope_base, bool debug_mode) : |
621 | runtime_(runtime), |
622 | - scope_base_(scope_base) |
623 | + scope_base_(scope_base), |
624 | + debug_mode_(debug_mode) |
625 | { |
626 | assert(runtime); |
627 | assert(scope_base); |
628 | @@ -217,6 +218,11 @@ |
629 | ); |
630 | } |
631 | |
632 | +bool ScopeObject::debug_mode() const |
633 | +{ |
634 | + return debug_mode_; |
635 | +} |
636 | + |
637 | } // namespace internal |
638 | |
639 | } // namespace scopes |
640 | |
641 | === modified file 'src/scopes/internal/smartscopes/SSScopeObject.cpp' |
642 | --- src/scopes/internal/smartscopes/SSScopeObject.cpp 2014-07-28 08:30:35 +0000 |
643 | +++ src/scopes/internal/smartscopes/SSScopeObject.cpp 2014-08-13 04:58:30 +0000 |
644 | @@ -192,6 +192,11 @@ |
645 | return info.mw->create_query_ctrl_proxy(reply->identity() + ".c", info.mw->get_query_ctrl_endpoint()); |
646 | } |
647 | |
648 | +bool SSScopeObject::debug_mode() const |
649 | +{ |
650 | + return false; |
651 | +} |
652 | + |
653 | } // namespace smartscopes |
654 | |
655 | } // namespace internal |
656 | |
657 | === modified file 'src/scopes/internal/zmq_middleware/ScopeI.cpp' |
658 | --- src/scopes/internal/zmq_middleware/ScopeI.cpp 2014-05-29 15:41:42 +0000 |
659 | +++ src/scopes/internal/zmq_middleware/ScopeI.cpp 2014-08-13 04:58:30 +0000 |
660 | @@ -60,6 +60,7 @@ |
661 | QueryCtrl* preview(ValueDict result, ValueDict hints, Reply* replyProxy); |
662 | QueryCtrl* perform_action(ValueDict result, ValueDict hints, string action_id, Reply* replyProxy); |
663 | QueryCtrl* activate(ValueDict result, ValueDict hints, Reply* replyProxy); |
664 | + bool debug_mode(); |
665 | }; |
666 | |
667 | */ |
668 | @@ -71,7 +72,8 @@ |
669 | { "search", bind(&ScopeI::search_, this, _1, _2, _3) }, |
670 | { "preview", bind(&ScopeI::preview_, this, _1, _2, _3) }, |
671 | { "activate", bind(&ScopeI::activate_, this, _1, _2, _3) }, |
672 | - { "perform_action", bind(&ScopeI::perform_action_, this, _1, _2, _3) } |
673 | + { "perform_action", bind(&ScopeI::perform_action_, this, _1, _2, _3) }, |
674 | + { "debug_mode", bind(&ScopeI::debug_mode_, this, _1, _2, _3) } |
675 | }) |
676 | { |
677 | } |
678 | @@ -81,8 +83,8 @@ |
679 | } |
680 | |
681 | void ScopeI::search_(Current const& current, |
682 | - capnp::AnyPointer::Reader& in_params, |
683 | - capnproto::Response::Builder& r) |
684 | + capnp::AnyPointer::Reader& in_params, |
685 | + capnproto::Response::Builder& r) |
686 | { |
687 | auto req = in_params.getAs<capnproto::Scope::CreateQueryRequest>(); |
688 | auto query = internal::CannedQueryImpl::create(to_variant_map(req.getQuery())); |
689 | @@ -135,8 +137,8 @@ |
690 | } |
691 | |
692 | void ScopeI::perform_action_(Current const& current, |
693 | - capnp::AnyPointer::Reader& in_params, |
694 | - capnproto::Response::Builder& r) |
695 | + capnp::AnyPointer::Reader& in_params, |
696 | + capnproto::Response::Builder& r) |
697 | { |
698 | auto req = in_params.getAs<capnproto::Scope::ActionActivationRequest>(); |
699 | auto result = ResultImpl::create_result(to_variant_map(req.getResult())); |
700 | @@ -192,6 +194,18 @@ |
701 | p.setCategory(ctrl_proxy->target_category().c_str()); |
702 | } |
703 | |
704 | +void ScopeI::debug_mode_(Current const&, |
705 | + capnp::AnyPointer::Reader&, |
706 | + capnproto::Response::Builder& r) |
707 | +{ |
708 | + auto delegate = dynamic_pointer_cast<ScopeObjectBase>(del()); |
709 | + assert(delegate); |
710 | + auto debug_mode = delegate->debug_mode(); |
711 | + r.setStatus(capnproto::ResponseStatus::SUCCESS); |
712 | + auto debug_mode_response = r.initPayload().getAs<capnproto::Scope::DebugModeResponse>(); |
713 | + debug_mode_response.setReturnValue(debug_mode); |
714 | +} |
715 | + |
716 | } // namespace zmq_middleware |
717 | |
718 | } // namespace internal |
719 | |
720 | === modified file 'src/scopes/internal/zmq_middleware/ZmqObject.cpp' |
721 | --- src/scopes/internal/zmq_middleware/ZmqObject.cpp 2014-08-08 12:22:19 +0000 |
722 | +++ src/scopes/internal/zmq_middleware/ZmqObject.cpp 2014-08-13 04:58:30 +0000 |
723 | @@ -206,7 +206,7 @@ |
724 | return invoke_twoway_(out_params, timeout_); |
725 | } |
726 | |
727 | -ZmqReceiver ZmqObjectProxy::invoke_twoway_(capnp::MessageBuilder& out_params, int64_t timeout) |
728 | +ZmqReceiver ZmqObjectProxy::invoke_twoway_(capnp::MessageBuilder& out_params, int64_t twoway_timeout, int64_t locate_timeout) |
729 | { |
730 | auto registry_proxy = mw_base()->registry_proxy(); |
731 | auto ss_registry_proxy = mw_base()->ss_registry_proxy(); |
732 | @@ -221,7 +221,15 @@ |
733 | { |
734 | try |
735 | { |
736 | - ObjectProxy new_proxy = registry_proxy->locate(identity()); |
737 | + ObjectProxy new_proxy; |
738 | + if (locate_timeout != -1) |
739 | + { |
740 | + new_proxy = registry_proxy->locate(identity(), locate_timeout); |
741 | + } |
742 | + else |
743 | + { |
744 | + new_proxy = registry_proxy->locate(identity()); |
745 | + } |
746 | // update our proxy with the newly received data |
747 | // (we need to first store values in local variables outside of the mutex, |
748 | // otherwise we will deadlock on the following ZmqObjectProxy methods) |
749 | @@ -244,7 +252,7 @@ |
750 | } |
751 | |
752 | // Try the invocation |
753 | - return invoke_twoway__(out_params, timeout); |
754 | + return invoke_twoway__(out_params, twoway_timeout); |
755 | } |
756 | |
757 | // Get a socket to the endpoint for this proxy and write the request on the wire. |
758 | |
759 | === modified file 'src/scopes/internal/zmq_middleware/ZmqRegistry.cpp' |
760 | --- src/scopes/internal/zmq_middleware/ZmqRegistry.cpp 2014-07-14 06:54:43 +0000 |
761 | +++ src/scopes/internal/zmq_middleware/ZmqRegistry.cpp 2014-08-13 04:58:30 +0000 |
762 | @@ -144,7 +144,7 @@ |
763 | return sm; |
764 | } |
765 | |
766 | -ObjectProxy ZmqRegistry::locate(std::string const& identity) |
767 | +ObjectProxy ZmqRegistry::locate(std::string const& identity, int64_t timeout) |
768 | { |
769 | capnp::MallocMessageBuilder request_builder; |
770 | auto request = make_request_(request_builder, "locate"); |
771 | @@ -152,7 +152,6 @@ |
772 | in_params.setIdentity(identity.c_str()); |
773 | |
774 | // locate uses a custom timeout because it needs to potentially fork/exec a scope. |
775 | - int64_t timeout = mw_base()->locate_timeout(); |
776 | auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder, timeout); }); |
777 | auto receiver = future.get(); |
778 | auto segments = receiver.receive(); |
779 | @@ -192,6 +191,11 @@ |
780 | } |
781 | } |
782 | |
783 | +ObjectProxy ZmqRegistry::locate(std::string const& identity) |
784 | +{ |
785 | + return locate(identity, mw_base()->locate_timeout()); |
786 | +} |
787 | + |
788 | bool ZmqRegistry::is_scope_running(std::string const& scope_id) |
789 | { |
790 | capnp::MallocMessageBuilder request_builder; |
791 | |
792 | === modified file 'src/scopes/internal/zmq_middleware/ZmqScope.cpp' |
793 | --- src/scopes/internal/zmq_middleware/ZmqScope.cpp 2014-06-30 07:30:25 +0000 |
794 | +++ src/scopes/internal/zmq_middleware/ZmqScope.cpp 2014-08-13 04:58:30 +0000 |
795 | @@ -54,6 +54,7 @@ |
796 | QueryCtrl* activate(string query, ValueDict hints, Reply* replyProxy); |
797 | QueryCtrl* perform_action(string query, ValueDict hints, string action_id, Reply* replyProxy); |
798 | QueryCtrl* preview(string query, ValueDict hints, Reply* replyProxy); |
799 | + bool debug_mode(); |
800 | }; |
801 | |
802 | */ |
803 | @@ -90,7 +91,7 @@ |
804 | p.setCategory(reply_proxy->target_category().c_str()); |
805 | } |
806 | |
807 | - auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder); }); |
808 | + auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_scope_(request_builder); }); |
809 | |
810 | auto receiver = future.get(); |
811 | auto segments = receiver.receive(); |
812 | @@ -122,7 +123,7 @@ |
813 | p.setIdentity(reply_proxy->identity().c_str()); |
814 | } |
815 | |
816 | - auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder); }); |
817 | + auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_scope_(request_builder); }); |
818 | |
819 | auto receiver = future.get(); |
820 | auto segments = receiver.receive(); |
821 | @@ -157,7 +158,7 @@ |
822 | p.setIdentity(reply_proxy->identity().c_str()); |
823 | } |
824 | |
825 | - auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder); }); |
826 | + auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_scope_(request_builder); }); |
827 | future.wait(); |
828 | |
829 | auto receiver = future.get(); |
830 | @@ -190,7 +191,7 @@ |
831 | p.setIdentity(reply_proxy->identity().c_str()); |
832 | } |
833 | |
834 | - auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder); }); |
835 | + auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_scope_(request_builder); }); |
836 | |
837 | auto receiver = future.get(); |
838 | auto segments = receiver.receive(); |
839 | @@ -206,6 +207,39 @@ |
840 | return make_shared<QueryCtrlImpl>(p, reply_proxy); |
841 | } |
842 | |
843 | +bool ZmqScope::debug_mode() |
844 | +{ |
845 | + // We only need to retrieve the debug mode state once, so we cache it in debug_mode_ |
846 | + if (!debug_mode_) |
847 | + { |
848 | + capnp::MallocMessageBuilder request_builder; |
849 | + make_request_(request_builder, "debug_mode"); |
850 | + |
851 | + auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder); }); |
852 | + auto receiver = future.get(); |
853 | + auto segments = receiver.receive(); |
854 | + capnp::SegmentArrayMessageReader reader(segments); |
855 | + auto response = reader.getRoot<capnproto::Response>(); |
856 | + throw_if_runtime_exception(response); |
857 | + |
858 | + auto debug_mode_response = response.getPayload().getAs<capnproto::Scope::DebugModeResponse>(); |
859 | + debug_mode_.reset(new bool(debug_mode_response.getReturnValue())); |
860 | + } |
861 | + |
862 | + return *debug_mode_; |
863 | +} |
864 | + |
865 | +ZmqReceiver ZmqScope::invoke_scope_(capnp::MessageBuilder& out_params) |
866 | +{ |
867 | + // Check if this scope has requested debug mode, if so, disable two-way timeout and set |
868 | + // locate timeout to 15s. |
869 | + if (debug_mode()) |
870 | + { |
871 | + return this->invoke_twoway_(out_params, -1, 15000); |
872 | + } |
873 | + return this->invoke_twoway_(out_params); |
874 | +} |
875 | + |
876 | } // namespace zmq_middleware |
877 | |
878 | } // namespace internal |
879 | |
880 | === modified file 'src/scopes/internal/zmq_middleware/capnproto/Scope.capnp' |
881 | --- src/scopes/internal/zmq_middleware/capnproto/Scope.capnp 2014-02-04 15:15:25 +0000 |
882 | +++ src/scopes/internal/zmq_middleware/capnproto/Scope.capnp 2014-08-13 04:58:30 +0000 |
883 | @@ -75,3 +75,8 @@ |
884 | hints @1 : ValueDict.ValueDict; |
885 | replyProxy @2 : Proxy.Proxy; |
886 | } |
887 | + |
888 | +struct DebugModeResponse |
889 | +{ |
890 | + returnValue @0 : Bool; |
891 | +} |
892 | |
893 | === modified file 'test/gtest/scopes/Invocation/CMakeLists.txt' |
894 | --- test/gtest/scopes/Invocation/CMakeLists.txt 2014-05-13 01:40:09 +0000 |
895 | +++ test/gtest/scopes/Invocation/CMakeLists.txt 2014-08-13 04:58:30 +0000 |
896 | @@ -1,8 +1,9 @@ |
897 | configure_file(Registry.ini.in ${CMAKE_CURRENT_BINARY_DIR}/Registry.ini) |
898 | configure_file(Runtime.ini.in ${CMAKE_CURRENT_BINARY_DIR}/Runtime.ini) |
899 | configure_file(Zmq.ini.in ${CMAKE_CURRENT_BINARY_DIR}/Zmq.ini) |
900 | +configure_file(DebugTestScope.ini.in ${CMAKE_CURRENT_BINARY_DIR}/DebugTestScope.ini) |
901 | |
902 | -add_executable(Invocation_test Invocation_test.cpp TestScope.cpp EmptyScope.cpp) |
903 | +add_executable(Invocation_test Invocation_test.cpp TestScope.cpp EmptyScope.cpp DebugTestScope.cpp) |
904 | target_link_libraries(Invocation_test ${TESTLIBS}) |
905 | |
906 | add_test(Invocation Invocation_test) |
907 | |
908 | === added file 'test/gtest/scopes/Invocation/DebugTestScope.cpp' |
909 | --- test/gtest/scopes/Invocation/DebugTestScope.cpp 1970-01-01 00:00:00 +0000 |
910 | +++ test/gtest/scopes/Invocation/DebugTestScope.cpp 2014-08-13 04:58:30 +0000 |
911 | @@ -0,0 +1,59 @@ |
912 | +/* |
913 | + * Copyright (C) 2014 Canonical Ltd |
914 | + * |
915 | + * This program is free software: you can redistribute it and/or modify |
916 | + * it under the terms of the GNU Lesser General Public License version 3 as |
917 | + * published by the Free Software Foundation. |
918 | + * |
919 | + * This program is distributed in the hope that it will be useful, |
920 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
921 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
922 | + * GNU Lesser General Public License for more details. |
923 | + * |
924 | + * You should have received a copy of the GNU Lesser General Public License |
925 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
926 | + * |
927 | + * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com> |
928 | + */ |
929 | + |
930 | +#include "DebugTestScope.h" |
931 | + |
932 | +#include <unity/scopes/ScopeBase.h> |
933 | + |
934 | +#include <thread> |
935 | + |
936 | +using namespace std; |
937 | +using namespace unity::scopes; |
938 | + |
939 | +namespace |
940 | +{ |
941 | + |
942 | +class TestQuery : public SearchQueryBase |
943 | +{ |
944 | +public: |
945 | + TestQuery(CannedQuery const& query, SearchMetadata const& metadata) |
946 | + : SearchQueryBase(query, metadata) |
947 | + { |
948 | + } |
949 | + |
950 | + virtual void cancelled() override |
951 | + { |
952 | + } |
953 | + |
954 | + virtual void run(SearchReplyProxy const&) override |
955 | + { |
956 | + } |
957 | +}; |
958 | + |
959 | +} // namespace |
960 | + |
961 | +SearchQueryBase::UPtr DebugTestScope::search(CannedQuery const& query, SearchMetadata const& metadata) |
962 | +{ |
963 | + this_thread::sleep_for(chrono::milliseconds(2000)); // Attempt to timeout the two-way invocation |
964 | + return SearchQueryBase::UPtr(new TestQuery(query, metadata)); |
965 | +} |
966 | + |
967 | +PreviewQueryBase::UPtr DebugTestScope::preview(Result const&, ActionMetadata const&) |
968 | +{ |
969 | + return nullptr; // unused |
970 | +} |
971 | |
972 | === added file 'test/gtest/scopes/Invocation/DebugTestScope.h' |
973 | --- test/gtest/scopes/Invocation/DebugTestScope.h 1970-01-01 00:00:00 +0000 |
974 | +++ test/gtest/scopes/Invocation/DebugTestScope.h 2014-08-13 04:58:30 +0000 |
975 | @@ -0,0 +1,33 @@ |
976 | +/* |
977 | + * Copyright (C) 2014 Canonical Ltd |
978 | + * |
979 | + * This program is free software: you can redistribute it and/or modify |
980 | + * it under the terms of the GNU Lesser General Public License version 3 as |
981 | + * published by the Free Software Foundation. |
982 | + * |
983 | + * This program is distributed in the hope that it will be useful, |
984 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
985 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
986 | + * GNU Lesser General Public License for more details. |
987 | + * |
988 | + * You should have received a copy of the GNU Lesser General Public License |
989 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
990 | + * |
991 | + * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com> |
992 | + */ |
993 | + |
994 | +#ifndef TEST_DEBUGTESTSCOPE_H |
995 | +#define TEST_DEBUGTESTSCOPE_H |
996 | + |
997 | +#include <unity/scopes/ScopeBase.h> |
998 | + |
999 | +class DebugTestScope : public unity::scopes::ScopeBase |
1000 | +{ |
1001 | +public: |
1002 | + virtual unity::scopes::SearchQueryBase::UPtr search(unity::scopes::CannedQuery const&, |
1003 | + unity::scopes::SearchMetadata const&) override; |
1004 | + virtual unity::scopes::PreviewQueryBase::UPtr preview(unity::scopes::Result const&, |
1005 | + unity::scopes::ActionMetadata const&) override; |
1006 | +}; |
1007 | + |
1008 | +#endif |
1009 | |
1010 | === added file 'test/gtest/scopes/Invocation/DebugTestScope.ini.in' |
1011 | --- test/gtest/scopes/Invocation/DebugTestScope.ini.in 1970-01-01 00:00:00 +0000 |
1012 | +++ test/gtest/scopes/Invocation/DebugTestScope.ini.in 2014-08-13 04:58:30 +0000 |
1013 | @@ -0,0 +1,5 @@ |
1014 | +[ScopeConfig] |
1015 | +DisplayName = Debug Test Scope |
1016 | +Description = Debug Test Scope description |
1017 | +Author = Canonical |
1018 | +DebugMode = true |
1019 | |
1020 | === modified file 'test/gtest/scopes/Invocation/Invocation_test.cpp' |
1021 | --- test/gtest/scopes/Invocation/Invocation_test.cpp 2014-07-28 08:30:35 +0000 |
1022 | +++ test/gtest/scopes/Invocation/Invocation_test.cpp 2014-08-13 04:58:30 +0000 |
1023 | @@ -38,6 +38,7 @@ |
1024 | |
1025 | #include "EmptyScope.h" |
1026 | #include "TestScope.h" |
1027 | +#include "DebugTestScope.h" |
1028 | |
1029 | using namespace std; |
1030 | using namespace unity::scopes; |
1031 | @@ -136,6 +137,26 @@ |
1032 | EXPECT_EQ("", receiver->error_message()); |
1033 | } |
1034 | |
1035 | +TEST(Invocation, no_timeout_in_debug_mode) |
1036 | +{ |
1037 | + auto reg_rt = run_test_registry(); |
1038 | + auto rt = internal::RuntimeImpl::create("", "Runtime.ini"); |
1039 | + auto mw = rt->factory()->create("DebugTestScope", "Zmq", "Zmq.ini"); |
1040 | + mw->start(); |
1041 | + auto proxy = mw->create_scope_proxy("DebugTestScope"); |
1042 | + auto scope = internal::ScopeImpl::create(proxy, rt.get(), "TestScope"); |
1043 | + |
1044 | + auto receiver = make_shared<TestReceiver>(); |
1045 | + |
1046 | + // This call sleeps for 2s then returns |
1047 | + scope->search("test", SearchMetadata("unused", "unused"), receiver); |
1048 | + receiver->wait_until_finished(); |
1049 | + |
1050 | + // Check that the two-way invocation timeout did not kick in due to "DebugMode = true" |
1051 | + EXPECT_EQ(CompletionDetails::OK, receiver->status()); |
1052 | + EXPECT_EQ("", receiver->error_message()); |
1053 | +} |
1054 | + |
1055 | class NullReceiver : public SearchListenerBase |
1056 | { |
1057 | public: |
1058 | @@ -154,6 +175,7 @@ |
1059 | |
1060 | TEST(Invocation, shutdown_with_outstanding_async) |
1061 | { |
1062 | + auto reg_rt = run_test_registry(); |
1063 | auto rt = internal::RuntimeImpl::create("", "Runtime.ini"); |
1064 | auto mw = rt->factory()->create("EmptyScope", "Zmq", "Zmq.ini"); |
1065 | mw->start(); |
1066 | @@ -183,6 +205,12 @@ |
1067 | rt->run_scope(&scope, runtime_ini_file, ""); |
1068 | } |
1069 | |
1070 | +void debugtestscope_thread(Runtime::SPtr const& rt, string const& runtime_ini_file) |
1071 | +{ |
1072 | + DebugTestScope scope; |
1073 | + rt->run_scope(&scope, runtime_ini_file, "DebugTestScope.ini"); |
1074 | +} |
1075 | + |
1076 | int main(int argc, char **argv) |
1077 | { |
1078 | ::testing::InitGoogleTest(&argc, argv); |
1079 | @@ -193,6 +221,9 @@ |
1080 | Runtime::SPtr esrt = move(Runtime::create_scope_runtime("EmptyScope", "Runtime.ini")); |
1081 | std::thread emptyscope_t(nullscope_thread, esrt, "Runtime.ini"); |
1082 | |
1083 | + Runtime::SPtr dsrt = move(Runtime::create_scope_runtime("DebugTestScope", "Runtime.ini")); |
1084 | + std::thread debugtestscope_t(debugtestscope_thread, dsrt, "Runtime.ini"); |
1085 | + |
1086 | // Give threads some time to bind to endpoints, to avoid getting ObjectNotExistException |
1087 | // from a synchronous remote call. |
1088 | this_thread::sleep_for(chrono::milliseconds(500)); |
1089 | @@ -205,5 +236,8 @@ |
1090 | esrt->destroy(); |
1091 | emptyscope_t.join(); |
1092 | |
1093 | + dsrt->destroy(); |
1094 | + debugtestscope_t.join(); |
1095 | + |
1096 | return rc; |
1097 | } |
1098 | |
1099 | === modified file 'test/gtest/scopes/Registry/Registry_test.cpp' |
1100 | --- test/gtest/scopes/Registry/Registry_test.cpp 2014-08-01 03:19:32 +0000 |
1101 | +++ test/gtest/scopes/Registry/Registry_test.cpp 2014-08-13 04:58:30 +0000 |
1102 | @@ -240,6 +240,64 @@ |
1103 | EXPECT_FALSE(r->is_scope_running("testscopeB")); |
1104 | } |
1105 | |
1106 | +TEST(Registry, no_idle_timeout_in_debug_mode) |
1107 | +{ |
1108 | + bool update_received = false; |
1109 | + std::mutex mutex; |
1110 | + std::condition_variable cond; |
1111 | + |
1112 | + Runtime::UPtr rt = Runtime::create(TEST_RUNTIME_FILE); |
1113 | + RegistryProxy r = rt->registry(); |
1114 | + |
1115 | + // Configure testscopeC scope_state_callback |
1116 | + auto conn = r->set_scope_state_callback("testscopeC", [&update_received, &mutex, &cond](bool) |
1117 | + { |
1118 | + std::lock_guard<std::mutex> lock(mutex); |
1119 | + update_received = true; |
1120 | + cond.notify_one(); |
1121 | + }); |
1122 | + |
1123 | + auto wait_for_state_update = [&update_received, &mutex, &cond] |
1124 | + { |
1125 | + // Wait for an update notification |
1126 | + std::unique_lock<std::mutex> lock(mutex); |
1127 | + bool success = cond.wait_for(lock, std::chrono::milliseconds(500), [&update_received] { return update_received; }); |
1128 | + update_received = false; |
1129 | + return success; |
1130 | + }; |
1131 | + |
1132 | + // Move testscopeC into the scopes folder |
1133 | + filesystem::rename(TEST_RUNTIME_PATH "/other_scopes/testscopeC", TEST_RUNTIME_PATH "/scopes/testscopeC"); |
1134 | + std::this_thread::sleep_for(std::chrono::milliseconds(500)); |
1135 | + |
1136 | + auto meta = r->get_metadata("testscopeC"); |
1137 | + auto sp = meta.proxy(); |
1138 | + |
1139 | + // testscopeC should not be running at this point |
1140 | + EXPECT_FALSE(r->is_scope_running("testscopeC")); |
1141 | + EXPECT_FALSE(wait_for_state_update()); |
1142 | + |
1143 | + // search would fail if testscopeC can't be executed |
1144 | + auto receiver = std::make_shared<Receiver>(); |
1145 | + SearchListenerBase::SPtr reply(receiver); |
1146 | + auto ctrl = sp->search("foo", SearchMetadata("C", "desktop"), reply); |
1147 | + EXPECT_TRUE(receiver->wait_until_finished()); |
1148 | + |
1149 | + // testscopeC should now be running |
1150 | + EXPECT_TRUE(wait_for_state_update()); |
1151 | + EXPECT_TRUE(r->is_scope_running("testscopeC")); |
1152 | + |
1153 | + // check that the scope is still running after 4s |
1154 | + // (due to "DebugMode = true" and despite "IdleTimeout = 2") |
1155 | + std::this_thread::sleep_for(std::chrono::seconds{4}); |
1156 | + EXPECT_FALSE(wait_for_state_update()); |
1157 | + EXPECT_TRUE(r->is_scope_running("testscopeC")); |
1158 | + |
1159 | + // Move testscopeC back into the other_scopes folder |
1160 | + filesystem::rename(TEST_RUNTIME_PATH "/scopes/testscopeC", TEST_RUNTIME_PATH "/other_scopes/testscopeC"); |
1161 | + std::this_thread::sleep_for(std::chrono::milliseconds(500)); |
1162 | +} |
1163 | + |
1164 | TEST(Registry, list_update_notify_before_click_folder_exists) |
1165 | { |
1166 | bool update_received = false; |
1167 | |
1168 | === modified file 'test/gtest/scopes/Registry/other_scopes/testscopeC/CMakeLists.txt' |
1169 | --- test/gtest/scopes/Registry/other_scopes/testscopeC/CMakeLists.txt 2014-06-04 17:49:34 +0000 |
1170 | +++ test/gtest/scopes/Registry/other_scopes/testscopeC/CMakeLists.txt 2014-08-13 04:58:30 +0000 |
1171 | @@ -1,1 +1,3 @@ |
1172 | +add_library(testscopeC MODULE testscopeC.cpp) |
1173 | +target_link_libraries(testscopeC ${LIBGTEST}) |
1174 | configure_file(testscopeC.ini.in testscopeC.ini) |
1175 | |
1176 | === added file 'test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.cpp' |
1177 | --- test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.cpp 1970-01-01 00:00:00 +0000 |
1178 | +++ test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.cpp 2014-08-13 04:58:30 +0000 |
1179 | @@ -0,0 +1,99 @@ |
1180 | +/* |
1181 | + * Copyright (C) 2014 Canonical Ltd |
1182 | + * |
1183 | + * This program is free software: you can redistribute it and/or modify |
1184 | + * it under the terms of the GNU Lesser General Public License version 3 as |
1185 | + * published by the Free Software Foundation. |
1186 | + * |
1187 | + * This program is distributed in the hope that it will be useful, |
1188 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1189 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1190 | + * GNU Lesser General Public License for more details. |
1191 | + * |
1192 | + * You should have received a copy of the GNU Lesser General Public License |
1193 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1194 | + * |
1195 | + * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com> |
1196 | + */ |
1197 | + |
1198 | +#include <unity/scopes/ScopeBase.h> |
1199 | + |
1200 | +#define EXPORT __attribute__ ((visibility ("default"))) |
1201 | + |
1202 | +using namespace unity::scopes; |
1203 | + |
1204 | +class MyQuery : public SearchQueryBase |
1205 | +{ |
1206 | +public: |
1207 | + MyQuery(CannedQuery const& query, SearchMetadata const& metadata) : |
1208 | + SearchQueryBase(query, metadata) |
1209 | + { |
1210 | + } |
1211 | + |
1212 | + virtual void cancelled() override |
1213 | + { |
1214 | + } |
1215 | + |
1216 | + virtual void run(SearchReplyProxy const&) override |
1217 | + { |
1218 | + } |
1219 | +}; |
1220 | + |
1221 | +class MyPreview : public PreviewQueryBase |
1222 | +{ |
1223 | +public: |
1224 | + MyPreview(Result const& result, ActionMetadata const& metadata) |
1225 | + : PreviewQueryBase(result, metadata) |
1226 | + { |
1227 | + } |
1228 | + |
1229 | + virtual void cancelled() override |
1230 | + { |
1231 | + } |
1232 | + |
1233 | + virtual void run(PreviewReplyProxy const&) override |
1234 | + { |
1235 | + } |
1236 | +}; |
1237 | + |
1238 | +class MyScope : public ScopeBase |
1239 | +{ |
1240 | +public: |
1241 | + virtual void start(std::string const&) override |
1242 | + { |
1243 | + } |
1244 | + |
1245 | + virtual void stop() override {} |
1246 | + |
1247 | + virtual SearchQueryBase::UPtr search(CannedQuery const& q, SearchMetadata const& metadata) override |
1248 | + { |
1249 | + SearchQueryBase::UPtr query(new MyQuery(q, metadata)); |
1250 | + return query; |
1251 | + } |
1252 | + |
1253 | + virtual PreviewQueryBase::UPtr preview(Result const& result, ActionMetadata const& metadata) override |
1254 | + { |
1255 | + PreviewQueryBase::UPtr preview(new MyPreview(result, metadata)); |
1256 | + return preview; |
1257 | + } |
1258 | +}; |
1259 | + |
1260 | +extern "C" |
1261 | +{ |
1262 | + |
1263 | + EXPORT |
1264 | + unity::scopes::ScopeBase* |
1265 | + // cppcheck-suppress unusedFunction |
1266 | + UNITY_SCOPE_CREATE_FUNCTION() |
1267 | + { |
1268 | + return new MyScope; |
1269 | + } |
1270 | + |
1271 | + EXPORT |
1272 | + void |
1273 | + // cppcheck-suppress unusedFunction |
1274 | + UNITY_SCOPE_DESTROY_FUNCTION(unity::scopes::ScopeBase* scope_base) |
1275 | + { |
1276 | + delete scope_base; |
1277 | + } |
1278 | +} |
1279 | |
1280 | === modified file 'test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.ini.in' |
1281 | --- test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.ini.in 2014-06-04 17:49:34 +0000 |
1282 | +++ test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.ini.in 2014-08-13 04:58:30 +0000 |
1283 | @@ -6,3 +6,5 @@ |
1284 | Icon = /foo/scope-C.Icon |
1285 | SearchHint = scope-C.SearchHint |
1286 | HotKey = scope-C.HotKey |
1287 | +IdleTimeout = 2 |
1288 | +DebugMode = true |
1289 | |
1290 | === modified file 'test/gtest/scopes/ReplyReaper/CMakeLists.txt' |
1291 | --- test/gtest/scopes/ReplyReaper/CMakeLists.txt 2014-07-30 21:34:13 +0000 |
1292 | +++ test/gtest/scopes/ReplyReaper/CMakeLists.txt 2014-08-13 04:58:30 +0000 |
1293 | @@ -1,6 +1,7 @@ |
1294 | configure_file(Registry.ini.in ${CMAKE_CURRENT_BINARY_DIR}/Registry.ini) |
1295 | configure_file(Runtime.ini.in ${CMAKE_CURRENT_BINARY_DIR}/Runtime.ini) |
1296 | configure_file(Zmq.ini.in ${CMAKE_CURRENT_BINARY_DIR}/Zmq.ini) |
1297 | +configure_file(DebugScope.ini.in ${CMAKE_CURRENT_BINARY_DIR}/DebugScope.ini) |
1298 | |
1299 | add_definitions(-DTEST_DIR="${CMAKE_CURRENT_BINARY_DIR}") |
1300 | |
1301 | |
1302 | === added file 'test/gtest/scopes/ReplyReaper/DebugScope.ini.in' |
1303 | --- test/gtest/scopes/ReplyReaper/DebugScope.ini.in 1970-01-01 00:00:00 +0000 |
1304 | +++ test/gtest/scopes/ReplyReaper/DebugScope.ini.in 2014-08-13 04:58:30 +0000 |
1305 | @@ -0,0 +1,5 @@ |
1306 | +[ScopeConfig] |
1307 | +DisplayName = DebugScope |
1308 | +Description = Debug Scope |
1309 | +Author = Canonical |
1310 | +DebugMode = true |
1311 | |
1312 | === modified file 'test/gtest/scopes/ReplyReaper/ReplyReaper_test.cpp' |
1313 | --- test/gtest/scopes/ReplyReaper/ReplyReaper_test.cpp 2014-08-06 04:54:06 +0000 |
1314 | +++ test/gtest/scopes/ReplyReaper/ReplyReaper_test.cpp 2014-08-13 04:58:30 +0000 |
1315 | @@ -106,3 +106,66 @@ |
1316 | no_reply_rt->destroy(); |
1317 | scope_t.join(); |
1318 | } |
1319 | + |
1320 | +class NoReapReceiver : public SearchListenerBase |
1321 | +{ |
1322 | +public: |
1323 | + NoReapReceiver() |
1324 | + : query_complete_(false) |
1325 | + { |
1326 | + } |
1327 | + |
1328 | + virtual void push(CategorisedResult /* result */) override |
1329 | + { |
1330 | + } |
1331 | + |
1332 | + virtual void finished(CompletionDetails const& details) override |
1333 | + { |
1334 | + // Check that finished() was called by the reaper. |
1335 | + EXPECT_EQ(CompletionDetails::OK, details.status()); |
1336 | + EXPECT_EQ("", details.message()); |
1337 | + lock_guard<mutex> lock(mutex_); |
1338 | + query_complete_ = true; |
1339 | + cond_.notify_all(); |
1340 | + } |
1341 | + |
1342 | + void wait_until_finished() |
1343 | + { |
1344 | + unique_lock<mutex> lock(mutex_); |
1345 | + cond_.wait(lock, [this] { return this->query_complete_; }); |
1346 | + } |
1347 | + |
1348 | +private: |
1349 | + bool query_complete_; |
1350 | + mutex mutex_; |
1351 | + condition_variable cond_; |
1352 | +}; |
1353 | + |
1354 | +void scope_thread_debug_mode(Runtime::SPtr const& rt, string const& runtime_ini_file) |
1355 | +{ |
1356 | + NoReplyScope scope; |
1357 | + rt->run_scope(&scope, runtime_ini_file, TEST_DIR "/DebugScope.ini"); |
1358 | +} |
1359 | + |
1360 | +TEST(ReplyReaper, no_reap_in_debug_mode) |
1361 | +{ |
1362 | + auto reg_rt = run_test_registry(); |
1363 | + |
1364 | + Runtime::SPtr no_reply_rt = move(Runtime::create_scope_runtime("NoReplyScope", TEST_DIR "/Runtime.ini")); |
1365 | + std::thread scope_t(scope_thread_debug_mode, no_reply_rt, TEST_DIR "/Runtime.ini"); |
1366 | + |
1367 | + // Run a query in the scope. The query will do nothing for 3 seconds, |
1368 | + // but the reaper will reap after at most 2 seconds. |
1369 | + auto rt = internal::RuntimeImpl::create("", TEST_DIR "/Runtime.ini"); |
1370 | + auto mw = rt->factory()->create("NoReplyScope", "Zmq", TEST_DIR "/Zmq.ini"); |
1371 | + mw->start(); |
1372 | + auto proxy = mw->create_scope_proxy("NoReplyScope"); |
1373 | + auto scope = internal::ScopeImpl::create(proxy, rt.get(), "NoReplyScope"); |
1374 | + |
1375 | + auto receiver = make_shared<NoReapReceiver>(); |
1376 | + scope->search("test", SearchMetadata("en", "phone"), receiver); |
1377 | + receiver->wait_until_finished(); |
1378 | + |
1379 | + no_reply_rt->destroy(); |
1380 | + scope_t.join(); |
1381 | +} |
1382 | |
1383 | === modified file 'test/gtest/scopes/internal/ScopeConfig/ScopeConfig_test.cpp' |
1384 | --- test/gtest/scopes/internal/ScopeConfig/ScopeConfig_test.cpp 2014-08-08 14:06:59 +0000 |
1385 | +++ test/gtest/scopes/internal/ScopeConfig/ScopeConfig_test.cpp 2014-08-13 04:58:30 +0000 |
1386 | @@ -49,6 +49,7 @@ |
1387 | EXPECT_EQ(300, cfg.idle_timeout()); |
1388 | EXPECT_EQ(ScopeMetadata::ResultsTtlType::Large, cfg.results_ttl_type()); |
1389 | EXPECT_TRUE(cfg.location_data_needed()); |
1390 | + EXPECT_TRUE(cfg.debug_mode()); |
1391 | |
1392 | auto attrs = cfg.appearance_attributes(); |
1393 | EXPECT_EQ(5, attrs.size()); |
1394 | @@ -78,6 +79,7 @@ |
1395 | EXPECT_EQ(DFLT_SCOPE_IDLE_TIMEOUT, cfg.idle_timeout()); |
1396 | EXPECT_EQ(ScopeMetadata::ResultsTtlType::None, cfg.results_ttl_type()); |
1397 | EXPECT_FALSE(cfg.location_data_needed()); |
1398 | + EXPECT_FALSE(cfg.debug_mode()); |
1399 | |
1400 | EXPECT_EQ(0, cfg.appearance_attributes().size()); |
1401 | |
1402 | |
1403 | === modified file 'test/gtest/scopes/internal/ScopeConfig/complete_config.ini.in' |
1404 | --- test/gtest/scopes/internal/ScopeConfig/complete_config.ini.in 2014-07-18 04:02:58 +0000 |
1405 | +++ test/gtest/scopes/internal/ScopeConfig/complete_config.ini.in 2014-08-13 04:58:30 +0000 |
1406 | @@ -16,6 +16,7 @@ |
1407 | ResultsTtlType = large |
1408 | LocationDataNeeded = true |
1409 | ConfinementType = unconfined |
1410 | +DebugMode = true |
1411 | |
1412 | [Appearance] |
1413 | arbitrary_key = true |
1414 | |
1415 | === modified file 'test/gtest/scopes/internal/zmq_middleware/ZmqMiddleware/ZmqMiddleware_test.cpp' |
1416 | --- test/gtest/scopes/internal/zmq_middleware/ZmqMiddleware/ZmqMiddleware_test.cpp 2014-07-24 10:43:37 +0000 |
1417 | +++ test/gtest/scopes/internal/zmq_middleware/ZmqMiddleware/ZmqMiddleware_test.cpp 2014-08-13 04:58:30 +0000 |
1418 | @@ -452,6 +452,11 @@ |
1419 | { |
1420 | return nullptr; |
1421 | } |
1422 | + |
1423 | + virtual bool debug_mode() const override |
1424 | + { |
1425 | + return false; |
1426 | + } |
1427 | }; |
1428 | |
1429 | // Make sure that multiple threads calling wait_for_shutdown() complete |