Unittests for pkgmgr plugins management code 10/88010/1
authorTomasz Iwanek <t.iwanek@samsung.com>
Fri, 9 Sep 2016 08:13:44 +0000 (10:13 +0200)
committerTomasz Iwanek <t.iwanek@samsung.com>
Mon, 12 Sep 2016 12:19:45 +0000 (14:19 +0200)
Run new tests:
 $ /usr/bin/app-installers-ut/plugins_unittest

This test requires several helper libraries to test
if plugins are called in correct way. Commit implements
3 test plugins and test assessor library. Test assessor
library is used by plugins and test code to set and get
results of plugin execution.

Change-Id: Idc30b953d6e5453c0e8fde94e1eea6d691225ea3

15 files changed:
CMakeLists.txt
packaging/app-installers.spec
src/common/utils/glist_range.h
src/unit_tests/CMakeLists.txt
src/unit_tests/libs/CMakeLists.txt [new file with mode: 0644]
src/unit_tests/libs/test_assessor.cc [new file with mode: 0644]
src/unit_tests/libs/test_assessor.h [new file with mode: 0644]
src/unit_tests/libs/test_category_plugin.cc [new file with mode: 0644]
src/unit_tests/libs/test_metadata_plugin.cc [new file with mode: 0644]
src/unit_tests/libs/test_tag_plugin.cc [new file with mode: 0644]
src/unit_tests/plugins_unittest.cc [new file with mode: 0644]
src/unit_tests/test_samples/plugins/invalid_manifest.xml [new file with mode: 0644]
src/unit_tests/test_samples/plugins/invalid_plugin_list.txt [new file with mode: 0644]
src/unit_tests/test_samples/plugins/test_plugin_list.txt [new file with mode: 0644]
src/unit_tests/test_samples/plugins/tizen-manifest.xml [new file with mode: 0644]

index 2acdfef..bfb4df8 100644 (file)
@@ -53,7 +53,6 @@ PKG_CHECK_MODULES(PKGMGR_PARSER_DEPS REQUIRED pkgmgr-parser)
 PKG_CHECK_MODULES(PKGMGR_INFO_DEPS REQUIRED pkgmgr-info)
 PKG_CHECK_MODULES(LIBXML_DEPS REQUIRED libxml-2.0)
 PKG_CHECK_MODULES(PRIVILEGE_CHECKER_DEPS REQUIRED security-privilege-manager)
-PKG_CHECK_MODULES(TPK_MANIFEST_HANDLERS_DEPS REQUIRED tpk-manifest-handlers)
 PKG_CHECK_MODULES(DBUS_DEPS REQUIRED dbus-1)
 PKG_CHECK_MODULES(GDBUS_DEPS REQUIRED glib-2.0 gio-2.0)
 PKG_CHECK_MODULES(GUM_DEPS REQUIRED libgum)
index e510377..7dbb363 100644 (file)
@@ -107,6 +107,7 @@ make %{?_smp_mflags}
 %manifest app-installers-tests.manifest
 %{_bindir}/app-installers-ut/*
 %{_datadir}/app-installers-ut/*
+%{_libdir}/libtest-assessor-lib.so*
 
 %changelog
 * Tue Sep 01 2015 Pawel Sikorski <p.sikorski@samsung.com> 1.8-1
index 20ebade..cbeeec2 100644 (file)
@@ -73,6 +73,10 @@ class GListRange {
     return list_;
   }
 
+  guint Size() const {
+    return g_list_length(list_);
+  }
+
  private:
   GList* list_;
 };
index e52c495..7746348 100644 (file)
@@ -2,14 +2,31 @@ SET(DESTINATION_DIR app-installers-ut)
 
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../)
 
+SET(TARGET_ASSESSOR_LIB "test-assessor-lib")
+SET(TARGET_TEST_TAG_PLUGIN "test-tag-plugin")
+SET(TARGET_TEST_CATEGORY_PLUGIN "test-category-plugin")
+SET(TARGET_TEST_METADATA_PLUGIN "test-metadata-plugin")
+
+SET(TARGET_PLUGINS_TEST "plugins_unittest")
+SET(TARGET_SIGNATURE_TEST "signature_unittest")
+
 # Executables
-ADD_EXECUTABLE(signature_unittest
+ADD_EXECUTABLE(${TARGET_SIGNATURE_TEST}
   signature_unittest.cc
 )
 
+ADD_EXECUTABLE(${TARGET_PLUGINS_TEST}
+  plugins_unittest.cc
+)
+
 INSTALL(DIRECTORY test_samples/ DESTINATION ${SHAREDIR}/${DESTINATION_DIR}/test_samples)
 
-APPLY_PKG_CONFIG(signature_unittest PUBLIC
+APPLY_PKG_CONFIG(${TARGET_SIGNATURE_TEST} PUBLIC
+  Boost
+  GTEST
+)
+
+APPLY_PKG_CONFIG(plugins_unittest PUBLIC
   Boost
   GTEST
 )
@@ -17,6 +34,20 @@ APPLY_PKG_CONFIG(signature_unittest PUBLIC
 # FindGTest module do not sets all needed libraries in GTEST_LIBRARIES and
 # GTest main libraries is still missing, so additional linking of
 # GTEST_MAIN_LIBRARIES is needed.
-TARGET_LINK_LIBRARIES(signature_unittest PUBLIC ${TARGET_LIBNAME_COMMON} ${GTEST_MAIN_LIBRARIES} pthread)
+TARGET_LINK_LIBRARIES(${TARGET_SIGNATURE_TEST} PUBLIC
+  ${TARGET_LIBNAME_COMMON}
+  ${GTEST_MAIN_LIBRARIES}
+  pthread
+)
+TARGET_LINK_LIBRARIES(${TARGET_PLUGINS_TEST} PUBLIC
+  ${TARGET_LIBNAME_COMMON}
+  ${TPK_MANIFEST_HANDLERS_DEPS}
+  ${GTEST_MAIN_LIBRARIES}
+  ${TARGET_ASSESSOR_LIB}
+  pthread
+)
+
+INSTALL(TARGETS ${TARGET_SIGNATURE_TEST} DESTINATION ${BINDIR}/${DESTINATION_DIR})
+INSTALL(TARGETS ${TARGET_PLUGINS_TEST} DESTINATION ${BINDIR}/${DESTINATION_DIR})
 
-INSTALL(TARGETS signature_unittest DESTINATION ${BINDIR}/${DESTINATION_DIR})
+ADD_SUBDIRECTORY(libs)
diff --git a/src/unit_tests/libs/CMakeLists.txt b/src/unit_tests/libs/CMakeLists.txt
new file mode 100644 (file)
index 0000000..488712c
--- /dev/null
@@ -0,0 +1,26 @@
+SET(PLUGIN_DIR ${SHAREDIR}/${DESTINATION_DIR}/test_samples/plugins/)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
+
+ADD_LIBRARY(${TARGET_ASSESSOR_LIB} SHARED
+  test_assessor.cc
+)
+ADD_LIBRARY(${TARGET_TEST_TAG_PLUGIN} SHARED
+  test_tag_plugin.cc
+)
+ADD_LIBRARY(${TARGET_TEST_CATEGORY_PLUGIN} SHARED
+  test_category_plugin.cc
+)
+ADD_LIBRARY(${TARGET_TEST_METADATA_PLUGIN} SHARED
+  test_metadata_plugin.cc
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_ASSESSOR_LIB} PUBLIC ${TARGET_LIBNAME_COMMON})
+TARGET_LINK_LIBRARIES(${TARGET_TEST_TAG_PLUGIN} PUBLIC ${TARGET_LIBNAME_COMMON} ${TARGET_ASSESSOR_LIB})
+TARGET_LINK_LIBRARIES(${TARGET_TEST_CATEGORY_PLUGIN} PUBLIC ${TARGET_LIBNAME_COMMON} ${TARGET_ASSESSOR_LIB})
+TARGET_LINK_LIBRARIES(${TARGET_TEST_METADATA_PLUGIN} PUBLIC ${TARGET_LIBNAME_COMMON} ${TARGET_ASSESSOR_LIB})
+
+INSTALL(TARGETS ${TARGET_ASSESSOR_LIB} DESTINATION ${LIBDIR})
+INSTALL(TARGETS ${TARGET_TEST_TAG_PLUGIN} DESTINATION ${PLUGIN_DIR})
+INSTALL(TARGETS ${TARGET_TEST_CATEGORY_PLUGIN} DESTINATION ${PLUGIN_DIR})
+INSTALL(TARGETS ${TARGET_TEST_METADATA_PLUGIN} DESTINATION ${PLUGIN_DIR})
diff --git a/src/unit_tests/libs/test_assessor.cc b/src/unit_tests/libs/test_assessor.cc
new file mode 100644 (file)
index 0000000..2becc77
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "unit_tests/libs/test_assessor.h"
+
+namespace common_installer {
+
+const char kTagPluginName[] = "tag";
+const char kCategoryPluginName[] = "category";
+const char kMetadataPluginName[] = "metadata";
+const char kTestPackageId[] = "org.tizen.testapp";
+const char kTestApplicationId[] = "org.tizen.testapp.main";
+
+void TestAssessor::ClearResults() {
+  results.clear();
+}
+
+void TestAssessor::AddResult(const ResultLine& result,
+                             const boost::optional<std::string>& error) {
+  results.insert(std::make_pair(result, error));
+}
+
+const TestAssessor::ResultStore& TestAssessor::GetResults() const {
+  return results;
+}
+
+}  // namespace common_installer
diff --git a/src/unit_tests/libs/test_assessor.h b/src/unit_tests/libs/test_assessor.h
new file mode 100644 (file)
index 0000000..21473d4
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef UNIT_TESTS_LIBS_TEST_ASSESSOR_H_
+#define UNIT_TESTS_LIBS_TEST_ASSESSOR_H_
+
+#include <boost/optional/optional.hpp>
+
+#include <map>
+#include <string>
+#include <tuple>
+#include <utility>
+
+#include "common/plugins/plugin.h"
+#include "common/utils/singleton.h"
+
+namespace common_installer {
+
+extern const char kTagPluginName[];
+extern const char kCategoryPluginName[];
+extern const char kMetadataPluginName[];
+extern const char kTestPackageId[];
+extern const char kTestApplicationId[];
+
+class TestAssessor : public common_installer::Singleton<TestAssessor> {
+  CRTP_DECLARE_DEFAULT_CONSTRUCTOR_CLASS(TestAssessor)
+ public:
+  using ResultLine = std::tuple<std::string, Plugin::ActionType,
+                            Plugin::ProcessType>;
+  using ResultStore = std::map<ResultLine, boost::optional<std::string>>;
+
+  void ClearResults();
+  void AddResult(const ResultLine& result,
+                 const boost::optional<std::string> &error);
+  const ResultStore& GetResults() const;
+
+ private:
+  ResultStore results;
+};
+
+}  // namespace common_installer
+
+#endif  // UNIT_TESTS_LIBS_TEST_ASSESSOR_H_
diff --git a/src/unit_tests/libs/test_category_plugin.cc b/src/unit_tests/libs/test_category_plugin.cc
new file mode 100644 (file)
index 0000000..ffb1305
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include <boost/optional/optional.hpp>
+
+#include <pkgmgr_parser.h>
+
+#include <glib/glist.h>
+
+#include <cstring>
+#include <string>
+#include <tuple>
+
+#include "common/plugins/plugin.h"
+#include "common/utils/glist_range.h"
+#include "unit_tests/libs/test_assessor.h"
+
+namespace ci = common_installer;
+
+namespace {
+
+boost::optional<std::string> CheckArgs(
+    const char* pkgid,
+    const char* appid,
+    GList* categories) {
+  if (!pkgid)
+    return std::string("Package id is null for category plugin");
+  if (!appid)
+    return std::string("Application id is null for category plugin");
+  if (strcmp(pkgid, ci::kTestPackageId) != 0)
+    return std::string("Package id doesn't match for category plugin");
+  if (strcmp(appid, ci::kTestApplicationId) != 0)
+    return std::string("Application id doesn't match for category plugin");
+  auto range = GListRange<__category_t*>(categories);
+  if (range.Size() != 3)
+    return std::string("Metadata Glist is wrong size for category plugin");
+  bool found_a = false;
+  bool found_b = false;
+  bool found_c = false;
+  for (__category_t* meta : range) {
+    if (strcmp(meta->name, "http://tizen.org/category/test_category/value_a")
+       == 0) {
+      found_a = true;
+    }
+    if (strcmp(meta->name, "http://tizen.org/category/test_category/value_b")
+       == 0) {
+      found_b = true;
+    }
+    if (strcmp(meta->name, "http://tizen.org/category/test_category/value_c")
+       == 0) {
+      found_c = true;
+    }
+  }
+  if (!found_a)
+    return std::string("Category value_a not found");
+  if (!found_b)
+    return std::string("Category value_b not found");
+  if (!found_c)
+    return std::string("Category value_c not found");
+  return {};
+}
+
+}  // namespace
+
+extern "C" int PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL(
+    const char* pkgid,
+    const char* appid,
+    GList* categories) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kCategoryPluginName,
+      ci::Plugin::ActionType::Install,
+      ci::Plugin::ProcessType::Main),
+      CheckArgs(pkgid, appid, categories));
+  return 0;
+}
+
+extern "C" int PKGMGR_CATEGORY_PARSER_PLUGIN_UPGRADE(
+    const char* pkgid,
+    const char* appid,
+    GList* categories) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kCategoryPluginName,
+      ci::Plugin::ActionType::Upgrade,
+      ci::Plugin::ProcessType::Main),
+      CheckArgs(pkgid, appid, categories));
+  return 0;
+}
+
+extern "C" int PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL(
+    const char* pkgid,
+    const char* appid,
+    GList* categories) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kCategoryPluginName,
+      ci::Plugin::ActionType::Uninstall,
+      ci::Plugin::ProcessType::Main),
+      CheckArgs(pkgid, appid, categories));
+  return 0;
+}
diff --git a/src/unit_tests/libs/test_metadata_plugin.cc b/src/unit_tests/libs/test_metadata_plugin.cc
new file mode 100644 (file)
index 0000000..5253845
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include <boost/optional/optional.hpp>
+
+#include <pkgmgr_parser.h>
+
+#include <glib/glist.h>
+
+#include <cstring>
+#include <string>
+#include <tuple>
+
+#include "common/plugins/plugin.h"
+#include "common/utils/glist_range.h"
+#include "unit_tests/libs/test_assessor.h"
+
+namespace ci = common_installer;
+
+namespace {
+
+boost::optional<std::string> CheckArgs(
+    const char* pkgid,
+    const char* appid,
+    GList* metadata) {
+  if (!pkgid)
+    return std::string("Package id is null for metadata plugin");
+  if (!appid)
+    return std::string("Application id is null for metadata plugin");
+  if (strcmp(pkgid, ci::kTestPackageId) != 0)
+    return std::string("Package id doesn't match for metadata plugin");
+  if (strcmp(appid, ci::kTestApplicationId) != 0)
+    return std::string("Application id doesn't match for metadata plugin");
+  auto range = GListRange<__metadata_t*>(metadata);
+  if (range.Size() != 3)
+    return std::string("Metadata Glist is wrong size for metadata plugin");
+  bool found_a = false;
+  bool found_b = false;
+  bool found_c = false;
+  for (__metadata_t* meta : range) {
+    if (strcmp(meta->key,
+       "http://developer.samsung.com/tizen/metadata/test_metadata/key_a")
+       == 0 && strcmp(meta->value, "value_a") == 0) {
+      found_a = true;
+    }
+    if (strcmp(meta->key,
+       "http://developer.samsung.com/tizen/metadata/test_metadata/key_b")
+       == 0 && strcmp(meta->value, "value_b") == 0) {
+      found_b = true;
+    }
+    if (strcmp(meta->key,
+       "http://developer.samsung.com/tizen/metadata/test_metadata/key_c")
+       == 0 && strcmp(meta->value, "value_c") == 0) {
+      found_c = true;
+    }
+  }
+  if (!found_a)
+    return std::string("Metadata key_a incorrect or not found");
+  if (!found_b)
+    return std::string("Metadata key_b incorrect or not found");
+  if (!found_c)
+    return std::string("Metadata key_c incorrect or not found");
+  return {};
+}
+
+}  // namespace
+
+extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(
+    const char* pkgid,
+    const char* appid,
+    GList* metadata) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kMetadataPluginName,
+      ci::Plugin::ActionType::Install,
+      ci::Plugin::ProcessType::Main),
+      CheckArgs(pkgid, appid, metadata));
+  return 0;
+}
+
+extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(
+    const char* pkgid,
+    const char* appid,
+    GList* metadata) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kMetadataPluginName,
+      ci::Plugin::ActionType::Upgrade,
+      ci::Plugin::ProcessType::Main),
+      CheckArgs(pkgid, appid, metadata));
+  return 0;
+}
+
+extern "C" int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(
+    const char* pkgid,
+    const char* appid,
+    GList* metadata) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kMetadataPluginName,
+      ci::Plugin::ActionType::Uninstall,
+      ci::Plugin::ProcessType::Main),
+      CheckArgs(pkgid, appid, metadata));
+  return 0;
+}
diff --git a/src/unit_tests/libs/test_tag_plugin.cc b/src/unit_tests/libs/test_tag_plugin.cc
new file mode 100644 (file)
index 0000000..8eeaa81
--- /dev/null
@@ -0,0 +1,116 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include <boost/optional/optional.hpp>
+
+#include <cstring>
+#include <string>
+#include <tuple>
+
+#include "common/plugins/plugin.h"
+#include "unit_tests/libs/test_assessor.h"
+
+namespace ci = common_installer;
+
+namespace {
+
+boost::optional<std::string> CheckArgs(const char* pkgid) {
+  if (!pkgid)
+    return std::string("Package id is null for tag plugin");
+  if (strcmp(pkgid, ci::kTestPackageId) != 0)
+    return std::string("Package id doesn't match for tag plugin") +
+        "Expected: " + ci::kTestPackageId + " actual: " + pkgid;
+  return {};
+}
+
+boost::optional<std::string> CheckArgs(xmlDocPtr doc, const char* pkgid) {
+  if (!doc)
+    return std::string("XML doc pointer is null for tag plugin");
+  return CheckArgs(pkgid);
+}
+
+}  // namespace
+
+extern "C" int PKGMGR_PARSER_PLUGIN_PRE_INSTALL(const char* package) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kTagPluginName,
+      ci::Plugin::ActionType::Install,
+      ci::Plugin::ProcessType::Pre),
+      CheckArgs(package));
+  return 0;
+}
+
+extern "C" int PKGMGR_PARSER_PLUGIN_PRE_UPGRADE(const char* package) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kTagPluginName,
+      ci::Plugin::ActionType::Upgrade,
+      ci::Plugin::ProcessType::Pre),
+      CheckArgs(package));
+  return 0;
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL(const char* package) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kTagPluginName,
+      ci::Plugin::ActionType::Uninstall,
+      ci::Plugin::ProcessType::Pre),
+      CheckArgs(package));
+  return 0;
+}
+
+extern "C" int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr doc,
+                                            const char* package) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kTagPluginName,
+      ci::Plugin::ActionType::Install,
+      ci::Plugin::ProcessType::Main),
+      CheckArgs(doc, package));
+  return 0;
+}
+
+extern "C" int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr doc,
+                                            const char* package) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+     ci::kTagPluginName,
+      ci::Plugin::ActionType::Upgrade,
+      ci::Plugin::ProcessType::Main),
+      CheckArgs(doc, package));
+  return 0;
+}
+
+extern "C" int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr doc,
+                                              const char* package) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kTagPluginName,
+      ci::Plugin::ActionType::Uninstall,
+      ci::Plugin::ProcessType::Main),
+      CheckArgs(doc, package));
+  return 0;
+}
+
+extern "C" int PKGMGR_PARSER_PLUGIN_POST_INSTALL(const char* package) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kTagPluginName,
+      ci::Plugin::ActionType::Install,
+      ci::Plugin::ProcessType::Post),
+      CheckArgs(package));
+  return 0;
+}
+
+extern "C" int PKGMGR_PARSER_PLUGIN_POST_UPGRADE(const char* package) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kTagPluginName,
+      ci::Plugin::ActionType::Upgrade,
+      ci::Plugin::ProcessType::Post),
+      CheckArgs(package));
+  return 0;
+}
+
+extern "C" int PKGMGR_PARSER_PLUGIN_POST_UNINSTALL(const char* package) {
+  ci::TestAssessor::Instance().AddResult(std::make_tuple(
+      ci::kTagPluginName,
+      ci::Plugin::ActionType::Uninstall,
+      ci::Plugin::ProcessType::Post),
+      CheckArgs(package));
+  return 0;
+}
diff --git a/src/unit_tests/plugins_unittest.cc b/src/unit_tests/plugins_unittest.cc
new file mode 100644 (file)
index 0000000..87abee7
--- /dev/null
@@ -0,0 +1,180 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include <boost/filesystem/path.hpp>
+#include <gtest/gtest.h>
+
+#include <memory>
+#include <iterator>
+#include <tuple>
+
+#include "common/installer_context.h"
+#include "common/step/configuration/step_parse_manifest.h"
+#include "common/plugins/plugin_factory.h"
+#include "common/plugins/plugin_list_parser.h"
+#include "common/plugins/plugin_manager.h"
+#include "common/plugins/plugin_xml_parser.h"
+#include "unit_tests/libs/test_assessor.h"
+
+namespace bf = boost::filesystem;
+namespace ci = common_installer;
+
+namespace {
+
+const char kPluginsTestFiles[] =
+    "/usr/share/app-installers-ut/test_samples/plugins";
+
+const bf::path kTestTagPlugin =
+    bf::path(kPluginsTestFiles) / "libtest-tag-plugin.so";
+const bf::path kTestCategoryPlugin =
+    bf::path(kPluginsTestFiles) / "libtest-category-plugin.so";
+const bf::path kTestMetadataPlugin =
+    bf::path(kPluginsTestFiles) / "libtest-metadata-plugin.so";
+
+void CheckCall(
+    const ci::TestAssessor::ResultStore& store,
+    const std::string& name,
+    ci::Plugin::ActionType action) {
+  auto iter_pre = store.find(
+      std::make_tuple(name, action, ci::Plugin::ProcessType::Pre));
+  auto iter_main = store.find(
+      std::make_tuple(name, action, ci::Plugin::ProcessType::Main));
+  auto iter_post = store.find(
+      std::make_tuple(name, action, ci::Plugin::ProcessType::Post));
+  ASSERT_NE(iter_pre, store.end());
+  ASSERT_NE(iter_main, store.end());
+  ASSERT_NE(iter_post, store.end());
+
+  // Error is not set
+  ASSERT_TRUE(!iter_pre->second) << *iter_pre->second;
+  ASSERT_TRUE(!iter_main->second) << *iter_main->second;
+  ASSERT_TRUE(!iter_post->second) << *iter_post->second;
+
+  // Check order of calling
+  auto ts_pre = std::distance(store.begin(), iter_pre);
+  auto ts_main = std::distance(store.begin(), iter_main);
+  auto ts_post = std::distance(store.begin(), iter_post);
+  ASSERT_GT(ts_main, ts_pre);
+  ASSERT_GT(ts_post, ts_main);
+}
+
+void CheckCallMain(
+    const ci::TestAssessor::ResultStore& store,
+    const std::string& name,
+    ci::Plugin::ActionType action) {
+  auto iter_main = store.find(
+      std::make_tuple(name, action, ci::Plugin::ProcessType::Main));
+  ASSERT_NE(iter_main, store.end());
+
+  // Error is not set
+  ASSERT_TRUE(!iter_main->second) << *iter_main->second;
+}
+
+}  // namespace
+
+namespace common_installer {
+
+class PluginTest : public testing::Test {
+};
+
+TEST_F(PluginTest, PluginsXmlParser_Valid) {
+  bf::path manifest = bf::path(kPluginsTestFiles) / "tizen-manifest.xml";
+  PluginsXmlParser parser(manifest);
+  ASSERT_TRUE(parser.Parse());
+  ASSERT_NE(parser.doc_ptr(), nullptr);
+  auto tags = parser.tags_list();
+  ASSERT_NE(std::find(tags.begin(), tags.end(), "author"), tags.end());
+  ASSERT_NE(std::find(tags.begin(), tags.end(), "description"), tags.end());
+  ASSERT_NE(std::find(tags.begin(), tags.end(), "ui-application"), tags.end());
+  ASSERT_NE(std::find(tags.begin(), tags.end(), "test"), tags.end());
+
+  ASSERT_EQ(std::find(tags.begin(), tags.end(), "label"), tags.end());
+  ASSERT_EQ(std::find(tags.begin(), tags.end(), "app-control"), tags.end());
+  ASSERT_EQ(std::find(tags.begin(), tags.end(), "datacontrol"), tags.end());
+  ASSERT_EQ(std::find(tags.begin(), tags.end(), "mime"), tags.end());
+  ASSERT_EQ(std::find(tags.begin(), tags.end(), "operation"), tags.end());
+  ASSERT_EQ(std::find(tags.begin(), tags.end(), "uri"), tags.end());
+  ASSERT_EQ(std::find(tags.begin(), tags.end(), "key"), tags.end());
+  ASSERT_EQ(std::find(tags.begin(), tags.end(), "name"), tags.end());
+  ASSERT_EQ(std::find(tags.begin(), tags.end(), ""), tags.end());
+}
+
+TEST_F(PluginTest, PluginsXmlParser_Invalid) {
+  bf::path manifest = bf::path(kPluginsTestFiles) / "invalid_manifest.xml";
+  PluginsXmlParser parser(manifest);
+  ASSERT_FALSE(parser.Parse());
+}
+
+TEST_F(PluginTest, PluginsListParser_Valid) {
+  bf::path list_file = bf::path(kPluginsTestFiles) / "test_plugin_list.txt";
+  PluginsListParser parser(list_file);
+  ASSERT_TRUE(parser.Parse());
+  auto list = parser.PluginInfoList();
+  ASSERT_EQ(list.size(), 3);
+  ASSERT_EQ(list[0]->flag(), 1);
+  ASSERT_EQ(list[0]->type(), "tag");
+  ASSERT_EQ(list[0]->name(), "test");
+  ASSERT_EQ(list[0]->path(), kTestTagPlugin.string());
+  ASSERT_EQ(list[1]->flag(), 2);
+  ASSERT_EQ(list[1]->type(), "category");
+  ASSERT_EQ(list[1]->name(), "http://tizen.org/category/test_category");
+  ASSERT_EQ(list[1]->path(), kTestCategoryPlugin.string());
+  ASSERT_EQ(list[2]->flag(), 4);
+  ASSERT_EQ(list[2]->type(), "metadata");
+  ASSERT_EQ(list[2]->name(),
+      "http://developer.samsung.com/tizen/metadata/test_metadata");
+  ASSERT_EQ(list[2]->path(), kTestMetadataPlugin.string());
+}
+
+TEST_F(PluginTest, PluginsListParser_Invalid) {
+  bf::path list_file = bf::path(kPluginsTestFiles) / "invalid_plugin_list.txt";
+  PluginsListParser parser(list_file);
+  ASSERT_FALSE(parser.Parse());
+}
+
+TEST_F(PluginTest, PluginFactory_CreatingPlugins) {
+  PluginFactory factory;
+  PluginInfo tag_info(1, "tag", "test", kTestTagPlugin.string());
+  ASSERT_TRUE(!!factory.CreatePluginByPluginInfo(tag_info));
+  PluginInfo category_info(2, "category", "category",
+                           kTestCategoryPlugin.string());
+  ASSERT_TRUE(!!factory.CreatePluginByPluginInfo(category_info));
+  PluginInfo metadata_info(3, "metadata", "metadata",
+                           kTestMetadataPlugin.string());
+  ASSERT_TRUE(!!factory.CreatePluginByPluginInfo(metadata_info));
+  PluginInfo missing_info(1, "tag", "test",
+                          "/usr/lib/libmynonexistingplugin.so");
+  ASSERT_FALSE(!!factory.CreatePluginByPluginInfo(missing_info));
+  PluginInfo new_info(1, "newtype", "test", kTestTagPlugin.string());
+  ASSERT_FALSE(!!factory.CreatePluginByPluginInfo(new_info));
+}
+
+#define CALLING_PLUGIN_FOR_ACTION_TEST(NAME, ACTION)                           \
+    TEST_F(PluginTest, PluginManager_CallingPlugins ## NAME) {                 \
+      TestAssessor::Instance().ClearResults();                                 \
+                                                                               \
+      bf::path manifest = bf::path(kPluginsTestFiles) / "tizen-manifest.xml";  \
+      bf::path list = bf::path(kPluginsTestFiles) / "test_plugin_list.txt";    \
+                                                                               \
+      InstallerContext context;                                                \
+      context.unpacked_dir_path.set(manifest.parent_path());                   \
+      configuration::StepParseManifest step(&context,                          \
+          configuration::StepParseManifest::ManifestLocation::PACKAGE,         \
+          configuration::StepParseManifest::StoreLocation::NORMAL);            \
+      ASSERT_EQ(step.process(), Step::Status::OK);                             \
+      PluginManager manager(manifest, list, context.manifest_data.get());      \
+      ASSERT_TRUE(manager.LoadPlugins());                                      \
+      manager.RunPlugins(ACTION);                                              \
+      auto result = TestAssessor::Instance().GetResults();                     \
+      ASSERT_EQ(result.size(), 5);                                             \
+      CheckCall(result, kTagPluginName, ACTION);                               \
+      CheckCallMain(result, kMetadataPluginName, ACTION);                      \
+      CheckCallMain(result, kCategoryPluginName, ACTION);                      \
+    }
+
+CALLING_PLUGIN_FOR_ACTION_TEST(Install, Plugin::ActionType::Install)
+CALLING_PLUGIN_FOR_ACTION_TEST(Upgrade, Plugin::ActionType::Upgrade)
+CALLING_PLUGIN_FOR_ACTION_TEST(Uninstall, Plugin::ActionType::Uninstall)
+
+}  // namespace common_installer
diff --git a/src/unit_tests/test_samples/plugins/invalid_manifest.xml b/src/unit_tests/test_samples/plugins/invalid_manifest.xml
new file mode 100644 (file)
index 0000000..7c1efb7
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="2.3" package="org.tizen.testapp" version="1.0.0">
+  <broken_xml
+</manifest>
diff --git a/src/unit_tests/test_samples/plugins/invalid_plugin_list.txt b/src/unit_tests/test_samples/plugins/invalid_plugin_list.txt
new file mode 100644 (file)
index 0000000..513365b
--- /dev/null
@@ -0,0 +1,3 @@
+flag="0x00000001";type="tag";name="test";path="/usr/share/app-installers-ut/test_samples/plugins/libtest-tag-plugin.so"
+flag="0x00000002";type="category";;;;;;name="http://tizen.org/category/test_category";path="/usr/share/app-installers-ut/test_samples/plugins/libtest-category-plugin.so"
+flag="0x00000004";type="metadata";name="http://developer.samsung.com/tizen/metadata/test_metadata";path="/usr/share/app-installers-ut/test_samples/plugins/libtest-metadata-plugin.so"
diff --git a/src/unit_tests/test_samples/plugins/test_plugin_list.txt b/src/unit_tests/test_samples/plugins/test_plugin_list.txt
new file mode 100644 (file)
index 0000000..283cea8
--- /dev/null
@@ -0,0 +1,3 @@
+flag="0x00000001";type="tag";name="test";path="/usr/share/app-installers-ut/test_samples/plugins/libtest-tag-plugin.so"
+flag="0x00000002";type="category";name="http://tizen.org/category/test_category";path="/usr/share/app-installers-ut/test_samples/plugins/libtest-category-plugin.so"
+flag="0x00000004";type="metadata";name="http://developer.samsung.com/tizen/metadata/test_metadata";path="/usr/share/app-installers-ut/test_samples/plugins/libtest-metadata-plugin.so"
diff --git a/src/unit_tests/test_samples/plugins/tizen-manifest.xml b/src/unit_tests/test_samples/plugins/tizen-manifest.xml
new file mode 100644 (file)
index 0000000..7b4781c
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="2.3" package="org.tizen.testapp" version="1.0.0">
+    <author email="tester@samsung.com" href="www.tizen.org">tester</author>
+    <description>This is default description</description>
+    <description xml:lang="en-us">This is test description</description>
+    <ui-application appid="org.tizen.testapp.main" exec="testapp" multiple="false" nodisplay="false" taskmanage="true" type="capp">
+        <label>testapp</label>
+        <label xml:lang="en-us">Test</label>
+        <icon>testapp.png</icon>
+        <app-control>
+            <mime name="EditMime"/>
+            <operation name="http://tizen.org/appcontrol/operation/edit"/>
+            <uri name="EditUri"/>
+        </app-control>
+        <app-control>
+            <operation name="http://tizen.org/appcontrol/operation/view"/>
+            <uri name="ViewUri"/>
+            <mime name="ViewMime"/>
+        </app-control>
+        <metadata key="metakey1" value="metaval1"/>
+        <metadata key="metakey2" value="metaval2"/>
+        <metadata key="http://developer.samsung.com/tizen/metadata/test_metadata/key_a" value="value_a"/>
+        <metadata key="http://developer.samsung.com/tizen/metadata/test_metadata/key_b" value="value_b"/>
+        <metadata key="http://developer.samsung.com/tizen/metadata/test_metadata/key_c" value="value_c"/>
+        <datacontrol access="ReadOnly" providerid="http://testapp.com/datacontrol/provider/testapp" type="Sql"/>
+        <datacontrol access="ReadOnly" providerid="http://testapp.com/datacontrol/provider/testapp" type="Map"/>
+        <category name="http://tizen.org/category/test_category/value_a" />
+        <category name="http://tizen.org/category/test_category/value_b" />
+        <category name="http://tizen.org/category/test_category/value_c" />
+    </ui-application>
+    <test>
+    </test>
+</manifest>