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