Smoke test for mount install
[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/backup_paths.h>
10 #include <common/pkgmgr_interface.h>
11 #include <common/pkgmgr_registration.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::IsPackageInstalled(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::IsPackageInstalled(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
264 ci::AppInstaller::Result Install(const bf::path& path,
265                                  PackageType type,
266                                  RequestResult mode = RequestResult::NORMAL) {
267   const char* argv[] = {"", "-i", path.c_str()};
268   TestPkgmgrInstaller pkgmgr_installer;
269   std::unique_ptr<ci::AppQueryInterface> query_interface =
270       CreateQueryInterface();
271   auto pkgmgr =
272       ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), 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 Update(const bf::path& path_old,
282                                 const bf::path& path_new,
283                                 PackageType type,
284                                 RequestResult mode = RequestResult::NORMAL) {
285   if (Install(path_old, type) != ci::AppInstaller::Result::OK) {
286     LOG(ERROR) << "Failed to install application. Cannot update";
287     return ci::AppInstaller::Result::UNKNOWN;
288   }
289   return Install(path_new, type, mode);
290 }
291
292 ci::AppInstaller::Result MountInstall(const bf::path& path,
293     PackageType type, RequestResult mode = RequestResult::NORMAL) {
294   const char* argv[] = {"", "-w", path.c_str()};
295   TestPkgmgrInstaller pkgmgr_installer;
296   std::unique_ptr<ci::AppQueryInterface> query_interface =
297       CreateQueryInterface();
298   auto pkgmgr =
299       ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast<char**>(argv),
300                                   &pkgmgr_installer, query_interface.get());
301   if (!pkgmgr) {
302     LOG(ERROR) << "Failed to initialize pkgmgr interface";
303     return ci::AppInstaller::Result::UNKNOWN;
304   }
305   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
306 }
307
308 ci::AppInstaller::Result MountUpdate(const bf::path& path_old,
309     const bf::path& path_new, PackageType type,
310     RequestResult mode = RequestResult::NORMAL) {
311   if (MountInstall(path_old, type) != ci::AppInstaller::Result::OK) {
312     LOG(ERROR) << "Failed to mount-install application. Cannot mount-update";
313     return ci::AppInstaller::Result::UNKNOWN;
314   }
315   return MountInstall(path_new, type, mode);
316 }
317
318 ci::AppInstaller::Result Uninstall(const std::string& pkgid,
319                                    PackageType type,
320                                    RequestResult mode = RequestResult::NORMAL) {
321   const char* argv[] = {"", "-d", pkgid.c_str()};
322   TestPkgmgrInstaller pkgmgr_installer;
323   std::unique_ptr<ci::AppQueryInterface> query_interface =
324       CreateQueryInterface();
325   auto pkgmgr =
326       ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast<char**>(argv),
327                                   &pkgmgr_installer, query_interface.get());
328   if (!pkgmgr) {
329     LOG(ERROR) << "Failed to initialize pkgmgr interface";
330     return ci::AppInstaller::Result::UNKNOWN;
331   }
332   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
333 }
334
335 ci::AppInstaller::Result Reinstall(const bf::path& path,
336                                    const bf::path& delta_dir,
337                                    PackageType type,
338                                    RequestResult mode = RequestResult::NORMAL) {
339   if (Install(path, type) != ci::AppInstaller::Result::OK) {
340     LOG(ERROR) << "Failed to install application. Cannot perform RDS";
341     return ci::AppInstaller::Result::UNKNOWN;
342   }
343   const char* argv[] = {"", "-r", delta_dir.c_str()};
344   TestPkgmgrInstaller pkgmgr_installer;
345   std::unique_ptr<ci::AppQueryInterface> query_interface =
346       CreateQueryInterface();
347   auto pkgmgr =
348       ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast<char**>(argv),
349                                   &pkgmgr_installer, query_interface.get());
350   if (!pkgmgr) {
351     LOG(ERROR) << "Failed to initialize pkgmgr interface";
352     return ci::AppInstaller::Result::UNKNOWN;
353   }
354   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
355 }
356
357 ci::AppInstaller::Result DeltaInstall(const bf::path& path,
358     const bf::path& delta_package, PackageType type) {
359   if (Install(path, type) != ci::AppInstaller::Result::OK) {
360     LOG(ERROR) << "Failed to install application. Cannot perform delta update";
361     return ci::AppInstaller::Result::UNKNOWN;
362   }
363   return Install(delta_package, type);
364 }
365
366 ci::AppInstaller::Result Clear(const std::string& pkgid,
367                                    PackageType type,
368                                    RequestResult mode = RequestResult::NORMAL) {
369   const char* argv[] = {"", "-c", pkgid.c_str()};
370   TestPkgmgrInstaller pkgmgr_installer;
371   std::unique_ptr<ci::AppQueryInterface> query_interface =
372       CreateQueryInterface();
373   auto pkgmgr =
374       ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast<char**>(argv),
375                                   &pkgmgr_installer, query_interface.get());
376   if (!pkgmgr) {
377     LOG(ERROR) << "Failed to initialize pkgmgr interface";
378     return ci::AppInstaller::Result::UNKNOWN;
379   }
380   return RunInstallerWithPkgrmgr(pkgmgr, 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()};
387   TestPkgmgrInstaller pkgmgr_installer;
388   std::unique_ptr<ci::AppQueryInterface> query_interface =
389       CreateQueryInterface();
390   auto pkgmgr =
391       ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast<char**>(argv),
392                                   &pkgmgr_installer, query_interface.get());
393   if (!pkgmgr) {
394     LOG(ERROR) << "Failed to initialize pkgmgr interface";
395     return ci::AppInstaller::Result::UNKNOWN;
396   }
397   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
398 }
399
400 }  // namespace
401
402 namespace common_installer {
403
404 class SmokeEnvironment : public testing::Environment {
405  public:
406   explicit SmokeEnvironment(const bf::path& home) : home_(home) {
407   }
408   void SetUp() override {
409     bs::error_code error;
410     bf::remove_all(home_ / kApplicationDirBackup, error);
411     bf::remove_all(home_ / KUserAppsDirBackup, error);
412     if (bf::exists(home_ / KUserAppsDir)) {
413       bf::rename(home_ / KUserAppsDir, home_ / KUserAppsDirBackup, error);
414       if (error)
415         LOG(ERROR) << "Failed to setup test environment. Does some previous"
416                    << " test crashed? Directory: "
417                    << (home_ / KUserAppsDirBackup) << " should not exist.";
418       assert(!error);
419     }
420     if (bf::exists(home_ / kApplicationDir)) {
421       bf::rename(home_ / kApplicationDir, home_ / kApplicationDirBackup, error);
422       if (error)
423         LOG(ERROR) << "Failed to setup test environment. Does some previous"
424                    << " test crashed? Directory: "
425                    << (home_ / kApplicationDirBackup) << " should not exist.";
426       assert(!error);
427     }
428   }
429   void TearDown() override {
430     bs::error_code error;
431     bf::remove_all(home_ / kApplicationDir, error);
432     bf::remove_all(home_ / KUserAppsDir, error);
433     if (bf::exists(home_ / KUserAppsDirBackup))
434       bf::rename(home_ / KUserAppsDirBackup, home_ / KUserAppsDir, error);
435     if (bf::exists(home_ / kApplicationDirBackup))
436       bf::rename(home_ / kApplicationDirBackup, home_ / kApplicationDir, error);
437   }
438
439  private:
440   bf::path home_;
441 };
442
443 class SmokeTest : public testing::Test {
444 };
445
446 TEST_F(SmokeTest, InstallationMode) {
447   bf::path path = kSmokePackagesDirectory / "InstallationMode.wgt";
448   std::string pkgid = "smokeapp03";
449   std::string appid = "smokeapp03.InstallationMode";
450   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
451   ValidatePackage(pkgid, {appid});
452 }
453
454 TEST_F(SmokeTest, UpdateMode) {
455   bf::path path_old = kSmokePackagesDirectory / "UpdateMode.wgt";
456   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_2.wgt";
457   std::string pkgid = "smokeapp04";
458   std::string appid = "smokeapp04.UpdateMode";
459   ASSERT_EQ(Update(path_old, path_new, PackageType::WGT),
460             ci::AppInstaller::Result::OK);
461   ValidatePackage(pkgid, {appid});
462
463   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
464 }
465
466 TEST_F(SmokeTest, DeinstallationMode) {
467   bf::path path = kSmokePackagesDirectory / "DeinstallationMode.wgt";
468   std::string pkgid = "smokeapp05";
469   std::string appid = "smokeapp05.DeinstallationMode";
470   ASSERT_EQ(Install(path, PackageType::WGT),
471             ci::AppInstaller::Result::OK);
472   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK);
473   CheckPackageNonExistance(pkgid, {appid});
474 }
475
476 TEST_F(SmokeTest, RDSMode) {
477   bf::path path = kSmokePackagesDirectory / "RDSMode.wgt";
478   bf::path delta_directory = kSmokePackagesDirectory / "delta_dir/";
479   std::string pkgid = "smokeapp11";
480   std::string appid = "smokeapp11.RDSMode";
481   ASSERT_EQ(Reinstall(path, delta_directory, PackageType::WGT),
482             ci::AppInstaller::Result::OK);
483   ValidatePackage(pkgid, {appid});
484
485   // Check delta modifications
486   bf::path root_path = ci::GetRootAppPath(false);
487   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
488   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
489   ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "2\n");
490 }
491
492 TEST_F(SmokeTest, ClearMode) {
493   bf::path path = kSmokePackagesDirectory / "ClearMode.wgt";
494   std::string pkgid = "smokeapp20";
495   std::string appid = "smokeapp20.ClearMode";
496   ASSERT_EQ(Install(path, PackageType::WGT),
497             ci::AppInstaller::Result::OK);
498   bf::path root_path = ci::GetRootAppPath(false);
499   bs::error_code error;
500   bf::create_directory(root_path / pkgid / "data" / "dir", error);
501   ASSERT_FALSE(error);
502   ASSERT_TRUE(TouchFile(root_path / pkgid / "data" / "dir" / "file"));
503   ASSERT_TRUE(TouchFile(root_path / pkgid / "data" / "file"));
504   ASSERT_EQ(Clear(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK);
505   ValidatePackage(pkgid, {appid});
506   ASSERT_FALSE(bf::exists(root_path / pkgid / "data" / "dir" / "file"));
507   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "file"));
508 }
509
510 TEST_F(SmokeTest, DeltaMode) {
511   bf::path path = kSmokePackagesDirectory / "DeltaMode.wgt";
512   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode.delta";
513   std::string pkgid = "smokeapp17";
514   std::string appid = "smokeapp17.DeltaMode";
515   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
516             ci::AppInstaller::Result::OK);
517   ValidatePackage(pkgid, {appid});
518
519   // Check delta modifications
520   bf::path root_path = ci::GetRootAppPath(false);
521   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
522   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
523   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "css" / "style.css"));  // NOLINT
524   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
525   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "js" / "main.js"));
526   ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n");
527 }
528
529 TEST_F(SmokeTest, RecoveryMode_ForInstallation) {
530   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForInstallation.wgt";
531   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
532   backend_crash.Run("-i", path.string());
533   ASSERT_NE(backend_crash.Wait(), 0);
534
535   std::string pkgid = "smokeapp09";
536   std::string appid = "smokeapp09.RecoveryModeForInstallation";
537   bf::path recovery_file = FindRecoveryFile();
538   ASSERT_FALSE(recovery_file.empty());
539   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
540       ci::AppInstaller::Result::OK);
541   CheckPackageNonExistance(pkgid, {appid});
542 }
543
544 TEST_F(SmokeTest, RecoveryMode_ForUpdate) {
545   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForUpdate.wgt";
546   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForUpdate_2.wgt";
547   RemoveAllRecoveryFiles();
548   Subprocess backend_test("/usr/bin/wgt-backend");
549   backend_test.Run("-i", path_old.string());
550   ASSERT_EQ(backend_test.Wait(), 0);
551   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
552   backend_crash.Run("-i", path_new.string());
553   ASSERT_NE(backend_crash.Wait(), 0);
554
555   std::string pkgid = "smokeapp10";
556   std::string appid = "smokeapp10.RecoveryModeForUpdate";
557   bf::path recovery_file = FindRecoveryFile();
558   ASSERT_FALSE(recovery_file.empty());
559   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
560             ci::AppInstaller::Result::OK);
561   ValidatePackage(pkgid, {appid});
562
563   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
564 }
565
566 TEST_F(SmokeTest, InstallationMode_GoodSignature) {
567   bf::path path = kSmokePackagesDirectory / "InstallationMode_GoodSignature.wgt";  // NOLINT
568   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
569 }
570
571 TEST_F(SmokeTest, InstallationMode_WrongSignature) {
572   bf::path path = kSmokePackagesDirectory / "InstallationMode_WrongSignature.wgt";  // NOLINT
573   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::ERROR);
574 }
575
576 TEST_F(SmokeTest, InstallationMode_Rollback) {
577   bf::path path = kSmokePackagesDirectory / "InstallationMode_Rollback.wgt";
578   std::string pkgid = "smokeapp06";
579   std::string appid = "smokeapp06.InstallationModeRollback";
580   ASSERT_EQ(Install(path, PackageType::WGT, RequestResult::FAIL),
581             ci::AppInstaller::Result::ERROR);
582   CheckPackageNonExistance(pkgid, {appid});
583 }
584
585 TEST_F(SmokeTest, UpdateMode_Rollback) {
586   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Rollback.wgt";
587   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Rollback_2.wgt";
588   std::string pkgid = "smokeapp07";
589   std::string appid = "smokeapp07.UpdateModeRollback";
590   ASSERT_EQ(Update(path_old, path_new, PackageType::WGT, RequestResult::FAIL),
591                    ci::AppInstaller::Result::ERROR);
592   ValidatePackage(pkgid, {appid});
593
594   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
595 }
596
597 TEST_F(SmokeTest, InstallationMode_Hybrid) {
598   bf::path path = kSmokePackagesDirectory / "InstallationMode_Hybrid.wgt";
599   std::string pkgid = "smokehyb01";
600   std::string appid1 = "smokehyb01.Web";
601   std::string appid2 = "smokehyb01.Native";
602   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
603   ValidatePackage(pkgid, {appid1, appid2});
604 }
605
606 TEST_F(SmokeTest, UpdateMode_Hybrid) {
607   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Hybrid.wgt";
608   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Hybrid_2.wgt";
609   std::string pkgid = "smokehyb02";
610   std::string appid1 = "smokehyb02.Web";
611   std::string appid2 = "smokehyb02.Native";
612   ASSERT_EQ(Update(path_old, path_new, PackageType::HYBRID),
613             ci::AppInstaller::Result::OK);
614   ValidatePackage(pkgid, {appid1, appid2});
615
616   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
617   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "VERSION", "2\n"));
618 }
619
620 TEST_F(SmokeTest, DeinstallationMode_Hybrid) {
621   bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Hybrid.wgt";
622   std::string pkgid = "smokehyb03";
623   std::string appid1 = "smokehyb03.Web";
624   std::string appid2 = "smokehyb03.Native";
625   ASSERT_EQ(Install(path, PackageType::HYBRID),
626             ci::AppInstaller::Result::OK);
627   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK);
628   CheckPackageNonExistance(pkgid, {appid1, appid2});
629 }
630
631 TEST_F(SmokeTest, DeltaMode_Hybrid) {
632   bf::path path = kSmokePackagesDirectory / "DeltaMode_Hybrid.wgt";
633   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Hybrid.delta";
634   std::string pkgid = "smokehyb04";
635   std::string appid1 = "smokehyb04.Web";
636   std::string appid2 = "smokehyb04.Native";
637   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
638             ci::AppInstaller::Result::OK);
639   ValidatePackage(pkgid, {appid1, appid2});
640
641   // Check delta modifications
642   bf::path root_path = ci::GetRootAppPath(false);
643   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
644   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
645   ASSERT_FALSE(bf::exists(root_path / pkgid / "lib" / "DELETED"));
646   ASSERT_TRUE(bf::exists(root_path / pkgid / "lib" / "ADDED"));
647   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "css" / "style.css"));  // NOLINT
648   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
649   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "js" / "main.js"));
650   ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n");
651   ValidateFileContentInPackage(pkgid, "lib/MODIFIED", "version 2\n");
652 }
653
654 TEST_F(SmokeTest, MountInstallationMode) {
655   bf::path path = kSmokePackagesDirectory / "MountInstallationMode.wgt";
656   std::string pkgid = "smokeapp28";
657   std::string appid = "smokeapp28.InstallationMode";
658   ASSERT_EQ(MountInstall(path, PackageType::WGT), ci::AppInstaller::Result::OK);
659   ScopedTzipInterface interface(pkgid);
660   ValidatePackage(pkgid, {appid});
661 }
662
663 TEST_F(SmokeTest, MountUpdateMode) {
664   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode.wgt";
665   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_2.wgt";
666   std::string pkgid = "smokeapp29";
667   std::string appid = "smokeapp29.UpdateMode";
668   ASSERT_EQ(MountUpdate(path_old, path_new, PackageType::WGT),
669             ci::AppInstaller::Result::OK);
670   ScopedTzipInterface interface(pkgid);
671   ValidatePackage(pkgid, {appid});
672
673   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
674 }
675
676 }  // namespace common_installer
677
678 int main(int argc,  char** argv) {
679   testing::InitGoogleTest(&argc, argv);
680   const char* directory = getenv("HOME");
681   if (!directory) {
682     LOG(ERROR) << "Cannot get $HOME value";
683     return 1;
684   }
685   testing::AddGlobalTestEnvironment(
686       new common_installer::SmokeEnvironment(directory));
687   return RUN_ALL_TESTS();
688 }