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 TEST_SMOKE_TESTS_COMMON_SMOKE_UTILS_H_
6 #define TEST_SMOKE_TESTS_COMMON_SMOKE_UTILS_H_
8 #include <pkgmgr-info.h>
11 #include <tzplatform_config.h>
13 #include <boost/filesystem/operations.hpp>
14 #include <boost/range/iterator_range.hpp>
15 #include <boost/format.hpp>
16 #include <boost/program_options.hpp>
17 #include <boost/system/error_code.hpp>
19 #include <gtest/gtest.h>
20 #include <gtest/gtest-death-test.h>
22 #include <manifest_parser/utils/version_number.h>
24 #include <common/utils/subprocess.h>
25 #include <common/utils/user_util.h>
26 #include <common/utils/file_util.h>
27 #include <common/utils/request.h>
28 #include <common/tzip_interface.h>
29 #include <common/installer/app_installer.h>
30 #include <common/utils/paths.h>
31 #include <common/utils/pkgmgr_query.h>
32 #include <common/recovery_file.h>
43 #define SIZEOFARRAY(ARR) \
44 sizeof(ARR) / sizeof(ARR[0]) \
46 #define EXTENDED_ASSERT_TRUE(expression) do { \
47 bool tmp = expression; \
48 EXPECT_TRUE(tmp) << #expression << " is not true"; \
53 #define EXTENDED_ASSERT_FALSE(expression) do { \
54 bool tmp = expression; \
55 EXPECT_FALSE(tmp) << #expression << " is not false"; \
60 #define EXTENDED_ASSERT_EQ(expression, value) do { \
61 auto ret = expression; \
62 EXPECT_EQ(ret, value) << #expression << " is not equal to " << #value; \
67 namespace smoke_test {
69 extern const bf::path kSmokePackagesDirectory;
70 extern const bf::path kSdkDirectory;
71 extern const uid_t kGlobalUserUid;
72 extern const uid_t kGlobalUserGid;
73 extern const char kLegacyExtImageDir[];
74 extern const std::string& kDefaultUserIdStr;
76 using App = std::pair<std::string, std::string>;
77 using Apps = std::vector<App>;
79 enum class RequestResult {
84 enum class StorageType {
90 class ScopedTzipInterface {
92 explicit ScopedTzipInterface(const std::string& pkgid, uid_t test_user)
93 : pkg_path_(boost::filesystem::path(
94 common_installer::GetRootAppPath(false, test_user)) / pkgid),
95 interface_(common_installer::GetMountLocation(pkg_path_)),
97 interface_.MountZip(common_installer::GetZipPackageLocation(pkg_path_,
103 interface_.UnmountZip();
108 ~ScopedTzipInterface() {
113 boost::filesystem::path pkg_path_;
114 common_installer::TzipInterface interface_;
118 class TestPkgmgrInstaller : public common_installer::PkgmgrInstallerInterface {
120 bool CreatePkgMgrInstaller(pkgmgr_installer** installer,
121 common_installer::InstallationMode* mode) {
122 *installer = pkgmgr_installer_offline_new();
125 *mode = common_installer::InstallationMode::ONLINE;
129 bool ShouldCreateSignal() const {
134 enum class PackageType {
141 uid_t uid = kGlobalUserUid;
142 gid_t gid = kGlobalUserGid;
145 struct TestParameters {
146 TestParameters(PackageType type, bool readonly) :
147 pkg_type(type), is_readonly(readonly) {}
148 TestParameters(const TestParameters& other) : pkg_type(other.pkg_type),
149 is_readonly(other.is_readonly), test_user{other.test_user} {}
150 PackageType pkg_type;
155 class FileInfoCollector {
157 using FileInfo = std::tuple<bf::path, bf::file_type, bf::perms,
158 std::string, std::string, std::string>;
160 FileInfoCollector(std::string pkgid, TestParameters params) :
161 pkgid_(pkgid), params_(params) {}
162 bool FileInfoToFile(const bf::path& path) const;
164 bool IsEqual(const FileInfoCollector& collector,
165 const std::vector<bf::path>* exception_list = nullptr) const;
166 bool LoadFromFile(const bf::path& path);
169 void AddPath(const bf::path& path);
170 bool CollectFileInfoRecursive();
171 bool GetFileListTraversal(const bf::path& cur);
172 std::string FileInfoToString(const FileInfo& file_info) const;
175 TestParameters params_;
176 std::vector<bf::path> root_paths_;
177 std::vector<FileInfo> FileInfos_;
180 struct PackageAttributes {
181 explicit PackageAttributes(common_installer::PkgQueryInterface pi)
182 : is_global(pi.IsGlobalPackage()), is_readonly(pi.IsReadonlyPackage()),
183 is_update(pi.IsUpdatedPackage()), is_preload(pi.IsPreloadPackage()),
184 is_system(pi.IsSystemPackage()), is_removable(pi.IsRemovablePackage()) {
187 bool operator==(const PackageAttributes& other) const {
188 return (is_global == other.is_global) &&
189 (is_readonly == other.is_readonly) &&
190 (is_update == other.is_update) &&
191 (is_preload == other.is_preload) &&
192 (is_system == other.is_system) &&
193 (is_removable == other.is_removable);
204 common_installer::RequestMode ParseRequestMode(int argc, char** argv);
206 bool TouchFile(const boost::filesystem::path& path);
208 void AddDataFiles(const std::string& pkgid, uid_t uid,
209 std::vector<bf::path>* result = nullptr);
211 bool AddTestUser(User* test_user);
213 bool DeleteTestUser();
215 void RemoveAllRecoveryFiles(const std::string& prefix, uid_t uid);
217 boost::filesystem::path FindRecoveryFile(const std::string& prefix, uid_t uid);
219 boost::filesystem::path GetPackageRoot(const std::string& pkgid, uid_t uid);
221 std::unique_ptr<common_installer::recovery::RecoveryFile> GetRecoverFileInfo(
222 const bf::path& recovery_file_path);
224 bool ValidateFileContentInPackage(const std::string& pkgid,
225 const std::string& relative,
226 const std::string& expected,
227 const TestParameters& params);
229 bool ValidatePackage(const std::string& pkgid, const Apps& apps,
230 const TestParameters& params);
232 bool ValidateDataFiles(const std::string& pkgid, uid_t uid);
234 bool ValidateExternalPackage(const std::string& pkgid, const Apps& apps,
235 const TestParameters& params);
236 bool ValidateExtendedPackage(const std::string& pkgid, const Apps& apps,
237 const TestParameters& params);
239 bool CheckPackageNonExistance(const std::string& pkgid,
240 const TestParameters& params);
242 bool CheckPackageReadonlyNonExistance(const std::string& pkgid,
243 const TestParameters& params);
245 bool CheckSharedDataExistance(const std::string& pkgid,
246 const TestParameters& params);
248 bool CheckSharedDataNonExistance(const std::string& pkgid,
249 const TestParameters& params);
251 bool TouchFile(const boost::filesystem::path& path);
253 class SmokeInstallerFactory {
255 using AppInstallerPtr = std::unique_ptr<common_installer::AppInstaller>;
256 virtual ~SmokeInstallerFactory() = default;
257 virtual AppInstallerPtr CreateInstaller(
258 int idx, common_installer::PkgMgrPtr pkgmgr) const = 0;
259 virtual AppInstallerPtr CreateFailExpectedInstaller(
260 int idx, common_installer::PkgMgrPtr pkgmgr, int fail_at = -1) const = 0;
263 class BackendInterface {
265 enum class SubProcessResult {
272 using CommandResult = common_installer::AppInstaller::Result;
273 using SmokeInstallerFactoryPtr = std::unique_ptr<SmokeInstallerFactory>;
274 explicit BackendInterface(std::string uid,
275 RequestResult mode = RequestResult::NORMAL)
276 : uid_str_(uid), mode_(mode) {}
277 explicit BackendInterface(SmokeInstallerFactoryPtr factory,
279 RequestResult mode = RequestResult::NORMAL)
280 : factory_(std::move(factory)), uid_str_(uid), mode_(mode) {}
281 virtual ~BackendInterface() = default;
283 void TestRollbackAfterEachStep(int argc, const char* argv[],
284 std::function<bool()> validator) const;
285 void CrashAfterEachStep(std::vector<std::string>* args,
286 std::function<bool(int iter)> validator,
287 PackageType type) const;
288 CommandResult Install(const std::vector<bf::path>& paths) const;
289 CommandResult InstallSuccess(const std::vector<bf::path>& paths) const;
290 CommandResult Install(const boost::filesystem::path& path) const;
291 CommandResult InstallPreload(const boost::filesystem::path& path) const;
292 CommandResult InstallWithStorage(const boost::filesystem::path& path,
293 StorageType type = StorageType::INTERNAL) const;
294 CommandResult InstallSuccess(const bf::path& path) const;
295 CommandResult InstallPreloadSuccess(
296 const boost::filesystem::path& path) const;
298 CommandResult Uninstall(const std::vector<std::string>& pkgids) const;
299 CommandResult Uninstall(const std::string& pkgid) const;
300 CommandResult UninstallPreload(const std::string& pkgid) const;
302 CommandResult EnablePackage(const std::string& pkgid) const;
303 CommandResult DisablePackage(const std::string& pkgid) const;
305 CommandResult MountInstall(const boost::filesystem::path& path) const;
306 CommandResult MountInstallSuccess(const bf::path& path) const;
307 CommandResult ManifestDirectInstall(const std::string& pkgid) const;
309 CommandResult MigrateLegacyExternalImage(const std::string& pkgid,
310 const boost::filesystem::path& path,
311 const boost::filesystem::path& legacy_path) const;
313 CommandResult RDSUpdate(const boost::filesystem::path& path,
314 const std::string& pkgid) const;
316 CommandResult Recover(const boost::filesystem::path& recovery_file) const;
318 SubProcessResult InstallWithSubprocess(const bf::path& path) const;
319 SubProcessResult MountInstallWithSubprocess(const bf::path& path) const;
320 SubProcessResult RecoverWithSubprocess(const bf::path& path) const;
321 SubProcessResult UninstallWithSubprocess(const std::string& pkgid) const;
322 SubProcessResult InstallPreloadWithSubprocess(
323 const boost::filesystem::path& path) const;
324 SubProcessResult InstallWithSubprocessAndKill(
325 const bf::path& path, useconds_t delay) const;
326 SubProcessResult MountInstallWithSubprocessAndKill(
327 const bf::path& path, useconds_t delay) const;
328 SubProcessResult UninstallWithSubprocessAndKill(
329 const std::string& pkgid, useconds_t delay) const;
330 SubProcessResult InstallPkgsWithSubprocess(
331 const std::vector<bf::path>& paths) const;
332 SubProcessResult MountInstallPkgsWithSubprocess(
333 const std::vector<bf::path>& paths) const;
334 SubProcessResult RecoverPkgsWithSubprocess(
335 const std::vector<bf::path>& paths) const;
336 SubProcessResult UninstallPkgsWithSubprocess(
337 const std::vector<std::string>& pkgids) const;
338 SubProcessResult InstallPkgsWithSubprocessAndKill(
339 const std::vector<bf::path>& paths, useconds_t delay) const;
340 SubProcessResult MountInstallPkgsWithSubprocessAndKill(
341 const std::vector<bf::path>& paths, useconds_t delay) const;
344 CommandResult CallBackend(int argc, const char* argv[]) const;
345 CommandResult CallBackendWithRunner(int argc, const char* argv[]) const;
346 using AppQueryInterfacePtr =
347 std::shared_ptr<common_installer::AppQueryInterface>;
348 using AppInstallerPtr = std::unique_ptr<common_installer::AppInstaller>;
349 SmokeInstallerFactoryPtr factory_;
350 std::string uid_str_;
354 CommandResult RunInstallerWithPkgrmgr(
355 common_installer::PkgMgrPtr pkgmgr) const;
356 virtual AppQueryInterfacePtr CreateQueryInterface() const = 0;
357 virtual AppInstallerPtr CreateInstaller(
358 common_installer::PkgMgrPtr pkgmgr) const = 0;
359 virtual AppInstallerPtr CreateFailExpectedInstaller(
360 common_installer::PkgMgrPtr pkgmgr, int fail_at = -1) const = 0;
361 CommandResult RunInstallersWithPkgmgr(
362 common_installer::PkgMgrPtr pkgmgr) const;
363 SubProcessResult RunSubprocess(std::vector<std::string> args) const;
364 SubProcessResult RunSubprocessAndKill(std::vector<std::string> args,
365 useconds_t delay) const;
366 virtual common_installer::Subprocess CreateSubprocess() const {
367 return common_installer::Subprocess("");
371 bool CheckAvailableExternalPath();
373 bool CheckAvailableExtendedPath();
375 bool BackupPathCopyAndRemove(const boost::filesystem::path& path);
377 bool BackupPath(const boost::filesystem::path& path);
379 void CreateDatabase();
381 bool RestorePathCopyAndRemove(const boost::filesystem::path& path);
383 bool RestorePath(const boost::filesystem::path& path);
385 std::vector<boost::filesystem::path> SetupBackupDirectories(uid_t test_uid);
387 void UninstallAllAppsInDirectory(boost::filesystem::path dir, bool is_preload,
388 BackendInterface* backend);
390 void UninstallAllSmokeApps(common_installer::RequestMode request_mode,
391 uid_t test_uid, BackendInterface* backend);
393 int GetAppInstalledTime(const char* appid, uid_t uid);
395 enum class CrashStepType {
400 class StepCrash : public common_installer::Step {
404 explicit StepCrash(common_installer::InstallerContext* context,
406 : common_installer::Step::Step(context), type_(type) {}
408 common_installer::Step::Status process() override {
409 if (type_ == CrashStepType::PROCESS)
413 common_installer::Step::Status clean() override {
414 if (type_ == CrashStepType::CLEAN)
418 common_installer::Step::Status undo() override {
419 return common_installer::Step::Status::OK;
421 common_installer::Step::Status precheck() override {
422 return common_installer::Step::Status::OK;
431 bool CompareFileInfo(const std::string& pkgid, const TestParameters& params,
432 const bf::path& file);
434 } // namespace smoke_test
436 #endif // TEST_SMOKE_TESTS_COMMON_SMOKE_UTILS_H_