94f75690085fc570f7c1673740fa7e7e53cae882
[platform/core/appfw/app-installers.git] / test / smoke_tests / common / smoke_utils.h
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.
4
5 #ifndef TEST_SMOKE_TESTS_COMMON_SMOKE_UTILS_H_
6 #define TEST_SMOKE_TESTS_COMMON_SMOKE_UTILS_H_
7
8 #include <pkgmgr-info.h>
9 #include <signal.h>
10 #include <unistd.h>
11 #include <tzplatform_config.h>
12
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>
18
19 #include <gtest/gtest.h>
20 #include <gtest/gtest-death-test.h>
21
22 #include <manifest_parser/utils/version_number.h>
23
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>
33
34 #include <array>
35 #include <cstdio>
36 #include <cstdlib>
37 #include <memory>
38 #include <regex>
39 #include <string>
40 #include <vector>
41 #include <utility>
42
43 #define SIZEOFARRAY(ARR)                                                       \
44   sizeof(ARR) / sizeof(ARR[0])                                                 \
45
46 #define EXTENDED_ASSERT_TRUE(expression) do {                                  \
47     bool tmp = expression;                                                     \
48     EXPECT_TRUE(tmp) << #expression << " is not true";                         \
49     if (!tmp)                                                                  \
50         return false;                                                          \
51 } while (0);
52
53 #define EXTENDED_ASSERT_FALSE(expression) do {                                 \
54     bool tmp = expression;                                                     \
55     EXPECT_FALSE(tmp) << #expression << " is not false";                       \
56     if (tmp)                                                                   \
57         return false;                                                          \
58 } while (0);
59
60 #define EXTENDED_ASSERT_EQ(expression, value) do {                             \
61     auto ret = expression;                                                     \
62     EXPECT_EQ(ret, value) << #expression << " is not equal to " << #value;     \
63     if (ret != value)                                                          \
64         return false;                                                          \
65 } while (0);
66
67 namespace smoke_test {
68
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;
75
76 using App = std::pair<std::string, std::string>;
77 using Apps = std::vector<App>;
78
79 enum class RequestResult {
80   NORMAL,
81   FAIL
82 };
83
84 enum class StorageType {
85   INTERNAL,
86   EXTERNAL,
87   EXTENDED
88 };
89
90 class ScopedTzipInterface {
91  public:
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_)),
96         mounted_(true) {
97     interface_.MountZip(common_installer::GetZipPackageLocation(pkg_path_,
98                                                                 pkgid));
99   }
100
101   void Release() {
102     if (mounted_) {
103       interface_.UnmountZip();
104       mounted_ = false;
105     }
106   }
107
108   ~ScopedTzipInterface() {
109     Release();
110   }
111
112  private:
113   boost::filesystem::path pkg_path_;
114   common_installer::TzipInterface interface_;
115   bool mounted_;
116 };
117
118 class TestPkgmgrInstaller : public common_installer::PkgmgrInstallerInterface {
119  public:
120   bool CreatePkgMgrInstaller(pkgmgr_installer** installer,
121                              common_installer::InstallationMode* mode) {
122     *installer = pkgmgr_installer_offline_new();
123     if (!*installer)
124       return false;
125     *mode = common_installer::InstallationMode::ONLINE;
126     return true;
127   }
128
129   bool ShouldCreateSignal() const {
130     return false;
131   }
132 };
133
134 enum class PackageType {
135   TPK,
136   WGT,
137   HYBRID
138 };
139
140 struct User {
141   uid_t uid = kGlobalUserUid;
142   gid_t gid = kGlobalUserGid;
143 };
144
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;
151   bool is_readonly;
152   User test_user;
153 };
154
155 struct PackageAttributes {
156   explicit PackageAttributes(common_installer::PkgQueryInterface pi)
157       : is_global(pi.IsGlobalPackage()), is_readonly(pi.IsReadonlyPackage()),
158         is_update(pi.IsUpdatedPackage()), is_preload(pi.IsPreloadPackage()),
159         is_system(pi.IsSystemPackage()), is_removable(pi.IsRemovablePackage()) {
160   }
161
162   bool operator==(const PackageAttributes& other) const {
163     return (is_global == other.is_global) &&
164            (is_readonly == other.is_readonly) &&
165            (is_update == other.is_update) &&
166            (is_preload == other.is_preload) &&
167            (is_system == other.is_system) &&
168            (is_removable == other.is_removable);
169   }
170
171   bool is_global;
172   bool is_readonly;
173   bool is_update;
174   bool is_preload;
175   bool is_system;
176   bool is_removable;
177 };
178
179 common_installer::RequestMode ParseRequestMode(int argc,  char** argv);
180
181 bool TouchFile(const boost::filesystem::path& path);
182
183 void AddDataFiles(const std::string& pkgid, uid_t uid);
184
185 bool AddTestUser(User* test_user);
186
187 bool DeleteTestUser();
188
189 void RemoveAllRecoveryFiles(const std::string& prefix, uid_t uid);
190
191 boost::filesystem::path FindRecoveryFile(const std::string& prefix, uid_t uid);
192
193 boost::filesystem::path GetPackageRoot(const std::string& pkgid, uid_t uid);
194
195 std::unique_ptr<common_installer::recovery::RecoveryFile> GetRecoverFileInfo(
196     const bf::path& recovery_file_path);
197
198 bool ValidateFileContentInPackage(const std::string& pkgid,
199                                   const std::string& relative,
200                                   const std::string& expected,
201                                   const TestParameters& params);
202
203 bool ValidatePackage(const std::string& pkgid, const Apps& apps,
204     const TestParameters& params);
205
206 bool ValidateDataFiles(const std::string& pkgid, uid_t uid);
207
208 bool ValidateExternalPackage(const std::string& pkgid, const Apps& apps,
209     const TestParameters& params);
210 bool ValidateExtendedPackage(const std::string& pkgid, const Apps& apps,
211     const TestParameters& params);
212
213 bool CheckPackageNonExistance(const std::string& pkgid,
214                               const TestParameters& params);
215
216 bool CheckPackageReadonlyNonExistance(const std::string& pkgid,
217                                       const TestParameters& params);
218
219 bool CheckSharedDataExistance(const std::string& pkgid,
220                               const TestParameters& params);
221
222 bool CheckSharedDataNonExistance(const std::string& pkgid,
223                                 const TestParameters& params);
224
225 bool TouchFile(const boost::filesystem::path& path);
226
227 class SmokeInstallerFactory {
228  public:
229   using AppInstallerPtr = std::unique_ptr<common_installer::AppInstaller>;
230   virtual ~SmokeInstallerFactory() = default;
231   virtual AppInstallerPtr CreateInstaller(
232       int idx, common_installer::PkgMgrPtr pkgmgr) const = 0;
233   virtual AppInstallerPtr CreateFailExpectedInstaller(
234       int idx, common_installer::PkgMgrPtr pkgmgr, int fail_at = -1) const = 0;
235 };
236
237 class BackendInterface {
238  public:
239   enum class SubProcessResult {
240     SUCCESS,
241     FAIL,
242     KILLED,
243     UnKnown
244   };
245
246   using CommandResult = common_installer::AppInstaller::Result;
247   using SmokeInstallerFactoryPtr = std::unique_ptr<SmokeInstallerFactory>;
248   explicit BackendInterface(std::string uid,
249       RequestResult mode = RequestResult::NORMAL)
250       : uid_str_(uid), mode_(mode) {}
251   explicit BackendInterface(SmokeInstallerFactoryPtr factory,
252       std::string uid,
253       RequestResult mode = RequestResult::NORMAL)
254       : factory_(std::move(factory)), uid_str_(uid), mode_(mode) {}
255   virtual ~BackendInterface() = default;
256
257   void TestRollbackAfterEachStep(int argc, const char* argv[],
258                                  std::function<bool()> validator) const;
259   void CrashAfterEachStep(std::vector<std::string>* args,
260                           std::function<bool(int iter)> validator,
261                           PackageType type) const;
262   CommandResult Install(const std::vector<bf::path>& paths) const;
263   CommandResult InstallSuccess(const std::vector<bf::path>& paths) const;
264   CommandResult Install(const boost::filesystem::path& path) const;
265   CommandResult InstallPreload(const boost::filesystem::path& path) const;
266   CommandResult InstallWithStorage(const boost::filesystem::path& path,
267       StorageType type = StorageType::INTERNAL) const;
268   CommandResult InstallSuccess(const bf::path& path) const;
269   CommandResult InstallPreloadSuccess(
270       const boost::filesystem::path& path) const;
271
272   CommandResult Uninstall(const std::vector<std::string>& pkgids) const;
273   CommandResult Uninstall(const std::string& pkgid) const;
274   CommandResult UninstallPreload(const std::string& pkgid) const;
275
276   CommandResult EnablePackage(const std::string& pkgid) const;
277   CommandResult DisablePackage(const std::string& pkgid) const;
278
279   CommandResult MountInstall(const boost::filesystem::path& path) const;
280   CommandResult MountInstallSuccess(const bf::path& path) const;
281   CommandResult ManifestDirectInstall(const std::string& pkgid) const;
282
283   CommandResult MigrateLegacyExternalImage(const std::string& pkgid,
284       const boost::filesystem::path& path,
285       const boost::filesystem::path& legacy_path) const;
286
287   CommandResult RDSUpdate(const boost::filesystem::path& path,
288       const std::string& pkgid) const;
289
290   CommandResult Recover(const boost::filesystem::path& recovery_file) const;
291
292   SubProcessResult InstallWithSubprocess(const bf::path& path) const;
293   SubProcessResult MountInstallWithSubprocess(const bf::path& path) const;
294   SubProcessResult RecoverWithSubprocess(const bf::path& path) const;
295   SubProcessResult UninstallWithSubprocess(const std::string& pkgid) const;
296   SubProcessResult InstallPreloadWithSubprocess(
297       const boost::filesystem::path& path) const;
298   SubProcessResult InstallWithSubprocessAndKill(
299       const bf::path& path, useconds_t delay) const;
300   SubProcessResult MountInstallWithSubprocessAndKill(
301       const bf::path& path, useconds_t delay) const;
302   SubProcessResult UninstallWithSubprocessAndKill(
303       const std::string& pkgid, useconds_t delay) const;
304   SubProcessResult InstallPkgsWithSubprocess(
305       const std::vector<bf::path>& paths) const;
306   SubProcessResult MountInstallPkgsWithSubprocess(
307       const std::vector<bf::path>& paths) const;
308   SubProcessResult RecoverPkgsWithSubprocess(
309       const std::vector<bf::path>& paths) const;
310   SubProcessResult UninstallPkgsWithSubprocess(
311       const std::vector<std::string>& pkgids) const;
312   SubProcessResult InstallPkgsWithSubprocessAndKill(
313       const std::vector<bf::path>& paths, useconds_t delay) const;
314   SubProcessResult MountInstallPkgsWithSubprocessAndKill(
315       const std::vector<bf::path>& paths, useconds_t delay) const;
316
317  protected:
318   CommandResult CallBackend(int argc, const char* argv[]) const;
319   CommandResult CallBackendWithRunner(int argc, const char* argv[]) const;
320   using AppQueryInterfacePtr =
321       std::shared_ptr<common_installer::AppQueryInterface>;
322   using AppInstallerPtr = std::unique_ptr<common_installer::AppInstaller>;
323   SmokeInstallerFactoryPtr factory_;
324   std::string uid_str_;
325   RequestResult mode_;
326
327  protected:
328   CommandResult RunInstallerWithPkgrmgr(
329       common_installer::PkgMgrPtr pkgmgr) const;
330   virtual AppQueryInterfacePtr CreateQueryInterface() const = 0;
331   virtual AppInstallerPtr CreateInstaller(
332       common_installer::PkgMgrPtr pkgmgr) const = 0;
333   virtual AppInstallerPtr CreateFailExpectedInstaller(
334       common_installer::PkgMgrPtr pkgmgr, int fail_at = -1) const = 0;
335   CommandResult RunInstallersWithPkgmgr(
336       common_installer::PkgMgrPtr pkgmgr) const;
337   SubProcessResult RunSubprocess(std::vector<std::string> args) const;
338   SubProcessResult RunSubprocessAndKill(std::vector<std::string> args,
339       useconds_t delay) const;
340   virtual common_installer::Subprocess CreateSubprocess() const {
341     return common_installer::Subprocess("");
342   }
343 };
344
345 bool CheckAvailableExternalPath();
346
347 bool CheckAvailableExtendedPath();
348
349 bool BackupPathCopyAndRemove(const boost::filesystem::path& path);
350
351 bool BackupPath(const boost::filesystem::path& path);
352
353 void CreateDatabase();
354
355 bool RestorePathCopyAndRemove(const boost::filesystem::path& path);
356
357 bool RestorePath(const boost::filesystem::path& path);
358
359 std::vector<boost::filesystem::path> SetupBackupDirectories(uid_t test_uid);
360
361 void UninstallAllAppsInDirectory(boost::filesystem::path dir, bool is_preload,
362     BackendInterface* backend);
363
364 void UninstallAllSmokeApps(common_installer::RequestMode request_mode,
365     uid_t test_uid, BackendInterface* backend);
366
367 int GetAppInstalledTime(const char* appid, uid_t uid);
368
369 enum class CrashStepType {
370   PROCESS,
371   CLEAN
372 };
373
374 class StepCrash : public common_installer::Step {
375  public:
376   using Step::Step;
377
378   explicit StepCrash(common_installer::InstallerContext* context,
379       CrashStepType type)
380       : common_installer::Step::Step(context), type_(type) {}
381
382   common_installer::Step::Status process() override {
383     if (type_ == CrashStepType::PROCESS)
384       raise(SIGKILL);
385     return Status::OK;
386   }
387   common_installer::Step::Status clean() override {
388     if (type_ == CrashStepType::CLEAN)
389       raise(SIGKILL);
390     return Status::OK;
391   }
392   common_installer::Step::Status undo() override {
393     return common_installer::Step::Status::OK;
394   }
395   common_installer::Step::Status precheck() override {
396     return common_installer::Step::Status::OK;
397   }
398
399   STEP_NAME(Crash)
400
401  private:
402   CrashStepType type_;
403 };
404
405 }  // namespace smoke_test
406
407 #endif  // TEST_SMOKE_TESTS_COMMON_SMOKE_UTILS_H_