Remove boost dependency
[platform/core/appfw/app-installers.git] / test / smoke_tests / common / smoke_utils.cc
index db141c5..027098c 100644 (file)
@@ -4,15 +4,16 @@
 
 #include "smoke_tests/common/smoke_utils.h"
 
+#include <getopt.h>
 #include <gum/gum-user.h>
 #include <gum/gum-user-service.h>
 #include <gum/common/gum-user-types.h>
 #include <manifest_parser/utils/version_number.h>
 #include <sys/smack.h>
+#include <unistd.h>
 #include <vconf.h>
 #include <vconf-internal-keys.h>
 
-#include <boost/filesystem/path.hpp>
 #include <gtest/gtest.h>
 
 #include <common/installer/app_installer.h>
 #include <common/utils/pkgmgr_query.h>
 #include <common/tzip_interface.h>
 
+#include "pkgmgr_parser_db.h"
+
+#include <filesystem>
+#include <fstream>
 #include <list>
 #include <memory>
+#include <sstream>
 #include <string>
+#include <system_error>
 #include <vector>
 
-namespace bf = boost::filesystem;
-namespace bs = boost::system;
 namespace ci = common_installer;
-namespace bo = boost::program_options;
+namespace fs = std::filesystem;
 
 namespace {
 
@@ -81,39 +86,59 @@ const char kLegacyExtImageDir[] = "legacy_extimage_dir";
 const std::string& kDefaultUserIdStr = std::to_string(kDefaultUserUid);
 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
 const uid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER);
-extern const bf::path kSdkDirectory = "/home/owner/share/tmp/sdk_tools";
+extern const fs::path kSdkDirectory = "/home/owner/share/tmp/sdk_tools";
 
 ci::RequestMode ParseRequestMode(int argc,  char** argv) {
-  bo::options_description desc("Available options");
-  desc.add_options()
-      ("request-mode", bo::value<std::string>(), "set request mode")
-      ("global-request,g", "set request mode to global")
-      ("user-request,u", "set request mode to user");
-
-  bo::variables_map vm;
-  bo::store(bo::command_line_parser(argc, argv).
-      options(desc).allow_unregistered().run(), vm);
-  bo::notify(vm);
-
-  if (vm.count("global-request")) {
+  const struct option long_opts[] = {
+    { "request-mode", required_argument, nullptr, 'r' },
+    { "global-request", no_argument, nullptr, 'g' },
+    { "user-request", no_argument, nullptr, 'u' },
+    { 0, 0, 0, 0 }
+  };
+
+  std::string request_mode;
+  bool is_global_request = false;
+  bool is_user_request = false;
+  while (true) {
+    int opt = getopt_long(argc, argv, "gu", long_opts, nullptr);
+    if (opt == -1)
+      break;
+
+    switch (opt) {
+      case 'r':
+        if (optarg)
+          request_mode = optarg;
+        break;
+      case 'g':
+        is_global_request = true;
+        break;
+      case 'u':
+        is_user_request = true;
+        break;
+      default:
+        break;
+    }
+  }
+
+  if (is_global_request) {
     std::cout << "Request mode was set to global." << std::endl;
     return ci::RequestMode::GLOBAL;
   }
-  if (vm.count("user-request")) {
+  if (is_user_request) {
     std::cout << "Request mode was set to user." << std::endl;
     return ci::RequestMode::USER;
   }
-  if (vm.count("request-mode")) {
-    if (vm["request-mode"].as<std::string>() == "global") {
+  if (!request_mode.empty()) {
+    if (request_mode.compare("global") == 0) {
       std::cout << "Request mode was set to global." << std::endl;
       return ci::RequestMode::GLOBAL;
     }
-    if (vm["request-mode"].as<std::string>() == "user") {
+    if (request_mode.compare("user") == 0) {
       std::cout << "Request mode was set to user." << std::endl;
       return ci::RequestMode::USER;
     }
     std::cout << "Cannot set request mode to "
-              << vm["request-mode"].as<std::string>() << std::endl;
+              << request_mode << std::endl;
   }
   std::cout << "Request mode was set to global." << std::endl;
   return ci::RequestMode::GLOBAL;
@@ -144,10 +169,10 @@ static bool DeleteUser(const char* user_name, bool rem_home_dir) {
 bool AddTestUser(User* test_user) {
   std::cout << "Adding test user: " << kNormalUserName << std::endl;
   AddUser(kNormalUserName);
-  if (boost::optional<uid_t> uid = ci::GetUidByUserName(kNormalUserName)) {
+  if (std::optional<uid_t> uid = ci::GetUidByUserName(kNormalUserName)) {
     test_user->uid = *uid;
     std::cout << "User created properly: uid=" << *uid;
-    if (boost::optional<gid_t> gid = ci::GetGidByUid(*uid)) {
+    if (std::optional<gid_t> gid = ci::GetGidByUid(*uid)) {
       test_user->gid = *gid;
       std::cout << " gid=" << *gid;
     }
@@ -161,7 +186,7 @@ bool AddTestUser(User* test_user) {
 bool DeleteTestUser() {
   std::cout << "Deleting test user: " << kNormalUserName << std::endl;
   uid_t test_uid;
-  if (boost::optional<uid_t> uid = ci::GetUidByUserName(kNormalUserName))
+  if (std::optional<uid_t> uid = ci::GetUidByUserName(kNormalUserName))
     test_uid = *uid;
   else
     return false;
@@ -175,7 +200,7 @@ bool DeleteTestUser() {
   return false;
 }
 
-bool TouchFile(const bf::path& path) {
+bool TouchFile(const fs::path& path) {
   FILE* f = fopen(path.c_str(), "w+");
   if (!f)
     return false;
@@ -183,49 +208,56 @@ bool TouchFile(const bf::path& path) {
   return true;
 }
 
-void AddDataFiles(const std::string& pkgid, uid_t uid) {
+void AddDataFiles(const std::string& pkgid, uid_t uid,
+    std::vector<fs::path>* result) {
+  std::vector<fs::path> files;
+  files.clear();
   if (uid == kGlobalUserUid) {
     ci::UserList list = ci::GetUserList();
     for (auto l : list) {
       auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l));
-      ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt"));
-      ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt"));
+      files.emplace_back(pkg_path / "data" / "file1.txt");
+      files.emplace_back(pkg_path / "data" / "file2.txt");
     }
   } else {
     auto pkg_path = GetPackageRoot(pkgid, uid);
-    ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt"));
-    ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt"));
+    files.emplace_back(pkg_path / "data" / "file1.txt");
+    files.emplace_back(pkg_path / "data" / "file2.txt");
   }
+
+  for (const auto& path : files)
+    ASSERT_TRUE(TouchFile(path));
+
+  if (result)
+    *result = std::move(files);
 }
 
 void RemoveAllRecoveryFiles(const std::string& prefix, uid_t uid) {
-  bf::path root_path = ci::GetRootAppPath(false, uid);
-  if (!bf::exists(root_path))
+  fs::path root_path = ci::GetRootAppPath(false, uid);
+  if (!fs::exists(root_path))
     return;
-  for (auto& dir_entry : boost::make_iterator_range(
-      bf::directory_iterator(root_path), bf::directory_iterator())) {
-    if (bf::is_regular_file(dir_entry)) {
+  for (auto& dir_entry : fs::directory_iterator(root_path)) {
+    if (fs::is_regular_file(dir_entry)) {
       if (dir_entry.path().string().find(prefix) != std::string::npos) {
-        bs::error_code error;
-        bf::remove(dir_entry.path(), error);
+        std::error_code error;
+        fs::remove(dir_entry, error);
         if (error)
-          LOG(ERROR) << "Failed to remove " << dir_entry.path()
+          LOG(ERROR) << "Failed to remove " << dir_entry
                      << ": " << error.message();
       }
     }
   }
 }
 
-bf::path FindRecoveryFile(const std::string& prefix, uid_t uid) {
-  bf::path root_path = ci::GetRootAppPath(false, uid);
-  if (!bf::exists(root_path))
+fs::path FindRecoveryFile(const std::string& prefix, uid_t uid) {
+  fs::path root_path = ci::GetRootAppPath(false, uid);
+  if (!fs::exists(root_path))
     return {};
 
-  for (auto& dir_entry : boost::make_iterator_range(
-      bf::directory_iterator(root_path), bf::directory_iterator())) {
-    if (bf::is_regular_file(dir_entry)) {
+  for (auto& dir_entry : fs::directory_iterator(root_path)) {
+    if (fs::is_regular_file(dir_entry)) {
       if (dir_entry.path().string().find(prefix) != std::string::npos) {
-        return dir_entry.path();
+        return dir_entry;
       }
     }
   }
@@ -233,12 +265,12 @@ bf::path FindRecoveryFile(const std::string& prefix, uid_t uid) {
 }
 
 std::unique_ptr<ci::recovery::RecoveryFile> GetRecoverFileInfo(
-    const bf::path& recovery_file_path) {
+    const fs::path& recovery_file_path) {
   return ci::recovery::RecoveryFile::OpenRecoveryFile(recovery_file_path);
 }
 
-bf::path GetPackageRoot(const std::string& pkgid, uid_t uid) {
-  bf::path root_path = ci::GetRootAppPath(false, uid);
+fs::path GetPackageRoot(const std::string& pkgid, uid_t uid) {
+  fs::path root_path = ci::GetRootAppPath(false, uid);
   return root_path / pkgid;
 }
 
@@ -246,10 +278,10 @@ bool ValidateFileContentInPackage(const std::string& pkgid,
                                   const std::string& relative,
                                   const std::string& expected,
                                   const TestParameters& params) {
-  bf::path file_path = ci::GetRootAppPath(params.is_readonly,
+  fs::path file_path = ci::GetRootAppPath(params.is_readonly,
                                           params.test_user.uid);
   file_path = file_path / pkgid / relative;
-  if (!bf::exists(file_path)) {
+  if (!fs::exists(file_path)) {
     LOG(ERROR) << file_path << " doesn't exist";
     return false;
   }
@@ -268,23 +300,23 @@ bool ValidateFileContentInPackage(const std::string& pkgid,
 }
 
 static bool ValidatePackageRWFS(const std::string& pkgid, uid_t uid) {
-  bf::path root_path = ci::GetRootAppPath(false, uid);
-  bf::path package_path = root_path / pkgid;
-  bf::path data_path = package_path / rwDirectories[DATA];
-  bf::path cache_path = package_path / rwDirectories[CACHE];
-  bf::path shared_data_path = package_path / rwDirectories[SHARED_DATA];
+  fs::path root_path = ci::GetRootAppPath(false, uid);
+  fs::path package_path = root_path / pkgid;
+  fs::path data_path = package_path / rwDirectories[DATA];
+  fs::path cache_path = package_path / rwDirectories[CACHE];
+  fs::path shared_data_path = package_path / rwDirectories[SHARED_DATA];
 
-  EXTENDED_ASSERT_TRUE(bf::exists(data_path));
-  EXTENDED_ASSERT_TRUE(bf::exists(cache_path));
+  EXTENDED_ASSERT_TRUE(fs::exists(data_path));
+  EXTENDED_ASSERT_TRUE(fs::exists(cache_path));
 
   struct stat stats;
   stat(data_path.c_str(), &stats);
   // gid of RW dirs should be system_share
-  boost::optional<gid_t> system_share =
+  std::optional<gid_t> system_share =
       ci::GetGidByGroupName(kSystemShareGroupName);
   EXTENDED_ASSERT_EQ(uid, stats.st_uid);
   EXTENDED_ASSERT_EQ(*system_share, stats.st_gid);
-  if (bf::exists(shared_data_path)) {
+  if (fs::exists(shared_data_path)) {
     stat(shared_data_path.c_str(), &stats);
     EXTENDED_ASSERT_EQ(uid, stats.st_uid);
     EXTENDED_ASSERT_EQ(*system_share, stats.st_gid);
@@ -298,54 +330,54 @@ static bool ValidatePackageRWFS(const std::string& pkgid, uid_t uid) {
 
 static bool ValidatePackageFS(const std::string& pkgid, const Apps& apps,
     const TestParameters& params) {
-  bf::path root_path = ci::GetRootAppPath(params.is_readonly,
+  fs::path root_path = ci::GetRootAppPath(params.is_readonly,
                                           params.test_user.uid);
-  bf::path package_path = root_path / pkgid;
-  bf::path shared_path = package_path / "shared";
-  EXTENDED_ASSERT_TRUE(bf::exists(root_path));
-  EXTENDED_ASSERT_TRUE(bf::exists(package_path));
-  EXTENDED_ASSERT_TRUE(bf::exists(shared_path));
-
-  bf::path manifest_path =
-      bf::path(getUserManifestPath(params.test_user.uid,
+  fs::path package_path = root_path / pkgid;
+  fs::path shared_path = package_path / "shared";
+  EXTENDED_ASSERT_TRUE(fs::exists(root_path));
+  EXTENDED_ASSERT_TRUE(fs::exists(package_path));
+  EXTENDED_ASSERT_TRUE(fs::exists(shared_path));
+
+  fs::path manifest_path =
+      fs::path(getUserManifestPath(params.test_user.uid,
           params.is_readonly)) / (pkgid + ".xml");
-  EXTENDED_ASSERT_TRUE(bf::exists(manifest_path));
+  EXTENDED_ASSERT_TRUE(fs::exists(manifest_path));
 
   for (auto& app : apps) {
     const std::string &exec = app.second;
-    bf::path binary_path = package_path / "bin" / exec;
-    EXTENDED_ASSERT_TRUE(bf::exists(binary_path));
+    fs::path binary_path = package_path / "bin" / exec;
+    EXTENDED_ASSERT_TRUE(fs::exists(binary_path));
   }
 
   if (params.pkg_type == PackageType::WGT ||
       params.pkg_type == PackageType::HYBRID) {
-    bf::path widget_root_path = package_path / "res" / "wgt";
-    bf::path config_path = widget_root_path / "config.xml";
-    EXTENDED_ASSERT_TRUE(bf::exists(widget_root_path));
-    EXTENDED_ASSERT_TRUE(bf::exists(config_path));
+    fs::path widget_root_path = package_path / "res" / "wgt";
+    fs::path config_path = widget_root_path / "config.xml";
+    EXTENDED_ASSERT_TRUE(fs::exists(widget_root_path));
+    EXTENDED_ASSERT_TRUE(fs::exists(config_path));
 
-    bf::path private_tmp_path = package_path / "tmp";
-    EXTENDED_ASSERT_TRUE(bf::exists(private_tmp_path));
+    fs::path private_tmp_path = package_path / "tmp";
+    EXTENDED_ASSERT_TRUE(fs::exists(private_tmp_path));
   }
 
   // backups should not exist
-  bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
-  bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
-  EXTENDED_ASSERT_FALSE(bf::exists(package_backup));
-  EXTENDED_ASSERT_FALSE(bf::exists(manifest_backup));
-
-  for (bf::recursive_directory_iterator iter(package_path);
-      iter != bf::recursive_directory_iterator(); ++iter) {
-    if (bf::is_symlink(symlink_status(iter->path())))
+  fs::path package_backup = ci::GetBackupPathForPackagePath(package_path);
+  fs::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
+  EXTENDED_ASSERT_FALSE(fs::exists(package_backup));
+  EXTENDED_ASSERT_FALSE(fs::exists(manifest_backup));
+
+  for (fs::recursive_directory_iterator iter(package_path);
+      iter != fs::recursive_directory_iterator(); ++iter) {
+    if (fs::is_symlink(symlink_status(iter->path())))
       continue;
     bool is_rw_dir = false;
     for (const auto rw_dir : rwDirectories) {
-      bf::path rw_dir_path = rw_dir;
+      fs::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") {
-      iter.no_push();
+      iter.disable_recursion_pending();
       continue;
     }
     struct stat stats;
@@ -377,13 +409,13 @@ bool ValidateDataFiles(const std::string& pkgid, uid_t uid) {
     ci::UserList list = ci::GetUserList();
     for (auto l : list) {
       auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l));
-      EXTENDED_ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt"));
-      EXTENDED_ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt"));
+      EXTENDED_ASSERT_TRUE(fs::exists(pkg_path / "data" / "file1.txt"));
+      EXTENDED_ASSERT_TRUE(fs::exists(pkg_path / "data" / "file2.txt"));
     }
   } else {
     auto pkg_path = GetPackageRoot(pkgid, uid);
-    EXTENDED_ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt"));
-    EXTENDED_ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt"));
+    EXTENDED_ASSERT_TRUE(fs::exists(pkg_path / "data" / "file1.txt"));
+    EXTENDED_ASSERT_TRUE(fs::exists(pkg_path / "data" / "file2.txt"));
   }
   return true;
 }
@@ -392,12 +424,12 @@ static bool ValidateExternalPackageFS(const std::string& pkgid,
     const Apps& apps, const TestParameters& params) {
   EXTENDED_ASSERT_EQ(app2ext_usr_enable_external_pkg(pkgid.c_str(),
       params.test_user.uid), 0);
-  bf::path root_path = ci::GetRootAppPath(false, params.test_user.uid);
+  fs::path root_path = ci::GetRootAppPath(false, params.test_user.uid);
   if (params.pkg_type == PackageType::TPK) {
-    EXTENDED_ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "bin"));
-    EXTENDED_ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "lib"));
+    EXTENDED_ASSERT_TRUE(fs::exists(root_path / pkgid / ".mmc" / "bin"));
+    EXTENDED_ASSERT_TRUE(fs::exists(root_path / pkgid / ".mmc" / "lib"));
   }
-  EXTENDED_ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "res"));
+  EXTENDED_ASSERT_TRUE(fs::exists(root_path / pkgid / ".mmc" / "res"));
   EXTENDED_ASSERT_TRUE(ValidatePackageFS(pkgid, apps, params));
   EXTENDED_ASSERT_EQ(app2ext_usr_disable_external_pkg(pkgid.c_str(),
       params.test_user.uid), 0);
@@ -408,8 +440,8 @@ bool ValidateExternalPackage(const std::string& pkgid, const Apps& apps,
     const TestParameters& params) {
   ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid, true);
   std::string storage = pkg_query.StorageForPkgId();
-  bf::path ext_mount_path = ci::GetExternalCardPath();
-  if (bf::is_empty(ext_mount_path)) {
+  fs::path ext_mount_path = ci::GetExternalCardPath();
+  if (fs::is_empty(ext_mount_path)) {
     LOG(INFO) << "Sdcard not exists!";
     EXTENDED_ASSERT_EQ(storage, "installed_internal");
   } else {
@@ -423,9 +455,9 @@ bool ValidateExtendedPackage(const std::string& pkgid, const Apps& apps,
     const TestParameters& params) {
   ci::PkgQueryInterface pkg_query(pkgid, params.test_user.uid, true);
   std::string storage = pkg_query.StorageForPkgId();
-  bf::path extended_path =
-      bf::path(ci::GetExtendedRootAppPath(params.test_user.uid)) / pkgid;
-  if (!bf::exists(extended_path)) {
+  fs::path extended_path =
+      fs::path(ci::GetExtendedRootAppPath(params.test_user.uid)) / pkgid;
+  if (!fs::exists(extended_path)) {
     LOG(INFO) << "Extended storage not exists!";
     EXTENDED_ASSERT_EQ(storage, "installed_internal");
   } else {
@@ -437,20 +469,20 @@ bool ValidateExtendedPackage(const std::string& pkgid, const Apps& apps,
 
 static bool PackageCheckCleanup(const std::string& pkgid,
     const TestParameters& params) {
-  bf::path root_path = ci::GetRootAppPath(params.is_readonly,
+  fs::path root_path = ci::GetRootAppPath(params.is_readonly,
                                           params.test_user.uid);
-  bf::path package_path = root_path / pkgid;
-  EXTENDED_ASSERT_FALSE(bf::exists(package_path));
+  fs::path package_path = root_path / pkgid;
+  EXTENDED_ASSERT_FALSE(fs::exists(package_path));
 
-  bf::path manifest_path = bf::path(getUserManifestPath(params.test_user.uid,
+  fs::path manifest_path = fs::path(getUserManifestPath(params.test_user.uid,
       params.is_readonly)) / (pkgid + ".xml");
-  EXTENDED_ASSERT_FALSE(bf::exists(manifest_path));
+  EXTENDED_ASSERT_FALSE(fs::exists(manifest_path));
 
   // backups should not exist
-  bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
-  bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
-  EXTENDED_ASSERT_FALSE(bf::exists(package_backup));
-  EXTENDED_ASSERT_FALSE(bf::exists(manifest_backup));
+  fs::path package_backup = ci::GetBackupPathForPackagePath(package_path);
+  fs::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
+  EXTENDED_ASSERT_FALSE(fs::exists(package_backup));
+  EXTENDED_ASSERT_FALSE(fs::exists(manifest_backup));
   return true;
 }
 
@@ -461,24 +493,24 @@ bool CheckPackageNonExistance(const std::string& pkgid,
       ci::GetRequestMode(params.test_user.uid)));
   EXTENDED_ASSERT_TRUE(PackageCheckCleanup(pkgid, params));
   if (params.test_user.uid == kGlobalUserUid) {
-    bf::path skel_path(kSkelDir);
-    EXTENDED_ASSERT_FALSE(bf::exists(skel_path / pkgid));
-    EXTENDED_ASSERT_FALSE(bf::exists(skel_path / kShared / pkgid));
-    EXTENDED_ASSERT_FALSE(bf::exists(skel_path / kSharedTmp / pkgid));
+    fs::path skel_path(kSkelDir);
+    EXTENDED_ASSERT_FALSE(fs::exists(skel_path / pkgid));
+    EXTENDED_ASSERT_FALSE(fs::exists(skel_path / kShared / pkgid));
+    EXTENDED_ASSERT_FALSE(fs::exists(skel_path / kSharedTmp / pkgid));
     ci::UserList list = ci::GetUserList();
     for (auto& l : list) {
-      bf::path root_path = ci::GetRootAppPath(false, std::get<0>(l));
-      EXTENDED_ASSERT_FALSE(bf::exists(root_path / kShared / pkgid));
-      EXTENDED_ASSERT_FALSE(bf::exists(root_path / kSharedTmp / pkgid));
-      bf::path package_path = root_path / pkgid;
-      EXTENDED_ASSERT_FALSE(bf::exists(package_path));
+      fs::path root_path = ci::GetRootAppPath(false, std::get<0>(l));
+      EXTENDED_ASSERT_FALSE(fs::exists(root_path / kShared / pkgid));
+      EXTENDED_ASSERT_FALSE(fs::exists(root_path / kSharedTmp / pkgid));
+      fs::path package_path = root_path / pkgid;
+      EXTENDED_ASSERT_FALSE(fs::exists(package_path));
     }
   }
   return true;
 }
 
 bool CheckAvailableExternalPath() {
-  bf::path ext_mount_path = ci::GetExternalCardPath();
+  fs::path ext_mount_path = ci::GetExternalCardPath();
   LOG(DEBUG) << "ext_mount_path :" << ext_mount_path;
   if (ext_mount_path.empty()) {
     LOG(ERROR) << "Sdcard not exists!";
@@ -488,10 +520,10 @@ bool CheckAvailableExternalPath() {
 }
 
 bool CheckAvailableExtendedPath() {
-  bf::path extended_path = bf::path(tzplatform_getenv(TZ_SYS_EXTENDEDSD));
+  fs::path extended_path = fs::path(tzplatform_getenv(TZ_SYS_EXTENDEDSD));
   LOG(DEBUG) << "extended_path :" << extended_path;
   // TODO(jeremy.jang): It should be checked by libstorage API.
-  if (!bf::exists(extended_path)) {
+  if (!fs::exists(extended_path)) {
     LOG(ERROR) << "Extended storage not exists!";
     return false;
   }
@@ -507,24 +539,24 @@ bool CheckPackageReadonlyNonExistance(const std::string& pkgid,
   return true;
 }
 
-static bool CheckSharedDataExistanceForPath(const bf::path& apps_rw,
+static bool CheckSharedDataExistanceForPath(const fs::path& apps_rw,
     const std::string& pkgid) {
-  bf::path shared_data_path = apps_rw / pkgid / rwDirectories[SHARED_DATA];
-  bf::path shared = apps_rw / kShared / pkgid / kData;
-  bf::path shared_tmp = apps_rw / kSharedTmp / pkgid;
-  EXTENDED_ASSERT_TRUE(bf::exists(shared_data_path));
-  EXTENDED_ASSERT_TRUE(bf::exists(shared));
-  EXTENDED_ASSERT_TRUE(bf::exists(shared_tmp));
+  fs::path shared_data_path = apps_rw / pkgid / rwDirectories[SHARED_DATA];
+  fs::path shared = apps_rw / kShared / pkgid / kData;
+  fs::path shared_tmp = apps_rw / kSharedTmp / pkgid;
+  EXTENDED_ASSERT_TRUE(fs::exists(shared_data_path));
+  EXTENDED_ASSERT_TRUE(fs::exists(shared));
+  EXTENDED_ASSERT_TRUE(fs::exists(shared_tmp));
   return true;
 }
 
-static bool CheckSharedDataPermissions(const bf::path& apps_rw,
+static bool CheckSharedDataPermissions(const fs::path& apps_rw,
     const std::string& pkgid, uid_t uid) {
-  bf::path shared_data_path = apps_rw / pkgid / rwDirectories[SHARED_DATA];
-  bf::path shared = apps_rw / kShared / pkgid / kData;
-  bf::path shared_tmp = apps_rw / kSharedTmp / pkgid;
+  fs::path shared_data_path = apps_rw / pkgid / rwDirectories[SHARED_DATA];
+  fs::path shared = apps_rw / kShared / pkgid / kData;
+  fs::path shared_tmp = apps_rw / kSharedTmp / pkgid;
   // gid of RW dirs should be system_share
-  boost::optional<gid_t> system_share =
+  std::optional<gid_t> system_share =
       ci::GetGidByGroupName(kSystemShareGroupName);
   struct stat stats;
   stat(shared_data_path.c_str(), &stats);
@@ -542,17 +574,17 @@ static bool CheckSharedDataPermissions(const bf::path& apps_rw,
 bool CheckSharedDataExistance(const std::string& pkgid,
     const TestParameters& params) {
   if (params.test_user.uid == kGlobalUserUid) {
-    bf::path skel_path(kSkelDir);
+    fs::path skel_path(kSkelDir);
     EXTENDED_ASSERT_TRUE(CheckSharedDataExistanceForPath(kSkelDir, pkgid));
     ci::UserList list = ci::GetUserList();
     for (auto& l : list) {
       uid_t uid = std::get<0>(l);
-      bf::path apps_rw = ci::GetRootAppPath(false, uid);
+      fs::path apps_rw = ci::GetRootAppPath(false, uid);
       EXTENDED_ASSERT_TRUE(CheckSharedDataExistanceForPath(apps_rw, pkgid));
       EXTENDED_ASSERT_TRUE(CheckSharedDataPermissions(apps_rw, pkgid, uid));
     }
   } else {
-    bf::path apps_rw = ci::GetRootAppPath(false, params.test_user.uid);
+    fs::path apps_rw = ci::GetRootAppPath(false, params.test_user.uid);
     EXTENDED_ASSERT_TRUE(CheckSharedDataExistanceForPath(apps_rw, pkgid));
     EXTENDED_ASSERT_TRUE(
         CheckSharedDataPermissions(apps_rw, pkgid, params.test_user.uid));
@@ -560,111 +592,415 @@ bool CheckSharedDataExistance(const std::string& pkgid,
   return true;
 }
 
-static bool CheckSharedDataNonExistanceForPath(const bf::path& apps_rw,
+static bool CheckSharedDataNonExistanceForPath(const fs::path& apps_rw,
     const std::string pkgid) {
-  bf::path shared_data_path = apps_rw / pkgid / rwDirectories[SHARED_DATA];
-  bf::path shared = apps_rw / kShared / pkgid / kData;
-  bf::path shared_tmp = apps_rw / kSharedTmp / pkgid;
-  EXTENDED_ASSERT_FALSE(bf::exists(shared_data_path));
-  EXTENDED_ASSERT_FALSE(bf::exists(shared));
-  EXTENDED_ASSERT_FALSE(bf::exists(shared_tmp));
+  fs::path shared_data_path = apps_rw / pkgid / rwDirectories[SHARED_DATA];
+  fs::path shared = apps_rw / kShared / pkgid / kData;
+  fs::path shared_tmp = apps_rw / kSharedTmp / pkgid;
+  EXTENDED_ASSERT_FALSE(fs::exists(shared_data_path));
+  EXTENDED_ASSERT_FALSE(fs::exists(shared));
+  EXTENDED_ASSERT_FALSE(fs::exists(shared_tmp));
   return true;
 }
 
 bool CheckSharedDataNonExistance(const std::string& pkgid,
     const TestParameters& params) {
   if (params.test_user.uid == kGlobalUserUid) {
-    bf::path skel_path(kSkelDir);
+    fs::path skel_path(kSkelDir);
     EXTENDED_ASSERT_TRUE(
         CheckSharedDataNonExistanceForPath(skel_path, pkgid));
 
     ci::UserList list = ci::GetUserList();
     for (auto& l : list) {
       uid_t uid = std::get<0>(l);
-      bf::path apps_rw = ci::GetRootAppPath(false, uid);
+      fs::path apps_rw = ci::GetRootAppPath(false, uid);
       EXTENDED_ASSERT_TRUE(CheckSharedDataNonExistanceForPath(apps_rw, pkgid));
     }
   } else {
-    bf::path apps_rw = ci::GetRootAppPath(false, params.test_user.uid);
+    fs::path apps_rw = ci::GetRootAppPath(false, params.test_user.uid);
     EXTENDED_ASSERT_TRUE(CheckSharedDataNonExistanceForPath(apps_rw, pkgid));
   }
   return true;
 }
 
-void BackendInterface::TestRollbackAfterEachStep(int argc, const char* argv[],
-    std::function<bool()> validator) const {
-  TestPkgmgrInstaller pkgmgr_installer;
-  std::shared_ptr<ci::AppQueryInterface> query_interface =
-      CreateQueryInterface();
-  auto pkgmgr =
-      ci::PkgMgrInterface::Create(argc, const_cast<char**>(argv),
-                                  &pkgmgr_installer,
-                                  query_interface);
-  if (!pkgmgr) {
-    LOG(ERROR) << "Failed to initialize pkgmgr interface";
-    return;
+void FileInfoCollector::AddPath(const fs::path& path) {
+  root_paths_.emplace_back(path);
+}
+
+bool FileInfoCollector::CollectFileInfoRecursive() {
+  for (const auto& path : root_paths_) {
+    if (!fs::exists(path) && !fs::is_symlink(path))
+      continue;
+
+    if (!GetFileListTraversal(path))
+      return false;
   }
-  AppInstallerPtr backend;
-  unsigned int insert_idx = 0;
-  do {
-    backend = CreateFailExpectedInstaller(pkgmgr, insert_idx);
-    LOG(DEBUG) << "StepFail is inserted at: " << insert_idx;
-    ASSERT_EQ(ci::AppInstaller::Result::ERROR, backend->Run());
-    if (!validator())
-      break;
-    insert_idx++;
-  } while (insert_idx < backend->StepCount());
-  ASSERT_EQ(insert_idx, backend->StepCount());
+
+  return true;
 }
 
-void BackendInterface::CrashAfterEachStep(std::vector<std::string>* args,
-    std::function<bool(int iter)> validator, PackageType type) const {
-  std::unique_ptr<const char*[]> argv(new const char*[args->size()]);
-  for (size_t i = 0; i < args->size(); ++i) {
-    argv[i] = args->at(i).c_str();
+bool FileInfoCollector::GetFileListTraversal(const fs::path& cur) {
+  std::error_code error;
+  fs::file_status file_status = fs::symlink_status(cur, error);
+  if (error) {
+    LOG(ERROR) << "Fail to get symlink_status, " << error.message();
+    return false;
   }
-  TestPkgmgrInstaller pkgmgr_installer;
-  auto query_interface = CreateQueryInterface();
-  auto pkgmgr =
-      ci::PkgMgrInterface::Create(args->size(), const_cast<char**>(argv.get()),
-                                  &pkgmgr_installer,
-                                  query_interface);
-  if (!pkgmgr) {
-    LOG(ERROR) << "Failed to initialize pkgmgr interface";
-    return;
+
+  struct stat info;
+  if (lstat(cur.c_str(), &info) != 0) {
+    LOG(ERROR) << "Fail to lstat from [" << cur << "]";
+    return false;
   }
-  auto backend = CreateFailExpectedInstaller(pkgmgr, 0);
-  ASSERT_EQ(backend->Run(), ci::AppInstaller::Result::ERROR);
-  int stepCount = backend->StepCount();
-
-  args->push_back("-idx");
-  args->push_back(std::to_string(stepCount));
-  int i;
-  std::string prefix = (type == PackageType::TPK) ? "tpk" : "wgt";
-  for (i = 0; i < stepCount; i++) {
-    ci::Subprocess backend_crash(
-        "/usr/bin/" + prefix + "-installer-ut/smoke-test-helper");
-    args->back() = std::to_string(i);
-    backend_crash.Run(*args);
-    ASSERT_NE(backend_crash.Wait(), 0);
-    if (!validator(i))
-      break;
+
+  std::string owner = ci::GetUsernameByUid(info.st_uid);
+  std::string group = ci::GetGroupNameByGid(info.st_gid);
+
+  char* access_label = nullptr;
+  if (smack_lgetlabel(cur.c_str(), &access_label, SMACK_LABEL_ACCESS) < 0) {
+    LOG(ERROR) << "Fail to get access label from [" << cur << "]";
+    return false;
   }
-  ASSERT_EQ(stepCount, i);
-
-  args->push_back("-type_clean");
-  for (i = stepCount - 1; i >= 2; i--) {
-    ci::Subprocess backend_crash(
-        "/usr/bin/" + prefix + "-installer-ut/smoke-test-helper");
-    auto it = args->end();
-    it -= 2;
-    *it = std::to_string(i);
-    backend_crash.Run(*args);
-    ASSERT_NE(backend_crash.Wait(), 0);
-    if (!validator(i))
-      break;
+
+  if (access_label == nullptr) {
+    LOG(ERROR) << "Fail to get access label from [" << cur << "]";
+    return false;
+  }
+
+  FileInfos_.emplace_back(cur, file_status.type(),
+      file_status.permissions(), owner, group, access_label);
+
+  if (!fs::is_directory(cur) || fs::is_symlink(cur))
+    return true;
+
+  for (fs::directory_iterator file(cur);
+      file != fs::directory_iterator();
+      ++file) {
+    if (!GetFileListTraversal(file->path())) {
+      FileInfos_.clear();
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool FileInfoCollector::FileInfoToFile(const fs::path& path) const {
+  std::ofstream out(path.string());
+
+  for (const auto& info : FileInfos_)
+    out << FileInfoToString(info) << std::endl;
+
+  out.close();
+
+  return true;
+}
+
+bool FileInfoCollector::Init() {
+  fs::path skel_apps_rw = fs::path(kSkelDir);
+  fs::path root_path =
+      ci::GetRootAppPath(params_.is_readonly, params_.test_user.uid);
+
+  AddPath(root_path / pkgid_);
+  AddPath(skel_apps_rw / pkgid_);
+
+  if (params_.test_user.uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)) {
+    // per user dir
+    ci::UserList list = ci::GetUserList();
+    for (auto l : list) {
+      fs::path apps_rw = std::get<2>(l) / "apps_rw";
+      AddPath(apps_rw / pkgid_);
+      AddPath(apps_rw / kShared / pkgid_);
+      AddPath(apps_rw / kSharedTmp / pkgid_);
+    }
+  } else {
+    AddPath(root_path / kShared / pkgid_);
+    AddPath(root_path / kSharedTmp / pkgid_);
+  }
+
+  if (!CollectFileInfoRecursive())
+    return false;
+
+  std::sort(FileInfos_.begin(), FileInfos_.end(),
+      [](const FileInfo& l, const FileInfo& r) -> bool {
+        return std::get<0>(l) < std::get<0>(r);
+      });
+
+  return true;
+}
+
+bool FileInfoCollector::LoadFromFile(const fs::path& path) {
+  std::ifstream readFile;
+  readFile.open(path.c_str());
+
+  if (!readFile.is_open()) {
+    LOG(ERROR) << "Fail to read file : " << path;
+    return false;
+  }
+
+  std::string line;
+
+  while (std::getline(readFile, line)) {
+    std::istringstream iss(line);
+    fs::path p;
+    int file_permission;
+    int file_type;
+    std::string owner;
+    std::string group;
+    std::string access_label;
+
+    iss >> p >> file_type >> std::oct >> file_permission
+        >> owner >> group >> access_label;
+
+    FileInfos_.emplace_back(p, fs::file_type(file_type),
+        fs::perms(file_permission), owner, group, access_label);
+  }
+
+  readFile.close();
+
+  return true;
+}
+
+std::string FileInfoCollector::FileTypeToString(const fs::file_type type) const {
+  switch (type) {
+    case fs::file_type::none:
+      return "none";
+    case fs::file_type::not_found:
+      return "not_found";
+    case fs::file_type::regular:
+      return "regular";
+    case fs::file_type::directory:
+      return "directory";
+    case fs::file_type::symlink:
+      return "symlink";
+    case fs::file_type::block:
+      return "block";
+    case fs::file_type::character:
+      return "character";
+    case fs::file_type::fifo:
+      return "fifo";
+    case fs::file_type::socket:
+      return "socket";
+    case fs::file_type::unknown:
+      return "unknown";
+    default:
+      return "implementation-defined";
+  }
+}
+
+int FileInfoCollector::PermsToInt(const fs::perms p) const {
+  int perm_int = 0;
+
+  perm_int |= fs::perms::none == (p & fs::perms::owner_read) ? 0 : 0400;
+  perm_int |= fs::perms::none == (p & fs::perms::owner_write) ? 0 : 0200;
+  perm_int |= fs::perms::none == (p & fs::perms::owner_exec) ? 0 :  0100;
+  perm_int |= fs::perms::none == (p & fs::perms::group_read) ? 0 : 040;
+  perm_int |= fs::perms::none == (p & fs::perms::group_write) ? 0 : 020;
+  perm_int |= fs::perms::none == (p & fs::perms::group_exec) ? 0 : 010;
+  perm_int |= fs::perms::none == (p & fs::perms::others_read) ? 0 :  04;
+  perm_int |= fs::perms::none == (p & fs::perms::others_write) ? 0 : 02;
+  perm_int |= fs::perms::none == (p & fs::perms::others_exec) ? 0 : 01;
+
+  return perm_int;
+}
+
+std::string FileInfoCollector::FileInfoToString(
+    const FileInfo& file_info) const {
+  fs::path p = std::get<0>(file_info);
+  fs::file_type file_type = std::get<1>(file_info);
+  std::string file_permission;
+  std::string owner = std::get<3>(file_info);
+  std::string group = std::get<4>(file_info);
+  std::string access_label = std::get<5>(file_info);
+  std::stringstream ss;
+  ss << std::oct << PermsToInt(std::get<2>(file_info));
+  ss >> file_permission;
+
+  std::string res;
+  res += p.string();
+  res += " ";
+  res += FileTypeToString(file_type);
+  res += " ";
+  res += file_permission;
+  res += " ";
+  res += owner;
+  res += " ";
+  res += group;
+  res += " ";
+  res += access_label;
+
+  return res;
+}
+
+bool FileInfoCollector::IsEqual(const FileInfoCollector& that,
+    const std::vector<fs::path>* exception_list) const {
+  auto it_l = FileInfos_.begin();
+  auto it_r = that.FileInfos_.begin();
+  bool res = true;
+
+  while (it_l != FileInfos_.end() && it_r != that.FileInfos_.end()) {
+    if (*it_l == *it_r) {
+      it_l++;
+      it_r++;
+      continue;
+    }
+
+    fs::path path_l = std::get<0>(*it_l);
+    fs::path path_r = std::get<0>(*it_r);
+    if (exception_list && path_l == path_r &&
+        std::find(exception_list->begin(), exception_list->end(), path_r)
+            != exception_list->end()) {
+      it_l++;
+      it_r++;
+      continue;
+    }
+
+    res = false;
+
+    if (path_l > path_r) {
+      LOG(ERROR) << "There is an unexpected file [" << path_r << "]";
+      it_r++;
+    } else if (path_l < path_r) {
+      LOG(ERROR) << "There is not exists an expected file [" << path_l << "]";
+      it_l++;
+    } else {
+      LOG(ERROR) << "There is a different status file. expected ["
+          << FileInfoToString(*it_l) << "], result ["
+          << FileInfoToString(*it_r) << "]";
+      it_l++;
+      it_r++;
+    }
+  }
+
+  while (it_l != FileInfos_.end()) {
+    LOG(ERROR) << "There is an unexpected file [" << std::get<0>(*it_l) << "]";
+    it_l++;
+    res = false;
+  }
+
+  while (it_r != that.FileInfos_.end()) {
+    LOG(ERROR) << "There is not exists an expected file ["
+        << std::get<0>(*it_r) << "]";
+    it_r++;
+    res = false;
   }
-  ASSERT_EQ(i , 1);
+
+  return res;
+}
+
+void BackendInterface::TestRollbackAfterEachStep(int argc, const char* argv[],
+    std::function<bool()> validator) const {
+  ci::Subprocess backend_helper = CreateSubprocess();
+  bool result = backend_helper.RunFunc({[&]() -> int {
+    TestPkgmgrInstaller pkgmgr_installer;
+    std::shared_ptr<ci::AppQueryInterface> query_interface =
+        CreateQueryInterface();
+    auto pkgmgr =
+        ci::PkgMgrInterface::Create(argc, const_cast<char**>(argv),
+                                    &pkgmgr_installer,
+                                    query_interface);
+    if (!pkgmgr) {
+      LOG(ERROR) << "Failed to initialize pkgmgr interface";
+      return 1;
+    }
+    AppInstallerPtr backend;
+    unsigned int insert_idx = 0;
+    do {
+      backend = CreateFailExpectedInstaller(pkgmgr, insert_idx);
+      LOG(DEBUG) << "StepFail is inserted at: " << insert_idx;
+      ci::AppInstaller::Result ret = backend->Run();
+      if (ret != ci::AppInstaller::Result::ERROR) {
+        LOG(ERROR) << "StepFail not executed";
+        return 1;
+      }
+      if (!validator()) {
+        LOG(ERROR) << "Fail to validate. index of StepFail : " << insert_idx;
+        break;
+      }
+      insert_idx++;
+    } while (insert_idx < backend->StepCount());
+    if (insert_idx != backend->StepCount())
+      return 1;
+
+    return 0;
+  }});
+  ASSERT_EQ(result, true);
+  int status = backend_helper.Wait();
+  ASSERT_NE(WIFEXITED(status), 0);
+  ASSERT_EQ(WEXITSTATUS(status), 0);
+}
+
+void BackendInterface::CrashAfterEachStep(std::vector<std::string>* args,
+    std::function<bool(int iter)> validator, PackageType type) const {
+  ci::Subprocess backend_helper = CreateSubprocess();
+  bool result = backend_helper.RunFunc({[&]() {
+    std::unique_ptr<const char*[]> argv(new const char*[args->size()]);
+    for (size_t i = 0; i < args->size(); ++i) {
+      argv[i] = args->at(i).c_str();
+    }
+    TestPkgmgrInstaller pkgmgr_installer;
+    auto query_interface = CreateQueryInterface();
+    auto pkgmgr = ci::PkgMgrInterface::Create(args->size(),
+        const_cast<char**>(argv.get()), &pkgmgr_installer, query_interface);
+    if (!pkgmgr) {
+      LOG(ERROR) << "Failed to initialize pkgmgr interface";
+      return 1;
+    }
+    auto backend = CreateFailExpectedInstaller(pkgmgr, 0);
+    if (backend->Run() != ci::AppInstaller::Result::ERROR) {
+      LOG(ERROR) << "StepFail not executed";
+      return 1;
+    }
+    int stepCount = backend->StepCount();
+
+    args->push_back("-idx");
+    args->push_back(std::to_string(stepCount));
+    int insert_idx;
+    std::string prefix = (type == PackageType::TPK) ? "tpk" : "wgt";
+    for (insert_idx = 0; insert_idx < stepCount; insert_idx++) {
+      ci::Subprocess backend_crash(
+          "/usr/bin/" + prefix + "-installer-ut/smoke-test-helper");
+      args->back() = std::to_string(insert_idx);
+      backend_crash.Run(*args);
+      if (backend_crash.Wait() == 0) {
+        LOG(ERROR) << "Subprocess exit without crash";
+        return 1;
+      }
+      if (!validator(insert_idx)) {
+        LOG(ERROR) << "Fail to validate. index of StepCrash : " << insert_idx;
+        break;
+      }
+    }
+    if (stepCount != insert_idx)
+      return 1;
+
+    args->push_back("-type_clean");
+    for (insert_idx = stepCount - 1; insert_idx >= 2; insert_idx--) {
+      ci::Subprocess backend_crash(
+          "/usr/bin/" + prefix + "-installer-ut/smoke-test-helper");
+      auto it = args->end();
+      it -= 2;
+      *it = std::to_string(insert_idx);
+      backend_crash.Run(*args);
+      if (backend_crash.Wait() == 0) {
+        LOG(ERROR) << "Subprocess exit without crash";
+        return 1;
+      }
+      if (!validator(insert_idx)) {
+        LOG(ERROR) << "Fail to validate. index of StepCrash : " << insert_idx;
+        break;
+      }
+    }
+    if (insert_idx != 1)
+      return 1;
+
+    return 0;
+  }});
+
+  ASSERT_EQ(result, true);
+  int status = backend_helper.Wait();
+  ASSERT_NE(WIFEXITED(status), 0);
+  ASSERT_EQ(WEXITSTATUS(status), 0);
 }
 
 BackendInterface::CommandResult BackendInterface::RunInstallersWithPkgmgr(
@@ -719,12 +1055,12 @@ BackendInterface::CommandResult BackendInterface::CallBackendWithRunner(
 }
 
 BackendInterface::CommandResult BackendInterface::Install(
-    const std::vector<bf::path>& paths) const {
+    const std::vector<fs::path>& paths) const {
   std::vector<const char*> argv;
   argv.emplace_back("");
   argv.emplace_back("-i");
   for (const auto& p : paths)
-    argv.emplace_back(p.string().c_str());
+    argv.emplace_back(p.c_str());
   return CallBackendWithRunner(argv.size(), argv.data());
 }
 
@@ -739,7 +1075,7 @@ BackendInterface::CommandResult BackendInterface::Uninstall(
 }
 
 BackendInterface::CommandResult BackendInterface::InstallSuccess(
-    const std::vector<bf::path>& paths) const {
+    const std::vector<fs::path>& paths) const {
   RequestResult tmp_mode = mode_;
   RequestResult &original_mode = const_cast<RequestResult&>(mode_);
   original_mode = RequestResult::NORMAL;
@@ -779,19 +1115,19 @@ BackendInterface::CommandResult BackendInterface::CallBackend(int argc,
 }
 
 BackendInterface::CommandResult BackendInterface::Install(
-    const bf::path& path) const {
+    const fs::path& path) const {
   const char* argv[] = {"", "-i", path.c_str(), "-u", uid_str_.c_str()};
   return CallBackend(SIZEOFARRAY(argv), argv);
 }
 
 BackendInterface::CommandResult BackendInterface::InstallPreload(
-    const bf::path& path) const {
+    const fs::path& path) const {
   const char* argv[] = {"", "-i", path.c_str(), "--preload"};
   return CallBackend(SIZEOFARRAY(argv), argv);
 }
 
 BackendInterface::CommandResult BackendInterface::InstallWithStorage(
-    const bf::path& path, StorageType type) const {
+    const fs::path& path, StorageType type) const {
   int default_storage = 0;
   int storage = 0;
   switch (type) {
@@ -833,20 +1169,20 @@ BackendInterface::CommandResult BackendInterface::InstallWithStorage(
 
 BackendInterface::CommandResult BackendInterface::MigrateLegacyExternalImage(
     const std::string& pkgid,
-    const bf::path& path,
-    const bf::path& legacy_path) const {
+    const fs::path& path,
+    const fs::path& legacy_path) const {
   if (InstallWithStorage(path, StorageType::EXTERNAL) !=
       BackendInterface::CommandResult::OK) {
     LOG(ERROR) << "Failed to install application. Cannot perform Migrate";
     return BackendInterface::CommandResult::ERROR;
   }
 
-  bf::path ext_mount_path = ci::GetExternalCardPath();
-  if (bf::is_empty(ext_mount_path)) {
+  fs::path ext_mount_path = ci::GetExternalCardPath();
+  if (fs::is_empty(ext_mount_path)) {
     LOG(ERROR) << "Sdcard not exists!";
     return BackendInterface::CommandResult::ERROR;
   }
-  bf::path app2sd_path = ext_mount_path / "app2sd";
+  fs::path app2sd_path = ext_mount_path / "app2sd";
 
   char* image_name = app2ext_usr_getname_image(pkgid.c_str(),
                      kGlobalUserUid);
@@ -854,38 +1190,38 @@ BackendInterface::CommandResult BackendInterface::MigrateLegacyExternalImage(
     LOG(ERROR) << "Failed to get external image name";
     return BackendInterface::CommandResult::ERROR;
   }
-  bf::path org_image = app2sd_path / image_name;
+  fs::path org_image = app2sd_path / image_name;
   free(image_name);
 
-  bs::error_code error;
-  bf::remove(org_image, error);
+  std::error_code error;
+  fs::remove(org_image, error);
   if (error) {
     LOG(ERROR) << "Failed to remove org image";
     return BackendInterface::CommandResult::ERROR;
   }
 
-  bf::path db_path = tzplatform_getenv(TZ_SYS_DB);
-  bf::path app2sd_db = db_path / ".app2sd.db";
-  bf::path app2sd_db_journal = db_path / ".app2sd.db-journal";
-  bf::remove(app2sd_db, error);
+  fs::path db_path = tzplatform_getenv(TZ_SYS_DB);
+  fs::path app2sd_db = db_path / ".app2sd.db";
+  fs::path app2sd_db_journal = db_path / ".app2sd.db-journal";
+  fs::remove(app2sd_db, error);
   if (error) {
     LOG(ERROR) << "Failed to remove app2sd db";
     return BackendInterface::CommandResult::ERROR;
   }
-  bf::remove(app2sd_db_journal, error);
+  fs::remove(app2sd_db_journal, error);
   if (error) {
     LOG(ERROR) << "Failed to remove app2sd journal db";
     return BackendInterface::CommandResult::ERROR;
   }
 
-  bf::path app2sd_migrate_db = legacy_path / kMigrateTestDBName;
+  fs::path app2sd_migrate_db = legacy_path / kMigrateTestDBName;
   if (!ci::CopyFile(app2sd_migrate_db, app2sd_db)) {
     LOG(ERROR) << "Failed to copy test db";
     return BackendInterface::CommandResult::ERROR;
   }
 
-  bf::path legacy_src = legacy_path / pkgid;
-  bf::path legacy_dst = app2sd_path / pkgid;
+  fs::path legacy_src = legacy_path / pkgid;
+  fs::path legacy_dst = app2sd_path / pkgid;
   if (!ci::CopyFile(legacy_src, legacy_dst)) {
     LOG(ERROR) << "Failed to copy test image";
     return BackendInterface::CommandResult::ERROR;
@@ -896,7 +1232,7 @@ BackendInterface::CommandResult BackendInterface::MigrateLegacyExternalImage(
 }
 
 BackendInterface::CommandResult BackendInterface::RDSUpdate(
-    const bf::path& path,
+    const fs::path& path,
     const std::string& pkgid) const {
   RequestResult tmp_mode = mode_;
   RequestResult &original_mode = const_cast<RequestResult&>(mode_);
@@ -924,7 +1260,7 @@ BackendInterface::CommandResult BackendInterface::DisablePackage(
 }
 
 BackendInterface::CommandResult BackendInterface::Recover(
-    const bf::path& recovery_file) const {
+    const fs::path& recovery_file) const {
   const char* argv[] = {"", "-b", recovery_file.c_str(), "-u",
       uid_str_.c_str()};
   return CallBackend(SIZEOFARRAY(argv), argv);
@@ -950,7 +1286,7 @@ BackendInterface::CommandResult BackendInterface::UninstallPreload(
 }
 
 BackendInterface::CommandResult BackendInterface::InstallSuccess(
-    const bf::path& path) const {
+    const fs::path& path) const {
   RequestResult tmp_mode = mode_;
   RequestResult &original_mode = const_cast<RequestResult&>(mode_);
   original_mode = RequestResult::NORMAL;
@@ -963,7 +1299,7 @@ BackendInterface::CommandResult BackendInterface::InstallSuccess(
 }
 
 BackendInterface::CommandResult BackendInterface::InstallPreloadSuccess(
-    const bf::path& path) const {
+    const fs::path& path) const {
   RequestResult tmp_mode = mode_;
   RequestResult &original_mode = const_cast<RequestResult&>(mode_);
   original_mode = RequestResult::NORMAL;
@@ -976,13 +1312,13 @@ BackendInterface::CommandResult BackendInterface::InstallPreloadSuccess(
 }
 
 BackendInterface::CommandResult BackendInterface::MountInstall(
-    const bf::path& path) const {
+    const fs::path& path) const {
   const char* argv[] = {"", "-w", path.c_str(), "-u", uid_str_.c_str()};
   return CallBackend(SIZEOFARRAY(argv), argv);
 }
 
 BackendInterface::CommandResult BackendInterface::MountInstallSuccess(
-    const bf::path& path) const {
+    const fs::path& path) const {
   RequestResult tmp_mode = mode_;
   RequestResult &original_mode = const_cast<RequestResult&>(mode_);
   original_mode = RequestResult::NORMAL;
@@ -994,12 +1330,12 @@ BackendInterface::CommandResult BackendInterface::MountInstallSuccess(
   return BackendInterface::CommandResult::OK;
 }
 
-static boost::filesystem::path GetTrashPath(
-    const boost::filesystem::path& path) {
+static std::filesystem::path GetTrashPath(
+    const std::filesystem::path& path) {
   return path.string() + ".trash";
 }
 
-SmokeTestHelperRunner::Result SmokeTestHelperRunner::RunSubprocess(
+BackendInterface::SubProcessResult BackendInterface::RunSubprocess(
     std::vector<std::string> args) const {
   args.push_back("-remove_plugin_steps");
   ci::Subprocess backend = CreateSubprocess();
@@ -1007,14 +1343,14 @@ SmokeTestHelperRunner::Result SmokeTestHelperRunner::RunSubprocess(
   int status = backend.Wait();
   if (WIFEXITED(status)) {
     if (WEXITSTATUS(status) == 0)
-      return SmokeTestHelperRunner::Result::SUCCESS;
+      return BackendInterface::SubProcessResult::SUCCESS;
     else
-      return SmokeTestHelperRunner::Result::FAIL;
+      return BackendInterface::SubProcessResult::FAIL;
   }
-  return SmokeTestHelperRunner::Result::UnKnown;
+  return BackendInterface::SubProcessResult::UnKnown;
 }
 
-SmokeTestHelperRunner::Result SmokeTestHelperRunner::RunSubprocessAndKill(
+BackendInterface::SubProcessResult BackendInterface::RunSubprocessAndKill(
     std::vector<std::string> args, useconds_t delay) const {
   args.push_back("-remove_plugin_steps");
   ci::Subprocess backend = CreateSubprocess();
@@ -1024,140 +1360,147 @@ SmokeTestHelperRunner::Result SmokeTestHelperRunner::RunSubprocessAndKill(
   int status = backend.Wait();
   if (WIFEXITED(status)) {
     if (WEXITSTATUS(status) == 0)
-      return SmokeTestHelperRunner::Result::SUCCESS;
+      return BackendInterface::SubProcessResult::SUCCESS;
     else
-      return SmokeTestHelperRunner::Result::FAIL;
+      return BackendInterface::SubProcessResult::FAIL;
   } else {
     if (WTERMSIG(status) == SIGKILL)
-      return SmokeTestHelperRunner::Result::KILLED;
+      return BackendInterface::SubProcessResult::KILLED;
     else
-      return SmokeTestHelperRunner::Result::UnKnown;
+      return BackendInterface::SubProcessResult::UnKnown;
   }
 }
 
-SmokeTestHelperRunner::Result SmokeTestHelperRunner::InstallWithSubprocess(
-    const bf::path& path, uid_t uid) const {
+BackendInterface::SubProcessResult BackendInterface::InstallWithSubprocess(
+    const fs::path& path) const {
   std::vector<std::string> args =
-      { "-i", path.string(), "-u", std::to_string(uid) };
+      { "-i", path.string(), "-u", uid_str_ };
   return RunSubprocess(args);
 }
 
-SmokeTestHelperRunner::Result SmokeTestHelperRunner::MountInstallWithSubprocess(
-    const bf::path& path, uid_t uid) const {
+BackendInterface::SubProcessResult BackendInterface::MountInstallWithSubprocess(
+    const fs::path& path) const {
   std::vector<std::string> args =
-      { "-w", path.string(), "-u", std::to_string(uid) };
+      { "-w", path.string(), "-u", uid_str_ };
   return RunSubprocess(args);
 }
 
-SmokeTestHelperRunner::Result SmokeTestHelperRunner::RecoveryWithSubprocess(
-    const bf::path& path, uid_t uid) const {
+BackendInterface::SubProcessResult BackendInterface::RecoverWithSubprocess(
+    const fs::path& path) const {
   std::vector<std::string> args =
-      { "-b", path.string(), "-u", std::to_string(uid) };
+      { "-b", path.string(), "-u", uid_str_ };
   return RunSubprocess(args);
 }
 
-SmokeTestHelperRunner::Result SmokeTestHelperRunner::UninstallWithSubprocess(
-    const std::string& pkgid, uid_t uid) const {
-  std::vector<std::string> args = { "-d", pkgid, "-u", std::to_string(uid) };
+BackendInterface::SubProcessResult BackendInterface::UninstallWithSubprocess(
+    const std::string& pkgid) const {
+  std::vector<std::string> args = { "-d", pkgid, "-u", uid_str_ };
   return RunSubprocess(args);
 }
 
-SmokeTestHelperRunner::Result
-    SmokeTestHelperRunner::InstallWithSubprocessAndKill(
-        const bf::path& path, uid_t uid, useconds_t delay) const {
+BackendInterface::SubProcessResult
+BackendInterface::InstallPreloadWithSubprocess(
+    const std::filesystem::path& path) const {
+  std::vector<std::string> args = { "", "-i", path.string(), "--preload" };
+  return RunSubprocess(args);
+}
+
+BackendInterface::SubProcessResult
+    BackendInterface::InstallWithSubprocessAndKill(
+        const fs::path& path, useconds_t delay) const {
   std::vector<std::string> args =
-      { "-i", path.string(), "-u", std::to_string(uid) };
+      { "-i", path.string(), "-u", uid_str_ };
   return RunSubprocessAndKill(args, delay);
 }
 
-SmokeTestHelperRunner::Result
-    SmokeTestHelperRunner::MountInstallWithSubprocessAndKill(
-        const bf::path& path, uid_t uid, useconds_t delay) const {
+BackendInterface::SubProcessResult
+    BackendInterface::MountInstallWithSubprocessAndKill(
+        const fs::path& path, useconds_t delay) const {
   std::vector<std::string> args =
-      { "-w", path.string(), "-u", std::to_string(uid) };
+      { "-w", path.string(), "-u", uid_str_ };
   return RunSubprocessAndKill(args, delay);
 }
 
-SmokeTestHelperRunner::Result
-    SmokeTestHelperRunner::UninstallWithSubprocessAndKill(
-        const std::string& pkgid, uid_t uid, useconds_t delay) const {
+BackendInterface::SubProcessResult
+    BackendInterface::UninstallWithSubprocessAndKill(
+        const std::string& pkgid, useconds_t delay) const {
   std::vector<std::string> args =
-      { "-d", pkgid, "-u", std::to_string(uid) };
+      { "-d", pkgid, "-u", uid_str_ };
   return RunSubprocessAndKill(args, delay);
 }
 
-SmokeTestHelperRunner::Result SmokeTestHelperRunner::InstallPkgsWithSubprocess(
-    const std::vector<bf::path>& paths, uid_t uid) const {
+BackendInterface::SubProcessResult BackendInterface::InstallPkgsWithSubprocess(
+    const std::vector<fs::path>& paths) const {
   std::vector<std::string> args;
   args.emplace_back("-i");
-  for (const bf::path& p : paths)
+  for (const fs::path& p : paths)
     args.emplace_back(p.string());
   args.emplace_back("-u");
-  args.emplace_back(std::to_string(uid));
+  args.emplace_back(uid_str_);
   return RunSubprocess(args);
 }
 
-SmokeTestHelperRunner::Result
-    SmokeTestHelperRunner::MountInstallPkgsWithSubprocess(
-    const std::vector<bf::path>& paths, uid_t uid) const {
+BackendInterface::SubProcessResult
+    BackendInterface::MountInstallPkgsWithSubprocess(
+    const std::vector<fs::path>& paths) const {
   std::vector<std::string> args;
   args.emplace_back("-w");
-  for (const bf::path& p : paths)
+  for (const fs::path& p : paths)
     args.emplace_back(p.string());
   args.emplace_back("-u");
-  args.emplace_back(std::to_string(uid));
+  args.emplace_back(uid_str_);
   return RunSubprocess(args);
 }
 
-SmokeTestHelperRunner::Result SmokeTestHelperRunner::RecoveryPkgsWithSubprocess(
-    const std::vector<bf::path>& paths, uid_t uid) const {
+BackendInterface::SubProcessResult BackendInterface::RecoverPkgsWithSubprocess(
+    const std::vector<fs::path>& paths) const {
   std::vector<std::string> args;
   args.emplace_back("-b");
-  for (const bf::path& p : paths)
+  for (const fs::path& p : paths)
     args.emplace_back(p.string());
   args.emplace_back("-u");
-  args.emplace_back(std::to_string(uid));
+  args.emplace_back(uid_str_);
   return RunSubprocess(args);
 }
 
-SmokeTestHelperRunner::Result
-    SmokeTestHelperRunner::UninstallPkgsWithSubprocess(
-        const std::vector<std::string>& pkgids, uid_t uid) const {
+BackendInterface::SubProcessResult
+    BackendInterface::UninstallPkgsWithSubprocess(
+        const std::vector<std::string>& pkgids) const {
   std::vector<std::string> args;
   args.emplace_back("-d");
   args.insert(args.end(), pkgids.begin(), pkgids.end());
   args.emplace_back("-u");
-  args.emplace_back(std::to_string(uid));
+  args.emplace_back(uid_str_);
   return RunSubprocess(args);
 }
 
-SmokeTestHelperRunner::Result
-    SmokeTestHelperRunner::InstallPkgsWithSubprocessAndKill(
-        const std::vector<bf::path>& paths, uid_t uid, useconds_t delay) const {
+BackendInterface::SubProcessResult
+    BackendInterface::InstallPkgsWithSubprocessAndKill(
+        const std::vector<fs::path>& paths, useconds_t delay) const {
   std::vector<std::string> args;
   args.emplace_back("-i");
-  for (const bf::path& p : paths)
+  for (const fs::path& p : paths)
     args.emplace_back(p.string());
   args.emplace_back("-u");
-  args.emplace_back(std::to_string(uid));
+  args.emplace_back(uid_str_);
   return RunSubprocessAndKill(args, delay);
 }
 
-SmokeTestHelperRunner::Result
-    SmokeTestHelperRunner::MountInstallPkgsWithSubprocessAndKill(
-        const std::vector<bf::path>& paths, uid_t uid, useconds_t delay) const {
+BackendInterface::SubProcessResult
+    BackendInterface::MountInstallPkgsWithSubprocessAndKill(
+        const std::vector<fs::path>& paths, useconds_t delay) const {
   std::vector<std::string> args;
   args.emplace_back("-w");
-  for (const bf::path& p : paths)
+  for (const fs::path& p : paths)
     args.emplace_back(p.string());
   args.emplace_back("-u");
-  args.emplace_back(std::to_string(uid));
+  args.emplace_back(uid_str_);
   return RunSubprocessAndKill(args, delay);
 }
 
-bool CopySmackAccess(const boost::filesystem::path& src,
-                     const boost::filesystem::path& dst) {
-  if (!bf::exists(src) && !bf::is_symlink(src)) {
+bool CopySmackAccess(const std::filesystem::path& src,
+                     const std::filesystem::path& dst) {
+  if (!fs::exists(src) && !fs::is_symlink(src)) {
     LOG(ERROR) << "Failed to copy smack access label";
     return false;
   }
@@ -1179,9 +1522,9 @@ bool CopySmackAccess(const boost::filesystem::path& src,
   return true;
 }
 
-bool CopySmackExec(const boost::filesystem::path& src,
-                   const boost::filesystem::path& dst) {
-  if (!bf::exists(src) && !bf::is_symlink(src)) {
+bool CopySmackExec(const std::filesystem::path& src,
+                   const std::filesystem::path& dst) {
+  if (!fs::exists(src) && !fs::is_symlink(src)) {
     LOG(ERROR) << "Failed to copy smack exec label";
     return false;
   }
@@ -1203,9 +1546,9 @@ bool CopySmackExec(const boost::filesystem::path& src,
   return true;
 }
 
-bool CopySmackMmap(const boost::filesystem::path& src,
-                   const boost::filesystem::path& dst) {
-  if (!bf::exists(src) && !bf::is_symlink(src)) {
+bool CopySmackMmap(const std::filesystem::path& src,
+                   const std::filesystem::path& dst) {
+  if (!fs::exists(src) && !fs::is_symlink(src)) {
     LOG(ERROR) << "Failed to copy smack mmap label";
     return false;
   }
@@ -1227,9 +1570,9 @@ bool CopySmackMmap(const boost::filesystem::path& src,
   return true;
 }
 
-bool CopySmackTransmute(const boost::filesystem::path& src,
-                        const boost::filesystem::path& dst) {
-  if (!bf::exists(src)) {
+bool CopySmackTransmute(const std::filesystem::path& src,
+                        const std::filesystem::path& dst) {
+  if (!fs::exists(src)) {
     LOG(ERROR) << "Failed to copy smack tranmute label";
     return false;
   }
@@ -1257,40 +1600,40 @@ bool CopySmackTransmute(const boost::filesystem::path& src,
   return true;
 }
 
-bool CopySmackLabels(const boost::filesystem::path& src,
-                     const boost::filesystem::path& dst) {
+bool CopySmackLabels(const std::filesystem::path& src,
+                     const std::filesystem::path& dst) {
   if (!CopySmackAccess(src, dst))
     return false;
   if (!CopySmackExec(src, dst))
     return false;
   if (!CopySmackMmap(src, dst))
     return false;
-  if (!bf::is_symlink(src) && bf::is_directory(src)) {
+  if (!fs::is_symlink(src) && fs::is_directory(src)) {
     if (!CopySmackTransmute(src, dst))
       return false;
   }
   return true;
 }
 
-bool CopyAndRemoveWithSmack(const bf::path& src, const bf::path& dst) {
-  bs::error_code error;
-  if (bf::exists(dst)) {
+bool CopyAndRemoveWithSmack(const fs::path& src, const fs::path& dst) {
+  std::error_code error;
+  if (fs::exists(dst)) {
     try {
-      bf::remove_all(dst, error);
+      fs::remove_all(dst, error);
     } catch (...) {
       std::cout << "Exception occurred during remove [" << dst.string()
                 << "], and skip this file"<< std::endl;
     }
     if (error) {
-      if (!bf::is_directory(dst)) {
+      if (!fs::is_directory(dst)) {
         LOG(ERROR) << "remove_all fail";
         return false;
       }
     }
   }
   try {
-    if (bf::is_symlink(src)) {
-      bf::copy_symlink(src, dst, error);
+    if (fs::is_symlink(src)) {
+      fs::copy_symlink(src, dst, error);
       if (error) {
         LOG(ERROR) << "Failed to copy symlink: " << src << ", "
                    << error.message();
@@ -1301,9 +1644,9 @@ bool CopyAndRemoveWithSmack(const bf::path& src, const bf::path& dst) {
                    << "] to [" << dst.string() << "] fail";
         return false;
       }
-    } else if (bf::is_directory(src)) {
-      if (!bf::exists(dst)) {
-        bf::create_directories(dst, error);
+    } else if (fs::is_directory(src)) {
+      if (!fs::exists(dst)) {
+        fs::create_directories(dst, error);
         if (error) {
           LOG(ERROR) << "create directories fail";
           return false;
@@ -1316,25 +1659,25 @@ bool CopyAndRemoveWithSmack(const bf::path& src, const bf::path& dst) {
         }
       }
       bool success = true;
-      for (bf::directory_iterator file(src);
-          file != bf::directory_iterator();
+      for (fs::directory_iterator file(src);
+          file != fs::directory_iterator();
           ++file) {
-        bf::path current(file->path());
-        bf::path target = dst / current.filename();
+        fs::path current(file->path());
+        fs::path target = dst / current.filename();
         success &= CopyAndRemoveWithSmack(current, target);
       }
-      bf::remove_all(src);
+      fs::remove_all(src);
       if (!success)
         return false;
     } else {
-      bf::copy_file(src, dst);
+      fs::copy_file(src, dst);
       ci::CopyOwnershipAndPermissions(src, dst);
       if (!CopySmackLabels(src, dst)) {
         LOG(ERROR) << "copy smack label from [" << src.string()
                    << "] to [" << dst.string() << "] fail";
         return false;
       }
-      bf::remove_all(src);
+      fs::remove_all(src);
     }
   } catch (...) {
     std::cout << "Exception occurred during copy [" << src.string()
@@ -1345,11 +1688,11 @@ bool CopyAndRemoveWithSmack(const bf::path& src, const bf::path& dst) {
   return true;
 }
 
-bool BackupPathCopyAndRemove(const bf::path& path) {
-  if (!bf::exists(path))
+bool BackupPathCopyAndRemove(const fs::path& path) {
+  if (!fs::exists(path))
     return true;
 
-  bf::path backup_path = path.string() + ".bck";
+  fs::path backup_path = path.string() + ".bck";
   std::cout << "Backup path: " << path << " to " << backup_path << std::endl;
   if (!CopyAndRemoveWithSmack(path, backup_path)) {
     LOG(ERROR) << "Failed to setup test environment. Does some previous"
@@ -1360,22 +1703,22 @@ bool BackupPathCopyAndRemove(const bf::path& path) {
   return true;
 }
 
-bool BackupPath(const bf::path& path) {
-  bf::path trash_path = GetTrashPath(path);
-  if (bf::exists(trash_path)) {
+bool BackupPath(const fs::path& path) {
+  fs::path trash_path = GetTrashPath(path);
+  if (fs::exists(trash_path)) {
     LOG(ERROR) << trash_path << " exists. Please remove "
                << trash_path << " manually!";
     return false;
   }
-  bf::path backup_path = path.string() + ".bck";
+  fs::path backup_path = path.string() + ".bck";
   std::cout << "Backup path: " << path << " to " << backup_path << std::endl;
-  bs::error_code error;
-  bf::remove_all(backup_path, error);
+  std::error_code error;
+  fs::remove_all(backup_path, error);
   if (error)
     LOG(ERROR) << "Remove failed: " << backup_path
                << " (" << error.message() << ")";
-  if (bf::exists(path)) {
-    bf::rename(path, backup_path, error);
+  if (fs::exists(path)) {
+    fs::rename(path, backup_path, error);
     if (error) {
       LOG(ERROR) << "Failed to setup test environment. Does some previous"
                  << " test crashed? Path: "
@@ -1383,15 +1726,20 @@ bool BackupPath(const bf::path& path) {
       return false;
     }
     assert(!error);
-    if (bf::is_directory(backup_path))
-      bf::create_directory(path);
+    if (fs::is_directory(backup_path))
+      fs::create_directory(path);
   }
   return true;
 }
 
-bool RestorePathCopyAndRemove(const bf::path& path) {
-  bf::path backup_path = path.string() + ".bck";
-  if (!bf::exists(backup_path))
+void CreateDatabase() {
+  pkgmgr_parser_create_and_initialize_db(kGlobalUserUid);
+  pkgmgr_parser_create_and_initialize_db(getuid());
+}
+
+bool RestorePathCopyAndRemove(const fs::path& path) {
+  fs::path backup_path = path.string() + ".bck";
+  if (!fs::exists(backup_path))
     return true;
 
   std::cout << "Restore path: " << path << " from " << backup_path << std::endl;
@@ -1402,24 +1750,24 @@ bool RestorePathCopyAndRemove(const bf::path& path) {
   return true;
 }
 
-bool RestorePath(const bf::path& path) {
-  bf::path backup_path = path.string() + ".bck";
+bool RestorePath(const fs::path& path) {
+  fs::path backup_path = path.string() + ".bck";
   std::cout << "Restore path: " << path << " from " << backup_path << std::endl;
-  bs::error_code error;
-  bf::remove_all(path, error);
+  std::error_code error;
+  fs::remove_all(path, error);
   if (error) {
-    bf::path trash_path = GetTrashPath(path);
+    fs::path trash_path = GetTrashPath(path);
     LOG(ERROR) << "Remove failed: " << path << " (" << error.message() << ")";
     std::cout << "Moving " << path << " to " << trash_path << std::endl;
-    bf::rename(path, trash_path, error);
+    fs::rename(path, trash_path, error);
     if (error)
       LOG(ERROR) << "Failed to move " << path << " to " << trash_path
                  << " (" << error.message() << ")";
     else
       LOG(ERROR) << trash_path << " should be removed manually!";
   }
-  if (bf::exists(backup_path)) {
-    bf::rename(backup_path, path, error);
+  if (fs::exists(backup_path)) {
+    fs::rename(backup_path, path, error);
     if (error) {
       LOG(ERROR) << "Failed to restore backup path: " << backup_path
                  << " (" << error.message() << ")";
@@ -1429,13 +1777,13 @@ bool RestorePath(const bf::path& path) {
   return true;
 }
 
-std::vector<bf::path> SetupBackupDirectories(uid_t test_uid) {
-  std::vector<bf::path> entries;
-  bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB));
+std::vector<fs::path> SetupBackupDirectories(uid_t test_uid) {
+  std::vector<fs::path> entries;
+  fs::path db_dir = fs::path(tzplatform_getenv(TZ_SYS_DB));
   if (test_uid != kGlobalUserUid)
     db_dir = db_dir / "user" / std::to_string(test_uid);
   for (auto e : kDBEntries) {
-    bf::path path = db_dir / e;
+    fs::path path = db_dir / e;
     entries.emplace_back(path);
   }
 
@@ -1450,30 +1798,29 @@ std::vector<bf::path> SetupBackupDirectories(uid_t test_uid) {
     entries.emplace_back(kGlobalManifestDir);
     ci::UserList list = ci::GetUserList();
     for (auto l : list) {
-      bf::path apps = std::get<2>(l) / "apps_rw";
+      fs::path apps = std::get<2>(l) / "apps_rw";
       entries.emplace_back(apps);
     }
   } else {
     tzplatform_set_user(test_uid);
-    bf::path approot = tzplatform_getenv(TZ_USER_APPROOT);
+    fs::path approot = tzplatform_getenv(TZ_USER_APPROOT);
     tzplatform_reset_user();
     entries.emplace_back(approot);
   }
 
-  bf::path apps_rw = ci::GetRootAppPath(false, test_uid);
+  fs::path apps_rw = ci::GetRootAppPath(false, test_uid);
   entries.emplace_back(apps_rw);
   entries.emplace_back(kSdkDirectory);
 
   return entries;
 }
 
-void UninstallAllAppsInDirectory(bf::path dir, bool is_preload,
+void UninstallAllAppsInDirectory(fs::path dir, bool is_preload,
     BackendInterface* backend) {
-  if (bf::exists(dir)) {
-    for (auto& dir_entry : boost::make_iterator_range(
-        bf::directory_iterator(dir), bf::directory_iterator())) {
+  if (fs::exists(dir)) {
+    for (auto& dir_entry : fs::directory_iterator(dir)) {
       if (dir_entry.path().string().find("smoke") != std::string::npos &&
-          bf::is_directory(dir_entry)) {
+          fs::is_directory(dir_entry)) {
         std::string package = dir_entry.path().filename().string();
         std::regex pkg_regex("smoke[a-zA-Z0-9]{5,}");
         if (std::regex_match(package, pkg_regex)) {
@@ -1498,10 +1845,10 @@ void UninstallAllAppsInDirectory(bf::path dir, bool is_preload,
 void UninstallAllSmokeApps(ci::RequestMode request_mode, uid_t test_uid,
     BackendInterface *backend) {
   std::cout << "Uninstalling all smoke apps" << std::endl;
-  bf::path apps_rw = ci::GetRootAppPath(false, test_uid);
+  fs::path apps_rw = ci::GetRootAppPath(false, test_uid);
   UninstallAllAppsInDirectory(apps_rw, false, backend);
   if (getuid() == 0 && request_mode == ci::RequestMode::GLOBAL) {
-    bf::path root_path = kPreloadApps;
+    fs::path root_path = kPreloadApps;
     UninstallAllAppsInDirectory(root_path, true, backend);
   }
 }
@@ -1522,4 +1869,23 @@ int GetAppInstalledTime(const char* appid, uid_t uid) {
   return installed_time;
 }
 
+bool CompareFileInfo(const std::string& pkgid, const TestParameters& params,
+    const fs::path& file) {
+  FileInfoCollector result(pkgid, params);
+  if (!result.Init())
+    return false;
+
+  fs::path p = "/tmp";
+  p /= file.filename();
+
+  if (!result.FileInfoToFile(p))
+    return false;
+
+  FileInfoCollector expected(pkgid, params);
+  if (!expected.LoadFromFile(file))
+    return false;
+
+  return result.IsEqual(expected);
+}
+
 }  // namespace smoke_test