Fix pkg_upgrader 68/262068/10
authorjh9216.park <jh9216.park@samsung.com>
Mon, 2 Aug 2021 08:07:20 +0000 (04:07 -0400)
committerJunghyun Yeon <jungh.yeon@samsung.com>
Thu, 5 Aug 2021 00:38:06 +0000 (00:38 +0000)
- In case of Uninstall operation, the tool shouldn't unzip files
- Fixed PkgUpgrader::CompareVersion()
- Added unittests

Change-Id: I31d591527b37a4d97d5d80c5e9f1c9867409d11d
Signed-off-by: jh9216.park <jh9216.park@samsung.com>
src/pkg_upgrade/src/backend_invoker.cc
src/pkg_upgrade/src/pkg_upgrader.cc
src/pkg_upgrade/src/rw2ro_upgrader.cc
src/pkg_upgrade/src/rw_upgrader.cc
tests/mock/os_mock.cc
tests/mock/os_mock.h
tests/unit_tests/pkg_upgrade/data/packages/org.tizen.app-selector.xml [deleted file]
tests/unit_tests/pkg_upgrade/data/packages/org.tizen.bluetooth.xml [deleted file]
tests/unit_tests/pkg_upgrade/data/rw/list.txt
tests/unit_tests/pkg_upgrade/src/test_backend_invoker.cc
tests/unit_tests/pkg_upgrade/src/test_pkg_upgrader.cc

index c2f5823..1308bad 100644 (file)
@@ -67,7 +67,8 @@ BackendInvoker::BackendInvoker(std::string pkgid, PkgType type,
     parameters_.push_back(kForceRemoveOptStr);
     parameters_.push_back(kPartialRWOptStr);
   } else if (op == PkgOperation::UNINSTALL_KEEP_RW_DATA) {
-    parameters_.push_back(kForceRemoveOptStr);
+    if (loc == PkgLocation::RO)
+      parameters_.push_back(kForceRemoveOptStr);
     parameters_.push_back(kKeepRWDataOptStr);
   }
 }
@@ -134,7 +135,7 @@ int BackendInvoker::XSystem(const char *argv[]) {
   case 0:
     /* child */
     execvp(argv[0], (char *const *)argv);
-    _exit(-1);
+    return 0;
   default:
     /* parent */
     break;
index 4043183..b3e553b 100644 (file)
@@ -67,9 +67,9 @@ PkgVersionCmpResult PkgUpgrader::CompareVersion(
     return PkgVersionCmpResult::UNKNOWN;
 
   if (compare == PMINFO_VERSION_NEW)
-    return PkgVersionCmpResult::HIGHER;
-  else if (compare == PMINFO_VERSION_OLD)
     return PkgVersionCmpResult::LOWER;
+  else if (compare == PMINFO_VERSION_OLD)
+    return PkgVersionCmpResult::HIGHER;
   else
     return PkgVersionCmpResult::SAME;
 }
index 3cd9911..59f1b84 100644 (file)
@@ -48,11 +48,6 @@ bool Rw2RoUpgrader::Upgrade() {
     return false;
   }
 
-  if (!new_pkg_->Upgrade()) {
-    LOG(ERROR) << "Upgrade operation of new RO package failed";
-    return false;
-  }
-
   return true;
 }
 
index 666cabe..e8b3192 100644 (file)
@@ -49,8 +49,11 @@ bool RwUpgrader::Upgrade() {
     }
   }
 
-  if (!UnzipPkgFromZip(new_pkg_->GetId()))
-    return false;
+  if (new_pkg_->GetOperation() != PkgOperation::UNINSTALL &&
+      new_pkg_->GetOperation() != PkgOperation::UNINSTALL_KEEP_RW_DATA) {
+    if (!UnzipPkgFromZip(new_pkg_->GetId()))
+      return false;
+  }
 
   if (!new_pkg_->Upgrade()) {
     LOG(ERROR) << "Upgrade operation failed";
index 32c8560..f16a95e 100644 (file)
@@ -38,3 +38,7 @@ extern "C" int smack_setlabel(const char *path, const char* label,
     enum smack_label_type type) {
   return MOCK_HOOK_P3(OsMock, smack_setlabel, path, label, type);
 }
+
+extern "C" int execvp(const char* file, char* const argv[]) {
+  return MOCK_HOOK_P2(OsMock, execvp, file, argv);
+}
index 7744ba2..f935f3f 100644 (file)
@@ -33,6 +33,7 @@ class OsMock : public virtual ModuleMock {
   MOCK_METHOD3(fchown, int(int, uid_t, gid_t));
   MOCK_METHOD2(fchmod, int(int, mode_t));
   MOCK_METHOD3(smack_setlabel, int(const char*, const char*, smack_label_type));
+  MOCK_METHOD2(execvp, int(const char*, char* const []));
 };
 
 #endif  // TESTS_MOCK_OS_MOCK_H_
diff --git a/tests/unit_tests/pkg_upgrade/data/packages/org.tizen.app-selector.xml b/tests/unit_tests/pkg_upgrade/data/packages/org.tizen.app-selector.xml
deleted file mode 100644 (file)
index 314cff5..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns="http://tizen.org/ns/packages" package="org.tizen.app-selector" version="0.1.9" api-version="3.0" install-location="internal-only" type="tpk" readonly="true" preload="true" removable="false">
-       <label>Application Selection Popup</label>
-       <description>Application Selection Popup</description>
-       <ui-application appid="org.tizen.app-selector" exec="/usr/apps/org.tizen.app-selector/bin/app-selector" nodisplay="true" multiple="false" type="capp" taskmanage="false" hw-acceleration="on" launch_mode="group">
-               <label>Application Selection Popup</label>
-       </ui-application>
-    <privileges>
-        <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
-       <privilege>http://tizen.org/privilege/mediastorage</privilege>
-       <privilege>http://tizen.org/privilege/externalstorage</privilege>
-    </privileges>
-</manifest>
diff --git a/tests/unit_tests/pkg_upgrade/data/packages/org.tizen.bluetooth.xml b/tests/unit_tests/pkg_upgrade/data/packages/org.tizen.bluetooth.xml
deleted file mode 100644 (file)
index b3f618e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns="http://tizen.org/ns/packages" package="org.tizen.bluetooth" api-version="3.0" version="2.0.25" install-location="internal-only" type="rpm" preload="true" readonly="true" removable="false">
-       <label>iW bluetooth</label>
-       <author email="insung.cho@samsung.com" href="www.samsung.com">Insung Cho</author>
-       <description>W bluetooth</description>
-       <ui-application appid="org.tizen.bluetooth" exec="/usr/apps/org.tizen.bluetooth/bin/bluetooth" nodisplay="true" multiple="false" type="capp" taskmanage="false" launch_mode="group">
-               <icon/>
-               <label>Bluetooth application</label>
-               <label xml:lang="en-us">Bluetooth application</label>
-               <app-control>
-                       <operation name="http://tizen.org/appcontrol/operation/edit"/>
-                       <mime name="application/x-bluetooth-on-off"/>
-                       <mime name="application/x-bluetooth-visibility"/>
-               </app-control>
-       </ui-application>
-       <privileges>
-               <privilege>http://tizen.org/privilege/bluetooth</privilege>
-               <privilege>http://tizen.org/privilege/bluetooth.admin</privilege>
-       </privileges>
-</manifest>
index eaba1da..367415c 100644 (file)
@@ -1,2 +1 @@
-"package=org.tizen.new_rw":"version=1.2.0":"type=tpk":"removable=false"
-"package=org.test.pkg2":"version=1.2.0":"type=wgt":"removable=true"
+"package=org.tizen.new_rw":"version=1.2.0":"type=tpk":"removable=true"
index 9dcf535..1cdd933 100644 (file)
@@ -175,7 +175,7 @@ TEST_F(BackendInvokerTest, TPKRWUninstallKeepRWData) {
       PkgLocation::RW, PkgOperation::UNINSTALL_KEEP_RW_DATA, false);
 
   std::list<std::string> expected_argument { "/usr/bin/tpk-backend", "-d",
-      "tpk_pkgid", "--force-remove", "--keep-rwdata"};
+      "tpk_pkgid", "--keep-rwdata"};
   EXPECT_TRUE(CompareArgumentList(backend.GetParameter(),
       expected_argument));
 }
@@ -185,7 +185,7 @@ TEST_F(BackendInvokerTest, WGTRWUninstallKeepRWData) {
       PkgLocation::RW, PkgOperation::UNINSTALL_KEEP_RW_DATA, false);
 
   std::list<std::string> expected_argument { "/usr/bin/wgt-backend", "-d",
-      "wgt_pkgid", "--force-remove", "--keep-rwdata"};
+      "wgt_pkgid", "--keep-rwdata"};
   EXPECT_TRUE(CompareArgumentList(backend.GetParameter(),
       expected_argument));
 }
index 5262384..286128b 100644 (file)
@@ -19,6 +19,8 @@
 #include <stdio.h>
 
 #include <memory>
+#include <string>
+#include <vector>
 
 #include "mock/os_mock.h"
 #include "mock/pkgmgr_info_mock.h"
@@ -48,6 +50,14 @@ class PkgFinderTest : public TestFixture {
   virtual ~PkgFinderTest() {}
 
   virtual void SetUp() {
+  }
+
+  virtual void TearDown() {
+  }
+
+  void SetOldPkgInfo(const char* ro_pkg_id, const char* ro_pkg_type,
+      const char* ro_pkg_version, const char* rw_pkg_id, const char* rw_pkg_type,
+      const char* rw_pkg_version) {
     static int k;
     pkgmgrinfo_pkginfo_filter_h dummy_filter = (pkgmgrinfo_pkginfo_filter_h)&k;
 
@@ -63,8 +73,6 @@ class PkgFinderTest : public TestFixture {
             Invoke([](pkgmgrinfo_pkginfo_filter_h handle,
                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data) -> int {
               pkg_cb(nullptr, user_data);
-              pkg_cb(nullptr, user_data);
-              pkg_cb(nullptr, user_data);
               return 0;
             })
         )
@@ -73,67 +81,24 @@ class PkgFinderTest : public TestFixture {
               pkg_cb(nullptr, user_data);
               return 0;
             }));
-
-    const char* old_ro_pkgid[] = {
-      "org.test.pkg1",
-      "org.test.pkg2",
-      "org.tizen.app-selector"
-    };
-
-    const char* old_ro_pkg_type[] = {
-      "tpk",
-      "wgt",
-      "tpk"
-    };
-
-    const char* old_ro_pkg_version[] = {
-      "1.0.0",
-      "1.2.0",
-      "0.1.0"
-    };
-
-    const char* old_rw_pkgid[] = {
-      "org.tizen.alarm"
-    };
-
-    const char* old_rw_pkg_type[] = {
-      "tpk"
-    };
-
-    const char* old_rw_pkg_version[] = {
-      "1.5.0",
-    };
-
     EXPECT_CALL(GetMock<PkgMgrInfoMock>(),
         pkgmgrinfo_pkginfo_get_pkgid(_, _))
         .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_ro_pkgid[0])), Return(0)))
-        .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_ro_pkgid[1])), Return(0)))
-        .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_ro_pkgid[2])), Return(0)))
+            const_cast<char*>(ro_pkg_id)), Return(0)))
         .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_rw_pkgid[0])), Return(0)));
+            const_cast<char*>(rw_pkg_id)), Return(0)));
     EXPECT_CALL(GetMock<PkgMgrInfoMock>(),
         pkgmgrinfo_pkginfo_get_type(_, _))
         .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_ro_pkg_type[0])), Return(0)))
+            const_cast<char*>(ro_pkg_type)), Return(0)))
         .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_ro_pkg_type[1])), Return(0)))
-        .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_ro_pkg_type[2])), Return(0)))
-        .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_rw_pkg_type[0])), Return(0)));
+            const_cast<char*>(rw_pkg_type)), Return(0)));
     EXPECT_CALL(GetMock<PkgMgrInfoMock>(),
         pkgmgrinfo_pkginfo_get_version(_, _))
         .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_ro_pkg_version[0])), Return(0)))
-        .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_ro_pkg_version[1])), Return(0)))
-        .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_ro_pkg_version[2])), Return(0)))
+            const_cast<char*>(ro_pkg_version)), Return(0)))
         .WillOnce(DoAll(SetArgPointee<1>(
-            const_cast<char*>(old_rw_pkg_version[0])), Return(0)));
+            const_cast<char*>(rw_pkg_version)), Return(0)));
 
     EXPECT_CALL(GetMock<PkgMgrInfoMock>(), pkgmgrinfo_pkginfo_filter_destroy(_))
         .WillRepeatedly(Return(0));
@@ -142,24 +107,25 @@ class PkgFinderTest : public TestFixture {
     finder_.SetPreloadRwListPath("./tests/unit_tests/pkg_upgrade/data/rw/list.txt");
   }
 
-  virtual void TearDown() {
-  }
-
   PkgFinder finder_;
 };
 
 TEST_F(PkgFinderTest, PkgFinder) {
-  finder_.Find();
+  SetOldPkgInfo("org.tizen.alarm", "tpk", "1.0.0",  // RO
+      "org.test.test1", "wgt", "1.0.0");  // RW
 
-  EXPECT_EQ(finder_.GetOldPkgs().size(), 4);
-  EXPECT_EQ(finder_.GetNewPkgs().size(), 5);
+  finder_.Find();
+  EXPECT_EQ(finder_.GetOldPkgs().size(), 2);
+  EXPECT_EQ(finder_.GetNewPkgs().size(), 2);
 }
 
 TEST_F(PkgFinderTest, PkgUpgraderFactory) {
   PkgUpgraderFactory factory;
-  auto list = factory.MakeList(&finder_);
+  SetOldPkgInfo("org.tizen.alarm", "tpk", "1.0.0",  // RO
+      "org.test.test1", "wgt", "1.0.0");  // RW
 
-  EXPECT_EQ(list.size(), 6);
+  auto list = factory.MakeList(&finder_);
+  EXPECT_EQ(list.size(), 2);
 }
 
 class PkgUpgraderTest : public PkgFinderTest {
@@ -170,7 +136,7 @@ class PkgUpgraderTest : public PkgFinderTest {
   void SetUp() override {
     PkgFinderTest::SetUp();
     EXPECT_CALL(GetMock<OsMock>(), fork())
-        .WillRepeatedly(Return(1));
+        .WillRepeatedly(Return(0));
     EXPECT_CALL(GetMock<OsMock>(), waitpid(_, _, _))
           .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(1)));
     EXPECT_CALL(GetMock<OsMock>(), fchown(_, _, _))
@@ -184,19 +150,376 @@ class PkgUpgraderTest : public PkgFinderTest {
   void TearDown() override {
     PkgFinderTest::TearDown();
   }
+
+  std::string GetCmd(char* const argv[]) {
+    std::string cmd;
+    for (int i = 0; argv[i] != nullptr; i++) {
+      if (i > 0)
+        cmd += " ";
+      cmd += argv[i];
+    }
+    return cmd;
+  }
 };
 
-TEST_F(PkgUpgraderTest, Upgrader) {
+TEST_F(PkgUpgraderTest, Upgrader_RO2RO_RW2RW_HIGH_VERSION) {
   Upgrader upgrader;
-
   upgrader.SetDbPath("./tests/unit_tests/pkg_upgrade/data/db");
+  std::vector<std::string> cmds;
+  SetOldPkgInfo("org.tizen.alarm", "tpk", "1.0.0",  // RO
+      "org.tizen.new_rw", "tpk", "1.0.0");  // RW
+  // New pkg : org.tizen.alarm 2.0.0 (ro), org.tizen.new_rw 1.2.0 (rw)
+
+  EXPECT_CALL(GetMock<OsMock>(),
+        execvp(_, _))
+        .WillRepeatedly(
+            Invoke([&](const char* file, char* const argv[]) -> int {
+              std::string cmd = GetCmd(argv);
+              cmds.push_back(std::move(cmd));
+              return 0;
+            })
+        );
+
   ASSERT_TRUE(upgrader.Process(&finder_));
+  const auto& success = upgrader.GetSuccessList();
+  const auto& failure = upgrader.GetFailureList();
+
+  EXPECT_EQ(success.size(), 2); //RO2RO, RW2RW
+  EXPECT_EQ(failure.size(), 0);
+  EXPECT_EQ(cmds.size(), 5);
+  EXPECT_EQ(cmds[0], "/usr/bin/tpk-backend --preload -y org.tizen.alarm"
+      " --partial-rw --skip-check-reference");
+  EXPECT_EQ(cmds[1], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/share/packages/org.tizen.new_rw.xml -d /");
+  EXPECT_EQ(cmds[2], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/usr/globalapps/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[3], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/etc/skel/apps_rw/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[4], "/usr/bin/tpk-backend -y org.tizen.new_rw --preload-rw "
+      "--skip-check-reference");
+}
 
+TEST_F(PkgUpgraderTest, Upgrader_RO2RO_RW2RW_SAME_VERSION) {
+  Upgrader upgrader;
+  upgrader.SetDbPath("./tests/unit_tests/pkg_upgrade/data/db");
+  std::vector<std::string> cmds;
+  SetOldPkgInfo("org.tizen.alarm", "tpk", "2.0.0",  // RO
+      "org.tizen.new_rw", "tpk", "1.2.0");  // RW
+  // New pkg : org.tizen.alarm 2.0.0 (ro), org.tizen.new_rw 1.2.0 (rw)
+
+  EXPECT_CALL(GetMock<OsMock>(),
+        execvp(_, _))
+        .WillRepeatedly(
+            Invoke([&](const char* file, char* const argv[]) -> int {
+              std::string cmd = GetCmd(argv);
+              cmds.push_back(std::move(cmd));
+              return 0;
+            })
+        );
+
+  ASSERT_TRUE(upgrader.Process(&finder_));
   const auto& success = upgrader.GetSuccessList();
   const auto& failure = upgrader.GetFailureList();
 
-  EXPECT_EQ(success.size(), 6);
+  EXPECT_EQ(success.size(), 2); //RO2RO, RW2RW
   EXPECT_EQ(failure.size(), 0);
+  EXPECT_EQ(cmds.size(), 0);
+}
+
+TEST_F(PkgUpgraderTest, Upgrader_RO2RO_RW2RW_LOW_VERSION) {
+  Upgrader upgrader;
+  upgrader.SetDbPath("./tests/unit_tests/pkg_upgrade/data/db");
+  std::vector<std::string> cmds;
+  SetOldPkgInfo("org.tizen.alarm", "tpk", "2.5.0",  // RO
+      "org.tizen.new_rw", "tpk", "2.0.0");  // RW
+  // New pkg : org.tizen.alarm 2.0.0 (ro), org.tizen.new_rw 1.2.0 (rw)
+
+  EXPECT_CALL(GetMock<OsMock>(),
+        execvp(_, _))
+        .WillRepeatedly(
+            Invoke([&](const char* file, char* const argv[]) -> int {
+              std::string cmd = GetCmd(argv);
+              cmds.push_back(std::move(cmd));
+              return 0;
+            })
+        );
+
+  ASSERT_TRUE(upgrader.Process(&finder_));
+
+  EXPECT_EQ(cmds.size(), 5);
+  EXPECT_EQ(cmds[0], "/usr/bin/tpk-backend --preload -y org.tizen.alarm"
+      " --partial-rw --skip-check-reference");
+  EXPECT_EQ(cmds[1], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/share/packages/org.tizen.new_rw.xml -d /");
+  EXPECT_EQ(cmds[2], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/usr/globalapps/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[3], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/etc/skel/apps_rw/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[4], "/usr/bin/tpk-backend -y org.tizen.new_rw --preload-rw "
+      "--skip-check-reference");
+}
+
+TEST_F(PkgUpgraderTest, Upgrader_RO_REMOVE) {
+  Upgrader upgrader;
+  upgrader.SetDbPath("./tests/unit_tests/pkg_upgrade/data/db");
+  std::vector<std::string> cmds;
+  SetOldPkgInfo("org.test.del", "tpk", "1.0.0",  // RO
+      "org.tizen.new_rw", "tpk", "1.2.0");  // RW
+  // New pkg : org.tizen.alarm 2.0.0 (ro), org.tizen.new_rw 1.2.0 (rw)
+
+  EXPECT_CALL(GetMock<OsMock>(),
+        execvp(_, _))
+        .WillRepeatedly(
+            Invoke([&](const char* file, char* const argv[]) -> int {
+              std::string cmd = GetCmd(argv);
+              cmds.push_back(std::move(cmd));
+              return 0;
+            })
+        );
+
+  ASSERT_TRUE(upgrader.Process(&finder_));
+  EXPECT_EQ(cmds.size(), 2);
+  EXPECT_EQ(cmds[0], "/usr/bin/tpk-backend --preload -y org.tizen.alarm "
+      "--partial-rw --skip-check-reference");
+  EXPECT_EQ(cmds[1], "/usr/bin/tpk-backend --preload -d org.test.del "
+      "--force-remove --partial-rw");
+}
+
+TEST_F(PkgUpgraderTest, Upgrader_RW_DO_NOT_REMOVE) {
+  Upgrader upgrader;
+  upgrader.SetDbPath("./tests/unit_tests/pkg_upgrade/data/db");
+  std::vector<std::string> cmds;
+  SetOldPkgInfo("org.tizen.alarm", "tpk", "2.0.0",  // RO
+      "org.test.don'tDel", "tpk", "1.0.0");  // RW
+  // New pkg : org.tizen.alarm 2.0.0 (ro), org.tizen.new_rw 1.2.0 (rw)
+
+  EXPECT_CALL(GetMock<OsMock>(),
+        execvp(_, _))
+        .WillRepeatedly(
+            Invoke([&](const char* file, char* const argv[]) -> int {
+              std::string cmd = GetCmd(argv);
+              cmds.push_back(std::move(cmd));
+              return 0;
+            })
+        );
+
+  ASSERT_TRUE(upgrader.Process(&finder_));
+  EXPECT_EQ(cmds.size(), 4);
+  EXPECT_EQ(cmds[0], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/share/packages/org.tizen.new_rw.xml -d /");
+  EXPECT_EQ(cmds[1], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/usr/globalapps/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[2], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/etc/skel/apps_rw/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[3], "/usr/bin/tpk-backend -y org.tizen.new_rw --preload-rw "
+      "--skip-check-reference");
+}
+
+TEST_F(PkgUpgraderTest, Upgrader_RW2RO_HIGH_VERSION) {
+  Upgrader upgrader;
+  upgrader.SetDbPath("./tests/unit_tests/pkg_upgrade/data/db");
+  std::vector<std::string> cmds;
+  SetOldPkgInfo("org.tizen.test", "tpk", "1.0.0", // RO
+      "org.tizen.alarm", "tpk", "1.5.0");  // RW
+  // New pkg : org.tizen.alarm 2.0.0 (ro), org.tizen.new_rw 1.2.0 (rw)
+
+  EXPECT_CALL(GetMock<OsMock>(),
+        execvp(_, _))
+        .WillRepeatedly(
+            Invoke([&](const char* file, char* const argv[]) -> int {
+              std::string cmd = GetCmd(argv);
+              cmds.push_back(std::move(cmd));
+              return 0;
+            })
+        );
+
+  ASSERT_TRUE(upgrader.Process(&finder_));
+
+  EXPECT_EQ(cmds.size(), 6);
+  EXPECT_EQ(cmds[0], "/usr/bin/tpk-backend -d org.tizen.alarm "
+      "--keep-rwdata");
+  EXPECT_EQ(cmds[1], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/share/packages/org.tizen.new_rw.xml -d /");
+  EXPECT_EQ(cmds[2], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/usr/globalapps/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[3], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/etc/skel/apps_rw/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[4], "/usr/bin/tpk-backend -y org.tizen.new_rw --preload-rw "
+      "--skip-check-reference");
+  EXPECT_EQ(cmds[5], "/usr/bin/tpk-backend --preload -d org.tizen.test "
+      "--force-remove --partial-rw");
+}
+
+TEST_F(PkgUpgraderTest, Upgrader_RW2RO_LOW_VERSION) {
+  Upgrader upgrader;
+  upgrader.SetDbPath("./tests/unit_tests/pkg_upgrade/data/db");
+  std::vector<std::string> cmds;
+  SetOldPkgInfo("org.tizen.test", "tpk", "1.0.0", // RO
+      "org.tizen.alarm", "tpk", "2.5.0");  // RW
+  // New pkg : org.tizen.alarm 2.0.0 (ro), org.tizen.new_rw 1.2.0 (rw)
+
+  EXPECT_CALL(GetMock<OsMock>(),
+        execvp(_, _))
+        .WillRepeatedly(
+            Invoke([&](const char* file, char* const argv[]) -> int {
+              std::string cmd = GetCmd(argv);
+              cmds.push_back(std::move(cmd));
+              return 0;
+            })
+        );
+
+  ASSERT_TRUE(upgrader.Process(&finder_));
+
+  EXPECT_EQ(cmds.size(), 5);
+  EXPECT_EQ(cmds[0], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/share/packages/org.tizen.new_rw.xml -d /");
+  EXPECT_EQ(cmds[1], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/usr/globalapps/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[2], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/etc/skel/apps_rw/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[3], "/usr/bin/tpk-backend -y org.tizen.new_rw --preload-rw "
+      "--skip-check-reference");
+  EXPECT_EQ(cmds[4], "/usr/bin/tpk-backend --preload -d org.tizen.test "
+      "--force-remove --partial-rw");
+}
+
+TEST_F(PkgUpgraderTest, Upgrader_RW2RO_SAME_VERSION) {
+  Upgrader upgrader;
+  upgrader.SetDbPath("./tests/unit_tests/pkg_upgrade/data/db");
+  std::vector<std::string> cmds;
+  SetOldPkgInfo("org.tizen.test", "tpk", "1.0.0", // RO
+      "org.tizen.alarm", "tpk", "2.0.0");  // RW
+  // New pkg : org.tizen.alarm 2.0.0 (ro), org.tizen.new_rw 1.2.0 (rw)
+
+  EXPECT_CALL(GetMock<OsMock>(),
+        execvp(_, _))
+        .WillRepeatedly(
+            Invoke([&](const char* file, char* const argv[]) -> int {
+              std::string cmd = GetCmd(argv);
+              cmds.push_back(std::move(cmd));
+              return 0;
+            })
+        );
+
+  ASSERT_TRUE(upgrader.Process(&finder_));
+
+  EXPECT_EQ(cmds.size(), 6);
+  EXPECT_EQ(cmds[0], "/usr/bin/tpk-backend -d org.tizen.alarm "
+      "--keep-rwdata");
+  EXPECT_EQ(cmds[1], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/share/packages/org.tizen.new_rw.xml -d /");
+  EXPECT_EQ(cmds[2], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/usr/globalapps/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[3], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/etc/skel/apps_rw/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[4], "/usr/bin/tpk-backend -y org.tizen.new_rw --preload-rw "
+      "--skip-check-reference");
+  EXPECT_EQ(cmds[5], "/usr/bin/tpk-backend --preload -d org.tizen.test "
+      "--force-remove --partial-rw");
+}
+
+TEST_F(PkgUpgraderTest, Upgrader_RO2RW_HIGH_VERSION) {
+  Upgrader upgrader;
+  upgrader.SetDbPath("./tests/unit_tests/pkg_upgrade/data/db");
+  std::vector<std::string> cmds;
+  SetOldPkgInfo("org.tizen.new_rw", "tpk", "1.0.0", // RO
+      "org.tizen.alarm", "tpk", "2.0.0");  // RW
+  // New pkg : org.tizen.alarm 2.0.0 (ro), org.tizen.new_rw 1.2.0 (rw)
+
+  EXPECT_CALL(GetMock<OsMock>(),
+        execvp(_, _))
+        .WillRepeatedly(
+            Invoke([&](const char* file, char* const argv[]) -> int {
+              std::string cmd = GetCmd(argv);
+              cmds.push_back(std::move(cmd));
+              return 0;
+            })
+        );
+
+  ASSERT_TRUE(upgrader.Process(&finder_));
+
+  EXPECT_EQ(cmds.size(), 6);
+  EXPECT_EQ(cmds[0], "/usr/bin/tpk-backend -d org.tizen.alarm "
+      "--keep-rwdata");
+  EXPECT_EQ(cmds[1], "/usr/bin/tpk-backend --preload -d org.tizen.new_rw "
+      "--force-remove --keep-rwdata");
+  EXPECT_EQ(cmds[2], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/share/packages/org.tizen.new_rw.xml -d /");
+  EXPECT_EQ(cmds[3], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/usr/globalapps/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[4], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/etc/skel/apps_rw/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[5], "/usr/bin/tpk-backend -y org.tizen.new_rw --preload-rw "
+      "--skip-check-reference");
+}
+
+TEST_F(PkgUpgraderTest, Upgrader_RO2RW_LOW_VERSION) {
+  Upgrader upgrader;
+  upgrader.SetDbPath("./tests/unit_tests/pkg_upgrade/data/db");
+  std::vector<std::string> cmds;
+  SetOldPkgInfo("org.tizen.new_rw", "tpk", "2.0.0", // RO
+      "org.tizen.alarm", "tpk", "2.0.0");  // RW
+  // New pkg : org.tizen.alarm 2.0.0 (ro), org.tizen.new_rw 1.2.0 (rw)
+
+  EXPECT_CALL(GetMock<OsMock>(),
+        execvp(_, _))
+        .WillRepeatedly(
+            Invoke([&](const char* file, char* const argv[]) -> int {
+              std::string cmd = GetCmd(argv);
+              cmds.push_back(std::move(cmd));
+              return 0;
+            })
+        );
+
+  ASSERT_TRUE(upgrader.Process(&finder_));
+
+  EXPECT_EQ(cmds.size(), 6);
+  EXPECT_EQ(cmds[0], "/usr/bin/tpk-backend -d org.tizen.alarm "
+      "--keep-rwdata");
+  EXPECT_EQ(cmds[1], "/usr/bin/tpk-backend --preload -d org.tizen.new_rw "
+      "--force-remove --keep-rwdata");
+  EXPECT_EQ(cmds[2], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/share/packages/org.tizen.new_rw.xml -d /");
+  EXPECT_EQ(cmds[3], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/usr/globalapps/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[4], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/etc/skel/apps_rw/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[5], "/usr/bin/tpk-backend -y org.tizen.new_rw --preload-rw "
+      "--skip-check-reference");
+}
+
+TEST_F(PkgUpgraderTest, Upgrader_RO2RW_SAME_VERSION) {
+  Upgrader upgrader;
+  upgrader.SetDbPath("./tests/unit_tests/pkg_upgrade/data/db");
+  std::vector<std::string> cmds;
+  SetOldPkgInfo("org.tizen.new_rw", "tpk", "1.2.0", // RO
+      "org.tizen.alarm", "tpk", "2.0.0");  // RW
+  // New pkg : org.tizen.alarm 2.0.0 (ro), org.tizen.new_rw 1.2.0 (rw)
+
+  EXPECT_CALL(GetMock<OsMock>(),
+        execvp(_, _))
+        .WillRepeatedly(
+            Invoke([&](const char* file, char* const argv[]) -> int {
+              std::string cmd = GetCmd(argv);
+              cmds.push_back(std::move(cmd));
+              return 0;
+            })
+        );
+
+  ASSERT_TRUE(upgrader.Process(&finder_));
+
+  EXPECT_EQ(cmds.size(), 6);
+  EXPECT_EQ(cmds[0], "/usr/bin/tpk-backend -d org.tizen.alarm --keep-rwdata");
+  EXPECT_EQ(cmds[1], "/usr/bin/tpk-backend --preload -d org.tizen.new_rw "
+      "--force-remove --keep-rwdata");
+  EXPECT_EQ(cmds[2], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/share/packages/org.tizen.new_rw.xml -d /");
+  EXPECT_EQ(cmds[3], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/usr/globalapps/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[4], "/usr/bin/unzip -oXqq /usr/system/RestoreDir/opt.zip "
+      "opt/etc/skel/apps_rw/org.tizen.new_rw/* -d /");
+  EXPECT_EQ(cmds[5], "/usr/bin/tpk-backend -y org.tizen.new_rw --preload-rw "
+      "--skip-check-reference");
 }
 
 TEST_F(PkgUpgraderTest, Upgrader_db_bck) {