{
detail::CallId callId;
detail::displayDebugCallInfoSignal(callId, signalName, info, connectionInfo->interfaceName);
- auto tmp = new std::function<void(const Eldbus_Message *msg)> {
- [ callId, connectionState = this->connectionState, callback, signalName, connectionInfo = this->connectionInfo ]
- (const Eldbus_Message * msg) -> void {
- const char *errname, *aux;
- if (eldbus_message_error_get(msg, &errname, &aux))
- {
- DBUS_DEBUG("call %d: Eldbus error: %s %s", callId.id, errname, aux);
- return;
- }
- connectionInfo->emit(signalName.c_str(), DBusActionType::SIGNAL_RECEIVED);
- DBUS_DEBUG("call %d: received signal with signature '%s'", callId.id, eldbus_message_signature_get(msg));
- using ParamsType = typename detail::dbus_interface_traits<SignalType>::VEArgs;
- auto params = detail::unpackValues<ParamsType>(callId, msg);
- if (!params)
- {
- DBUS_DEBUG("call %d: failed: %s", callId.id, params.getError().message.c_str());
- return;
- }
- try
- {
- detail::apply(callback, params.getValues());
- } catch (...)
- {
- ERROR("unhandled exception");
- }
+ auto callbackLambda = [ callId, connectionState = this->connectionState, callback, signalName, connectionInfo = this->connectionInfo ]
+ (const Eldbus_Message * msg) -> void {
+ const char *errname, *aux;
+ if (eldbus_message_error_get(msg, &errname, &aux))
+ {
+ DBUS_DEBUG("call %d: Eldbus error: %s %s", callId.id, errname, aux);
+ return;
+ }
+ connectionInfo->emit(signalName.c_str(), DBusActionType::SIGNAL_RECEIVED);
+ DBUS_DEBUG("call %d: received signal with signature '%s'", callId.id, eldbus_message_signature_get(msg));
+ using ParamsType = typename detail::dbus_interface_traits<SignalType>::VEArgs;
+ auto params = detail::unpackValues<ParamsType>(callId, msg);
+ if (!params)
+ {
+ DBUS_DEBUG("call %d: failed: %s", callId.id, params.getError().message.c_str());
+ return;
+ }
+ try
+ {
+ detail::apply(callback, params.getValues());
+ } catch (...)
+ {
+ ERROR("unhandled exception");
}
};
+ auto tmp = new std::function<void(const Eldbus_Message *msg)> { std::move(callbackLambda) };
auto handler = eldbus_proxy_signal_handler_add(connectionState.proxy, signalName.c_str(), listenerCallback, tmp);
destructors.push_back([ = ]() {
eldbus_signal_handler_del(handler);
void insertWaits()
{
- variables["tts"] = EvaluationValueFunction{ [&](std::string pattern) -> EvaluationValue_ {
- std::regex regex;
- if (!pattern.empty())
+ struct WaitTTSImpl : public EvaluationValueWaitInterface {
+ TestExecutor *self;
+ std::chrono::high_resolution_clock::time_point untilMoment;
+ std::string pattern;
+ bool success = false;
+
+ void join() override {
+ if (success) return;
+ auto h = self->ttsInfo.lock();
+ success = h.waitForCondition(untilMoment, [&]()
{
- try {
- regex = std::regex {
- pattern,
- std::regex_constants::nosubs |
- std::regex_constants::optimize |
- std::regex_constants::ECMAScript
- };
- } catch (...) {
- throw EvaluationFailure{} << "invalid regex pattern '" << pattern << "'";
- }
- }
+ return h->mode == TTSInfo::Mode::found;
+ });
+ if (!success)
{
- auto h = ttsInfo.lock();
- if (!pattern.empty())
- h->searchLine = std::move(regex);
- h->mode = TTSInfo::Mode::search;
+ h->mode = TTSInfo::Mode::ignore;
+ throw EvaluationFailure{} << "wait for dlog ('" << pattern << "'): operation timeouted";
}
- struct Impl : public EvaluationValueWaitInterface {
- TestExecutor *self;
- std::chrono::high_resolution_clock::time_point untilMoment;
- std::string pattern;
- bool success = false;
-
- void join() override {
- if (success) return;
- auto h = self->ttsInfo.lock();
- success = h.waitForCondition(untilMoment, [&]()
- {
- return h->mode == TTSInfo::Mode::found;
- });
- if (!success)
- {
- h->mode = TTSInfo::Mode::ignore;
- throw EvaluationFailure{} << "wait for dlog ('" << pattern << "'): operation timeouted";
- }
- h->mode = TTSInfo::Mode::ignore;
- }
- bool isSatisfied() override {
- if (success) return true;
- auto h = self->ttsInfo.lock();
- return success = (h->mode == TTSInfo::Mode::found);
- }
- };
- auto impl = std::make_shared<Impl>();
- impl->self = this;
- impl->untilMoment = std::chrono::high_resolution_clock::now() + 3s;
- impl->pattern = std::move(pattern);
- return EvaluationValue_{ impl };
- }, { { "pattern", EvaluationValue_{ "" } } } };
- variables["gui"] = EvaluationValueFunction{ [&](std::string name) -> EvaluationValue_ {
- struct Impl : public EvaluationValueWaitInterface {
- TestExecutor *self;
- std::chrono::high_resolution_clock::time_point untilMoment;
- std::string name;
- std::string currentRootName;
- bool success = false, searchForAnyChange = false;
-
- void join() override {
- if (success) return;
- auto h = self->contextInfo.lock();
- success = h.waitForCondition(untilMoment, [&]()
- {
- return
- (searchForAnyChange && currentRootName != h->rootName) ||
- (!searchForAnyChange && h->rootName == name);
- });
- if (!success)
- {
- throw EvaluationFailure{} << "wait for gui ('" << name << "'): operation timeouted, " <<
- "current root name is '" << h->rootName << "'";
- }
- }
- bool isSatisfied() override {
- if (success) return true;
- auto h = self->contextInfo.lock();
- return success = (h->rootName == name);
- }
- };
- auto impl = std::make_shared<Impl>();
- impl->self = this;
- impl->untilMoment = std::chrono::high_resolution_clock::now() + 3s;
- impl->name = std::move(name);
- if (impl->name.empty())
+ h->mode = TTSInfo::Mode::ignore;
+ }
+ bool isSatisfied() override {
+ if (success) return true;
+ auto h = self->ttsInfo.lock();
+ return success = (h->mode == TTSInfo::Mode::found);
+ }
+ };
+
+ auto waitTTSImpl = [&](std::string pattern) -> EvaluationValue_ {
+ std::regex regex;
+ if (!pattern.empty())
+ {
+ try {
+ regex = std::regex {
+ pattern,
+ std::regex_constants::nosubs |
+ std::regex_constants::optimize |
+ std::regex_constants::ECMAScript
+ };
+ } catch (...) {
+ throw EvaluationFailure{} << "invalid regex pattern '" << pattern << "'";
+ }
+ }
+ {
+ auto h = ttsInfo.lock();
+ if (!pattern.empty())
+ h->searchLine = std::move(regex);
+ h->mode = TTSInfo::Mode::search;
+ }
+ auto impl = std::make_shared<WaitTTSImpl>();
+ impl->self = this;
+ impl->untilMoment = std::chrono::high_resolution_clock::now() + 3s;
+ impl->pattern = std::move(pattern);
+ return EvaluationValue_{ impl };
+ };
+ variables["tts"] = EvaluationValueFunction{ std::move(waitTTSImpl), { { "pattern", EvaluationValue_{ "" } } } };
+
+ struct WaitGuiImpl : public EvaluationValueWaitInterface {
+ TestExecutor *self;
+ std::chrono::high_resolution_clock::time_point untilMoment;
+ std::string name;
+ std::string currentRootName;
+ bool success = false, searchForAnyChange = false;
+
+ void join() override {
+ if (success) return;
+ auto h = self->contextInfo.lock();
+ success = h.waitForCondition(untilMoment, [&]()
+ {
+ return
+ (searchForAnyChange && currentRootName != h->rootName) ||
+ (!searchForAnyChange && h->rootName == name);
+ });
+ if (!success)
{
- auto h = contextInfo.lock();
- impl->currentRootName = h->rootName;
- impl->searchForAnyChange = true;
+ throw EvaluationFailure{} << "wait for gui ('" << name << "'): operation timeouted, " <<
+ "current root name is '" << h->rootName << "'";
}
- return EvaluationValue_{ impl };
- }, { { "name", EvaluationValue_{ "" } } } };
+ }
+ bool isSatisfied() override {
+ if (success) return true;
+ auto h = self->contextInfo.lock();
+ return success = (h->rootName == name);
+ }
+ };
+
+ auto waitGuiImpl = [&](std::string name) -> EvaluationValue_ {
+ auto impl = std::make_shared<WaitGuiImpl>();
+ impl->self = this;
+ impl->untilMoment = std::chrono::high_resolution_clock::now() + 3s;
+ impl->name = std::move(name);
+ if (impl->name.empty())
+ {
+ auto h = contextInfo.lock();
+ impl->currentRootName = h->rootName;
+ impl->searchForAnyChange = true;
+ }
+ return EvaluationValue_{ impl };
+ };
+ variables["gui"] = EvaluationValueFunction{ std::move(waitGuiImpl), { { "name", EvaluationValue_{ "" } } } };
}
void insertActivities()
*outputPtr << os.str() << "\n\n";
}
auto exec = std::make_unique<TestExecutor>(*outputPtr);
- return std::thread { [result = std::move(result), exec = std::move(exec), outputPtr = std::move(outputPtr), dlog = std::move(dlog) ]() mutable
+ auto threadFunc = [result = std::move(result), exec = std::move(exec), outputPtr = std::move(outputPtr), dlog = std::move(dlog) ]() mutable
{
EvaluationContext ec(*exec);
exec->outputStream() << "waiting for context change...\n";
ecore_main_loop_quit();
});
DEBUG("done batch");
- } };
+ };
+ return std::thread { std::move(threadFunc) };
}