diff options
author | Krzysztof Jackiewicz <k.jackiewicz@samsung.com> | 2015-08-27 12:44:16 +0200 |
---|---|---|
committer | Janusz Kozerski <j.kozerski@samsung.com> | 2015-09-08 14:12:36 +0200 |
commit | 8fc0b8fc2a814035dc9cf8c7e211dc3a8f74d11b (patch) | |
tree | 6f86a12ee0423d9b83eb5ca5f55bd20cb8dee129 | |
parent | ae4a130374e96d383e09571f2e098ef237e28418 (diff) | |
download | cert-checker-8fc0b8fc2a814035dc9cf8c7e211dc3a8f74d11b.tar.gz cert-checker-8fc0b8fc2a814035dc9cf8c7e211dc3a8f74d11b.tar.bz2 cert-checker-8fc0b8fc2a814035dc9cf8c7e211dc3a8f74d11b.zip |
Fixed synchronisation issues
[Problem] Production code mixed with test code. Poor readability.
Synchronisation issues.
[Solution] Synchronisation reimplemented. Test code separated from production
code.
[Verification] Run all test
Change-Id: Iea5ed2ce9f10a4cdac8994acf91809cd12050d69
-rw-r--r-- | src/include/cchecker/logic.h | 11 | ||||
-rw-r--r-- | src/logic.cpp | 130 | ||||
-rw-r--r-- | tests/logic_.cpp | 127 | ||||
-rw-r--r-- | tests/logic_.h | 82 | ||||
-rw-r--r-- | tests/test_logic.cpp | 452 |
5 files changed, 743 insertions, 59 deletions
diff --git a/src/include/cchecker/logic.h b/src/include/cchecker/logic.h index aa50388..b5f1c22 100644 --- a/src/include/cchecker/logic.h +++ b/src/include/cchecker/logic.h @@ -97,10 +97,15 @@ class Logic { void *logic_ptr) ); + void push_event(event_t event); + void process_all(void); void process_queue(void); - void process_event(const event_t &event); + virtual void process_event(const event_t &event); + + bool process_app(app_t& app); void process_buffer(void); + virtual void app_processed() {}; // for tests bool get_online(void) const; void set_online(bool online); @@ -108,7 +113,7 @@ class Logic { bool get_should_exit(void) const; void set_should_exit(void); - void call_ui(const app_t &app); + bool call_ui(const app_t &app); Queue m_queue; Certs m_certs; @@ -117,6 +122,8 @@ class Logic { bool m_was_setup_called; bool m_is_online; + // TODO: use m_queue for online events + bool m_is_online_enabled; std::condition_variable m_to_process; std::mutex m_mutex_cv; std::thread m_thread; diff --git a/src/logic.cpp b/src/logic.cpp index aef6aec..da1599c 100644 --- a/src/logic.cpp +++ b/src/logic.cpp @@ -46,8 +46,11 @@ Logic::~Logic(void) // wait and join processing thread if (m_thread.joinable()) { LogDebug("Waiting for join processing thread"); - set_should_exit(); - m_to_process.notify_one(); + { + std::lock_guard<std::mutex> lock(m_mutex_cv); + set_should_exit(); + m_to_process.notify_one(); + } m_thread.join(); LogDebug("Processing thread joined"); } @@ -67,6 +70,7 @@ Logic::Logic(void) : m_sqlquery(NULL), m_was_setup_called(false), m_is_online(false), + m_is_online_enabled(false), m_should_exit(false), m_proxy_connman(NULL), m_proxy_pkgmgr_install(NULL), @@ -80,7 +84,14 @@ bool Logic::get_online() const void Logic::set_online(bool online) { + std::lock_guard<std::mutex> lock(m_mutex_cv); + if (m_is_online == online) + return; m_is_online = online; + if (m_is_online) { + m_is_online_enabled = true; + m_to_process.notify_one(); + } } error_t Logic::setup_db() @@ -316,15 +327,13 @@ void Logic::pkgmgr_callback_internal(GVariant *parameters, if (event == EVENT_INSTALL) { LogDebug("Install: uid : " << uid << ", pkgid: " << pkgid << ", state: " << state << ", status: " << status); - m_queue.push_event(event_t(app, event_t::event_type_t::APP_INSTALL)); + push_event(event_t(app, event_t::event_type_t::APP_INSTALL)); } else if (event == EVENT_UNINSTALL) { LogDebug("Uninstall: uid : " << uid << ", pkgid: " << pkgid << ", state: " << state << ", status: " << status); - m_queue.push_event(event_t(app, event_t::event_type_t::APP_UNINSTALL)); + push_event(event_t(app, event_t::event_type_t::APP_UNINSTALL)); } - - m_to_process.notify_one(); } else LogDebug("Wrong state (" << std::string(state) << ") or status (" << std::string(status) << ")"); @@ -381,82 +390,92 @@ void Logic::process_queue(void) } } -void Logic::call_ui(const app_t &app) +bool Logic::call_ui(const app_t &app) { UI::UIBackend ui; if (ui.call_popup(app)) { // If calling popup or app_controll service will fail, // do not remove application, and ask about it once again later - remove_app_from_buffer_and_database(app); LogDebug("Popup shown correctly. Application will be removed from DB and buffer"); + return true; } - else - LogDebug("Popup error. Application will be marked to show popup later."); + LogDebug("Popup error. Application will be marked to show popup later."); + return false; } -void Logic::process_buffer(void) -{ - for (auto iter = m_buffer.begin(); iter != m_buffer.end();) { - - // Check if app hasn't already been verified. - // If yes then just try to display popup once again, and go the next app. +bool Logic::process_app(app_t& app) { + // Check if app hasn't already been verified. + // If yes then just try to display popup once again, and go the next app. #if POPUP - if (iter->verified == app_t::verified_t::NO) { - app_t app_cpy = *iter; - LogDebug(app_cpy.str() << " has been verified before. Popup should be shown."); - call_ui(app_cpy); - iter++; - continue; - } + if (app.verified == app_t::verified_t::NO) { + LogDebug(app.str() << " has been verified before. Popup should be shown."); + return call_ui(app); + } #endif - Certs::ocsp_response_t ret; - ret = m_certs.check_ocsp(*iter); + Certs::ocsp_response_t ret; + ret = m_certs.check_ocsp(app); - // If OCSP returns success or OCSP checking fails we should remove application from buffer and database - if (ret == Certs::ocsp_response_t::OCSP_APP_OK || - ret == Certs::ocsp_response_t::OCSP_CERT_ERROR) { - LogDebug(iter->str() << " OCSP verified (or not available for app's chains)"); - app_t app_cpy = *iter; - iter++; - remove_app_from_buffer_and_database(app_cpy); - } - else if (ret == Certs::ocsp_response_t::OCSP_APP_REVOKED) { - LogDebug(iter->str() << " certificate has been revoked. Popup should be shown"); - iter->verified = app_t::verified_t::NO; - app_t app_cpy = *iter; - iter++; + // If OCSP returns success or OCSP checking fails we should remove application from buffer and database + if (ret == Certs::ocsp_response_t::OCSP_APP_OK || + ret == Certs::ocsp_response_t::OCSP_CERT_ERROR) { + LogDebug(app.str() << " OCSP verified (or not available for app's chains)"); + return true; + } + else if (ret == Certs::ocsp_response_t::OCSP_APP_REVOKED) { + LogDebug(app.str() << " certificate has been revoked. Popup should be shown"); + app.verified = app_t::verified_t::NO; #if POPUP // Do not remove app here - just waits for user answer from popup // Temporary solution because notification framework doesn't work - call_ui(app_cpy); + return call_ui(app); #else - remove_app_from_buffer_and_database(app_cpy); + return true; #endif - } - else { - LogDebug(iter->str() << " should be checked again later"); - // If check_ocsp returns Certs::ocsp_response_t::OCSP_CHECK_AGAIN - // app should be checked again later - iter++; - } } + else { + LogDebug(app.str() << " should be checked again later"); + // If check_ocsp returns Certs::ocsp_response_t::OCSP_CHECK_AGAIN + // app should be checked again later + } + return false; +} + +void Logic::process_buffer(void) +{ + for (auto iter = m_buffer.begin(); iter != m_buffer.end();) { + bool remove = process_app(*iter); + auto prev = *iter; + iter++; + if (remove) + remove_app_from_buffer_and_database(prev); + app_processed(); + } +} + +void Logic::push_event(event_t event) +{ + std::lock_guard<std::mutex> lock(m_mutex_cv); + m_queue.push_event(std::move(event)); + m_to_process.notify_one(); } void Logic::process_all() { - //Check if should't exit - while (!get_should_exit()) { + for(;;) { std::unique_lock<std::mutex> lock(m_mutex_cv); + if (m_should_exit) + break; //lock will be unlocked upon destruction - if (m_queue.empty()) { + // don't sleep if there are online/installation/deinstallation events to process + if(m_queue.empty() && !m_is_online_enabled) { LogDebug("Processing thread: waiting on condition"); - m_to_process.wait(lock); + m_to_process.wait(lock); // spurious wakeups do not concern us + LogDebug("Processing thread: running"); } - else - LogDebug("Processing thread: More events in queue - processing again"); - LogDebug("Processing thread: running"); + m_is_online_enabled = false; + lock.unlock(); process_queue(); if (get_online()) @@ -466,9 +485,6 @@ void Logic::process_all() LogDebug("Processing done"); } - - // should process queue just before exit - process_queue(); } void Logic::process_event(const event_t &event) diff --git a/tests/logic_.cpp b/tests/logic_.cpp new file mode 100644 index 0000000..17dc0bb --- /dev/null +++ b/tests/logic_.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file logic_.cpp + * @author Janusz Kozerski (j.kozerski@samsung.com) + * @version 1.0 + * @brief This file is the implementation of SQL queries + */ + +/* + * This Class makes all methods from Logic Class public - for testing purpose. + * Some of methods are stubbed, and some of them just calls corresponding methods from Logic Class. + */ + +#include <cchecker/log.h> +#include <chrono> +#include <boost/test/unit_test.hpp> + +#include <logic_.h> + +namespace CCHECKER { + +Logic_::Logic_(void) : + Logic(), + m_installCnt(0), + m_uninstallCnt(0), + m_bufferCnt(0) +{} + +Logic_::~Logic_(void) +{ + clean(); +} + +// For tests only + +void Logic_::connman_callback_manual_(bool state) +{ + Logic::set_online(state); +} + +void Logic_::pkgmgr_install_manual_(const app_t &app) +{ + push_event(event_t(app, event_t::event_type_t::APP_INSTALL)); +} + +void Logic_::pkgmgr_uninstall_manual_(const app_t &app) +{ + push_event(event_t(app, event_t::event_type_t::APP_UNINSTALL)); +} + +void Logic_::process_event(const event_t &event) +{ + Logic::process_event(event); + + std::lock_guard<std::mutex> lock(_m_mutex_wait_cv); + switch(event.event_type) + { + case event_t::event_type_t::APP_INSTALL: + m_installCnt++; + LogDebug(m_installCnt << " " << m_uninstallCnt << " " << m_bufferCnt); + break; + case event_t::event_type_t::APP_UNINSTALL: + m_uninstallCnt++; + LogDebug(m_installCnt << " " << m_uninstallCnt << " " << m_bufferCnt); + break; + default: + return; + } + // notify caller + _m_wait_for_process.notify_one(); +} + +void Logic_::app_processed() +{ + std::lock_guard<std::mutex> lock(_m_mutex_wait_cv); + m_bufferCnt++; + LogDebug(m_installCnt << " " << m_uninstallCnt << " " << m_bufferCnt); + + // notify caller + _m_wait_for_process.notify_one(); +} + +void Logic_::reset_cnt() +{ + m_installCnt = 0; + m_uninstallCnt = 0; + m_bufferCnt = 0; +} + +void Logic_::wait_for_worker(int installCnt, int uninstallCnt, int bufferCnt) +{ + LogDebug("Wait for: " << installCnt << " " << uninstallCnt << " " << bufferCnt); + std::unique_lock<std::mutex> lock(_m_mutex_wait_cv); + bool timeout = !_m_wait_for_process.wait_for( + lock, + std::chrono::seconds(10), + [this, installCnt, uninstallCnt, bufferCnt]{ + return m_installCnt == installCnt && + m_uninstallCnt == uninstallCnt && + m_bufferCnt == bufferCnt; + } + ); + _m_mutex_wait_cv.unlock(); + BOOST_REQUIRE(!timeout); + reset_cnt(); +} + +const std::list<app_t>& Logic_::get_buffer_() +{ + return m_buffer; +} + +} // CCHECKER diff --git a/tests/logic_.h b/tests/logic_.h new file mode 100644 index 0000000..29f0e37 --- /dev/null +++ b/tests/logic_.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file logic_.h + * @author Janusz Kozerski (j.kozerski@samsung.com) + * @version 1.0 + * @brief This file is the tesst implementation of Logic class + */ + +#ifndef CCHECKER_LOGIC__H +#define CCHECKER_LOGIC__H + +/* + * This Class makes all methods from Logic Class public - for testing purpose. + * Some of methods are stubbed, and some of them just calls corresponding methods from Logic Class. + */ + +#include <cchecker/logic.h> + +namespace CCHECKER { + +class Logic_ : public Logic { + public: + Logic_(void); + virtual ~Logic_(void); + + // For tests only + void connman_callback_manual_(bool state); + void pkgmgr_install_manual_(const app_t &app); + void pkgmgr_uninstall_manual_(const app_t &app); + const std::list<app_t>& get_buffer_(); + + void reset_cnt(); + void wait_for_worker(int installCnt, int uninstallCnt, int bufferCnt); + + private: + int m_installCnt; + int m_uninstallCnt; + int m_bufferCnt; + + void process_event(const event_t &event); + void app_processed(); + std::condition_variable _m_wait_for_process; + std::mutex _m_mutex_wait_cv; +}; + +class LogicWrapper { +public: + LogicWrapper() {} + ~LogicWrapper() { m_logic.clean(); } + + error_t setup() { return m_logic.setup(); } + void clean() { m_logic.clean(); } + void connman_callback_manual_(bool state) { m_logic.connman_callback_manual_(state); } + void pkgmgr_install_manual_(const app_t &app) { m_logic.pkgmgr_install_manual_(app); } + void pkgmgr_uninstall_manual_(const app_t &app) { m_logic.pkgmgr_uninstall_manual_(app); } + const std::list<app_t>& get_buffer_() { return m_logic.get_buffer_(); } + + void wait_for_worker(int installCnt = 0, int uninstallCnt = 0, int bufferCnt = 0) { + m_logic.wait_for_worker(installCnt, uninstallCnt, bufferCnt); + } + +private: + Logic_ m_logic; +}; + +} // CCHECKER + +#endif //CCHECKER_LOGIC__H diff --git a/tests/test_logic.cpp b/tests/test_logic.cpp new file mode 100644 index 0000000..99871fe --- /dev/null +++ b/tests/test_logic.cpp @@ -0,0 +1,452 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file test_logic.cpp + * @author Janusz Kozerski (j.kozerski@samsung.com) + * @version 1.0 + * @brief Tests of Logic class + */ + +#define BOOST_TEST_MODULE CERT_CHECKER_TESTS +#include <boost/test/unit_test.hpp> +#include <string> +#include <unistd.h> + +#include <cchecker/log.h> + +#include <logic_.h> +#include <app_event_operators.h> + +using namespace CCHECKER; + +namespace { + +std::string log_apps(std::list<app_t> &apps, std::list<app_t> buff) +{ + std::string ret = "\nApps:\n"; + + for (const auto &iter : apps) { + ret += iter.str() + "\n"; + } + + ret += "Buff:\n"; + for (const auto &iter : buff) { + ret+= iter.str() + "\n"; + } + + return ret; +} + +} //anonymus + +BOOST_FIXTURE_TEST_SUITE(LOGIC_TEST, LogicWrapper) + + +BOOST_AUTO_TEST_CASE(logic_setup) { + + BOOST_REQUIRE(setup() == NO_ERROR); + + // double setup + BOOST_REQUIRE(setup() == INTERNAL_ERROR); + + // double setup + BOOST_REQUIRE(setup() == INTERNAL_ERROR); +} + +BOOST_AUTO_TEST_CASE(logic_workflow_mixed) { + + BOOST_REQUIRE(setup() == NO_ERROR); + + wait_for_worker(); + + // turn off the network + connman_callback_manual_(false); + + // add applications: + app_t app1("app_1", "pkg_1", 5001, {}); + pkgmgr_install_manual_(app1); + + app_t app2("app_2", "pkg_1", 5001, {}); + pkgmgr_install_manual_(app2); + + app_t app3("app_2", "pkg_2", 5001, {}); + pkgmgr_install_manual_(app3); + + // remove app 2 + pkgmgr_uninstall_manual_(app2); + + wait_for_worker(3, 1); + + std::list<app_t> buff = get_buffer_(); + std::list<app_t> apps = {app1, app2, app3}; + BOOST_REQUIRE(buff != apps); + + apps = {app1, app3}; + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); + + // Add other apps + pkgmgr_install_manual_(app2); + + // install the same app again + // it should never happen in real workflow + pkgmgr_install_manual_(app3); + + app_t app4("app_4", "pkg_4", 5002, {}); + pkgmgr_install_manual_(app4); + + wait_for_worker(3); + + buff = get_buffer_(); + BOOST_REQUIRE(buff != apps); + + apps = {app1, app3, app2, app4}; + + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); + + // turn on the Internet - buffer should be processed + connman_callback_manual_(true); + + wait_for_worker(0, 0, 4); + buff = get_buffer_(); + BOOST_CHECK(buff.empty()); +} + +BOOST_AUTO_TEST_CASE(logic_workflow_mixed_2) { + + BOOST_REQUIRE(setup() == NO_ERROR); + + wait_for_worker(); + + // turn off the network + connman_callback_manual_(true); + + // add applications: + app_t app1("app_1", "pkg_1", 5001, {}); + pkgmgr_install_manual_(app1); + + app_t app2("app_2", "pkg_2", 5002, {{"OCSP_CERT_ERROR"}}); + pkgmgr_install_manual_(app2); + + app_t app3("app_3", "pkg_3", 5003, {{"OCSP_CHECK_AGAIN"}}); + pkgmgr_install_manual_(app3); + + app_t app4("app_4", "pkg_4", 5004, {{"OCSP_APP_REVOKED"}}); // popup will succeed + pkgmgr_install_manual_(app4); + + app_t app5("app_5", "pkg_5", 100, {{"OCSP_APP_REVOKED"}}); // popup will fail + pkgmgr_install_manual_(app5); + + wait_for_worker(5, 0, 5); + std::list<app_t> buff = get_buffer_(); +#if POPUP + std::list<app_t> apps = {app3, app5}; +#else + std::list<app_t> apps = {app3}; // only if popup is disabled +#endif + + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); +} + +BOOST_AUTO_TEST_CASE(logic_workflow_mixed_3) { + + BOOST_REQUIRE(setup() == NO_ERROR); + + wait_for_worker(); + + // turn off the network + connman_callback_manual_(false); + + // add applications: + app_t app1("app_1", "pkg_1", 5001, {{"OCSP_CHECK_AGAIN"}}); + pkgmgr_install_manual_(app1); + + app_t app2("app_2", "pkg_2", 5002, {{"OCSP_CERT_ERROR"}}); + pkgmgr_install_manual_(app2); + + app_t app3("app_3", "pkg_3", 100, {{"OCSP_APP_REVOKED"}}); // popup will fail + pkgmgr_install_manual_(app3); + + app_t app4("app_4", "pkg_4", 5004, {{"OCSP_APP_REVOKED"}}); // popup will succeed + pkgmgr_install_manual_(app4); + + app_t app5("app_5", "pkg_5", 5005, {{"OCSP_CERT_ERROR"}}); + pkgmgr_install_manual_(app5); + + app_t app6("app_6", "pkg_6", 101, {{"OCSP_APP_REVOKED"}}); // popup will fail + pkgmgr_install_manual_(app6); + + wait_for_worker(6); + + std::list<app_t> buff = get_buffer_(); + std::list<app_t> apps = {app1, app2, app3, app4, app5, app6}; + + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); + + connman_callback_manual_(true); + wait_for_worker(0, 0, 6); + buff = get_buffer_(); +#if POPUP + apps = {app1, app3, app6}; +#else + apps = {app1}; // only if popup is disabled +#endif + + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); +} + +BOOST_AUTO_TEST_CASE(logic_workflow_mixed_4) { + + BOOST_REQUIRE(setup() == NO_ERROR); + + wait_for_worker(); + + // turn off the network + connman_callback_manual_(false); + + // add applications: + app_t app1("app_1", "pkg_1", 5001, {}); + pkgmgr_install_manual_(app1); + + wait_for_worker(1); + + std::list<app_t> apps = {app1}; + std::list<app_t> buff = get_buffer_(); + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); + + app_t app2("app_2", "pkg_2", 5002, {{"OCSP_CERT_ERROR"}}); + pkgmgr_install_manual_(app2); + + wait_for_worker(1); + + apps = {app1, app2}; + buff = get_buffer_(); + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); + + app_t app3("app_3", "pkg_3", 5003, {{"OCSP_CHECK_AGAIN"}}); + pkgmgr_install_manual_(app3); + + wait_for_worker(1); + + apps = {app1, app2, app3}; + buff = get_buffer_(); + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); + + app_t app4("app_4", "pkg_4", 5004, {{"OCSP_APP_REVOKED"}}); // popup will succeed + pkgmgr_install_manual_(app4); + + wait_for_worker(1); + + apps = {app1, app2, app3, app4}; + buff = get_buffer_(); + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); + + app_t app5("app_5", "pkg_5", 100, {{"OCSP_APP_REVOKED"}}); // popup will fail + pkgmgr_install_manual_(app5); + + wait_for_worker(1); + + apps = {app1, app2, app3, app4, app5}; + buff = get_buffer_(); + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); +} + +// OCSP_CHECK_AGAIN - apps should stay in buffer +BOOST_AUTO_TEST_CASE(logic_workflow_OCSP_CHECK_AGAIN) { + + BOOST_REQUIRE(setup() == NO_ERROR); + + wait_for_worker(); + + // turn off the network + connman_callback_manual_(false); + + // add applications: + app_t app1("app_1", "pkg_1", 5001, {{"OCSP_CHECK_AGAIN"}}); + pkgmgr_install_manual_(app1); + + app_t app2("app_2", "pkg_2", 5002, {{"OCSP_CHECK_AGAIN"}}); + pkgmgr_install_manual_(app2); + + connman_callback_manual_(true); + + app_t app3("app_3", "pkg_3", 100, {{"OCSP_CHECK_AGAIN"}}); + pkgmgr_install_manual_(app3); + + app_t app4("app_4", "pkg_4", 5004, {{"OCSP_CHECK_AGAIN"}}); + pkgmgr_install_manual_(app4); + + wait_for_worker(4, 0, 4); + + std::list<app_t> buff = get_buffer_(); + std::list<app_t> apps = {app1, app2, app3, app4}; + + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); + + connman_callback_manual_(false); + + wait_for_worker(0, 0, 0); + + buff = get_buffer_(); + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); + + connman_callback_manual_(true); + + wait_for_worker(0, 0, 4); + + buff = get_buffer_(); + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); +} + +// OCSP_CERT_ERROR - apps should be removed from buffer +// OCSP_APP_OK should have the same effect +BOOST_AUTO_TEST_CASE(logic_workflow_OCSP_CERT_ERROR) { + + BOOST_REQUIRE(setup() == NO_ERROR); + + wait_for_worker(); + + // turn off the network + connman_callback_manual_(false); + + // add applications: + app_t app1("app_1", "pkg_1", 5001, {{"OCSP_CERT_ERROR"}}); + pkgmgr_install_manual_(app1); + + app_t app2("app_2", "pkg_2", 5002, {{"OCSP_CERT_ERROR"}}); + pkgmgr_install_manual_(app2); + + connman_callback_manual_(true); + + app_t app3("app_3", "pkg_3", 100, {{"OCSP_CERT_ERROR"}}); + pkgmgr_install_manual_(app3); + + app_t app4("app_4", "pkg_4", 5004, {{"OCSP_CERT_ERROR"}}); + pkgmgr_install_manual_(app4); + + wait_for_worker(4, 0, 4); + std::list<app_t> buff = get_buffer_(); + + BOOST_REQUIRE(buff.empty()); + + connman_callback_manual_(true); + + wait_for_worker(); + + buff = get_buffer_(); + BOOST_REQUIRE(buff.empty()); + + connman_callback_manual_(true); + + wait_for_worker(); + + buff = get_buffer_(); + BOOST_REQUIRE(buff.empty()); +} + +// OCSP_APP_REVOKED - popup OK - apps should be removed from buffer +BOOST_AUTO_TEST_CASE(logic_workflow_OCSP_APP_REVOKED) { + + BOOST_REQUIRE(setup() == NO_ERROR); + + wait_for_worker(); + + // turn off the network + connman_callback_manual_(false); + + // add applications: + app_t app1("app_1", "pkg_1", 5001, {{"OCSP_APP_REVOKED"}}); + pkgmgr_install_manual_(app1); + + app_t app2("app_2", "pkg_2", 5002, {{"OCSP_APP_REVOKED"}}); + pkgmgr_install_manual_(app2); + + connman_callback_manual_(true); + + app_t app3("app_3", "pkg_3", 5003, {{"OCSP_APP_REVOKED"}}); + pkgmgr_install_manual_(app3); + + app_t app4("app_4", "pkg_4", 5004, {{"OCSP_APP_REVOKED"}}); + pkgmgr_install_manual_(app4); + + wait_for_worker(4, 0, 4); + + std::list<app_t> buff = get_buffer_(); + + BOOST_REQUIRE(buff.empty()); + + connman_callback_manual_(true); + + wait_for_worker(); + + buff = get_buffer_(); + BOOST_REQUIRE(buff.empty()); + + connman_callback_manual_(true); + + wait_for_worker(); + + buff = get_buffer_(); + BOOST_REQUIRE(buff.empty()); +} + +// OCSP_APP_REVOKED - popup fail - apps should stay in buffer +BOOST_AUTO_TEST_CASE(logic_workflow_OCSP_APP_REVOKED_2) { + + BOOST_REQUIRE(setup() == NO_ERROR); + + wait_for_worker(); + + // turn off the network + connman_callback_manual_(false); + + // add applications: + app_t app1("app_1", "pkg_1", 1001, {{"OCSP_APP_REVOKED"}}); + pkgmgr_install_manual_(app1); + + app_t app2("app_2", "pkg_2", 1002, {{"OCSP_APP_REVOKED"}}); + pkgmgr_install_manual_(app2); + + connman_callback_manual_(true); + + app_t app3("app_3", "pkg_3", 1003, {{"OCSP_APP_REVOKED"}}); + pkgmgr_install_manual_(app3); + + app_t app4("app_4", "pkg_4", 1004, {{"OCSP_APP_REVOKED"}}); + pkgmgr_install_manual_(app4); + + wait_for_worker(4, 0, 4); + + std::list<app_t> buff = get_buffer_(); + std::list<app_t> apps = {app1, app2, app3, app4}; + + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); + + connman_callback_manual_(true); + + wait_for_worker(); + + buff = get_buffer_(); + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); + + connman_callback_manual_(true); + + wait_for_worker(); + + buff = get_buffer_(); + BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); +} + +BOOST_AUTO_TEST_SUITE_END() |