Modify to generate SIGKILL instead of SIGSEGV in StepCrash
[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   using CommandResult = common_installer::AppInstaller::Result;
240   using SmokeInstallerFactoryPtr = std::unique_ptr<SmokeInstallerFactory>;
241   explicit BackendInterface(std::string uid,
242       RequestResult mode = RequestResult::NORMAL)
243       : uid_str_(uid), mode_(mode) {}
244   explicit BackendInterface(SmokeInstallerFactoryPtr factory,
245       std::string uid,
246       RequestResult mode = RequestResult::NORMAL)
247       : factory_(std::move(factory)), uid_str_(uid), mode_(mode) {}
248   virtual ~BackendInterface() = default;
249
250   void TestRollbackAfterEachStep(int argc, const char* argv[],
251                                  std::function<bool()> validator) const;
252   void CrashAfterEachStep(std::vector<std::string>* args,
253                           std::function<bool(int iter)> validator,
254                           PackageType type) const;
255   CommandResult Install(const std::vector<bf::path>& paths) const;
256   CommandResult InstallSuccess(const std::vector<bf::path>& paths) const;
257   CommandResult Install(const boost::filesystem::path& path) const;
258   CommandResult InstallPreload(const boost::filesystem::path& path) const;
259   CommandResult InstallWithStorage(const boost::filesystem::path& path,
260       StorageType type = StorageType::INTERNAL) const;
261   CommandResult InstallSuccess(const bf::path& path) const;
262   CommandResult InstallPreloadSuccess(
263       const boost::filesystem::path& path) const;
264
265   CommandResult Uninstall(const std::vector<std::string>& pkgids) const;
266   CommandResult Uninstall(const std::string& pkgid) const;
267   CommandResult UninstallPreload(const std::string& pkgid) const;
268
269   CommandResult EnablePackage(const std::string& pkgid) const;
270   CommandResult DisablePackage(const std::string& pkgid) const;
271
272   CommandResult MountInstall(const boost::filesystem::path& path) const;
273   CommandResult MountInstallSuccess(const bf::path& path) const;
274   CommandResult ManifestDirectInstall(const std::string& pkgid) const;
275
276   CommandResult MigrateLegacyExternalImage(const std::string& pkgid,
277       const boost::filesystem::path& path,
278       const boost::filesystem::path& legacy_path) const;
279
280   CommandResult RDSUpdate(const boost::filesystem::path& path,
281       const std::string& pkgid) const;
282
283   CommandResult Recover(const boost::filesystem::path& recovery_file) const;
284
285  protected:
286   CommandResult CallBackend(int argc, const char* argv[]) const;
287   CommandResult CallBackendWithRunner(int argc, const char* argv[]) const;
288   using AppQueryInterfacePtr =
289       std::shared_ptr<common_installer::AppQueryInterface>;
290   using AppInstallerPtr = std::unique_ptr<common_installer::AppInstaller>;
291   SmokeInstallerFactoryPtr factory_;
292   std::string uid_str_;
293   RequestResult mode_;
294
295  private:
296   CommandResult RunInstallerWithPkgrmgr(
297       common_installer::PkgMgrPtr pkgmgr) const;
298   virtual AppQueryInterfacePtr CreateQueryInterface() const = 0;
299   virtual AppInstallerPtr CreateInstaller(
300       common_installer::PkgMgrPtr pkgmgr) const = 0;
301   virtual AppInstallerPtr CreateFailExpectedInstaller(
302       common_installer::PkgMgrPtr pkgmgr, int fail_at = -1) const = 0;
303   CommandResult RunInstallersWithPkgmgr(
304       common_installer::PkgMgrPtr pkgmgr) const;
305 };
306
307 class SmokeTestHelperRunner {
308  public:
309   enum class Result {
310     SUCCESS,
311     FAIL,
312     KILLED,
313     UnKnown
314   };
315
316   virtual ~SmokeTestHelperRunner() = default;
317   Result InstallWithSubprocess(const bf::path& path, uid_t uid) const;
318   Result MountInstallWithSubprocess(const bf::path& path, uid_t uid) const;
319   Result RecoveryWithSubprocess(const bf::path& path, uid_t uid) const;
320   Result UninstallWithSubprocess(const std::string& pkgid, uid_t uid) const;
321   Result InstallWithSubprocessAndKill(
322       const bf::path& path, uid_t uid, useconds_t delay) const;
323   Result MountInstallWithSubprocessAndKill(
324       const bf::path& path, uid_t uid, useconds_t delay) const;
325   Result UninstallWithSubprocessAndKill(
326       const std::string& pkgid, uid_t uid, useconds_t delay) const;
327   Result InstallPkgsWithSubprocess(
328       const std::vector<bf::path>& paths, uid_t uid) const;
329   Result MountInstallPkgsWithSubprocess(
330       const std::vector<bf::path>& paths, uid_t uid) const;
331   Result RecoveryPkgsWithSubprocess(
332       const std::vector<bf::path>& paths, uid_t uid) const;
333   Result UninstallPkgsWithSubprocess(
334       const std::vector<std::string>& pkgids, uid_t uid) const;
335   Result InstallPkgsWithSubprocessAndKill(
336       const std::vector<bf::path>& paths, uid_t uid, useconds_t delay) const;
337   Result MountInstallPkgsWithSubprocessAndKill(
338       const std::vector<bf::path>& paths, uid_t uid, useconds_t delay) const;
339
340  private:
341   Result RunSubprocess(std::vector<std::string> args) const;
342   Result RunSubprocessAndKill(std::vector<std::string> args,
343       useconds_t delay) const;
344   virtual common_installer::Subprocess CreateSubprocess() const = 0;
345 };
346
347 bool CheckAvailableExternalPath();
348
349 bool CheckAvailableExtendedPath();
350
351 bool BackupPathCopyAndRemove(const boost::filesystem::path& path);
352
353 bool BackupPath(const boost::filesystem::path& path);
354
355 void CreateDatabase();
356
357 bool RestorePathCopyAndRemove(const boost::filesystem::path& path);
358
359 bool RestorePath(const boost::filesystem::path& path);
360
361 std::vector<boost::filesystem::path> SetupBackupDirectories(uid_t test_uid);
362
363 void UninstallAllAppsInDirectory(boost::filesystem::path dir, bool is_preload,
364     BackendInterface* backend);
365
366 void UninstallAllSmokeApps(common_installer::RequestMode request_mode,
367     uid_t test_uid, BackendInterface* backend);
368
369 int GetAppInstalledTime(const char* appid, uid_t uid);
370
371 enum class CrashStepType {
372   PROCESS,
373   CLEAN
374 };
375
376 class StepCrash : public common_installer::Step {
377  public:
378   using Step::Step;
379
380   explicit StepCrash(common_installer::InstallerContext* context,
381       CrashStepType type)
382       : common_installer::Step::Step(context), type_(type) {}
383
384   common_installer::Step::Status process() override {
385     if (type_ == CrashStepType::PROCESS)
386       raise(SIGKILL);
387     return Status::OK;
388   }
389   common_installer::Step::Status clean() override {
390     if (type_ == CrashStepType::CLEAN)
391       raise(SIGKILL);
392     return Status::OK;
393   }
394   common_installer::Step::Status undo() override {
395     return common_installer::Step::Status::OK;
396   }
397   common_installer::Step::Status precheck() override {
398     return common_installer::Step::Status::OK;
399   }
400
401   STEP_NAME(Crash)
402
403  private:
404   CrashStepType type_;
405 };
406
407 }  // namespace smoke_test
408
409 #endif  // TEST_SMOKE_TESTS_COMMON_SMOKE_UTILS_H_