Smoke tests- check if package dont exist in skel directory
[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       bf::path skel_path(kSkelDir);
397       ASSERT_FALSE(bf::exists(skel_path / pkgid));
398       for (auto& l : list) {
399         bf::path root_path = ci::GetRootAppPath(false, std::get<0>(l));
400         bf::path package_path = root_path / pkgid;
401         ASSERT_FALSE(bf::exists(package_path));
402       }
403   }
404 }
405
406 void CheckPackageReadonlyNonExistance(const std::string& pkgid,
407                                       const std::vector<std::string>& appids) {
408   ASSERT_FALSE(ci::QueryIsPackageInstalled(
409       pkgid, ci::GetRequestMode(kTestUserId), kTestUserId));
410   PackageCheckCleanup(pkgid, appids, true);
411 }
412
413 std::unique_ptr<ci::AppQueryInterface> CreateQueryInterface() {
414   std::unique_ptr<ci::AppQueryInterface> query_interface(
415       new wgt::WgtAppQueryInterface());
416   return query_interface;
417 }
418
419 std::unique_ptr<ci::AppInstaller> CreateInstaller(ci::PkgMgrPtr pkgmgr,
420                                                   PackageType type) {
421   switch (type) {
422     case PackageType::WGT:
423       return std::unique_ptr<ci::AppInstaller>(new wgt::WgtInstaller(pkgmgr));
424     case PackageType::HYBRID:
425       return std::unique_ptr<ci::AppInstaller>(
426           new hybrid::HybridInstaller(pkgmgr));
427     default:
428       LOG(ERROR) << "Unknown installer type";
429       return nullptr;
430   }
431 }
432
433 ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr,
434                                                  PackageType type,
435                                                  RequestResult mode) {
436   std::unique_ptr<ci::AppInstaller> installer = CreateInstaller(pkgmgr, type);
437   switch (mode) {
438   case RequestResult::FAIL:
439     installer->AddStep<ci::configuration::StepFail>();
440     break;
441   default:
442     break;
443   }
444   return installer->Run();
445 }
446 ci::AppInstaller::Result CallBackend(int argc,
447                                      const char* argv[],
448                                      PackageType type,
449                                      RequestResult mode = RequestResult::NORMAL
450                                      ) {
451   TestPkgmgrInstaller pkgmgr_installer;
452   std::unique_ptr<ci::AppQueryInterface> query_interface =
453       CreateQueryInterface();
454   auto pkgmgr =
455       ci::PkgMgrInterface::Create(argc, const_cast<char**>(argv),
456                                   &pkgmgr_installer, query_interface.get());
457   if (!pkgmgr) {
458     LOG(ERROR) << "Failed to initialize pkgmgr interface";
459     return ci::AppInstaller::Result::UNKNOWN;
460   }
461   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
462 }
463
464 ci::AppInstaller::Result Install(const bf::path& path,
465                                  PackageType type,
466                                  RequestResult mode = RequestResult::NORMAL) {
467   const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()};
468   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
469 }
470
471 ci::AppInstaller::Result InstallPreload(const bf::path& path, PackageType type,
472     RequestResult mode = RequestResult::NORMAL) {
473   const char* argv[] = {"", "-i", path.c_str(), "--preload"};
474   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
475 }
476
477 bool CheckAvailableExternalPath() {
478   bf::path ext_mount_path = ci::GetExternalCardPath();
479   LOG(DEBUG) << "ext_mount_path :" << ext_mount_path;
480   if (ext_mount_path.empty()) {
481     LOG(ERROR) << "Sdcard not exists!";
482     return false;
483   }
484   return true;
485 }
486
487 ci::AppInstaller::Result InstallExternal(const bf::path& path,
488                                  PackageType type,
489                                  RequestResult mode = RequestResult::NORMAL) {
490   int default_storage = 0;
491   vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
492                 &default_storage);
493   vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, 1);
494
495   const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()};
496   ci::AppInstaller::Result result =
497                           CallBackend(SIZEOFARRAY(argv), argv, type, mode);
498
499   vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
500                 default_storage);
501   return result;
502 }
503
504 ci::AppInstaller::Result MigrateLegacyExternalImage(const std::string& pkgid,
505                                  const bf::path& path,
506                                  const bf::path& legacy_path,
507                                  PackageType type,
508                                  RequestResult mode = RequestResult::NORMAL) {
509   if (InstallExternal(path, type) != ci::AppInstaller::Result::OK) {
510     LOG(ERROR) << "Failed to install application. Cannot perform Migrate";
511     return ci::AppInstaller::Result::ERROR;
512   }
513
514   bf::path ext_mount_path = ci::GetExternalCardPath();
515   if (bf::is_empty(ext_mount_path)) {
516     LOG(ERROR) << "Sdcard not exists!";
517     return ci::AppInstaller::Result::ERROR;
518   }
519   bf::path app2sd_path = ext_mount_path / "app2sd";
520
521   char* image_name = app2ext_usr_getname_image(pkgid.c_str(),
522                      kGlobalUserUid);
523   if (!image_name) {
524     LOG(ERROR) << "Failed to get external image name";
525     return ci::AppInstaller::Result::ERROR;
526   }
527   bf::path org_image = app2sd_path / image_name;
528   free(image_name);
529
530   bs::error_code error;
531   bf::remove(org_image, error);
532   if (error) {
533     LOG(ERROR) << "Failed to remove org image";
534     return ci::AppInstaller::Result::ERROR;
535   }
536
537   bf::path db_path = tzplatform_getenv(TZ_SYS_DB);
538   bf::path app2sd_db = db_path / ".app2sd.db";
539   bf::path app2sd_db_journal = db_path / ".app2sd.db-journal";
540   bf::remove(app2sd_db, error);
541   if (error) {
542     LOG(ERROR) << "Failed to remove app2sd db";
543     return ci::AppInstaller::Result::ERROR;
544   }
545   bf::remove(app2sd_db_journal, error);
546   if (error) {
547     LOG(ERROR) << "Failed to remove app2sd journal db";
548     return ci::AppInstaller::Result::ERROR;
549   }
550
551   bf::path app2sd_migrate_db = legacy_path / kMigrateTestDBName;
552   if (!ci::CopyFile(app2sd_migrate_db, app2sd_db)) {
553     LOG(ERROR) << "Failed to copy test db";
554     return ci::AppInstaller::Result::ERROR;
555   }
556
557   bf::path legacy_src = legacy_path / pkgid;
558   bf::path legacy_dst = app2sd_path / pkgid;
559   if (!ci::CopyFile(legacy_src, legacy_dst)) {
560     LOG(ERROR) << "Failed to copy test image";
561     return ci::AppInstaller::Result::ERROR;
562   }
563   const char* argv[] = {"", "--migrate-extimg", pkgid.c_str(),
564                        "-u", kDefaultUserIdStr.c_str()};
565   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
566 }
567
568 ci::AppInstaller::Result MountInstall(const bf::path& path,
569     PackageType type, RequestResult mode = RequestResult::NORMAL) {
570   const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()};
571   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
572 }
573
574 ci::AppInstaller::Result Uninstall(const std::string& pkgid,
575                                    PackageType type,
576                                    bool is_preload,
577                                    RequestResult mode = RequestResult::NORMAL) {
578   if (is_preload) {
579     const char* argv[] = {"", "-d", pkgid.c_str(), "--preload",
580         "--force-remove"};
581     return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
582   } else {
583     const char* argv[] = {"", "-d", pkgid.c_str(), "-u",
584         kTestUserIdStr.c_str()};
585     return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
586   }
587 }
588
589 ci::AppInstaller::Result RDSUpdate(const bf::path& path,
590                                    const std::string& pkgid,
591                                    PackageType type,
592                                    RequestResult mode = RequestResult::NORMAL) {
593   if (Install(path, type) != ci::AppInstaller::Result::OK) {
594     LOG(ERROR) << "Failed to install application. Cannot perform RDS";
595     return ci::AppInstaller::Result::UNKNOWN;
596   }
597   const char* argv[] = {"", "-r", pkgid.c_str(), "-u",
598                         kTestUserIdStr.c_str()};
599   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
600 }
601
602 ci::AppInstaller::Result DeltaInstall(const bf::path& path,
603     const bf::path& delta_package, PackageType type) {
604   if (Install(path, type) != ci::AppInstaller::Result::OK) {
605     LOG(ERROR) << "Failed to install application. Cannot perform delta update";
606     return ci::AppInstaller::Result::UNKNOWN;
607   }
608   return Install(delta_package, type);
609 }
610
611 ci::AppInstaller::Result EnablePackage(const std::string& pkgid,
612                                   PackageType type,
613                                   RequestResult mode = RequestResult::NORMAL) {
614   const char* argv[] = {"", "-A", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
615   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
616 }
617
618 ci::AppInstaller::Result DisablePackage(const std::string& pkgid,
619                                   PackageType type,
620                                   RequestResult mode = RequestResult::NORMAL) {
621   const char* argv[] = {"", "-D", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
622   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
623 }
624
625 ci::AppInstaller::Result Recover(const bf::path& recovery_file,
626                                  PackageType type,
627                                  RequestResult mode = RequestResult::NORMAL) {
628   const char* argv[] = {"", "-b", recovery_file.c_str(), "-u",
629                         kTestUserIdStr.c_str()};
630   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
631 }
632
633 void BackupPath(const bf::path& path) {
634   bf::path backup_path = path.string() + ".bck";
635   std::cout << "Backup path: " << path << " to " << backup_path << std::endl;
636   bs::error_code error;
637   bf::remove_all(backup_path, error);
638   if (error)
639     LOG(ERROR) << "Remove failed: " << backup_path
640                << " (" << error.message() << ")";
641   if (bf::exists(path)) {
642     bf::rename(path, backup_path, error);
643     if (error)
644       LOG(ERROR) << "Failed to setup test environment. Does some previous"
645                  << " test crashed? Path: "
646                  << backup_path << " should not exist.";
647     assert(!error);
648   }
649 }
650
651 void RestorePath(const bf::path& path) {
652   bf::path backup_path = path.string() + ".bck";
653   std::cout << "Restore path: " << path << " from " << backup_path << std::endl;
654   bs::error_code error;
655   bf::remove_all(path, error);
656   if (error)
657     LOG(ERROR) << "Remove failed: " << path
658                << " (" << error.message() << ")";
659   if (bf::exists(backup_path)) {
660     bf::rename(backup_path, path, error);
661     if (error)
662       LOG(ERROR) << "Failed to restore backup path: " << backup_path
663                  << " (" << error.message() << ")";
664   }
665 }
666
667 std::vector<bf::path> SetupBackupDirectories(uid_t uid) {
668   std::vector<bf::path> entries;
669   bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB));
670   if (uid != kGlobalUserUid)
671     db_dir = db_dir / "user" / std::to_string(uid);
672   for (auto e : kDBEntries) {
673     bf::path path = db_dir / e;
674     entries.emplace_back(path);
675   }
676
677   if (getuid() == 0) {
678     entries.emplace_back(kPreloadApps);
679     entries.emplace_back(kPreloadManifestDir);
680     entries.emplace_back(kPreloadIcons);
681   }
682
683   if (uid == kGlobalUserUid) {
684     entries.emplace_back(kSkelDir);
685     entries.emplace_back(kGlobalManifestDir);
686     ci::UserList list = ci::GetUserList();
687     for (auto l : list) {
688       bf::path apps = std::get<2>(l) / "apps_rw";
689       entries.emplace_back(apps);
690     }
691   } else {
692     tzplatform_set_user(uid);
693     bf::path approot = tzplatform_getenv(TZ_USER_APPROOT);
694     tzplatform_reset_user();
695     entries.emplace_back(approot);
696   }
697
698   bf::path apps_rw = ci::GetRootAppPath(false, uid);
699   entries.emplace_back(apps_rw);
700
701   return entries;
702 }
703
704 void UninstallAllAppsInDirectory(bf::path dir, bool is_preload) {
705   if(bf::exists(dir)) {
706     for (auto& dir_entry : boost::make_iterator_range(
707         bf::directory_iterator(dir), bf::directory_iterator())) {
708       if (dir_entry.path().string().find("smoke") != std::string::npos &&
709           bf::is_directory(dir_entry)) {
710         if(Uninstall(dir_entry.path().filename().string(), PackageType::WGT,
711             is_preload, RequestResult::NORMAL) !=
712             ci::AppInstaller::Result::OK) {
713           LOG(ERROR) << "Cannot uninstall smoke test app: "
714               << dir_entry.path().filename().string();
715         }
716       }
717     }
718   }
719 }
720
721 void UninstallAllSmokeApps(uid_t uid) {
722   if (getuid() == 0) {
723     bf::path root_path = kPreloadApps;
724     UninstallAllAppsInDirectory(root_path, true);
725   }
726   bf::path apps_rw = ci::GetRootAppPath(false, uid);
727   UninstallAllAppsInDirectory(apps_rw, false);
728 }
729
730 }  // namespace
731
732 namespace common_installer {
733
734 class SmokeEnvironment : public testing::Environment {
735  public:
736   explicit SmokeEnvironment(uid_t uid) : uid_(uid) {
737   }
738   void SetUp() override {
739     backups_ = SetupBackupDirectories(uid_);
740     for (auto& path : backups_)
741       BackupPath(path);
742   }
743   void TearDown() override {
744     UninstallAllSmokeApps(uid_);
745     for (auto& path : backups_)
746       RestorePath(path);
747   }
748
749  private:
750   uid_t uid_;
751   std::vector<bf::path> backups_;
752 };
753
754 class SmokeTest : public testing::Test {
755 };
756
757 TEST_F(SmokeTest, InstallationMode) {
758   bf::path path = kSmokePackagesDirectory / "InstallationMode.wgt";
759   std::string pkgid = "smokewgt03";
760   std::string appid = "smokewgt03.InstallationMode";
761   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
762   ValidatePackage(pkgid, {appid});
763 }
764
765 TEST_F(SmokeTest, UpdateMode) {
766   bf::path path_old = kSmokePackagesDirectory / "UpdateMode.wgt";
767   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_2.wgt";
768   std::string pkgid = "smokewgt04";
769   std::string appid = "smokewgt04.UpdateMode";
770   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
771   AddDataFiles(pkgid, kTestUserId);
772   ASSERT_EQ(Install(path_new, PackageType::WGT), ci::AppInstaller::Result::OK);
773   ValidatePackage(pkgid, {appid});
774
775   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
776   ValidateDataFiles(pkgid, kTestUserId);
777 }
778
779 TEST_F(SmokeTest, DeinstallationMode) {
780   bf::path path = kSmokePackagesDirectory / "DeinstallationMode.wgt";
781   std::string pkgid = "smokewgt05";
782   std::string appid = "smokewgt05.DeinstallationMode";
783   ASSERT_EQ(Install(path, PackageType::WGT),
784             ci::AppInstaller::Result::OK);
785   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT, false),
786             ci::AppInstaller::Result::OK);
787   CheckPackageNonExistance(pkgid, {appid});
788 }
789
790 TEST_F(SmokeTest, RDSMode) {
791   bf::path path = kSmokePackagesDirectory / "RDSMode.wgt";
792   std::string pkgid = "smokewgt11";
793   std::string appid = "smokewgt11.RDSMode";
794   bf::path delta_directory = kSmokePackagesDirectory / "delta_dir/";
795   bf::path sdk_expected_directory =
796       bf::path(ci::GetRootAppPath(false, kTestUserId)) / "tmp" / pkgid;
797   bs::error_code error;
798   bf::create_directories(sdk_expected_directory.parent_path(), error);
799   ASSERT_FALSE(error);
800   ASSERT_TRUE(CopyDir(delta_directory, sdk_expected_directory));
801   ASSERT_EQ(RDSUpdate(path, pkgid, PackageType::WGT),
802             ci::AppInstaller::Result::OK);
803   ValidatePackage(pkgid, {appid});
804
805   // Check delta modifications
806   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
807       "res" / "wgt" / "DELETED"));
808   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
809       "res" / "wgt" / "ADDED"));
810   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "2\n"));
811 }
812
813 TEST_F(SmokeTest, EnablePkg) {
814   bf::path path = kSmokePackagesDirectory / "EnablePkg.wgt";
815   std::string pkgid = "smokewgt22";
816   ASSERT_EQ(Install(path, PackageType::WGT),
817             ci::AppInstaller::Result::OK);
818   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
819             ci::AppInstaller::Result::OK);
820   ASSERT_EQ(EnablePackage(pkgid, PackageType::WGT),
821             ci::AppInstaller::Result::OK);
822
823   ASSERT_TRUE(ci::QueryIsPackageInstalled(pkgid,
824       ci::GetRequestMode(kTestUserId),
825       kTestUserId));
826 }
827
828 TEST_F(SmokeTest, DisablePkg) {
829   bf::path path = kSmokePackagesDirectory / "DisablePkg.wgt";
830   std::string pkgid = "smokewgt21";
831   std::string appid = "smokewgt21.DisablePkg";
832   ASSERT_EQ(Install(path, PackageType::WGT),
833             ci::AppInstaller::Result::OK);
834   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
835             ci::AppInstaller::Result::OK);
836   ASSERT_TRUE(ci::QueryIsDisabledPackage(pkgid, kTestUserId));
837   ValidatePackage(pkgid, {appid});
838 }
839
840 TEST_F(SmokeTest, DeltaMode) {
841   bf::path path = kSmokePackagesDirectory / "DeltaMode.wgt";
842   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode.delta";
843   std::string pkgid = "smokewgt17";
844   std::string appid = "smokewgt17.DeltaMode";
845   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
846             ci::AppInstaller::Result::OK);
847   ValidatePackage(pkgid, {appid});
848
849   // Check delta modifications
850   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
851       "res" / "wgt" / "DELETED"));
852   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
853       "res" / "wgt" / "ADDED"));
854   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
855       "res" / "wgt" / "css" / "style.css"));
856   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
857       "res" / "wgt" / "images" / "tizen_32.png"));
858   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
859       "res" / "wgt" / "js" / "main.js"));
860   ASSERT_TRUE(ValidateFileContentInPackage(
861       pkgid, "res/wgt/MODIFIED", "version 2\n"));
862 }
863
864 TEST_F(SmokeTest, RecoveryMode_ForInstallation) {
865   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForInstallation.wgt";
866   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
867   backend_crash.Run("-i", path.string(), "-u", kTestUserIdStr.c_str());
868   ASSERT_NE(backend_crash.Wait(), 0);
869
870   std::string pkgid = "smokewgt09";
871   std::string appid = "smokewgt09.RecoveryModeForInstallation";
872   bf::path recovery_file = FindRecoveryFile();
873   ASSERT_FALSE(recovery_file.empty());
874   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
875       ci::AppInstaller::Result::OK);
876   CheckPackageNonExistance(pkgid, {appid});
877 }
878
879 TEST_F(SmokeTest, RecoveryMode_ForUpdate) {
880   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForUpdate.wgt";
881   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForUpdate_2.wgt";
882   RemoveAllRecoveryFiles();
883   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
884   std::string pkgid = "smokewgt10";
885   std::string appid = "smokewgt10.RecoveryModeForUpdate";
886   AddDataFiles(pkgid, kTestUserId);
887   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
888   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
889   ASSERT_NE(backend_crash.Wait(), 0);
890
891   bf::path recovery_file = FindRecoveryFile();
892   ASSERT_FALSE(recovery_file.empty());
893   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
894             ci::AppInstaller::Result::OK);
895   ValidatePackage(pkgid, {appid});
896
897   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
898   ValidateDataFiles(pkgid, kTestUserId);
899 }
900
901 TEST_F(SmokeTest, RecoveryMode_ForDelta) {
902   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForDelta.wgt";
903   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForDelta.delta";
904   RemoveAllRecoveryFiles();
905   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
906   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
907   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
908   ASSERT_NE(backend_crash.Wait(), 0);
909
910   std::string pkgid = "smokewgt30";
911   std::string appid = "smokewgt30.RecoveryModeForDelta";
912   bf::path recovery_file = FindRecoveryFile();
913   ASSERT_FALSE(recovery_file.empty());
914   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
915             ci::AppInstaller::Result::OK);
916   ValidatePackage(pkgid, {appid});
917
918   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
919 }
920
921 TEST_F(SmokeTest, RecoveryMode_ForMountInstall) {
922   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForMountInstall.wgt";
923   RemoveAllRecoveryFiles();
924   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
925   backend_crash.Run("-w", path.string(), "-u", kTestUserIdStr.c_str());
926   ASSERT_NE(backend_crash.Wait(), 0);
927
928   std::string pkgid = "smokewgt31";
929   std::string appid = "smokewgt31.RecoveryModeForMountInstall";
930   bf::path recovery_file = FindRecoveryFile();
931   ASSERT_FALSE(recovery_file.empty());
932   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
933             ci::AppInstaller::Result::OK);
934   CheckPackageNonExistance(pkgid, {appid});
935 }
936
937 TEST_F(SmokeTest, RecoveryMode_ForMountUpdate) {
938   bf::path path_old =
939       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate.wgt";
940   bf::path path_new =
941       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate_2.wgt";
942   std::string pkgid = "smokewgt32";
943   std::string appid = "smokewgt32.RecoveryModeForMountUpdate";
944   RemoveAllRecoveryFiles();
945   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
946             ci::AppInstaller::Result::OK);
947   AddDataFiles(pkgid, kTestUserId);
948   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
949   backend_crash.Run("-w", path_new.string(), "-u", kTestUserIdStr.c_str());
950   ASSERT_NE(backend_crash.Wait(), 0);
951
952   // Filesystem may be mounted after crash
953   ScopedTzipInterface poweroff_unmount_interface(pkgid);
954   poweroff_unmount_interface.Release();
955
956   bf::path recovery_file = FindRecoveryFile();
957   ASSERT_FALSE(recovery_file.empty());
958   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
959             ci::AppInstaller::Result::OK);
960
961   ScopedTzipInterface interface(pkgid);
962   ValidatePackage(pkgid, {appid});
963   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
964   ValidateDataFiles(pkgid, kTestUserId);
965 }
966
967 TEST_F(SmokeTest, InstallationMode_GoodSignature) {
968   bf::path path = kSmokePackagesDirectory / "InstallationMode_GoodSignature.wgt";  // NOLINT
969   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
970 }
971
972 TEST_F(SmokeTest, InstallationMode_WrongSignature) {
973   bf::path path = kSmokePackagesDirectory / "InstallationMode_WrongSignature.wgt";  // NOLINT
974   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::ERROR);
975 }
976
977 TEST_F(SmokeTest, InstallationMode_Rollback) {
978   bf::path path = kSmokePackagesDirectory / "InstallationMode_Rollback.wgt";
979   std::string pkgid = "smokewgt06";
980   std::string appid = "smokewgt06.InstallationModeRollback";
981   ASSERT_EQ(Install(path, PackageType::WGT, RequestResult::FAIL),
982             ci::AppInstaller::Result::ERROR);
983   CheckPackageNonExistance(pkgid, {appid});
984 }
985
986 TEST_F(SmokeTest, UpdateMode_Rollback) {
987   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Rollback.wgt";
988   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Rollback_2.wgt";
989   std::string pkgid = "smokewgt07";
990   std::string appid = "smokewgt07.UpdateModeRollback";
991   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
992   AddDataFiles(pkgid, kTestUserId);
993   ASSERT_EQ(Install(path_new, PackageType::WGT, RequestResult::FAIL),
994                     ci::AppInstaller::Result::ERROR);
995   ValidatePackage(pkgid, {appid});
996
997   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
998   ValidateDataFiles(pkgid, kTestUserId);
999 }
1000
1001 TEST_F(SmokeTest, DeltaMode_Rollback) {
1002   bf::path path = kSmokePackagesDirectory / "DeltaMode_Rollback.wgt";
1003   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Rollback.delta";
1004   std::string pkgid = "smokewgt01";
1005   std::string appid = "smokewgt01.DeltaMode";
1006   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1007   AddDataFiles(pkgid, kTestUserId);
1008   ASSERT_EQ(Install(delta_package, PackageType::WGT, RequestResult::FAIL),
1009             ci::AppInstaller::Result::ERROR);
1010
1011   ValidatePackage(pkgid, {appid});
1012   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED",
1013                                            "version 1\n"));
1014   ValidateDataFiles(pkgid, kTestUserId);
1015   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
1016                          "res/wgt/DELETED"));
1017   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
1018                           "res/wgt/ADDED"));
1019 }
1020
1021 TEST_F(SmokeTest, InstallationMode_Hybrid) {
1022   bf::path path = kSmokePackagesDirectory / "InstallationMode_Hybrid.wgt";
1023   std::string pkgid = "smokehyb01";
1024   // Excutable for native app doesn't create symlink
1025   std::string appid1 = "smokehyb01.Web";
1026   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
1027   ValidatePackage(pkgid, {appid1});
1028 }
1029
1030 TEST_F(SmokeTest, UpdateMode_Hybrid) {
1031   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Hybrid.wgt";
1032   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Hybrid_2.wgt";
1033   std::string pkgid = "smokehyb02";
1034   std::string appid1 = "smokehyb02.Web";
1035   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
1036             ci::AppInstaller::Result::OK);
1037 //  AddDataFiles(pkgid, kTestUserId);
1038   ASSERT_EQ(Install(path_new, PackageType::HYBRID),
1039             ci::AppInstaller::Result::OK);
1040   ValidatePackage(pkgid, {appid1});
1041
1042   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
1043   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "VERSION", "2\n"));
1044 //  ValidateDataFiles(pkgid, kTestUserId);
1045 }
1046
1047 TEST_F(SmokeTest, DeinstallationMode_Hybrid) {
1048   bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Hybrid.wgt";
1049   std::string pkgid = "smokehyb03";
1050   std::string appid1 = "smokehyb03.Web";
1051   ASSERT_EQ(Install(path, PackageType::HYBRID),
1052             ci::AppInstaller::Result::OK);
1053   ASSERT_EQ(Uninstall(pkgid, PackageType::HYBRID, false),
1054             ci::AppInstaller::Result::OK);
1055   CheckPackageNonExistance(pkgid, {appid1});
1056 }
1057
1058 TEST_F(SmokeTest, DeltaMode_Hybrid) {
1059   bf::path path = kSmokePackagesDirectory / "DeltaMode_Hybrid.wgt";
1060   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Hybrid.delta";
1061   std::string pkgid = "smokehyb04";
1062   std::string appid1 = "smokehyb04.Web";
1063   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
1064             ci::AppInstaller::Result::OK);
1065   ValidatePackage(pkgid, {appid1});
1066
1067   // Check delta modifications
1068   bf::path root_path = ci::GetRootAppPath(false,
1069       kTestUserId);
1070   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
1071   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
1072   ASSERT_FALSE(bf::exists(root_path / pkgid / "lib" / "DELETED"));
1073   ASSERT_TRUE(bf::exists(root_path / pkgid / "lib" / "ADDED"));
1074   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "css" / "style.css"));  // NOLINT
1075   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
1076   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "js" / "main.js"));
1077   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n"));  // NOLINT
1078   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/MODIFIED", "version 2\n"));  // NOLINT
1079 }
1080
1081 TEST_F(SmokeTest, MountInstallationMode_Hybrid) {
1082   bf::path path = kSmokePackagesDirectory / "MountInstallationMode_Hybrid.wgt";
1083   std::string pkgid = "smokehyb05";
1084   std::string appid1 = "smokehyb05.web";
1085   ASSERT_EQ(MountInstall(path, PackageType::HYBRID),
1086             ci::AppInstaller::Result::OK);
1087   ScopedTzipInterface interface(pkgid);
1088   ValidatePackage(pkgid, {appid1});
1089 }
1090
1091 TEST_F(SmokeTest, MountUpdateMode_Hybrid) {
1092   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Hybrid.wgt";
1093   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_Hybrid_2.wgt";
1094   std::string pkgid = "smokehyb06";
1095   std::string appid1 = "smokehyb06.web";
1096   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
1097             ci::AppInstaller::Result::OK);
1098   AddDataFiles(pkgid, kTestUserId);
1099   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID),
1100             ci::AppInstaller::Result::OK);
1101   ScopedTzipInterface interface(pkgid);
1102   ValidatePackage(pkgid, {appid1});
1103
1104   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
1105   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "2\n"));
1106   ValidateDataFiles(pkgid, kTestUserId);
1107 }
1108
1109 TEST_F(SmokeTest, InstallationMode_Rollback_Hybrid) {
1110   bf::path path = kSmokePackagesDirectory /
1111       "InstallationMode_Rollback_Hybrid.wgt";
1112   std::string pkgid = "smokehyb07";
1113   std::string appid1 = "smokehyb07.web";
1114   ASSERT_EQ(Install(path, PackageType::HYBRID, RequestResult::FAIL),
1115             ci::AppInstaller::Result::ERROR);
1116   CheckPackageNonExistance(pkgid, {appid1});
1117 }
1118
1119 TEST_F(SmokeTest, UpdateMode_Rollback_Hybrid) {
1120   bf::path path_old = kSmokePackagesDirectory /
1121       "UpdateMode_Rollback_Hybrid.wgt";
1122   bf::path path_new = kSmokePackagesDirectory /
1123       "UpdateMode_Rollback_Hybrid_2.wgt";
1124   std::string pkgid = "smokehyb08";
1125   std::string appid1 = "smokehyb08.web";
1126   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
1127             ci::AppInstaller::Result::OK);
1128   AddDataFiles(pkgid, kTestUserId);
1129   ASSERT_EQ(Install(path_new, PackageType::HYBRID,
1130       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
1131   ValidatePackage(pkgid, {appid1});
1132
1133   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1134   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
1135   ValidateDataFiles(pkgid, kTestUserId);
1136 }
1137
1138 TEST_F(SmokeTest, DeltaMode_Rollback_Hybrid) {
1139   bf::path path = kSmokePackagesDirectory / "DeltaMode_Rollback_Hybrid.wgt";
1140   bf::path delta_package = kSmokePackagesDirectory /
1141       "DeltaMode_Rollback_Hybrid.delta";
1142   std::string pkgid = "smokehyb11";
1143   std::string appid1 = "smokehyb11.web";
1144   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
1145   AddDataFiles(pkgid, kTestUserId);
1146   ASSERT_EQ(Install(delta_package, PackageType::HYBRID, RequestResult::FAIL),
1147             ci::AppInstaller::Result::ERROR);
1148
1149   ValidatePackage(pkgid, {appid1});
1150   // Check delta modifications
1151   bf::path root_path = GetPackageRoot(pkgid, kTestUserId);
1152   ASSERT_TRUE(bf::exists(root_path / "res" / "wgt" / "DELETED"));
1153   ASSERT_FALSE(bf::exists(root_path / "res" / "wgt" / "ADDED"));
1154   ASSERT_TRUE(bf::exists(root_path / "lib" / "DELETED"));
1155   ASSERT_FALSE(bf::exists(root_path / "lib" / "ADDED"));
1156   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED",
1157                                            "version 1\n"));
1158   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/MODIFIED",
1159                                            "version 1\n"));
1160   ValidateDataFiles(pkgid, kTestUserId);
1161 }
1162
1163 TEST_F(SmokeTest, MountInstallationMode_Rollback_Hybrid) {
1164   bf::path path = kSmokePackagesDirectory /
1165       "MountInstallationMode_Rollback_Hybrid.wgt";
1166   std::string pkgid = "smokehyb09";
1167   std::string appid1 = "smokehyb09.web";
1168   ASSERT_EQ(MountInstall(path, PackageType::HYBRID, RequestResult::FAIL),
1169       ci::AppInstaller::Result::ERROR);
1170   ScopedTzipInterface interface(pkgid);
1171   CheckPackageNonExistance(pkgid, {appid1});
1172 }
1173
1174 TEST_F(SmokeTest, MountUpdateMode_Rollback_Hybrid) {
1175   bf::path path_old = kSmokePackagesDirectory /
1176       "MountUpdateMode_Rollback_Hybrid.wgt";
1177   bf::path path_new = kSmokePackagesDirectory /
1178       "MountUpdateMode_Rollback_Hybrid_2.wgt";
1179   std::string pkgid = "smokehyb10";
1180   std::string appid1 = "smokehyb10.web";
1181   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
1182             ci::AppInstaller::Result::OK);
1183   AddDataFiles(pkgid, kTestUserId);
1184   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID,
1185       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
1186   ScopedTzipInterface interface(pkgid);
1187   ValidatePackage(pkgid, {appid1});
1188
1189   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1190   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
1191   ValidateDataFiles(pkgid, kTestUserId);
1192 }
1193
1194 TEST_F(SmokeTest, MountInstallationMode) {
1195   bf::path path = kSmokePackagesDirectory / "MountInstallationMode.wgt";
1196   std::string pkgid = "smokewgt28";
1197   std::string appid = "smokewgt28.InstallationMode";
1198   ASSERT_EQ(MountInstall(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1199   ScopedTzipInterface interface(pkgid);
1200   ValidatePackage(pkgid, {appid});
1201 }
1202
1203 TEST_F(SmokeTest, MountUpdateMode) {
1204   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode.wgt";
1205   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_2.wgt";
1206   std::string pkgid = "smokewgt29";
1207   std::string appid = "smokewgt29.UpdateMode";
1208   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
1209             ci::AppInstaller::Result::OK);
1210   AddDataFiles(pkgid, kTestUserId);
1211   ASSERT_EQ(MountInstall(path_new, PackageType::WGT),
1212             ci::AppInstaller::Result::OK);
1213   ScopedTzipInterface interface(pkgid);
1214   ValidatePackage(pkgid, {appid});
1215
1216   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
1217   ValidateDataFiles(pkgid, kTestUserId);
1218 }
1219
1220 TEST_F(SmokeTest, MountInstallationMode_Rollback) {
1221   bf::path path =
1222       kSmokePackagesDirectory / "MountInstallationMode_Rollback.wgt";
1223   std::string pkgid = "smokewgt33";
1224   std::string appid = "smokewgt33.web";
1225   ASSERT_EQ(MountInstall(path, PackageType::WGT, RequestResult::FAIL),
1226             ci::AppInstaller::Result::ERROR);
1227   ScopedTzipInterface interface(pkgid);
1228   CheckPackageNonExistance(pkgid, {appid});
1229 }
1230
1231 TEST_F(SmokeTest, MountUpdateMode_Rollback) {
1232   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Rollback.wgt";
1233   bf::path path_new =
1234       kSmokePackagesDirectory / "MountUpdateMode_Rollback_2.wgt";
1235   std::string pkgid = "smokewgt34";
1236   std::string appid = "smokewgt34.web";
1237   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
1238             ci::AppInstaller::Result::OK);
1239   AddDataFiles(pkgid, kTestUserId);
1240   ASSERT_EQ(MountInstall(path_new, PackageType::WGT,
1241       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
1242   ScopedTzipInterface interface(pkgid);
1243   ValidatePackage(pkgid, {appid});
1244
1245   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
1246   ValidateDataFiles(pkgid, kTestUserId);
1247 }
1248
1249 TEST_F(SmokeTest, UserDefinedPlugins) {
1250   bf::path path = kSmokePackagesDirectory / "SimpleEchoPrivilege.wgt";
1251   std::string pkgid = "smokewgt02";
1252   std::string appid = "smokewgt02.SimpleEcho";
1253   std::string call_privilege = "http://tizen.org/privilege/call";
1254   std::string location_privilege = "http://tizen.org/privilege/location";
1255   std::string power_privilege = "http://tizen.org/privilege/power";
1256
1257   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1258   ValidatePackage(pkgid, {appid});
1259   std::vector<std::string> res;
1260   ASSERT_TRUE(ci::QueryPrivilegesForPkgId(pkgid, kTestUserId, &res));
1261   ASSERT_TRUE(std::find(res.begin(), res.end(), call_privilege) != res.end());
1262   ASSERT_TRUE(std::find(res.begin(), res.end(), location_privilege)
1263           != res.end());
1264   ASSERT_TRUE(std::find(res.begin(), res.end(), power_privilege) != res.end());
1265 }
1266
1267 TEST_F(SmokeTest, InstallExternalMode) {
1268   ASSERT_TRUE(CheckAvailableExternalPath());
1269   bf::path path = kSmokePackagesDirectory / "InstallExternalMode.wgt";
1270   std::string pkgid = "smokewgt35";
1271   std::string appid = "smokewgt35.web";
1272   ASSERT_EQ(InstallExternal(path, PackageType::WGT),
1273       ci::AppInstaller::Result::OK);
1274   ValidateExternalPackage(pkgid, {appid});
1275 }
1276
1277 TEST_F(SmokeTest, MigrateLegacyExternalImageMode) {
1278   ASSERT_TRUE(CheckAvailableExternalPath());
1279   bf::path path =
1280       kSmokePackagesDirectory / "MigrateLegacyExternalImageMode.wgt";
1281   std::string pkgid = "smokewgt36";
1282   std::string appid = "smokewgt36.web";
1283   bf::path legacy_path = kSmokePackagesDirectory / kLegacyExtImageDir;
1284   ASSERT_EQ(MigrateLegacyExternalImage(pkgid, path, legacy_path,
1285       PackageType::WGT), ci::AppInstaller::Result::OK);
1286   ValidateExternalPackage(pkgid, {appid});
1287 }
1288
1289 TEST_F(SmokeTest, InstallationMode_Preload) {
1290   ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
1291   bf::path path = kSmokePackagesDirectory / "InstallationMode_Preload.wgt";
1292   std::string pkgid = "smokewgt37";
1293   std::string appid = "smokewgt37.InstallationModePreload";
1294   ASSERT_EQ(InstallPreload(path, PackageType::WGT),
1295             ci::AppInstaller::Result::OK);
1296   ValidatePackage(pkgid, {appid}, true);
1297 }
1298
1299 TEST_F(SmokeTest, UpdateMode_Preload) {
1300   ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
1301   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Preload.wgt";
1302   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Preload2.wgt";
1303   std::string pkgid = "smokewgt38";
1304   std::string appid = "smokewgt38.UpdateModePreload";
1305   ASSERT_EQ(InstallPreload(path_old, PackageType::WGT),
1306             ci::AppInstaller::Result::OK);
1307   AddDataFiles(pkgid, kTestUserId);
1308   ASSERT_EQ(InstallPreload(path_new, PackageType::WGT),
1309             ci::AppInstaller::Result::OK);
1310   ValidatePackage(pkgid, {appid}, true);
1311
1312   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2",
1313                                            true));
1314   ValidateDataFiles(pkgid, kTestUserId);
1315 }
1316
1317 TEST_F(SmokeTest, DeinstallationMode_Preload) {
1318   ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
1319   bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Preload.wgt";
1320   std::string pkgid = "smokewgt39";
1321   std::string appid = "smokewgt39.DeinstallationModePreload";
1322   ASSERT_EQ(InstallPreload(path, PackageType::WGT),
1323             ci::AppInstaller::Result::OK);
1324   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT, true),
1325             ci::AppInstaller::Result::OK);
1326   CheckPackageReadonlyNonExistance(pkgid, {appid});
1327 }
1328
1329 }  // namespace common_installer
1330
1331 int main(int argc,  char** argv) {
1332   testing::InitGoogleTest(&argc, argv);
1333   testing::AddGlobalTestEnvironment(
1334       new common_installer::SmokeEnvironment(kGlobalUserUid));
1335   return RUN_ALL_TESTS();
1336 }