From 90f7070f171e8abe145d30150b976f0a4e13bd86 Mon Sep 17 00:00:00 2001
From: Piotr Ganicz
Date: Fri, 21 Oct 2016 16:30:51 +0200
Subject: [PATCH 01/16] [Refactor] AppInstaller logic export
This commit gather the logic of choosing proper steps sequence
to app-installer repository. All backends have to prepare their
own sequences for each pkgmgr request. The default implementation
of such methods is provided and there is no need for overriding
each function in backends.
Submit together:
- https://review.tizen.org/gerrit/#/c/93999/
- https://review.tizen.org/gerrit/#/c/93998/
Change-Id: I1f049c28908408a20db057bd36e246ba789c999b
---
src/hybrid/hybrid_installer.cc | 88 ++++++++++++++++++++++-------------------
src/hybrid/hybrid_installer.h | 20 ++++++++++
src/wgt/wgt_installer.cc | 89 +-----------------------------------------
src/wgt/wgt_installer.h | 39 +++++++++---------
4 files changed, 87 insertions(+), 149 deletions(-)
diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc
index 4e36b4b..14521ab 100644
--- a/src/hybrid/hybrid_installer.cc
+++ b/src/hybrid/hybrid_installer.cc
@@ -103,9 +103,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
: AppInstaller("wgt", pkgmgr) {
context_->cross_app_rules.set(true);
context_->backend_data.set(new HybridBackendData());
+}
- switch (pkgmgr_->GetRequestType()) {
- case ci::RequestType::Install:
+void HybridInstaller::InstallSteps() {
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -152,8 +152,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
wgt::filesystem::HybridAdditionalSharedDirs);
AddStep();
AddStep();
- break;
- case ci::RequestType::Update:
+}
+
+void HybridInstaller::UpdateSteps() {
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -202,8 +203,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
ci::Plugin::ActionType::Upgrade);
AddStep();
AddStep();
- break;
- case ci::RequestType::Uninstall:
+}
+
+void HybridInstaller::UninstallSteps() {
AddStep(pkgmgr_);
AddStep();
AddStep();
@@ -227,12 +229,14 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
AddStep();
AddStep();
AddStep();
- break;
- case ci::RequestType::Reinstall:
+}
+
+void HybridInstaller::ReinstallSteps() {
// RDS is not supported for hybrid apps
AddStep();
- break;
- case ci::RequestType::Delta:
+}
+
+void HybridInstaller::DeltaSteps() {
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -284,8 +288,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
ci::Plugin::ActionType::Upgrade);
AddStep();
AddStep();
- break;
- case ci::RequestType::Recovery:
+}
+
+void HybridInstaller::RecoverySteps() {
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -302,8 +307,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
AddStep();
AddStep();
AddStep();
- break;
- case ci::RequestType::MountInstall:
+}
+
+void HybridInstaller::MountInstallSteps() {
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -350,8 +356,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
wgt::filesystem::HybridAdditionalSharedDirs);
AddStep();
AddStep();
- break;
- case ci::RequestType::MountUpdate:
+}
+
+void HybridInstaller::MountUpdateSteps() {
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -399,8 +406,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
ci::Plugin::ActionType::Upgrade);
AddStep();
AddStep();
- break;
- case ci::RequestType::ManifestDirectInstall:
+}
+
+void HybridInstaller::ManifestDirectInstallSteps() {
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -431,8 +439,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
wgt::filesystem::HybridAdditionalSharedDirs);
AddStep();
AddStep();
- break;
- case ci::RequestType::ManifestDirectUpdate:
+}
+
+void HybridInstaller::ManifestDirectUpdateSteps() {
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -463,8 +472,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
ci::Plugin::ActionType::Upgrade);
AddStep();
AddStep();
- break;
- case ci::RequestType::ManifestPartialInstall: {
+}
+
+void HybridInstaller::ManifestPartialInstallSteps() {
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -483,9 +493,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
AddStep(
wgt::filesystem::HybridAdditionalSharedDirs);
AddStep();
- break;
- }
- case ci::RequestType::ManifestPartialUpdate: {
+}
+
+void HybridInstaller::ManifestPartialUpdateSteps() {
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -506,9 +516,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
AddStep(
ci::Plugin::ActionType::Upgrade);
AddStep();
- break;
- }
- case ci::RequestType::PartialUninstall: {
+}
+
+void HybridInstaller::PartialUninstallSteps() {
AddStep(pkgmgr_);
AddStep();
AddStep();
@@ -524,9 +534,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
AddStep();
AddStep();
AddStep();
- break;
- }
- case ci::RequestType::EnablePkg:
+}
+
+void HybridInstaller::EnablePkgSteps() {
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -536,8 +546,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
ci::pkgmgr::StepUpdatePkgDisableInfo::ActionType::Enable);
AddStep(
ci::Plugin::ActionType::Uninstall);
- break;
- case ci::RequestType::DisablePkg:
+}
+
+void HybridInstaller::DisablePkgSteps() {
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -547,17 +558,12 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
ci::pkgmgr::StepUpdatePkgDisableInfo::ActionType::Disable);
AddStep(
ci::Plugin::ActionType::Uninstall);
- break;
- case ci::RequestType::MigrateExtImg: {
+}
+
+void HybridInstaller::MigrateExtImgSteps() {
AddStep(pkgmgr_);
AddStep();
AddStep();
- break;
- }
- default:
- AddStep();
- break;
- }
}
} // namespace hybrid
diff --git a/src/hybrid/hybrid_installer.h b/src/hybrid/hybrid_installer.h
index 9824d21..8331393 100644
--- a/src/hybrid/hybrid_installer.h
+++ b/src/hybrid/hybrid_installer.h
@@ -8,6 +8,8 @@
#include "common/app_installer.h"
#include "common/pkgmgr_interface.h"
+namespace ci = common_installer;
+
namespace hybrid {
/**
@@ -24,6 +26,24 @@ class HybridInstaller : public common_installer::AppInstaller {
explicit HybridInstaller(common_installer::PkgMgrPtr pkgmgr);
SCOPE_LOG_TAG(HybridInstaller)
+
+ private:
+ void InstallSteps() override;
+ void UpdateSteps() override;
+ void UninstallSteps() override;
+ void ReinstallSteps() override;
+ void DeltaSteps() override;
+ void RecoverySteps() override;
+ void MountInstallSteps() override;
+ void MountUpdateSteps() override;
+ void ManifestDirectInstallSteps() override;
+ void ManifestDirectUpdateSteps() override;
+ void DisablePkgSteps() override;
+ void EnablePkgSteps() override;
+ void ManifestPartialInstallSteps() override;
+ void ManifestPartialUpdateSteps() override;
+ void PartialUninstallSteps() override;
+ void MigrateExtImgSteps() override;
};
} // namespace hybrid
diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc
index ffa669f..e3d32ed 100755
--- a/src/wgt/wgt_installer.cc
+++ b/src/wgt/wgt_installer.cc
@@ -110,89 +110,6 @@ namespace wgt {
WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
: AppInstaller("wgt", pkgrmgr) {
context_->backend_data.set(new WgtBackendData());
-
- /* treat the request */
- switch (pkgmgr_->GetRequestType()) {
- case ci::RequestType::Install : {
- InstallSteps();
- break;
- }
- case ci::RequestType::Update: {
- UpdateSteps();
- break;
- }
- case ci::RequestType::Uninstall: {
- UninstallSteps();
- break;
- }
- case ci::RequestType::Reinstall: {
- ReinstallSteps();
- break;
- }
- case ci::RequestType::Delta: {
- DeltaSteps();
- break;
- }
- case ci::RequestType::Recovery: {
- RecoverySteps();
- break;
- }
- case ci::RequestType::MountInstall: {
- MountInstallSteps();
- break;
- }
- case ci::RequestType::MountUpdate: {
- MountUpdateSteps();
- break;
- }
- case ci::RequestType::ManifestDirectInstall: {
- ManifestDirectInstallSteps();
- break;
- }
- case ci::RequestType::ManifestDirectUpdate: {
- ManifestDirectUpdateSteps();
- break;
- }
- case ci::RequestType::ReadonlyUpdateInstall: {
- ReadonlyUpdateInstallSteps();
- break;
- }
- case ci::RequestType::ReadonlyUpdateUninstall: {
- ReadonlyUpdateUninstallSteps();
- break;
- }
- case ci::RequestType::ManifestPartialInstall: {
- ManifestPartialInstallSteps();
- break;
- }
- case ci::RequestType::ManifestPartialUpdate: {
- ManifestPartialUpdateSteps();
- break;
- }
- case ci::RequestType::PartialUninstall: {
- ManifestPartialUninstallSteps();
- break;
- }
- case ci::RequestType::Move: {
- MoveSteps();
- break;
- }
- case ci::RequestType::EnablePkg: {
- EnablePkgSteps();
- break;
- }
- case ci::RequestType::DisablePkg: {
- DisablePkgSteps();
- break;
- }
- case ci::RequestType::MigrateExtImg: {
- MigrateExtImgSteps();
- break;
- }
- default: {
- DefaultSteps();
- }
- }
}
void WgtInstaller::InstallSteps() {
AddStep(pkgmgr_);
@@ -638,7 +555,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
AddStep();
}
- void WgtInstaller::ManifestPartialUninstallSteps() {
+ void WgtInstaller::PartialUninstallSteps() {
AddStep(pkgmgr_);
AddStep();
AddStep();
@@ -696,8 +613,4 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
AddStep();
}
- void WgtInstaller::DefaultSteps() {
- AddStep();
- }
-
} // namespace wgt
diff --git a/src/wgt/wgt_installer.h b/src/wgt/wgt_installer.h
index 0c3a5e9..c25c2e1 100644
--- a/src/wgt/wgt_installer.h
+++ b/src/wgt/wgt_installer.h
@@ -26,26 +26,25 @@ class WgtInstaller : public common_installer::AppInstaller {
explicit WgtInstaller(common_installer::PkgMgrPtr pkgrmgr);
private:
- void InstallSteps();
- void UpdateSteps();
- void UninstallSteps();
- void ReinstallSteps();
- void DeltaSteps();
- void RecoverySteps();
- void MountInstallSteps();
- void MountUpdateSteps();
- void ManifestDirectInstallSteps();
- void ManifestDirectUpdateSteps();
- void ReadonlyUpdateInstallSteps();
- void ReadonlyUpdateUninstallSteps();
- void ManifestPartialInstallSteps();
- void ManifestPartialUpdateSteps();
- void ManifestPartialUninstallSteps();
- void MoveSteps();
- void EnablePkgSteps();
- void DisablePkgSteps();
- void MigrateExtImgSteps();
- void DefaultSteps();
+ void InstallSteps() override;
+ void UpdateSteps() override;
+ void UninstallSteps() override;
+ void ReinstallSteps() override;
+ void DeltaSteps() override;
+ void MoveSteps() override;
+ void RecoverySteps() override;
+ void MountInstallSteps() override;
+ void MountUpdateSteps() override;
+ void ManifestDirectInstallSteps() override;
+ void ManifestDirectUpdateSteps() override;
+ void ManifestPartialInstallSteps() override;
+ void ManifestPartialUpdateSteps() override;
+ void PartialUninstallSteps() override;
+ void ReadonlyUpdateInstallSteps() override;
+ void ReadonlyUpdateUninstallSteps() override;
+ void DisablePkgSteps() override;
+ void EnablePkgSteps() override;
+ void MigrateExtImgSteps() override;
};
} // namespace wgt
--
2.7.4
From 35519ad818702263ead855736499c174b3e97dbe Mon Sep 17 00:00:00 2001
From: jongmyeong ko
Date: Fri, 3 Mar 2017 01:14:18 -0800
Subject: [PATCH 02/16] Revert "[Refactor] AppInstaller logic export"
This reverts commit 90f7070f171e8abe145d30150b976f0a4e13bd86.
Change-Id: Iaaa68f8f60076803c49a5231b1be35478768846e
---
src/hybrid/hybrid_installer.cc | 88 +++++++++++++++++++----------------------
src/hybrid/hybrid_installer.h | 20 ----------
src/wgt/wgt_installer.cc | 89 +++++++++++++++++++++++++++++++++++++++++-
src/wgt/wgt_installer.h | 39 +++++++++---------
4 files changed, 149 insertions(+), 87 deletions(-)
diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc
index 14521ab..4e36b4b 100644
--- a/src/hybrid/hybrid_installer.cc
+++ b/src/hybrid/hybrid_installer.cc
@@ -103,9 +103,9 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
: AppInstaller("wgt", pkgmgr) {
context_->cross_app_rules.set(true);
context_->backend_data.set(new HybridBackendData());
-}
-void HybridInstaller::InstallSteps() {
+ switch (pkgmgr_->GetRequestType()) {
+ case ci::RequestType::Install:
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -152,9 +152,8 @@ void HybridInstaller::InstallSteps() {
wgt::filesystem::HybridAdditionalSharedDirs);
AddStep();
AddStep();
-}
-
-void HybridInstaller::UpdateSteps() {
+ break;
+ case ci::RequestType::Update:
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -203,9 +202,8 @@ void HybridInstaller::UpdateSteps() {
ci::Plugin::ActionType::Upgrade);
AddStep();
AddStep();
-}
-
-void HybridInstaller::UninstallSteps() {
+ break;
+ case ci::RequestType::Uninstall:
AddStep(pkgmgr_);
AddStep();
AddStep();
@@ -229,14 +227,12 @@ void HybridInstaller::UninstallSteps() {
AddStep();
AddStep();
AddStep();
-}
-
-void HybridInstaller::ReinstallSteps() {
+ break;
+ case ci::RequestType::Reinstall:
// RDS is not supported for hybrid apps
AddStep();
-}
-
-void HybridInstaller::DeltaSteps() {
+ break;
+ case ci::RequestType::Delta:
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -288,9 +284,8 @@ void HybridInstaller::DeltaSteps() {
ci::Plugin::ActionType::Upgrade);
AddStep();
AddStep();
-}
-
-void HybridInstaller::RecoverySteps() {
+ break;
+ case ci::RequestType::Recovery:
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -307,9 +302,8 @@ void HybridInstaller::RecoverySteps() {
AddStep();
AddStep();
AddStep();
-}
-
-void HybridInstaller::MountInstallSteps() {
+ break;
+ case ci::RequestType::MountInstall:
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -356,9 +350,8 @@ void HybridInstaller::MountInstallSteps() {
wgt::filesystem::HybridAdditionalSharedDirs);
AddStep();
AddStep();
-}
-
-void HybridInstaller::MountUpdateSteps() {
+ break;
+ case ci::RequestType::MountUpdate:
AddStep(pkgmgr_);
AddStep();
AddStep(
@@ -406,9 +399,8 @@ void HybridInstaller::MountUpdateSteps() {
ci::Plugin::ActionType::Upgrade);
AddStep();
AddStep();
-}
-
-void HybridInstaller::ManifestDirectInstallSteps() {
+ break;
+ case ci::RequestType::ManifestDirectInstall:
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -439,9 +431,8 @@ void HybridInstaller::ManifestDirectInstallSteps() {
wgt::filesystem::HybridAdditionalSharedDirs);
AddStep();
AddStep();
-}
-
-void HybridInstaller::ManifestDirectUpdateSteps() {
+ break;
+ case ci::RequestType::ManifestDirectUpdate:
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -472,9 +463,8 @@ void HybridInstaller::ManifestDirectUpdateSteps() {
ci::Plugin::ActionType::Upgrade);
AddStep();
AddStep();
-}
-
-void HybridInstaller::ManifestPartialInstallSteps() {
+ break;
+ case ci::RequestType::ManifestPartialInstall: {
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -493,9 +483,9 @@ void HybridInstaller::ManifestPartialInstallSteps() {
AddStep(
wgt::filesystem::HybridAdditionalSharedDirs);
AddStep();
-}
-
-void HybridInstaller::ManifestPartialUpdateSteps() {
+ break;
+ }
+ case ci::RequestType::ManifestPartialUpdate: {
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -516,9 +506,9 @@ void HybridInstaller::ManifestPartialUpdateSteps() {
AddStep(
ci::Plugin::ActionType::Upgrade);
AddStep();
-}
-
-void HybridInstaller::PartialUninstallSteps() {
+ break;
+ }
+ case ci::RequestType::PartialUninstall: {
AddStep(pkgmgr_);
AddStep();
AddStep();
@@ -534,9 +524,9 @@ void HybridInstaller::PartialUninstallSteps() {
AddStep();
AddStep();
AddStep();
-}
-
-void HybridInstaller::EnablePkgSteps() {
+ break;
+ }
+ case ci::RequestType::EnablePkg:
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -546,9 +536,8 @@ void HybridInstaller::EnablePkgSteps() {
ci::pkgmgr::StepUpdatePkgDisableInfo::ActionType::Enable);
AddStep(
ci::Plugin::ActionType::Uninstall);
-}
-
-void HybridInstaller::DisablePkgSteps() {
+ break;
+ case ci::RequestType::DisablePkg:
AddStep(pkgmgr_);
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
@@ -558,12 +547,17 @@ void HybridInstaller::DisablePkgSteps() {
ci::pkgmgr::StepUpdatePkgDisableInfo::ActionType::Disable);
AddStep(
ci::Plugin::ActionType::Uninstall);
-}
-
-void HybridInstaller::MigrateExtImgSteps() {
+ break;
+ case ci::RequestType::MigrateExtImg: {
AddStep(pkgmgr_);
AddStep();
AddStep();
+ break;
+ }
+ default:
+ AddStep();
+ break;
+ }
}
} // namespace hybrid
diff --git a/src/hybrid/hybrid_installer.h b/src/hybrid/hybrid_installer.h
index 8331393..9824d21 100644
--- a/src/hybrid/hybrid_installer.h
+++ b/src/hybrid/hybrid_installer.h
@@ -8,8 +8,6 @@
#include "common/app_installer.h"
#include "common/pkgmgr_interface.h"
-namespace ci = common_installer;
-
namespace hybrid {
/**
@@ -26,24 +24,6 @@ class HybridInstaller : public common_installer::AppInstaller {
explicit HybridInstaller(common_installer::PkgMgrPtr pkgmgr);
SCOPE_LOG_TAG(HybridInstaller)
-
- private:
- void InstallSteps() override;
- void UpdateSteps() override;
- void UninstallSteps() override;
- void ReinstallSteps() override;
- void DeltaSteps() override;
- void RecoverySteps() override;
- void MountInstallSteps() override;
- void MountUpdateSteps() override;
- void ManifestDirectInstallSteps() override;
- void ManifestDirectUpdateSteps() override;
- void DisablePkgSteps() override;
- void EnablePkgSteps() override;
- void ManifestPartialInstallSteps() override;
- void ManifestPartialUpdateSteps() override;
- void PartialUninstallSteps() override;
- void MigrateExtImgSteps() override;
};
} // namespace hybrid
diff --git a/src/wgt/wgt_installer.cc b/src/wgt/wgt_installer.cc
index e3d32ed..ffa669f 100755
--- a/src/wgt/wgt_installer.cc
+++ b/src/wgt/wgt_installer.cc
@@ -110,6 +110,89 @@ namespace wgt {
WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
: AppInstaller("wgt", pkgrmgr) {
context_->backend_data.set(new WgtBackendData());
+
+ /* treat the request */
+ switch (pkgmgr_->GetRequestType()) {
+ case ci::RequestType::Install : {
+ InstallSteps();
+ break;
+ }
+ case ci::RequestType::Update: {
+ UpdateSteps();
+ break;
+ }
+ case ci::RequestType::Uninstall: {
+ UninstallSteps();
+ break;
+ }
+ case ci::RequestType::Reinstall: {
+ ReinstallSteps();
+ break;
+ }
+ case ci::RequestType::Delta: {
+ DeltaSteps();
+ break;
+ }
+ case ci::RequestType::Recovery: {
+ RecoverySteps();
+ break;
+ }
+ case ci::RequestType::MountInstall: {
+ MountInstallSteps();
+ break;
+ }
+ case ci::RequestType::MountUpdate: {
+ MountUpdateSteps();
+ break;
+ }
+ case ci::RequestType::ManifestDirectInstall: {
+ ManifestDirectInstallSteps();
+ break;
+ }
+ case ci::RequestType::ManifestDirectUpdate: {
+ ManifestDirectUpdateSteps();
+ break;
+ }
+ case ci::RequestType::ReadonlyUpdateInstall: {
+ ReadonlyUpdateInstallSteps();
+ break;
+ }
+ case ci::RequestType::ReadonlyUpdateUninstall: {
+ ReadonlyUpdateUninstallSteps();
+ break;
+ }
+ case ci::RequestType::ManifestPartialInstall: {
+ ManifestPartialInstallSteps();
+ break;
+ }
+ case ci::RequestType::ManifestPartialUpdate: {
+ ManifestPartialUpdateSteps();
+ break;
+ }
+ case ci::RequestType::PartialUninstall: {
+ ManifestPartialUninstallSteps();
+ break;
+ }
+ case ci::RequestType::Move: {
+ MoveSteps();
+ break;
+ }
+ case ci::RequestType::EnablePkg: {
+ EnablePkgSteps();
+ break;
+ }
+ case ci::RequestType::DisablePkg: {
+ DisablePkgSteps();
+ break;
+ }
+ case ci::RequestType::MigrateExtImg: {
+ MigrateExtImgSteps();
+ break;
+ }
+ default: {
+ DefaultSteps();
+ }
+ }
}
void WgtInstaller::InstallSteps() {
AddStep(pkgmgr_);
@@ -555,7 +638,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
AddStep();
}
- void WgtInstaller::PartialUninstallSteps() {
+ void WgtInstaller::ManifestPartialUninstallSteps() {
AddStep(pkgmgr_);
AddStep();
AddStep();
@@ -613,4 +696,8 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
AddStep();
}
+ void WgtInstaller::DefaultSteps() {
+ AddStep();
+ }
+
} // namespace wgt
diff --git a/src/wgt/wgt_installer.h b/src/wgt/wgt_installer.h
index c25c2e1..0c3a5e9 100644
--- a/src/wgt/wgt_installer.h
+++ b/src/wgt/wgt_installer.h
@@ -26,25 +26,26 @@ class WgtInstaller : public common_installer::AppInstaller {
explicit WgtInstaller(common_installer::PkgMgrPtr pkgrmgr);
private:
- void InstallSteps() override;
- void UpdateSteps() override;
- void UninstallSteps() override;
- void ReinstallSteps() override;
- void DeltaSteps() override;
- void MoveSteps() override;
- void RecoverySteps() override;
- void MountInstallSteps() override;
- void MountUpdateSteps() override;
- void ManifestDirectInstallSteps() override;
- void ManifestDirectUpdateSteps() override;
- void ManifestPartialInstallSteps() override;
- void ManifestPartialUpdateSteps() override;
- void PartialUninstallSteps() override;
- void ReadonlyUpdateInstallSteps() override;
- void ReadonlyUpdateUninstallSteps() override;
- void DisablePkgSteps() override;
- void EnablePkgSteps() override;
- void MigrateExtImgSteps() override;
+ void InstallSteps();
+ void UpdateSteps();
+ void UninstallSteps();
+ void ReinstallSteps();
+ void DeltaSteps();
+ void RecoverySteps();
+ void MountInstallSteps();
+ void MountUpdateSteps();
+ void ManifestDirectInstallSteps();
+ void ManifestDirectUpdateSteps();
+ void ReadonlyUpdateInstallSteps();
+ void ReadonlyUpdateUninstallSteps();
+ void ManifestPartialInstallSteps();
+ void ManifestPartialUpdateSteps();
+ void ManifestPartialUninstallSteps();
+ void MoveSteps();
+ void EnablePkgSteps();
+ void DisablePkgSteps();
+ void MigrateExtImgSteps();
+ void DefaultSteps();
};
} // namespace wgt
--
2.7.4
From 4d621d245beb97813bcc0b38b0032fdd3157dfc8 Mon Sep 17 00:00:00 2001
From: jongmyeongko
Date: Sat, 4 Mar 2017 18:05:39 +0900
Subject: [PATCH 03/16] Release version 0.4.0
Changes:
- Smoke tests- check if package dont exist in skel directory
- Fix rw filesystem validation
- Rename smoke test to new convention
- Add some missing error checking
- Add signature check step in RW partial request
- Add KillApp step in RW partial update
- Adjust some values in xml
Change-Id: I3f673fe1df183ba4bee8a140321c19c0c6417829
Signed-off-by: jongmyeongko
---
packaging/wgt-backend.spec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packaging/wgt-backend.spec b/packaging/wgt-backend.spec
index 5158fe1..4dd083f 100644
--- a/packaging/wgt-backend.spec
+++ b/packaging/wgt-backend.spec
@@ -1,6 +1,6 @@
Name: wgt-backend
Summary: Application installer backend for WGT
-Version: 0.3.1
+Version: 0.4.0
Release: 1
Group: Application Framework/Package Management
License: Apache-2.0
--
2.7.4
From e2687ca7eb39fc8aa1ba278199a2b641e376f4ab Mon Sep 17 00:00:00 2001
From: Damian Pietruchowski
Date: Wed, 22 Feb 2017 17:12:39 +0100
Subject: [PATCH 04/16] [SmokeTest] Add request mode choice
Smoke tests can be run with normal or global user.
Normal user is created in environment SetUp() and
is deleted in TearDown() method. Normal user name
is "smokeuser".
You can run tests by normal user with flags:
-u or --request_mode=user
You can run tests by global user with flags:
-g or --request_mode=global
Without above flags tests are run with global user
by default
Requires:
- https://review.tizen.org/gerrit/#/c/116229/
Signed-off-by: Damian Pietruchowski
Change-Id: If59225a8fac3f4ed25277f31466549c0cc636c50
---
src/unit_tests/smoke_test.cc | 134 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 112 insertions(+), 22 deletions(-)
diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc
index 844fa1c..38b9945 100644
--- a/src/unit_tests/smoke_test.cc
+++ b/src/unit_tests/smoke_test.cc
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
#include
#include
@@ -25,6 +26,7 @@
#include
#include
#include
+#include
#include
#include
@@ -43,15 +45,51 @@ namespace bs = boost::system;
namespace ci = common_installer;
namespace {
+ci::RequestMode kRequestMode = ci::RequestMode::GLOBAL;
+const char *short_opts = "g:u";
+const struct option long_opts[] = {
+ { "request_mode", 1, NULL, 'r' },
+ { 0, 0, 0, 0 } /* sentinel */
+};
+const char *request_modes[] {
+ "global",
+ "user"
+};
+void ParseRequestMode(int argc, char** argv) {
+ int c;
+ int opt_idx = 0;
+ do {
+ c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
+ switch (c) {
+ case 'r':
+ if (strncmp(optarg, request_modes[0], strlen(request_modes[0])) == 0)
+ kRequestMode = ci::RequestMode::GLOBAL;
+ else if (strncmp(optarg, request_modes[1], strlen(request_modes[1])) == 0)
+ kRequestMode = ci::RequestMode::USER;
+ else
+ LOG(ERROR) << "Wrong request mode " << optarg
+ << ". Available: \"global\" or \"user\"";
+ break;
+ case 'g':
+ kRequestMode = ci::RequestMode::GLOBAL;
+ break;
+ case 'u':
+ kRequestMode = ci::RequestMode::USER;
+ break;
+ default:
+ break;
+ }
+ } while (c != -1);
+}
const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
const uid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER);
const uid_t kDefaultUserUid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
-const uid_t kTestUserId = kGlobalUserUid;
-const gid_t kTestGroupId = kGlobalUserGid;
+uid_t kTestUserId = kGlobalUserUid;
+gid_t kTestGroupId = kGlobalUserGid;
+std::string kTestUserIdStr = std::to_string(kTestUserId);
+const char kNormalUserName[] = "smokeuser";
const char kSystemShareGroupName[] = "system_share";
-const std::string& kTestUserIdStr =
- std::to_string(kTestUserId);
const std::string& kDefaultUserIdStr = std::to_string(kDefaultUserUid);
const char kLegacyExtImageDir[] = "legacy_extimage_dir";
const char kMigrateTestDBName[] = "app2sd_migrate.db";
@@ -152,6 +190,40 @@ bool TouchFile(const bf::path& path) {
return true;
}
+bool AddTestUser(const char *user_name) {
+ std::cout << "Adding test user: " << user_name << std::endl;
+ gboolean ret = ci::AddUser(user_name);
+ if (boost::optional uid = ci::GetUidByUserName(user_name)) {
+ kTestUserId = *uid;
+ kTestUserIdStr = std::to_string(kTestUserId);
+ std::cout << "User created properly: uid=" << *uid;
+ if (boost::optional gid = ci::GetGidByUid(*uid)) {
+ kTestGroupId = *gid;
+ std::cout << " gid=" << *gid;
+ }
+ std::cout << std::endl;
+ return true;
+ }
+ LOG(ERROR) << "Adding test user failed";
+ return false;
+}
+
+bool DeleteTestUser(const char *user_name) {
+ std::cout << "Deleting test user: " << user_name << std::endl;
+ uid_t test_uid;
+ if (boost::optional uid = ci::GetUidByUserName(user_name))
+ test_uid = *uid;
+ gboolean ret = ci::DeleteUser(user_name, true);
+ if (boost::optional uid = ci::GetUidByUserName(user_name));
+ else {
+ std::cout << "User deleted properly: user_name=" << user_name
+ << " uid=" << test_uid << std::endl;
+ return true;
+ }
+ LOG(ERROR) << "Deleting test user failed";
+ return false;
+}
+
void RemoveAllRecoveryFiles() {
bf::path root_path = ci::GetRootAppPath(false,
kTestUserId);
@@ -664,11 +736,11 @@ void RestorePath(const bf::path& path) {
}
}
-std::vector SetupBackupDirectories(uid_t uid) {
+std::vector SetupBackupDirectories() {
std::vector entries;
bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB));
- if (uid != kGlobalUserUid)
- db_dir = db_dir / "user" / std::to_string(uid);
+ if (kTestUserId != kGlobalUserUid)
+ db_dir = db_dir / "user" / std::to_string(kTestUserId);
for (auto e : kDBEntries) {
bf::path path = db_dir / e;
entries.emplace_back(path);
@@ -680,7 +752,7 @@ std::vector SetupBackupDirectories(uid_t uid) {
entries.emplace_back(kPreloadIcons);
}
- if (uid == kGlobalUserUid) {
+ if (kTestUserId == kGlobalUserUid) {
entries.emplace_back(kSkelDir);
entries.emplace_back(kGlobalManifestDir);
ci::UserList list = ci::GetUserList();
@@ -689,13 +761,13 @@ std::vector SetupBackupDirectories(uid_t uid) {
entries.emplace_back(apps);
}
} else {
- tzplatform_set_user(uid);
+ tzplatform_set_user(kTestUserId);
bf::path approot = tzplatform_getenv(TZ_USER_APPROOT);
tzplatform_reset_user();
entries.emplace_back(approot);
}
- bf::path apps_rw = ci::GetRootAppPath(false, uid);
+ bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId);
entries.emplace_back(apps_rw);
return entries;
@@ -718,12 +790,12 @@ void UninstallAllAppsInDirectory(bf::path dir, bool is_preload) {
}
}
-void UninstallAllSmokeApps(uid_t uid) {
- if (getuid() == 0) {
+void UninstallAllSmokeApps() {
+ if (getuid() == 0 && kRequestMode == ci::RequestMode::GLOBAL) {
bf::path root_path = kPreloadApps;
UninstallAllAppsInDirectory(root_path, true);
}
- bf::path apps_rw = ci::GetRootAppPath(false, uid);
+ bf::path apps_rw = ci::GetRootAppPath(false, kTestUserId);
UninstallAllAppsInDirectory(apps_rw, false);
}
@@ -733,27 +805,44 @@ namespace common_installer {
class SmokeEnvironment : public testing::Environment {
public:
- explicit SmokeEnvironment(uid_t uid) : uid_(uid) {
+ explicit SmokeEnvironment() {
}
void SetUp() override {
- backups_ = SetupBackupDirectories(uid_);
+ if (kRequestMode == ci::RequestMode::USER)
+ ASSERT_TRUE(AddTestUser(kNormalUserName));
+ else {
+ kTestUserId = kGlobalUserUid;
+ kTestGroupId = kGlobalUserGid;
+ kTestUserIdStr = std::to_string(kTestUserId);
+ }
+ backups_ = SetupBackupDirectories();
for (auto& path : backups_)
BackupPath(path);
}
void TearDown() override {
- UninstallAllSmokeApps(uid_);
+ ASSERT_TRUE(kRequestMode == ci::RequestMode::GLOBAL ||
+ (kRequestMode == ci::RequestMode::USER &&
+ kGlobalUserUid != kTestUserId));
+ UninstallAllSmokeApps();
for (auto& path : backups_)
RestorePath(path);
+ if (kRequestMode == ci::RequestMode::USER)
+ ASSERT_TRUE(DeleteTestUser(kNormalUserName));
}
private:
- uid_t uid_;
std::vector backups_;
};
class SmokeTest : public testing::Test {
};
+class PreloadSmokeTest : public testing::Test {
+ void SetUp() override {
+ ASSERT_TRUE(kRequestMode == ci::RequestMode::GLOBAL);
+ }
+};
+
TEST_F(SmokeTest, InstallationMode) {
bf::path path = kSmokePackagesDirectory / "InstallationMode.wgt";
std::string pkgid = "smokewgt03";
@@ -1286,7 +1375,7 @@ TEST_F(SmokeTest, MigrateLegacyExternalImageMode) {
ValidateExternalPackage(pkgid, {appid});
}
-TEST_F(SmokeTest, InstallationMode_Preload) {
+TEST_F(PreloadSmokeTest, InstallationMode_Preload) {
ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
bf::path path = kSmokePackagesDirectory / "InstallationMode_Preload.wgt";
std::string pkgid = "smokewgt37";
@@ -1296,7 +1385,7 @@ TEST_F(SmokeTest, InstallationMode_Preload) {
ValidatePackage(pkgid, {appid}, true);
}
-TEST_F(SmokeTest, UpdateMode_Preload) {
+TEST_F(PreloadSmokeTest, UpdateMode_Preload) {
ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Preload.wgt";
bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Preload2.wgt";
@@ -1314,7 +1403,7 @@ TEST_F(SmokeTest, UpdateMode_Preload) {
ValidateDataFiles(pkgid, kTestUserId);
}
-TEST_F(SmokeTest, DeinstallationMode_Preload) {
+TEST_F(PreloadSmokeTest, DeinstallationMode_Preload) {
ASSERT_EQ(getuid(), 0) << "Test cannot be run by normal user";
bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Preload.wgt";
std::string pkgid = "smokewgt39";
@@ -1330,7 +1419,8 @@ TEST_F(SmokeTest, DeinstallationMode_Preload) {
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
- testing::AddGlobalTestEnvironment(
- new common_installer::SmokeEnvironment(kGlobalUserUid));
+ testing::Environment *env = testing::AddGlobalTestEnvironment(
+ new common_installer::SmokeEnvironment());
+ ParseRequestMode(argc, argv);
return RUN_ALL_TESTS();
}
--
2.7.4
From 24c8b7dbf25617328525678421ca19c8877cf966 Mon Sep 17 00:00:00 2001
From: Damian Pietruchowski
Date: Tue, 7 Mar 2017 12:45:28 +0100
Subject: [PATCH 05/16] [SmokeTest] Fix rw filesystem validation
Remove validation for files in rw directories
Change-Id: I25c22040609664d5f707f42f67ff53e813b05ca0
Signed-off-by: Damian Pietruchowski
---
src/unit_tests/smoke_test.cc | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc
index 38b9945..e150b84 100644
--- a/src/unit_tests/smoke_test.cc
+++ b/src/unit_tests/smoke_test.cc
@@ -384,8 +384,10 @@ void ValidatePackageFS(const std::string& pkgid,
bf::path rw_dir_path = rw_dir;
is_rw_dir |= ci::MakeRelativePath(iter->path(), package_path) == rw_dir_path;
}
- if (is_rw_dir || iter->path().filename() == ".mmc")
+ if (is_rw_dir || iter->path().filename() == ".mmc") {
+ iter.no_push();
continue;
+ }
struct stat stats;
stat(iter->path().c_str(), &stats);
ASSERT_EQ(uid, stats.st_uid) << "Invalid uid: " << iter->path();
--
2.7.4
From f32618319568331491d0f6e3b7ce777f6e462bc1 Mon Sep 17 00:00:00 2001
From: Damian Pietruchowski
Date: Thu, 9 Mar 2017 15:07:45 +0100
Subject: [PATCH 06/16] [SmokeTest] Regex match for uninstall in tear down
After all tests, apps are uninstalled based on names of directories
in globalapps or apps_rw directory. It should avoid trying to uninstall
apps like "tmp" or "pkgdid.bck".
Change-Id: If64970a49aa657df759de1173e1f1c96fe7e87ea
Signed-off-by: Damian Pietruchowski
---
src/unit_tests/smoke_test.cc | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc
index e150b84..d4c0efc 100644
--- a/src/unit_tests/smoke_test.cc
+++ b/src/unit_tests/smoke_test.cc
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
#include "hybrid/hybrid_installer.h"
#include "wgt/wgt_app_query_interface.h"
@@ -781,11 +782,15 @@ void UninstallAllAppsInDirectory(bf::path dir, bool is_preload) {
bf::directory_iterator(dir), bf::directory_iterator())) {
if (dir_entry.path().string().find("smoke") != std::string::npos &&
bf::is_directory(dir_entry)) {
- if(Uninstall(dir_entry.path().filename().string(), PackageType::WGT,
- is_preload, RequestResult::NORMAL) !=
- ci::AppInstaller::Result::OK) {
- LOG(ERROR) << "Cannot uninstall smoke test app: "
- << dir_entry.path().filename().string();
+ std::string package = dir_entry.path().filename().string();
+ std::regex pkg_regex("smoke[a-zA-Z]{3,}[1-9]{2,}");
+ if (std::regex_match(package, pkg_regex)) {
+ if(Uninstall(dir_entry.path().filename().string(), PackageType::WGT,
+ is_preload, RequestResult::NORMAL) !=
+ ci::AppInstaller::Result::OK) {
+ LOG(ERROR) << "Cannot uninstall smoke test app: "
+ << dir_entry.path().filename().string();
+ }
}
}
}
--
2.7.4
From 8df9eaf6ee1ad528374695dd58f7a0a25aace5b9 Mon Sep 17 00:00:00 2001
From: Piotr Dabrowski
Date: Mon, 19 Sep 2016 15:43:16 +0200
Subject: [PATCH 07/16] Reworked sharing of widget's shared/res directory.
./res/wgt/shared/res directory content was moved to ./shared/res
and then ./res/wgt/shared/res was symlinked to ./shared/res
This broke signatures check for delta update.
Now all items (files and directories) under ./res/wgt/shared/res
are symlinked into ./shared/res, and vice versa.
During delta update these symlinks are removed, so that the
signatures check can complete successfully, and later the symlinks
are recreated again.
Added smoke tests for symlinking shared/res contents in Tizen 3.0
To added tests pass requires:
- https://review.tizen.org/gerrit/#/c/117264/
Change-Id: I9423d78aba5cb338b14a9f8853754e0fa8980e0c
---
src/hybrid/hybrid_installer.cc | 2 +
src/unit_tests/smoke_test.cc | 71 ++++++++++++++++
src/unit_tests/test_samples/smoke/SharedRes24.wgt | Bin 0 -> 38439 bytes
src/unit_tests/test_samples/smoke/SharedRes30.wgt | Bin 0 -> 38419 bytes
.../test_samples/smoke/SharedRes30Delta.delta | Bin 0 -> 6053 bytes
.../test_samples/smoke/SharedRes30Delta.wgt | Bin 0 -> 38431 bytes
.../test_samples/smoke/SharedRes30Delta_2.wgt | Bin 0 -> 38431 bytes
.../test_samples/smoke/SharedRes30Hybrid.wgt | Bin 0 -> 64163 bytes
.../smoke/SharedRes30HybridDelta.delta | Bin 0 -> 8044 bytes
.../test_samples/smoke/SharedRes30HybridDelta.wgt | Bin 0 -> 64231 bytes
.../smoke/SharedRes30HybridDelta_2.wgt | Bin 0 -> 64232 bytes
.../step_wgt_patch_storage_directories.cc | 87 +++++++++++++------
.../step_wgt_patch_storage_directories.h | 5 +-
.../step_wgt_undo_patch_storage_directories.cc | 94 +++++++++++++++++++++
.../step_wgt_undo_patch_storage_directories.h | 39 +++++++++
src/wgt/wgt_installer.cc | 2 +
16 files changed, 274 insertions(+), 26 deletions(-)
create mode 100644 src/unit_tests/test_samples/smoke/SharedRes24.wgt
create mode 100644 src/unit_tests/test_samples/smoke/SharedRes30.wgt
create mode 100644 src/unit_tests/test_samples/smoke/SharedRes30Delta.delta
create mode 100644 src/unit_tests/test_samples/smoke/SharedRes30Delta.wgt
create mode 100644 src/unit_tests/test_samples/smoke/SharedRes30Delta_2.wgt
create mode 100644 src/unit_tests/test_samples/smoke/SharedRes30Hybrid.wgt
create mode 100644 src/unit_tests/test_samples/smoke/SharedRes30HybridDelta.delta
create mode 100644 src/unit_tests/test_samples/smoke/SharedRes30HybridDelta.wgt
create mode 100644 src/unit_tests/test_samples/smoke/SharedRes30HybridDelta_2.wgt
create mode 100644 src/wgt/step/filesystem/step_wgt_undo_patch_storage_directories.cc
create mode 100644 src/wgt/step/filesystem/step_wgt_undo_patch_storage_directories.h
diff --git a/src/hybrid/hybrid_installer.cc b/src/hybrid/hybrid_installer.cc
index 4e36b4b..f1dd5c4 100644
--- a/src/hybrid/hybrid_installer.cc
+++ b/src/hybrid/hybrid_installer.cc
@@ -89,6 +89,7 @@
#include "wgt/step/filesystem/step_create_symbolic_link.h"
#include "wgt/step/filesystem/step_wgt_patch_icons.h"
#include "wgt/step/filesystem/step_wgt_patch_storage_directories.h"
+#include "wgt/step/filesystem/step_wgt_undo_patch_storage_directories.h"
#include "wgt/step/pkgmgr/step_generate_xml.h"
#include "wgt/step/security/step_check_settings_level.h"
#include "wgt/step/security/step_check_wgt_background_category.h"
@@ -238,6 +239,7 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::PACKAGE,
ci::configuration::StepParseManifest::StoreLocation::NORMAL);
+ AddStep();
AddStep();
AddStep(
ci::configuration::StepParseManifest::ManifestLocation::INSTALLED,
diff --git a/src/unit_tests/smoke_test.cc b/src/unit_tests/smoke_test.cc
index d4c0efc..8322b48 100644
--- a/src/unit_tests/smoke_test.cc
+++ b/src/unit_tests/smoke_test.cc
@@ -1422,6 +1422,77 @@ TEST_F(PreloadSmokeTest, DeinstallationMode_Preload) {
CheckPackageReadonlyNonExistance(pkgid, {appid});
}
+TEST_F(SmokeTest, SharedRes24) {
+ bf::path path = kSmokePackagesDirectory / "SharedRes24.wgt";
+ std::string pkgid = "smokeSh2xx";
+ std::string appid = "smokeSh2xx.SharedRes24";
+ ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
+ ValidatePackage(pkgid, {appid});
+ bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
+ ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "NOT-SHARED-WGT")); // NOLINT
+ ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "NOT-SHARED-WGT")); // NOLINT
+}
+
+TEST_F(SmokeTest, SharedRes30) {
+ bf::path path = kSmokePackagesDirectory / "SharedRes30.wgt";
+ std::string pkgid = "smokeSh3xx";
+ std::string appid = "smokeSh3xx.SharedRes30";
+ ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
+ ValidatePackage(pkgid, {appid});
+ bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
+ ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT")); // NOLINT
+ ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT")); // NOLINT
+}
+
+TEST_F(SmokeTest, SharedRes30Delta) {
+ bf::path path = kSmokePackagesDirectory / "SharedRes30Delta.wgt";
+ bf::path delta_package = kSmokePackagesDirectory / "SharedRes30Delta.delta";
+ std::string pkgid = "smokeSh3De";
+ std::string appid = "smokeSh3De.SharedRes30Delta";
+ ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
+ ci::AppInstaller::Result::OK);
+ ValidatePackage(pkgid, {appid});
+ // Check delta modifications
+ bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
+ ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-2")); // NOLINT
+ ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT-2")); // NOLINT
+ ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-1")); // NOLINT
+ ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "SHARED-WGT-1")); // NOLINT
+}
+
+TEST_F(SmokeTest, SharedRes30Hybrid) {
+ bf::path path = kSmokePackagesDirectory / "SharedRes30Hybrid.wgt";
+ std::string pkgid = "smokeSh3Hy";
+ std::string appid1 = "smokeSh3Hy.SharedRes30Hybrid";
+ std::string appid2 = "sharedres30hybridserivce";
+ ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
+ ValidatePackage(pkgid, {appid1, appid2});
+ bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
+ ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT")); // NOLINT
+ ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT")); // NOLINT
+ ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "shared" / "res" / "SHARED-TPK")); // NOLINT
+ ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-TPK")); // NOLINT
+}
+
+TEST_F(SmokeTest, SharedRes30HybridDelta) {
+ bf::path path = kSmokePackagesDirectory / "SharedRes30HybridDelta.wgt";
+ bf::path delta_package = kSmokePackagesDirectory / "SharedRes30HybridDelta.delta";
+ std::string pkgid = "smokeSh3HD";
+ std::string appid1 = "smokeSh3HD.SharedRes30HybridDelta";
+ std::string appid2 = "sharedres30hybriddeltaserivce";
+ ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
+ ci::AppInstaller::Result::OK);
+ ValidatePackage(pkgid, {appid1, appid2});
+ // Check delta modifications
+ bf::path root_path = ci::GetRootAppPath(false, kTestUserId);
+ ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-2")); // NOLINT
+ ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "shared" / "res" / "SHARED-WGT-2")); // NOLINT
+ ASSERT_TRUE(bf::is_regular_file(root_path / pkgid / "shared" / "res" / "SHARED-TPK-2")); // NOLINT
+ ASSERT_TRUE(bf::is_symlink(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-TPK-2")); // NOLINT
+ ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "shared" / "res" / "SHARED-WGT-1")); // NOLINT
+ ASSERT_FALSE(bf::exists(root_path / pkgid / "shared" / "res" / "SHARED-WGT-1")); // NOLINT
+}
+
} // namespace common_installer
int main(int argc, char** argv) {
diff --git a/src/unit_tests/test_samples/smoke/SharedRes24.wgt b/src/unit_tests/test_samples/smoke/SharedRes24.wgt
new file mode 100644
index 0000000000000000000000000000000000000000..782e7e924926614c53ed245162d280fe3ce58219
GIT binary patch
literal 38439
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