summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>2015-08-27 10:44:16 (GMT)
committerJanusz Kozerski <j.kozerski@samsung.com>2015-09-08 12:12:36 (GMT)
commit8fc0b8fc2a814035dc9cf8c7e211dc3a8f74d11b (patch)
tree6f86a12ee0423d9b83eb5ca5f55bd20cb8dee129
parentae4a130374e96d383e09571f2e098ef237e28418 (diff)
downloadcert-checker-8fc0b8fc2a814035dc9cf8c7e211dc3a8f74d11b.zip
cert-checker-8fc0b8fc2a814035dc9cf8c7e211dc3a8f74d11b.tar.gz
cert-checker-8fc0b8fc2a814035dc9cf8c7e211dc3a8f74d11b.tar.bz2
Fixed synchronisation issuesrefs/changes/62/46962/4
[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.h11
-rw-r--r--src/logic.cpp130
-rw-r--r--tests/logic_.cpp127
-rw-r--r--tests/logic_.h82
-rw-r--r--tests/test_logic.cpp452
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()