Revert "[SmokeTest] Add request mode choice"
[platform/core/appfw/wgt-backend.git] / src / unit_tests / smoke_test.cc
1 // Copyright (c) 2015 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 #include <boost/filesystem/operations.hpp>
6 #include <boost/filesystem/path.hpp>
7 #include <boost/range/iterator_range.hpp>
8 #include <boost/system/error_code.hpp>
9
10 #include <common/paths.h>
11 #include <common/pkgmgr_interface.h>
12 #include <common/pkgmgr_query.h>
13 #include <common/request.h>
14 #include <common/step/configuration/step_fail.h>
15 #include <common/tzip_interface.h>
16 #include <common/utils/file_util.h>
17 #include <common/utils/subprocess.h>
18 #include <common/utils/user_util.h>
19
20 #include <gtest/gtest.h>
21 #include <gtest/gtest-death-test.h>
22 #include <pkgmgr-info.h>
23 #include <signal.h>
24 #include <unistd.h>
25 #include <tzplatform_config.h>
26 #include <vconf.h>
27 #include <vconf-internal-keys.h>
28
29 #include <array>
30 #include <cstdio>
31 #include <cstdlib>
32 #include <vector>
33 #include <regex>
34
35 #include "hybrid/hybrid_installer.h"
36 #include "wgt/wgt_app_query_interface.h"
37 #include "wgt/wgt_installer.h"
38
39 #define SIZEOFARRAY(ARR)                                                       \
40   sizeof(ARR) / sizeof(ARR[0])                                                 \
41
42 namespace bf = boost::filesystem;
43 namespace bs = boost::system;
44 namespace ci = common_installer;
45
46 namespace {
47
48 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
49 const uid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER);
50 const uid_t kDefaultUserUid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
51 const uid_t kTestUserId = kGlobalUserUid;
52 const gid_t kTestGroupId = kGlobalUserGid;
53 const char kSystemShareGroupName[] = "system_share";
54 const std::string& kTestUserIdStr =
55     std::to_string(kTestUserId);
56 const std::string& kDefaultUserIdStr = std::to_string(kDefaultUserUid);
57 const char kLegacyExtImageDir[] = "legacy_extimage_dir";
58 const char kMigrateTestDBName[] = "app2sd_migrate.db";
59
60 const bf::path kSmokePackagesDirectory =
61     "/usr/share/wgt-backend-ut/test_samples/smoke/";
62
63 enum RWDirectory {
64     DATA,
65     CACHE,
66     SHARED_CACHE,
67     SHARED_DATA,
68     SHARED_TRUSTED
69 };
70
71 const char* rwDirectories[] = {
72   "data",
73   "cache",
74   "shared/cache",
75   "shared/data",
76   "shared/trusted",
77 };
78
79 // common entries
80 const std::vector<std::string> kDBEntries = {
81   {".pkgmgr_parser.db"},
82   {".pkgmgr_parser.db-journal"},
83   {".pkgmgr_cert.db"},
84   {".pkgmgr_cert.db-journal"},
85   {".app2sd.db"},
86   {".app2sd.db-journal"},
87 };
88 // globaluser entries
89 const char kGlobalManifestDir[] = "/opt/share/packages";
90 const char kSkelDir[] = "/etc/skel/apps_rw";
91 const char kPreloadApps[] = "/usr/apps";
92 const char kPreloadManifestDir[] = "/usr/share/packages";
93 const char kPreloadIcons[] = "/usr/share/icons";
94
95 enum class RequestResult {
96   NORMAL,
97   FAIL
98 };
99
100 class ScopedTzipInterface {
101  public:
102   explicit ScopedTzipInterface(const std::string& pkgid)
103       : pkg_path_(bf::path(ci::GetRootAppPath(false,
104             kTestUserId)) / pkgid),
105         interface_(ci::GetMountLocation(pkg_path_)),
106         mounted_(true) {
107     interface_.MountZip(ci::GetZipPackageLocation(pkg_path_, pkgid));
108   }
109
110   void Release() {
111     if (mounted_) {
112       interface_.UnmountZip();
113       mounted_ = false;
114     }
115   }
116
117   ~ScopedTzipInterface() {
118     Release();
119   }
120
121  private:
122   bf::path pkg_path_;
123   ci::TzipInterface interface_;
124   bool mounted_;
125 };
126
127 class TestPkgmgrInstaller : public ci::PkgmgrInstallerInterface {
128  public:
129   bool CreatePkgMgrInstaller(pkgmgr_installer** installer,
130                              ci::InstallationMode* mode) {
131     *installer = pkgmgr_installer_offline_new();
132     if (!*installer)
133       return false;
134     *mode = ci::InstallationMode::ONLINE;
135     return true;
136   }
137
138   bool ShouldCreateSignal() const {
139     return false;
140   }
141 };
142
143 enum class PackageType {
144   WGT,
145   HYBRID
146 };
147
148 bool TouchFile(const bf::path& path) {
149   FILE* f = fopen(path.c_str(), "w+");
150   if (!f)
151     return false;
152   fclose(f);
153   return true;
154 }
155
156 void RemoveAllRecoveryFiles() {
157   bf::path root_path = ci::GetRootAppPath(false,
158       kTestUserId);
159   if (!bf::exists(root_path))
160     return;
161   for (auto& dir_entry : boost::make_iterator_range(
162          bf::directory_iterator(root_path), bf::directory_iterator())) {
163     if (bf::is_regular_file(dir_entry)) {
164       if (dir_entry.path().string().find("/wgt-recovery")
165           != std::string::npos) {
166         bs::error_code error;
167         bf::remove(dir_entry.path(), error);
168       }
169     }
170   }
171 }
172
173 bf::path FindRecoveryFile() {
174   bf::path root_path = ci::GetRootAppPath(false,
175       kTestUserId);
176   for (auto& dir_entry : boost::make_iterator_range(
177          bf::directory_iterator(root_path), bf::directory_iterator())) {
178     if (bf::is_regular_file(dir_entry)) {
179       if (dir_entry.path().string().find("/wgt-recovery")
180           != std::string::npos) {
181         return dir_entry.path();
182       }
183     }
184   }
185   return {};
186 }
187
188 bf::path GetPackageRoot(const std::string& pkgid, uid_t uid) {
189   bf::path root_path = ci::GetRootAppPath(false, uid);
190   return root_path / pkgid;
191 }
192
193 bool ValidateFileContentInPackage(const std::string& pkgid,
194                                   const std::string& relative,
195                                   const std::string& expected,
196                                   bool is_readonly = false) {
197   bf::path file_path = ci::GetRootAppPath(is_readonly, kTestUserId);
198   file_path = file_path / pkgid / relative;
199   if (!bf::exists(file_path)) {
200     LOG(ERROR) << file_path << " doesn't exist";
201     return false;
202   }
203   FILE* handle = fopen(file_path.c_str(), "r");
204   if (!handle) {
205     LOG(ERROR) << file_path << " cannot  be open";
206     return false;
207   }
208   std::string content;
209   std::array<char, 200> buffer;
210   while (fgets(buffer.data(), buffer.size(), handle)) {
211     content += buffer.data();
212   }
213   fclose(handle);
214   return content == expected;
215 }
216
217 void AddDataFiles(const std::string& pkgid, uid_t uid) {
218   if (uid == kGlobalUserUid) {
219     ci::UserList list = ci::GetUserList();
220     for (auto l : list) {
221       auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l));
222       ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt"));
223       ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt"));
224     }
225   } else {
226     auto pkg_path = GetPackageRoot(pkgid, uid);
227     ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt"));
228     ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt"));
229   }
230 }
231
232 void ValidateDataFiles(const std::string& pkgid, uid_t uid) {
233   if (uid == kGlobalUserUid) {
234     ci::UserList list = ci::GetUserList();
235     for (auto l : list) {
236       auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l));
237       ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt"));
238       ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt"));
239     }
240   } else {
241     auto pkg_path = GetPackageRoot(pkgid, uid);
242     ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt"));
243     ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt"));
244   }
245 }
246
247 void ValidatePackageRWFS(const std::string& pkgid, uid_t uid) {
248   bf::path root_path = ci::GetRootAppPath(false, uid);
249   bf::path package_path = root_path / pkgid;
250   bf::path data_path = package_path / rwDirectories[DATA];
251   bf::path cache_path = package_path / rwDirectories[CACHE];
252   bf::path shared_data_path = package_path / rwDirectories[SHARED_DATA];
253
254   ASSERT_TRUE(bf::exists(data_path));
255   ASSERT_TRUE(bf::exists(cache_path));
256
257   struct stat stats;
258   stat(data_path.c_str(), &stats);
259   // gid of RW dirs should be system_share
260   boost::optional<gid_t> system_share =
261     ci::GetGidByGroupName(kSystemShareGroupName);
262   ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << data_path;
263   ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: " << data_path;
264   if (bf::exists(shared_data_path)) {
265     stat(shared_data_path.c_str(), &stats);
266     ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << shared_data_path;
267     ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: "
268       << shared_data_path;
269   }
270
271   stat(cache_path.c_str(), &stats);
272   ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << cache_path;
273   ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: " << cache_path;
274 }
275
276 void ValidatePackageFS(const std::string& pkgid,
277                        const std::vector<std::string>& appids,
278                        uid_t uid, gid_t gid, bool is_readonly) {
279   bf::path root_path = ci::GetRootAppPath(is_readonly, uid);
280   bf::path package_path = root_path / pkgid;
281   bf::path shared_path = package_path / "shared";
282   ASSERT_TRUE(bf::exists(root_path));
283   ASSERT_TRUE(bf::exists(package_path));
284   ASSERT_TRUE(bf::exists(shared_path));
285
286   bf::path manifest_path =
287       bf::path(getUserManifestPath(uid, is_readonly)) / (pkgid + ".xml");
288   ASSERT_TRUE(bf::exists(manifest_path));
289
290   for (auto& appid : appids) {
291     bf::path binary_path = package_path / "bin" / appid;
292     ASSERT_TRUE(bf::exists(binary_path));
293   }
294
295   bf::path widget_root_path = package_path / "res" / "wgt";
296   bf::path config_path = widget_root_path / "config.xml";
297   ASSERT_TRUE(bf::exists(widget_root_path));
298   ASSERT_TRUE(bf::exists(config_path));
299
300   bf::path private_tmp_path = package_path / "tmp";
301   ASSERT_TRUE(bf::exists(private_tmp_path));
302
303   // backups should not exist
304   bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
305   bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
306   ASSERT_FALSE(bf::exists(package_backup));
307   ASSERT_FALSE(bf::exists(manifest_backup));
308
309   for (bf::recursive_directory_iterator iter(package_path);
310       iter != bf::recursive_directory_iterator(); ++iter) {
311     if (bf::is_symlink(symlink_status(iter->path())))
312       continue;
313     bool is_rw_dir = false;
314     for(const auto rw_dir : rwDirectories) {
315       bf::path rw_dir_path = rw_dir;
316       is_rw_dir |= ci::MakeRelativePath(iter->path(), package_path) == rw_dir_path;
317     }
318     if (is_rw_dir || iter->path().filename() == ".mmc") {
319       iter.no_push();
320       continue;
321     }
322     struct stat stats;
323     stat(iter->path().c_str(), &stats);
324     ASSERT_EQ(uid, stats.st_uid) << "Invalid uid: " << iter->path();
325     ASSERT_EQ(gid, stats.st_gid) << "Invalid gid: " << iter->path();
326   }
327 }
328
329 void PackageCheckCleanup(const std::string& pkgid,
330     const std::vector<std::string>&, bool is_readonly = false) {
331   bf::path root_path = ci::GetRootAppPath(is_readonly, kTestUserId);
332   bf::path package_path = root_path / pkgid;
333   ASSERT_FALSE(bf::exists(package_path));
334
335   bf::path manifest_path = bf::path(getUserManifestPath(kTestUserId,
336       is_readonly)) / (pkgid + ".xml");
337   ASSERT_FALSE(bf::exists(manifest_path));
338
339   // backups should not exist
340   bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
341   bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
342   ASSERT_FALSE(bf::exists(package_backup));
343   ASSERT_FALSE(bf::exists(manifest_backup));
344 }
345
346 void ValidatePackage(const std::string& pkgid,
347     const std::vector<std::string>& appids, bool is_readonly = false) {
348   ASSERT_TRUE(ci::QueryIsPackageInstalled(
349       pkgid, ci::GetRequestMode(kTestUserId), kTestUserId));
350   ValidatePackageFS(pkgid, appids, kTestUserId, kTestGroupId, is_readonly);
351   if (kTestUserId == kGlobalUserUid) {
352     ci::UserList list = ci::GetUserList();
353     for (auto& l : list)
354       ValidatePackageRWFS(pkgid, std::get<0>(l));
355   } else {
356     ValidatePackageRWFS(pkgid, kTestUserId);
357   }
358 }
359
360 void ValidateExternalPackageFS(const std::string& pkgid,
361                                const std::vector<std::string>& appids,
362                                uid_t uid, gid_t gid) {
363   ASSERT_EQ(app2ext_usr_enable_external_pkg(pkgid.c_str(), uid), 0);
364   bf::path root_path = ci::GetRootAppPath(false, uid);
365   ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "res"));
366   ValidatePackageFS(pkgid, appids, uid, gid, false);
367   ASSERT_EQ(app2ext_usr_disable_external_pkg(pkgid.c_str(), uid), 0);
368 }
369
370 void ValidateExternalPackage(const std::string& pkgid,
371                              const std::vector<std::string>& appids) {
372   ASSERT_TRUE(ci::QueryIsPackageInstalled(
373       pkgid, ci::GetRequestMode(kTestUserId),
374       kTestUserId));
375   std::string storage = ci::QueryStorageForPkgId(pkgid, kTestUserId);
376   bf::path ext_mount_path = ci::GetExternalCardPath();
377   if (bf::is_empty(ext_mount_path)) {
378     LOG(INFO) << "Sdcard not exists!";
379     ASSERT_EQ(storage, "installed_internal");
380   } else {
381     ASSERT_EQ(storage, "installed_external");
382   }
383   ValidateExternalPackageFS(pkgid, appids, kTestUserId, kTestGroupId);
384   if (kTestUserId == kGlobalUserUid) {
385     ci::UserList list = ci::GetUserList();
386     for (auto& l : list)
387       ValidatePackageRWFS(pkgid, std::get<0>(l));
388   } else {
389     ValidatePackageRWFS(pkgid, kTestUserId);
390   }
391 }
392
393 void CheckPackageNonExistance(const std::string& pkgid,
394                               const std::vector<std::string>& appids) {
395   ASSERT_FALSE(ci::QueryIsPackageInstalled(
396       pkgid, ci::GetRequestMode(kTestUserId),
397       kTestUserId));
398   PackageCheckCleanup(pkgid, appids);
399   if (kTestUserId == kGlobalUserUid) {
400       ci::UserList list = ci::GetUserList();
401       bf::path skel_path(kSkelDir);
402       ASSERT_FALSE(bf::exists(skel_path / pkgid));
403       for (auto& l : list) {
404         bf::path root_path = ci::GetRootAppPath(false, std::get<0>(l));
405         bf::path package_path = root_path / pkgid;
406         ASSERT_FALSE(bf::exists(package_path));
407       }
408   }
409 }
410
411 void CheckPackageReadonlyNonExistance(const std::string& pkgid,
412                                       const std::vector<std::string>& appids) {
413   ASSERT_FALSE(ci::QueryIsPackageInstalled(
414       pkgid, ci::GetRequestMode(kTestUserId), kTestUserId));
415   PackageCheckCleanup(pkgid, appids, true);
416 }
417
418 std::unique_ptr<ci::AppQueryInterface> CreateQueryInterface() {
419   std::unique_ptr<ci::AppQueryInterface> query_interface(
420       new wgt::WgtAppQueryInterface());
421   return query_interface;
422 }
423
424 std::unique_ptr<ci::AppInstaller> CreateInstaller(ci::PkgMgrPtr pkgmgr,
425                                                   PackageType type) {
426   switch (type) {
427     case PackageType::WGT:
428       return std::unique_ptr<ci::AppInstaller>(new wgt::WgtInstaller(pkgmgr));
429     case PackageType::HYBRID:
430       return std::unique_ptr<ci::AppInstaller>(
431           new hybrid::HybridInstaller(pkgmgr));
432     default:
433       LOG(ERROR) << "Unknown installer type";
434       return nullptr;
435   }
436 }
437
438 ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr,
439                                                  PackageType type,
440                                                  RequestResult mode) {
441   std::unique_ptr<ci::AppInstaller> installer = CreateInstaller(pkgmgr, type);
442   switch (mode) {
443   case RequestResult::FAIL:
444     installer->AddStep<ci::configuration::StepFail>();
445     break;
446   default:
447     break;
448   }
449   return installer->Run();
450 }
451 ci::AppInstaller::Result CallBackend(int argc,
452                                      const char* argv[],
453                                      PackageType type,
454                                      RequestResult mode = RequestResult::NORMAL
455                                      ) {
456   TestPkgmgrInstaller pkgmgr_installer;
457   std::unique_ptr<ci::AppQueryInterface> query_interface =
458       CreateQueryInterface();
459   auto pkgmgr =
460       ci::PkgMgrInterface::Create(argc, const_cast<char**>(argv),
461                                   &pkgmgr_installer, query_interface.get());
462   if (!pkgmgr) {
463     LOG(ERROR) << "Failed to initialize pkgmgr interface";
464     return ci::AppInstaller::Result::UNKNOWN;
465   }
466   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
467 }
468
469 ci::AppInstaller::Result Install(const bf::path& path,
470                                  PackageType type,
471                                  RequestResult mode = RequestResult::NORMAL) {
472   const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()};
473   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
474 }
475
476 ci::AppInstaller::Result InstallPreload(const bf::path& path, PackageType type,
477     RequestResult mode = RequestResult::NORMAL) {
478   const char* argv[] = {"", "-i", path.c_str(), "--preload"};
479   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
480 }
481
482 bool CheckAvailableExternalPath() {
483   bf::path ext_mount_path = ci::GetExternalCardPath();
484   LOG(DEBUG) << "ext_mount_path :" << ext_mount_path;
485   if (ext_mount_path.empty()) {
486     LOG(ERROR) << "Sdcard not exists!";
487     return false;
488   }
489   return true;
490 }
491
492 ci::AppInstaller::Result InstallExternal(const bf::path& path,
493                                  PackageType type,
494                                  RequestResult mode = RequestResult::NORMAL) {
495   int default_storage = 0;
496   vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
497                 &default_storage);
498   vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, 1);
499
500   const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()};
501   ci::AppInstaller::Result result =
502                           CallBackend(SIZEOFARRAY(argv), argv, type, mode);
503
504   vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
505                 default_storage);
506   return result;
507 }
508
509 ci::AppInstaller::Result MigrateLegacyExternalImage(const std::string& pkgid,
510                                  const bf::path& path,
511                                  const bf::path& legacy_path,
512                                  PackageType type,
513                                  RequestResult mode = RequestResult::NORMAL) {
514   if (InstallExternal(path, type) != ci::AppInstaller::Result::OK) {
515     LOG(ERROR) << "Failed to install application. Cannot perform Migrate";
516     return ci::AppInstaller::Result::ERROR;
517   }
518
519   bf::path ext_mount_path = ci::GetExternalCardPath();
520   if (bf::is_empty(ext_mount_path)) {
521     LOG(ERROR) << "Sdcard not exists!";
522     return ci::AppInstaller::Result::ERROR;
523   }
524   bf::path app2sd_path = ext_mount_path / "app2sd";
525
526   char* image_name = app2ext_usr_getname_image(pkgid.c_str(),
527                      kGlobalUserUid);
528   if (!image_name) {
529     LOG(ERROR) << "Failed to get external image name";
530     return ci::AppInstaller::Result::ERROR;
531   }
532   bf::path org_image = app2sd_path / image_name;
533   free(image_name);
534
535   bs::error_code error;
536   bf::remove(org_image, error);
537   if (error) {
538     LOG(ERROR) << "Failed to remove org image";
539     return ci::AppInstaller::Result::ERROR;
540   }
541
542   bf::path db_path = tzplatform_getenv(TZ_SYS_DB);
543   bf::path app2sd_db = db_path / ".app2sd.db";
544   bf::path app2sd_db_journal = db_path / ".app2sd.db-journal";
545   bf::remove(app2sd_db, error);
546   if (error) {
547     LOG(ERROR) << "Failed to remove app2sd db";
548     return ci::AppInstaller::Result::ERROR;
549   }
550   bf::remove(app2sd_db_journal, error);
551   if (error) {
552     LOG(ERROR) << "Failed to remove app2sd journal db";
553     return ci::AppInstaller::Result::ERROR;
554   }
555
556   bf::path app2sd_migrate_db = legacy_path / kMigrateTestDBName;
557   if (!ci::CopyFile(app2sd_migrate_db, app2sd_db)) {
558     LOG(ERROR) << "Failed to copy test db";
559     return ci::AppInstaller::Result::ERROR;
560   }
561
562   bf::path legacy_src = legacy_path / pkgid;
563   bf::path legacy_dst = app2sd_path / pkgid;
564   if (!ci::CopyFile(legacy_src, legacy_dst)) {
565     LOG(ERROR) << "Failed to copy test image";
566     return ci::AppInstaller::Result::ERROR;
567   }
568   const char* argv[] = {"", "--migrate-extimg", pkgid.c_str(),
569                        "-u", kDefaultUserIdStr.c_str()};
570   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
571 }
572
573 ci::AppInstaller::Result MountInstall(const bf::path& path,
574     PackageType type, RequestResult mode = RequestResult::NORMAL) {
575   const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()};
576   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
577 }
578
579 ci::AppInstaller::Result Uninstall(const std::string& pkgid,
580                                    PackageType type,
581                                    bool is_preload,
582                                    RequestResult mode = RequestResult::NORMAL) {
583   if (is_preload) {
584     const char* argv[] = {"", "-d", pkgid.c_str(), "--preload",
585         "--force-remove"};
586     return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
587   } else {
588     const char* argv[] = {"", "-d", pkgid.c_str(), "-u",
589         kTestUserIdStr.c_str()};
590     return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
591   }
592 }
593
594 ci::AppInstaller::Result RDSUpdate(const bf::path& path,
595                                    const std::string& pkgid,
596                                    PackageType type,
597                                    RequestResult mode = RequestResult::NORMAL) {
598   if (Install(path, type) != ci::AppInstaller::Result::OK) {
599     LOG(ERROR) << "Failed to install application. Cannot perform RDS";
600     return ci::AppInstaller::Result::UNKNOWN;
601   }
602   const char* argv[] = {"", "-r", pkgid.c_str(), "-u",
603                         kTestUserIdStr.c_str()};
604   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
605 }
606
607 ci::AppInstaller::Result DeltaInstall(const bf::path& path,
608     const bf::path& delta_package, PackageType type) {
609   if (Install(path, type) != ci::AppInstaller::Result::OK) {
610     LOG(ERROR) << "Failed to install application. Cannot perform delta update";
611     return ci::AppInstaller::Result::UNKNOWN;
612   }
613   return Install(delta_package, type);
614 }
615
616 ci::AppInstaller::Result EnablePackage(const std::string& pkgid,
617                                   PackageType type,
618                                   RequestResult mode = RequestResult::NORMAL) {
619   const char* argv[] = {"", "-A", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
620   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
621 }
622
623 ci::AppInstaller::Result DisablePackage(const std::string& pkgid,
624                                   PackageType type,
625                                   RequestResult mode = RequestResult::NORMAL) {
626   const char* argv[] = {"", "-D", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
627   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
628 }
629
630 ci::AppInstaller::Result Recover(const bf::path& recovery_file,
631                                  PackageType type,
632                                  RequestResult mode = RequestResult::NORMAL) {
633   const char* argv[] = {"", "-b", recovery_file.c_str(), "-u",
634                         kTestUserIdStr.c_str()};
635   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
636 }
637
638 void BackupPath(const bf::path& path) {
639   bf::path backup_path = path.string() + ".bck";
640   std::cout << "Backup path: " << path << " to " << backup_path << std::endl;
641   bs::error_code error;
642   bf::remove_all(backup_path, error);
643   if (error)
644     LOG(ERROR) << "Remove failed: " << backup_path
645                << " (" << error.message() << ")";
646   if (bf::exists(path)) {
647     bf::rename(path, backup_path, error);
648     if (error)
649       LOG(ERROR) << "Failed to setup test environment. Does some previous"
650                  << " test crashed? Path: "
651                  << backup_path << " should not exist.";
652     assert(!error);
653   }
654 }
655
656 void RestorePath(const bf::path& path) {
657   bf::path backup_path = path.string() + ".bck";
658   std::cout << "Restore path: " << path << " from " << backup_path << std::endl;
659   bs::error_code error;
660   bf::remove_all(path, error);
661   if (error)
662     LOG(ERROR) << "Remove failed: " << path
663                << " (" << error.message() << ")";
664   if (bf::exists(backup_path)) {
665     bf::rename(backup_path, path, error);
666     if (error)
667       LOG(ERROR) << "Failed to restore backup path: " << backup_path
668                  << " (" << error.message() << ")";
669   }
670 }
671
672 std::vector<bf::path> SetupBackupDirectories(uid_t uid) {
673   std::vector<bf::path> entries;
674   bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB));
675   if (uid != kGlobalUserUid)
676     db_dir = db_dir / "user" / std::to_string(uid);
677   for (auto e : kDBEntries) {
678     bf::path path = db_dir / e;
679     entries.emplace_back(path);
680   }
681
682   if (getuid() == 0) {
683     entries.emplace_back(kPreloadApps);
684     entries.emplace_back(kPreloadManifestDir);
685     entries.emplace_back(kPreloadIcons);
686   }
687
688   if (uid == kGlobalUserUid) {
689     entries.emplace_back(kSkelDir);
690     entries.emplace_back(kGlobalManifestDir);
691     ci::UserList list = ci::GetUserList();
692     for (auto l : list) {
693       bf::path apps = std::get<2>(l) / "apps_rw";
694       entries.emplace_back(apps);
695     }
696   } else {
697     tzplatform_set_user(uid);
698     bf::path approot = tzplatform_getenv(TZ_USER_APPROOT);
699     tzplatform_reset_user();
700     entries.emplace_back(approot);
701   }
702
703   bf::path apps_rw = ci::GetRootAppPath(false, uid);
704   entries.emplace_back(apps_rw);
705
706   return entries;
707 }
708
709 void UninstallAllAppsInDirectory(bf::path dir, bool is_preload) {
710   if(bf::exists(dir)) {
711     for (auto& dir_entry : boost::make_iterator_range(
712         bf::directory_iterator(dir), bf::directory_iterator())) {
713       if (dir_entry.path().string().find("smoke") != std::string::npos &&
714           bf::is_directory(dir_entry)) {
715         std::string package = dir_entry.path().filename().string();
716         std::regex pkg_regex("smoke[a-zA-Z]{3,}[1-9]{2,}");
717         if (std::regex_match(package, pkg_regex)) {
718           if(Uninstall(dir_entry.path().filename().string(), PackageType::WGT,
719               is_preload, RequestResult::NORMAL) !=
720               ci::AppInstaller::Result::OK) {
721             LOG(ERROR) << "Cannot uninstall smoke test app: "
722                 << dir_entry.path().filename().string();
723           }
724         }
725       }
726     }
727   }
728 }
729
730 void UninstallAllSmokeApps(uid_t uid) {
731   if (getuid() == 0) {
732     bf::path root_path = kPreloadApps;
733     UninstallAllAppsInDirectory(root_path, true);
734   }
735   bf::path apps_rw = ci::GetRootAppPath(false, uid);
736   UninstallAllAppsInDirectory(apps_rw, false);
737 }
738
739 }  // namespace
740
741 namespace common_installer {
742
743 class SmokeEnvironment : public testing::Environment {
744  public:
745   explicit SmokeEnvironment(uid_t uid) : uid_(uid) {
746   }
747   void SetUp() override {
748     backups_ = SetupBackupDirectories(uid_);
749     for (auto& path : backups_)
750       BackupPath(path);
751   }
752   void TearDown() override {
753     UninstallAllSmokeApps(uid_);
754     for (auto& path : backups_)
755       RestorePath(path);
756   }
757
758  private:
759   uid_t uid_;
760   std::vector<bf::path> backups_;
761 };
762
763 class SmokeTest : public testing::Test {
764 };
765
766 TEST_F(SmokeTest, InstallationMode) {
767   bf::path path = kSmokePackagesDirectory / "InstallationMode.wgt";
768   std::string pkgid = "smokewgt03";
769   std::string appid = "smokewgt03.InstallationMode";
770   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
771   ValidatePackage(pkgid, {appid});
772 }
773
774 TEST_F(SmokeTest, UpdateMode) {
775   bf::path path_old = kSmokePackagesDirectory / "UpdateMode.wgt";
776   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_2.wgt";
777   std::string pkgid = "smokewgt04";
778   std::string appid = "smokewgt04.UpdateMode";
779   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
780   AddDataFiles(pkgid, kTestUserId);
781   ASSERT_EQ(Install(path_new, PackageType::WGT), ci::AppInstaller::Result::OK);
782   ValidatePackage(pkgid, {appid});
783
784   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
785   ValidateDataFiles(pkgid, kTestUserId);
786 }
787
788 TEST_F(SmokeTest, DeinstallationMode) {
789   bf::path path = kSmokePackagesDirectory / "DeinstallationMode.wgt";
790   std::string pkgid = "smokewgt05";
791   std::string appid = "smokewgt05.DeinstallationMode";
792   ASSERT_EQ(Install(path, PackageType::WGT),
793             ci::AppInstaller::Result::OK);
794   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT, false),
795             ci::AppInstaller::Result::OK);
796   CheckPackageNonExistance(pkgid, {appid});
797 }
798
799 TEST_F(SmokeTest, RDSMode) {
800   bf::path path = kSmokePackagesDirectory / "RDSMode.wgt";
801   std::string pkgid = "smokewgt11";
802   std::string appid = "smokewgt11.RDSMode";
803   bf::path delta_directory = kSmokePackagesDirectory / "delta_dir/";
804   bf::path sdk_expected_directory =
805       bf::path(ci::GetRootAppPath(false, kTestUserId)) / "tmp" / pkgid;
806   bs::error_code error;
807   bf::create_directories(sdk_expected_directory.parent_path(), error);
808   ASSERT_FALSE(error);
809   ASSERT_TRUE(CopyDir(delta_directory, sdk_expected_directory));
810   ASSERT_EQ(RDSUpdate(path, pkgid, PackageType::WGT),
811             ci::AppInstaller::Result::OK);
812   ValidatePackage(pkgid, {appid});
813
814   // Check delta modifications
815   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
816       "res" / "wgt" / "DELETED"));
817   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
818       "res" / "wgt" / "ADDED"));
819   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "2\n"));
820 }
821
822 TEST_F(SmokeTest, EnablePkg) {
823   bf::path path = kSmokePackagesDirectory / "EnablePkg.wgt";
824   std::string pkgid = "smokewgt22";
825   ASSERT_EQ(Install(path, PackageType::WGT),
826             ci::AppInstaller::Result::OK);
827   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
828             ci::AppInstaller::Result::OK);
829   ASSERT_EQ(EnablePackage(pkgid, PackageType::WGT),
830             ci::AppInstaller::Result::OK);
831
832   ASSERT_TRUE(ci::QueryIsPackageInstalled(pkgid,
833       ci::GetRequestMode(kTestUserId),
834       kTestUserId));
835 }
836
837 TEST_F(SmokeTest, DisablePkg) {
838   bf::path path = kSmokePackagesDirectory / "DisablePkg.wgt";
839   std::string pkgid = "smokewgt21";
840   std::string appid = "smokewgt21.DisablePkg";
841   ASSERT_EQ(Install(path, PackageType::WGT),
842             ci::AppInstaller::Result::OK);
843   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
844             ci::AppInstaller::Result::OK);
845   ASSERT_TRUE(ci::QueryIsDisabledPackage(pkgid, kTestUserId));
846   ValidatePackage(pkgid, {appid});
847 }
848
849 TEST_F(SmokeTest, DeltaMode) {
850   bf::path path = kSmokePackagesDirectory / "DeltaMode.wgt";
851   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode.delta";
852   std::string pkgid = "smokewgt17";
853   std::string appid = "smokewgt17.DeltaMode";
854   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
855             ci::AppInstaller::Result::OK);
856   ValidatePackage(pkgid, {appid});
857
858   // Check delta modifications
859   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
860       "res" / "wgt" / "DELETED"));
861   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
862       "res" / "wgt" / "ADDED"));
863   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
864       "res" / "wgt" / "css" / "style.css"));
865   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
866       "res" / "wgt" / "images" / "tizen_32.png"));
867   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
868       "res" / "wgt" / "js" / "main.js"));
869   ASSERT_TRUE(ValidateFileContentInPackage(
870       pkgid, "res/wgt/MODIFIED", "version 2\n"));
871 }
872
873 TEST_F(SmokeTest, RecoveryMode_ForInstallation) {
874   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForInstallation.wgt";
875   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
876   backend_crash.Run("-i", path.string(), "-u", kTestUserIdStr.c_str());
877   ASSERT_NE(backend_crash.Wait(), 0);
878
879   std::string pkgid = "smokewgt09";
880   std::string appid = "smokewgt09.RecoveryModeForInstallation";
881   bf::path recovery_file = FindRecoveryFile();
882   ASSERT_FALSE(recovery_file.empty());
883   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
884       ci::AppInstaller::Result::OK);
885   CheckPackageNonExistance(pkgid, {appid});
886 }
887
888 TEST_F(SmokeTest, RecoveryMode_ForUpdate) {
889   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForUpdate.wgt";
890   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForUpdate_2.wgt";
891   RemoveAllRecoveryFiles();
892   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
893   std::string pkgid = "smokewgt10";
894   std::string appid = "smokewgt10.RecoveryModeForUpdate";
895   AddDataFiles(pkgid, kTestUserId);
896   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
897   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
898   ASSERT_NE(backend_crash.Wait(), 0);
899
900   bf::path recovery_file = FindRecoveryFile();
901   ASSERT_FALSE(recovery_file.empty());
902   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
903             ci::AppInstaller::Result::OK);
904   ValidatePackage(pkgid, {appid});
905
906   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
907   ValidateDataFiles(pkgid, kTestUserId);
908 }
909
910 TEST_F(SmokeTest, RecoveryMode_ForDelta) {
911   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForDelta.wgt";
912   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForDelta.delta";
913   RemoveAllRecoveryFiles();
914   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
915   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
916   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
917   ASSERT_NE(backend_crash.Wait(), 0);
918
919   std::string pkgid = "smokewgt30";
920   std::string appid = "smokewgt30.RecoveryModeForDelta";
921   bf::path recovery_file = FindRecoveryFile();
922   ASSERT_FALSE(recovery_file.empty());
923   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
924             ci::AppInstaller::Result::OK);
925   ValidatePackage(pkgid, {appid});
926
927   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
928 }
929
930 TEST_F(SmokeTest, RecoveryMode_ForMountInstall) {
931   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForMountInstall.wgt";
932   RemoveAllRecoveryFiles();
933   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
934   backend_crash.Run("-w", path.string(), "-u", kTestUserIdStr.c_str());
935   ASSERT_NE(backend_crash.Wait(), 0);
936
937   std::string pkgid = "smokewgt31";
938   std::string appid = "smokewgt31.RecoveryModeForMountInstall";
939   bf::path recovery_file = FindRecoveryFile();
940   ASSERT_FALSE(recovery_file.empty());
941   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
942             ci::AppInstaller::Result::OK);
943   CheckPackageNonExistance(pkgid, {appid});
944 }
945
946 TEST_F(SmokeTest, RecoveryMode_ForMountUpdate) {
947   bf::path path_old =
948       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate.wgt";
949   bf::path path_new =
950       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate_2.wgt";
951   std::string pkgid = "smokewgt32";
952   std::string appid = "smokewgt32.RecoveryModeForMountUpdate";
953   RemoveAllRecoveryFiles();
954   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
955             ci::AppInstaller::Result::OK);
956   AddDataFiles(pkgid, kTestUserId);
957   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
958   backend_crash.Run("-w", path_new.string(), "-u", kTestUserIdStr.c_str());
959   ASSERT_NE(backend_crash.Wait(), 0);
960
961   // Filesystem may be mounted after crash
962   ScopedTzipInterface poweroff_unmount_interface(pkgid);
963   poweroff_unmount_interface.Release();
964
965   bf::path recovery_file = FindRecoveryFile();
966   ASSERT_FALSE(recovery_file.empty());
967   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
968             ci::AppInstaller::Result::OK);
969
970   ScopedTzipInterface interface(pkgid);
971   ValidatePackage(pkgid, {appid});
972   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
973   ValidateDataFiles(pkgid, kTestUserId);
974 }
975
976 TEST_F(SmokeTest, InstallationMode_GoodSignature) {
977   // pkgid: smokewgt08
978   bf::path path = kSmokePackagesDirectory / "InstallationMode_GoodSignature.wgt";  // NOLINT
979   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
980 }
981
982 TEST_F(SmokeTest, InstallationMode_WrongSignature) {
983   // pkgid: smokewgt12
984   bf::path path = kSmokePackagesDirectory / "InstallationMode_WrongSignature.wgt";  // NOLINT
985   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::ERROR);
986 }
987
988 TEST_F(SmokeTest, InstallationMode_Rollback) {
989   bf::path path = kSmokePackagesDirectory / "InstallationMode_Rollback.wgt";
990   std::string pkgid = "smokewgt06";
991   std::string appid = "smokewgt06.InstallationModeRollback";
992   ASSERT_EQ(Install(path, PackageType::WGT, RequestResult::FAIL),
993             ci::AppInstaller::Result::ERROR);
994   CheckPackageNonExistance(pkgid, {appid});
995 }
996
997 TEST_F(SmokeTest, UpdateMode_Rollback) {
998   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Rollback.wgt";
999   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Rollback_2.wgt";
1000   std::string pkgid = "smokewgt07";
1001   std::string appid = "smokewgt07.UpdateModeRollback";
1002   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
1003   AddDataFiles(pkgid, kTestUserId);
1004   ASSERT_EQ(Install(path_new, PackageType::WGT, RequestResult::FAIL),
1005                     ci::AppInstaller::Result::ERROR);
1006   ValidatePackage(pkgid, {appid});
1007
1008   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1009   ValidateDataFiles(pkgid, kTestUserId);
1010 }
1011
1012 TEST_F(SmokeTest, DeltaMode_Rollback) {
1013   bf::path path = kSmokePackagesDirectory / "DeltaMode_Rollback.wgt";
1014   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Rollback.delta";
1015   std::string pkgid = "smokewgt01";
1016   std::string appid = "smokewgt01.DeltaMode";
1017   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1018   AddDataFiles(pkgid, kTestUserId);
1019   ASSERT_EQ(Install(delta_package, PackageType::WGT, RequestResult::FAIL),
1020             ci::AppInstaller::Result::ERROR);
1021
1022   ValidatePackage(pkgid, {appid});
1023   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED",
1024                                            "version 1\n"));
1025   ValidateDataFiles(pkgid, kTestUserId);
1026   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
1027                          "res/wgt/DELETED"));
1028   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
1029                           "res/wgt/ADDED"));
1030 }
1031
1032 TEST_F(SmokeTest, InstallationMode_Hybrid) {
1033   bf::path path = kSmokePackagesDirectory / "InstallationMode_Hybrid.wgt";
1034   std::string pkgid = "smokehyb01";
1035   // Excutable for native app doesn't create symlink
1036   std::string appid1 = "smokehyb01.Web";
1037   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
1038   ValidatePackage(pkgid, {appid1});
1039 }
1040
1041 TEST_F(SmokeTest, UpdateMode_Hybrid) {
1042   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Hybrid.wgt";
1043   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Hybrid_2.wgt";
1044   std::string pkgid = "smokehyb02";
1045   std::string appid1 = "smokehyb02.Web";
1046   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
1047             ci::AppInstaller::Result::OK);
1048 //  AddDataFiles(pkgid, kTestUserId);
1049   ASSERT_EQ(Install(path_new, PackageType::HYBRID),
1050             ci::AppInstaller::Result::OK);
1051   ValidatePackage(pkgid, {appid1});
1052
1053   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
1054   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "VERSION", "2\n"));
1055 //  ValidateDataFiles(pkgid, kTestUserId);
1056 }
1057
1058 TEST_F(SmokeTest, DeinstallationMode_Hybrid) {
1059   bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Hybrid.wgt";
1060   std::string pkgid = "smokehyb03";
1061   std::string appid1 = "smokehyb03.Web";
1062   ASSERT_EQ(Install(path, PackageType::HYBRID),
1063             ci::AppInstaller::Result::OK);
1064   ASSERT_EQ(Uninstall(pkgid, PackageType::HYBRID, false),
1065             ci::AppInstaller::Result::OK);
1066   CheckPackageNonExistance(pkgid, {appid1});
1067 }
1068
1069 TEST_F(SmokeTest, DeltaMode_Hybrid) {
1070   bf::path path = kSmokePackagesDirectory / "DeltaMode_Hybrid.wgt";
1071   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Hybrid.delta";
1072   std::string pkgid = "smokehyb04";
1073   std::string appid1 = "smokehyb04.Web";
1074   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
1075             ci::AppInstaller::Result::OK);
1076   ValidatePackage(pkgid, {appid1});
1077
1078   // Check delta modifications
1079   bf::path root_path = ci::GetRootAppPath(false,
1080       kTestUserId);
1081   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
1082   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
1083   ASSERT_FALSE(bf::exists(root_path / pkgid / "lib" / "DELETED"));
1084   ASSERT_TRUE(bf::exists(root_path / pkgid / "lib" / "ADDED"));
1085   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "css" / "style.css"));  // NOLINT
1086   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
1087   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "js" / "main.js"));
1088   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n"));  // NOLINT
1089   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/MODIFIED", "version 2\n"));  // NOLINT
1090 }
1091
1092 TEST_F(SmokeTest, MountInstallationMode_Hybrid) {
1093   bf::path path = kSmokePackagesDirectory / "MountInstallationMode_Hybrid.wgt";
1094   std::string pkgid = "smokehyb05";
1095   std::string appid1 = "smokehyb05.web";
1096   ASSERT_EQ(MountInstall(path, PackageType::HYBRID),
1097             ci::AppInstaller::Result::OK);
1098   ScopedTzipInterface interface(pkgid);
1099   ValidatePackage(pkgid, {appid1});
1100 }
1101
1102 TEST_F(SmokeTest, MountUpdateMode_Hybrid) {
1103   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Hybrid.wgt";
1104   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_Hybrid_2.wgt";
1105   std::string pkgid = "smokehyb06";
1106   std::string appid1 = "smokehyb06.web";
1107   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
1108             ci::AppInstaller::Result::OK);
1109   AddDataFiles(pkgid, kTestUserId);
1110   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID),
1111             ci::AppInstaller::Result::OK);
1112   ScopedTzipInterface interface(pkgid);
1113   ValidatePackage(pkgid, {appid1});
1114
1115   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
1116   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "2\n"));
1117   ValidateDataFiles(pkgid, kTestUserId);
1118 }
1119
1120 TEST_F(SmokeTest, InstallationMode_Rollback_Hybrid) {
1121   bf::path path = kSmokePackagesDirectory /
1122       "InstallationMode_Rollback_Hybrid.wgt";
1123   std::string pkgid = "smokehyb07";
1124   std::string appid1 = "smokehyb07.web";
1125   ASSERT_EQ(Install(path, PackageType::HYBRID, RequestResult::FAIL),
1126             ci::AppInstaller::Result::ERROR);
1127   CheckPackageNonExistance(pkgid, {appid1});
1128 }
1129
1130 TEST_F(SmokeTest, UpdateMode_Rollback_Hybrid) {
1131   bf::path path_old = kSmokePackagesDirectory /
1132       "UpdateMode_Rollback_Hybrid.wgt";
1133   bf::path path_new = kSmokePackagesDirectory /
1134       "UpdateMode_Rollback_Hybrid_2.wgt";
1135   std::string pkgid = "smokehyb08";
1136   std::string appid1 = "smokehyb08.web";
1137   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
1138             ci::AppInstaller::Result::OK);
1139   AddDataFiles(pkgid, kTestUserId);
1140   ASSERT_EQ(Install(path_new, PackageType::HYBRID,
1141       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
1142   ValidatePackage(pkgid, {appid1});
1143
1144   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1145   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
1146   ValidateDataFiles(pkgid, kTestUserId);
1147 }
1148
1149 TEST_F(SmokeTest, DeltaMode_Rollback_Hybrid) {
1150   bf::path path = kSmokePackagesDirectory / "DeltaMode_Rollback_Hybrid.wgt";
1151   bf::path delta_package = kSmokePackagesDirectory /
1152       "DeltaMode_Rollback_Hybrid.delta";
1153   std::string pkgid = "smokehyb11";
1154   std::string appid1 = "smokehyb11.web";
1155   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
1156   AddDataFiles(pkgid, kTestUserId);
1157   ASSERT_EQ(Install(delta_package, PackageType::HYBRID, RequestResult::FAIL),
1158             ci::AppInstaller::Result::ERROR);
1159
1160   ValidatePackage(pkgid, {appid1});
1161   // Check delta modifications
1162   bf::path root_path = GetPackageRoot(pkgid, kTestUserId);
1163   ASSERT_TRUE(bf::exists(root_path / "res" / "wgt" / "DELETED"));
1164   ASSERT_FALSE(bf::exists(root_path / "res" / "wgt" / "ADDED"));
1165   ASSERT_TRUE(bf::exists(root_path / "lib" / "DELETED"));
1166   ASSERT_FALSE(bf::exists(root_path / "lib" / "ADDED"));
1167   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED",
1168                                            "version 1\n"));
1169   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/MODIFIED",
1170                                            "version 1\n"));
1171   ValidateDataFiles(pkgid, kTestUserId);
1172 }
1173
1174 TEST_F(SmokeTest, MountInstallationMode_Rollback_Hybrid) {
1175   bf::path path = kSmokePackagesDirectory /
1176       "MountInstallationMode_Rollback_Hybrid.wgt";
1177   std::string pkgid = "smokehyb09";
1178   std::string appid1 = "smokehyb09.web";
1179   ASSERT_EQ(MountInstall(path, PackageType::HYBRID, RequestResult::FAIL),
1180       ci::AppInstaller::Result::ERROR);
1181   ScopedTzipInterface interface(pkgid);
1182   CheckPackageNonExistance(pkgid, {appid1});
1183 }
1184
1185 TEST_F(SmokeTest, MountUpdateMode_Rollback_Hybrid) {
1186   bf::path path_old = kSmokePackagesDirectory /
1187       "MountUpdateMode_Rollback_Hybrid.wgt";
1188   bf::path path_new = kSmokePackagesDirectory /
1189       "MountUpdateMode_Rollback_Hybrid_2.wgt";
1190   std::string pkgid = "smokehyb10";
1191   std::string appid1 = "smokehyb10.web";
1192   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
1193             ci::AppInstaller::Result::OK);
1194   AddDataFiles(pkgid, kTestUserId);
1195   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID,
1196       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
1197   ScopedTzipInterface interface(pkgid);
1198   ValidatePackage(pkgid, {appid1});
1199
1200   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1201   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
1202   ValidateDataFiles(pkgid, kTestUserId);
1203 }
1204
1205 TEST_F(SmokeTest, MountInstallationMode) {
1206   bf::path path = kSmokePackagesDirectory / "MountInstallationMode.wgt";
1207   std::string pkgid = "smokewgt28";
1208   std::string appid = "smokewgt28.InstallationMode";
1209   ASSERT_EQ(MountInstall(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1210   ScopedTzipInterface interface(pkgid);
1211   ValidatePackage(pkgid, {appid});
1212 }
1213
1214 TEST_F(SmokeTest, MountUpdateMode) {
1215   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode.wgt";
1216   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_2.wgt";
1217   std::string pkgid = "smokewgt29";
1218   std::string appid = "smokewgt29.UpdateMode";
1219   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
1220             ci::AppInstaller::Result::OK);
1221   AddDataFiles(pkgid, kTestUserId);
1222   ASSERT_EQ(MountInstall(path_new, PackageType::WGT),
1223             ci::AppInstaller::Result::OK);
1224   ScopedTzipInterface interface(pkgid);
1225   ValidatePackage(pkgid, {appid});
1226
1227   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
1228   ValidateDataFiles(pkgid, kTestUserId);
1229 }
1230
1231 TEST_F(SmokeTest, MountInstallationMode_Rollback) {
1232   bf::path path =
1233       kSmokePackagesDirectory / "MountInstallationMode_Rollback.wgt";
1234   std::string pkgid = "smokewgt33";
1235   std::string appid = "smokewgt33.web";
1236   ASSERT_EQ(MountInstall(path, PackageType::WGT, RequestResult::FAIL),
1237             ci::AppInstaller::Result::ERROR);
1238   ScopedTzipInterface interface(pkgid);
1239   CheckPackageNonExistance(pkgid, {appid});
1240 }
1241
1242 TEST_F(SmokeTest, MountUpdateMode_Rollback) {
1243   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Rollback.wgt";
1244   bf::path path_new =
1245       kSmokePackagesDirectory / "MountUpdateMode_Rollback_2.wgt";
1246   std::string pkgid = "smokewgt34";
1247   std::string appid = "smokewgt34.web";
1248   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
1249             ci::AppInstaller::Result::OK);
1250   AddDataFiles(pkgid, kTestUserId);
1251   ASSERT_EQ(MountInstall(path_new, PackageType::WGT,
1252       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
1253   ScopedTzipInterface interface(pkgid);
1254   ValidatePackage(pkgid, {appid});
1255
1256   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1257   ValidateDataFiles(pkgid, kTestUserId);
1258 }
1259
1260 TEST_F(SmokeTest, UserDefinedPlugins) {
1261   bf::path path = kSmokePackagesDirectory / "SimpleEchoPrivilege.wgt";
1262   std::string pkgid = "smokewgt02";
1263   std::string appid = "smokewgt02.SimpleEcho";
1264   std::string call_privilege = "http://tizen.org/privilege/call";
1265   std::string location_privilege = "http://tizen.org/privilege/location";
1266   std::string power_privilege = "http://tizen.org/privilege/power";
1267
1268   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1269   ValidatePackage(pkgid, {appid});
1270   std::vector<std::string> res;
1271   ASSERT_TRUE(ci::QueryPrivilegesForPkgId(pkgid, kTestUserId, &res));
1272   ASSERT_TRUE(std::find(res.begin(), res.end(), call_privilege) != res.end());
1273   ASSERT_TRUE(std::find(res.begin(), res.end(), location_privilege)
1274           != res.end());
1275   ASSERT_TRUE(std::find(res.begin(), res.end(), power_privilege) != res.end());
1276 }
1277
1278 TEST_F(SmokeTest, InstallExternalMode) {
1279   ASSERT_TRUE(CheckAvailableExternalPath());
1280   bf::path path = kSmokePackagesDirectory / "InstallExternalMode.wgt";
1281   std::string pkgid = "smokewgt35";
1282   std::string appid = "smokewgt35.web";
1283   ASSERT_EQ(InstallExternal(path, PackageType::WGT),
1284       ci::AppInstaller::Result::OK);
1285   ValidateExternalPackage(pkgid, {appid});
1286 }
1287
1288 TEST_F(SmokeTest, MigrateLegacyExternalImageMode) {
1289   ASSERT_TRUE(CheckAvailableExternalPath());
1290   bf::path path =
1291       kSmokePackagesDirectory / "MigrateLegacyExternalImageMode.wgt";
1292   std::string pkgid = "smokewgt36";
1293   std::string appid = "smokewgt36.web";
1294   bf::path legacy_path = kSmokePackagesDirectory / kLegacyExtImageDir;
1295   ASSERT_EQ(MigrateLegacyExternalImage(pkgid, path, legacy_path,
1296       PackageType::WGT), ci::AppInstaller::Result::OK);
1297   ValidateExternalPackage(pkgid, {appid});
1298 }
1299
1300 TEST_F(SmokeTest, InstallationMode_Preload) {
1301   ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
1302   bf::path path = kSmokePackagesDirectory / "InstallationMode_Preload.wgt";
1303   std::string pkgid = "smokewgt37";
1304   std::string appid = "smokewgt37.InstallationModePreload";
1305   ASSERT_EQ(InstallPreload(path, PackageType::WGT),
1306             ci::AppInstaller::Result::OK);
1307   ValidatePackage(pkgid, {appid}, true);
1308 }
1309
1310 TEST_F(SmokeTest, UpdateMode_Preload) {
1311   ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
1312   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Preload.wgt";
1313   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Preload2.wgt";
1314   std::string pkgid = "smokewgt38";
1315   std::string appid = "smokewgt38.UpdateModePreload";
1316   ASSERT_EQ(InstallPreload(path_old, PackageType::WGT),
1317             ci::AppInstaller::Result::OK);
1318   AddDataFiles(pkgid, kTestUserId);
1319   ASSERT_EQ(InstallPreload(path_new, PackageType::WGT),
1320             ci::AppInstaller::Result::OK);
1321   ValidatePackage(pkgid, {appid}, true);
1322
1323   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2",
1324                                            true));
1325   ValidateDataFiles(pkgid, kTestUserId);
1326 }
1327
1328 TEST_F(SmokeTest, DeinstallationMode_Preload) {
1329   ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
1330   bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Preload.wgt";
1331   std::string pkgid = "smokewgt39";
1332   std::string appid = "smokewgt39.DeinstallationModePreload";
1333   ASSERT_EQ(InstallPreload(path, PackageType::WGT),
1334             ci::AppInstaller::Result::OK);
1335   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT, true),
1336             ci::AppInstaller::Result::OK);
1337   CheckPackageReadonlyNonExistance(pkgid, {appid});
1338 }
1339
1340 TEST_F(SmokeTest, SharedRes24) {
1341   bf::path path = kSmokePackagesDirectory / "SharedRes24.wgt";
1342   std::string pkgid = "smokeSh2xx";
1343   std::string appid = "smokeSh2xx.SharedRes24";
1344   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1345   ValidatePackage(pkgid, {appid});
1346   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
1347   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "NOT-SHARED-WGT"));  // NOLINT
1348   ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "NOT-SHARED-WGT"));  // NOLINT
1349 }
1350
1351 TEST_F(SmokeTest, SharedRes30) {
1352   bf::path path = kSmokePackagesDirectory / "SharedRes30.wgt";
1353   std::string pkgid = "smokeSh3xx";
1354   std::string appid = "smokeSh3xx.SharedRes30";
1355   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1356   ValidatePackage(pkgid, {appid});
1357   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
1358   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT"));  // NOLINT
1359   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT"));  // NOLINT
1360 }
1361
1362 TEST_F(SmokeTest, SharedRes30Delta) {
1363   bf::path path = kSmokePackagesDirectory / "SharedRes30Delta.wgt";
1364   bf::path delta_package = kSmokePackagesDirectory / "SharedRes30Delta.delta";
1365   std::string pkgid = "smokeSh3De";
1366   std::string appid = "smokeSh3De.SharedRes30Delta";
1367   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
1368             ci::AppInstaller::Result::OK);
1369   ValidatePackage(pkgid, {appid});
1370   // Check delta modifications
1371   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
1372   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-2"));  // NOLINT
1373   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT-2"));  // NOLINT
1374   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-1"));  // NOLINT
1375   ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "SHARED-WGT-1"));  // NOLINT
1376 }
1377
1378 TEST_F(SmokeTest, SharedRes30Hybrid) {
1379   bf::path path = kSmokePackagesDirectory / "SharedRes30Hybrid.wgt";
1380   std::string pkgid = "smokeSh3Hy";
1381   std::string appid1 = "smokeSh3Hy.SharedRes30Hybrid";
1382   std::string appid2 = "sharedres30hybridserivce";
1383   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
1384   ValidatePackage(pkgid, {appid1, appid2});
1385   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
1386   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT"));  // NOLINT
1387   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT"));  // NOLINT
1388   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "shared" / "res" / "SHARED-TPK"));  // NOLINT
1389   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-TPK"));  // NOLINT
1390 }
1391
1392 TEST_F(SmokeTest, SharedRes30HybridDelta) {
1393   bf::path path = kSmokePackagesDirectory / "SharedRes30HybridDelta.wgt";
1394   bf::path delta_package = kSmokePackagesDirectory / "SharedRes30HybridDelta.delta";
1395   std::string pkgid = "smokeSh3HD";
1396   std::string appid1 = "smokeSh3HD.SharedRes30HybridDelta";
1397   std::string appid2 = "sharedres30hybriddeltaserivce";
1398   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
1399             ci::AppInstaller::Result::OK);
1400   ValidatePackage(pkgid, {appid1, appid2});
1401   // Check delta modifications
1402   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
1403   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-2"));  // NOLINT
1404   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT-2"));  // NOLINT
1405   ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "shared" / "res" / "SHARED-TPK-2"));  // NOLINT
1406   ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-TPK-2"));  // NOLINT
1407   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-1"));  // NOLINT
1408   ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "SHARED-WGT-1"));  // NOLINT
1409 }
1410
1411 }  // namespace common_installer
1412
1413 int main(int argc,  char** argv) {
1414   testing::InitGoogleTest(&argc, argv);
1415   testing::AddGlobalTestEnvironment(
1416       new common_installer::SmokeEnvironment(kGlobalUserUid));
1417   return RUN_ALL_TESTS();
1418 }