2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <cynara_test_env.h>
18 #include <tests_common.h>
19 #include <dbus_access.h>
22 #include <sys/types.h>
24 #include <sys/sendfile.h>
35 typedef CStringPtr PwBufPtr;
37 DEFINE_SMARTPTR(closedir, DIR, DirPtr);
39 const std::string cynaraDbDir = CYNARA_DB_DIR;
40 const std::string tmpDir = "/tmp/";
41 const std::string cynaraUser = "cynara";
42 const std::string cynaraLabel = "System";
44 int removeContents(const char *fpath, const struct stat * /*sb*/,
45 int tflag, struct FTW * /*ftwbuf*/)
48 RUNNER_ASSERT_ERRNO_MSG(!unlink(fpath), "Unable to unlink " << fpath << " file");
50 RUNNER_ASSERT_MSG(tflag == FTW_DP, "Visited file should not exist. Path: " << fpath);
54 void copyFile(const std::string &src, const std::string &dst)
56 int inFd = TEMP_FAILURE_RETRY(open(src.c_str(), O_RDONLY));
57 RUNNER_ASSERT_ERRNO_MSG(inFd > 0, "Opening " << src << " file failed");
58 FdUniquePtr inFdPtr(&inFd);
60 int outFd = TEMP_FAILURE_RETRY(creat(dst.c_str(), 0700));
61 RUNNER_ASSERT_ERRNO_MSG(outFd > 0, "Creating " << dst << " file failed");
62 FdUniquePtr outFdPtr(&outFd);
64 long int len = sysconf(_SC_GETPW_R_SIZE_MAX);
65 RUNNER_ASSERT_MSG(len != -1, "No suggested buflen");
67 char *buf = static_cast<char*>(malloc(buflen));
69 PwBufPtr pwBufPtr(buf);
71 struct passwd pwbuf, *pwbufp = nullptr;
72 int ret = TEMP_FAILURE_RETRY(getpwnam_r(cynaraUser.c_str(),
73 &pwbuf, buf, buflen, &pwbufp));
74 RUNNER_ASSERT_ERRNO_MSG(ret == 0, "getpwnam_r failed on " << cynaraUser << " user");
75 RUNNER_ASSERT_MSG(pwbufp, "User " << cynaraUser << " does not exist");
77 ret = fchown(outFd, pwbufp->pw_uid, pwbufp->pw_gid);
78 RUNNER_ASSERT_ERRNO_MSG(ret != -1, "fchown failed");
80 ret = smack_fsetlabel(outFd, cynaraLabel.c_str(), SMACK_LABEL_ACCESS);
81 RUNNER_ASSERT_MSG(ret == 0, "Setting smack label failed");
84 ret = fstat(inFd, &statSrc);
85 RUNNER_ASSERT_ERRNO_MSG(ret != -1, "fstat failed");
87 ret = sendfile(outFd, inFd, 0, statSrc.st_size);
88 RUNNER_ASSERT_ERRNO_MSG(ret != -1, "sendfile failed");
91 void copyDir(const std::string &source, const std::string &destination)
93 DIR *dirPtr = nullptr;
94 struct dirent *direntPtr;
96 RUNNER_ASSERT_ERRNO_MSG(dirPtr = opendir(source.c_str()),
97 "opening " << source << " dir failed");
98 DirPtr dirScopedPtr(dirPtr);
100 while((direntPtr = readdir(dirPtr)) != nullptr) {
101 if (!strcmp(direntPtr->d_name, ".")
102 || !strcmp(direntPtr->d_name, ".."))
104 std::string tempDest = destination + "/" + direntPtr->d_name;
105 std::string tempSrc = source + "/" + direntPtr->d_name;
106 copyFile(tempSrc, tempDest);
110 void clear(const std::string &dir)
112 int ret = nftw(dir.c_str(), removeContents, 2, FTW_DEPTH | FTW_PHYS);
114 RUNNER_ASSERT_ERRNO_MSG(errno == ENOENT, "nftw failed");
117 void removeDirIfExists(const std::string &dir)
119 RUNNER_ASSERT_ERRNO_MSG(!rmdir(dir.c_str()) || errno == ENOENT,
120 "Removing " << dir << " dir failed");
123 bool cynaraDbExists()
126 int ret = stat(cynaraDbDir.c_str(), &st);
127 if (ret == -1 && errno == ENOENT) {
129 } else if (ret == -1) {
130 RUNNER_ASSERT_ERRNO_MSG(false, "Cannot stat " << cynaraDbDir
131 << " not due to its nonexistence");
133 RUNNER_ASSERT_MSG(st.st_mode & S_IFDIR, cynaraDbDir << " is not a directory");
139 CynaraTestEnv::CynaraTestEnv(const char *dirName)
142 m_dir = tmpDir + dirName;
145 CynaraTestEnv::~CynaraTestEnv()
149 void CynaraTestEnv::save()
152 removeDirIfExists(m_dir);
154 DBusAccess dbusAccess("cynara.service");
157 m_dbPresent = cynaraDbExists();
159 RUNNER_ASSERT_ERRNO_MSG(!mkdir(m_dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO),
160 "Unable to make " << m_dir << " test directory");
161 copyDir(cynaraDbDir, m_dir);
167 void CynaraTestEnv::restore()
169 DBusAccess dbusAccess("cynara.service");
174 copyDir(m_dir, cynaraDbDir);
176 removeDirIfExists(cynaraDbDir);
181 removeDirIfExists(m_dir);