Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
dac8a34
Remove Mockshell dependency from JSONRPC Functional Tests
smanes0213 Jun 9, 2026
4f92c50
Merge branch 'master' into development/Remove_MockShell_Dependency
smanes0213 Jun 9, 2026
34186b3
Merge branch 'master' into development/Remove_MockShell_Dependency
smanes0213 Jun 10, 2026
88902ce
Resolve review comments
smanes0213 Jun 10, 2026
1d858df
Add new interface headers to add the missed flags and add respective …
smanes0213 Jun 12, 2026
797396f
Merge branch 'master' into development/Covering_Missed_Tags
smanes0213 Jun 12, 2026
40a31e3
Add implementation files and update CMake accordingly
smanes0213 Jun 15, 2026
4598ea8
refactor: split ITestJsonFormatting into per-interface files, add res…
smanes0213 Jun 16, 2026
695afd6
Resolve review comments
smanes0213 Jun 16, 2026
f968e7d
Potential fix for pull request finding
smanes0213 Jun 16, 2026
f6761ba
Potential fix for pull request finding
smanes0213 Jun 16, 2026
7e2a380
Potential fix for pull request finding
smanes0213 Jun 16, 2026
7792415
Potential fix for pull request finding
smanes0213 Jun 16, 2026
551f3f1
Potential fix for pull request finding
smanes0213 Jun 16, 2026
ef6b950
Resolve review comments
smanes0213 Jun 16, 2026
76794b6
Resolve test failure
smanes0213 Jun 16, 2026
e6ec66d
Resolve test failure
smanes0213 Jun 16, 2026
74c74fc
Add Jsonrpc functional tests
smanes0213 Jun 17, 2026
522a4c9
Resolve build failure
smanes0213 Jun 17, 2026
8f0880e
Resolve build failure
smanes0213 Jun 17, 2026
9d96547
Update the include path for JSONRPC.h
smanes0213 Jun 17, 2026
3175253
Update the include path for JSONRPC.h
smanes0213 Jun 17, 2026
3e7f0d9
Resolve test failure
smanes0213 Jun 17, 2026
9e06ccd
Potential fix for pull request finding
smanes0213 Jun 17, 2026
04a7a5f
Resolve review comments
smanes0213 Jun 18, 2026
6831e12
Resolve review comments
smanes0213 Jun 18, 2026
21fd51f
Resolve workflow error
smanes0213 Jun 18, 2026
90ff5ac
Resolve workflow error
smanes0213 Jun 18, 2026
22e3d23
Resolve copilot review comments
smanes0213 Jun 18, 2026
b9609dc
Merge branch 'master' into development/Covering_Missed_Tags
smanes0213 Jun 22, 2026
1982d31
Resolve workflow failure
smanes0213 Jun 22, 2026
05a7e08
Resolve workflow failure
smanes0213 Jun 22, 2026
4d69c52
Resolve workflow failure
smanes0213 Jun 22, 2026
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
3 changes: 2 additions & 1 deletion .github/workflows/ProxyStubFunctionalTests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
run: |
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
PKGS="python3-venv python3-pip build-essential cmake ninja-build"
PKGS="python3-venv python3-pip build-essential cmake ninja-build libgtest-dev"
if [ "${{ matrix.architecture }}" = "32" ]; then
PKGS="$PKGS zlib1g-dev:i386 libssl-dev:i386 gcc-13-multilib g++-13-multilib"
else
Expand Down Expand Up @@ -86,6 +86,7 @@ jobs:
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DENABLE_TESTING=ON \
-DFUNCTIONAL_TESTS=ON \
-DENABLE_TEST_RUNTIME=ON \
-DPROXYSTUB_GENERATOR=$(pwd)/ProxyStubGenerator/StubGenerator.py \
-DJSON_GENERATOR=$(pwd)/JsonGenerator/JsonGenerator.py
cmake \
Expand Down
8 changes: 8 additions & 0 deletions tests/FunctionalTests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ option(TEST_OPTIONALS "Enable optional parameters tests" ON)
option(TEST_PRIMITIVES "Enable primitive types tests" ON)
option(TEST_RESTRICTIONS "Enable restrict annotation tests" ON)
option(TEST_STRUCTS "Enable POD struct tests" ON)
option(TEST_ENCODING_MAC "Enable @encode:mac annotation tests" ON)
option(TEST_LENGTH_MODES "Enable @length:void/@length:return tests" ON)
option(TEST_JSON_SHAPE "Enable @wrapped/@extract shape tests" ON)
option(TEST_JSON_TEXT_KEEP "Enable @text:keep naming tests" ON)
option(TEST_JSON_TEXT_CASE "Enable @text:legacy case convention tests" ON)
option(TEST_JSON_COMPLIANT "Enable @compliant format tests" ON)
option(TEST_JSON_UNCOMPLIANT_EXT "Enable @uncompliant:extended format tests" ON)
option(TEST_JSON_UNCOMPLIANT_COL "Enable @uncompliant:collapsed format tests" ON)

set(CMAKE_MODULE_PATH "${CMAKE_BINARY_DIR}" CACHE BOOL "" FORCE)
Comment thread
smanes0213 marked this conversation as resolved.

Expand Down
14 changes: 7 additions & 7 deletions tests/FunctionalTests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ This generates JSON-RPC dispatch code but integration with the main test executa

### JSON-RPC functional tests

A separate test executable validates JsonGenerator output using a simplified header-only architecture:
A separate test executable validates JsonGenerator output using a lightweight two-file server infrastructure:

```bash
cmake -S . -B build -DBUILD_JSON_RPC_TESTS=ON
Comment thread
smanes0213 marked this conversation as resolved.
Expand All @@ -71,7 +71,7 @@ cmake --build build --target JsonRpcFunctionalTests
This creates `JsonRpcFunctionalTests` executable that:
- Reuses the same interface definitions and implementation classes as COM-RPC tests
- Tests **full round-trip JSON marshalling/unmarshalling** using Thunder's `PluginHost::JSONRPC::Invoke()` directly
- Uses **header-only infrastructure** (`JsonRpcServer.h` contains both registration system and dispatcher)
- Uses a lightweight two-file infrastructure: `JsonRpcServer.h` contains the registration system and dispatcher, `JsonRpcServer.cpp` contains the runtime bootstrap (`ThunderTestRuntime` init and `IShell` attach)
- **One-line registration** per interface using lambda-based static registrars (no template specialization boilerplate)
- Uses `JsonRpcTestHarness<IF>` fixtures instead of `TestHarness<IF>`
- Validates that generated `J<Interface>::Register()` dispatch code compiles and works correctly
Comment thread
smanes0213 marked this conversation as resolved.
Expand Down Expand Up @@ -140,7 +140,7 @@ ProxyStubs are generated by `ProxyStubGenerator` at build time into `build/comrp

## JSON-RPC test architecture

The JSON-RPC test binary uses Thunder's `PluginHost::JSONRPC` for direct method dispatch without network transport. The infrastructure is **header-only** - all registration and dispatch logic lives in `JsonRpcServer.h`:
The JSON-RPC test binary performs direct in-process dispatcher invocation (no network transport). `JsonRpcServer` is built on `Test::JsonRPCRegister` (from `JsonRpcRegistrations.h`), which derives from `PluginHost::JSONRPCSupportsEventStatus`. The infrastructure splits across two files: `JsonRpcServer.h` contains the registration system and dispatcher, while `JsonRpcServer.cpp` contains the runtime bootstrap (`ThunderTestRuntime` initialisation and `IShell` attachment):

```
┌────────────────────────────────────────────────────┐
Expand All @@ -158,8 +158,8 @@ The JSON-RPC test binary uses Thunder's `PluginHost::JSONRPC` for direct method
│ │ │based registry) │ │ │ ↓ │ │
│ │ └─────────────────┘ │ │ JSON-RPC 2.0 │ │
│ │ │ │ params/response │ │
│ │ MockShell │ │ │ │
│ │ (IShell stub) │ │ │ │
│ │ ThunderTestRuntime │ │ │ │
│ │ + real IShell │ │ │ │
│ │ │ │ │ │
│ │ Impl (reused) │ │ │ │
│ └─────────────────────┘ └─────────────────┘ │
Expand All @@ -168,9 +168,9 @@ The JSON-RPC test binary uses Thunder's `PluginHost::JSONRPC` for direct method
└────────────────────────────────────────────────────┘
```

**Server side** — `JsonRpcServer` inherits from `PluginHost::JSONRPC` and `PluginHost::IPlugin`. A `MockShell` provides the minimal `IShell` interface needed for initialization. Implementation classes are the same protocol-agnostic implementations used for COM-RPC tests.
**Server side** — `JsonRpcServer` derives from `Test::JsonRPCRegister` (which derives from `PluginHost::JSONRPCSupportsEventStatus`) and does not implement `PluginHost::IPlugin`. It initializes `Thunder::TestCore::ThunderTestRuntime` and attaches to a real `IShell` from the embedded Thunder `PluginHost::Server` (Controller callsign). Implementation classes are the same protocol-agnostic implementations used for COM-RPC tests.

**Registration system** (header-only in `JsonRpcServer.h`):
**Registration system** (in `JsonRpcServer.h`):
- `JsonRpcRegistrationProvider`: Singleton collecting registration lambdas
- `JsonRpcRegistrar<INTERFACE, IMPL>`: Template class capturing register function in lambda
- Static initialization: Each implementation file has one-line registrar:
Expand Down
40 changes: 40 additions & 0 deletions tests/FunctionalTests/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ target_link_libraries(FunctionalTestCommon
${NAMESPACE}COM::${NAMESPACE}COM
)

if(ENABLE_JSON_RPC_TESTS)
target_link_libraries(FunctionalTestCommon
PUBLIC
${NAMESPACE}Plugins::${NAMESPACE}Plugins
)
endif()

add_library(FunctionalTestProxySources OBJECT)
add_library(FunctionalTestJsonSources OBJECT)

Expand All @@ -65,6 +72,7 @@ target_link_libraries(FunctionalTestJsonSources
PRIVATE
FunctionalTestCommon
${NAMESPACE}Core::${NAMESPACE}Core
${NAMESPACE}Plugins::${NAMESPACE}Plugins
)

macro(AddTestInterface TestName)
Expand Down Expand Up @@ -155,6 +163,38 @@ if (TEST_ASYNC)
AddTestInterface("Async" COM_RPC JSON_RPC)
endif()

if (TEST_ENCODING_MAC)
AddTestInterface("EncodingMac" COM_RPC JSON_RPC)
endif()

if (TEST_LENGTH_MODES)
AddTestInterface("LengthModes" COM_RPC) # COM-RPC only — @length:return requires non-uint32_t return type, unsupported by JsonGenerator
endif()

if (TEST_JSON_SHAPE)
AddTestInterface("JsonShape" COM_RPC JSON_RPC)
endif()

if (TEST_JSON_TEXT_KEEP)
AddTestInterface("JsonTextKeep" COM_RPC JSON_RPC)
endif()

if (TEST_JSON_TEXT_CASE)
AddTestInterface("JsonTextCase" COM_RPC JSON_RPC)
endif()

if (TEST_JSON_COMPLIANT)
AddTestInterface("JsonCompliant" COM_RPC JSON_RPC)
endif()

if (TEST_JSON_UNCOMPLIANT_EXT)
AddTestInterface("JsonUncompliantExtended" COM_RPC JSON_RPC)
endif()

if (TEST_JSON_UNCOMPLIANT_COL)
AddTestInterface("JsonUncompliantCollapsed" COM_RPC JSON_RPC)
endif()

list(LENGTH COM_RPC_INTERFACE_HEADERS NUM_COM_TESTS)
list(LENGTH JSON_INTERFACE_HEADERS NUM_JSON_TESTS)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2026 Metrological
*
* 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 <ImplementationFactory.h>
#include <ITestEncodingMac.h>
#include <cstring>

namespace Thunder {
namespace TestImplementation {

class TestEncodingMacImpl : public FunctionalTest::ITestEncodingMac {
public:
TestEncodingMacImpl() { memset(_mac, 0, sizeof(_mac)); }
~TestEncodingMacImpl() override = default;

TestEncodingMacImpl(const TestEncodingMacImpl&) = delete;
TestEncodingMacImpl& operator=(const TestEncodingMacImpl&) = delete;

Core::hresult SetMacAddress(const uint8_t mac[]) override
{
memcpy(_mac, mac, 6);
return Core::ERROR_NONE;
}

Core::hresult GetMacAddress(uint8_t mac[]) const override
{
memcpy(mac, _mac, 6);
return Core::ERROR_NONE;
}

Core::hresult EchoMacAddress(const uint8_t input[], uint8_t output[]) const override
{
memcpy(output, input, 6);
return Core::ERROR_NONE;
}

BEGIN_INTERFACE_MAP(TestEncodingMacImpl)
INTERFACE_ENTRY(FunctionalTest::ITestEncodingMac)
END_INTERFACE_MAP

private:
uint8_t _mac[6];
};

static Factory::Registrar<FunctionalTest::ITestEncodingMac, TestEncodingMacImpl> g_encodingMacRegistrar;

} // namespace TestImplementation
} // namespace Thunder
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2026 Metrological
*
* 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 <ImplementationFactory.h>
#include <ITestJsonCompliant.h>

namespace Thunder {
namespace TestImplementation {

class TestJsonCompliantImpl : public FunctionalTest::ITestJsonCompliant {
public:
TestJsonCompliantImpl() = default;
~TestJsonCompliantImpl() override = default;

TestJsonCompliantImpl(const TestJsonCompliantImpl&) = delete;
TestJsonCompliantImpl& operator=(const TestJsonCompliantImpl&) = delete;

Core::hresult Ping(const string& payload, string& reply) const override
{
reply = payload;
return Core::ERROR_NONE;
}

BEGIN_INTERFACE_MAP(TestJsonCompliantImpl)
INTERFACE_ENTRY(FunctionalTest::ITestJsonCompliant)
END_INTERFACE_MAP
};

static Factory::Registrar<FunctionalTest::ITestJsonCompliant, TestJsonCompliantImpl> g_registrar;

} // namespace TestImplementation
} // namespace Thunder
67 changes: 67 additions & 0 deletions tests/FunctionalTests/common/implementations/TestJsonShapeImpl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2026 Metrological
*
* 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 <ImplementationFactory.h>
#include <ITestJsonShape.h>

namespace Thunder {
namespace TestImplementation {

class TestJsonShapeImpl : public FunctionalTest::ITestJsonShape {
public:
TestJsonShapeImpl() : _counter(42) {}
~TestJsonShapeImpl() override = default;

TestJsonShapeImpl(const TestJsonShapeImpl&) = delete;
TestJsonShapeImpl& operator=(const TestJsonShapeImpl&) = delete;

Core::hresult GetWrappedCounter(uint32_t& counter) const override
{
counter = _counter;
return Core::ERROR_NONE;
}

Core::hresult EchoExtractedList(
const std::vector<uint32_t>& input,
std::vector<uint32_t>& output) const override
{
output = input;
return Core::ERROR_NONE;
}

Core::hresult EchoStruct(
const Dimensions& in,
Dimensions& out) const override
{
out = in;
return Core::ERROR_NONE;
}

BEGIN_INTERFACE_MAP(TestJsonShapeImpl)
INTERFACE_ENTRY(FunctionalTest::ITestJsonShape)
END_INTERFACE_MAP

private:
uint32_t _counter;
};

static Factory::Registrar<FunctionalTest::ITestJsonShape, TestJsonShapeImpl> g_jsonShapeRegistrar;

} // namespace TestImplementation
} // namespace Thunder
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2026 Metrological
*
* 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 <ImplementationFactory.h>
#include <ITestJsonTextCase.h>

namespace Thunder {
namespace TestImplementation {

class TestJsonTextCaseImpl : public FunctionalTest::ITestJsonTextCase {
public:
TestJsonTextCaseImpl() = default;
~TestJsonTextCaseImpl() override = default;

TestJsonTextCaseImpl(const TestJsonTextCaseImpl&) = delete;
TestJsonTextCaseImpl& operator=(const TestJsonTextCaseImpl&) = delete;

Core::hresult EchoCaseConvention(const uint16_t sourceValue, uint16_t& resultValue) const override
{
resultValue = sourceValue;
return Core::ERROR_NONE;
}

BEGIN_INTERFACE_MAP(TestJsonTextCaseImpl)
INTERFACE_ENTRY(FunctionalTest::ITestJsonTextCase)
END_INTERFACE_MAP
};

static Factory::Registrar<FunctionalTest::ITestJsonTextCase, TestJsonTextCaseImpl> g_registrar;

} // namespace TestImplementation
} // namespace Thunder
Loading
Loading