SET(CMAKE_CXX_FLAGS_CCOV "-O0 -std=c++0x -g --coverage")
OPTION(DPL_LOG "DPL logs status" ON)
+OPTION(WITH_TESTS "Build tests" OFF)
IF(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling")
MESSAGE(STATUS "Logging enabled for DPL")
ADD_DEFINITIONS("-DDPL_LOGS_ENABLED")
ELSE(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling")
MESSAGE(STATUS "Logging disabled for DPL")
ENDIF(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling")
+MESSAGE(STATUS "WITH_TESTS: " ${WITH_TESTS})
# If supported for the target machine, emit position-independent code,suitable
# for dynamic linking and avoiding any limit on the size of the global offset
############################# subdirectories ##################################
ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(etc)
+
+IF(WITH_TESTS)
+ ADD_SUBDIRECTORY(tests)
+ENDIF(WITH_TESTS)
+wrt-installer (0.1.6) unstable; urgency=low
+
+ * code clean up - src/configuration_parser/WidgetConfigurationManager
+ * Implement tizen privilege for w3c API
+ * Fixed can't uninstall using pkgid from pkgcmd
+ * Fixed required version issue
+ * Renaming tests binaries
+ * Move installer test suites to installer repository
+
+ -- leerang Song <leerang.song@samsung.com> Fri, 22 Feb 2013 15:35:49 +0900
+
+wrt-installer (0.1.5) unstable; urgency=low
+
+ * REG_NOERROR value is not defined for function regexec.
+ * Fixed skip to validate a signature
+
+ -- Soyoung Kim <sy037.kim@samsung.com> Thu, 14 Feb 2013 19:17:48 +0900
+
wrt-installer (0.1.4) unstable; urgency=low
* Fixed uninstallation using pkgid and installation without pkgid in config.xml
-#git:framework/web/wrt-installer wrt-installer 0.1.4
+#git:framework/web/wrt-installer wrt-installer 0.1.6
Name: wrt-installer
Summary: Installer for tizen Webruntime
-Version: 0.1.4
+Version: 0.1.6
Release: 1
Group: Development/Libraries
License: Apache License, Version 2.0
BuildRequires: pkgconfig(drm-service-core-intel)
BuildRequires: pkgconfig(app2sd)
BuildRequires: pkgconfig(web-provider-svc)
+BuildRequires: pkgconfig(libprivilege-control)
Requires: xmlsec1
%description
%prep
%setup -q
+%define with_tests 0
+%if "%{WITH_TESTS}" == "ON" || "%{WITH_TESTS}" == "Y" || "%{WITH_TESTS}" == "YES" || "%{WITH_TESTS}" == "TRUE" || "%{WITH_TESTS}" == "1"
+ %define with_tests 1
+%endif
+
%build
export LDFLAGS+="-Wl,--rpath=/usr/lib -Wl,--hash-style=both -Wl,--as-needed"
cmake . -DCMAKE_INSTALL_PREFIX=/usr \
-DDPL_LOG=ON \
-DCMAKE_PACKAGE_VERSION=%{version} \
- -DCMAKE_BUILD_TYPE=%{?build_type:%build_type}
+ -DCMAKE_BUILD_TYPE=%{?build_type:%build_type} \
+ %{?WITH_TESTS:-DWITH_TESTS=%WITH_TESTS}
make %{?jobs:-j%jobs}
%install
#for booting recovery
mkdir -p /opt/share/widget/temp_info
+[ -h /etc/rc.d/rc3.d/S46lwrt_preinstall_widgets.sh ] && rm /etc/rc.d/rc3.d/S46lwrt_preinstall_widgets.sh
+[ -h /etc/rc.d/rc5.d/S46lwrt_preinstall_widgets.sh ] && rm /etc/rc.d/rc5.d/S46lwrt_preinstall_widgets.sh
+ln -s /etc/rc.d/init.d/wrt_preinstall_widgets.sh /etc/rc.d/rc3.d/S46lwrt_preinstall_widgets.sh
+ln -s /etc/rc.d/init.d/wrt_preinstall_widgets.sh /etc/rc.d/rc5.d/S46lwrt_preinstall_widgets.sh
# for downloadable Application icons path
mkdir -p /opt/share/icons/default/small
%{_datadir}/license/%{name}
%{_libdir}/systemd/user/tizen-mobile-session.target.wants/wrt-preinstall-widgets.service
%{_libdir}/systemd/user/wrt-preinstall-widgets.service
+%if %{with_tests}
+ %attr(755,root,root) %{_bindir}/wrt-installer-tests-*
+%endif
dpl-wrt-dao-ro
dpl-wrt-dao-rw
wrt-commons-custom-handler-dao-rw
+ wrt-commons-security-origin-dao
dpl-encryption
wrt-plugins-types
pkgmgr-installer
+++ /dev/null
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * @file WidgetConfigurationManager.cpp
- * @author Piotr Fatyga (p.fatyga@samsung.com)
- * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
- * @version 0.1
- * @brief
- */
-#include "WidgetConfigurationManager.h"
-#include <dirent.h>
-#include <dpl/wrt-dao-ro/global_config.h>
-#include "root_parser.h"
-#include "parser_runner.h"
-#include "widget_parser.h"
-#include <wrt_error.h>
-#include <dpl/utils/mime_type_utils.h>
-#include <dpl/localization/w3c_file_localization.h>
-#include <dpl/utils/wrt_utility.h>
-#include <dpl/singleton_impl.h>
-IMPLEMENT_SINGLETON(WidgetConfigurationManager)
-
-//TODO Rewrite this as steps/tasks
-namespace // anonymous
-{
-const char *const DEFAULT_LANGUAGE = "default";
-const size_t MAX_WIDGET_PATH_SIZE = 1024;
-
-//#define WRT_WIDGET_DEFAULT_ICON_WIDTH 80
-//#define WRT_WIDGET_DEFAULT_ICON_HEIGHT 80
-
-//#define WRT_WIDGET_CONFIG_BASE_LOCALE "locales"
-const char *const WRT_WIDGET_CONFIG_FILE_NAME = "config.xml";
-}
-
-bool WidgetConfigurationManager::locateAndParseConfigurationFile(
- const std::string& _currentPath,
- WrtDB::WidgetRegisterInfo& pWidgetConfigInfo,
- const std::string& baseFolder,
- int* pErrCode)
-{
- using namespace WrtDB;
-
- if (!pErrCode) {
- return false;
- }
-
- ConfigParserData& configInfo = pWidgetConfigInfo.configInfo;
-
- // check if this installation from browser, or not.
- size_t pos = _currentPath.rfind("/");
- std::ostringstream infoPath;
- infoPath << _currentPath.substr(pos + 1);
-
- ParserRunner parser;
- std::string language = "";
-
- if (infoPath.str() != WRT_WIDGET_CONFIG_FILE_NAME) {
- // in case of general installation using wgt archive
- //TODO: use DPL::String in the caller to this function too.
- DPL::String currentPath = DPL::FromUTF8String(_currentPath);
-
- if (currentPath.empty() || baseFolder.empty()) {
- *pErrCode = WRT_ERR_INVALID_ARG;
- return false;
- }
-
- //TODO: rewrite this madness
- char cfgAbsPath[MAX_WIDGET_PATH_SIZE + 1] = { 0 };
- DIR* dir = NULL;
- struct dirent* ptr = NULL;
-
- dir = opendir(_currentPath.c_str());
- if (dir == NULL) {
- *pErrCode = WRT_ERR_UNKNOWN;
- return false;
- }
-
- //TODO why don't we use fopen here
- bool has_config_xml = false;
- errno = 0;
- while ((ptr = readdir(dir)) != NULL) { //Find configuration file, based
- // on its name
- if (ptr->d_type == DT_REG) {
- if (!strcmp(ptr->d_name, WRT_WIDGET_CONFIG_FILE_NAME)) {
- _WrtUtilSetAbsolutePath(cfgAbsPath,
- _currentPath.c_str(), ptr->d_name);
- //Parse widget configuration file
- LogDebug("Found config: " << cfgAbsPath);
-
- Try
- {
- parser.Parse(cfgAbsPath, ElementParserPtr(new
- RootParser<
- WidgetParser>(
- configInfo,
- DPL
- ::
- FromUTF32String(
- L"widget"))));
- }
- Catch(ElementParser::Exception::Base)
- {
- LogDebug("Invalid widget configuration file!");
- // _rethrown_exception.Dump();
- *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE;
- closedir(dir);
- return false;
- }
-
- //
- // WidgetConfigurationParser & parser =
- // WidgetConfigurationParserSingleton::Instance();
- // if
- // (!parser.parseConfigurationFile(cfgAbsPath, configInfo,
- // baseFolder.c_str(), pWidgetConfigInfo.signature_type)) {
- // LogDebug("Invalid widget configuration
- // file!");
- // *pErrCode =
- // WRT_WM_ERR_INVALID_ARCHIVE;
- // closedir(dir);
- // return false;
- // }
-
- has_config_xml = true;
- break;
- }
- }
- }
- closedir(dir);
-
- //We must have config.xml so leaveing if we doesn't
- if (!has_config_xml) {
- LogDebug("Invalid archive");
- *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE;
- return false;
- }
- } else {
- // in case of browser installation
- Try
- {
- parser.Parse(_currentPath, ElementParserPtr(new
- RootParser<
- WidgetParser>(
- configInfo,
- DPL::
- FromUTF32String(
- L"widget"))));
- }
- Catch(ElementParser::Exception::Base)
- {
- LogDebug("Invalid widget configuration file!");
- // _rethrown_exception.Dump();
- *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE;
- return false;
- }
- }
-
- char *tmp_language;
- if (!_WrtUtilStringToLower(baseFolder.c_str(), &tmp_language)) {
- *pErrCode = WRT_ERR_UNKNOWN;
- return false;
- }
-
- if (!tmp_language) {
- *pErrCode = WRT_ERR_UNKNOWN;
- return false;
- }
- language = tmp_language;
- free(tmp_language);
-
- if (!!configInfo.widget_id) {
- if (!pWidgetConfigInfo.guid) {
- pWidgetConfigInfo.guid = configInfo.widget_id;
- } else {
- if (pWidgetConfigInfo.guid != configInfo.widget_id) {
- *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE;
- LogDebug("Invalid archive");
- return false;
- }
- }
- }
-
- if (!!configInfo.tizenId) {
- if (pWidgetConfigInfo.pkgName != *configInfo.tizenId) {
- *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE;
- LogDebug("Invalid archive - Tizen ID not same error");
- return false;
- }
- }
-
- if (!!configInfo.version) {
- if (!pWidgetConfigInfo.version) {
- pWidgetConfigInfo.version = configInfo.version;
- } else {
- if (pWidgetConfigInfo.version != configInfo.version) {
- *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE;
- LogDebug("Invalid archive");
- return false;
- }
- }
- }
-
- if (!!configInfo.minVersionRequired) {
- pWidgetConfigInfo.minVersion = configInfo.minVersionRequired;
- } else if (!!configInfo.tizenMinVersionRequired) {
- pWidgetConfigInfo.minVersion = configInfo.tizenMinVersionRequired;
- }
-
- return true;
-}
-
-void WidgetConfigurationManager::processFile(
- const std::string& path,
- WrtDB::WidgetRegisterInfo &
- widgetConfiguration)
-{
- int pErrCode;
-
- if (!locateAndParseConfigurationFile(path, widgetConfiguration,
- DEFAULT_LANGUAGE, &pErrCode))
- {
- LogWarning("Widget archive: Failed while parsing config file");
- ThrowMsg(Exception::ProcessFailed, path);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * @file WidgetConfigurationManager.h
- * @author Piotr Fatyga (p.fatyga@samsung.com)
- * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
- * @version 0.1
- * @brief
- */
-#ifndef _WIDGETCONFIGURATIONMANAGER_H
-#define _WIDGETCONFIGURATIONMANAGER_H
-
-#include <dpl/singleton.h>
-#include <dpl/string.h>
-#include <dpl/optional.h>
-#include <dpl/wrt-dao-ro/config_parser_data.h>
-#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
-#include <list>
-
-class WidgetConfigurationManager
-{
- public:
- class Exception
- {
- public:
- DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
- DECLARE_EXCEPTION_TYPE(Base, ProcessFailed)
- };
-
- /**
- * This method is used to process the config.xml of widget, get
- * the corresponding configuration to pWidgetConfigInfo
- *
- * @param[in] path Specified the widget archive file path (absolute path).
- * @return Configuration information of widget
- */
- void processFile(const std::string& path,
- WrtDB::WidgetRegisterInfo &wConfig);
-
- private:
- typedef std::list<std::pair<DPL::String, DPL::String> > StringPairList;
-
- bool locateAndParseConfigurationFile(
- const std::string& currentPath,
- WrtDB::WidgetRegisterInfo&
- pWidgetConfigInfo,
- const std::string& baseFolder,
- int* pErrCode);
-};
-
-typedef DPL::Singleton<WidgetConfigurationManager>
-WidgetConfigurationManagerSingleton;
-
-#endif // _WIDGETCONFIGURATIONMANAGER_H
if ((regexec(®,
DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid).
c_str(),
- static_cast<size_t>(0), NULL, 0) != REG_NOERROR) ||
+ static_cast<size_t>(0), NULL, 0) == REG_NOMATCH) ||
(checkTizenPkgIdExist(DPL::ToUTF8String(m_installerContext.widgetConfig
.tzPkgid)) &&
result != ConfigureResult::Updated))
WrtSignatureValidator::Result result;
+ WrtSignatureValidator validator(
+ appType,
+ !GlobalSettings::
+ OCSPTestModeEnabled(),
+ !GlobalSettings::
+ CrlTestModeEnabled(),
+ complianceMode);
+
+ result = validator.check(data, widgetPath);
+
if (m_contextData.widgetConfig.packagingType
== WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
{
// In directory installation mode, the validation is skipped.
result = WrtSignatureValidator::SIGNATURE_VERIFIED;
- } else {
- WrtSignatureValidator validator(
- appType,
- !GlobalSettings::
- OCSPTestModeEnabled(),
- !GlobalSettings::
- CrlTestModeEnabled(),
- complianceMode);
-
- result = validator.check(data, widgetPath);
}
if (result == WrtSignatureValidator::SIGNATURE_REVOKED) {
#include <dpl/utils/wrt_utility.h>
#include <dpl/log/log.h>
#include <dpl/assert.h>
+#include <wrt-commons/security-origin-dao/security_origin_dao.h>
#include <string>
#include <sstream>
#include <ace_api_install.h>
AddStep(&TaskDatabase::StepRegisterExternalFiles);
AddStep(&TaskDatabase::StepWrtDBInsert);
AddStep(&TaskDatabase::StepAceDBInsert);
+ AddStep(&TaskDatabase::StepSecurityOriginDBInsert);
AddStep(&TaskDatabase::StepRemoveExternalFiles);
AddStep(&TaskDatabase::StepCreateVconf);
AddStep(&TaskDatabase::StepLiveboxDBInsert);
"Update failure. ace_register_widget failed");
}
LogDebug("Ace data inserted");
+}
+
+void TaskDatabase::StepSecurityOriginDBInsert()
+{
+ LogDebug("Create Security origin database");
+ // automatically create security origin database
+ using namespace SecurityOriginDB;
+ SecurityOriginDAO dao(m_context.locations->getPkgId());
+
+ // Checking privilege list for setting security origin exception data
+ FOREACH(it, m_context.widgetConfig.configInfo.privilegeList) {
+ std::map<std::string, Feature>::const_iterator result =
+ g_W3CPrivilegeTextMap.find(DPL::ToUTF8String(it->name));
+ if (result != g_W3CPrivilegeTextMap.end()) {
+ dao.setPrivilegeSecurityOriginData(result->second);
+ }
+ }
m_context.job->UpdateProgress(
InstallerContext::INSTALL_NEW_DB_INSERT,
void StepRegisterExternalFiles();
void StepWrtDBInsert();
void StepAceDBInsert();
+ void StepSecurityOriginDBInsert();
void StepRemoveExternalFiles();
void StepCreateVconf();
void StepLiveboxDBInsert();
if (widgetVersion.IsNull() || (*widgetVersion).empty()) {
LogWarning("minVersion attribute is empty. WRT assumes platform "
"supports this widget.");
- return true;
+ return false;
}
//Parse widget version
minorWidget, microWidget))
{
LogWarning("Invalid format of widget version string.");
- return true;
+ return false;
}
//Parse supported version
* to package manager
*/
#include "package-manager-plugin.h"
+#include <regex.h>
#include <dlog.h>
#include <dpl/wrt-dao-ro/global_config.h>
#include <vcore/VCore.h>
static int pkg_plugin_app_is_installed(const char *pkg_name)
{
+ const char* REG_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
LogDebug("pkg_plugin_app_is_installed() is called");
WrtDB::WrtDatabase::attachToThreadRO();
- bool result = WidgetDAOReadOnly::isWidgetInstalled(
- DPL::FromUTF8String(pkg_name));
+ regex_t reg;
+ if (regcomp(®, REG_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+ LogDebug("Regcomp failed");
+ }
+
+ WrtDB::TizenAppId appid;
+
+ if ((regexec(®, pkg_name,
+ static_cast<size_t>(0), NULL, 0) == 0))
+ {
+ WrtDB::TizenPkgId pkgid(DPL::FromUTF8String(pkg_name));
+ appid = WidgetDAOReadOnly::getTzAppId(pkgid);
+ } else {
+ appid = DPL::FromUTF8String(pkg_name);
+ }
+
+ bool result = WidgetDAOReadOnly::isWidgetInstalled(appid);
WrtDB::WrtDatabase::detachFromThread();
if (result) {
--- /dev/null
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# @file CMakeLists.txt
+# @author Karol Pawlowski (k.pawlowski@samsung.com)
+#
+
+
+ADD_SUBDIRECTORY(general)
--- /dev/null
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# @file CMakeLists.txt
+# @author Karol Pawlowski (k.pawlowski@samsung.com)
+#
+
+
+# TODO cleanup dependencies
+PKG_CHECK_MODULES(COMMON_LIB_PKGS
+ dbus-1
+ libpcrecpp
+ dpl-efl
+ dpl-test-efl
+ dpl-utils-efl
+ dpl-wrt-dao-ro
+ dpl-event-efl
+ glib-2.0
+ gthread-2.0
+ edje
+ ecore
+ ecore-x
+ ecore-imf
+ ecore-ipc
+ ecore-evas
+ ecore-file
+ ecore-input
+ evas
+ eina
+ elementary
+ vconf
+ aul
+ libidn
+ xmlsec1
+ libiri
+ REQUIRED
+ )
+
+INCLUDE(CMakeUtils.txt)
+
+pkg_search_module(dpl REQUIRED dpl-efl)
+pkg_search_module(dpl-test REQUIRED dpl-test-efl)
+
+SET(WRT_TEST_LIBRARY "wrt-tests-libs")
+
+include_directories(
+ ${dpl_INCLUDE_DIRS}
+ ${dpl-test_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/common
+)
+
+ADD_SUBDIRECTORY(common)
+
+SET(INSTALLER_TESTS_SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/TestInit.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/TestCases.cpp
+)
+
+SET(INSTALLER_TESTS_TARGET "wrt-installer-tests-general")
+
+WRT_TEST_BUILD(${INSTALLER_TESTS_TARGET} ${INSTALLER_TESTS_SOURCES})
+WRT_TEST_INSTALL(${INSTALLER_TESTS_TARGET})
+target_link_libraries(${INSTALLER_TESTS_TARGET}
+ ${dpl_LIBRARIES}
+ ${dpl-test_LIBRARIES}
+ ${WRT_TEST_LIBRARY}
+ ${TARGET_CORE_MODULE_LIB}
+ ${COMMON_LIB_PKGS_LIBRARIES}
+)
--- /dev/null
+# @file CMakeUtils.txt
+# @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com)
+# @author Pawel Sikorski (p.sikorski@samsung.com)
+# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+# @version 1.0
+# @brief
+#
+
+#
+# Discovers target's INCLUDE_DIRECTORIES and LINK_DIRECTORIES.
+# This is done by retrieving the directory target was built in and
+# fetching appropriate properties of that directory.
+FUNCTION(WRT_INTROSPECT_TARGET PREFIX TARGET_NAME)
+ GET_TARGET_PROPERTY(LOCATION ${TARGET_NAME} LOCATION)
+ IF(${LOCATION} STREQUAL "LOCATION-NOTFOUND")
+ MESSAGE(FATAL_ERROR "Target '${TARGET_NAME}' introspection failed")
+ ELSE(${LOCATION} STREQUAL "LOCATION-NOTFOUND")
+ STRING(FIND ${LOCATION} "/" LAST_SLASH_POSITION REVERSE)
+ STRING(SUBSTRING ${LOCATION} 0 ${LAST_SLASH_POSITION} LOCATION)
+
+ GET_DIRECTORY_PROPERTY(INCLUDE_DIRS DIRECTORY ${LOCATION} INCLUDE_DIRECTORIES)
+ SET("${PREFIX}_INCLUDE_DIRS" ${INCLUDE_DIRS} PARENT_SCOPE)
+
+ GET_DIRECTORY_PROPERTY(LIBRARY_DIRS DIRECTORY ${LOCATION} LINK_DIRECTORIES)
+ SET("${PREFIX}_LIBRARY_DIRS" ${LIBRARY_DIRS} PARENT_SCOPE)
+ ENDIF(${LOCATION} STREQUAL "LOCATION-NOTFOUND")
+ENDFUNCTION(WRT_INTROSPECT_TARGET)
+
+FUNCTION(WRT_TEST_LIBRARY)
+ SET_PROPERTY(GLOBAL APPEND PROPERTY COMMON_TESTS_LIBRARY ${ARGV})
+ENDFUNCTION(WRT_TEST_LIBRARY)
+
+#
+# Replacement functions for standard (w/o "WRT_" prefix) CMake functions.
+# They store supplied arguments in global properties to assign them to tests.
+# Anything added with this functions is used by all targets that are built with
+# WRT_TEST_BUILD function.
+
+#
+# Appends directories to global property TESTS_INCLUDE_DIRS which is
+# then read by WRT_TEST_BUILD and its content is forwarded to
+# command INCLUDE_DIRECTORIES() (for all targets).
+FUNCTION(WRT_INCLUDE_DIRECTORIES)
+ SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_INCLUDE_DIRS ${ARGV})
+ENDFUNCTION(WRT_INCLUDE_DIRECTORIES)
+
+#
+# Appends directories to global property TESTS_LIBRARY_DIRS which is
+# then read by WRT_TEST_BUILD and its content is forwarded to
+# command LINK_DIRECTORIES() (for all targets).
+FUNCTION(WRT_LINK_DIRECTORIES)
+ SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_LIBRARY_DIRS ${ARGV})
+ENDFUNCTION(WRT_LINK_DIRECTORIES)
+
+#
+# Appends directories to global property TESTS_LIBRARIES which is
+# then read by WRT_TEST_BUILD and its content is forwarded to
+# command TARGET_LINK_LIBRARIES() (for all targets).
+FUNCTION(WRT_TARGET_LINK_LIBRARIES)
+ SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_LIBRARIES ${ARGV})
+ENDFUNCTION(WRT_TARGET_LINK_LIBRARIES)
+
+#
+# Convenience method that fills TESTS_INCLUDE_DIRS, TESTS_LIBRARY_DIRS
+# and TESTS_LIBRARIES with values discovered from introspecting supplied
+# targets.
+# Function takes arbitrary number of targets.
+FUNCTION(WRT_ADD_INTERNAL_DEPENDENCIES)
+ FOREACH(DEPENDENCY ${ARGV})
+ WRT_INTROSPECT_TARGET(prefix ${DEPENDENCY})
+ WRT_INCLUDE_DIRECTORIES(${prefix_INCLUDE_DIRS})
+ WRT_LINK_DIRECTORIES(${prefix_LIBRARY_DIRS})
+ WRT_TARGET_LINK_LIBRARIES(${DEPENDENCY})
+ ENDFOREACH(DEPENDENCY)
+ENDFUNCTION(WRT_ADD_INTERNAL_DEPENDENCIES)
+
+
+#
+# Replacement functions for standard (w/o "WRT_" prefix) CMake functions.
+# They store supplied arguments in global properties to assign them to specific
+# tests. Properties names are based on the test target name.
+# Anything added with this functions is used only by the specified target that
+# is built with WRT_TEST_BUILD function.
+
+#
+# Appends directories to global property ${TARGET_NAME}_INCLUDE_DIRS
+# which is then read by WRT_TEST_BUILD and its content is forwarded to
+# command INCLUDE_DIRECTORIES() (for specified target).
+FUNCTION(WRT_TEST_INCLUDE_DIRECTORIES TARGET_NAME)
+ SET_PROPERTY(GLOBAL APPEND PROPERTY ${TARGET_NAME}_INCLUDE_DIRS ${ARGN})
+ENDFUNCTION(WRT_TEST_INCLUDE_DIRECTORIES)
+
+#
+# Appends directories to global property ${TARGET_NAME}_LIBRARY_DIRS
+# which is then read by WRT_TEST_BUILD and its content is forwarded to
+# command LINK_DIRECTORIES() (for specified target).
+FUNCTION(WRT_TEST_LINK_DIRECTORIES TARGET_NAME)
+ SET_PROPERTY(GLOBAL APPEND PROPERTY ${TARGET_NAME}_LIBRARY_DIRS ${ARGN})
+ENDFUNCTION(WRT_TEST_LINK_DIRECTORIES)
+
+#
+# Appends directories to global property ${TARGET_NAME}_LIBRARIES
+# which is then read by WRT_TEST_BUILD and its content is forwarded to
+# command TARGET_LINK_LIBRARIES() (for specified target).
+FUNCTION(WRT_TEST_TARGET_LINK_LIBRARIES TARGET_NAME)
+ SET_PROPERTY(GLOBAL APPEND PROPERTY ${TARGET_NAME}_LIBRARIES ${ARGN})
+ENDFUNCTION(WRT_TEST_TARGET_LINK_LIBRARIES)
+
+#
+# Convenience method that fills ${TARGET_NAME}_INCLUDE_DIRS,
+# ${TARGET_NAME}_LIBRARY_DIRS and ${TARGET_NAME}_LIBRARIES with
+# values discovered from introspecting supplied targets.
+# Function takes arbitrary number of targets.
+FUNCTION(WRT_TEST_ADD_INTERNAL_DEPENDENCIES TARGET_NAME)
+ FOREACH(DEPENDENCY ${ARGN})
+ WRT_INTROSPECT_TARGET(prefix ${DEPENDENCY})
+ WRT_TEST_INCLUDE_DIRECTORIES(${TARGET_NAME} ${prefix_INCLUDE_DIRS})
+ WRT_TEST_LINK_DIRECTORIES(${TARGET_NAME} ${prefix_LIBRARY_DIRS})
+ WRT_TEST_TARGET_LINK_LIBRARIES(${TARGET_NAME} ${DEPENDENCY})
+ ENDFOREACH(DEPENDENCY)
+ENDFUNCTION(WRT_TEST_ADD_INTERNAL_DEPENDENCIES)
+
+# Functions used to build test targets (proper sources, includes, libs are
+# added automatically)
+FUNCTION(WRT_TEST_BUILD TARGET_NAME)
+ SET(SOURCES "${ARGN}")
+ ADD_EXECUTABLE("${TARGET_NAME}" ${SOURCES})
+
+ # get include dirs global property
+ GET_PROPERTY(INCLUDE_DIRS GLOBAL PROPERTY TESTS_INCLUDE_DIRS)
+ GET_PROPERTY(TEST_INCLUDE_DIRS GLOBAL PROPERTY ${TARGET_NAME}_INCLUDE_DIRS)
+ INCLUDE_DIRECTORIES(
+ ${INCLUDE_DIRS}
+ ${TEST_INCLUDE_DIRS}
+ )
+
+ # get library dirs global property
+ GET_PROPERTY(LIBRARY_DIRS GLOBAL PROPERTY TESTS_LIBRARY_DIRS)
+ GET_PROPERTY(TEST_LIBRARY_DIRS GLOBAL PROPERTY ${TARGET_NAME}_LIBRARY_DIRS)
+ LINK_DIRECTORIES(
+ ${LIBRARY_DIRS}
+ ${TEST_LIBRARY_DIRS}
+ )
+
+ # get link libraries global property
+ GET_PROPERTY(LINK_LIBRARIES GLOBAL PROPERTY TESTS_LIBRARIES)
+ GET_PROPERTY(TEST_LIBRARIES GLOBAL PROPERTY ${TARGET_NAME}_LIBRARIES)
+ TARGET_LINK_LIBRARIES("${TARGET_NAME}"
+ ${LINK_LIBRARIES}
+ ${TEST_LIBRARIES}
+ )
+ENDFUNCTION(WRT_TEST_BUILD)
+
+FUNCTION(WRT_TEST_INSTALL)
+ SET_TARGET_PROPERTIES(${ARGV} PROPERTIES
+ BUILD_WITH_INSTALL_RPATH ON
+ INSTALL_RPATH_USE_LINK_PATH ON
+ )
+ INSTALL(TARGETS ${ARGV}
+ DESTINATION bin
+ PERMISSIONS OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ GROUP_EXECUTE
+ WORLD_READ
+ WORLD_EXECUTE
+ )
+ENDFUNCTION(WRT_TEST_INSTALL)
+
+# Takes arbitrary number of arguments and concatenates them using ':' character.
+# Rationale:
+# CMake list when converted to a string is joined with ';' character. However,
+# GCC takes strings with multiple elements separated with ':' (e.g. list of
+# paths). Used typically when generating DB schemas with ORM mechanism.
+FUNCTION(WRT_CONVERT_TO_GCC_LIST OUTPUT_VARIABLE)
+ FOREACH(ITEM ${ARGN})
+ LIST(APPEND ITEMS ${ITEM})
+ ENDFOREACH(ITEM)
+ STRING(REPLACE ";" ":" OUTPUT "${ITEMS}")
+ SET("${OUTPUT_VARIABLE}" "${OUTPUT}" PARENT_SCOPE)
+ENDFUNCTION(WRT_CONVERT_TO_GCC_LIST)
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file TestCases.cpp
+ * @author Karol Pawlowski (k.pawlowski@samsung.com)
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ * @brief Miscellaneous test's bodies
+ */
+
+#include <string>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+#include <InstallerWrapper.h>
+#include <ManifestFile.h>
+
+using namespace InstallerWrapper;
+
+namespace {
+
+const std::string miscWidgetsStuff = "/opt/share/widget/tests/misc/";
+
+struct Result {
+ bool m_exc;
+ bool m_exd;
+ bool m_exs;
+ std::string message;
+ Result(bool exc = false, bool exd = false, bool exs = false)
+ : m_exc(exc), m_exd(exd), m_exs(exs) {}
+};
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(Manifest)
+
+/*
+Name: creatingManifestFile
+Description: Creation of manifest file by wrt-installer test
+Expected: file should be created and installed by wrt-installer. Content should
+ match expected values
+*/
+RUNNER_TEST(creatingManifestFile)
+{
+ const char * manifestPath = "/opt/share/packages/manifest01.xml";
+ /* This widget removal should stay here in case previous test run failed
+ * (so widget has not been uninstalled) */
+ uninstallByGuid("http://test.samsung.com/widget/manifestTest");
+ std::string tizenId;
+ RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/manifest.wgt", tizenId)
+ == InstallerWrapper::Success);
+ RUNNER_ASSERT(WrtUtilFileExists(manifestPath));
+ ManifestFile mf(manifestPath);
+
+ Try
+ {
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/@package")
+ == "manifest01");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/@type")
+ == "wgt");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/@version")
+ == "1.0");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:label")
+ == "Manifest Example");
+
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:author/@email")
+ == "manifest@misc.test.create.desktop.com");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:author/@href")
+ == "http://misc.test.create.desktop.com");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:author")
+ == "Manifest");
+
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/@appid")
+ == "manifest01");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/@nodisplay")
+ == "false");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/@type")
+ == "webapp");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/@extraid")
+ == "http://test.samsung.com/widget/manifestTest");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/@taskmanage")
+ == "true");
+
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:icon")
+ == "manifest01.png");
+
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:label[not(@xml:lang)]")
+ == "Manifest Example");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:label[@xml:lang='de_DE']")
+ == "Manifest Beispiel");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:label[@xml:lang='en_US']")
+ == "Manifest Example");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:label[@xml:lang='pl']")
+ == "Przykład Manifest");
+ RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:label[@xml:lang='pt_PT']")
+ == "Exemplo manifesto");
+ }
+ Catch(ManifestFile::ManifestParseError)
+ {
+ RUNNER_ASSERT_MSG(false,DPL::Exception::KnownExceptionToString(_rethrown_exception));
+ }
+ /* If test finished sucessfully than uninstall test widget */
+ uninstall(tizenId);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(BackgroundPage)
+
+/*
+Name: widgetWithBackgroundPage
+Description: Tests if widget with background page is installed correctly
+Expected: widget should be installed correctly
+*/
+RUNNER_TEST(widgetWithBackgroundPage)
+{
+ std::string tizenId;
+ RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/bg-00-with_bg.wgt",
+ tizenId) == InstallerWrapper::Success);
+ uninstall(tizenId);
+}
+
+/*
+Name: missingBackgroundFile
+Description: Tests if widget with declared in conifg background page
+ but missing background file will be installed correctly.
+Expected: widget should NOT be installed
+*/
+RUNNER_TEST(missingBackgroundFile)
+{
+ std::string tizenId;
+ if(install(miscWidgetsStuff + "widgets/bg-01-missing_file.wgt",
+ tizenId) == InstallerWrapper::Success) {
+ uninstall(tizenId);
+ RUNNER_ASSERT_MSG(false, "Invalid widget package installed");
+ }
+}
+
+/*
+Name: widgetWithoutBackgroundPage
+Description: Complementary test to check if normal widget\
+ without background page is successfully installed
+Expected: widget should be installed
+*/
+RUNNER_TEST(widgetWithoutBackgroundPage)
+{
+ std::string tizenId;
+ RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/bg-02-without_bg.wgt",
+ tizenId) == InstallerWrapper::Success);
+ uninstall(tizenId);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(NonRootUser)
+
+/*
+Name: widgetNonRootInstallation
+Description: Check installation from other user than root
+Expected: widget should be installed
+*/
+RUNNER_TEST(widgetNonRootInstallation)
+{
+ std::string tizenId;
+ RUNNER_ASSERT(install(
+ miscWidgetsStuff + "widgets/nonroot.wgt",
+ tizenId,
+ "app") == InstallerWrapper::Success);
+ uninstall(tizenId);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(NPluginsInstall)
+
+/*
+Name: pluginFilesAdded
+Description: Tests installation of plugins attached to widget
+Expected: widget should be succesfully installed
+*/
+RUNNER_TEST(pluginFilesAdded)
+{
+ std::string tizenId;
+ RUNNER_ASSERT(install(miscWidgetsStuff
+ + "widgets/inst_nplug_1.wgt", tizenId) == InstallerWrapper::Success);
+ uninstall(tizenId);
+}
+
+/*
+Name: emptyPluginsDir
+Description: Tests installation with empty 'plugins' directory
+Expected: widget should be not installed
+*/
+RUNNER_TEST(emptyPluginsDir)
+{
+ std::string tizenId;
+ if(install(miscWidgetsStuff + "widgets/inst_nplug_2.wgt",
+ tizenId) == InstallerWrapper::Success) {
+ uninstall(tizenId);
+ RUNNER_ASSERT_MSG(false, "Invalid widget package installed");
+ }
+}
+
+/*
+Name: pluginFileAndOtherFile
+Description: Tests installation with plugins directory and data files
+Expected: widget should be installed
+*/
+RUNNER_TEST(pluginFileAndOtherFile)
+{
+ std::string tizenId;
+ RUNNER_ASSERT(install(miscWidgetsStuff
+ + "widgets/inst_nplug_3.wgt", tizenId) == InstallerWrapper::Success);
+ uninstall(tizenId);
+}
+
+/*
+Name: pluginFileAndSubdir
+Description: Tests installation with 'plugins' directory and subdirectories
+ inside plugin directory
+Expected: widget should be not installed
+*/
+RUNNER_TEST(pluginFileAndSubdir)
+{
+ std::string tizenId;
+ if(install(miscWidgetsStuff + "widgets/inst_nplug_4.wgt",
+ tizenId) == InstallerWrapper::Success) {
+ uninstall(tizenId);
+ RUNNER_ASSERT_MSG(false, "Invalid widget package installed");
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file TestInit.cpp
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ * @brief main for misc tests
+ */
+
+#include <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+
+int main (int argc, char *argv[])
+{
+ LogInfo("Starting tests");
+
+ WrtDB::WrtDatabase::attachToThreadRW();
+ int status =
+ DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+ WrtDB::WrtDatabase::detachFromThread();
+
+ return status;
+}
--- /dev/null
+# Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# @file CMakeLists.txt
+# @author Tomasz Iwanek (t.iwanek@samsung.com)
+# @author Karol Pawlowski (k.pawlowski@samsung.com)
+# @version 1.0
+# @brief
+#
+
+SET(COMMON_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/include")
+
+WRT_TEST_LIBRARY(${WRT_TEST_LIBRARY})
+
+WRT_INCLUDE_DIRECTORIES(
+ ${COMMON_LIB_PKGS_INCLUDE_DIRS}
+ ${COMMON_INCLUDES}
+ )
+WRT_LINK_DIRECTORIES(${COMMON_LIB_PKGS_LIBRARY_DIRS})
+WRT_TARGET_LINK_LIBRARIES(${COMMON_LIB_PKGS_LIBRARIES})
+
+SET(WRT_DETAIL_SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/InstallerWrapper.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/ManifestFile.cpp
+)
+
+INCLUDE_DIRECTORIES(${COMMON_INCLUDES})
+INCLUDE_DIRECTORIES(${COMMON_LIB_PKGS_INCLUDE_DIRS})
+
+ADD_LIBRARY(${WRT_TEST_LIBRARY} STATIC ${WRT_DETAIL_SOURCES})
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WRT_INSTALLER_TESTS_GENERAL_COMMON_INCLUDE_INSTALLER_WRAPPER_H
+#define WRT_INSTALLER_TESTS_GENERAL_COMMON_INCLUDE_INSTALLER_WRAPPER_H
+
+#include <string>
+
+namespace InstallerWrapper
+{
+
+typedef int InstallResult;
+const InstallResult WrongWidgetPackage = -2;
+const InstallResult OtherError = -1;
+const InstallResult Success = 0;
+
+InstallResult install(
+ const std::string& path,
+ std::string& tizenId,
+ const std::string& user = "");
+bool uninstall(const std::string& tizenId);
+bool uninstallByGuid(const std::string& guid);
+/**
+ * @brief killWrtClients kills processes that matches 'wrt-client'
+ * @return True if any client was killed
+ */
+bool sigintWrtClients();
+
+}
+
+#endif//WRT_INSTALLER_TESTS_GENERAL_COMMON_INCLUDE_INSTALLER_WRAPPER_H
--- /dev/null
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file ManifestFile.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Manifest file reading
+ */
+
+#ifndef WRT_INSTALLER_TESTS_GENERAL_COMMON_INCLUDE_MANIFESTFILE_H
+#define WRT_INSTALLER_TESTS_GENERAL_COMMON_INCLUDE_MANIFESTFILE_H
+
+#include <string>
+
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include <dpl/exception.h>
+
+/**
+ * @brief The ManifestFile class which serialize xml file to tree
+ */
+class ManifestFile
+{
+public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception,Base)
+ DECLARE_EXCEPTION_TYPE(Base,ManifestParseError)
+
+ ManifestFile(const std::string & file);
+ ~ManifestFile();
+
+ std::string getValueByXpath(const std::string & path) const;
+private:
+ void parse();
+
+ std::string filename;
+ xmlDocPtr doc;
+ xmlXPathContextPtr xpathCtx;
+};
+
+
+#endif //WRT_INSTALLER_TESTS_GENERAL_COMMON_INCLUDE_MANIFESTFILE_H
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "InstallerWrapper.h"
+
+#include <dpl/log/log.h>
+
+#include <cstdio>
+
+namespace
+{
+
+const std::string params = "DPL_USE_OLD_STYLE_LOGS=0 "
+ "DPL_USE_OLD_STYLE_PEDANTIC_LOGS=0 WRT_TEST_MODE=1 ";
+const std::string installCmd = params + "wrt-installer -if ";
+const std::string uninstallCmd = params + "wrt-installer -un ";
+const std::string uninstallByGuidCmd = params + "wrt-installer -ug \"";
+const std::string redirection = " 2>&1";
+const std::string INSTALLER_MESSAGE_ID_LINE =
+ "## wrt-installer : %s installation was successful.\n";
+const std::string INSTALLER_MESSSGE_START = "## wrt-installer : ";
+
+std::string getAndCutInstallerLogLine(std::string &src)
+{
+ size_t startIndex = src.find(INSTALLER_MESSSGE_START);
+ if (startIndex == std::string::npos)
+ {
+ LogWarning("Installer message can not be found");
+ return std::string();
+ }
+ size_t newLineIndex = src.find("\n", startIndex);
+ std::string line = src.substr(startIndex, newLineIndex - startIndex + 1);
+ src.erase(0, newLineIndex + 1);
+ return line;
+}
+
+}
+
+namespace InstallerWrapper
+{
+
+InstallResult install(
+ const std::string& path,
+ std::string& tizenId,
+ const std::string& user)
+{
+ std::string msg;
+
+ auto cmd = installCmd + path + redirection;
+ if(user.length()) //if other user should be used
+ {
+ cmd = "su " + user + " -c '" + cmd + "'";
+ }
+ auto filehandle = popen(cmd.c_str(), "r");
+ if (!filehandle) {;
+ return OtherError;
+ }
+
+ char buffer[1024] = "";
+ int ret;
+ while ((ret = fread_unlocked(buffer,
+ sizeof(char),
+ sizeof(buffer)/sizeof(char),
+ filehandle)) > 0)
+ {
+ msg += buffer;
+ }
+ LogDebug(msg);
+ auto err = pclose(filehandle);
+ if (!WIFEXITED(err)) {
+ return OtherError;
+ }
+ if (0 != WEXITSTATUS(err)) {
+ if (1 == WEXITSTATUS(err)) {
+ return WrongWidgetPackage;
+ }
+ return OtherError;
+ }
+
+ char* id = NULL;
+ std::string line;
+
+ while ((line = getAndCutInstallerLogLine(msg)) != "")
+ {
+ if (line.find("successful") != std::string::npos)
+ {
+ id = new char[line.length()];
+ int nr = sscanf(line.c_str(), INSTALLER_MESSAGE_ID_LINE.c_str(), id);
+
+ if (1 != nr)
+ {
+ LogWarning("Can not read widget ID from message: " << line);
+ delete[] id;
+ return OtherError;
+ }
+ tizenId = id;
+ delete[] id;
+ if (tizenId != "plugin")
+ {
+ return Success;
+ }
+ }
+ }
+
+ return OtherError;
+}
+
+bool uninstall(const std::string& tizenId)
+{
+ std::string cmd = uninstallCmd + tizenId + " > /dev/null 2>/dev/null";
+ LogDebug("executing: " << cmd);
+ return (system(cmd.c_str()) == EXIT_SUCCESS);
+}
+
+bool uninstallByGuid(const std::string& guid)
+{
+ std::string cmd = uninstallByGuidCmd + guid + "\" > /dev/null 2>/dev/null";
+ LogDebug("executing: " << cmd);
+ return (system(cmd.c_str()) == EXIT_SUCCESS);
+}
+
+bool sigintWrtClients()
+{
+ return (system("pkill -2 wrt-client") == 0);
+}
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file ManifestFile.cpp
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Manifest file reading
+ */
+
+#include <ManifestFile.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <dpl/log/log.h>
+
+//TODO: This file reads manifest file. This functionality is familiar with writing
+// in wrt-installer but reading ws not necessary there.
+// Maybe it should be changed in some way.
+
+ManifestFile::ManifestFile(const std::string & file) : filename(file)
+{
+ xmlInitParser();
+ LIBXML_TEST_VERSION
+ xmlXPathInit();
+ parse();
+}
+
+ManifestFile::~ManifestFile()
+{
+ xmlXPathFreeContext(xpathCtx);
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+}
+
+void ManifestFile::parse()
+{
+ doc = xmlReadFile(filename.c_str(), NULL, 0);
+ if (doc == NULL)
+ {
+ ThrowMsg(ManifestParseError,"File Problem");
+ }
+ else
+ {
+ //context
+ xpathCtx = xmlXPathNewContext(doc);
+ if(xpathCtx == NULL)
+ {
+ ThrowMsg(ManifestParseError,"Error: unable to create new XPath context\n");
+ }
+ xpathCtx->node = xmlDocGetRootElement(doc);
+
+ if(xmlXPathRegisterNs(xpathCtx, BAD_CAST "p", BAD_CAST "http://tizen.org/ns/packages") != 0)
+ {
+ ThrowMsg(ManifestParseError,"Error: unable to register namespace\n");
+ }
+ }
+}
+
+std::string ManifestFile::getValueByXpath(const std::string & path) const
+{
+ std::string result;
+ xmlXPathObjectPtr xpathObject;
+ //get requested node's values
+ xpathObject = xmlXPathEvalExpression(BAD_CAST path.c_str(), xpathCtx);
+ if(xpathObject == NULL)
+ {
+ ThrowMsg(ManifestParseError,"XPath evaluation failure: " << path);
+ }
+ xmlNodeSetPtr nodes = xpathObject->nodesetval;
+ int size = (nodes) ? nodes->nodeNr : 0;
+ if(size != 1)
+ {
+ ThrowMsg(ManifestParseError,"Xpath does not point 1 element but " << size
+ << " for xpath: " << path);
+ }
+ else
+ {
+ if(nodes->nodeTab[0]->type == XML_ELEMENT_NODE)
+ {
+ xmlNodePtr cur = nodes->nodeTab[0];
+ xmlChar * value = xmlNodeGetContent(cur);
+ result = std::string(reinterpret_cast<char*>(value)); //this cast should be safe...
+ xmlFree(value);
+ }
+ else if(nodes->nodeTab[0]->type == XML_ATTRIBUTE_NODE)
+ {
+ xmlNodePtr cur = nodes->nodeTab[0];
+ xmlChar * value = xmlNodeGetContent(cur);
+ result = std::string(reinterpret_cast<char*>(value));
+ xmlFree(value);
+ }
+ }
+ //Cleanup of XPath data
+ xmlXPathFreeObject(xpathObject);
+ return result;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen = "http://tizen.org/ns/widgets" id="htpp://custom_handlers6">
+ <tizen:application id="listener02" required_version="1.0"/>
+ <name>listener02</name>
+</widget>
+
--- /dev/null
+var id = "listener02";
+
+function hook(id, result, message){};
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+ <script type="text/javascript">
+ try {
+ navigator.registerContentHandler("application/test", "test.html?uri=%s", "Example content");
+ if (navigator.isContentHandlerRegistered("application/test", "test.html?uri=%s") === 'registered') {
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'content handler registered');
+ } else {
+ hook(id, 'fail', 'content handler not registered');
+ }
+ } catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+ }
+</script>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+ <script type="text/javascript">
+ try {
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'content handler registered');
+ } catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+ }
+</script>
+</body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen = "http://tizen.org/ns/widgets" id="htpp://custom_handlers8">
+ <tizen:application id="listener04" required_version="1.0"/>
+ <name>listener04</name>
+</widget>
+
--- /dev/null
+var id = "listener02";
+
+function hook(id, result, message){};
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+ <script type="text/javascript">
+ try {
+ navigator.registerContentHandler("application/test", "test.html?uri=%s", "Example content");
+ if (navigator.isContentHandlerRegistered("application/test", "test.html?uri=%s") === 'registered') {
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'content handler registered');
+ } else {
+ hook(id, 'fail', 'content handler not registered');
+ }
+ } catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+ }
+</script>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+ <script type="text/javascript">
+ try {
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'content handler registered');
+ } catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+ }
+</script>
+</body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen = "http://tizen.org/ns/widgets" id="htpp://custom_handlers5">
+ <tizen:application id="listener01" required_version="1.0"/>
+ <name>listener01</name>
+</widget>
+
--- /dev/null
+var id = "listener01";
+
+function hook(id, result, message){};
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+ <script type="text/javascript">
+ try {
+ navigator.registerProtocolHandler("news", "news.html?uri=%s", "Example news");
+ if (navigator.isProtocolHandlerRegistered("news", "news.html?uri=%s") === 'registered') {
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'protocol handler registered');
+ } else {
+ hook(id, 'fail', 'protocol handler not registered');
+ }
+ } catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+ }
+</script>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+ <script type="text/javascript">
+ try {
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'protocol handler registered');
+ } catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+ }
+</script>
+</body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen = "http://tizen.org/ns/widgets" id="htpp://custom_handlers7">
+ <tizen:application id="listener03" required_version="1.0"/>
+ <name>listener03</name>
+</widget>
+
--- /dev/null
+var id = "listener01";
+
+function hook(id, result, message){};
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+ <script type="text/javascript">
+ try {
+ navigator.registerProtocolHandler("news", "news.html?uri=%s", "Example news");
+ if (navigator.isProtocolHandlerRegistered("news", "news.html?uri=%s") === 'registered') {
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'protocol handler registered');
+ } else {
+ hook(id, 'fail', 'protocol handler not registered');
+ }
+ } catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+ }
+</script>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+ <script type="text/javascript">
+ try {
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'protocol handler registered');
+ } catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+ }
+</script>
+</body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen = "http://tizen.org/ns/widgets" id="htpp://custom_handlers3">
+ <tizen:application id="register03" required_version="1.0"/>
+ <name>register03</name>
+</widget>
+
--- /dev/null
+var id = "register03";
+
+function hook(id, result, message){};
+
+try {
+ navigator.registerContentHandler("application/test", "?uri=%s", "Example content");
+ if (navigator.isContentHandlerRegistered("application/test", "?uri=%s") === 'registered') {
+ navigator.unregisterContentHandler("application/test", "?uri=%s");
+ if (navigator.isContentHandlerRegistered("application/test", "?uri=%s") === 'new') {
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'content handler registered');
+ } else {
+ hook(id, 'fail', 'content handler registered (tried to unregister)');
+ }
+ } else {
+ hook(id, 'fail', 'content handler not registered');
+ }
+} catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+}
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+</body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen = "http://tizen.org/ns/widgets" id="htpp://custom_handlers4">
+ <tizen:application id="register04" required_version="1.0"/>
+ <name>register04</name>
+</widget>
+
--- /dev/null
+var id = "register04";
+
+function hook(id, result, message){};
+
+try {
+ try {
+ navigator.registerContentHandler("text/html", "?uri=%s", "Example http");
+ throw new Error("Exception not thrown!");
+ } catch (e) {
+ if (!(e instanceof DOMException) || e.code != 18 || e.name != "SECURITY_ERR") {
+ throw e;
+ }
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'content handler not registered');
+ }
+} catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+}
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+</body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen = "http://tizen.org/ns/widgets" id="htpp://custom_handlers1">
+ <tizen:application id="register01" required_version="1.0"/>
+ <name>register01</name>
+</widget>
+
--- /dev/null
+var id = "register01";
+
+function hook(id, result, message){};
+
+try {
+ navigator.registerProtocolHandler("news", "?uri=%s", "Example magnet");
+ if (navigator.isProtocolHandlerRegistered("news", "?uri=%s") === 'registered') {
+ navigator.unregisterProtocolHandler("news", "?uri=%s");
+ if (navigator.isProtocolHandlerRegistered("news", "?uri=%s") === 'new') {
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'protocol handler registered');
+ } else {
+ hook(id, 'fail', 'protocol handler registered (tried to unregister)');
+ }
+ } else {
+ hook(id, 'fail', 'protocol handler not registered');
+ }
+} catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+}
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+</body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen = "http://tizen.org/ns/widgets" id="htpp://custom_handlers2">
+ <tizen:application id="register02" required_version="1.0"/>
+ <name>register02</name>
+</widget>
+
--- /dev/null
+var id = "register02";
+
+function hook(id, result, message){};
+
+try {
+ try {
+ navigator.registerProtocolHandler("http", "?uri=%s", "Example http");
+ throw new Error("Exception not thrown!");
+ } catch (e) {
+ if (!(e instanceof DOMException) || e.code != 18 || e.name != "SECURITY_ERR") {
+ throw e;
+ }
+ document.getElementById('test').innerHTML = 'PASSED';
+ document.body.style.backgroundColor = 'green';
+ hook(id, 'pass', 'protocol handler not registered');
+ }
+} catch (e) {
+ hook(id, 'fail', 'widget failed because ' + e.message);
+}
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width" />
+ <title>Custom handlers</title>
+</head>
+<body style="background-color:red;">
+ <h1 id="test">FAIL</h1>
+ <script type="text/javascript" src="hook.js"></script>
+</body>
+</html>