You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2017/04/10 20:39:31 UTC
celix git commit: CELIX-408: Initial commit for adding add_runtime
command. Also add some usage for running/testing pubsub
Repository: celix
Updated Branches:
refs/heads/feature/CELIX-408_runtime [created] 97df926c2
CELIX-408: Initial commit for adding add_runtime command. Also add some usage for running/testing pubsub
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/97df926c
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/97df926c
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/97df926c
Branch: refs/heads/feature/CELIX-408_runtime
Commit: 97df926c2289323379506d47a6095b0182d752b7
Parents: 0616690
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Sat Apr 8 21:26:39 2017 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Apr 10 22:37:29 2017 +0200
----------------------------------------------------------------------
cmake/CMakeCelix.cmake | 1 +
cmake/cmake_celix/DeployPackaging.cmake | 22 +-
cmake/cmake_celix/Runtimes.cmake | 161 +++++++++++++++
cmake/cmake_celix/runtime_common.sh.in | 152 ++++++++++++++
cmake/cmake_celix/runtime_start.sh.in | 26 +++
cmake/cmake_celix/runtime_stop.sh.in | 19 ++
documents/cmake_commands/readme.md | 2 +
framework/private/src/bundle_context.c | 2 +-
launcher/CMakeLists.txt | 17 ++
launcher/private/src/celix_test_runner.cpp | 73 +++++++
pubsub/CMakeLists.txt | 3 +
pubsub/deploy/CMakeLists.txt | 58 ++++++
pubsub/mock/CMakeLists.txt | 8 +-
.../private/src/topic_publication.c | 8 +-
pubsub/test/CMakeLists.txt | 87 ++++++++
pubsub/test/msg_descriptors/msg.descriptor | 8 +
pubsub/test/test/msg.h | 27 +++
pubsub/test/test/sut_activator.c | 112 +++++++++++
pubsub/test/test/tst_activator.cpp | 199 +++++++++++++++++++
19 files changed, 971 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/cmake/CMakeCelix.cmake
----------------------------------------------------------------------
diff --git a/cmake/CMakeCelix.cmake b/cmake/CMakeCelix.cmake
index 9ca4de7..8c14577 100644
--- a/cmake/CMakeCelix.cmake
+++ b/cmake/CMakeCelix.cmake
@@ -26,6 +26,7 @@ include(${CELIX_CMAKE_DIRECTORY}/cmake_celix/Dependencies.cmake)
include(${CELIX_CMAKE_DIRECTORY}/cmake_celix/BundlePackaging.cmake)
include(${CELIX_CMAKE_DIRECTORY}/cmake_celix/DeployPackaging.cmake)
include(${CELIX_CMAKE_DIRECTORY}/cmake_celix/DockerPackaging.cmake)
+include(${CELIX_CMAKE_DIRECTORY}/cmake_celix/Runtimes.cmake)
include(${CELIX_CMAKE_DIRECTORY}/cmake_celix/ApacheRat.cmake)
include(${CELIX_CMAKE_DIRECTORY}/cmake_celix/CodeCoverage.cmake)
include(${CELIX_CMAKE_DIRECTORY}/cmake_celix/BuildOptions.cmake)
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/cmake/cmake_celix/DeployPackaging.cmake
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/DeployPackaging.cmake b/cmake/cmake_celix/DeployPackaging.cmake
index 22e2885..626b7b8 100644
--- a/cmake/cmake_celix/DeployPackaging.cmake
+++ b/cmake/cmake_celix/DeployPackaging.cmake
@@ -28,24 +28,27 @@ function(add_deploy)
list(REMOVE_AT ARGN 0)
set(OPTIONS COPY)
- set(ONE_VAL_ARGS GROUP NAME LAUNCHER)
+ set(ONE_VAL_ARGS GROUP NAME LAUNCHER DIR)
set(MULTI_VAL_ARGS BUNDLES PROPERTIES)
cmake_parse_arguments(DEPLOY "${OPTIONS}" "${ONE_VAL_ARGS}" "${MULTI_VAL_ARGS}" ${ARGN})
##### Check arguments #####
- if(NOT DEPLOY_NAME)
+ if (NOT DEPLOY_NAME)
set(DEPLOY_NAME "${DEPLOY_TARGET}")
- endif()
+ endif ()
+ if (NOT DEPLOY_DIR)
+ set(DEPLOY_DIR "${CMAKE_BINARY_DIR}/deploy")
+ endif ()
######
##### Setting defaults #####
- if(DEPLOY_GROUP)
- set(DEPLOY_LOCATION "${CMAKE_BINARY_DIR}/deploy/${DEPLOY_GROUP}/${DEPLOY_NAME}")
+ if (DEPLOY_GROUP)
+ set(DEPLOY_LOCATION "${DEPLOY_DIR}/${DEPLOY_GROUP}/${DEPLOY_NAME}")
set(DEPLOY_PRINT_NAME "${DEPLOY_GROUP}/${DEPLOY_NAME}")
- else()
- set(DEPLOY_LOCATION "${CMAKE_BINARY_DIR}/deploy/${DEPLOY_NAME}")
+ else ()
+ set(DEPLOY_LOCATION "${DEPLOY_DIR}/${DEPLOY_NAME}")
set(DEPLOY_PRINT_NAME "${DEPLOY_NAME}")
- endif()
+ endif ()
######
@@ -77,6 +80,9 @@ function(add_deploy)
#setup dependencies based on timestamp
add_custom_command(OUTPUT "${TIMESTAMP_FILE}"
COMMAND ${CMAKE_COMMAND} -E touch ${TIMESTAMP_FILE}
+ COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_PROPERTY:${DEPLOY_TARGET},DEPLOY_LOCATION>
+ COMMAND chmod +x $<TARGET_PROPERTY:${DEPLOY_TARGET},DEPLOY_LOCATION>/run.sh
+ COMMAND chmod +x $<TARGET_PROPERTY:${DEPLOY_TARGET},DEPLOY_LOCATION>/release.sh
DEPENDS "$<TARGET_PROPERTY:${DEPLOY_TARGET},DEPLOY_TARGET_DEPS>" ${DEPLOY_FILE_TARGETS}
WORKING_DIRECTORY "${DEPLOY_LOCATION}"
COMMENT "Deploying ${DEPLOY_PRINT_NAME}" VERBATIM
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/cmake/cmake_celix/Runtimes.cmake
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/Runtimes.cmake b/cmake/cmake_celix/Runtimes.cmake
new file mode 100644
index 0000000..14f88eb
--- /dev/null
+++ b/cmake/cmake_celix/Runtimes.cmake
@@ -0,0 +1,161 @@
+add_custom_target(runtimes ALL
+ DEPENDS "$<TARGET_PROPERTY:runtimes,DEPS>"
+)
+set_target_properties(runtimes PROPERTIES "DEPS" "")
+set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_BINARY_DIR}/runtimes")
+
+function(add_runtime)
+ list(GET ARGN 0 RUNTIME_TARGET_NAME)
+ list(REMOVE_AT ARGN 0)
+
+ set(OPTIONS USE_TERM LOG_TO_FILES)
+ set(ONE_VAL_ARGS WAIT_FOR NAME GROUP)
+ set(MULTI_VAL_ARGS DEPLOYMENTS COMMANDS)
+ cmake_parse_arguments(RUNTIME "${OPTIONS}" "${ONE_VAL_ARGS}" "${MULTI_VAL_ARGS}" ${ARGN})
+
+ if (NOT RUNTIME_NAME)
+ set(RUNTIME_NAME ${RUNTIME_TARGET_NAME})
+ endif ()
+ if (NOT RUNTIME_GROUP)
+ set(RUNTIME_LOCATION "${PROJECT_BINARY_DIR}/runtimes/${RUNTIME_NAME}")
+ else ()
+ set(RUNTIME_LOCATION "${PROJECT_BINARY_DIR}/runtimes/${RUNTIME_GROUP}/${RUNTIME_NAME}")
+ endif ()
+ set(TIMESTAMP_FILE "${CMAKE_CURRENT_BINARY_DIR}/${RUNTIME_TARGET_NAME}-runtime-timestamp")
+
+ set(START_SCRIPT "$<TARGET_PROPERTY:${RUNTIME_TARGET_NAME},RUNTIME_LOCATION>/start.sh")
+ set(STOP_SCRIPT "$<TARGET_PROPERTY:${RUNTIME_TARGET_NAME},RUNTIME_LOCATION>/stop.sh")
+ set(COMMON_SCRIPT "$<TARGET_PROPERTY:${RUNTIME_TARGET_NAME},RUNTIME_LOCATION>/common.sh")
+
+ add_custom_command(OUTPUT "${TIMESTAMP_FILE}"
+ COMMAND ${CMAKE_COMMAND} -E touch ${TIMESTAMP_FILE}
+ COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_PROPERTY:${RUNTIME_TARGET_NAME},RUNTIME_LOCATION>
+ COMMAND chmod +x $<TARGET_PROPERTY:${RUNTIME_TARGET_NAME},RUNTIME_LOCATION>/start.sh
+ COMMAND chmod +x $<TARGET_PROPERTY:${RUNTIME_TARGET_NAME},RUNTIME_LOCATION>/stop.sh
+ #TODO DEPENDS "$<TARGET_PROPERTY:${DEPLOY_TARGET},DEPLOY_TARGET_DEPS>" ${DEPLOY_FILE_TARGETS}
+ DEPENDS ${START_SCRIPT} ${STOP_SCRIPT} ${SETUP_SCRIPT}
+ WORKING_DIRECTORY "${RUNTIME_LOCATION}"
+ COMMENT "Creating runtime ${RUNTIME_TARGET_NAME}" VERBATIM
+ )
+ add_custom_target(${RUNTIME_TARGET_NAME}
+ DEPENDS "${TIMESTAMP_FILE}"
+ )
+
+ set_target_properties(${RUNTIME_TARGET_NAME} PROPERTIES "RUNTIME_DEPLOYMENTS" "") #deployments that should be runned
+ set_target_properties(${RUNTIME_TARGET_NAME} PROPERTIES "RUNTIME_COMMANDS" "") #command that should be executed
+ set_target_properties(${RUNTIME_TARGET_NAME} PROPERTIES "RUNTIME_NAME" "${RUNTIME_NAME}") #The runtime workdir
+ set_target_properties(${RUNTIME_TARGET_NAME} PROPERTIES "RUNTIME_GROUP" "${RUNTIME_GROUP}") #The runtime workdir
+ set_target_properties(${RUNTIME_TARGET_NAME} PROPERTIES "RUNTIME_LOCATION" "${RUNTIME_LOCATION}") #The runtime workdir
+ set_target_properties(${RUNTIME_TARGET_NAME} PROPERTIES "RUNTIME_USE_TERM" "${RUNTIME_USE_TERM}") #Wether or not the use terminal
+ set_target_properties(${RUNTIME_TARGET_NAME} PROPERTIES "RUNTIME_LOG_TO_FILES" "${RUNTIME_LOG_TO_FILES}") #log to files or std out/err
+
+ #wait for deployment, e.g. the one that control the lifecycle of the runtime.
+ set_target_properties(${RUNTIME_TARGET_NAME} PROPERTIES "RUNTIME_WAIT_FOR_DEPLOYMENT" "")
+
+ #wait for command, e.g. the one that control the lifecycle of the runtime.
+ set_target_properties(${RUNTIME_TARGET_NAME} PROPERTIES "RUNTIME_WAIT_FOR_COMMAND" "")
+
+
+ #replaces @RUNTIME_TARGET_NAME@
+ #TODO move to another location
+ configure_file("${CELIX_CMAKE_DIRECTORY}/cmake_celix/runtime_start.sh.in" "${CMAKE_CURRENT_BINARY_DIR}/start.sh.${RUNTIME_TARGET_NAME}.in.1" @ONLY)
+ configure_file("${CELIX_CMAKE_DIRECTORY}/cmake_celix/runtime_stop.sh.in" "${CMAKE_CURRENT_BINARY_DIR}/stop.sh.${RUNTIME_TARGET_NAME}.in.1" @ONLY)
+ configure_file("${CELIX_CMAKE_DIRECTORY}/cmake_celix/runtime_common.sh.in" "${CMAKE_CURRENT_BINARY_DIR}/common.sh.${RUNTIME_TARGET_NAME}.in.1" @ONLY)
+
+
+ #replaces $<TARGET_PROPERTY:<RUNTIME_NAME>,RUNTIME_DEPLOYMENTS>
+ file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/common.sh.${RUNTIME_TARGET_NAME}.in.2"
+ INPUT "${CMAKE_CURRENT_BINARY_DIR}/common.sh.${RUNTIME_TARGET_NAME}.in.1"
+ )
+ file(GENERATE
+ OUTPUT "${START_SCRIPT}"
+ INPUT "${CMAKE_CURRENT_BINARY_DIR}/start.sh.${RUNTIME_TARGET_NAME}.in.1"
+ )
+ file(GENERATE
+ OUTPUT "${STOP_SCRIPT}"
+ INPUT "${CMAKE_CURRENT_BINARY_DIR}/stop.sh.${RUNTIME_TARGET_NAME}.in.1"
+ )
+
+
+ #replaces list of $<TARGET_PROPERTY:<DEPLOY_NAME>,DEPLOY_LOCATION>, only needed for common
+ file(GENERATE
+ OUTPUT "${COMMON_SCRIPT}"
+ INPUT "${CMAKE_CURRENT_BINARY_DIR}/common.sh.${RUNTIME_TARGET_NAME}.in.2"
+ )
+
+ get_target_property(DEPS runtimes "DEPS")
+ list(APPEND DEPS "${RUNTIME_TARGET_NAME}")
+ set_target_properties(runtimes PROPERTIES "DEPS" "${DEPS}")
+
+ runtime_deployments(${RUNTIME_TARGET_NAME} ${RUNTIME_DEPLOYMENTS})
+ runtime_commands(${RUNTIME_TARGET_NAME} ${RUNTIME_COMMANDS})
+
+ if (RUNTIME_WAIT_FOR)
+ runtime_deployment_wait_for(${RUNTIME_TARGET_NAME} ${RUNTIME_WAIT_FOR})
+ endif ()
+
+endfunction()
+
+function(runtime_use_term)
+ #0 is runtime TARGET
+ #1 is BOOL (use xterm)
+ list(GET ARGN 0 RUNTIME_NAME)
+ list(GET ARGN 1 USE_TERM)
+ set_target_properties(${RUNTIME_NAME} PROPERTIES "RUNTIME_USE_TERM" "${USE_TERM}")
+endfunction()
+
+function(runtime_log_to_files)
+ #0 is runtime TARGET
+ #1 is BOOL (log to files)
+ list(GET ARGN 0 RUNTIME_NAME)
+ list(GET ARGN 1 LOG_TO_FILES)
+ set_target_properties(${RUNTIME_NAME} PROPERTIES "RUNTIME_LOG_TO_FILES" "${LOG_TO_FILES}")
+endfunction()
+
+function(runtime_deployments)
+ #0 is runtime TARGET
+ #1..n is deployments
+ list(GET ARGN 0 RUNTIME_NAME)
+ list(REMOVE_AT ARGN 0)
+
+ get_target_property(DEPLOYMENTS ${RUNTIME_NAME} "RUNTIME_DEPLOYMENTS")
+ foreach(DEPLOYMENT IN ITEMS ${ARGN})
+ list(APPEND DEPLOYMENTS "$<TARGET_PROPERTY:${DEPLOYMENT},DEPLOY_LOCATION>")
+ endforeach()
+
+ set_target_properties(${RUNTIME_NAME} PROPERTIES "RUNTIME_DEPLOYMENTS" "${DEPLOYMENTS}")
+endfunction()
+
+function(runtime_deployment_wait_for)
+ #0 is runtime TARGET
+ #1 is deployment TARGET
+ list(GET ARGN 0 RUNTIME_NAME)
+ list(GET ARGN 1 DEPLOYMENT)
+
+ set_target_properties(${RUNTIME_NAME} PROPERTIES "RUNTIME_WAIT_FOR_DEPLOYMENT" "$<TARGET_PROPERTY:${DEPLOYMENT},DEPLOY_LOCATION>")
+ set_target_properties(${RUNTIME_NAME} PROPERTIES "RUNTIME_WAIT_FOR_COMMAND" "")
+endfunction()
+
+function(runtime_commands)
+ #0 is runtime TARGET
+ #1..n is commands
+ list(GET ARGN 0 RUNTIME_NAME)
+ list(REMOVE_AT ARGN 0)
+
+ get_target_property(COMMANDS ${RUNTIME_NAME} "RUNTIME_COMMANDS")
+ foreach(CMD IN ITEMS ${ARGN})
+ list(APPEND COMMANDS ${CMD})
+ endforeach()
+ set_target_properties(${RUNTIME_NAME} PROPERTIES "RUNTIME_COMMANDS" "${COMMANDS}")
+endfunction()
+
+function(runtime_command_wait_for)
+ #0 is deploy TARGET
+ #1 is COMMAND STR
+ list(GET ARGN 0 RUNTIME_NAME)
+ list(GET ARGN 1 COMMAND)
+
+ set_target_properties(${RUNTIME_NAME} PROPERTIES "RUNTIME_WAIT_FOR_COMMAND" "${COMMAND}")
+ set_target_properties(${RUNTIME_NAME} PROPERTIES "RUNTIME_WAIT_FOR_DEPLOYMENT" "")
+endfunction()
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/cmake/cmake_celix/runtime_common.sh.in
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/runtime_common.sh.in b/cmake/cmake_celix/runtime_common.sh.in
new file mode 100644
index 0000000..e59c6b0
--- /dev/null
+++ b/cmake/cmake_celix/runtime_common.sh.in
@@ -0,0 +1,152 @@
+#!/bin/sh
+
+#Locations
+BUILD_DIR="${BUILD_DIR:-@PROJECT_BINARY_DIR@}"
+RUNTIME_DIR="${RUNTIME_DIR:-$<TARGET_PROPERTY:@RUNTIME_TARGET_NAME@,RUNTIME_LOCATION>}"
+DEPLOY_DIR="${DEPLOY_DIR:-${BUILD_DIR}/deploy}"
+
+#Name & Group
+RUNTIME_NAME="${RUNTIME_NAME:-$<TARGET_PROPERTY:@RUNTIME_TARGET_NAME@,RUNTIME_NAME>}"
+RUNTIME_GROUP="${RUNTIME_NAME:-$<TARGET_PROPERTY:@RUNTIME_TARGET_NAME@,RUNTIME_GROUP>}"
+
+#deployments & commands
+DEPLOYMENTS=${DEPLOYMENTS:-"$<JOIN:$<TARGET_PROPERTY:@RUNTIME_TARGET_NAME@,RUNTIME_DEPLOYMENTS>, >"}
+COMMANDS=${COMMANDS:-"$<JOIN:$<TARGET_PROPERTY:@RUNTIME_TARGET_NAME@,RUNTIME_COMMANDS>, >"}
+
+#Options
+TERM_CMD="${TERM_CMD:-xterm}"
+TERM_OPTS="${TERM_OPTS:-}"
+USE_TERM="${USE_TERM:-$<TARGET_PROPERTY:@RUNTIME_TARGET_NAME@,RUNTIME_USE_TERM>}"
+RELEASE_SH="${RELEASE_SH:-}"
+WAIT_FOR_DEPLOYMENT="${WAIT_FOR_DEPLOYMENT:-$<TARGET_PROPERTY:@RUNTIME_TARGET_NAME@,RUNTIME_WAIT_FOR_DEPLOYMENT>}"
+WAIT_FOR_CMD="${WAIT_FOR_CMD:-$<TARGET_PROPERTY:@RUNTIME_TARGET_NAME@,RUNTIME_WAIT_FOR_COMMAND>}"
+LOG_TO_FILES="${LOG_TO_FILES:-$<TARGET_PROPERTY:@RUNTIME_TARGET_NAME@,RUNTIME_LOG_TO_FILES>}"
+KILL_OPTS="${KILL_OPTS:-}"
+
+PIDS=""
+WAIT_FOR_PID=""
+LOG_SUFFIX=$(date +"%s")
+trap stop_all INT
+
+#clear dirs
+function rt_init() {
+ rm -fr ${RUNTIME_DIR}/run #contains pids, etc
+ mkdir ${RUNTIME_DIR}/run
+ if [ ! -e ${RUNTIME_DIR}/logs ] ; then
+ mkdir ${RUNTIME_DIR}/logs
+ fi
+}
+
+##functions
+function rt_stop_all() {
+ for PID in ${PIDS}; do
+ echo "Sending signal to ${PID}"
+ kill ${KILL_OPTS} ${PID}
+ done
+}
+
+function rt_stop() {
+ PIDS=$@
+ echo "Stopping pids ${PIDS}"
+ kill ${KILL_OPTS} ${PIDS}
+}
+
+function rt_run_deployment() {
+ DEPLOYMENT_DIR=$1
+ DEPLOYMENT=$(basename ${DEPLOYMENT_DIR})
+ LOG_FILE="${RUNTIME_DIR}/logs/${DEPLOYMENT}-${LOG_SUFFIX}.log"
+ echo "Running ${DEPLOYMENT}"
+ cd ${DEPLOYMENT_DIR} #assuming absolute dir
+ if [ -d .cache ] ; then
+ echo "Clearing cache"
+ rm -fr .cache #clear cache
+ fi
+ . ./release.sh #run deployment release
+ if [ "${USE_TERM}" = "TRUE" ] ; then
+ if [ "${LOG_TO_FILES}" = "TRUE" ] ; then
+ ${TERM_CMD} ${TERM_OPTS} -e "./${DEPLOYMENT} &> ${LOG_FILE}" &
+ else
+ ${TERM_CMD} ${TERM_OPTS} -e "./${DEPLOYMENT}" &
+ fi
+ else #run in this shell
+ if [ "${LOG_TO_FILES}" = "TRUE" ] ; then
+ ./${DEPLOYMENT} &> ${LOG_FILE} &
+ else
+ ./${DEPLOYMENT} &
+ fi
+ fi
+ PID=$!
+ echo "PID of DEPLOYMENT '${DEPLOYMENT}' is ${PID}"
+ if [ ! -z "${WAIT_FOR_DEPLOYMENT}" -a "${DEPLOYMENT_DIR}" = "${WAIT_FOR_DEPLOYMENT}" ] ; then
+ WAIT_FOR_PID=${PID}
+ echo "${PID}" > ${RUNTIME_DIR}/run/wait_for_pid
+ else
+ PIDS="${PID} ${PIDS}"
+ echo "${PIDS}" > ${RUNTIME_DIR}/run/pids
+ fi
+ cd -
+}
+
+function rt_run_cmd() {
+ CMD="$1"
+ LOG_FILE="${RUNTIME_DIR}/logs/${CMD}-${LOG_SUFFIX}.log" #TODO only use first word in case of complex command
+ cd ${RUNTIME_DIR}
+ if [ "${USE_TERM}" = "TRUE" ] ; then
+ if [ "${LOG_TO_FILES}" = "TRUE" ] ; then
+ ${TERM_CMD} ${TERM_OPTS} -e "${CMD} &> ${LOG_FILE}" &
+ else
+ ${TERM_CMD} ${TERM_OPTS} -e "${CMD}" &
+ fi
+ else
+ if [ "${LOG_TO_FILES}" = "TRUE" ] ; then
+ ${CMD} &> \"${LOG_FILE}\" &
+ else
+ ${CMD} &
+ fi
+ fi
+ PID=$!
+ echo "PID of COMMAND '${CMD}' is ${PID}"
+ if [ ! -z "${WAIT_FOR_CMD}" -a "${CMD}" = "${MWAIT_FOR_CMD}" ] ; then
+ WAIT_FOR_PID=${PID}
+ echo "${PID}" > ${RUNTIME_DIR}/run/wait_for_pid
+ else
+ PIDS="${PID} ${PIDS}"
+ echo "${PIDS}" > ${RUNTIME_DIR}/run/pids
+ fi
+ cd -
+}
+
+function rt_wait_for() {
+ RESULT=0
+ echo "Waiting for pid ${WAIT_FOR_PID}"
+ if wait ${WAIT_FOR_PID}; then
+ echo "${WAIT_FOR_PID} exited normal"
+ else
+ echo "${WAIT_FOR_PID} exited with error"
+ RESULT=1
+ fi
+
+ echo "Signalling pids:${PIDS}"
+ kill ${PIDS}
+
+ for PID in ${PIDS}; do
+ if wait ${PID}; then
+ echo "${PID} exited normal"
+ else
+ echo "${PID} exited with error"
+ fi
+ done
+
+ echo ${RESULT}
+}
+
+
+if [ -z "${RELEASE_SH}" ] ; then
+ true #pass
+elif [ -e "${RELEASE_SH}" ]; then #absolute release file
+ source ${RELEASE_SH}
+elif [ -e "${RUNTIME_DIR}/${RELEASE_SH}" ] ; then #release file in runtime dir
+ source ${RUNTIME_DIR}/${RELEASE_SH}
+elif [ -e "${BUILD_DIR}/${RELEASE_SH}" ] ; then #release file in build dir
+ source ${BUILD_DIR}/${RELEASE_SH}
+fi
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/cmake/cmake_celix/runtime_start.sh.in
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/runtime_start.sh.in b/cmake/cmake_celix/runtime_start.sh.in
new file mode 100644
index 0000000..e7e94f6
--- /dev/null
+++ b/cmake/cmake_celix/runtime_start.sh.in
@@ -0,0 +1,26 @@
+#!/bin/sh
+source $<TARGET_PROPERTY:@RUNTIME_TARGET_NAME@,RUNTIME_LOCATION>/common.sh
+
+echo "Starting runtime ${RUNTIME_NAME}"
+
+rt_init
+
+for DEPLOYMENT_DIR in ${DEPLOYMENTS}; do
+ rt_run_deployment ${DEPLOYMENT_DIR}
+done
+
+for CMD in ${COMMANDS}; do
+ rt_run_cmd "${CMD}"
+done
+
+echo "PIDS are ${PIDS}."
+
+if [ ! -z "${WAIT_FOR_PID}" ] ; then
+ rt_wait_for #sets RESULT
+ echo "RESULT is ${RESULT}"
+ exit ${RESULT}
+fi
+
+
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/cmake/cmake_celix/runtime_stop.sh.in
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/runtime_stop.sh.in b/cmake/cmake_celix/runtime_stop.sh.in
new file mode 100644
index 0000000..fd7338e
--- /dev/null
+++ b/cmake/cmake_celix/runtime_stop.sh.in
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+source $<TARGET_PROPERTY:@RUNTIME_TARGET_NAME@,RUNTIME_LOCATION>/common.sh
+
+#Options
+USE_SIGNAL=${USE_SIGNAL:-}
+
+#TODO parse option to easily select kill -9
+
+if [ -e ${RUNTIME_DIR}/run/main_pid ] ; then
+ MAIN_PID=$(cat ${RUNTIME_DIR}/run/wait_for_pid)
+ rt_stop ${MAIN_PID}
+fi
+
+if [ -e ${RUNTIME_DIR}/run/pids ] ; then
+ PIDS=$(cat ${RUNTIME_DIR}/run/pids)
+ rt_stop ${PIDS}
+fi
+
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/documents/cmake_commands/readme.md
----------------------------------------------------------------------
diff --git a/documents/cmake_commands/readme.md b/documents/cmake_commands/readme.md
index f68eb37..63f8732 100644
--- a/documents/cmake_commands/readme.md
+++ b/documents/cmake_commands/readme.md
@@ -161,6 +161,7 @@ add_deploy(<deploy_target_name>
[GROUP group_name]
[NAME deploy_name]
[LAUNCHER launcher]
+ [DIR dir]
[BUNDLES <bundle1> <bundle2> ...]
[PROPERTIES "prop1=val1" "prop2=val2" ...]
)
@@ -179,6 +180,7 @@ If the bundle target is never added CMake will give an error:
- If GROUP is provided the deployment will be grouped in the provided group name.
- If NAME is provided that name will be used for the deployment dir. Default the deploy target name will be used.
- If LAUNCHER is provided that path or target will be used as launcher executable for the deployment. If no LAUNCHER is not provided the celix executable will be used.
+- If DIR is provided, the specified dir is used instead of `<cmake_build_dir>/deploy` as deploy dir
- If BUNDLES is provided the list of bundles will be added the the generated config.properties for startup. Combined with COPY the bundles will also be copied to a bundles dir.
- If PROPERTIES is provided the list of properties will be appended to the generated config.properties
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/framework/private/src/bundle_context.c
----------------------------------------------------------------------
diff --git a/framework/private/src/bundle_context.c b/framework/private/src/bundle_context.c
index 7951f87..face85d 100644
--- a/framework/private/src/bundle_context.c
+++ b/framework/private/src/bundle_context.c
@@ -126,7 +126,7 @@ celix_status_t bundleContext_registerService(bundle_context_pt context, const ch
service_registration_pt registration = NULL;
celix_status_t status = CELIX_SUCCESS;
- if (context != NULL && *service_registration == NULL) {
+ if (context != NULL) {
fw_registerService(context->framework, ®istration, context->bundle, serviceName, svcObj, properties);
*service_registration = registration;
} else {
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/launcher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 920d4c0..8bac20e 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -36,4 +36,21 @@ if (LAUNCHER)
include_directories("${CURL_INCLUDE_DIRS}")
install(TARGETS celix RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT framework)
+
+ find_package(CppUTest QUIET)
+ if (CPPUTEST_FOUND)
+ #Test running which start celix and run CppUTest RUN_ALL_TESTS.
+ #Using this test running it is possible to create bundles containing CppUTests.
+ add_executable(celix_test_runner
+ private/src/celix_test_runner.cpp
+ )
+ set_target_properties(celix_test_runner PROPERTIES "INSTALL_RPATH" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
+ target_link_libraries(celix_test_runner
+ celix_framework
+ ${CURL_LIBRARIES}
+ ${CPPUTEST_LIBRARIES}
+ ${CPPUTEST_EXT_LIBRARIES}
+ )
+ install(TARGETS celix_test_runner RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT framework)
+ endif ()
endif (LAUNCHER)
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/launcher/private/src/celix_test_runner.cpp
----------------------------------------------------------------------
diff --git a/launcher/private/src/celix_test_runner.cpp b/launcher/private/src/celix_test_runner.cpp
new file mode 100644
index 0000000..d1ea2e6
--- /dev/null
+++ b/launcher/private/src/celix_test_runner.cpp
@@ -0,0 +1,73 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you 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 <signal.h>
+
+#include "celix_launcher.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+
+static void shutdown_framework(int signal);
+static void ignore(int signal);
+
+#define DEFAULT_CONFIG_FILE "config.properties"
+
+static framework_pt framework = NULL;
+
+int main(int argc, char *argv[]) {
+ // Perform some minimal command-line option parsing...
+ char *cfg = DEFAULT_CONFIG_FILE;
+
+ // Set signal handler
+ (void) signal(SIGINT, shutdown_framework);
+ (void) signal(SIGUSR1, ignore);
+ (void) signal(SIGUSR2, ignore);
+
+ int rc = celixLauncher_launch(cfg, &framework);
+ if (rc != 0) {
+ printf("Error starting Celix\n");
+ }
+
+ if (rc == 0 && framework != NULL) {
+ rc = RUN_ALL_TESTS(argc, argv);
+
+ celixLauncher_stop(framework);
+ celixLauncher_waitForShutdown(framework);
+ celixLauncher_destroy(framework);
+ }
+
+ if (rc != 0) {
+ printf("*** FAILURE ***\n");
+ } else {
+ printf("*** SUCCESS ***\n");
+ }
+
+ return rc;
+}
+
+static void shutdown_framework(int signal) {
+ if (framework != NULL) {
+ celixLauncher_stop(framework); //NOTE main thread will destroy
+ }
+}
+
+static void ignore(int signal) {
+ //ignoring for signal SIGUSR1, SIGUSR2. Can be used to interrupt sleep, etc
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/pubsub/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/CMakeLists.txt b/pubsub/CMakeLists.txt
index 44f3bd1..7ad7677 100644
--- a/pubsub/CMakeLists.txt
+++ b/pubsub/CMakeLists.txt
@@ -36,6 +36,9 @@ if (PUBSUB)
add_subdirectory(deploy)
add_subdirectory(keygen)
add_subdirectory(mock)
+ if (ENABLE_TESTING)
+ add_subdirectory(test)
+ endif()
#install api
install(FILES api/pubsub/publisher.h api/pubsub/subscriber.h DESTINATION include/celix/pubsub COMPONENT framework)
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/pubsub/deploy/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/deploy/CMakeLists.txt b/pubsub/deploy/CMakeLists.txt
index b35ae14..52fecc9 100644
--- a/pubsub/deploy/CMakeLists.txt
+++ b/pubsub/deploy/CMakeLists.txt
@@ -15,6 +15,8 @@
# specific language governing permissions and limitations
# under the License.
+find_program(ETCD_CMD NAMES etcd)
+find_program(XTERM_CMD NAMES xterm)
# UDP Multicast
add_deploy("pubsub_publisher_udp_mc"
@@ -54,6 +56,23 @@ add_deploy("pubsub_subscriber2_udp_mc"
org.apache.celix.pubsub_serializer.PubSubSerializerJson
)
+if (ETCD_CMD AND XTERM_CMD)
+ #Runtime starting a publish and subscriber for udp mc
+ add_runtime(pubsub_rt_upd_mc
+ NAME udp_mc
+ GROUP pubsub
+ DEPLOYMENTS
+ pubsub_publisher_udp_mc
+ pubsub_subscriber_udp_mc
+ pubsub_subscriber2_udp_mc
+ COMMANDS
+ etcd
+ USE_TERM
+ )
+else ()
+ message(WARNING "Cannot create runtime for pubsub because etcd and/or xterm is not installed")
+endif ()
+
if (BUILD_PUBSUB_PSA_ZMQ)
# Dynamic ZMQ / UDP admin
@@ -168,4 +187,43 @@ if (BUILD_PUBSUB_PSA_ZMQ)
org.apache.celix.pubsub_serializer.PubSubSerializerJson
)
+ if (ETCD_CMD AND XTERM_CMD)
+ #Runtime starting two bundles using both zmq and upd mc pubsub
+ add_runtime(pubsub_rt_zmq_udpmc_combi
+ NAME combi
+ GROUP pubsub
+ DEPLOYMENTS
+ pubsub_publisher_zmq
+ pubsub_subscriber_zmq
+ pubsub_subscriber_zmq
+ COMMANDS
+ etcd
+ USE_TERM
+ )
+
+ #Runtime starting a publish and 2 subscribers for zmq
+ add_runtime(pubsub_rt_zmq
+ NAME zmq
+ GROUP pubsub
+ DEPLOYMENTS
+ pubsub_publisher
+ pubsub_subscriber2_zmq
+ COMMANDS
+ etcd
+ USE_TERM
+ )
+
+ #Runtime starting a multipart (multiple message in one send) publish and subscriber for zmq
+ add_runtime(pubsub_rt_multipart_zmq
+ NAME zmq_multipart
+ GROUP pubsub
+ DEPLOYMENTS
+ pubsub_mp_subscriber_zmq
+ pubsub_mp_publisher_zmq
+ COMMANDS
+ etcd
+ USE_TERM
+ )
+ endif ()
+
endif()
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/pubsub/mock/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/mock/CMakeLists.txt b/pubsub/mock/CMakeLists.txt
index 09d7b2a..189ddc2 100644
--- a/pubsub/mock/CMakeLists.txt
+++ b/pubsub/mock/CMakeLists.txt
@@ -23,15 +23,15 @@ if (CPPUTEST_FOUND)
api
${CPPUTEST_INCLUDE_DIR}
)
-
+
add_library(celix_pubsubmock STATIC
src/publisher_mock.cc
- )
+ ../test/test/msg.h)
target_link_libraries(celix_pubsubmock ${CPPUTEST_LIBRARY})
-
+
install(TARGETS celix_pubsubmock DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT framework)
install(FILES api/pubsub/publisher_mock.h DESTINATION include/celix/pubsub COMPONENT framework)
-
+
if (ENABLE_TESTING)
add_executable(pubsubmock_test
tst/pubsubmock_test.cc
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c b/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c
index cff5005..aa3faf0 100644
--- a/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c
+++ b/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c
@@ -364,6 +364,8 @@ static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, con
celixThreadMutex_lock(&(bound->parent->tp_lock));
celixThreadMutex_lock(&(bound->mp_lock));
+ //TODO //FIXME -> should use pointer to int as identifier, can be many pointers to int ....
+ printf("TODO FIX usage of msg id's in the serializer hashmap. This seems wrongly based on pointers to uints!!!!\n");
pubsub_message_type *msgType = hashMap_get(bound->msgTypes, &msgTypeId);
int major=0, minor=0;
@@ -401,7 +403,11 @@ static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, con
free(serializedOutput);
} else {
- printf("TP: Message %u not supported.",msgTypeId);
+ if (bound->parent->serializerSvc == NULL) {
+ printf("TP: Serializer is not set!\n");
+ } else {
+ printf("TP: Message %u not supported.\n",msgTypeId);
+ }
status=-1;
}
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/pubsub/test/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/test/CMakeLists.txt b/pubsub/test/CMakeLists.txt
new file mode 100644
index 0000000..7cd0003
--- /dev/null
+++ b/pubsub/test/CMakeLists.txt
@@ -0,0 +1,87 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+find_program(ETCD_CMD NAMES etcd)
+
+find_package(CppUTest REQUIRED)
+include_directories(${CPPUTEST_INCLUDE_DIR})
+
+include_directories(
+ ${CMAKE_SOURCE_DIR}/pubsub/api
+ test
+)
+
+add_bundle(pubsub_sut
+ #"Vanilla" bundle which is under test
+ SOURCES
+ test/sut_activator.c
+ VERSION 1.0.0
+)
+bundle_files(pubsub_sut
+ msg_descriptors/msg.descriptor
+ DESTINATION "META-INF/descriptors/messages"
+)
+add_deploy(pubsub_udpmc_sut
+ NAME deploy_sut
+ BUNDLES
+ org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+ org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+ org.apache.celix.pubsub_admin.PubSubAdminUdpMc
+ #org.apache.celix.pubsub_admin.PubSubAdminZmq
+ org.apache.celix.pubsub_serializer.PubSubSerializerJson
+ pubsub_sut
+ DIR ${PROJECT_BINARY_DIR}/runtimes/test/pubsub/udpmc
+)
+
+add_bundle(pubsub_tst
+ #Test bundle containing cpputests and uses celix_test_runner launcher instead of the celix launcher
+ SOURCES
+ test/tst_activator.cpp
+ VERSION 1.0.0
+)
+bundle_files(pubsub_tst
+ msg_descriptors/msg.descriptor
+ DESTINATION "META-INF/descriptors/messages"
+)
+add_deploy(pubsub_udpmc_tst
+ NAME deploy_tst
+ BUNDLES
+ org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+ org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+ org.apache.celix.pubsub_admin.PubSubAdminUdpMc
+ #org.apache.celix.pubsub_admin.PubSubAdminZmq
+ org.apache.celix.pubsub_serializer.PubSubSerializerJson
+ pubsub_tst
+ DIR ${PROJECT_BINARY_DIR}/runtimes/test/pubsub/udpmc
+ LAUNCHER celix_test_runner
+)
+
+if (ETCD_CMD)
+ add_runtime(pubsub_rt_test_udpmc
+ NAME udpmc
+ GROUP test/pubsub
+ DEPLOYMENTS
+ pubsub_udpmc_sut
+ pubsub_udpmc_tst
+ COMMANDS
+ etcd
+ WAIT_FOR
+ pubsub_udpmc_tst
+ USE_TERM
+ #LOG_TO_FILES
+ )
+endif ()
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/pubsub/test/msg_descriptors/msg.descriptor
----------------------------------------------------------------------
diff --git a/pubsub/test/msg_descriptors/msg.descriptor b/pubsub/test/msg_descriptors/msg.descriptor
new file mode 100644
index 0000000..808644c
--- /dev/null
+++ b/pubsub/test/msg_descriptors/msg.descriptor
@@ -0,0 +1,8 @@
+:header
+type=message
+name=msg
+version=1.0.0
+:annotations
+:types
+:message
+{n seqnR}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/pubsub/test/test/msg.h
----------------------------------------------------------------------
diff --git a/pubsub/test/test/msg.h b/pubsub/test/test/msg.h
new file mode 100644
index 0000000..babfd1f
--- /dev/null
+++ b/pubsub/test/test/msg.h
@@ -0,0 +1,27 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you 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 MSG_H
+#define MSG_H
+
+typedef struct msg {
+ int seqNr;
+} msg_t;
+
+#endif //MSG_H
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/pubsub/test/test/sut_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/test/test/sut_activator.c b/pubsub/test/test/sut_activator.c
new file mode 100644
index 0000000..3e3b33b
--- /dev/null
+++ b/pubsub/test/test/sut_activator.c
@@ -0,0 +1,112 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you 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 <stdio.h>
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "service_tracker.h"
+
+#include "pubsub/subscriber.h"
+#include "pubsub/publisher.h"
+
+static int sut_receive(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, pubsub_multipart_callbacks_t *callbacks, bool *release);
+static int sut_pubAdded(void *handle, service_reference_pt reference, void *service);
+static int sut_pubRemoved(void *handle, service_reference_pt reference, void *service);
+
+
+struct activator {
+ pubsub_subscriber_t subSvc;
+ service_registration_pt reg;
+
+ service_tracker_pt tracker;
+
+ pthread_mutex_t mutex;
+ pubsub_publisher_t* pubSvc;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ struct activator* act = malloc(sizeof(*act));
+ *userData = act;
+ return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ struct activator* act = (struct activator*) userData;
+
+ properties_pt props = properties_create();
+ properties_set(props, "pubsub.topic", "ping");
+ act->subSvc.handle = act;
+ act->subSvc.receive = sut_receive;
+ act->reg = NULL;
+ bundleContext_registerService(context, PUBSUB_SUBSCRIBER_SERVICE_NAME, &act->subSvc, props, &act->reg);
+
+ const char* filter = "(&(objectClass=pubsub.publisher)(pubsub.topic=pong))";
+ service_tracker_customizer_pt customizer = NULL;
+ serviceTrackerCustomizer_create(act, NULL, sut_pubAdded, NULL, sut_pubRemoved, &customizer);
+ serviceTracker_createWithFilter(context, filter, customizer, &act->tracker);
+ serviceTracker_open(act->tracker);
+
+ return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt __attribute__((unused)) context) {
+ struct activator* act = userData;
+ serviceTracker_close(act->tracker);
+ return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt __attribute__((unused)) context) {
+ struct activator* act = userData;
+ serviceTracker_destroy(act->tracker);
+ return CELIX_SUCCESS;
+}
+
+static int sut_receive(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, pubsub_multipart_callbacks_t *callbacks, bool *release) {
+ struct activator* act = handle;
+ printf("Received msg %s, sending back\n", msgType);
+ pthread_mutex_lock(&act->mutex);
+ if (act->pubSvc != NULL) {
+ unsigned int sendId = 0;
+ act->pubSvc->localMsgTypeIdForMsgType(act->pubSvc->handle, msgType, &sendId);
+ act->pubSvc->send(act->pubSvc->handle, sendId, msg);
+ }
+ pthread_mutex_unlock(&act->mutex);
+ return CELIX_SUCCESS;
+}
+
+static int sut_pubAdded(void *handle, service_reference_pt reference, void *service) {
+ struct activator* act = handle;
+ pthread_mutex_lock(&act->mutex);
+ act->pubSvc = service;
+ pthread_mutex_unlock(&act->mutex);
+ return CELIX_SUCCESS;
+
+}
+
+static int sut_pubRemoved(void *handle, service_reference_pt reference, void *service) {
+ struct activator* act = handle;
+ pthread_mutex_lock(&act->mutex);
+ if (act->pubSvc == service) {
+ act->pubSvc = NULL;
+ }
+ pthread_mutex_unlock(&act->mutex);
+ return CELIX_SUCCESS;
+}
+
http://git-wip-us.apache.org/repos/asf/celix/blob/97df926c/pubsub/test/test/tst_activator.cpp
----------------------------------------------------------------------
diff --git a/pubsub/test/test/tst_activator.cpp b/pubsub/test/test/tst_activator.cpp
new file mode 100644
index 0000000..6d957a0
--- /dev/null
+++ b/pubsub/test/test/tst_activator.cpp
@@ -0,0 +1,199 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "bundle_activator.h"
+#include "service_tracker.h"
+
+#include "pubsub/subscriber.h"
+#include "pubsub/publisher.h"
+
+#include "msg.h"
+
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+
+
+
+static int tst_receive(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, pubsub_multipart_callbacks_t *callbacks, bool *release);
+static int tst_pubAdded(void *handle, service_reference_pt reference, void *service);
+static int tst_pubRemoved(void *handle, service_reference_pt reference, void *service);
+
+#define MSG_NAME "msg"
+
+struct activator {
+ pubsub_subscriber_t subSvc;
+ service_registration_pt reg = nullptr;
+
+ service_tracker_pt tracker = nullptr;
+
+ pthread_mutex_t mutex; //protects below
+ pubsub_publisher_t* pubSvc = nullptr;
+ unsigned int msgId = 0;
+ unsigned int count = 0;
+
+ bool started = false;
+
+};
+
+static struct activator g_act; //global
+
+celix_status_t bundleActivator_create(__attribute__((unused)) bundle_context_pt context, __attribute__((unused)) void **userData) {
+ //memset(&g_act, 0, sizeof(g_act));
+ return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_start(__attribute__((unused)) void * userData, bundle_context_pt context) {
+ properties_pt props = properties_create();
+ properties_set(props, "pubsub.topic", "pong");
+ g_act.subSvc.handle = &g_act;
+ g_act.subSvc.receive = tst_receive;
+ bundleContext_registerService(context, PUBSUB_SUBSCRIBER_SERVICE_NAME, &g_act.subSvc, props, &g_act.reg);
+
+ const char* filter = "(&(objectClass=pubsub.publisher)(pubsub.topic=ping))";
+ service_tracker_customizer_pt customizer = NULL;
+ serviceTrackerCustomizer_create(&g_act, NULL, tst_pubAdded, NULL, tst_pubRemoved, &customizer);
+ serviceTracker_createWithFilter(context, filter, customizer, &g_act.tracker);
+ serviceTracker_open(g_act.tracker);
+
+ g_act.started = true;
+
+ return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_stop(__attribute__((unused)) void * userData, bundle_context_pt __attribute__((unused)) context) {
+ serviceTracker_close(g_act.tracker);
+ return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(__attribute__((unused)) void * userData, bundle_context_pt __attribute__((unused)) context) {
+ serviceTracker_destroy(g_act.tracker);
+ return CELIX_SUCCESS;
+}
+
+static int tst_receive(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, pubsub_multipart_callbacks_t *callbacks, bool *release) {
+ struct activator* act = static_cast<struct activator*>(handle);
+ pthread_mutex_lock(&act->mutex);
+ act->count += 1;
+ pthread_mutex_unlock(&act->mutex);
+ return CELIX_SUCCESS;
+}
+
+static int tst_pubAdded(void *handle, service_reference_pt reference, void *service) {
+ struct activator* act = static_cast<struct activator*>(handle);
+ pthread_mutex_lock(&act->mutex);
+ act->pubSvc = static_cast<pubsub_publisher_t*>(service);
+ act->pubSvc->localMsgTypeIdForMsgType(act->pubSvc->handle, MSG_NAME, &g_act.msgId);
+ pthread_mutex_unlock(&act->mutex);
+ return CELIX_SUCCESS;
+
+}
+
+static int tst_pubRemoved(void *handle, service_reference_pt reference, void *service) {
+ struct activator* act = static_cast<struct activator*>(handle);
+ pthread_mutex_lock(&act->mutex);
+ if (act->pubSvc == service) {
+ act->pubSvc = NULL;
+ }
+ pthread_mutex_unlock(&act->mutex);
+ return CELIX_SUCCESS;
+}
+
+
+TEST_GROUP(PUBSUB_INT_GROUP)
+{
+ void setup() {
+ constexpr int TRIES = 25;
+ constexpr int TIMEOUT = 1000000;
+ CHECK_EQUAL(true, g_act.started);
+
+ //check if publisher is available
+ unsigned int msgId = 0;
+ for (int i = 0; i < TRIES; ++i) {
+ pthread_mutex_lock(&g_act.mutex);
+ msgId = g_act.msgId;
+ pthread_mutex_unlock(&g_act.mutex);
+ if (msgId == 0) {
+ printf("publisher still nullptr / msg Id is still 0, waiting for a while\n");
+ usleep(TIMEOUT);
+ } else {
+ break;
+ }
+ }
+ CHECK(msgId != 0);
+
+ //check if message are returned
+ msg_t initMsg;
+ initMsg.seqNr = 0;
+ for (int i = 0; i < TRIES; ++i) {
+ pthread_mutex_lock(&g_act.mutex);
+ g_act.pubSvc->send(g_act.pubSvc->handle, g_act.msgId, &initMsg);
+ pthread_mutex_unlock(&g_act.mutex);
+ usleep(TIMEOUT);
+ pthread_mutex_lock(&g_act.mutex);
+ int count = g_act.count;
+ pthread_mutex_unlock(&g_act.mutex);
+ if (count > 0) {
+ break;
+ } else {
+ printf("No return message received, waiting for a while\n");
+ }
+ }
+ }
+
+ void teardown() {
+ //nop
+ }
+};
+
+TEST(PUBSUB_INT_GROUP, sendRecvTest) {
+ g_act.count = 0;
+ constexpr int COUNT = 50;
+ msg_t msg;
+ for (int i = 0; i < COUNT; ++i) {
+ msg.seqNr = i;
+ pthread_mutex_lock(&g_act.mutex);
+ g_act.pubSvc->send(g_act.pubSvc->handle, g_act.msgId, &msg);
+ pthread_mutex_unlock(&g_act.mutex);
+ usleep(100000);
+ }
+
+ constexpr int TRIES = 25;
+ constexpr int TIMEOUT = 250000;
+ for (int i = 0; i < TRIES; ++i) {
+ pthread_mutex_lock(&g_act.mutex);
+ int count = g_act.count;
+ pthread_mutex_unlock(&g_act.mutex);
+ if (count == COUNT) {
+ break;
+ } else {
+ printf("Current count is %i, should be %i. Waiting a little\n", count, COUNT);
+ usleep(TIMEOUT);
+ }
+ }
+
+ pthread_mutex_lock(&g_act.mutex);
+ int count = g_act.count;
+ pthread_mutex_unlock(&g_act.mutex);
+ CHECK_EQUAL(COUNT, count);
+}
\ No newline at end of file