1 // Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
5 #ifndef UNIT_TESTS_COMMON_SMOKE_UTILS_H_
6 #define UNIT_TESTS_COMMON_SMOKE_UTILS_H_
8 #include <pkgmgr-info.h>
11 #include <tzplatform_config.h>
13 #include <vconf-internal-keys.h>
15 #include <boost/filesystem/operations.hpp>
16 #include <boost/range/iterator_range.hpp>
17 #include <boost/format.hpp>
18 #include <boost/program_options.hpp>
19 #include <boost/system/error_code.hpp>
21 #include <gtest/gtest.h>
22 #include <gtest/gtest-death-test.h>
24 #include <manifest_parser/utils/version_number.h>
26 #include <common/utils/subprocess.h>
27 #include <common/utils/user_util.h>
28 #include <common/utils/file_util.h>
29 #include <common/request.h>
30 #include <common/tzip_interface.h>
31 #include <common/app_installer.h>
32 #include <common/paths.h>
33 #include <common/pkgmgr_query.h>
34 #include <common/recovery_file.h>
45 #define SIZEOFARRAY(ARR) \
46 sizeof(ARR) / sizeof(ARR[0]) \
48 #define EXTENDED_ASSERT_TRUE(expression) do { \
49 bool tmp = expression; \
50 EXPECT_TRUE(tmp) << #expression << " is not true"; \
55 #define EXTENDED_ASSERT_FALSE(expression) do { \
56 bool tmp = expression; \
57 EXPECT_FALSE(tmp) << #expression << " is not false"; \
62 #define EXTENDED_ASSERT_EQ(expression, value) do { \
63 auto ret = expression; \
64 EXPECT_EQ(ret, value) << #expression << " is not equal to " << #value; \
69 namespace smoke_test {
71 extern const bf::path kSmokePackagesDirectory;
72 extern const bf::path kSdkDirectory;
73 extern const uid_t kGlobalUserUid;
74 extern const uid_t kGlobalUserGid;
75 extern const char kLegacyExtImageDir[];
76 extern const std::string& kDefaultUserIdStr;
78 using App = std::pair<std::string, std::string>;
79 using Apps = std::vector<App>;
81 enum class RequestResult {
86 enum class StorageType {
92 class ScopedTzipInterface {
94 explicit ScopedTzipInterface(const std::string& pkgid, uid_t test_user)
95 : pkg_path_(boost::filesystem::path(
96 common_installer::GetRootAppPath(false, test_user)) / pkgid),
97 interface_(common_installer::GetMountLocation(pkg_path_)),
99 interface_.MountZip(common_installer::GetZipPackageLocation(pkg_path_,
105 interface_.UnmountZip();
110 ~ScopedTzipInterface() {
115 boost::filesystem::path pkg_path_;
116 common_installer::TzipInterface interface_;
120 class TestPkgmgrInstaller : public common_installer::PkgmgrInstallerInterface {
122 bool CreatePkgMgrInstaller(pkgmgr_installer** installer,
123 common_installer::InstallationMode* mode) {
124 *installer = pkgmgr_installer_offline_new();
127 *mode = common_installer::InstallationMode::ONLINE;
131 bool ShouldCreateSignal() const {
136 enum class PackageType {
143 uid_t uid = kGlobalUserUid;
144 gid_t gid = kGlobalUserGid;
147 struct TestParameters {
148 TestParameters(PackageType type, bool readonly) :
149 pkg_type(type), is_readonly(readonly) {}
150 TestParameters(const TestParameters& other) : pkg_type(other.pkg_type),
151 is_readonly(other.is_readonly), test_user{other.test_user} {}
152 PackageType pkg_type;
157 struct PackageAttributes {
158 explicit PackageAttributes(common_installer::PkgQueryInterface pi)
159 : is_global(pi.IsGlobalPackage()), is_readonly(pi.IsReadonlyPackage()),
160 is_update(pi.IsUpdatedPackage()), is_preload(pi.IsPreloadPackage()),
161 is_system(pi.IsSystemPackage()), is_removable(pi.IsRemovablePackage()) {
164 bool operator==(const PackageAttributes& other) const {
165 return (is_global == other.is_global) &&
166 (is_readonly == other.is_readonly) &&
167 (is_update == other.is_update) &&
168 (is_preload == other.is_preload) &&
169 (is_system == other.is_system) &&
170 (is_removable == other.is_removable);
181 common_installer::RequestMode ParseRequestMode(int argc, char** argv);
183 bool TouchFile(const boost::filesystem::path& path);
185 void AddDataFiles(const std::string& pkgid, uid_t uid);
187 bool AddTestUser(User* test_user);
189 bool DeleteTestUser();
191 void RemoveAllRecoveryFiles(const std::string& prefix, uid_t uid);
193 boost::filesystem::path FindRecoveryFile(const std::string& prefix, uid_t uid);
195 boost::filesystem::path GetPackageRoot(const std::string& pkgid, uid_t uid);
197 std::unique_ptr<common_installer::recovery::RecoveryFile> GetRecoverFileInfo(
198 const bf::path& recovery_file_path);
200 bool ValidateFileContentInPackage(const std::string& pkgid,
201 const std::string& relative,
202 const std::string& expected,
203 const TestParameters& params);
205 bool ValidatePackage(const std::string& pkgid, const Apps& apps,
206 const TestParameters& params);
208 bool ValidateDataFiles(const std::string& pkgid, uid_t uid);
210 bool ValidateExternalPackage(const std::string& pkgid, const Apps& apps,
211 const TestParameters& params);
212 bool ValidateExtendedPackage(const std::string& pkgid, const Apps& apps,
213 const TestParameters& params);
215 bool CheckPackageNonExistance(const std::string& pkgid,
216 const TestParameters& params);
218 bool CheckPackageReadonlyNonExistance(const std::string& pkgid,
219 const TestParameters& params);
221 bool CheckSharedDataExistance(const std::string& pkgid,
222 const TestParameters& params);
224 bool CheckSharedDataNonExistance(const std::string& pkgid,
225 const TestParameters& params);
227 bool TouchFile(const boost::filesystem::path& path);
229 class BackendInterface {
231 using CommandResult = common_installer::AppInstaller::Result;
232 explicit BackendInterface(std::string uid,
233 RequestResult mode = RequestResult::NORMAL)
234 : uid_str_(uid), mode_(mode) {}
235 virtual ~BackendInterface() {}
237 void TestRollbackAfterEachStep(int argc, const char* argv[],
238 std::function<bool()> validator) const;
239 void CrashAfterEachStep(std::vector<std::string>* args,
240 std::function<bool(int iter)> validator,
241 PackageType type) const;
242 CommandResult Install(const boost::filesystem::path& path) const;
243 CommandResult InstallPreload(const boost::filesystem::path& path) const;
244 CommandResult InstallWithStorage(const boost::filesystem::path& path,
245 StorageType type = StorageType::INTERNAL) const;
246 CommandResult InstallSuccess(const bf::path& path) const;
247 CommandResult InstallPreloadSuccess(
248 const boost::filesystem::path& path) const;
250 CommandResult Uninstall(const std::string& pkgid) const;
251 CommandResult UninstallPreload(const std::string& pkgid) const;
253 CommandResult EnablePackage(const std::string& pkgid) const;
254 CommandResult DisablePackage(const std::string& pkgid) const;
256 CommandResult MountInstall(const boost::filesystem::path& path) const;
257 CommandResult MountInstallSuccess(const bf::path& path) const;
258 CommandResult ManifestDirectInstall(const std::string& pkgid) const;
260 CommandResult MigrateLegacyExternalImage(const std::string& pkgid,
261 const boost::filesystem::path& path,
262 const boost::filesystem::path& legacy_path) const;
264 CommandResult RDSUpdate(const boost::filesystem::path& path,
265 const std::string& pkgid) const;
267 CommandResult Recover(const boost::filesystem::path& recovery_file) const;
270 CommandResult CallBackend(int argc, const char* argv[]) const;
271 using AppQueryInterfacePtr =
272 std::unique_ptr<common_installer::AppQueryInterface>;
273 using AppInstallerPtr = std::unique_ptr<common_installer::AppInstaller>;
274 std::string uid_str_;
278 CommandResult RunInstallerWithPkgrmgr(
279 common_installer::PkgMgrPtr pkgmgr) const;
280 virtual AppQueryInterfacePtr CreateQueryInterface() const = 0;
281 virtual AppInstallerPtr CreateInstaller(
282 common_installer::PkgMgrPtr pkgmgr) const = 0;
283 virtual AppInstallerPtr CreateFailExpectedInstaller(
284 common_installer::PkgMgrPtr pkgmgr, int fail_at = -1) const = 0;
287 class SmokeTestHelperRunner {
296 Result InstallWithSubprocess(const bf::path& path, uid_t uid) const;
297 Result MountInstallWithSubprocess(const bf::path& path, uid_t uid) const;
298 Result RecoveryWithSubprocess(const bf::path& path, uid_t uid) const;
299 Result UninstallWithSubprocess(const std::string& pkgid, uid_t uid) const;
300 Result InstallWithSubprocessAndKill(
301 const bf::path& path, uid_t uid, useconds_t delay) const;
302 Result MountInstallWithSubprocessAndKill(
303 const bf::path& path, uid_t uid, useconds_t delay) const;
304 Result UninstallWithSubprocessAndKill(
305 const std::string& pkgid, uid_t uid, useconds_t delay) const;
308 Result RunSubprocess(std::vector<std::string> args) const;
309 Result RunSubprocessAndKill(std::vector<std::string> args,
310 useconds_t delay) const;
311 virtual common_installer::Subprocess CreateSubprocess() const = 0;
314 bool CheckAvailableExternalPath();
316 bool CheckAvailableExtendedPath();
318 bool BackupPathCopyAndRemove(const boost::filesystem::path& path);
320 bool BackupPath(const boost::filesystem::path& path);
322 bool RestorePathCopyAndRemove(const boost::filesystem::path& path);
324 bool RestorePath(const boost::filesystem::path& path);
326 std::vector<boost::filesystem::path> SetupBackupDirectories(uid_t test_uid);
328 void UninstallAllAppsInDirectory(boost::filesystem::path dir, bool is_preload,
329 BackendInterface* backend);
331 void UninstallAllSmokeApps(common_installer::RequestMode request_mode,
332 uid_t test_uid, BackendInterface* backend);
334 int GetAppInstalledTime(const char* appid, uid_t uid);
336 } // namespace smoke_test
338 #endif // UNIT_TESTS_COMMON_SMOKE_UTILS_H_