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