Add cynara test environment class 15/24515/25
authorMarcin Niesluchowski <m.niesluchow@samsung.com>
Tue, 15 Jul 2014 16:54:35 +0000 (18:54 +0200)
committerMarcin Niesluchowski <m.niesluchow@samsung.com>
Tue, 5 Aug 2014 11:39:26 +0000 (13:39 +0200)
Change-Id: I6a83f3aab6e5ff4de4d6a9092b0b882af0eb22be

CMakeLists.txt
packaging/security-tests.spec
tests/common/tests_common.h
tests/cynara-tests/CMakeLists.txt
tests/cynara-tests/common/cynara_test_env.cpp [new file with mode: 0644]
tests/cynara-tests/common/cynara_test_env.h [new file with mode: 0644]
tests/cynara-tests/test_cases.cpp

index 0ae305b..ca11bf1 100644 (file)
@@ -70,6 +70,7 @@ ADD_DEFINITIONS("-Wno-variadic-macros")         # Inhibit variadic macros warnin
 ADD_DEFINITIONS("-Wno-deprecated")               # No warnings about deprecated features
 STRING(REGEX MATCH "([^.]*)" API_VERSION "${VERSION}")
 ADD_DEFINITIONS("-DAPI_VERSION=\"$(API_VERSION)\"")
+ADD_DEFINITIONS("-DCYNARA_DB_DIR=\"${CYNARA_DB_DIR}\"")
 
 IF(SMACK_ENABLE)
     ADD_DEFINITIONS("-DWRT_SMACK_ENABLED")
index 4fde9eb..7cb7426 100644 (file)
@@ -38,7 +38,8 @@ cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \
         -DDPL_LOG="ON"                    \
         -DVERSION=%{version}              \
         -DCMAKE_BUILD_TYPE=%{?build_type:%build_type}%{!?build_type:DEBUG} \
-        -DCMAKE_VERBOSE_MAKEFILE=ON
+        -DCMAKE_VERBOSE_MAKEFILE=ON       \
+        -DCYNARA_DB_DIR=%{_localstatedir}/cynara/db
 make %{?jobs:-j%jobs}
 
 %install
index 98e6a5b..0307b95 100644 (file)
@@ -31,6 +31,8 @@
 #include <privilege-control.h>
 #include <sys/smack.h>
 #include <string>
+#include <errno.h>
+#include <string.h>
 
 #include "gdbbacktrace.h"
 
@@ -135,6 +137,9 @@ std::string formatCstr(const char *cstr);
                                                           msg << gdbbacktrace())
 #define RUNNER_ASSERT_BT(test) RUNNER_ASSERT_MSG_BT(test, "")
 
+#define RUNNER_ASSERT_MSG_ERRNO_BT(test, msg) \
+    RUNNER_ASSERT_MSG_BT(test, msg << strerror(errno))
+
 namespace DB {
 
     class Transaction
index c5a0025..9093003 100644 (file)
@@ -9,12 +9,15 @@ PKG_CHECK_MODULES(CYNARA_TARGET_DEP
     libprivilege-control
     cynara-admin
     cynara-client
+    dbus-1
+    dbus-glib-1
     )
 
 #files to compile
 SET(CYNARA_TARGET_TEST_SOURCES
     ${PROJECT_SOURCE_DIR}/tests/cynara-tests/common/cynara_test_admin.cpp
     ${PROJECT_SOURCE_DIR}/tests/cynara-tests/common/cynara_test_client.cpp
+    ${PROJECT_SOURCE_DIR}/tests/cynara-tests/common/cynara_test_env.cpp
     ${PROJECT_SOURCE_DIR}/tests/cynara-tests/cynara-test.cpp
     ${PROJECT_SOURCE_DIR}/tests/cynara-tests/test_cases.cpp
     )
@@ -29,6 +32,9 @@ INCLUDE_DIRECTORIES(
     ${PROJECT_SOURCE_DIR}/tests/cynara-tests/common/
     )
 
+
+ADD_DEFINITIONS("-I/usr/include/dbus-1.0/dbus")
+
 #output format
 ADD_EXECUTABLE(${CYNARA_TARGET_TEST} ${CYNARA_TARGET_TEST_SOURCES})
 
diff --git a/tests/cynara-tests/common/cynara_test_env.cpp b/tests/cynara-tests/common/cynara_test_env.cpp
new file mode 100644 (file)
index 0000000..65bf254
--- /dev/null
@@ -0,0 +1,167 @@
+#include <cynara_test_env.h>
+#include <tests_common.h>
+#include <dbus_access.h>
+#include <memory.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/sendfile.h>
+#include <unistd.h>
+#include <errno.h>
+#include <ftw.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <dirent.h>
+
+namespace
+{
+
+typedef CStringPtr PwBufPtr;
+
+DEFINE_SMARTPTR(closedir, DIR, DirPtr);
+
+const std::string cynaraDbDir = CYNARA_DB_DIR;
+const std::string tmpDir = "/tmp/";
+const std::string cynaraUser = "cynara";
+const std::string cynaraLabel = "System";
+
+int removeContents(const char *fpath, const struct stat * /*sb*/,
+                   int tflag, struct FTW * /*ftwbuf*/)
+{
+    if (tflag == FTW_F)
+        RUNNER_ASSERT_MSG_BT(!unlink(fpath), "Unable to unlink " << fpath << " file. "
+                                             << strerror(errno));
+    else
+        RUNNER_ASSERT_MSG_BT(tflag == FTW_DP, "Visited file should not exist. Path: " << fpath);
+    return 0;
+}
+
+void copyFile(const std::string &src, const std::string &dst)
+{
+    int inFd = TEMP_FAILURE_RETRY(open(src.c_str(), O_RDONLY));
+    RUNNER_ASSERT_MSG_ERRNO_BT(inFd > 0, "Opening " << src << " file failed");
+    FdUniquePtr inFdPtr(&inFd);
+
+    int outFd = TEMP_FAILURE_RETRY(creat(dst.c_str(), 0700));
+    RUNNER_ASSERT_MSG_ERRNO_BT(outFd > 0, "Creating " << dst << " file failed");
+    FdUniquePtr outFdPtr(&outFd);
+
+    long int len = sysconf(_SC_GETPW_R_SIZE_MAX);
+    RUNNER_ASSERT_MSG_BT(len != -1, "No suggested buflen");
+    size_t buflen = len;
+    char *buf = static_cast<char*>(malloc(buflen));
+
+    PwBufPtr pwBufPtr(buf);
+
+    struct passwd pwbuf, *pwbufp = nullptr;
+    int ret = TEMP_FAILURE_RETRY(getpwnam_r(cynaraUser.c_str(),
+                                            &pwbuf, buf, buflen, &pwbufp));
+    RUNNER_ASSERT_MSG_ERRNO_BT(ret == 0, "getpwnam_r failed on " << cynaraUser << " user");
+    RUNNER_ASSERT_MSG_BT(pwbufp, "User " << cynaraUser << " does not exist");
+
+    ret = fchown(outFd, pwbufp->pw_uid, pwbufp->pw_gid);
+    RUNNER_ASSERT_MSG_ERRNO_BT(ret != -1, "fchown failed");
+
+    ret = smack_fsetlabel(outFd, cynaraLabel.c_str(), SMACK_LABEL_ACCESS);
+    RUNNER_ASSERT_MSG_BT(ret == 0, "Setting smack label failed");
+
+    struct stat statSrc;
+    ret = fstat(inFd, &statSrc);
+    RUNNER_ASSERT_MSG_ERRNO_BT(ret != -1, "fstat failed");
+
+    ret = sendfile(outFd, inFd, 0, statSrc.st_size);
+    RUNNER_ASSERT_MSG_ERRNO_BT(ret != -1, "sendfile failed");
+}
+
+void copyDir(const std::string &source, const std::string &destination)
+{
+    DIR *dirPtr = nullptr;
+    struct dirent *direntPtr;
+
+    RUNNER_ASSERT_MSG_ERRNO_BT(dirPtr = opendir(source.c_str()),
+                               "opening " << source << " dir failed");
+    DirPtr dirScopedPtr(dirPtr);
+
+    while((direntPtr = readdir(dirPtr)) != nullptr) {
+        if (!strcmp(direntPtr->d_name, ".")
+         || !strcmp(direntPtr->d_name, ".."))
+            continue;
+        std::string tempDest = destination + "/" + direntPtr->d_name;
+        std::string tempSrc = source + "/" + direntPtr->d_name;
+        copyFile(tempSrc, tempDest);
+    }
+}
+
+void clear(const std::string &dir)
+{
+    int ret = nftw(dir.c_str(), removeContents, 2, FTW_DEPTH | FTW_PHYS);
+    if (ret == -1)
+        RUNNER_ASSERT_MSG_ERRNO_BT(errno == ENOENT, "nftw failed");
+}
+
+void removeDirIfExists(const std::string &dir)
+{
+    RUNNER_ASSERT_MSG_ERRNO_BT(!rmdir(dir.c_str()) || errno == ENOENT,
+                               "Removing " << dir << " dir failed");
+}
+
+bool cynaraDbExists()
+{
+    struct stat st;
+    int ret = stat(cynaraDbDir.c_str(), &st);
+    if (ret == -1 && errno == ENOENT) {
+        return false;
+    } else if (ret == -1) {
+        RUNNER_ASSERT_MSG_ERRNO_BT(false, "Cannot stat " << cynaraDbDir
+                                          << " not due to its nonexistence");
+    }
+    RUNNER_ASSERT_MSG_BT(st.st_mode & S_IFDIR, cynaraDbDir << " is not a directory");
+    return true;
+}
+
+}
+
+CynaraTestEnv::CynaraTestEnv(const char *dirName)
+    : m_dbPresent(false)
+{
+    m_dir = tmpDir + dirName;
+}
+
+CynaraTestEnv::~CynaraTestEnv()
+{
+}
+
+void CynaraTestEnv::save()
+{
+    clear(m_dir);
+    removeDirIfExists(m_dir);
+
+    DBusAccess dbusAccess("cynara.service");
+    dbusAccess.stopService();
+
+    m_dbPresent = cynaraDbExists();
+    if (m_dbPresent) {
+        RUNNER_ASSERT_MSG_ERRNO_BT(!mkdir(m_dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO),
+                                   "Unable to make " << m_dir << " test directory");
+        copyDir(cynaraDbDir, m_dir);
+    }
+
+    dbusAccess.startService();
+}
+
+void CynaraTestEnv::restore()
+{
+    DBusAccess dbusAccess("cynara.service");
+    dbusAccess.stopService();
+
+    clear(cynaraDbDir);
+    if (m_dbPresent)
+        copyDir(m_dir, cynaraDbDir);
+    else
+        removeDirIfExists(cynaraDbDir);
+
+    dbusAccess.startService();
+
+    clear(m_dir);
+    removeDirIfExists(m_dir);
+}
diff --git a/tests/cynara-tests/common/cynara_test_env.h b/tests/cynara-tests/common/cynara_test_env.h
new file mode 100644 (file)
index 0000000..d02ea78
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef CYNARA_TEST_ENV_H
+#define CYNARA_TEST_ENV_H
+
+#include <string>
+
+class CynaraTestEnv
+{
+public:
+    explicit CynaraTestEnv(const char *dirName);
+    virtual ~CynaraTestEnv();
+
+    void save();
+    void restore();
+
+private:
+    std::string m_dir;
+    bool m_dbPresent;
+};
+
+#endif // CYNARA_TEST_ENV_H
index e52332e..c61e632 100644 (file)
 #include <tests_common.h>
 #include <cynara_test_client.h>
 #include <cynara_test_admin.h>
+#include <cynara_test_env.h>
 
+#include <functional>
 #include <climits>
 
-RUNNER_TEST_GROUP_INIT(cynara_tests)
+void environmentWrap(const char *testName, const std::function<void(void)> &func)
+{
+    CynaraTestEnv env(testName);
+    env.save();
+
+    try {
+        func();
+    } catch (const DPL::Test::TestRunner::TestFailed &e) {
+        env.restore();
+        throw e;
+    } catch (const DPL::Test::TestRunner::Ignored &e) {
+        env.restore();
+        throw e;
+    } catch (const DPL::Exception &e) {
+        env.restore();
+        throw e;
+    } catch (const std::exception &e) {
+        env.restore();
+        throw e;
+    } catch (...) {
+        env.restore();
+        throw std::runtime_error("Unknown exception");
+    }
+    env.restore();
+}
 
-RUNNER_TEST(tc01_cynara_initialize) {
-    CynaraTestClient cynara;
+#define RUN_CYNARA_TEST(Proc)                \
+    RUNNER_TEST(Proc)                        \
+    {                                        \
+        environmentWrap(#Proc, Proc##_func); \
+    }
+
+void tc01_cynara_initialize_func()
+{
+    CynaraTestClient();
 }
 
-RUNNER_TEST(tc02_admin_initialize) {
+void tc02_admin_initialize_func()
+{
     CynaraTestAdmin admin;
 }
 
-RUNNER_TEST(tc03_cynara_check_invalid_params) {
+void tc03_cynara_check_invalid_params_func()
+{
     CynaraTestClient cynara;
 
     const char *client = "client03";
@@ -66,7 +101,8 @@ void checkInvalidPolicy(CynaraTestAdmin &admin,
     admin.setPolicies(cp, CYNARA_ADMIN_API_INVALID_PARAM);
 }
 
-RUNNER_TEST(tc04_admin_set_policies_invalid_params) {
+void tc04_admin_set_policies_invalid_params_func()
+{
     CynaraTestAdmin admin;
 
     const char *bucket = CYNARA_ADMIN_DEFAULT_BUCKET;
@@ -85,7 +121,8 @@ RUNNER_TEST(tc04_admin_set_policies_invalid_params) {
     checkInvalidPolicy(admin, bucket,  client,  user,    privilege, resultBucket, nullptr    );
 }
 
-RUNNER_TEST(tc05_admin_set_bucket_invalid_params) {
+void tc05_admin_set_bucket_invalid_params_func()
+{
     CynaraTestAdmin admin;
 
     const char *bucket = CYNARA_ADMIN_DEFAULT_BUCKET;
@@ -98,7 +135,7 @@ RUNNER_TEST(tc05_admin_set_bucket_invalid_params) {
     admin.setBucket(bucket,  operationDelete,  extra, CYNARA_ADMIN_API_OPERATION_NOT_ALLOWED);
 }
 
-RUNNER_TEST(tc06_cynara_check_empty_admin1)
+void tc06_cynara_check_empty_admin1_func()
 {
     CynaraTestClient cynara;
 
@@ -110,7 +147,7 @@ RUNNER_TEST(tc06_cynara_check_empty_admin1)
     cynara.check(client, session, user, privilege, CYNARA_API_ACCESS_DENIED);
 }
 
-RUNNER_TEST(tc06_cynara_check_empty_admin2)
+void tc06_cynara_check_empty_admin2_func()
 {
     CynaraTestClient cynara;
 
@@ -122,7 +159,7 @@ RUNNER_TEST(tc06_cynara_check_empty_admin2)
     cynara.check(client, session, user, privilege, CYNARA_API_ACCESS_DENIED);
 }
 
-RUNNER_TEST(tc07_admin_set_bucket_admin_allow_deny)
+void tc07_admin_set_bucket_admin_allow_deny_func()
 {
     CynaraTestAdmin admin;
     CynaraTestClient cynara;
@@ -143,7 +180,7 @@ RUNNER_TEST(tc07_admin_set_bucket_admin_allow_deny)
     cynara.check(client, session, user, privilege, CYNARA_API_ACCESS_DENIED);
 }
 
-RUNNER_TEST(tc08_admin_set_policies_allow_remove1)
+void tc08_admin_set_policies_allow_remove1_func()
 {
     CynaraTestAdmin admin;
     CynaraTestClient cynara;
@@ -199,7 +236,7 @@ RUNNER_TEST(tc08_admin_set_policies_allow_remove1)
     cynara.check(data[1][0], session, data[1][1], data[1][2], CYNARA_API_ACCESS_DENIED);
 }
 
-RUNNER_TEST(tc08_admin_set_policies_allow_remove2)
+void tc08_admin_set_policies_allow_remove2_func()
 {
     CynaraTestAdmin admin;
     CynaraTestClient cynara;
@@ -248,7 +285,7 @@ RUNNER_TEST(tc08_admin_set_policies_allow_remove2)
     cynara.check(data[1][0], session, data[1][1], data[1][2], CYNARA_API_ACCESS_DENIED);
 }
 
-RUNNER_TEST(tc08_admin_set_policies_allow_remove3)
+void tc08_admin_set_policies_allow_remove3_func()
 {
     CynaraTestAdmin admin;
     CynaraTestClient cynara;
@@ -359,7 +396,7 @@ void setSingleWildcardPolicies(const char *bucket,
     admin.setPolicies(cp);
 }
 
-RUNNER_TEST(tc09_admin_set_policies_wildcard_accesses)
+void tc09_admin_set_policies_wildcard_accesses_func()
 {
     const char *bucket = CYNARA_ADMIN_DEFAULT_BUCKET;
     const char *session = "session09";
@@ -382,7 +419,7 @@ RUNNER_TEST(tc09_admin_set_policies_wildcard_accesses)
     checkAllDeny(data, session);
 }
 
-RUNNER_TEST(tc10_admin_change_extra_bucket)
+void tc10_admin_change_extra_bucket_func()
 {
     CynaraTestAdmin admin;
     CynaraTestClient cynara;
@@ -442,7 +479,7 @@ RUNNER_TEST(tc10_admin_change_extra_bucket)
     admin.setBucket(bucket, CYNARA_ADMIN_DELETE, extra);
 }
 
-RUNNER_TEST(tc11_admin_bucket_not_found)
+void tc11_admin_bucket_not_found_func()
 {
     CynaraTestAdmin admin;
     CynaraTestClient cynara;
@@ -466,7 +503,7 @@ RUNNER_TEST(tc11_admin_bucket_not_found)
     cynara.check(client, session, user, privilege, CYNARA_API_ACCESS_DENIED);
 }
 
-RUNNER_TEST(tc12_admin_delete_bucket_with_policies_pointing_to_it)
+void tc12_admin_delete_bucket_with_policies_pointing_to_it_func()
 {
     CynaraTestAdmin admin;
     CynaraTestClient cynara;
@@ -500,7 +537,7 @@ RUNNER_TEST(tc12_admin_delete_bucket_with_policies_pointing_to_it)
     cynara.check(client, session, user, privilege, CYNARA_API_ACCESS_DENIED);
 }
 
-RUNNER_TEST(tc13_admin_set_policies_to_extra_bucket)
+void tc13_admin_set_policies_to_extra_bucket_func()
 {
     CynaraTestAdmin admin;
     CynaraTestClient cynara;
@@ -532,3 +569,22 @@ RUNNER_TEST(tc13_admin_set_policies_to_extra_bucket)
     admin.setBucket(bucket, CYNARA_ADMIN_DELETE, extra);
     cynara.check(client, session, user, privilege, CYNARA_API_ACCESS_DENIED);
 }
+
+RUNNER_TEST_GROUP_INIT(cynara_tests)
+
+RUN_CYNARA_TEST(tc01_cynara_initialize)
+RUN_CYNARA_TEST(tc02_admin_initialize)
+RUN_CYNARA_TEST(tc03_cynara_check_invalid_params)
+RUN_CYNARA_TEST(tc04_admin_set_policies_invalid_params)
+RUN_CYNARA_TEST(tc05_admin_set_bucket_invalid_params)
+RUN_CYNARA_TEST(tc06_cynara_check_empty_admin1)
+RUN_CYNARA_TEST(tc06_cynara_check_empty_admin2)
+RUN_CYNARA_TEST(tc07_admin_set_bucket_admin_allow_deny)
+RUN_CYNARA_TEST(tc08_admin_set_policies_allow_remove1)
+RUN_CYNARA_TEST(tc08_admin_set_policies_allow_remove2)
+RUN_CYNARA_TEST(tc08_admin_set_policies_allow_remove3)
+RUN_CYNARA_TEST(tc09_admin_set_policies_wildcard_accesses)
+RUN_CYNARA_TEST(tc10_admin_change_extra_bucket)
+RUN_CYNARA_TEST(tc11_admin_bucket_not_found)
+RUN_CYNARA_TEST(tc12_admin_delete_bucket_with_policies_pointing_to_it)
+RUN_CYNARA_TEST(tc13_admin_set_policies_to_extra_bucket)