diff options
-rw-r--r-- | db/cert-checker.sql | 14 | ||||
-rw-r--r-- | db/cert-checker.xml | 98 | ||||
-rw-r--r-- | src/app.cpp | 24 | ||||
-rw-r--r-- | src/certs.cpp | 9 | ||||
-rw-r--r-- | src/db/sql_query.cpp | 124 | ||||
-rw-r--r-- | src/include/cchecker/app.h | 18 | ||||
-rw-r--r-- | src/include/cchecker/sql_query.h | 1 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/app_event_operators.cpp | 86 | ||||
-rw-r--r-- | tests/app_event_operators.h | 41 | ||||
-rw-r--r-- | tests/test_app.cpp | 159 | ||||
-rw-r--r-- | tests/test_db.cpp | 98 | ||||
-rw-r--r-- | tests/test_queue.cpp | 50 |
13 files changed, 575 insertions, 149 deletions
diff --git a/db/cert-checker.sql b/db/cert-checker.sql index 0103a49..2503e7c 100644 --- a/db/cert-checker.sql +++ b/db/cert-checker.sql @@ -21,13 +21,21 @@ CREATE TABLE IF NOT EXISTS ocsp_urls ( date INTEGER NOT NULL ); +-- Table 'chains_to_check' +CREATE TABLE IF NOT EXISTS chains_to_check ( + chain_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + check_id INTEGER NOT NULL, + + FOREIGN KEY (check_id) REFERENCES to_check(check_id) ON DELETE CASCADE +); + -- Table 'certs_to_check' CREATE TABLE IF NOT EXISTS certs_to_check ( - cert_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - check_id INTEGER NOT NULL, + chain_id INTEGER NOT NULL, certificate TEXT NOT NULL, - FOREIGN KEY (check_id) REFERENCES to_check(check_id) ON DELETE CASCADE + PRIMARY KEY (chain_id, certificate), + FOREIGN KEY (chain_id) REFERENCES chains_to_check(chain_id) ON DELETE CASCADE ); COMMIT TRANSACTION; diff --git a/db/cert-checker.xml b/db/cert-checker.xml index c0221fc..e72b044 100644 --- a/db/cert-checker.xml +++ b/db/cert-checker.xml @@ -2,41 +2,41 @@ <!-- SQL XML created by WWW SQL Designer, http://code.google.com/p/wwwsqldesigner/ --> <sql> <datatypes db="mysql"> - <group label="Numeric" color="rgb(238,238,170)"> - <type label="TINYINT" length="0" sql="TINYINT" quote=""/> - <type label="SMALLINT" length="0" sql="SMALLINT" quote=""/> - <type label="MEDIUMINT" length="0" sql="MEDIUMINT" quote=""/> - <type label="INT" length="0" sql="INT" quote=""/> - <type label="Integer" length="0" sql="INTEGER" quote=""/> - <type label="BIGINT" length="0" sql="BIGINT" quote=""/> - <type label="Decimal" length="1" sql="DECIMAL" re="DEC" quote=""/> - <type label="Single precision" length="0" sql="FLOAT" quote=""/> - <type label="Double precision" length="0" sql="DOUBLE" re="DOUBLE" quote=""/> - </group> + <group label="Numeric" color="rgb(238,238,170)"> + <type label="TINYINT" length="0" sql="TINYINT" quote=""/> + <type label="SMALLINT" length="0" sql="SMALLINT" quote=""/> + <type label="MEDIUMINT" length="0" sql="MEDIUMINT" quote=""/> + <type label="INT" length="0" sql="INT" quote=""/> + <type label="Integer" length="0" sql="INTEGER" quote=""/> + <type label="BIGINT" length="0" sql="BIGINT" quote=""/> + <type label="Decimal" length="1" sql="DECIMAL" re="DEC" quote=""/> + <type label="Single precision" length="0" sql="FLOAT" quote=""/> + <type label="Double precision" length="0" sql="DOUBLE" re="DOUBLE" quote=""/> + </group> - <group label="Character" color="rgb(255,200,200)"> - <type label="Char" length="1" sql="CHAR" quote="'"/> - <type label="Varchar" length="1" sql="VARCHAR" quote="'"/> - <type label="Text" length="0" sql="MEDIUMTEXT" re="TEXT" quote="'"/> - <type label="Binary" length="1" sql="BINARY" quote="'"/> - <type label="Varbinary" length="1" sql="VARBINARY" quote="'"/> - <type label="BLOB" length="0" sql="BLOB" re="BLOB" quote="'"/> - </group> + <group label="Character" color="rgb(255,200,200)"> + <type label="Char" length="1" sql="CHAR" quote="'"/> + <type label="Varchar" length="1" sql="VARCHAR" quote="'"/> + <type label="Text" length="0" sql="MEDIUMTEXT" re="TEXT" quote="'"/> + <type label="Binary" length="1" sql="BINARY" quote="'"/> + <type label="Varbinary" length="1" sql="VARBINARY" quote="'"/> + <type label="BLOB" length="0" sql="BLOB" re="BLOB" quote="'"/> + </group> - <group label="Date & Time" color="rgb(200,255,200)"> - <type label="Date" length="0" sql="DATE" quote="'"/> - <type label="Time" length="0" sql="TIME" quote="'"/> - <type label="Datetime" length="0" sql="DATETIME" quote="'"/> - <type label="Year" length="0" sql="YEAR" quote=""/> - <type label="Timestamp" length="0" sql="TIMESTAMP" quote="'"/> - </group> - - <group label="Miscellaneous" color="rgb(200,200,255)"> - <type label="ENUM" length="1" sql="ENUM" quote=""/> - <type label="SET" length="1" sql="SET" quote=""/> - <type label="Bit" length="0" sql="bit" quote=""/> - </group> -</datatypes><table x="760" y="211" name="to_check"> + <group label="Date & Time" color="rgb(200,255,200)"> + <type label="Date" length="0" sql="DATE" quote="'"/> + <type label="Time" length="0" sql="TIME" quote="'"/> + <type label="Datetime" length="0" sql="DATETIME" quote="'"/> + <type label="Year" length="0" sql="YEAR" quote=""/> + <type label="Timestamp" length="0" sql="TIMESTAMP" quote="'"/> + </group> + + <group label="Miscellaneous" color="rgb(200,200,255)"> + <type label="ENUM" length="1" sql="ENUM" quote=""/> + <type label="SET" length="1" sql="SET" quote=""/> + <type label="Bit" length="0" sql="bit" quote=""/> + </group> +</datatypes><table x="730" y="211" name="to_check"> <row name="check_id" null="0" autoincrement="1"> <datatype>INTEGER</datatype> </row> @@ -51,15 +51,12 @@ </row> <row name="verified" null="0" autoincrement="0"> <datatype>INTEGER</datatype> -<default>2</default></row> +<default>NULL</default></row> <key type="PRIMARY" name=""> <part>check_id</part> </key> </table> -<table x="1132" y="211" name="ocsp_urls"> -<row name="url_id" null="0" autoincrement="1"> -<datatype>INTEGER</datatype> -</row> +<table x="1222" y="211" name="ocsp_urls"> <row name="issuer" null="0" autoincrement="0"> <datatype>MEDIUMTEXT</datatype> </row> @@ -70,21 +67,34 @@ <datatype>INT</datatype> </row> <key type="PRIMARY" name=""> -<part>url_id</part> +<part>issuer</part> +<part>url</part> </key> </table> -<table x="928" y="211" name="certs_to_check"> +<table x="897" y="211" name="certs_to_check"> <row name="check_id" null="0" autoincrement="0"> <datatype>INTEGER</datatype> <relation table="to_check" row="check_id" /> </row> -<row name="certificate" null="0" autoincrement="0"> -<datatype>MEDIUMTEXT</datatype> +<row name="chain_id" null="0" autoincrement="0"> +<datatype>INTEGER</datatype> +<default>NULL</default><relation table="certs" row="chain_id" /> </row> <key type="PRIMARY" name=""> <part>check_id</part> -<part>certificate</part> +<part>chain_id</part> +</key> +</table> +<table x="1097" y="235" name="certs"> +<row name="chain_id" null="0" autoincrement="0"> +<datatype>INTEGER</datatype> +<default>NULL</default></row> +<row name="certificates" null="0" autoincrement="0"> +<datatype>MEDIUMTEXT</datatype> +<default>'NULL'</default></row> +<key type="PRIMARY" name=""> +<part>certificates</part> +<part>chain_id</part> </key> </table> </sql> - diff --git a/src/app.cpp b/src/app.cpp index 58a7883..08b79a5 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -22,16 +22,14 @@ #include <sstream> #include <string> -#include <vector> #include <sys/types.h> #include <cchecker/app.h> +#include <cchecker/log.h> namespace CCHECKER { app_t::app_t(void): - check_id(-1), // -1 as invalid check_id - assume that in database - // all check_ids will be positive uid((uid_t)-1), // (uid_t)-1 (0xFF) is defined to be invalid uid. According // to chown manual page, you cannot change file group of owner // to (uid_t)-1, so we'll use it as initial, invalid value. @@ -41,19 +39,17 @@ app_t::app_t(void): app_t::app_t(const std::string &app_id, const std::string &pkg_id, uid_t uid, - const std::vector<std::string> &certificates): - check_id(-1), + const signatures_t &signatures): app_id(app_id), pkg_id(pkg_id), uid(uid), - certificates(certificates), + signatures(signatures), verified(verified_t::UNKNOWN) {} std::ostream & operator<< (std::ostream &out, const app_t &app) { - out << "app: " << app.app_id << ", pkg: " << app.pkg_id << ", uid: " << app.uid << - ", check_id: " << app.check_id; + out << "app: " << app.app_id << ", pkg: " << app.pkg_id << ", uid: " << app.uid; return out; } @@ -64,4 +60,16 @@ std::string app_t::str() const return ss.str(); } +std::string app_t::str_certs(void) const +{ + std::stringstream ss; + + for (const auto &iter : signatures) { + for (const auto iter_cert : iter) { + ss << "\"" << iter_cert << "\", "; + } + } + return ss.str(); +} + } //CCHECKER diff --git a/src/certs.cpp b/src/certs.cpp index 4a69fde..5b69ba0 100644 --- a/src/certs.cpp +++ b/src/certs.cpp @@ -119,7 +119,8 @@ void Certs::find_app_signatures (app_t &app, const std::string &app_path, ocsp_u LogDebug("Number of signature files: " << signature_files.size()); LogDebug("Searching for certificates"); - for (auto iter = signature_files.begin(); iter != signature_files.end(); iter++){ + for (auto iter = signature_files.begin(); iter != signature_files.end(); iter++) { + chain_t chain; LogDebug("Checking signature"); ValidationCore::SignatureData data(app_path + std::string("/") + (*iter).getFileName(), (*iter).getFileNumber()); @@ -131,7 +132,7 @@ void Certs::find_app_signatures (app_t &app, const std::string &app_path, ocsp_u ValidationCore::CertificateList certs = data.getCertList(); for (auto cert_iter = certs.begin(); cert_iter != certs.end(); cert_iter++ ){ std::string app_cert = (*cert_iter)->getBase64(); - app.certificates.push_back(app_cert); + chain.push_back(app_cert); LogDebug("Certificate: " << app_cert << " has been added"); // check OCSP URL @@ -150,6 +151,10 @@ void Certs::find_app_signatures (app_t &app, const std::string &app_path, ocsp_u // Needs to catch parser exceptions LogError("Error occured in ParserSchema: " << exception.DumpToString()); } + if (!chain.empty()) { + app.signatures.push_back(chain); + LogDebug("Certificates chain added to the app"); + } } } diff --git a/src/db/sql_query.cpp b/src/db/sql_query.cpp index 0968717..27eb52e 100644 --- a/src/db/sql_query.cpp +++ b/src/db/sql_query.cpp @@ -36,6 +36,12 @@ namespace { // 107 - check_id // 108 - certificate // 109 - verified + // 110 - chain_id + + // setup + const char *DB_CMD_SETUP = "VACUUM; PRAGMA foregin_keys=ON;"; + + const char *DB_CMD_GET_LAST_INSERTED_ROW = "SELECT last_insert_rowid();"; // urls const char *DB_CMD_GET_URL = @@ -54,17 +60,24 @@ namespace { const char *DB_CMD_GET_CHECK_ID = "SELECT check_id FROM to_check WHERE app_id=?104 AND pkg_id=?105 AND uid=?106;"; + const char *DB_CMD_ADD_CHAIN = + "INSERT INTO chains_to_check(check_id) VALUES(?107);"; + const char *DB_CMD_ADD_CERT = - "INSERT INTO certs_to_check(check_id, certificate) VALUES(?107, ?108);"; + "INSERT INTO certs_to_check(chain_id, certificate) VALUES(?110, ?108);"; + + const char *DB_CMD_GET_CHAINS = + "SELECT chain_id FROM chains_to_check INNER JOIN to_check ON chains_to_check.check_id=to_check.check_id \ +WHERE to_check.app_id=?104 AND to_check.pkg_id=?105 AND to_check.uid=?106;"; const char *DB_CMD_REMOVE_APP = "DELETE FROM to_check WHERE app_id=?104 AND pkg_id=?105 AND uid=?106;"; const char *DB_CMD_GET_APPS = - "SELECT * FROM to_check"; + "SELECT app_id, pkg_id, uid, verified FROM to_check"; const char *DB_CMD_GET_CERTS = - "SELECT certificate FROM certs_to_check WHERE check_id=?107;"; + "SELECT certificate FROM certs_to_check WHERE chain_id=?110;"; const char *DB_CMD_SET_APP_AS_VERIFIED = "UPDATE to_check SET verified=?109 WHERE check_id=?107"; @@ -91,7 +104,7 @@ bool SqlQuery::connect(const std::string& path) Try { m_connection = new SqlConnection(path, SqlConnection::Flag::None, SqlConnection::Flag::Option::CRW); - m_connection->ExecCommand("VACUUM;"); + m_connection->ExecCommand(DB_CMD_SETUP); return true; } Catch(std::bad_alloc) { LogError("Couldn't allocate SqlConnection"); @@ -185,6 +198,25 @@ bool SqlQuery::get_check_id(const app_t &app, int32_t &check_id) return false; } +bool SqlQuery::add_chain_id(const int32_t check_id, int32_t &chain_id) +{ + // Add new chain for an app + SqlConnection::DataCommandAutoPtr addChainCommand = + m_connection->PrepareDataCommand(DB_CMD_ADD_CHAIN); + addChainCommand->BindInt32(107, check_id); + addChainCommand->Step(); + + // get chain_id + SqlConnection::DataCommandAutoPtr getLastInserted = + m_connection->PrepareDataCommand(DB_CMD_GET_LAST_INSERTED_ROW); + if(getLastInserted->Step()) { + chain_id = getLastInserted->GetColumnInt32(0); + LogDebug("Found chain_id: " << chain_id << ", for check_id " << check_id); + return true; + } + return false; +} + bool SqlQuery::add_app_to_check_list(const app_t &app) { //Check if app exists in DB @@ -206,23 +238,35 @@ bool SqlQuery::add_app_to_check_list(const app_t &app) // Get check_id int32_t check_id; - if (get_check_id(app, check_id)) { - // If get check_id succeed we can add certificates to database - for (const auto &iter : app.certificates) { - SqlConnection::DataCommandAutoPtr addCertCommand = - m_connection->PrepareDataCommand(DB_CMD_ADD_CERT); - addCertCommand->BindInt32(107, check_id); - addCertCommand->BindString(108, iter.c_str()); - addCertCommand->Step(); - LogDebug("Certificate for app " << app.app_id << "added"); - } - m_connection->CommitTransaction(); - return true; - } else { // If get check_id failed return false; + if (!get_check_id(app, check_id)) { // If get check_id failed return false; LogDebug("Failed while addind app "<< app.app_id << " to to_check table."); m_connection->RollbackTransaction(); return false; } + + // If get check_id succeed we can add chain to database + int32_t chain_id; + for (const auto &iter : app.signatures) { + // Add chain + if (add_chain_id(check_id, chain_id)) { + // add certificates from chain + for (const auto &iter_cert : iter) { + SqlConnection::DataCommandAutoPtr addCertCommand = + m_connection->PrepareDataCommand(DB_CMD_ADD_CERT); + addCertCommand->BindInt32(110, chain_id); + addCertCommand->BindString(108, iter_cert.c_str()); + addCertCommand->Step(); + LogDebug("Certificate for app " << app.app_id << "added"); + } + } else { + LogDebug("Failed to add certificates chain"); + m_connection->RollbackTransaction(); + return false; + } + + } + m_connection->CommitTransaction(); + return true; } void SqlQuery::remove_app_from_check_list(const app_t &app) @@ -265,12 +309,11 @@ void SqlQuery::get_apps(std::list<app_t> &apps_buffer) while (getAppsCommand->Step()) { app_t app; - app.check_id = getAppsCommand->GetColumnInt32(0); - app.app_id = getAppsCommand->GetColumnString(1); - app.pkg_id = getAppsCommand->GetColumnString(2); - app.uid = getAppsCommand->GetColumnInt64(3); - app.verified = static_cast<app_t::verified_t>(getAppsCommand->GetColumnInt32(4)); - app.certificates = {}; + app.app_id = getAppsCommand->GetColumnString(0); + app.pkg_id = getAppsCommand->GetColumnString(1); + app.uid = getAppsCommand->GetColumnInt64(2); + app.verified = static_cast<app_t::verified_t>(getAppsCommand->GetColumnInt32(3)); + app.signatures = {}; LogDebug("App read from DB: app_id: " << app.str() << ", verified: " << static_cast<int32_t>(app.verified)); apps_buffer.push_back(app); } @@ -278,18 +321,37 @@ void SqlQuery::get_apps(std::list<app_t> &apps_buffer) void SqlQuery::get_app_list(std::list<app_t> &apps_buffer) { + m_connection->BeginTransaction(); get_apps(apps_buffer); - // Get certificates for apps - for (auto &iter : apps_buffer) { - SqlConnection::DataCommandAutoPtr getCertsCommand = - m_connection->PrepareDataCommand(DB_CMD_GET_CERTS); - getCertsCommand->BindInt32(107, iter.check_id); - - while (getCertsCommand->Step()) { - iter.certificates.push_back(getCertsCommand->GetColumnString(0)); + // Get chain for every application + for (auto &iter_app : apps_buffer) { + SqlConnection::DataCommandAutoPtr getChainsCommand = + m_connection->PrepareDataCommand(DB_CMD_GET_CHAINS); + getChainsCommand->BindString(104, iter_app.app_id.c_str()); + getChainsCommand->BindString(105, iter_app.pkg_id.c_str()); + getChainsCommand->BindInt32(106, iter_app.uid); + + // Get all certs from chain + while (getChainsCommand->Step()) { + chain_t chain; + int32_t chain_id; + chain_id = getChainsCommand->GetColumnInt32(0); + LogDebug("Found chain (" << chain_id << ") for " << iter_app.str()); + + SqlConnection::DataCommandAutoPtr getCertsCommand = + m_connection->PrepareDataCommand(DB_CMD_GET_CERTS); + getCertsCommand->BindInt32(110, chain_id); + + // Add found certs to chain + while (getCertsCommand->Step()) { + chain.push_back(getCertsCommand->GetColumnString(0)); + LogDebug("Found certificate (" << chain.size() << ") in chain no. " << chain_id); + } + iter_app.signatures.push_back(chain); } } + m_connection->CommitTransaction(); } } // DB diff --git a/src/include/cchecker/app.h b/src/include/cchecker/app.h index 3217bdb..46fd9b6 100644 --- a/src/include/cchecker/app.h +++ b/src/include/cchecker/app.h @@ -23,7 +23,6 @@ #define CCHECKER_APP_H #include <string> -#include <vector> #include <list> #include <sys/types.h> @@ -33,6 +32,9 @@ namespace CCHECKER { // Currently in signals from pkgmgr only information about pkg_id is included const char *const TEMP_APP_ID = "temp#app_id"; +typedef std::list<std::string> chain_t; +typedef std::list<chain_t> signatures_t; + struct app_t { enum class verified_t : int32_t { NO = 0, @@ -40,19 +42,19 @@ struct app_t { UNKNOWN = 2 }; - int32_t check_id; - std::string app_id; - std::string pkg_id; - uid_t uid; - std::vector<std::string> certificates; //TODO: add typedef - verified_t verified; + std::string app_id; + std::string pkg_id; + uid_t uid; + signatures_t signatures; + verified_t verified; app_t(void); app_t(const std::string &app_id, const std::string &pkg_id, uid_t uid, - const std::vector<std::string> &certificates); + const signatures_t &signatures); std::string str(void) const; + std::string str_certs(void) const; }; struct url_t { diff --git a/src/include/cchecker/sql_query.h b/src/include/cchecker/sql_query.h index 5a22740..e4cc582 100644 --- a/src/include/cchecker/sql_query.h +++ b/src/include/cchecker/sql_query.h @@ -69,6 +69,7 @@ class SqlQuery { void get_apps(std::list<app_t> &apps_buffer); bool check_if_app_exists(const app_t &app); bool get_check_id(const app_t &app, int32_t &check_id); + bool add_chain_id(const int32_t check_id, int32_t &chain_id); int verified_enum_to_int(const app_t::verified_t &verified); app_t::verified_t verified_int_to_enum(const int &verified); }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a1c88db..bff89b6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -23,6 +23,8 @@ SET(CERT_CHECKER_TESTS_SOURCES ${CERT_CHECKER_TESTS_SRC_PATH}/main.cpp ${CERT_CHECKER_TESTS_SRC_PATH}/dbfixture.cpp ${CERT_CHECKER_TESTS_SRC_PATH}/colour_log_formatter.cpp + ${CERT_CHECKER_TESTS_SRC_PATH}/app_event_operators.cpp + ${CERT_CHECKER_TESTS_SRC_PATH}/test_app.cpp ${CERT_CHECKER_TESTS_SRC_PATH}/test_db.cpp ${CERT_CHECKER_TESTS_SRC_PATH}/test_queue.cpp ${CERT_CHECKER_TESTS_SRC_PATH}/queue_test_thread.cpp diff --git a/tests/app_event_operators.cpp b/tests/app_event_operators.cpp new file mode 100644 index 0000000..1d26d60 --- /dev/null +++ b/tests/app_event_operators.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2011 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 app_test_class.cpp + * @author Janusz Kozerski (j.kozerski@samsung.com) + * @version 1.0 + * @brief Implementation of app_test class (from app_t) + */ + +#include <cchecker/log.h> +#include <app_event_operators.h> + +//using namespace CCHECKER; + +namespace CCHECKER { + +void sort(app_t &app) +{ + for (auto &iter : app.signatures) { + iter.sort(); + } + app.signatures.sort(); +} + +// Needed for sort() +bool operator < (const app_t &app1, const app_t &app2) +{ + if (app1.app_id != app2.app_id) + return app1.app_id < app2.app_id; + if (app1.pkg_id != app2.pkg_id) + return app1.pkg_id < app2.pkg_id; + if (app1.uid != app2.uid) + return app1.uid < app2.uid; + + return app1.signatures < app2.signatures; +} + +bool operator ==(const app_t &app1, const app_t &app2) +{ + if (app1.app_id != app2.app_id || + app1.pkg_id != app2.pkg_id || + app1.uid != app2.uid || + app1.signatures.size() != app2.signatures.size() || + app1.verified != app2.verified) { + LogDebug("app_t compare error: " << app1.str() << " is different than: " << app2.str()); + return false; + } + + return app1.signatures == app2.signatures; +} + +bool operator !=(const app_t &app1, const app_t &app2) +{ + return !(app1 == app2); +} + +bool operator ==(const event_t &event1, const event_t &event2) +{ + if (event1.event_type != event2.event_type) + return false; + + if (event1.app != event2.app) + return false; + + return true; +} + +bool operator !=(const event_t &event1, const event_t &event2) +{ + return !(event1 == event2); +} + +} // CHCHECKER diff --git a/tests/app_event_operators.h b/tests/app_event_operators.h new file mode 100644 index 0000000..3e96d28 --- /dev/null +++ b/tests/app_event_operators.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011 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 app_test_class.h + * @author Janusz Kozerski (j.kozerski@samsung.com) + * @version 1.0 + * @brief Implementation of app_test class (from app_t) + */ + +#include <cchecker/app.h> +#include <cchecker/queue.h> + +#ifndef CCHECKER_APP_TEST_CLASS_H +#define CCHECKER_APP_TEST_CLASS_H + +namespace CCHECKER { + +void sort(app_t &app); +bool operator ==(const app_t &app1, const app_t &app2); +bool operator !=(const app_t &app1, const app_t &app2); +bool operator < (const app_t &app1, const app_t &app2); + +bool operator ==(const event_t &event1, const event_t &event2); +bool operator !=(const event_t &event1, const event_t &event2); + +} // CCHECKER + +#endif //CCHECKER_APP_TEST_CLASS_H diff --git a/tests/test_app.cpp b/tests/test_app.cpp new file mode 100644 index 0000000..20bf905 --- /dev/null +++ b/tests/test_app.cpp @@ -0,0 +1,159 @@ +/* + * 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_app.cpp + * @author Janusz Kozerski (j.kozerski@samsung.com) + * @version 1.0 + * @brief App structure tests + */ + +#include <boost/test/unit_test.hpp> +#include <string> + +#include <cchecker/log.h> +#include <app_event_operators.h> + +using namespace CCHECKER; + +BOOST_FIXTURE_TEST_SUITE(APP_TEST, app_t) + +BOOST_AUTO_TEST_CASE(App_positive) { + + app_t app1("app_1", "pkg_1", 5001, {{"aaaaaa"}}); + app_t app2("app_1", "pkg_1", 5001, {{"aaaaaa"}}); + + app_t app3("app_2", "pkg_1", 5002, {{"aaa", "bbbb"}}); + app_t app4("app_2", "pkg_1", 5002, {{"bbbb", "aaa"}}); + + chain_t chain411 = {"cert_4.1", "cert 4.2"}; + chain_t chain412 = {"cert 4.2", "cert_4.1"}; + chain_t chain421 = {"cert_4.2.1", "cert 4.2.2", "cert 4.2.3"}; + chain_t chain422 = {"cert 4.2.2", "cert 4.2.3", "cert_4.2.1"}; + chain_t chain423 = {"cert 4.2.3", "cert_4.2.1", "cert 4.2.2"}; + chain_t chain424 = {"cert_4.2.1", "cert 4.2.3", "cert 4.2.2"}; + chain_t chain425 = {"cert 4.2.3", "cert 4.2.2", "cert_4.2.1"}; + chain_t chain426 = {"cert 4.2.2", "cert_4.2.1", "cert 4.2.3"}; + chain_t chain43 = {"cert_4.3.1"}; + + app_t app5("app_3", "pkg_1", 5003, {chain411, chain421, chain43}); + app_t app6("app_3", "pkg_1", 5003, {chain411, chain422, chain43}); + app_t app7("app_3", "pkg_1", 5003, {chain411, chain423, chain43}); + app_t app8("app_3", "pkg_1", 5003, {chain411, chain424, chain43}); + app_t app9("app_3", "pkg_1", 5003, {chain411, chain425, chain43}); + app_t app10("app_3", "pkg_1", 5003, {chain411, chain426, chain43}); + app_t app11("app_3", "pkg_1", 5003, {chain412, chain421, chain43}); + app_t app12("app_3", "pkg_1", 5003, {chain412, chain422, chain43}); + app_t app13("app_3", "pkg_1", 5003, {chain412, chain423, chain43}); + app_t app14("app_3", "pkg_1", 5003, {chain412, chain424, chain43}); + app_t app15("app_3", "pkg_1", 5003, {chain412, chain425, chain43}); + app_t app16("app_3", "pkg_1", 5003, {chain412, chain426, chain43}); + + sort(app1); + sort(app2); + sort(app3); + sort(app4); + sort(app5); + sort(app6); + sort(app7); + sort(app8); + sort(app9); + sort(app10); + sort(app11); + sort(app12); + sort(app13); + sort(app14); + sort(app15); + sort(app16); + + BOOST_REQUIRE(app1 == app2); + + BOOST_REQUIRE(app3 == app4); + + BOOST_REQUIRE(app5 == app6); + BOOST_REQUIRE(app6 == app7); + BOOST_REQUIRE(app7 == app8); + BOOST_REQUIRE(app8 == app9); + BOOST_REQUIRE(app9 == app10); + BOOST_REQUIRE(app10 == app11); + BOOST_REQUIRE(app11 == app12); + BOOST_REQUIRE(app12 == app13); + BOOST_REQUIRE(app13 == app14); + BOOST_REQUIRE(app14 == app15); + BOOST_REQUIRE(app15 == app16); + BOOST_REQUIRE(app16 == app5); +} + +BOOST_AUTO_TEST_CASE(App_negative) { + + app_t app1("app_1", "pkg_1", 5001, {{"aaaaaa"}}); + app_t app2("app_2", "pkg_1", 5001, {{"aaaaaa"}}); + app_t app3("app_2", "pkg_2", 5001, {{"aaaaaa"}}); + app_t app4("app_2", "pkg_2", 5002, {{"aaaaaa"}}); + + chain_t chain411 = {"cert_4.1", "cert 4.2"}; + chain_t chain412 = {"cert_4.1"}; + + chain_t chain421 = {"cert_4.2.1", "cert 4.2.2", "cert 4.2.3"}; + chain_t chain422 = {"" "cert 4.2.3", "cert_4.2.1"}; + chain_t chain423 = {"cert", "cert_4.2.1", "cert 4.2.2"}; + chain_t chain424 = {"cert_4.2.1", " ", "cert 4.2.2"}; + chain_t chain425 = {"cert 4.2.3", "cert 4.2.2"}; + chain_t chain426 = {"cert 4.2", "cert_4.2", "cert 4.2"}; + + chain_t chain43 = {"cert_4.3.1"}; + + app_t app5("app_3", "pkg_1", 5003, {chain411, chain421, chain43}); + app_t app6("app_3", "pkg_1", 5003, {chain411, chain422, chain43}); + app_t app7("app_3", "pkg_1", 5003, {chain411, chain423, chain43}); + app_t app8("app_3", "pkg_1", 5003, {chain411, chain424, chain43}); + app_t app9("app_3", "pkg_1", 5003, {chain411, chain425, chain43}); + app_t app10("app_3", "pkg_1", 5003, {chain411, chain426, chain43}); + app_t app11("app_3", "pkg_1", 5003, {chain412, chain421, chain43}); + app_t app12("app_3", "pkg_1", 5003, {chain412, chain422, chain43}); + app_t app13("app_3", "pkg_1", 5003, {chain412, chain423, chain43}); + app_t app14("app_3", "pkg_1", 5003, {chain412, chain424, chain43}); + app_t app15("app_3", "pkg_1", 5003, {chain412, chain425, chain43}); + app_t app16("app_3", "pkg_1", 5003, {chain412, chain426, chain43}); + + app_t apps[12] = {app5, app6, app7, app8, app9, app10, app11, app12, app13, app14, app15, app16}; + + sort(app1); + sort(app2); + sort(app3); + sort(app4); + + for (int i=0; i<12; i++) { + sort(apps[i]); + } + + BOOST_REQUIRE(app1 != app2); + BOOST_REQUIRE(app1 != app3); + BOOST_REQUIRE(app1 != app4); + BOOST_REQUIRE(app2 != app3); + BOOST_REQUIRE(app2 != app4); + BOOST_REQUIRE(app3 != app4); + + for (int i=0; i<12; i++) { + for (int j=0; j<12; j++) { + if (i != j) + BOOST_REQUIRE(apps[i] != apps[j]); + else + BOOST_REQUIRE(apps[i] == apps[j]); + } + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_db.cpp b/tests/test_db.cpp index dd5a962..e9685a8 100644 --- a/tests/test_db.cpp +++ b/tests/test_db.cpp @@ -24,9 +24,9 @@ #include <boost/test/unit_test.hpp> #include <string> -#include <cchecker/app.h> #include <cchecker/log.h> #include <dbfixture.h> +#include <app_event_operators.h> BOOST_FIXTURE_TEST_SUITE(DB_TEST, DBFixture) @@ -96,15 +96,27 @@ BOOST_AUTO_TEST_CASE(DB_url) { BOOST_REQUIRE(url==url_org2); } -BOOST_AUTO_TEST_CASE(DB_app) { +BOOST_AUTO_TEST_CASE(DB_app_positive) { clear_database(); std::list<app_t> buffer; app_t app1("app_1", "pkg_1", 5001, {}); - app_t app2("app_2", "pkg 2", 5002, {"cert_2"}); - app_t app2r("app_2_remove", "pkg 2", 5002, {"cert_2"}); - app_t app3("app 3", "pkg 3", 5003, {"cert_3.1", "cert 3.2"}); - app_t app4("app 4", "pkg 4", 5004, {"cert_4.1", "cert 4.2", "cert 4.3"}); + + chain_t chain2 = {"cert2"}; + app_t app2("app_2", "pkg 2", 5002, {chain2}); + + chain_t chain2r = {"cert2r"}; + app_t app2r("app_2_remove", "pkg 2", 5002, {chain2, chain2r}); + + chain_t chain31 = {"cert_3.1", "cert 3.2"}; + chain_t chain32 = {"cert_3.1"}; + app_t app3("app 3", "pkg 3", 5003, {chain31, chain32}); + + chain_t chain41 = {"cert_4.1", "cert 4.2"}; + chain_t chain42 = {"cert_4.2.1", "cert 4.2.2", "cert 4.2.3"}; + chain_t chain43 = {"cert_4.3.1"}; + + app_t app4("app 4", "pkg 4", 5004, {chain41, chain42, chain43}); BOOST_REQUIRE(add_app_to_check_list(app1)==true); BOOST_REQUIRE(add_app_to_check_list(app2)==true); @@ -118,29 +130,65 @@ BOOST_AUTO_TEST_CASE(DB_app) { app2.verified = app_t::verified_t::NO; app3.verified = app_t::verified_t::YES; + sort(app1); + sort(app2); + sort(app3); + sort(app4); + std::list<app_t> buffer_ok = {app1, app2, app3, app4}; + + get_app_list(buffer); + + buffer.sort(); + buffer_ok.sort(); + BOOST_REQUIRE(buffer_ok == buffer); +} + +BOOST_AUTO_TEST_CASE(DB_app_negative) { + clear_database(); + + std::list<app_t> buffer; + app_t app1("app_1", "pkg_1", 5001, {}); + + chain_t chain2 = {"cert2"}; + app_t app2("app_2", "pkg 2", 5002, {chain2}); + + chain_t chain2r = {"cert2r"}; + app_t app2r("app_2_remove", "pkg 2", 5002, {chain2, chain2r}); + + chain_t chain31 = {"cert_3.1", "cert 3.2"}; + chain_t chain32 = {"cert_3.1"}; + app_t app3("app 3", "pkg 3", 5003, {chain31, chain32}); + + chain_t chain41 = {"cert_4.1", "cert 4.2"}; + chain_t chain42 = {"cert_4.2.1", "cert 4.2.2", "cert 4.2.3"}; + chain_t chain43 = {"cert_4.3.1"}; + + app_t app4("app 4", "pkg 4", 5004, {chain41, chain42, chain43}); + + BOOST_REQUIRE(add_app_to_check_list(app1)==true); + BOOST_REQUIRE(add_app_to_check_list(app2)==true); + BOOST_REQUIRE(add_app_to_check_list(app2r)==true); + // Skipp adding app3 to database + BOOST_REQUIRE(add_app_to_check_list(app4)==true); + + mark_as_verified(app2, app_t::verified_t::NO); + mark_as_verified(app3, app_t::verified_t::YES); + remove_app_from_check_list(app2r); + + app2.verified = app_t::verified_t::NO; + app3.verified = app_t::verified_t::YES; + sort(app1); + sort(app2); + sort(app3); + sort(app4); std::list<app_t> buffer_ok = {app1, app2, app3, app4}; get_app_list(buffer); - std::list<app_t>::iterator iter = buffer.begin(); - std::list<app_t>::iterator iter_ok = buffer_ok.begin(); - for (; iter!=buffer.end(); iter++) { - bool is_ok = false; - for (iter_ok = buffer_ok.begin(); iter_ok!=buffer_ok.end(); iter_ok++) { - if (iter->app_id == iter_ok->app_id && - iter->pkg_id == iter_ok->pkg_id && - iter->uid == iter_ok->uid && - iter->certificates == iter_ok->certificates && - iter->verified == iter_ok->verified) { - // check_id field is created by database and can be ignored - LogDebug(iter->str() << " has been found"); - is_ok = true; - buffer_ok.erase(iter_ok); - break; - } - } - BOOST_REQUIRE(is_ok == true); - } + // list has to be sorted before comparison. + buffer.sort(); + buffer_ok.sort(); + BOOST_REQUIRE(buffer_ok != buffer); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_queue.cpp b/tests/test_queue.cpp index 2fe7f3e..384d6e4 100644 --- a/tests/test_queue.cpp +++ b/tests/test_queue.cpp @@ -24,16 +24,28 @@ #include <string> #include <thread> -#include <cchecker/app.h> #include <cchecker/log.h> -#include <cchecker/queue.h> - #include <queue_test_thread.h> +#include <app_event_operators.h> using namespace CCHECKER; BOOST_FIXTURE_TEST_SUITE(QUEUE_TEST, Queue) +BOOST_AUTO_TEST_CASE(Queue_operators) { + app_t app1("app_id1", "pkg_id1", 1, {}); + app_t app2("app_id2", "pkg_id2", 2, {}); + app_t app3("app_id@", "###", 3, {}); + + event_t ev1(app1, event_t::event_type_t::APP_INSTALL); + event_t ev2(app1, event_t::event_type_t::APP_UNINSTALL); + + BOOST_REQUIRE(ev1 == ev1); + BOOST_REQUIRE(ev1 != ev2); + BOOST_REQUIRE(ev2 != ev1); + BOOST_REQUIRE(ev2 == ev2); +} + BOOST_AUTO_TEST_CASE(Queue) { app_t app1("app_id1", "pkg_id1", 1, {}); @@ -55,12 +67,8 @@ BOOST_AUTO_TEST_CASE(Queue) { BOOST_REQUIRE(empty() == false); BOOST_REQUIRE(pop_event(ev) == true); - BOOST_REQUIRE(ev1.app.app_id == ev.app.app_id); - BOOST_REQUIRE(ev1.app.pkg_id == ev.app.pkg_id); - BOOST_REQUIRE(ev1.app.uid == ev.app.uid); - // Certs and verified flag aren't used in queue, but can be tested - BOOST_REQUIRE(ev1.app.certificates == ev.app.certificates); - BOOST_REQUIRE(ev1.app.verified == ev.app.verified); + BOOST_REQUIRE(ev1 == ev); + BOOST_REQUIRE(empty() == true); push_event(ev2); @@ -68,21 +76,11 @@ BOOST_AUTO_TEST_CASE(Queue) { BOOST_REQUIRE(empty() == false); BOOST_REQUIRE(pop_event(ev) == true); - BOOST_REQUIRE(ev2.app.app_id == ev.app.app_id); - BOOST_REQUIRE(ev2.app.pkg_id == ev.app.pkg_id); - BOOST_REQUIRE(ev2.app.uid == ev.app.uid); - // Certs and verified flag aren't used in queue, but can be tested - BOOST_REQUIRE(ev2.app.certificates == ev.app.certificates); - BOOST_REQUIRE(ev2.app.verified == ev.app.verified); - + BOOST_REQUIRE(ev2 == ev); BOOST_REQUIRE(pop_event(ev) == true); - BOOST_REQUIRE(ev3.app.app_id == ev.app.app_id); - BOOST_REQUIRE(ev3.app.pkg_id == ev.app.pkg_id); - BOOST_REQUIRE(ev3.app.uid == ev.app.uid); - // Certs and verified flag aren't used in queue, but can be tested - BOOST_REQUIRE(ev3.app.certificates == ev.app.certificates); - BOOST_REQUIRE(ev3.app.verified == ev.app.verified); + BOOST_REQUIRE(ev3 == ev); + BOOST_REQUIRE(empty() == true); BOOST_REQUIRE(pop_event(ev) == false); @@ -96,12 +94,8 @@ BOOST_AUTO_TEST_CASE(Queue) { push_event(ev4); BOOST_REQUIRE(pop_event(ev) == true); - BOOST_REQUIRE(ev4.app.app_id == ev.app.app_id); - BOOST_REQUIRE(ev4.app.pkg_id == ev.app.pkg_id); - BOOST_REQUIRE(ev4.app.uid == ev.app.uid); - // Certs and verified flag aren't used in queue, but can be tested - BOOST_REQUIRE(ev4.app.certificates == ev.app.certificates); - BOOST_REQUIRE(ev4.app.verified == ev.app.verified); + BOOST_REQUIRE(ev4 == ev); + BOOST_REQUIRE(pop_event(ev) == false); BOOST_REQUIRE(empty() == true); |