Smoke test for enable/disable pkg
[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 #include <common/paths.h>
10 #include <common/pkgmgr_interface.h>
11 #include <common/pkgmgr_query.h>
12 #include <common/request.h>
13 #include <common/step/configuration/step_fail.h>
14 #include <common/tzip_interface.h>
15 #include <common/utils/subprocess.h>
16 #include <gtest/gtest.h>
17 #include <gtest/gtest-death-test.h>
18 #include <pkgmgr-info.h>
19 #include <signal.h>
20 #include <unistd.h>
21 #include <tzplatform_config.h>
22
23 #include <array>
24 #include <cstdio>
25 #include <cstdlib>
26 #include <vector>
27
28 #include "hybrid/hybrid_installer.h"
29 #include "wgt/wgt_app_query_interface.h"
30 #include "wgt/wgt_installer.h"
31
32 #define SIZEOFARRAY(ARR)                                                       \
33   sizeof(ARR) / sizeof(ARR[0])                                                 \
34
35 namespace bf = boost::filesystem;
36 namespace bs = boost::system;
37 namespace ci = common_installer;
38
39 namespace {
40
41 const bf::path kSmokePackagesDirectory =
42     "/usr/share/wgt-backend-ut/test_samples/smoke/";
43
44 const char kApplicationDir[] = ".applications";
45 const char kApplicationDirBackup[] = ".applications.bck";
46 const char KUserAppsDir[] = "apps_rw";
47 const char KUserAppsDirBackup[] = "apps_rw.bck";
48
49 enum class RequestResult {
50   NORMAL,
51   FAIL
52 };
53
54 class ScopedTzipInterface {
55  public:
56   explicit ScopedTzipInterface(const std::string& pkgid)
57       : pkg_path_(bf::path(ci::GetRootAppPath(false)) / pkgid),
58         interface_(ci::GetMountLocation(pkg_path_)) {
59     interface_.MountZip(ci::GetZipPackageLocation(pkg_path_, pkgid));
60   }
61
62   ~ScopedTzipInterface() {
63     interface_.UnmountZip();
64   }
65
66  private:
67   bf::path pkg_path_;
68   ci::TzipInterface interface_;
69 };
70
71 class TestPkgmgrInstaller : public ci::PkgmgrInstallerInterface {
72  public:
73   bool CreatePkgMgrInstaller(pkgmgr_installer** installer,
74                              ci::InstallationMode* mode) {
75     *installer = pkgmgr_installer_offline_new();
76     if (!*installer)
77       return false;
78     *mode = ci::InstallationMode::ONLINE;
79     return true;
80   }
81
82   bool ShouldCreateSignal() const {
83     return false;
84   }
85 };
86
87 enum class PackageType {
88   WGT,
89   HYBRID
90 };
91
92 bool TouchFile(const bf::path& path) {
93   FILE* f = fopen(path.c_str(), "w+");
94   if (!f)
95     return false;
96   fclose(f);
97   return true;
98 }
99
100 void RemoveAllRecoveryFiles() {
101   bf::path root_path = ci::GetRootAppPath(false);
102   if (!bf::exists(root_path))
103     return;
104   for (auto& dir_entry : boost::make_iterator_range(
105          bf::directory_iterator(root_path), bf::directory_iterator())) {
106     if (bf::is_regular_file(dir_entry)) {
107       if (dir_entry.path().string().find("/recovery") != std::string::npos) {
108         bs::error_code error;
109         bf::remove(dir_entry.path(), error);
110       }
111     }
112   }
113 }
114
115 bf::path FindRecoveryFile() {
116   bf::path root_path = ci::GetRootAppPath(false);
117   for (auto& dir_entry : boost::make_iterator_range(
118          bf::directory_iterator(root_path), bf::directory_iterator())) {
119     if (bf::is_regular_file(dir_entry)) {
120       if (dir_entry.path().string().find("/recovery") != std::string::npos) {
121         return dir_entry.path();
122       }
123     }
124   }
125   return {};
126 }
127
128 bool ValidateFileContentInPackage(const std::string& pkgid,
129                                   const std::string& relative,
130                                   const std::string& expected) {
131   bf::path root_path = ci::GetRootAppPath(false);
132   bf::path file_path = root_path / pkgid / relative;
133   if (!bf::exists(file_path)) {
134     LOG(ERROR) << file_path << " doesn't exist";
135     return false;
136   }
137   FILE* handle = fopen(file_path.c_str(), "r");
138   if (!handle) {
139     LOG(ERROR) << file_path << " cannot  be open";
140     return false;
141   }
142   std::string content;
143   std::array<char, 200> buffer;
144   while (fgets(buffer.data(), buffer.size(), handle)) {
145     content += buffer.data();
146   }
147   fclose(handle);
148   return content == expected;
149 }
150
151 void ValidatePackageFS(const std::string& pkgid,
152                        const std::vector<std::string>& appids) {
153   bf::path root_path = ci::GetRootAppPath(false);
154   bf::path package_path = root_path / pkgid;
155   bf::path data_path = package_path / "data";
156   bf::path shared_path = package_path / "shared";
157   bf::path cache_path = package_path / "cache";
158   ASSERT_TRUE(bf::exists(root_path));
159   ASSERT_TRUE(bf::exists(package_path));
160   ASSERT_TRUE(bf::exists(data_path));
161   ASSERT_TRUE(bf::exists(shared_path));
162   ASSERT_TRUE(bf::exists(cache_path));
163
164   bf::path manifest_path =
165       bf::path(getUserManifestPath(getuid(), false)) / (pkgid + ".xml");
166   ASSERT_TRUE(bf::exists(manifest_path));
167
168   for (auto& appid : appids) {
169     bf::path binary_path = package_path / "bin" / appid;
170     ASSERT_TRUE(bf::exists(binary_path));
171     bf::path icon_path =
172         bf::path(getIconPath(getuid(), false)) / (appid + ".png");
173     ASSERT_TRUE(bf::exists(icon_path));
174     bf::path icon_backup = ci::GetBackupPathForIconFile(icon_path);
175     ASSERT_FALSE(bf::exists(icon_backup));
176   }
177
178   bf::path widget_root_path = package_path / "res" / "wgt";
179   bf::path config_path = widget_root_path / "config.xml";
180   ASSERT_TRUE(bf::exists(widget_root_path));
181   ASSERT_TRUE(bf::exists(config_path));
182
183   bf::path private_tmp_path = package_path / "tmp";
184   ASSERT_TRUE(bf::exists(private_tmp_path));
185
186   // backups should not exist
187   bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
188   bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
189   ASSERT_FALSE(bf::exists(package_backup));
190   ASSERT_FALSE(bf::exists(manifest_backup));
191 }
192
193 void PackageCheckCleanup(const std::string& pkgid,
194                          const std::vector<std::string>& appids) {
195   bf::path root_path = ci::GetRootAppPath(false);
196   bf::path package_path = root_path / pkgid;
197   ASSERT_FALSE(bf::exists(package_path));
198
199   bf::path manifest_path =
200       bf::path(getUserManifestPath(getuid(), false)) / (pkgid + ".xml");
201   ASSERT_FALSE(bf::exists(manifest_path));
202
203   for (auto& appid : appids) {
204     bf::path icon_path =
205         bf::path(getIconPath(getuid(), false)) / (appid + ".png");
206     ASSERT_FALSE(bf::exists(icon_path));
207     bf::path icon_backup = ci::GetBackupPathForIconFile(icon_path);
208     ASSERT_FALSE(bf::exists(icon_backup));
209   }
210
211   // backups should not exist
212   bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
213   bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
214   ASSERT_FALSE(bf::exists(package_backup));
215   ASSERT_FALSE(bf::exists(manifest_backup));
216 }
217
218 void ValidatePackage(const std::string& pkgid,
219                      const std::vector<std::string>& appids) {
220   ASSERT_TRUE(ci::QueryIsPackageInstalled(pkgid, ci::GetRequestMode()));
221   ValidatePackageFS(pkgid, appids);
222 }
223
224 void CheckPackageNonExistance(const std::string& pkgid,
225                               const std::vector<std::string>& appids) {
226   ASSERT_FALSE(ci::QueryIsPackageInstalled(pkgid, ci::GetRequestMode()));
227   PackageCheckCleanup(pkgid, appids);
228 }
229
230 std::unique_ptr<ci::AppQueryInterface> CreateQueryInterface() {
231   std::unique_ptr<ci::AppQueryInterface> query_interface(
232       new wgt::WgtAppQueryInterface());
233   return query_interface;
234 }
235
236 std::unique_ptr<ci::AppInstaller> CreateInstaller(ci::PkgMgrPtr pkgmgr,
237                                                   PackageType type) {
238   switch (type) {
239     case PackageType::WGT:
240       return std::unique_ptr<ci::AppInstaller>(new wgt::WgtInstaller(pkgmgr));
241     case PackageType::HYBRID:
242       return std::unique_ptr<ci::AppInstaller>(
243           new hybrid::HybridInstaller(pkgmgr));
244     default:
245       LOG(ERROR) << "Unknown installer type";
246       return nullptr;
247   }
248 }
249
250 ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr,
251                                                  PackageType type,
252                                                  RequestResult mode) {
253   std::unique_ptr<ci::AppInstaller> installer = CreateInstaller(pkgmgr, type);
254   switch (mode) {
255   case RequestResult::FAIL:
256     installer->AddStep<ci::configuration::StepFail>();
257     break;
258   default:
259     break;
260   }
261   return installer->Run();
262 }
263 ci::AppInstaller::Result CallBackend(int argc,
264                                      const char* argv[],
265                                      PackageType type,
266                                      RequestResult mode = RequestResult::NORMAL
267                                      ) {
268   TestPkgmgrInstaller pkgmgr_installer;
269   std::unique_ptr<ci::AppQueryInterface> query_interface =
270       CreateQueryInterface();
271   auto pkgmgr =
272       ci::PkgMgrInterface::Create(argc, const_cast<char**>(argv),
273                                   &pkgmgr_installer, query_interface.get());
274   if (!pkgmgr) {
275     LOG(ERROR) << "Failed to initialize pkgmgr interface";
276     return ci::AppInstaller::Result::UNKNOWN;
277   }
278   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
279 }
280
281 ci::AppInstaller::Result Install(const bf::path& path,
282                                  PackageType type,
283                                  RequestResult mode = RequestResult::NORMAL) {
284   const char* argv[] = {"", "-i", path.c_str()};
285   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
286 }
287
288 ci::AppInstaller::Result Update(const bf::path& path_old,
289                                 const bf::path& path_new,
290                                 PackageType type,
291                                 RequestResult mode = RequestResult::NORMAL) {
292   if (Install(path_old, type) != ci::AppInstaller::Result::OK) {
293     LOG(ERROR) << "Failed to install application. Cannot update";
294     return ci::AppInstaller::Result::UNKNOWN;
295   }
296   return Install(path_new, type, mode);
297 }
298
299 ci::AppInstaller::Result MountInstall(const bf::path& path,
300     PackageType type, RequestResult mode = RequestResult::NORMAL) {
301   const char* argv[] = {"", "-w", path.c_str()};
302   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
303 }
304
305 ci::AppInstaller::Result MountUpdate(const bf::path& path_old,
306     const bf::path& path_new, PackageType type,
307     RequestResult mode = RequestResult::NORMAL) {
308   if (MountInstall(path_old, type) != ci::AppInstaller::Result::OK) {
309     LOG(ERROR) << "Failed to mount-install application. Cannot mount-update";
310     return ci::AppInstaller::Result::UNKNOWN;
311   }
312   return MountInstall(path_new, type, mode);
313 }
314
315 ci::AppInstaller::Result Uninstall(const std::string& pkgid,
316                                    PackageType type,
317                                    RequestResult mode = RequestResult::NORMAL) {
318   const char* argv[] = {"", "-d", pkgid.c_str()};
319   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
320 }
321
322 ci::AppInstaller::Result Reinstall(const bf::path& path,
323                                    const bf::path& delta_dir,
324                                    PackageType type,
325                                    RequestResult mode = RequestResult::NORMAL) {
326   if (Install(path, type) != ci::AppInstaller::Result::OK) {
327     LOG(ERROR) << "Failed to install application. Cannot perform RDS";
328     return ci::AppInstaller::Result::UNKNOWN;
329   }
330   const char* argv[] = {"", "-r", delta_dir.c_str()};
331   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
332 }
333
334 ci::AppInstaller::Result DeltaInstall(const bf::path& path,
335     const bf::path& delta_package, PackageType type) {
336   if (Install(path, type) != ci::AppInstaller::Result::OK) {
337     LOG(ERROR) << "Failed to install application. Cannot perform delta update";
338     return ci::AppInstaller::Result::UNKNOWN;
339   }
340   return Install(delta_package, type);
341 }
342
343 ci::AppInstaller::Result Clear(const std::string& pkgid,
344                                    PackageType type,
345                                    RequestResult mode = RequestResult::NORMAL) {
346   const char* argv[] = {"", "-c", pkgid.c_str()};
347   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
348 }
349
350 ci::AppInstaller::Result EnablePackage(const std::string& pkgid,
351                                   PackageType type,
352                                   RequestResult mode = RequestResult::NORMAL) {
353   const char* argv[] = {"", "-A", pkgid.c_str()};
354   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
355 }
356
357 ci::AppInstaller::Result DisablePackage(const std::string& pkgid,
358                                   PackageType type,
359                                   RequestResult mode = RequestResult::NORMAL) {
360   const char* argv[] = {"", "-D", pkgid.c_str()};
361   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
362 }
363
364 ci::AppInstaller::Result Recover(const bf::path& recovery_file,
365                                  PackageType type,
366                                  RequestResult mode = RequestResult::NORMAL) {
367   const char* argv[] = {"", "-b", recovery_file.c_str()};
368   TestPkgmgrInstaller pkgmgr_installer;
369   std::unique_ptr<ci::AppQueryInterface> query_interface =
370       CreateQueryInterface();
371   auto pkgmgr =
372       ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast<char**>(argv),
373                                   &pkgmgr_installer, query_interface.get());
374   if (!pkgmgr) {
375     LOG(ERROR) << "Failed to initialize pkgmgr interface";
376     return ci::AppInstaller::Result::UNKNOWN;
377   }
378   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
379 }
380
381 }  // namespace
382
383 namespace common_installer {
384
385 class SmokeEnvironment : public testing::Environment {
386  public:
387   explicit SmokeEnvironment(const bf::path& home) : home_(home) {
388   }
389   void SetUp() override {
390     bs::error_code error;
391     bf::remove_all(home_ / kApplicationDirBackup, error);
392     bf::remove_all(home_ / KUserAppsDirBackup, error);
393     if (bf::exists(home_ / KUserAppsDir)) {
394       bf::rename(home_ / KUserAppsDir, home_ / KUserAppsDirBackup, error);
395       if (error)
396         LOG(ERROR) << "Failed to setup test environment. Does some previous"
397                    << " test crashed? Directory: "
398                    << (home_ / KUserAppsDirBackup) << " should not exist.";
399       assert(!error);
400     }
401     if (bf::exists(home_ / kApplicationDir)) {
402       bf::rename(home_ / kApplicationDir, home_ / kApplicationDirBackup, error);
403       if (error)
404         LOG(ERROR) << "Failed to setup test environment. Does some previous"
405                    << " test crashed? Directory: "
406                    << (home_ / kApplicationDirBackup) << " should not exist.";
407       assert(!error);
408     }
409   }
410   void TearDown() override {
411     bs::error_code error;
412     bf::remove_all(home_ / kApplicationDir, error);
413     bf::remove_all(home_ / KUserAppsDir, error);
414     if (bf::exists(home_ / KUserAppsDirBackup))
415       bf::rename(home_ / KUserAppsDirBackup, home_ / KUserAppsDir, error);
416     if (bf::exists(home_ / kApplicationDirBackup))
417       bf::rename(home_ / kApplicationDirBackup, home_ / kApplicationDir, error);
418   }
419
420  private:
421   bf::path home_;
422 };
423
424 class SmokeTest : public testing::Test {
425 };
426
427 TEST_F(SmokeTest, InstallationMode) {
428   bf::path path = kSmokePackagesDirectory / "InstallationMode.wgt";
429   std::string pkgid = "smokeapp03";
430   std::string appid = "smokeapp03.InstallationMode";
431   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
432   ValidatePackage(pkgid, {appid});
433 }
434
435 TEST_F(SmokeTest, UpdateMode) {
436   bf::path path_old = kSmokePackagesDirectory / "UpdateMode.wgt";
437   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_2.wgt";
438   std::string pkgid = "smokeapp04";
439   std::string appid = "smokeapp04.UpdateMode";
440   ASSERT_EQ(Update(path_old, path_new, PackageType::WGT),
441             ci::AppInstaller::Result::OK);
442   ValidatePackage(pkgid, {appid});
443
444   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
445 }
446
447 TEST_F(SmokeTest, DeinstallationMode) {
448   bf::path path = kSmokePackagesDirectory / "DeinstallationMode.wgt";
449   std::string pkgid = "smokeapp05";
450   std::string appid = "smokeapp05.DeinstallationMode";
451   ASSERT_EQ(Install(path, PackageType::WGT),
452             ci::AppInstaller::Result::OK);
453   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK);
454   CheckPackageNonExistance(pkgid, {appid});
455 }
456
457 TEST_F(SmokeTest, RDSMode) {
458   bf::path path = kSmokePackagesDirectory / "RDSMode.wgt";
459   bf::path delta_directory = kSmokePackagesDirectory / "delta_dir/";
460   std::string pkgid = "smokeapp11";
461   std::string appid = "smokeapp11.RDSMode";
462   ASSERT_EQ(Reinstall(path, delta_directory, PackageType::WGT),
463             ci::AppInstaller::Result::OK);
464   ValidatePackage(pkgid, {appid});
465
466   // Check delta modifications
467   bf::path root_path = ci::GetRootAppPath(false);
468   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
469   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
470   ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "2\n");
471 }
472
473 TEST_F(SmokeTest, EnablePkg) {
474   bf::path path = kSmokePackagesDirectory / "EnablePkg.wgt";
475   std::string pkgid = "smokeapp22";
476   ASSERT_EQ(Install(path, PackageType::WGT),
477             ci::AppInstaller::Result::OK);
478   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
479             ci::AppInstaller::Result::OK);
480   ASSERT_EQ(EnablePackage(pkgid, PackageType::WGT),
481             ci::AppInstaller::Result::OK);
482
483   ASSERT_TRUE(ci::QueryIsPackageInstalled(pkgid, ci::GetRequestMode()));
484 }
485
486 TEST_F(SmokeTest, DisablePkg) {
487   bf::path path = kSmokePackagesDirectory / "DisablePkg.wgt";
488   std::string pkgid = "smokeapp21";
489   std::string appid = "smokeapp21.DisablePkg";
490   ASSERT_EQ(Install(path, PackageType::WGT),
491             ci::AppInstaller::Result::OK);
492   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
493             ci::AppInstaller::Result::OK);
494   ASSERT_FALSE(ci::QueryIsPackageInstalled(pkgid, ci::GetRequestMode()));
495   ValidatePackageFS(pkgid, {appid});
496 }
497
498 TEST_F(SmokeTest, ClearMode) {
499   bf::path path = kSmokePackagesDirectory / "ClearMode.wgt";
500   std::string pkgid = "smokeapp20";
501   std::string appid = "smokeapp20.ClearMode";
502   ASSERT_EQ(Install(path, PackageType::WGT),
503             ci::AppInstaller::Result::OK);
504   bf::path root_path = ci::GetRootAppPath(false);
505   bs::error_code error;
506   bf::create_directory(root_path / pkgid / "data" / "dir", error);
507   ASSERT_FALSE(error);
508   ASSERT_TRUE(TouchFile(root_path / pkgid / "data" / "dir" / "file"));
509   ASSERT_TRUE(TouchFile(root_path / pkgid / "data" / "file"));
510   ASSERT_EQ(Clear(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK);
511   ValidatePackage(pkgid, {appid});
512   ASSERT_FALSE(bf::exists(root_path / pkgid / "data" / "dir" / "file"));
513   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "file"));
514 }
515
516 TEST_F(SmokeTest, DeltaMode) {
517   bf::path path = kSmokePackagesDirectory / "DeltaMode.wgt";
518   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode.delta";
519   std::string pkgid = "smokeapp17";
520   std::string appid = "smokeapp17.DeltaMode";
521   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
522             ci::AppInstaller::Result::OK);
523   ValidatePackage(pkgid, {appid});
524
525   // Check delta modifications
526   bf::path root_path = ci::GetRootAppPath(false);
527   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
528   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
529   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "css" / "style.css"));  // NOLINT
530   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
531   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "js" / "main.js"));
532   ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n");
533 }
534
535 TEST_F(SmokeTest, RecoveryMode_ForInstallation) {
536   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForInstallation.wgt";
537   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
538   backend_crash.Run("-i", path.string());
539   ASSERT_NE(backend_crash.Wait(), 0);
540
541   std::string pkgid = "smokeapp09";
542   std::string appid = "smokeapp09.RecoveryModeForInstallation";
543   bf::path recovery_file = FindRecoveryFile();
544   ASSERT_FALSE(recovery_file.empty());
545   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
546       ci::AppInstaller::Result::OK);
547   CheckPackageNonExistance(pkgid, {appid});
548 }
549
550 TEST_F(SmokeTest, RecoveryMode_ForUpdate) {
551   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForUpdate.wgt";
552   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForUpdate_2.wgt";
553   RemoveAllRecoveryFiles();
554   Subprocess backend_test("/usr/bin/wgt-backend");
555   backend_test.Run("-i", path_old.string());
556   ASSERT_EQ(backend_test.Wait(), 0);
557   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
558   backend_crash.Run("-i", path_new.string());
559   ASSERT_NE(backend_crash.Wait(), 0);
560
561   std::string pkgid = "smokeapp10";
562   std::string appid = "smokeapp10.RecoveryModeForUpdate";
563   bf::path recovery_file = FindRecoveryFile();
564   ASSERT_FALSE(recovery_file.empty());
565   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
566             ci::AppInstaller::Result::OK);
567   ValidatePackage(pkgid, {appid});
568
569   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
570 }
571
572 TEST_F(SmokeTest, InstallationMode_GoodSignature) {
573   bf::path path = kSmokePackagesDirectory / "InstallationMode_GoodSignature.wgt";  // NOLINT
574   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
575 }
576
577 TEST_F(SmokeTest, InstallationMode_WrongSignature) {
578   bf::path path = kSmokePackagesDirectory / "InstallationMode_WrongSignature.wgt";  // NOLINT
579   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::ERROR);
580 }
581
582 TEST_F(SmokeTest, InstallationMode_Rollback) {
583   bf::path path = kSmokePackagesDirectory / "InstallationMode_Rollback.wgt";
584   std::string pkgid = "smokeapp06";
585   std::string appid = "smokeapp06.InstallationModeRollback";
586   ASSERT_EQ(Install(path, PackageType::WGT, RequestResult::FAIL),
587             ci::AppInstaller::Result::ERROR);
588   CheckPackageNonExistance(pkgid, {appid});
589 }
590
591 TEST_F(SmokeTest, UpdateMode_Rollback) {
592   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Rollback.wgt";
593   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Rollback_2.wgt";
594   std::string pkgid = "smokeapp07";
595   std::string appid = "smokeapp07.UpdateModeRollback";
596   ASSERT_EQ(Update(path_old, path_new, PackageType::WGT, RequestResult::FAIL),
597                    ci::AppInstaller::Result::ERROR);
598   ValidatePackage(pkgid, {appid});
599
600   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
601 }
602
603 TEST_F(SmokeTest, InstallationMode_Hybrid) {
604   bf::path path = kSmokePackagesDirectory / "InstallationMode_Hybrid.wgt";
605   std::string pkgid = "smokehyb01";
606   std::string appid1 = "smokehyb01.Web";
607   std::string appid2 = "smokehyb01.Native";
608   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
609   ValidatePackage(pkgid, {appid1, appid2});
610 }
611
612 TEST_F(SmokeTest, UpdateMode_Hybrid) {
613   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Hybrid.wgt";
614   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Hybrid_2.wgt";
615   std::string pkgid = "smokehyb02";
616   std::string appid1 = "smokehyb02.Web";
617   std::string appid2 = "smokehyb02.Native";
618   ASSERT_EQ(Update(path_old, path_new, PackageType::HYBRID),
619             ci::AppInstaller::Result::OK);
620   ValidatePackage(pkgid, {appid1, appid2});
621
622   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
623   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "VERSION", "2\n"));
624 }
625
626 TEST_F(SmokeTest, DeinstallationMode_Hybrid) {
627   bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Hybrid.wgt";
628   std::string pkgid = "smokehyb03";
629   std::string appid1 = "smokehyb03.Web";
630   std::string appid2 = "smokehyb03.Native";
631   ASSERT_EQ(Install(path, PackageType::HYBRID),
632             ci::AppInstaller::Result::OK);
633   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK);
634   CheckPackageNonExistance(pkgid, {appid1, appid2});
635 }
636
637 TEST_F(SmokeTest, DeltaMode_Hybrid) {
638   bf::path path = kSmokePackagesDirectory / "DeltaMode_Hybrid.wgt";
639   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Hybrid.delta";
640   std::string pkgid = "smokehyb04";
641   std::string appid1 = "smokehyb04.Web";
642   std::string appid2 = "smokehyb04.Native";
643   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
644             ci::AppInstaller::Result::OK);
645   ValidatePackage(pkgid, {appid1, appid2});
646
647   // Check delta modifications
648   bf::path root_path = ci::GetRootAppPath(false);
649   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
650   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
651   ASSERT_FALSE(bf::exists(root_path / pkgid / "lib" / "DELETED"));
652   ASSERT_TRUE(bf::exists(root_path / pkgid / "lib" / "ADDED"));
653   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "css" / "style.css"));  // NOLINT
654   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
655   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "js" / "main.js"));
656   ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n");
657   ValidateFileContentInPackage(pkgid, "lib/MODIFIED", "version 2\n");
658 }
659
660 TEST_F(SmokeTest, MountInstallationMode) {
661   bf::path path = kSmokePackagesDirectory / "MountInstallationMode.wgt";
662   std::string pkgid = "smokeapp28";
663   std::string appid = "smokeapp28.InstallationMode";
664   ASSERT_EQ(MountInstall(path, PackageType::WGT), ci::AppInstaller::Result::OK);
665   ScopedTzipInterface interface(pkgid);
666   ValidatePackage(pkgid, {appid});
667 }
668
669 TEST_F(SmokeTest, MountUpdateMode) {
670   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode.wgt";
671   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_2.wgt";
672   std::string pkgid = "smokeapp29";
673   std::string appid = "smokeapp29.UpdateMode";
674   ASSERT_EQ(MountUpdate(path_old, path_new, PackageType::WGT),
675             ci::AppInstaller::Result::OK);
676   ScopedTzipInterface interface(pkgid);
677   ValidatePackage(pkgid, {appid});
678
679   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
680 }
681
682 }  // namespace common_installer
683
684 int main(int argc,  char** argv) {
685   testing::InitGoogleTest(&argc, argv);
686   const char* directory = getenv("HOME");
687   if (!directory) {
688     LOG(ERROR) << "Cannot get $HOME value";
689     return 1;
690   }
691   testing::AddGlobalTestEnvironment(
692       new common_installer::SmokeEnvironment(directory));
693   return RUN_ALL_TESTS();
694 }