Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions .github/workflows/Test_Thunder_Test_Support.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: Test Thunder Test Support Library

permissions:
contents: read

on:
workflow_dispatch:
push:
branches: ["master", "development/Thunder_Test_Lib"]
paths:
- 'Tests/test_support/**'
- 'Source/Thunder/**'
- 'Source/core/**'
- 'Source/plugins/**'
pull_request:
branches: ["master"]
paths:
- 'Tests/test_support/**'
- 'Source/Thunder/**'
- 'Source/core/**'
- 'Source/plugins/**'

jobs:
SmokeTest:
runs-on: ubuntu-24.04

strategy:
matrix:
build_type: [Debug, Release]

name: Smoke Test - ${{matrix.build_type}}

steps:
- name: Install necessary packages
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 10
command: |
sudo gem install apt-spy2
sudo apt-spy2 fix --commit --launchpad --country=US
sudo apt-get update
sudo apt-get install -y python3-pip build-essential cmake ninja-build libusb-1.0-0-dev zlib1g-dev libssl-dev libgtest-dev
python3 -m venv venv
source venv/bin/activate
pip install jsonref

# ----- Checkout -----
- name: Checkout Thunder
uses: actions/checkout@v4
with:
path: Thunder

- name: Checkout ThunderTools - default
if: ${{ !contains(github.event.pull_request.body, '[DependsOn=ThunderTools:') }}
uses: actions/checkout@v4
with:
path: ThunderTools
repository: rdkcentral/ThunderTools

- name: Regex ThunderTools
if: ${{ contains(github.event.pull_request.body, '[DependsOn=ThunderTools:') }}
id: tools
uses: AsasInnab/regex-action@v1
with:
regex_pattern: '(?<=\[DependsOn=ThunderTools:).*(?=\])'
regex_flags: 'gim'
search_string: ${{github.event.pull_request.body}}

- name: Checkout ThunderTools - ${{steps.tools.outputs.first_match}}
if: ${{ contains(github.event.pull_request.body, '[DependsOn=ThunderTools:') }}
uses: actions/checkout@v4
with:
path: ThunderTools
repository: rdkcentral/ThunderTools
ref: ${{steps.tools.outputs.first_match}}

# ----- Build -----
- name: Build ThunderTools
run: |
source venv/bin/activate
cmake -G Ninja -S ThunderTools -B ${{matrix.build_type}}/build/ThunderTools \
-DCMAKE_INSTALL_PREFIX="${{matrix.build_type}}/install/usr"
cmake --build ${{matrix.build_type}}/build/ThunderTools --target install

- name: Build Thunder with test support
run: |
source venv/bin/activate
cmake -G Ninja -S Thunder -B ${{matrix.build_type}}/build/Thunder \
-DBINDING="127.0.0.1" \
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-DCMAKE_INSTALL_PREFIX="${{matrix.build_type}}/install/usr" \
-DCMAKE_MODULE_PATH="${PWD}/${{matrix.build_type}}/install/usr/include/WPEFramework/Modules" \
-DPORT="0" \
-DENABLE_TEST_RUNTIME=ON \
-DENABLE_CXX17=OFF
cmake --build ${{matrix.build_type}}/build/Thunder --target install

# ----- Run smoke test -----
- name: Run smoke test
run: |
LD_LIBRARY_PATH="${{matrix.build_type}}/install/usr/lib:$LD_LIBRARY_PATH" \
${{matrix.build_type}}/build/Thunder/Tests/test_support/tests/thunder_test_runtime_smoke \
--gtest_output="xml:smoke-test-results.xml" \
--gtest_color=yes

- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: smoke-test-results-${{matrix.build_type}}
path: smoke-test-results.xml
5 changes: 5 additions & 0 deletions Tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ option(FILE_UNLINK_TEST "File unlink test" OFF)
option(REDIRECT_TEST "Test stream redirection" OFF)
option(MESSAGEBUFFER_TEST "Test message buffer" OFF)
option(UNRAVELLER "reveal thread details" OFF)
option(ENABLE_TEST_RUNTIME "Build Thunder test support library for plugin integration tests" OFF)

if(BUILD_TESTS)
add_subdirectory(unit)
Expand Down Expand Up @@ -40,4 +41,8 @@ endif()

if(UNRAVELLER)
add_subdirectory(unraveller)
endif()

if(ENABLE_TEST_RUNTIME)
add_subdirectory(test_support)
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ENABLE_TEST_RUNTIME can currently be enabled on any platform, but Tests/test_support/ThunderTestRuntime.cpp uses POSIX-only APIs (mkdtemp) and hardcoded /tmp paths. Consider adding a platform guard here (e.g., only add the test_support subdirectory on POSIX platforms, or emit a fatal error if the option is ON on unsupported systems) to avoid configuration/build failures.

Suggested change
add_subdirectory(test_support)
if(UNIX)
add_subdirectory(test_support)
else()
message(FATAL_ERROR "ENABLE_TEST_RUNTIME is only supported on POSIX/UNIX platforms because Tests/test_support uses POSIX-only APIs.")
endif()

Copilot uses AI. Check for mistakes.
endif()
115 changes: 115 additions & 0 deletions Tests/test_support/CMakeLists.txt
Comment thread
bramoosterhuis marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# ============================================================================
# thunder_test_support - Static library for Thunder plugin integration testing
#
# This library embeds the Thunder PluginHost server (PluginServer, Controller,
# SystemInfo, etc.) into a static archive so that GTest-based test binaries
# can spin up a real Thunder runtime in-process without launching the
# standalone Thunder daemon.
#
# Usage:
# 1. Link your test executable against thunder_test_support.
# 2. Use ThunderTestRuntime::Initialize() to start the embedded server.
# 3. Call JSON-RPC or COM-RPC methods directly against loaded plugins.
# 4. Call ThunderTestRuntime::Deinitialize() when done.
#
# NOTE: PluginHost.cpp is deliberately excluded — it contains main().
# The test binary provides its own main() via GTest.
# ============================================================================

find_package(Threads REQUIRED)

set(THUNDER_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../Source/Thunder")

set(THREADPOOL_COUNT "4" CACHE STRING "The number of threads in the thread pool for test runtime")
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THREADPOOL_COUNT is already defined as a CACHE variable in Source/Thunder/CMakeLists.txt, and this set(... CACHE ...) in a subdirectory will reuse/overwrite the same cache entry (including its help text). To avoid confusing cache UI/help strings, consider not re-declaring it here and just consuming the existing cache variable (or use a uniquely named cache var specific to test support).

Suggested change
set(THREADPOOL_COUNT "4" CACHE STRING "The number of threads in the thread pool for test runtime")
if(NOT DEFINED THREADPOOL_COUNT)
set(THREADPOOL_COUNT "4")
endif()

Copilot uses AI. Check for mistakes.

add_library(thunder_test_support STATIC
ThunderTestRuntime.cpp
Module.cpp
${THUNDER_SOURCE_DIR}/PluginServer.cpp
${THUNDER_SOURCE_DIR}/Controller.cpp
${THUNDER_SOURCE_DIR}/SystemInfo.cpp
${THUNDER_SOURCE_DIR}/PostMortem.cpp
${THUNDER_SOURCE_DIR}/Probe.cpp
)

# PluginHost.cpp is deliberately excluded — it contains main().
# The test binary supplies its own main via GTest/GMock.

target_compile_definitions(thunder_test_support
PRIVATE
NAMESPACE=${NAMESPACE}
APPLICATION_NAME=ThunderTestRuntime
MODULE_NAME=ThunderTestRuntime
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MODULE_NAME is set both via target_compile_definitions(... MODULE_NAME=ThunderTestRuntime) and again via #define MODULE_NAME ThunderTestRuntime in Tests/test_support/Module.cpp. This can trigger macro redefinition warnings and also forces the module name for all compiled Thunder server sources in this archive. Prefer defining MODULE_NAME only in the dedicated Module.cpp (and drop the compile definition here), similar to how the main Thunder target sets APPLICATION_NAME/THREADPOOL_COUNT but not MODULE_NAME.

Suggested change
MODULE_NAME=ThunderTestRuntime

Copilot uses AI. Check for mistakes.
THREADPOOL_COUNT=${THREADPOOL_COUNT}
)

target_compile_options(thunder_test_support PRIVATE -Wno-psabi)

target_link_libraries(thunder_test_support
PRIVATE
CompileSettings::CompileSettings
)

if(EXCEPTION_CATCHING)
set_source_files_properties(${THUNDER_SOURCE_DIR}/PluginServer.cpp PROPERTIES COMPILE_FLAGS "-fexceptions")
endif()

target_include_directories(thunder_test_support
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE
${THUNDER_SOURCE_DIR}
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/Source/plugins/generated/jsonrpc>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/Source/Thunder/generated>
)

target_link_libraries(thunder_test_support
PUBLIC
${NAMESPACE}Core::${NAMESPACE}Core
${NAMESPACE}Cryptalgo::${NAMESPACE}Cryptalgo
${NAMESPACE}COM::${NAMESPACE}COM
${NAMESPACE}Messaging::${NAMESPACE}Messaging
${NAMESPACE}WebSocket::${NAMESPACE}WebSocket
${NAMESPACE}Plugins::${NAMESPACE}Plugins
${NAMESPACE}COMProcess::${NAMESPACE}COMProcess
Threads::Threads
)

if(WARNING_REPORTING)
target_sources(thunder_test_support PRIVATE ${THUNDER_SOURCE_DIR}/WarningReportingCategories.cpp)
endif()

if(PROCESSCONTAINERS)
target_link_libraries(thunder_test_support
PUBLIC
${NAMESPACE}ProcessContainers::${NAMESPACE}ProcessContainers)
target_compile_definitions(thunder_test_support
PUBLIC
PROCESSCONTAINERS_ENABLED=1)
endif()

if(HIBERNATESUPPORT)
target_link_libraries(thunder_test_support PUBLIC
${NAMESPACE}Hibernate::${NAMESPACE}Hibernate)
target_compile_definitions(thunder_test_support PUBLIC
HIBERNATE_SUPPORT_ENABLED=1)
endif()

# Enforce --whole-archive for this target so consumers automatically pull in
# Thunder's static initializers (MODULE_NAME_DECLARATION, SERVICE_REGISTRATION).
# Scoped to this archive only via $<TARGET_FILE:...> — won't affect other libs.
target_link_options(thunder_test_support
INTERFACE
-Wl,--whole-archive $<TARGET_FILE:thunder_test_support> -Wl,--no-whole-archive
)
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--whole-archive/--no-whole-archive are GNU ld/LLD flags and will break on non-ELF linkers (e.g. Apple ld, MSVC) if ENABLE_TEST_RUNTIME is enabled. Please guard these link options by platform/toolchain (e.g. only on Linux/Android with GNU/Clang) and provide the equivalent flags where needed (e.g. -Wl,-force_load on Apple) or document the limitation.

Suggested change
# Enforce --whole-archive for this target so consumers automatically pull in
# Thunder's static initializers (MODULE_NAME_DECLARATION, SERVICE_REGISTRATION).
# Scoped to this archive only via $<TARGET_FILE:...> — won't affect other libs.
target_link_options(thunder_test_support
INTERFACE
-Wl,--whole-archive $<TARGET_FILE:thunder_test_support> -Wl,--no-whole-archive
)
# Enforce whole-archive semantics for this target so consumers automatically pull in
# Thunder's static initializers (MODULE_NAME_DECLARATION, SERVICE_REGISTRATION).
# Use linker-specific flags only on supported platforms/toolchains.
if(APPLE)
target_link_options(thunder_test_support
INTERFACE
"-Wl,-force_load,$<TARGET_FILE:thunder_test_support>"
)
elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android") AND
(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
# Scoped to this archive only via $<TARGET_FILE:...> — won't affect other libs.
target_link_options(thunder_test_support
INTERFACE
-Wl,--whole-archive $<TARGET_FILE:thunder_test_support> -Wl,--no-whole-archive
)
else()
message(WARNING
"Automatic whole-archive linking for thunder_test_support is not configured for "
"${CMAKE_SYSTEM_NAME} with ${CMAKE_CXX_COMPILER_ID}. Consumers may need to link "
"the archive with platform-specific whole-archive/force-load options to ensure "
"Thunder static initializers are included."
)
endif()

Copilot uses AI. Check for mistakes.

# --- Install rules ---
install(TARGETS thunder_test_support
ARCHIVE DESTINATION lib
)

install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ThunderTestRuntime.h
DESTINATION include/thunder_test_support
)
Comment on lines +134 to +140
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Install rules hardcode lib/include instead of using GNUInstallDirs variables (${CMAKE_INSTALL_LIBDIR}, ${CMAKE_INSTALL_INCLUDEDIR}) used elsewhere in the project. Using the standard variables improves portability across distros/multilib layouts.

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +140
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs and this CMake target describe consumers linking against the thunder_test_support CMake target to pick up INTERFACE whole-archive link options, but the install rules here only install the .a and header—there is no target export / CMake package config for thunder_test_support, and the include dirs also lack an INSTALL_INTERFACE. If this library is intended for external consumers via find_package, it should be exported and install-interface include dirs should be set; otherwise the docs should avoid implying the imported target exists / carries link options.

Copilot uses AI. Check for mistakes.

add_subdirectory(tests)
12 changes: 12 additions & 0 deletions Tests/test_support/Module.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Module definition for the thunder_test_support static library.
//
// Uses MODULE_NAME_ARCHIVE_DECLARATION instead of MODULE_NAME_DECLARATION
// because this is a static archive, not a standalone binary. The archive
// macro only defines the MODULE_NAME string symbol. The full declaration
// (ModuleBuildRef, GetModuleServices, SetModuleServices) is left to the
// consumer's own MODULE_NAME_DECLARATION, avoiding duplicate definitions.

#define MODULE_NAME ThunderTestRuntime
#include <core/core.h>

MODULE_NAME_ARCHIVE_DECLARATION
Loading
Loading