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