mkdir -p %{buildroot}/%{db_test_dir}
sqlite3 %{buildroot}/%{db_test_dir}/.security-manager-test.db < db/db.sql
sqlite3 %{buildroot}/%{db_test_dir}/.security-manager-test-v0.db < db/db_test_v0.sql
+dd bs=1K count=$(($(stat -c%s %{buildroot}/%{db_test_dir}/.security-manager-test.db) / 1024 - 1)) if=%{buildroot}/%{db_test_dir}/.security-manager-test.db of=%{buildroot}/%{db_test_dir}/.security-manager-test-corrupted.db
+cp -a %{buildroot}/%{db_test_dir}/.security-manager-test.db-journal %{buildroot}/%{db_test_dir}/.security-manager-test-corrupted.db-journal
echo -n > %{buildroot}/%{db_test_dir}/.security-manager-test-empty.db
echo -n > %{buildroot}/%{db_test_dir}/.security-manager-test-empty.db-journal
chsmack -a System %{db_test_dir}/.security-manager-test.db-journal
chsmack -a System %{db_test_dir}/.security-manager-test-v0.db
chsmack -a System %{db_test_dir}/.security-manager-test-v0.db-journal
+chsmack -a System %{db_test_dir}/.security-manager-test-corrupted.db
+chsmack -a System %{db_test_dir}/.security-manager-test-corrupted.db-journal
chsmack -a System %{db_test_dir}/.security-manager-test-empty.db
chsmack -a System %{db_test_dir}/.security-manager-test-empty.db-journal
%attr(0600,root,root) %{db_test_dir}/.security-manager-test.db-journal
%attr(0600,root,root) %{db_test_dir}/.security-manager-test-v0.db
%attr(0600,root,root) %{db_test_dir}/.security-manager-test-v0.db-journal
+%attr(0600,root,root) %{db_test_dir}/.security-manager-test-corrupted.db
+%attr(0600,root,root) %{db_test_dir}/.security-manager-test-corrupted.db-journal
%attr(0600,root,root) %{db_test_dir}/.security-manager-test-empty.db
%attr(0600,root,root) %{db_test_dir}/.security-manager-test-empty.db-journal
/*
- * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
#include <boost/program_options.hpp>
#include <boost/exception/diagnostic_information.hpp>
+#include <config.h>
+#include <filesystem.h>
+
namespace po = boost::program_options;
static std::map <std::string, enum app_install_path_type> app_install_path_type_map = {
("manage-apps,n", po::value<std::string>(), "add or remove app, parameter is either a/add or r/remove")
("manage-users,m", po::value<std::string>(), "add or remove user, parameter is either a/add or r/remove")
("manage-privilege,o", po::value<std::string>(), "allow or deny privilege, parameter is either a/allow or d/deny")
+ ("backup,b", "make a backup of the database file")
;
return opts;
}
auto policy_ptr = makeUnique(policy_update, security_manager_policy_update_req_free);
parsePrivilegeOptions(argc, argv, *req, vm);
return managePrivilegeOperation(*req, policy_update, operation);
+ } else if (vm.count("backup")) {
+ if (SECURITY_MANAGER_SUCCESS == FS::overwriteFile(Config::privilegeDbPath, Config::privilegeDbFallbackPath))
+ return EXIT_SUCCESS;
} else {
std::cout << "No command argument was given." << std::endl;
usage(std::string(argv[0]));
/*
- * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
#else
const bool IS_ASKUSER_ENABLED = false;
#endif
+
+const std::string privilegeDbPath = TizenPlatformConfig::makePath(TZ_SYS_DB, ".security-manager.db");
+const std::string privilegeDbFallbackPath = TizenPlatformConfig::makePath(TZ_SYS_RO_SHARE, "security-manager", ".security-manager.db");
+
+std::string dbBrokenFlagFileName(const std::string &dbPath) {
+ return dbPath + "-broken";
+}
};
} /* namespace SecurityManager */
/*
- * Copyright (c) 2016 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
return SECURITY_MANAGER_SUCCESS;
}
+int overwriteFile(const std::string &srcPath, const std::string &dstPath) {
+ std::ifstream src(srcPath, std::ios::binary);
+ if (!src)
+ return SECURITY_MANAGER_ERROR_FILE_OPEN_FAILED;
+ std::ofstream dst(dstPath, std::ios::binary|std::ios::trunc);
+ if (src.peek() != std::ifstream::traits_type::eof()) // otherwise dst.fail()
+ dst << src.rdbuf();
+ src.close();
+ dst.close();
+ return src && dst ? SECURITY_MANAGER_SUCCESS : SECURITY_MANAGER_ERROR_FILE_CREATE_FAILED;
+}
+
+int truncateFile(const std::string &path) {
+ std::ofstream dst(path, std::ios::binary|std::ios::trunc);
+ dst.close();
+ return dst ? SECURITY_MANAGER_SUCCESS : SECURITY_MANAGER_ERROR_FILE_CREATE_FAILED;
+}
+
+off_t fileSize(const std::string &path) {
+ struct stat st;
+ static_assert(std::is_same<off_t, decltype(st.st_size)>::value);
+ static_assert(std::is_signed<off_t>::value);
+ return -1 == lstat(path.c_str(), &st) || !S_ISREG(st.st_mode) ? -1 : st.st_size;
+}
+
} // namespace FS
} // namespace SecurityManager
/*
- * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
#pragma once
#include <string>
+#include <tzplatform-config.h>
namespace SecurityManager {
/* true if privacy-related privileges should result in UI-popup question*/
extern const bool IS_ASKUSER_ENABLED;
+
+extern const std::string privilegeDbPath;
+extern const std::string privilegeDbFallbackPath;
+
+std::string dbBrokenFlagFileName(const std::string &dbPath);
};
} /* namespace SecurityManager */
/*
- * Copyright (c) 2016 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
int createFile(const std::string &path);
int removeFile(const std::string &path);
int symLink(const std::string &src, const std::string &dst);
+int overwriteFile(const std::string &src, const std::string &dst);
+int truncateFile(const std::string &path);
+off_t fileSize(const std::string &path); // < 0 on error
} // namespace FS
} // namespace SecurityManager
namespace SecurityManager {
+std::string genJournalPath(const std::string &dbPath);
+
enum class StmtType : uint8_t {
EAddApplication,
ERemoveApplication,
* @exception PrivilegeDb::Exception::IOError on problems with database access
*
*/
- explicit PrivilegeDb(const std::string &path);
+ explicit PrivilegeDb(const std::string &path, const std::string &roFallbackPath);
static PrivilegeDb &getInstance();
#include <sys/stat.h>
#include <dpl/log/log.h>
+#include <config.h>
#include "../gen/db.h"
#include "privilege_db.h"
#include "tzplatform-config.h"
return cmd;
}
-std::string getPrivilegeDbPath()
-{
- static std::string path = TizenPlatformConfig::makePath(TZ_SYS_DB, ".security-manager.db");
- return path;
-}
-
bool dbEmpty(const std::string &dbPath) {
- struct stat buf;
- if (-1 == stat(dbPath.c_str(), &buf))
+ auto s = FS::fileSize(dbPath);
+ if (s < 0)
ThrowMsg(DB::SqlConnection::Exception::Base, "Failed to stat db file");
- return !buf.st_size;
+ return !s;
}
-void migrate(DB::SqlConnection &db, const std::string &path) {
+void connectMigrateVerify(DB::SqlConnection &db, const std::string &path) {
+ db.Connect(path, DB::SqlConnection::Flag::None, DB::SqlConnection::Flag::RW);
using Ex = DB::SqlConnection::Exception::Base;
int32_t version;
{
do db.ExecCommand(dbUpdateScript[version]); while (++version < dbVersion);
db.ExecCommand(dbSchema);
}
+
+ {
+ auto cmd = prepare(db, "PRAGMA integrity_check");
+ if (!cmd->Step())
+ ThrowMsg(Ex, "Integrity check returned no result");
+ if (cmd->GetColumnString(0) != "ok")
+ ThrowMsg(Ex, "Integrity check failed");
+ }
+
+ auto cmd = prepare(db, "PRAGMA foreign_key_check");
+ if (cmd->Step())
+ ThrowMsg(Ex, "Foreign key check failed");
}
-} //namespace
/* Common code for handling SqlConnection exceptions */
template <typename T>
}
}
-std::string getPrivilegeDbFailFlagPath()
-{
- static std::string path = TizenPlatformConfig::makePath(TZ_SYS_DB, ".security-manager.db-broken");
- return path;
+void throwDbInitEx(const std::string &errDesc) {
+ auto s = "Database initialization error: " + errDesc;
+ LogError(s);
+ ThrowMsg(PrivilegeDb::Exception::IOError, s);
+}
+
+void createBrokenFlagFile(const std::string &dbPath) {
+ if (SECURITY_MANAGER_SUCCESS != FS::createFile(Config::dbBrokenFlagFileName(dbPath)))
+ throwDbInitEx("Error creating db broken flag file");
}
-PrivilegeDb::PrivilegeDb() : PrivilegeDb(getPrivilegeDbPath())
+template <class F>
+void tryCatchDbInit(F &&f) {
+ try {
+ f();
+ } catch (DB::SqlConnection::Exception::Base &e) {
+ throwDbInitEx(e.DumpToString());
+ }
+}
+
+void applyFallbackDb(DB::SqlConnection &conn, const std::string &dbPath, const std::string &roFallbackPath) {
+ if (SECURITY_MANAGER_SUCCESS != FS::overwriteFile(roFallbackPath, dbPath))
+ throwDbInitEx("Error overwriting database with fallback: " + roFallbackPath);
+ if (SECURITY_MANAGER_SUCCESS != FS::truncateFile(genJournalPath(dbPath)))
+ throwDbInitEx("Error truncating journal");
+ tryCatchDbInit([&]{ connectMigrateVerify(conn, dbPath); });
+}
+} //namespace
+
+std::string genJournalPath(const std::string &dbPath) {
+ return dbPath + "-journal";
+}
+
+PrivilegeDb::PrivilegeDb()
+ : PrivilegeDb(Config::privilegeDbPath, Config::privilegeDbFallbackPath)
{
}
-PrivilegeDb::PrivilegeDb(const std::string &path)
+PrivilegeDb::PrivilegeDb(const std::string &path, const std::string &roFallbackPath)
{
- try {
- mSqlConnection.Connect(path,
- DB::SqlConnection::Flag::None,
- DB::SqlConnection::Flag::RW);
- migrate(mSqlConnection, path);
- initDataCommands();
+ if (!FS::fileStatus(path)) {
+ createBrokenFlagFile(path);
+ LogError("Database file missing, attempting fallback");
+ applyFallbackDb(mSqlConnection, path, roFallbackPath);
+ } else try {
+ connectMigrateVerify(mSqlConnection, path);
} catch (DB::SqlConnection::Exception::Base &e) {
- LogError("Database initialization error: " << e.DumpToString());
- FS::createFile(getPrivilegeDbFailFlagPath());
- ThrowMsg(PrivilegeDb::Exception::IOError,
- "Database initialization error:" << e.DumpToString());
- };
+ createBrokenFlagFile(path);
+ LogError("Database initialization error (" << e.DumpToString() << "), attempting fallback");
+ tryCatchDbInit([&]{ mSqlConnection.Disconnect(); });
+ applyFallbackDb(mSqlConnection, path, roFallbackPath);
+ }
+ tryCatchDbInit([&]{ initDataCommands(); });
}
void PrivilegeDb::initDataCommands()
// Synchronization object
std::unique_ptr<SynchronizationObject> m_synchronizationObject;
- void Disconnect();
-
void TurnOnForeignKeys();
static SynchronizationObject *AllocDefaultSynchronizationObject();
/**
* Open SQL connection
*
- * Called exactly once on a newly constructed object before using it.
+ * Called exactly once on a disconnected object before using it.
*
* @param address Database file name
* @param type Open options (ie. use Lucene index or not)
Flag::Option flag = Flag::RO);
/**
+ * Disconnect SQL connection
+ */
+ void Disconnect();
+
+ /**
* Destructor
*/
~SqlConnection();
${DPL_PATH}/log/src/abstract_log_provider.cpp
${DPL_PATH}/log/src/log.cpp
${DPL_PATH}/log/src/old_style_log_provider.cpp
+ ${PROJECT_SOURCE_DIR}/src/common/config.cpp
${PROJECT_SOURCE_DIR}/src/common/config-file.cpp
${PROJECT_SOURCE_DIR}/src/common/file-lock.cpp
${PROJECT_SOURCE_DIR}/src/common/privilege_db.cpp
${DPL_PATH}/log/src/abstract_log_provider.cpp
${DPL_PATH}/log/src/log.cpp
${DPL_PATH}/log/src/old_style_log_provider.cpp
+ ${PROJECT_SOURCE_DIR}/src/common/config.cpp
${PROJECT_SOURCE_DIR}/src/common/config-file.cpp
#${PROJECT_SOURCE_DIR}/src/common/file-lock.cpp
${PROJECT_SOURCE_DIR}/src/common/privilege_db.cpp
#include <boost/test/unit_test.hpp>
#include <boost/test/results_reporter.hpp>
+#include <config.h>
+#include <filesystem.h>
+
#include "privilege_db.h"
#include "privilege_db_fixture.h"
constexpr uid_t FirstUidForTests = 9900;
void putFile(const std::string &srcPath, const std::string &dstPath) {
- std::ifstream src(srcPath, std::ios::binary);
- std::ofstream dst(dstPath, std::ios::binary|std::ios::trunc);
- if (src.peek() != std::ifstream::traits_type::eof()) // otherwise dst.fail()
- dst << src.rdbuf();
- BOOST_REQUIRE(src && dst);
+ BOOST_REQUIRE(SECURITY_MANAGER_SUCCESS == FS::overwriteFile(srcPath, dstPath));
}
std::string genName(const std::string &prefix, int i)
}
} //namespace
-std::string genJournalPath(const char *dbPath) {
- Assert(dbPath);
- return dbPath + std::string("-journal");
+void requireNoDb(const std::string &dbPath) {
+ BOOST_REQUIRE(!FS::fileStatus(dbPath));
+ BOOST_REQUIRE(!FS::fileStatus(genJournalPath(dbPath)));
+ BOOST_REQUIRE(!FS::fileStatus(Config::dbBrokenFlagFileName(dbPath)));
}
-PrivilegeDBFixture::PrivilegeDBFixture(char const *src)
+PrivilegeDBFixture::PrivilegeDBFixture(const std::string &src, const std::string &fallback,
+ HaveBrokenFlagFile haveBrokenFlagFile, const std::string &dst)
+ : dbPath(dst)
{
- Assert(src);
- putFile(src, TEST_PRIVILEGE_DB_PATH);
- putFile(genJournalPath(src), genJournalPath(TEST_PRIVILEGE_DB_PATH));
-
- testPrivDb = new PrivilegeDb(TEST_PRIVILEGE_DB_PATH);
-};
+ requireNoDb(dst);
+ putFile(src, dst);
+ putFile(genJournalPath(src), genJournalPath(dst));
+
+ testPrivDb = new PrivilegeDb(dst, fallback);
+ const auto brokenFlagFileName = Config::dbBrokenFlagFileName(dst);
+ const auto flagFileStatus = FS::fileStatus(brokenFlagFileName);
+ if (haveBrokenFlagFile == HaveBrokenFlagFile::no) {
+ BOOST_REQUIRE(!flagFileStatus);
+ } else {
+ BOOST_REQUIRE(flagFileStatus > 0);
+ BOOST_REQUIRE(!FS::fileSize(brokenFlagFileName));
+ BOOST_REQUIRE(!remove(brokenFlagFileName.c_str()));
+ }
+}
PrivilegeDBFixture::~PrivilegeDBFixture()
{
- auto journalPath = genJournalPath(TEST_PRIVILEGE_DB_PATH);
- if (std::ifstream(TEST_PRIVILEGE_DB_PATH))
- BOOST_WARN_MESSAGE(remove(TEST_PRIVILEGE_DB_PATH) == 0,
- "Could not delete test database file: " << TEST_PRIVILEGE_DB_PATH);
- if (std::ifstream(journalPath))
- BOOST_WARN_MESSAGE(remove(journalPath.c_str()) == 0,
- "Could not delete test database file: " << journalPath);
-
+ BOOST_REQUIRE_MESSAGE(remove(dbPath.c_str()) == 0, "Could not delete test database file: " << dbPath);
+ auto journalPath = genJournalPath(dbPath);
+ BOOST_REQUIRE_MESSAGE(remove(journalPath.c_str()) == 0, "Could not delete test database journal file: " << journalPath);
+ BOOST_REQUIRE(!FS::fileStatus(Config::dbBrokenFlagFileName(dbPath)));
delete testPrivDb;
}
#define PRIVILEGE_DB_TEMPLATE DB_TEST_DIR"/.security-manager-test.db"
#define PRIVILEGE_DB_EXAMPLE_V0 DB_TEST_DIR"/.security-manager-test-v0.db"
+#define PRIVILEGE_DB_CORRUPTED DB_TEST_DIR"/.security-manager-test-corrupted.db"
#define PRIVILEGE_DB_EMPTY DB_TEST_DIR"/.security-manager-test-empty.db"
#define TEST_PRIVILEGE_DB_PATH "/tmp/.security-manager-test.db"
+#define TEST_PRIVILEGE_DB_PATH_2 "/tmp/.security-manager-test-2.db"
using namespace SecurityManager;
-std::string genJournalPath(const char *dbPath);
+void requireNoDb(const std::string &dbPath);
struct PrivilegeDBFixture {
public:
- explicit PrivilegeDBFixture(char const *src = PRIVILEGE_DB_TEMPLATE);
+ enum class HaveBrokenFlagFile : bool { no, yes };
+ explicit PrivilegeDBFixture(const std::string &src = PRIVILEGE_DB_TEMPLATE,
+ const std::string &fallback = PRIVILEGE_DB_TEMPLATE,
+ HaveBrokenFlagFile = HaveBrokenFlagFile::no, const std::string &dst = TEST_PRIVILEGE_DB_PATH);
~PrivilegeDBFixture();
PrivilegeDb* getPrivDb();
protected:
PrivilegeDb *testPrivDb;
+
+private:
+ std::string dbPath;
};
* limitations under the License
*/
+#include <stdio.h>
#include <stdlib.h>
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/unit_test_monitor.hpp>
+#include <config.h>
+#include <filesystem.h>
#include "privilege_db.h"
#include "privilege_db_fixture.h"
return s == b.size() && !memcmp(a.data(), b.data(), s);
}
+void requireTestDbContents(const std::string &db) {
+ BOOST_REQUIRE(fileContentsSame(TEST_PRIVILEGE_DB_PATH, db));
+}
+
+void requireTestDbAndJournalContents(const std::string &db) {
+ requireTestDbContents(db);
+ BOOST_REQUIRE(fileContentsSame(genJournalPath(TEST_PRIVILEGE_DB_PATH), genJournalPath(db)));
+}
+
void translateIOError(PrivilegeDb::Exception::IOError e) {
BOOST_FAIL("IOError: " + e.DumpToString());
}
-class Config {
+class TestConfig {
public:
- Config() {
+ TestConfig() {
boost::unit_test::unit_test_monitor.register_exception_translator<PrivilegeDb::Exception::IOError>(&translateIOError);
}
};
struct PrivilegeEmptyDBFixture : PrivilegeDBFixture {
PrivilegeEmptyDBFixture() : PrivilegeDBFixture(PRIVILEGE_DB_EMPTY) {}
};
+struct PrivilegeFallbackDBFixture : PrivilegeDBFixture {
+ PrivilegeFallbackDBFixture() : PrivilegeDBFixture(PRIVILEGE_DB_CORRUPTED, PRIVILEGE_DB_TEMPLATE, HaveBrokenFlagFile::yes) {}
+};
+struct PrivilegeFallbackV0DBFixture : PrivilegeDBFixture {
+ PrivilegeFallbackV0DBFixture() : PrivilegeDBFixture(PRIVILEGE_DB_CORRUPTED, PRIVILEGE_DB_EXAMPLE_V0, HaveBrokenFlagFile::yes) {}
+};
+struct PrivilegeFallbackEmptyDBFixture : PrivilegeDBFixture {
+ PrivilegeFallbackEmptyDBFixture() : PrivilegeDBFixture(PRIVILEGE_DB_CORRUPTED, PRIVILEGE_DB_EMPTY, HaveBrokenFlagFile::yes) {}
+};
} //namespace
-BOOST_GLOBAL_FIXTURE(Config)
+BOOST_GLOBAL_FIXTURE(TestConfig)
BOOST_FIXTURE_TEST_SUITE(PRIVILEGE_DB_TEST_EMPTY, PrivilegeEmptyDBFixture)
+BOOST_AUTO_TEST_CASE(T1500_schema_application) {
+ requireTestDbAndJournalContents(PRIVILEGE_DB_TEMPLATE);
+}
+BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_CASE(T1500_schema_application)
-{
- BOOST_REQUIRE(fileContentsSame(PRIVILEGE_DB_TEMPLATE, TEST_PRIVILEGE_DB_PATH));
- BOOST_REQUIRE(fileContentsSame(genJournalPath(PRIVILEGE_DB_TEMPLATE), genJournalPath(TEST_PRIVILEGE_DB_PATH)));
+BOOST_FIXTURE_TEST_SUITE(PRIVILEGE_DB_TEST_FALLBACK, PrivilegeFallbackDBFixture)
+BOOST_AUTO_TEST_CASE(T1510_fallback) {
+ requireTestDbContents(PRIVILEGE_DB_TEMPLATE);
+ BOOST_REQUIRE(!FS::fileSize(genJournalPath(TEST_PRIVILEGE_DB_PATH)));
+}
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_FIXTURE_TEST_SUITE(PRIVILEGE_DB_TEST_FALLBACK_EMPTY, PrivilegeFallbackEmptyDBFixture)
+BOOST_AUTO_TEST_CASE(T1520_fallback_schema_application) {
+ requireTestDbAndJournalContents(PRIVILEGE_DB_TEMPLATE);
+}
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_FIXTURE_TEST_SUITE(PRIVILEGE_DB_TEST_FALLBACK_V0, PrivilegeFallbackV0DBFixture)
+
+BOOST_AUTO_TEST_CASE(T1530_fallback_migration) {
+ PrivilegeDBFixture v0(PRIVILEGE_DB_EXAMPLE_V0, PRIVILEGE_DB_TEMPLATE,
+ PrivilegeDBFixture::HaveBrokenFlagFile::no, TEST_PRIVILEGE_DB_PATH_2);
+ requireTestDbContents(TEST_PRIVILEGE_DB_PATH_2);
+}
+
+BOOST_AUTO_TEST_CASE(T1540_db_missing_fallback_migration) {
+ const std::string missingDbPath("/tmp/thisNotExists.db");
+ requireNoDb(missingDbPath);
+ const auto missingDbPathJournal = genJournalPath(missingDbPath);
+ const auto missingDbPathFlag = Config::dbBrokenFlagFileName(missingDbPath);
+ BOOST_REQUIRE_NO_THROW(PrivilegeDb(missingDbPath, PRIVILEGE_DB_EXAMPLE_V0));
+ requireTestDbContents(missingDbPath);
+ BOOST_REQUIRE(!remove(missingDbPath.c_str()));
+ BOOST_REQUIRE(!remove(missingDbPathJournal.c_str()));
+ BOOST_REQUIRE(!FS::fileSize(missingDbPathFlag));
+ BOOST_REQUIRE(!remove(missingDbPathFlag.c_str()));
}
BOOST_AUTO_TEST_SUITE_END()
/*
- * Copyright (c) 2016 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016 - 2018 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.
#include <boost/test/results_reporter.hpp>
#include <boost/test/utils/wrap_stringstream.hpp>
+#include <config.h>
+#include <filesystem.h>
+
#include "privilege_db.h"
#include "privilege_db_fixture.h"
BOOST_FIXTURE_TEST_CASE(T100_privilegedb_constructor, Empty)
{
- PrivilegeDb *testPrivDb = nullptr;
+ std::unique_ptr<PrivilegeDb> testPrivDb;
+
+ BOOST_REQUIRE_NO_THROW(testPrivDb.reset(new PrivilegeDb()));
- BOOST_REQUIRE_NO_THROW(testPrivDb = new PrivilegeDb());
- delete testPrivDb;
- testPrivDb = nullptr;
- BOOST_REQUIRE_THROW(testPrivDb = new PrivilegeDb("/this/not/exists"),
+ std::string nExist("/tmp/thisNotExists"), nExist2("/tmp/neitherDoesThis");
+ requireNoDb(nExist);
+ requireNoDb(nExist2);
+ BOOST_REQUIRE_THROW(testPrivDb.reset(new PrivilegeDb(nExist, nExist2)),
PrivilegeDb::Exception::IOError);
- delete testPrivDb;
+ const auto flagFile = Config::dbBrokenFlagFileName(nExist);
+ BOOST_REQUIRE(!FS::fileSize(flagFile));
+ BOOST_REQUIRE(!remove(flagFile.c_str()));
+ requireNoDb(nExist);
+
+ // fallback existent but db can't be created w/out mkdir -p
+ std::string nExistDeep("/this/not/exists");
+ requireNoDb(nExistDeep);
+ BOOST_REQUIRE_THROW(testPrivDb.reset(new PrivilegeDb(nExistDeep, PRIVILEGE_DB_TEMPLATE)),
+ PrivilegeDb::Exception::IOError);
+ requireNoDb(nExistDeep);
}
// Transactions
BOOST_AUTO_TEST_CASE(T240_transaction)
{
BOOST_REQUIRE_NO_THROW(getPrivDb()->BeginTransaction());
- addAppSuccess(app(1),pkg(1), uid(1), tizenVer(1), author(1), NotHybrid);
+ addAppSuccess(app(1), pkg(1), uid(1), tizenVer(1), author(1), NotHybrid);
BOOST_REQUIRE_NO_THROW(getPrivDb()->CommitTransaction());
BOOST_REQUIRE_NO_THROW(getPrivDb()->BeginTransaction());