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