64a2d5fc1518aa84fbc96deb656c2ae2ff024dbf
[platform/core/appfw/app-installers.git] / src / unit_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 UNIT_TESTS_COMMON_SMOKE_UTILS_H_
6 #define UNIT_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 #include <vconf.h>
13 #include <vconf-internal-keys.h>
14
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>
20
21 #include <gtest/gtest.h>
22 #include <gtest/gtest-death-test.h>
23
24 #include <manifest_parser/utils/version_number.h>
25
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>
35
36 #include <array>
37 #include <cstdio>
38 #include <cstdlib>
39 #include <memory>
40 #include <regex>
41 #include <string>
42 #include <vector>
43 #include <utility>
44
45 #define SIZEOFARRAY(ARR)                                                       \
46   sizeof(ARR) / sizeof(ARR[0])                                                 \
47
48 #define EXTENDED_ASSERT_TRUE(expression) do {                                  \
49     bool tmp = expression;                                                     \
50     EXPECT_TRUE(tmp) << #expression << " is not true";                         \
51     if (!tmp)                                                                  \
52         return false;                                                          \
53 } while (0);
54
55 #define EXTENDED_ASSERT_FALSE(expression) do {                                 \
56     bool tmp = expression;                                                     \
57     EXPECT_FALSE(tmp) << #expression << " is not false";                       \
58     if (tmp)                                                                   \
59         return false;                                                          \
60 } while (0);
61
62 #define EXTENDED_ASSERT_EQ(expression, value) do {                             \
63     auto ret = expression;                                                     \
64     EXPECT_EQ(ret, value) << #expression << " is not equal to " << #value;     \
65     if (ret != value)                                                          \
66         return false;                                                          \
67 } while (0);
68
69 namespace smoke_test {
70
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;
77
78 using App = std::pair<std::string, std::string>;
79 using Apps = std::vector<App>;
80
81 enum class RequestResult {
82   NORMAL,
83   FAIL
84 };
85
86 enum class StorageType {
87   INTERNAL,
88   EXTERNAL,
89   EXTENDED
90 };
91
92 class ScopedTzipInterface {
93  public:
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_)),
98         mounted_(true) {
99     interface_.MountZip(common_installer::GetZipPackageLocation(pkg_path_,
100                                                                 pkgid));
101   }
102
103   void Release() {
104     if (mounted_) {
105       interface_.UnmountZip();
106       mounted_ = false;
107     }
108   }
109
110   ~ScopedTzipInterface() {
111     Release();
112   }
113
114  private:
115   boost::filesystem::path pkg_path_;
116   common_installer::TzipInterface interface_;
117   bool mounted_;
118 };
119
120 class TestPkgmgrInstaller : public common_installer::PkgmgrInstallerInterface {
121  public:
122   bool CreatePkgMgrInstaller(pkgmgr_installer** installer,
123                              common_installer::InstallationMode* mode) {
124     *installer = pkgmgr_installer_offline_new();
125     if (!*installer)
126       return false;
127     *mode = common_installer::InstallationMode::ONLINE;
128     return true;
129   }
130
131   bool ShouldCreateSignal() const {
132     return false;
133   }
134 };
135
136 enum class PackageType {
137   TPK,
138   WGT,
139   HYBRID
140 };
141
142 struct User {
143   uid_t uid = kGlobalUserUid;
144   gid_t gid = kGlobalUserGid;
145 };
146
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;
153   bool is_readonly;
154   User test_user;
155 };
156
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()) {
162   }
163
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);
171   }
172
173   bool is_global;
174   bool is_readonly;
175   bool is_update;
176   bool is_preload;
177   bool is_system;
178   bool is_removable;
179 };
180
181 common_installer::RequestMode ParseRequestMode(int argc,  char** argv);
182
183 bool TouchFile(const boost::filesystem::path& path);
184
185 void AddDataFiles(const std::string& pkgid, uid_t uid);
186
187 bool AddTestUser(User* test_user);
188
189 bool DeleteTestUser();
190
191 void RemoveAllRecoveryFiles(const std::string& prefix, uid_t uid);
192
193 boost::filesystem::path FindRecoveryFile(const std::string& prefix, uid_t uid);
194
195 boost::filesystem::path GetPackageRoot(const std::string& pkgid, uid_t uid);
196
197 std::unique_ptr<common_installer::recovery::RecoveryFile> GetRecoverFileInfo(
198     const bf::path& recovery_file_path);
199
200 bool ValidateFileContentInPackage(const std::string& pkgid,
201                                   const std::string& relative,
202                                   const std::string& expected,
203                                   const TestParameters& params);
204
205 bool ValidatePackage(const std::string& pkgid, const Apps& apps,
206     const TestParameters& params);
207
208 bool ValidateDataFiles(const std::string& pkgid, uid_t uid);
209
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);
214
215 bool CheckPackageNonExistance(const std::string& pkgid,
216                               const TestParameters& params);
217
218 bool CheckPackageReadonlyNonExistance(const std::string& pkgid,
219                                       const TestParameters& params);
220
221 bool CheckSharedDataExistance(const std::string& pkgid,
222                               const TestParameters& params);
223
224 bool CheckSharedDataNonExistance(const std::string& pkgid,
225                                 const TestParameters& params);
226
227 bool TouchFile(const boost::filesystem::path& path);
228
229 class BackendInterface {
230  public:
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() {}
236
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;
249
250   CommandResult Uninstall(const std::string& pkgid) const;
251   CommandResult UninstallPreload(const std::string& pkgid) const;
252
253   CommandResult EnablePackage(const std::string& pkgid) const;
254   CommandResult DisablePackage(const std::string& pkgid) const;
255
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;
259
260   CommandResult MigrateLegacyExternalImage(const std::string& pkgid,
261       const boost::filesystem::path& path,
262       const boost::filesystem::path& legacy_path) const;
263
264   CommandResult RDSUpdate(const boost::filesystem::path& path,
265       const std::string& pkgid) const;
266
267   CommandResult Recover(const boost::filesystem::path& recovery_file) const;
268
269  protected:
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_;
275   RequestResult mode_;
276
277  private:
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;
285 };
286
287 class SmokeTestHelperRunner {
288  public:
289   enum class Result {
290     SUCCESS,
291     FAIL,
292     KILLED,
293     UnKnown
294   };
295
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;
306
307  private:
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;
312 };
313
314 bool CheckAvailableExternalPath();
315
316 bool CheckAvailableExtendedPath();
317
318 bool BackupPathCopyAndRemove(const boost::filesystem::path& path);
319
320 bool BackupPath(const boost::filesystem::path& path);
321
322 bool RestorePathCopyAndRemove(const boost::filesystem::path& path);
323
324 bool RestorePath(const boost::filesystem::path& path);
325
326 std::vector<boost::filesystem::path> SetupBackupDirectories(uid_t test_uid);
327
328 void UninstallAllAppsInDirectory(boost::filesystem::path dir, bool is_preload,
329     BackendInterface* backend);
330
331 void UninstallAllSmokeApps(common_installer::RequestMode request_mode,
332     uid_t test_uid, BackendInterface* backend);
333
334 int GetAppInstalledTime(const char* appid, uid_t uid);
335
336 }  // namespace smoke_test
337
338 #endif  // UNIT_TESTS_COMMON_SMOKE_UTILS_H_