Remove cleardata feature
[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
27 #include <array>
28 #include <cstdio>
29 #include <cstdlib>
30 #include <vector>
31
32 #include "hybrid/hybrid_installer.h"
33 #include "wgt/wgt_app_query_interface.h"
34 #include "wgt/wgt_installer.h"
35
36 #define SIZEOFARRAY(ARR)                                                       \
37   sizeof(ARR) / sizeof(ARR[0])                                                 \
38
39 namespace bf = boost::filesystem;
40 namespace bs = boost::system;
41 namespace ci = common_installer;
42
43 namespace {
44
45 const uid_t kTestUserId = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
46 const gid_t kTestGroupId = tzplatform_getgid(TZ_SYS_DEFAULT_USER);
47 const char kTestGroupName[] = "system_share";
48 const std::string kTestUserIdStr =
49     std::to_string(kTestUserId);
50
51 const bf::path kSmokePackagesDirectory =
52     "/usr/share/wgt-backend-ut/test_samples/smoke/";
53
54 const char kApplicationDir[] = ".applications";
55 const char kApplicationDirBackup[] = ".applications.bck";
56 const char KUserAppsDir[] = "apps_rw";
57 const char KUserAppsDirBackup[] = "apps_rw.bck";
58 const char kUserDataBaseDir[] = "/opt/dbspace/user";
59
60 enum class RequestResult {
61   NORMAL,
62   FAIL
63 };
64
65 class ScopedTzipInterface {
66  public:
67   explicit ScopedTzipInterface(const std::string& pkgid)
68       : pkg_path_(bf::path(ci::GetRootAppPath(false,
69             kTestUserId)) / pkgid),
70         interface_(ci::GetMountLocation(pkg_path_)),
71         mounted_(true) {
72     interface_.MountZip(ci::GetZipPackageLocation(pkg_path_, pkgid));
73   }
74
75   void Release() {
76     if (mounted_) {
77       interface_.UnmountZip();
78       mounted_ = false;
79     }
80   }
81
82   ~ScopedTzipInterface() {
83     Release();
84   }
85
86  private:
87   bf::path pkg_path_;
88   ci::TzipInterface interface_;
89   bool mounted_;
90 };
91
92 class TestPkgmgrInstaller : public ci::PkgmgrInstallerInterface {
93  public:
94   bool CreatePkgMgrInstaller(pkgmgr_installer** installer,
95                              ci::InstallationMode* mode) {
96     *installer = pkgmgr_installer_offline_new();
97     if (!*installer)
98       return false;
99     *mode = ci::InstallationMode::ONLINE;
100     return true;
101   }
102
103   bool ShouldCreateSignal() const {
104     return false;
105   }
106 };
107
108 enum class PackageType {
109   WGT,
110   HYBRID
111 };
112
113 bool TouchFile(const bf::path& path) {
114   FILE* f = fopen(path.c_str(), "w+");
115   if (!f)
116     return false;
117   fclose(f);
118   return true;
119 }
120
121 void RemoveAllRecoveryFiles() {
122   bf::path root_path = ci::GetRootAppPath(false,
123       kTestUserId);
124   if (!bf::exists(root_path))
125     return;
126   for (auto& dir_entry : boost::make_iterator_range(
127          bf::directory_iterator(root_path), bf::directory_iterator())) {
128     if (bf::is_regular_file(dir_entry)) {
129       if (dir_entry.path().string().find("/recovery") != std::string::npos) {
130         bs::error_code error;
131         bf::remove(dir_entry.path(), error);
132       }
133     }
134   }
135 }
136
137 bf::path FindRecoveryFile() {
138   bf::path root_path = ci::GetRootAppPath(false,
139       kTestUserId);
140   for (auto& dir_entry : boost::make_iterator_range(
141          bf::directory_iterator(root_path), bf::directory_iterator())) {
142     if (bf::is_regular_file(dir_entry)) {
143       if (dir_entry.path().string().find("/recovery") != std::string::npos) {
144         return dir_entry.path();
145       }
146     }
147   }
148   return {};
149 }
150
151 bf::path GetPackageRoot(const std::string& pkgid) {
152   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
153   return root_path / pkgid;
154 }
155
156 bool ValidateFileContentInPackage(const std::string& pkgid,
157                                   const std::string& relative,
158                                   const std::string& expected) {
159   bf::path file_path = GetPackageRoot(pkgid) / relative;
160   if (!bf::exists(file_path)) {
161     LOG(ERROR) << file_path << " doesn't exist";
162     return false;
163   }
164   FILE* handle = fopen(file_path.c_str(), "r");
165   if (!handle) {
166     LOG(ERROR) << file_path << " cannot  be open";
167     return false;
168   }
169   std::string content;
170   std::array<char, 200> buffer;
171   while (fgets(buffer.data(), buffer.size(), handle)) {
172     content += buffer.data();
173   }
174   fclose(handle);
175   return content == expected;
176 }
177
178 void AddDataFiles(const std::string& pkgid) {
179   auto pkg_path = GetPackageRoot(pkgid);
180   ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt"));
181   ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt"));
182 }
183
184 void ValidateDataFiles(const std::string& pkgid) {
185   auto pkg_path = GetPackageRoot(pkgid);
186   ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt"));
187   ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt"));
188 }
189
190 void ValidatePackageFS(const std::string& pkgid,
191                        const std::vector<std::string>& appids) {
192   bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
193   bf::path package_path = GetPackageRoot(pkgid);
194   bf::path data_path = package_path / "data";
195   bf::path shared_path = package_path / "shared";
196   bf::path cache_path = package_path / "cache";
197   ASSERT_TRUE(bf::exists(root_path));
198   ASSERT_TRUE(bf::exists(package_path));
199   ASSERT_TRUE(bf::exists(data_path));
200   ASSERT_TRUE(bf::exists(shared_path));
201   ASSERT_TRUE(bf::exists(cache_path));
202
203   bf::path manifest_path =
204       bf::path(getUserManifestPath(
205           kTestUserId, false)) / (pkgid + ".xml");
206   ASSERT_TRUE(bf::exists(manifest_path));
207
208   for (auto& appid : appids) {
209     bf::path binary_path = package_path / "bin" / appid;
210     ASSERT_TRUE(bf::exists(binary_path));
211   }
212
213   bf::path widget_root_path = package_path / "res" / "wgt";
214   bf::path config_path = widget_root_path / "config.xml";
215   ASSERT_TRUE(bf::exists(widget_root_path));
216   ASSERT_TRUE(bf::exists(config_path));
217
218   bf::path private_tmp_path = package_path / "tmp";
219   ASSERT_TRUE(bf::exists(private_tmp_path));
220
221   // backups should not exist
222   bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
223   bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
224   ASSERT_FALSE(bf::exists(package_backup));
225   ASSERT_FALSE(bf::exists(manifest_backup));
226
227   for (bf::recursive_directory_iterator iter(package_path);
228       iter != bf::recursive_directory_iterator(); ++iter) {
229     if (bf::is_symlink(symlink_status(iter->path())))
230       continue;
231     struct stat stats;
232     stat(iter->path().c_str(), &stats);
233     ASSERT_EQ(kTestUserId, stats.st_uid) << "Invalid uid: " << iter->path();
234     if (iter->path().filename() == "data") {
235       boost::optional<gid_t> gid = ci::GetGidByGroupName(kTestGroupName);
236       ASSERT_EQ(*gid, stats.st_gid) << "Invalid gid: " << iter->path();
237     } else {
238       ASSERT_EQ(kTestGroupId, stats.st_gid) << "Invalid gid: " << iter->path();
239     }
240   }
241 }
242
243 void PackageCheckCleanup(const std::string& pkgid,
244                          const std::vector<std::string>&) {
245   bf::path package_path = GetPackageRoot(pkgid);
246   ASSERT_FALSE(bf::exists(package_path));
247
248   bf::path manifest_path =
249       bf::path(getUserManifestPath(
250           kTestUserId, false)) / (pkgid + ".xml");
251   ASSERT_FALSE(bf::exists(manifest_path));
252
253   // backups should not exist
254   bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
255   bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
256   ASSERT_FALSE(bf::exists(package_backup));
257   ASSERT_FALSE(bf::exists(manifest_backup));
258 }
259
260 void ValidatePackage(const std::string& pkgid,
261                      const std::vector<std::string>& appids) {
262   ASSERT_TRUE(ci::QueryIsPackageInstalled(
263       pkgid, ci::GetRequestMode(kTestUserId),
264       kTestUserId));
265   ValidatePackageFS(pkgid, appids);
266 }
267
268 void CheckPackageNonExistance(const std::string& pkgid,
269                               const std::vector<std::string>& appids) {
270   ASSERT_FALSE(ci::QueryIsPackageInstalled(
271       pkgid, ci::GetRequestMode(kTestUserId),
272       kTestUserId));
273   PackageCheckCleanup(pkgid, appids);
274 }
275
276 std::unique_ptr<ci::AppQueryInterface> CreateQueryInterface() {
277   std::unique_ptr<ci::AppQueryInterface> query_interface(
278       new wgt::WgtAppQueryInterface());
279   return query_interface;
280 }
281
282 std::unique_ptr<ci::AppInstaller> CreateInstaller(ci::PkgMgrPtr pkgmgr,
283                                                   PackageType type) {
284   switch (type) {
285     case PackageType::WGT:
286       return std::unique_ptr<ci::AppInstaller>(new wgt::WgtInstaller(pkgmgr));
287     case PackageType::HYBRID:
288       return std::unique_ptr<ci::AppInstaller>(
289           new hybrid::HybridInstaller(pkgmgr));
290     default:
291       LOG(ERROR) << "Unknown installer type";
292       return nullptr;
293   }
294 }
295
296 ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr,
297                                                  PackageType type,
298                                                  RequestResult mode) {
299   std::unique_ptr<ci::AppInstaller> installer = CreateInstaller(pkgmgr, type);
300   switch (mode) {
301   case RequestResult::FAIL:
302     installer->AddStep<ci::configuration::StepFail>();
303     break;
304   default:
305     break;
306   }
307   return installer->Run();
308 }
309 ci::AppInstaller::Result CallBackend(int argc,
310                                      const char* argv[],
311                                      PackageType type,
312                                      RequestResult mode = RequestResult::NORMAL
313                                      ) {
314   TestPkgmgrInstaller pkgmgr_installer;
315   std::unique_ptr<ci::AppQueryInterface> query_interface =
316       CreateQueryInterface();
317   auto pkgmgr =
318       ci::PkgMgrInterface::Create(argc, const_cast<char**>(argv),
319                                   &pkgmgr_installer, query_interface.get());
320   if (!pkgmgr) {
321     LOG(ERROR) << "Failed to initialize pkgmgr interface";
322     return ci::AppInstaller::Result::UNKNOWN;
323   }
324   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
325 }
326
327 ci::AppInstaller::Result Install(const bf::path& path,
328                                  PackageType type,
329                                  RequestResult mode = RequestResult::NORMAL) {
330   const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()};
331   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
332 }
333
334 ci::AppInstaller::Result MountInstall(const bf::path& path,
335     PackageType type, RequestResult mode = RequestResult::NORMAL) {
336   const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()};
337   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
338 }
339
340 ci::AppInstaller::Result Uninstall(const std::string& pkgid,
341                                    PackageType type,
342                                    RequestResult mode = RequestResult::NORMAL) {
343   const char* argv[] = {"", "-d", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
344   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
345 }
346
347 ci::AppInstaller::Result RDSUpdate(const bf::path& path,
348                                    const std::string& pkgid,
349                                    PackageType type,
350                                    RequestResult mode = RequestResult::NORMAL) {
351   if (Install(path, type) != ci::AppInstaller::Result::OK) {
352     LOG(ERROR) << "Failed to install application. Cannot perform RDS";
353     return ci::AppInstaller::Result::UNKNOWN;
354   }
355   const char* argv[] = {"", "-r", pkgid.c_str(), "-u",
356                         kTestUserIdStr.c_str()};
357   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
358 }
359
360 ci::AppInstaller::Result DeltaInstall(const bf::path& path,
361     const bf::path& delta_package, PackageType type) {
362   if (Install(path, type) != ci::AppInstaller::Result::OK) {
363     LOG(ERROR) << "Failed to install application. Cannot perform delta update";
364     return ci::AppInstaller::Result::UNKNOWN;
365   }
366   return Install(delta_package, type);
367 }
368
369 ci::AppInstaller::Result EnablePackage(const std::string& pkgid,
370                                   PackageType type,
371                                   RequestResult mode = RequestResult::NORMAL) {
372   const char* argv[] = {"", "-A", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
373   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
374 }
375
376 ci::AppInstaller::Result DisablePackage(const std::string& pkgid,
377                                   PackageType type,
378                                   RequestResult mode = RequestResult::NORMAL) {
379   const char* argv[] = {"", "-D", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
380   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
381 }
382
383 ci::AppInstaller::Result Recover(const bf::path& recovery_file,
384                                  PackageType type,
385                                  RequestResult mode = RequestResult::NORMAL) {
386   const char* argv[] = {"", "-b", recovery_file.c_str(), "-u",
387                         kTestUserIdStr.c_str()};
388   TestPkgmgrInstaller pkgmgr_installer;
389   std::unique_ptr<ci::AppQueryInterface> query_interface =
390       CreateQueryInterface();
391   auto pkgmgr =
392       ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast<char**>(argv),
393                                   &pkgmgr_installer, query_interface.get());
394   if (!pkgmgr) {
395     LOG(ERROR) << "Failed to initialize pkgmgr interface";
396     return ci::AppInstaller::Result::UNKNOWN;
397   }
398   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
399 }
400
401 }  // namespace
402
403 namespace common_installer {
404
405 class SmokeEnvironment : public testing::Environment {
406  public:
407   explicit SmokeEnvironment(const bf::path& home) : home_(home) {
408   }
409   void SetUp() override {
410     bf::path UserDBDir = bf::path(kUserDataBaseDir) / kTestUserIdStr;
411     bf::path UserDBDirBackup = UserDBDir.string() + std::string(".bck");
412
413     bs::error_code error;
414     bf::remove_all(home_ / kApplicationDirBackup, error);
415     bf::remove_all(home_ / KUserAppsDirBackup, error);
416     bf::remove_all(UserDBDirBackup, error);
417     if (bf::exists(home_ / KUserAppsDir)) {
418       bf::rename(home_ / KUserAppsDir, home_ / KUserAppsDirBackup, error);
419       if (error)
420         LOG(ERROR) << "Failed to setup test environment. Does some previous"
421                    << " test crashed? Directory: "
422                    << (home_ / KUserAppsDirBackup) << " should not exist.";
423       assert(!error);
424     }
425     if (bf::exists(home_ / kApplicationDir)) {
426       bf::rename(home_ / kApplicationDir, home_ / kApplicationDirBackup, error);
427       if (error)
428         LOG(ERROR) << "Failed to setup test environment. Does some previous"
429                    << " test crashed? Directory: "
430                    << (home_ / kApplicationDirBackup) << " should not exist.";
431       assert(!error);
432     }
433     if (bf::exists(UserDBDir)) {
434       bf::rename(UserDBDir, UserDBDirBackup, error);
435       if (error)
436         LOG(ERROR) << "Failed to setup test environment. Does some previous"
437                    << " test crashed? Directory: "
438                    << UserDBDirBackup << " should not exist.";
439       assert(!error);
440     }
441   }
442   void TearDown() override {
443     bf::path UserDBDir = bf::path(kUserDataBaseDir) / kTestUserIdStr;
444     bf::path UserDBDirBackup = UserDBDir.string() + std::string(".bck");
445
446     bs::error_code error;
447     bf::remove_all(home_ / kApplicationDir, error);
448     bf::remove_all(home_ / KUserAppsDir, error);
449     bf::remove_all(UserDBDir, error);
450     if (bf::exists(home_ / KUserAppsDirBackup))
451       bf::rename(home_ / KUserAppsDirBackup, home_ / KUserAppsDir, error);
452     if (bf::exists(home_ / kApplicationDirBackup))
453       bf::rename(home_ / kApplicationDirBackup, home_ / kApplicationDir, error);
454     if (bf::exists(UserDBDirBackup))
455       bf::rename(UserDBDirBackup, UserDBDir, error);
456   }
457
458  private:
459   bf::path home_;
460 };
461
462 class SmokeTest : public testing::Test {
463 };
464
465 TEST_F(SmokeTest, InstallationMode) {
466   bf::path path = kSmokePackagesDirectory / "InstallationMode.wgt";
467   std::string pkgid = "smokeapp03";
468   std::string appid = "smokeapp03.InstallationMode";
469   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
470   ValidatePackage(pkgid, {appid});
471 }
472
473 TEST_F(SmokeTest, UpdateMode) {
474   bf::path path_old = kSmokePackagesDirectory / "UpdateMode.wgt";
475   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_2.wgt";
476   std::string pkgid = "smokeapp04";
477   std::string appid = "smokeapp04.UpdateMode";
478   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
479   AddDataFiles(pkgid);
480   ASSERT_EQ(Install(path_new, PackageType::WGT), ci::AppInstaller::Result::OK);
481   ValidatePackage(pkgid, {appid});
482
483   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
484   ValidateDataFiles(pkgid);
485 }
486
487 TEST_F(SmokeTest, DeinstallationMode) {
488   bf::path path = kSmokePackagesDirectory / "DeinstallationMode.wgt";
489   std::string pkgid = "smokeapp05";
490   std::string appid = "smokeapp05.DeinstallationMode";
491   ASSERT_EQ(Install(path, PackageType::WGT),
492             ci::AppInstaller::Result::OK);
493   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK);
494   CheckPackageNonExistance(pkgid, {appid});
495 }
496
497 TEST_F(SmokeTest, RDSMode) {
498   bf::path path = kSmokePackagesDirectory / "RDSMode.wgt";
499   std::string pkgid = "smokeapp11";
500   std::string appid = "smokeapp11.RDSMode";
501   bf::path delta_directory = kSmokePackagesDirectory / "delta_dir/";
502   bf::path sdk_expected_directory =
503       bf::path(ci::GetRootAppPath(false, kTestUserId)) / "tmp" / pkgid;
504   bs::error_code error;
505   bf::create_directories(sdk_expected_directory.parent_path(), error);
506   ASSERT_FALSE(error);
507   ASSERT_TRUE(CopyDir(delta_directory, sdk_expected_directory));
508   ASSERT_EQ(RDSUpdate(path, pkgid, PackageType::WGT),
509             ci::AppInstaller::Result::OK);
510   ValidatePackage(pkgid, {appid});
511
512   // Check delta modifications
513   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid) / "res" / "wgt" / "DELETED"));
514   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid) / "res" / "wgt" / "ADDED"));
515   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "2\n"));
516 }
517
518 TEST_F(SmokeTest, EnablePkg) {
519   bf::path path = kSmokePackagesDirectory / "EnablePkg.wgt";
520   std::string pkgid = "smokeapp22";
521   ASSERT_EQ(Install(path, PackageType::WGT),
522             ci::AppInstaller::Result::OK);
523   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
524             ci::AppInstaller::Result::OK);
525   ASSERT_EQ(EnablePackage(pkgid, PackageType::WGT),
526             ci::AppInstaller::Result::OK);
527
528   ASSERT_TRUE(ci::QueryIsPackageInstalled(pkgid,
529       ci::GetRequestMode(kTestUserId),
530       kTestUserId));
531 }
532
533 TEST_F(SmokeTest, DisablePkg) {
534   bf::path path = kSmokePackagesDirectory / "DisablePkg.wgt";
535   std::string pkgid = "smokeapp21";
536   std::string appid = "smokeapp21.DisablePkg";
537   ASSERT_EQ(Install(path, PackageType::WGT),
538             ci::AppInstaller::Result::OK);
539   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
540             ci::AppInstaller::Result::OK);
541   ASSERT_TRUE(ci::QueryIsDisabledPackage(pkgid, kTestUserId));
542   ValidatePackageFS(pkgid, {appid});
543 }
544
545 TEST_F(SmokeTest, DeltaMode) {
546   bf::path path = kSmokePackagesDirectory / "DeltaMode.wgt";
547   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode.delta";
548   std::string pkgid = "smokeapp17";
549   std::string appid = "smokeapp17.DeltaMode";
550   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
551             ci::AppInstaller::Result::OK);
552   ValidatePackage(pkgid, {appid});
553
554   // Check delta modifications
555   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid) / "res" / "wgt" / "DELETED"));
556   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid) / "res" / "wgt" / "ADDED"));
557   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid) / "res" / "wgt" / "css" / "style.css"));  // NOLINT
558   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid) / "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
559   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid) / "res" / "wgt" / "js" / "main.js"));  // NOLINT
560   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n"));  // NOLINT
561 }
562
563 TEST_F(SmokeTest, RecoveryMode_ForInstallation) {
564   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForInstallation.wgt";
565   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
566   backend_crash.Run("-i", path.string(), "-u", kTestUserIdStr.c_str());
567   ASSERT_NE(backend_crash.Wait(), 0);
568
569   std::string pkgid = "smokeapp09";
570   std::string appid = "smokeapp09.RecoveryModeForInstallation";
571   bf::path recovery_file = FindRecoveryFile();
572   ASSERT_FALSE(recovery_file.empty());
573   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
574       ci::AppInstaller::Result::OK);
575   CheckPackageNonExistance(pkgid, {appid});
576 }
577
578 TEST_F(SmokeTest, RecoveryMode_ForUpdate) {
579   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForUpdate.wgt";
580   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForUpdate_2.wgt";
581   RemoveAllRecoveryFiles();
582   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
583   std::string pkgid = "smokeapp10";
584   std::string appid = "smokeapp10.RecoveryModeForUpdate";
585   AddDataFiles(pkgid);
586   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
587   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
588   ASSERT_NE(backend_crash.Wait(), 0);
589
590   bf::path recovery_file = FindRecoveryFile();
591   ASSERT_FALSE(recovery_file.empty());
592   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
593             ci::AppInstaller::Result::OK);
594   ValidatePackage(pkgid, {appid});
595
596   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
597   ValidateDataFiles(pkgid);
598 }
599
600 TEST_F(SmokeTest, RecoveryMode_ForDelta) {
601   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForDelta.wgt";
602   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForDelta.delta";
603   RemoveAllRecoveryFiles();
604   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
605   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
606   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
607   ASSERT_NE(backend_crash.Wait(), 0);
608
609   std::string pkgid = "smokeapp30";
610   std::string appid = "smokeapp30.RecoveryModeForDelta";
611   bf::path recovery_file = FindRecoveryFile();
612   ASSERT_FALSE(recovery_file.empty());
613   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
614             ci::AppInstaller::Result::OK);
615   ValidatePackage(pkgid, {appid});
616
617   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
618 }
619
620 TEST_F(SmokeTest, RecoveryMode_ForMountInstall) {
621   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForMountInstall.wgt";
622   RemoveAllRecoveryFiles();
623   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
624   backend_crash.Run("-w", path.string(), "-u", kTestUserIdStr.c_str());
625   ASSERT_NE(backend_crash.Wait(), 0);
626
627   std::string pkgid = "smokeapp31";
628   std::string appid = "smokeapp31.RecoveryModeForMountInstall";
629   bf::path recovery_file = FindRecoveryFile();
630   ASSERT_FALSE(recovery_file.empty());
631   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
632             ci::AppInstaller::Result::OK);
633   CheckPackageNonExistance(pkgid, {appid});
634 }
635
636 TEST_F(SmokeTest, RecoveryMode_ForMountUpdate) {
637   bf::path path_old =
638       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate.wgt";
639   bf::path path_new =
640       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate_2.wgt";
641   std::string pkgid = "smokeapp32";
642   std::string appid = "smokeapp32.RecoveryModeForMountUpdate";
643   RemoveAllRecoveryFiles();
644   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
645             ci::AppInstaller::Result::OK);
646   AddDataFiles(pkgid);
647   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
648   backend_crash.Run("-w", path_new.string(), "-u", kTestUserIdStr.c_str());
649   ASSERT_NE(backend_crash.Wait(), 0);
650
651   // Filesystem may be mounted after crash
652   ScopedTzipInterface poweroff_unmount_interface(pkgid);
653   poweroff_unmount_interface.Release();
654
655   bf::path recovery_file = FindRecoveryFile();
656   ASSERT_FALSE(recovery_file.empty());
657   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
658             ci::AppInstaller::Result::OK);
659
660   ScopedTzipInterface interface(pkgid);
661   ValidatePackage(pkgid, {appid});
662   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
663   ValidateDataFiles(pkgid);
664 }
665
666 TEST_F(SmokeTest, InstallationMode_GoodSignature) {
667   bf::path path = kSmokePackagesDirectory / "InstallationMode_GoodSignature.wgt";  // NOLINT
668   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
669 }
670
671 TEST_F(SmokeTest, InstallationMode_WrongSignature) {
672   bf::path path = kSmokePackagesDirectory / "InstallationMode_WrongSignature.wgt";  // NOLINT
673   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::ERROR);
674 }
675
676 TEST_F(SmokeTest, InstallationMode_Rollback) {
677   bf::path path = kSmokePackagesDirectory / "InstallationMode_Rollback.wgt";
678   std::string pkgid = "smokeapp06";
679   std::string appid = "smokeapp06.InstallationModeRollback";
680   ASSERT_EQ(Install(path, PackageType::WGT, RequestResult::FAIL),
681             ci::AppInstaller::Result::ERROR);
682   CheckPackageNonExistance(pkgid, {appid});
683 }
684
685 TEST_F(SmokeTest, UpdateMode_Rollback) {
686   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Rollback.wgt";
687   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Rollback_2.wgt";
688   std::string pkgid = "smokeapp07";
689   std::string appid = "smokeapp07.UpdateModeRollback";
690   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
691   AddDataFiles(pkgid);
692   ASSERT_EQ(Install(path_new, PackageType::WGT, RequestResult::FAIL),
693                     ci::AppInstaller::Result::ERROR);
694   ValidatePackage(pkgid, {appid});
695
696   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
697   ValidateDataFiles(pkgid);
698 }
699
700 TEST_F(SmokeTest, InstallationMode_Hybrid) {
701   bf::path path = kSmokePackagesDirectory / "InstallationMode_Hybrid.wgt";
702   std::string pkgid = "smokehyb01";
703   std::string appid1 = "smokehyb01.Web";
704   std::string appid2 = "smokehyb01.Native";
705   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
706   ValidatePackage(pkgid, {appid1, appid2});
707 }
708
709 TEST_F(SmokeTest, UpdateMode_Hybrid) {
710   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Hybrid.wgt";
711   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Hybrid_2.wgt";
712   std::string pkgid = "smokehyb02";
713   std::string appid1 = "smokehyb02.Web";
714   std::string appid2 = "smokehyb02.Native";
715   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
716             ci::AppInstaller::Result::OK);
717   AddDataFiles(pkgid);
718   ASSERT_EQ(Install(path_new, PackageType::HYBRID),
719             ci::AppInstaller::Result::OK);
720   ValidatePackage(pkgid, {appid1, appid2});
721
722   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
723   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "VERSION", "2\n"));
724   ValidateDataFiles(pkgid);
725 }
726
727 TEST_F(SmokeTest, DeinstallationMode_Hybrid) {
728   bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Hybrid.wgt";
729   std::string pkgid = "smokehyb03";
730   std::string appid1 = "smokehyb03.Web";
731   std::string appid2 = "smokehyb03.Native";
732   ASSERT_EQ(Install(path, PackageType::HYBRID),
733             ci::AppInstaller::Result::OK);
734   ASSERT_EQ(Uninstall(pkgid, PackageType::HYBRID),
735             ci::AppInstaller::Result::OK);
736   CheckPackageNonExistance(pkgid, {appid1, appid2});
737 }
738
739 TEST_F(SmokeTest, DeltaMode_Hybrid) {
740   bf::path path = kSmokePackagesDirectory / "DeltaMode_Hybrid.wgt";
741   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Hybrid.delta";
742   std::string pkgid = "smokehyb04";
743   std::string appid1 = "smokehyb04.Web";
744   std::string appid2 = "smokehyb04.Native";
745   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
746             ci::AppInstaller::Result::OK);
747   ValidatePackage(pkgid, {appid1, appid2});
748
749   // Check delta modifications
750   bf::path root_path = ci::GetRootAppPath(false,
751       kTestUserId);
752   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
753   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
754   ASSERT_FALSE(bf::exists(root_path / pkgid / "lib" / "DELETED"));
755   ASSERT_TRUE(bf::exists(root_path / pkgid / "lib" / "ADDED"));
756   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "css" / "style.css"));  // NOLINT
757   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
758   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "js" / "main.js"));
759   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n"));  // NOLINT
760   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/MODIFIED", "version 2\n"));  // NOLINT
761 }
762
763 TEST_F(SmokeTest, MountInstallationMode_Hybrid) {
764   bf::path path = kSmokePackagesDirectory / "MountInstallationMode_Hybrid.wgt";
765   std::string pkgid = "smokehyb05";
766   std::string appid1 = "smokehyb05.web";
767   std::string appid2 = "smokehyb05.service";
768   ASSERT_EQ(MountInstall(path, PackageType::HYBRID),
769             ci::AppInstaller::Result::OK);
770   ScopedTzipInterface interface(pkgid);
771   ValidatePackage(pkgid, {appid1, appid2});
772 }
773
774 TEST_F(SmokeTest, MountUpdateMode_Hybrid) {
775   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Hybrid.wgt";
776   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_Hybrid_2.wgt";
777   std::string pkgid = "smokehyb06";
778   std::string appid1 = "smokehyb06.web";
779   std::string appid2 = "smokehyb06.service";
780   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
781             ci::AppInstaller::Result::OK);
782   AddDataFiles(pkgid);
783   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID),
784             ci::AppInstaller::Result::OK);
785   ScopedTzipInterface interface(pkgid);
786   ValidatePackage(pkgid, {appid1, appid2});
787
788   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
789   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "2\n"));
790   ValidateDataFiles(pkgid);
791 }
792
793 TEST_F(SmokeTest, InstallationMode_Rollback_Hybrid) {
794   bf::path path = kSmokePackagesDirectory /
795       "InstallationMode_Rollback_Hybrid.wgt";
796   std::string pkgid = "smokehyb07";
797   std::string appid1 = "smokehyb07.web";
798   std::string appid2 = "smokehyb07.service";
799   ASSERT_EQ(Install(path, PackageType::HYBRID, RequestResult::FAIL),
800             ci::AppInstaller::Result::ERROR);
801   CheckPackageNonExistance(pkgid, {appid1, appid2});
802 }
803
804 TEST_F(SmokeTest, UpdateMode_Rollback_Hybrid) {
805   bf::path path_old = kSmokePackagesDirectory /
806       "UpdateMode_Rollback_Hybrid.wgt";
807   bf::path path_new = kSmokePackagesDirectory /
808       "UpdateMode_Rollback_Hybrid_2.wgt";
809   std::string pkgid = "smokehyb08";
810   std::string appid1 = "smokehyb08.web";
811   std::string appid2 = "smokehyb08.service";
812   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
813             ci::AppInstaller::Result::OK);
814   AddDataFiles(pkgid);
815   ASSERT_EQ(Install(path_new, PackageType::HYBRID,
816       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
817   ValidatePackage(pkgid, {appid1, appid2});
818
819   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
820   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
821   ValidateDataFiles(pkgid);
822 }
823
824 TEST_F(SmokeTest, MountInstallationMode_Rollback_Hybrid) {
825   bf::path path = kSmokePackagesDirectory /
826       "MountInstallationMode_Rollback_Hybrid.wgt";
827   std::string pkgid = "smokehyb09";
828   std::string appid1 = "smokehyb09.web";
829   std::string appid2 = "smokehyb09.service";
830   ASSERT_EQ(MountInstall(path, PackageType::HYBRID, RequestResult::FAIL),
831       ci::AppInstaller::Result::ERROR);
832   ScopedTzipInterface interface(pkgid);
833   CheckPackageNonExistance(pkgid, {appid1, appid2});
834 }
835
836 TEST_F(SmokeTest, MountUpdateMode_Rollback_Hybrid) {
837   bf::path path_old = kSmokePackagesDirectory /
838       "MountUpdateMode_Rollback_Hybrid.wgt";
839   bf::path path_new = kSmokePackagesDirectory /
840       "MountUpdateMode_Rollback_Hybrid_2.wgt";
841   std::string pkgid = "smokehyb10";
842   std::string appid1 = "smokehyb10.web";
843   std::string appid2 = "smokehyb10.service";
844   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
845             ci::AppInstaller::Result::OK);
846   AddDataFiles(pkgid);
847   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID,
848       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
849   ScopedTzipInterface interface(pkgid);
850   ValidatePackage(pkgid, {appid1, appid2});
851
852   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
853   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
854   ValidateDataFiles(pkgid);
855 }
856
857 TEST_F(SmokeTest, MountInstallationMode) {
858   bf::path path = kSmokePackagesDirectory / "MountInstallationMode.wgt";
859   std::string pkgid = "smokeapp28";
860   std::string appid = "smokeapp28.InstallationMode";
861   ASSERT_EQ(MountInstall(path, PackageType::WGT), ci::AppInstaller::Result::OK);
862   ScopedTzipInterface interface(pkgid);
863   ValidatePackage(pkgid, {appid});
864 }
865
866 TEST_F(SmokeTest, MountUpdateMode) {
867   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode.wgt";
868   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_2.wgt";
869   std::string pkgid = "smokeapp29";
870   std::string appid = "smokeapp29.UpdateMode";
871   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
872             ci::AppInstaller::Result::OK);
873   AddDataFiles(pkgid);
874   ASSERT_EQ(MountInstall(path_new, PackageType::WGT),
875             ci::AppInstaller::Result::OK);
876   ScopedTzipInterface interface(pkgid);
877   ValidatePackage(pkgid, {appid});
878
879   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
880   ValidateDataFiles(pkgid);
881 }
882
883 TEST_F(SmokeTest, MountInstallationMode_Rollback) {
884   bf::path path =
885       kSmokePackagesDirectory / "MountInstallationMode_Rollback.wgt";
886   std::string pkgid = "smokeapp33";
887   std::string appid = "smokeapp33.web";
888   ASSERT_EQ(MountInstall(path, PackageType::WGT, RequestResult::FAIL),
889             ci::AppInstaller::Result::ERROR);
890   ScopedTzipInterface interface(pkgid);
891   CheckPackageNonExistance(pkgid, {appid});
892 }
893
894 TEST_F(SmokeTest, MountUpdateMode_Rollback) {
895   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Rollback.wgt";
896   bf::path path_new =
897       kSmokePackagesDirectory / "MountUpdateMode_Rollback_2.wgt";
898   std::string pkgid = "smokeapp34";
899   std::string appid = "smokeapp34.web";
900   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
901             ci::AppInstaller::Result::OK);
902   AddDataFiles(pkgid);
903   ASSERT_EQ(MountInstall(path_new, PackageType::WGT,
904       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
905   ScopedTzipInterface interface(pkgid);
906   ValidatePackage(pkgid, {appid});
907
908   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
909   ValidateDataFiles(pkgid);
910 }
911
912 TEST_F(SmokeTest, UserDefinedPlugins) {
913   bf::path path = kSmokePackagesDirectory / "SimpleEchoPrivilege.wgt";
914   std::string pkgid = "0CSPVhKmRk";
915   std::string appid = "0CSPVhKmRk.SimpleEcho";
916   std::string call_privilege = "http://tizen.org/privilege/call";
917   std::string location_privilege = "http://tizen.org/privilege/location";
918   std::string power_privilege = "http://tizen.org/privilege/power";
919
920   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
921   ValidatePackage(pkgid, {appid});
922   std::vector<std::string> res;
923   ASSERT_TRUE(ci::QueryPrivilegesForPkgId(pkgid, kTestUserId, &res));
924   ASSERT_TRUE(std::find(res.begin(), res.end(), call_privilege) != res.end());
925   ASSERT_TRUE(std::find(res.begin(), res.end(), location_privilege)
926           != res.end());
927   ASSERT_TRUE(std::find(res.begin(), res.end(), power_privilege) != res.end());
928 }
929
930 }  // namespace common_installer
931
932 int main(int argc,  char** argv) {
933   testing::InitGoogleTest(&argc, argv);
934   bf::path directory =
935         bf::path("/home") / tzplatform_getenv(TZ_SYS_DEFAULT_USER);
936   testing::AddGlobalTestEnvironment(
937       new common_installer::SmokeEnvironment(directory));
938   return RUN_ALL_TESTS();
939 }