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