Initial release

This commit is contained in:
Martino Ferrari
2026-05-29 13:29:59 +02:00
commit 617b5bd712
110 changed files with 29234 additions and 0 deletions
@@ -0,0 +1 @@
include Makefile.inc
@@ -0,0 +1,58 @@
#############################################################
#
# Copyright 2015 F4E | European Joint Undertaking for ITER
# and the Development of Fusion Energy ('Fusion for Energy')
#
# Licensed under the EUPL, Version 1.1 or - as soon they
# will be approved by the European Commission - subsequent
# versions of the EUPL (the "Licence");
# You may not use this work except in compliance with the
# Licence.
# You may obtain a copy of the Licence at:
#
# http://ec.europa.eu/idabc/eupl
#
# Unless required by applicable law or agreed to in
# writing, software distributed under the Licence is
# distributed on an "AS IS" basis,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied.
# See the Licence for the specific language governing
# permissions and limitations under the Licence.
#
#############################################################
OBJSX = UDPStreamerTest.x UDPStreamerGTest.x
PACKAGE=Components/DataSources
ROOT_DIR=../../../..
MAKEDEFAULTDIR=$(MARTe2_DIR)/MakeDefaults
include $(MAKEDEFAULTDIR)/MakeStdLibDefs.$(TARGET)
INCLUDES += -I.
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L0Types
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L2Objects
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L3Streams
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Messages
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Configuration
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L5GAMs
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4StateMachine
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L5GAMs
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
INCLUDES += -I$(MARTe2_DIR)/Lib/gtest-1.7.0/include
INCLUDES += -I$(ROOT_DIR)/Common/UDP
INCLUDES += -I$(ROOT_DIR)/Source/Components/DataSources/UDPStreamer
all: $(OBJS) \
$(BUILD_DIR)/UDPStreamerTest$(LIBEXT)
echo $(OBJS)
include depends.$(TARGET)
include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)
@@ -0,0 +1,227 @@
/**
* @file UDPStreamerGTest.cpp
* @brief Source file for class UDPStreamerGTest
* @date 13/05/2026
* @author Martino Ferrari
*
* @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
* the Development of Fusion Energy ('Fusion for Energy').
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved
* by the European Commission - subsequent versions of the EUPL (the "Licence")
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
*
* @warning Unless required by applicable law or agreed to in writing,
* software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the Licence permissions and limitations under the Licence.
*
* @details This source file contains the GTest wrapper for all UDPStreamer tests.
*/
#define DLL_API
/*---------------------------------------------------------------------------*/
/* Standard header includes */
/*---------------------------------------------------------------------------*/
#include "gtest/gtest.h"
#include <limits.h>
/*---------------------------------------------------------------------------*/
/* Project header includes */
/*---------------------------------------------------------------------------*/
#include "UDPStreamerTest.h"
/*---------------------------------------------------------------------------*/
/* Method definitions */
/*---------------------------------------------------------------------------*/
TEST(UDPStreamerGTest, TestConstructor) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestConstructor());
}
TEST(UDPStreamerGTest, TestInitialise_Valid) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestInitialise_Valid());
}
TEST(UDPStreamerGTest, TestInitialise_DefaultPort) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestInitialise_DefaultPort());
}
TEST(UDPStreamerGTest, TestInitialise_InvalidMaxPayloadSize) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestInitialise_InvalidMaxPayloadSize());
}
TEST(UDPStreamerGTest, TestInitialise_ZeroStackSize) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestInitialise_ZeroStackSize());
}
TEST(UDPStreamerGTest, TestInitialise_AutoMode_Valid) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestInitialise_AutoMode_Valid());
}
TEST(UDPStreamerGTest, TestInitialise_AutoMode_MissingRefreshRate) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestInitialise_AutoMode_MissingRefreshRate());
}
TEST(UDPStreamerGTest, TestInitialise_UnknownPublishingMode) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestInitialise_UnknownPublishingMode());
}
TEST(UDPStreamerGTest, TestGetBrokerName_Output) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestGetBrokerName_Output());
}
TEST(UDPStreamerGTest, TestGetBrokerName_Input) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestGetBrokerName_Input());
}
TEST(UDPStreamerGTest, TestAllocateMemory) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestAllocateMemory());
}
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_BasicSignals) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestSetConfiguredDatabase_BasicSignals());
}
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_Quantized) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestSetConfiguredDatabase_Quantized());
}
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_InvalidQuantOnInteger) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestSetConfiguredDatabase_InvalidQuantOnInteger());
}
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_UnknownQuantType) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestSetConfiguredDatabase_UnknownQuantType());
}
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_TimeModePacket) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestSetConfiguredDatabase_TimeModePacket());
}
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_TimeModeFullArray) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestSetConfiguredDatabase_TimeModeFullArray());
}
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_TimeModeFirstSample) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestSetConfiguredDatabase_TimeModeFirstSample());
}
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_MissingSamplingRate) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestSetConfiguredDatabase_MissingSamplingRate());
}
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_InvalidTimeSignal) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestSetConfiguredDatabase_InvalidTimeSignal());
}
TEST(UDPStreamerGTest, TestSetConfiguredDatabase_FullArrayMismatch) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestSetConfiguredDatabase_FullArrayMismatch());
}
TEST(UDPStreamerGTest, TestPrepareNextState) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestPrepareNextState());
}
TEST(UDPStreamerGTest, TestSynchronise_NoClient) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestSynchronise_NoClient());
}
TEST(UDPStreamerGTest, TestExecute_ConnectDataDisconnect) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestExecute_ConnectDataDisconnect());
}
TEST(UDPStreamerGTest, TestExecute_Fragmentation) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestExecute_Fragmentation());
}
TEST(UDPStreamerGTest, TestQuantization_Uint16Extremes) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestQuantization_Uint16Extremes());
}
TEST(UDPStreamerGTest, TestQuantization_Uint8Clamping) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestQuantization_Uint8Clamping());
}
TEST(UDPStreamerGTest, TestGetPort) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestGetPort());
}
TEST(UDPStreamerGTest, TestGetMaxPayloadSize) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestGetMaxPayloadSize());
}
TEST(UDPStreamerGTest, TestIsClientConnected_InitiallyFalse) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestIsClientConnected_InitiallyFalse());
}
TEST(UDPStreamerGTest, TestHighFrequency_AllocateMemory) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestHighFrequency_AllocateMemory());
}
TEST(UDPStreamerGTest, TestHighFrequency_Fragmentation) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestHighFrequency_Fragmentation());
}
TEST(UDPStreamerGTest, TestHighFrequency_DataIntegrity) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestHighFrequency_DataIntegrity());
}
TEST(UDPStreamerGTest, TestInitialise_MulticastMode_Valid) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestInitialise_MulticastMode_Valid());
}
TEST(UDPStreamerGTest, TestInitialise_MulticastMode_DefaultDataPort) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestInitialise_MulticastMode_DefaultDataPort());
}
TEST(UDPStreamerGTest, TestInitialise_MulticastMode_InvalidDataPort) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestInitialise_MulticastMode_InvalidDataPort());
}
TEST(UDPStreamerGTest, TestPrepareNextState_Multicast) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestPrepareNextState_Multicast());
}
TEST(UDPStreamerGTest, TestExecute_MulticastConnectDataDisconnect) {
UDPStreamerTest test;
ASSERT_TRUE(test.TestExecute_MulticastConnectDataDisconnect());
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,239 @@
/**
* @file UDPStreamerTest.h
* @brief Header file for class UDPStreamerTest
* @date 13/05/2026
* @author Martino Ferrari
*
* @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
* the Development of Fusion Energy ('Fusion for Energy').
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved
* by the European Commission - subsequent versions of the EUPL (the "Licence")
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
*
* @warning Unless required by applicable law or agreed to in writing,
* software distributed under the Licence is distributed on an "AS IS"
* basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the Licence permissions and limitations under the Licence.
*
* @details This header file contains the declaration of the class UDPStreamerTest
* with all of its public, protected and private members. It may also include
* definitions for inline methods which need to be visible to the compiler.
*/
#ifndef UDPSTREAMERTEST_H_
#define UDPSTREAMERTEST_H_
/*---------------------------------------------------------------------------*/
/* Standard header includes */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Project header includes */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Class declaration */
/*---------------------------------------------------------------------------*/
/**
* @brief Tests the UDPStreamer DataSource public methods.
*/
class UDPStreamerTest {
public:
/**
* @brief Tests the default constructor.
*/
bool TestConstructor();
/**
* @brief Tests Initialise with a fully valid configuration.
*/
bool TestInitialise_Valid();
/**
* @brief Tests that a missing Port uses the default (44500).
*/
bool TestInitialise_DefaultPort();
/**
* @brief Tests that MaxPayloadSize below the minimum is rejected.
*/
bool TestInitialise_InvalidMaxPayloadSize();
/**
* @brief Tests that StackSize = 0 is rejected.
*/
bool TestInitialise_ZeroStackSize();
/**
* @brief Tests GetBrokerName returns the correct broker for OutputSignals.
*/
bool TestGetBrokerName_Output();
/**
* @brief Tests GetBrokerName returns empty string for InputSignals.
*/
bool TestGetBrokerName_Input();
/**
* @brief Tests AllocateMemory allocates readyBuffer, scratchBuffer, wireBuffer.
*/
bool TestAllocateMemory();
/**
* @brief Tests SetConfiguredDatabase with basic signal types.
*/
bool TestSetConfiguredDatabase_BasicSignals();
/**
* @brief Tests SetConfiguredDatabase with a quantized float signal.
*/
bool TestSetConfiguredDatabase_Quantized();
/**
* @brief Tests that quantization on a non-float signal is rejected.
*/
bool TestSetConfiguredDatabase_InvalidQuantOnInteger();
/**
* @brief Tests that an unknown QuantizedType is rejected.
*/
bool TestSetConfiguredDatabase_UnknownQuantType();
/**
* @brief Tests TimeMode = PacketTime (default).
*/
bool TestSetConfiguredDatabase_TimeModePacket();
/**
* @brief Tests TimeMode = FullArray with a matching time signal.
*/
bool TestSetConfiguredDatabase_TimeModeFullArray();
/**
* @brief Tests TimeMode = FirstSample with a scalar time signal.
*/
bool TestSetConfiguredDatabase_TimeModeFirstSample();
/**
* @brief Tests that FirstSample without SamplingRate is rejected.
*/
bool TestSetConfiguredDatabase_MissingSamplingRate();
/**
* @brief Tests that TimeSignal pointing to a non-existent signal is rejected.
*/
bool TestSetConfiguredDatabase_InvalidTimeSignal();
/**
* @brief Tests that FullArray TimeMode with mismatched element counts is rejected.
*/
bool TestSetConfiguredDatabase_FullArrayMismatch();
/**
* @brief Tests PrepareNextState starts the thread and opens the socket.
*/
bool TestPrepareNextState();
/**
* @brief Tests Synchronise when no client is connected (must return true, no crash).
*/
bool TestSynchronise_NoClient();
/**
* @brief Tests the full CONNECT → CONFIG → DATA → DISCONNECT flow via loopback UDP.
*/
bool TestExecute_ConnectDataDisconnect();
/**
* @brief Tests that DATA packets are fragmented correctly for large payloads.
*/
bool TestExecute_Fragmentation();
/**
* @brief Tests uint16 quantization: verifies that 0 maps to 0 and max maps to 65535.
*/
bool TestQuantization_Uint16Extremes();
/**
* @brief Tests uint8 quantization: verifies clamping of out-of-range values.
*/
bool TestQuantization_Uint8Clamping();
/**
* @brief Tests PublishingMode = "Auto" with a valid MinRefreshRate.
*/
bool TestInitialise_AutoMode_Valid();
/**
* @brief Tests that PublishingMode = "Auto" without MinRefreshRate is rejected.
*/
bool TestInitialise_AutoMode_MissingRefreshRate();
/**
* @brief Tests that an unknown PublishingMode string is rejected.
*/
bool TestInitialise_UnknownPublishingMode();
/**
* @brief Tests the GetPort() accessor.
*/
bool TestGetPort();
/**
* @brief Tests the GetMaxPayloadSize() accessor.
*/
bool TestGetMaxPayloadSize();
/**
* @brief Tests that IsClientConnected() returns false before any CONNECT.
*/
bool TestIsClientConnected_InitiallyFalse();
/**
* @brief Tests AllocateMemory with 4 high-frequency int16[1000] packed channels (1 MSps).
*/
bool TestHighFrequency_AllocateMemory();
/**
* @brief Tests that 4 int16[1000] channels produce exactly 6 fragments at MaxPayloadSize=1400.
* Payload: 8 (HRT) + 8 (T0/uint64) + 4×2000 (int16[1000]) = 8016 bytes;
* chunk = 1383 bytes → ceil(8016/1383) = 6 fragments.
*/
bool TestHighFrequency_Fragmentation();
/**
* @brief Tests full CONNECT→DATA→DISCONNECT cycle with high-frequency packed signals.
* Reassembles all fragments and verifies the total payload size.
*/
bool TestHighFrequency_DataIntegrity();
/**
* @brief Tests Initialise with MulticastGroup and explicit DataPort.
*/
bool TestInitialise_MulticastMode_Valid();
/**
* @brief Tests that DataPort defaults to Port+1 when MulticastGroup is set but DataPort is absent.
*/
bool TestInitialise_MulticastMode_DefaultDataPort();
/**
* @brief Tests that DataPort equal to Port is rejected.
*/
bool TestInitialise_MulticastMode_InvalidDataPort();
/**
* @brief Tests PrepareNextState in multicast mode: TCP listener opens, data socket connects.
*/
bool TestPrepareNextState_Multicast();
/**
* @brief Tests full TCP CONNECT → CONFIG → DATA via multicast → DISCONNECT on loopback.
*/
bool TestExecute_MulticastConnectDataDisconnect();
};
#endif /* UDPSTREAMERTEST_H_ */
+569
View File
@@ -0,0 +1,569 @@
/**
* Test MARTe2 application for UDPStreamer DataSource.
*
* Three independent RT threads demonstrate all four UDPStreamer time modes:
*
* Thread1 "Streamer" port 44500 TCP control / 44503 UDP multicast 239.0.0.1
* (scalar signals, auto-accumulated to arrays[10], multicast mode,
* 100 Hz flush = 10 samples per packet, 1 kHz source)
* Counter uint32 cycle counter
* Time uint32 time in microseconds (LinuxTimer, 1 kHz)
* Sine1 float32, 1 Hz, quantised to uint16 on wire (PacketTime)
* Sine2 float32, 0.3 Hz, raw float32 on wire (PacketTime)
*
* Thread2 "FastStreamer" port 44501 (packed arrays, FirstSample + LastSample)
* Time uint32 scalar anchor (5 kHz LinuxTimer)
* Ch1 float32[1000], 1 kHz sine (TimeMode = FirstSample)
* Ch2 float32[1000], 10 kHz sine (TimeMode = LastSample)
* Both channels use Time as the anchor and SamplingRate = 5 000 000 Hz so
* the WebUI reconstructs the 200 ns per-sample timestamps.
*
* Thread3 "FullArrStreamer" port 44502 (packed arrays, FullArray)
* TimeArray uint64[1000] per-sample timestamps in ns generated by TimeArrayGAM
* Ch3 float32[1000], 3 kHz sine (TimeMode = FullArray)
* Ch4 float32[1000], 500 Hz sine (TimeMode = FullArray)
* The WebUI uses the explicit timestamp for each sample rather than
* reconstructing them from a scalar anchor.
*/
$TestApp = {
Class = RealTimeApplication
+Functions = {
Class = ReferenceContainer
// ── Copy Counter + Time from LinuxTimer into the inter-GAM DDB ──────
+TimerGAM = {
Class = IOGAM
InputSignals = {
Counter = {
DataSource = Timer
Type = uint32
}
Time = {
Frequency = 1000
DataSource = Timer
Type = uint32
}
}
OutputSignals = {
Counter = {
DataSource = DDB
Type = uint32
}
Time = {
DataSource = DDB
Type = uint32
}
}
}
// ── 5 kHz fast timer for packed-array threads ────────────────────────
+FastTimerGAM = {
Class = IOGAM
InputSignals = {
Time = {
Frequency = 5000
DataSource = FastTimer
Type = uint32
}
}
OutputSignals = {
Time = {
DataSource = DDB2
Type = uint32
}
}
}
// ── 1 Hz sinusoidal signal ───────────────────────────────────────────
+SineGAM1 = {
Class = WaveformSin
Amplitude = 10.0
Frequency = 1.0
Phase = 0.0
Offset = 0.0
InputSignals = {
Time = {
DataSource = DDB
Type = uint32
}
}
OutputSignals = {
Sine1 = {
DataSource = DDB
Type = float32
}
}
}
// ── 0.3 Hz sinusoidal signal (phase-shifted) ─────────────────────────
+SineGAM2 = {
Class = WaveformSin
Amplitude = 5.0
Frequency = 0.3
Phase = 1.0472
Offset = 0.0
InputSignals = {
Time = {
DataSource = DDB
Type = uint32
}
}
OutputSignals = {
Sine2 = {
DataSource = DDB
Type = float32
}
}
}
// ── 1 kHz sine burst channel 1 (FirstSample anchor) ───────────────
+SineGAM3 = {
Class = SineArrayGAM
Frequency = 1000.0
Amplitude = 1.0
Phase = 0.0
Offset = 0.0
SamplingRate = 5000000.0
OutputSignals = {
Ch1 = {
DataSource = DDB2
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
// ── 10 kHz sine burst channel 2 (LastSample anchor) ───────────────
+SineGAM4 = {
Class = SineArrayGAM
Frequency = 10000.0
Amplitude = 0.5
Phase = 1.5708
Offset = 0.0
SamplingRate = 5000000.0
OutputSignals = {
Ch2 = {
DataSource = DDB2
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
// ── Route scalar signals → Streamer ──────────────────────────────────
+StreamerGAM = {
Class = IOGAM
InputSignals = {
Counter = {
DataSource = DDB
Type = uint32
}
Time = {
DataSource = DDB
Type = uint32
}
Sine1 = {
DataSource = DDB
Type = float32
}
Sine2 = {
DataSource = DDB
Type = float32
}
}
OutputSignals = {
Counter = {
DataSource = Streamer
Type = uint32
}
Time = {
DataSource = Streamer
Type = uint32
}
Sine1 = {
DataSource = Streamer
Type = float32
}
Sine2 = {
DataSource = Streamer
Type = float32
}
}
}
// ── Route packed arrays → FastStreamer (FirstSample + LastSample) ────
+FastStreamerGAM = {
Class = IOGAM
InputSignals = {
Time = {
DataSource = DDB2
Type = uint32
}
Ch1 = {
DataSource = DDB2
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
Ch2 = {
DataSource = DDB2
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
OutputSignals = {
Time = {
DataSource = FastStreamer
Type = uint32
}
Ch1 = {
DataSource = FastStreamer
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
Ch2 = {
DataSource = FastStreamer
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
// ── 3 kHz sine burst channel 3 (FullArray anchor) ─────────────────
+SineGAM5 = {
Class = SineArrayGAM
Frequency = 3000.0
Amplitude = 2.0
Phase = 0.0
Offset = 0.0
SamplingRate = 5000000.0
OutputSignals = {
Ch3 = {
DataSource = DDB3
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
// ── 500 Hz sine burst channel 4 (FullArray anchor) ─────────────────
+SineGAM6 = {
Class = SineArrayGAM
Frequency = 500.0
Amplitude = 3.0
Phase = 0.7854
Offset = 0.0
SamplingRate = 5000000.0
OutputSignals = {
Ch4 = {
DataSource = DDB3
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
// ── Build per-sample time array for FullArray channels ────────────────
// TimeArrayGAM expands the scalar LinuxTimer Time (uint32, µs) into a
// uint64[1000] array in nanoseconds where element[k] = Time_ns + k * period_ns.
// Using ns preserves sub-µs resolution at sampling rates > 1 MHz.
+TimeArrayGAM1 = {
Class = TimeArrayGAM
SamplingRate = 5000000.0
Anchor = FirstSample
InputSignals = {
Time = {
DataSource = DDB3
Type = uint32
}
}
OutputSignals = {
TimeArray = {
DataSource = DDB3
Type = uint64
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
// ── Fast timer for FullArray thread ───────────────────────────────────
+FullArrTimerGAM = {
Class = IOGAM
InputSignals = {
Time = {
Frequency = 5000
DataSource = FullArrTimer
Type = uint32
}
}
OutputSignals = {
Time = {
DataSource = DDB3
Type = uint32
}
}
}
// ── Route FullArray channels → FullArrStreamer ─────────────────────
+FullArrStreamerGAM = {
Class = IOGAM
InputSignals = {
TimeArray = {
DataSource = DDB3
Type = uint64
NumberOfDimensions = 1
NumberOfElements = 1000
}
Ch3 = {
DataSource = DDB3
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
Ch4 = {
DataSource = DDB3
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
OutputSignals = {
TimeArray = {
DataSource = FullArrStreamer
Type = uint64
NumberOfDimensions = 1
NumberOfElements = 1000
}
Ch3 = {
DataSource = FullArrStreamer
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
Ch4 = {
DataSource = FullArrStreamer
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
}
+Data = {
Class = ReferenceContainer
DefaultDataSource = DDB
+DDB = {
Class = GAMDataSource
}
+DDB2 = {
Class = GAMDataSource
}
+DDB3 = {
Class = GAMDataSource
}
// ── 1 kHz real-time clock (Thread1) ──────────────────────────────────
+Timer = {
Class = LinuxTimer
SleepNature = "Default"
Signals = {
Counter = {
Type = uint32
}
Time = {
Type = uint32
}
}
}
// ── 5 kHz fast timer (Thread2 FirstSample / LastSample) ────────────
+FastTimer = {
Class = LinuxTimer
SleepNature = "Default"
Signals = {
Counter = {
Type = uint32
}
Time = {
Type = uint32
}
}
}
// ── 5 kHz fast timer (Thread3 FullArray) ───────────────────────────
+FullArrTimer = {
Class = LinuxTimer
SleepNature = "Default"
Signals = {
Counter = {
Type = uint32
}
Time = {
Type = uint32
}
}
}
// ── Streamer: scalar signals, PacketTime (port 44500) ─────────────────
// Multicast mode: clients connect via TCP on port 44500 to receive the
// CONFIG packet, then join 239.0.0.1:44503 to receive DATA datagrams.
// Auto publishing ensures data is sent every RT cycle (1 kHz = 1 ms
// temporal resolution) but never faster, so the rate is bounded.
+Streamer = {
Class = UDPStreamer
Port = 44500
MulticastGroup = "239.0.0.1"
DataPort = 44503
MaxPayloadSize = 1400
PublishingMode = "Accumulate"
MinRefreshRate = 100
Signals = {
Counter = {
Type = uint32
}
Time = {
Type = uint32
Unit = "us"
}
Sine1 = {
Type = float32
Unit = "V"
RangeMin = -10.0
RangeMax = 10.0
QuantizedType = "uint16"
}
Sine2 = {
Type = float32
Unit = "V"
RangeMin = -5.0
RangeMax = 5.0
}
}
}
// ── FastStreamer: packed arrays, FirstSample + LastSample (port 44501)
//
// Ch1 uses TimeMode = FirstSample:
// Time is the timestamp of sample [0]; later samples are extrapolated
// forward: t[k] = Time + k / SamplingRate.
//
// Ch2 uses TimeMode = LastSample:
// Time is the timestamp of sample [N-1]; earlier samples are
// extrapolated backward: t[k] = Time - (N-1-k) / SamplingRate.
//
// Both modes produce identical wall-clock placements for a fixed-rate
// signal and are shown here side-by-side for comparison.
+FastStreamer = {
Class = UDPStreamer
Port = 44501
MaxPayloadSize = 1400
Signals = {
Time = {
Type = uint32
Unit = "us"
}
Ch1 = {
Type = float32
Unit = "V"
NumberOfDimensions = 1
NumberOfElements = 1000
TimeMode = FirstSample
TimeSignal = Time
SamplingRate = 5000000.0
}
Ch2 = {
Type = float32
Unit = "V"
NumberOfDimensions = 1
NumberOfElements = 1000
TimeMode = LastSample
TimeSignal = Time
SamplingRate = 5000000.0
}
}
}
// ── FullArrStreamer: packed arrays, FullArray (port 44502) ─────────────
//
// TimeMode = FullArray: the TimeSignal (TimeArray) has the same
// NumberOfElements as the data channel. Each sample pair
// (TimeArray[k], Ch3[k]) provides its own independent timestamp.
// This mode handles non-uniform sampling and explicit per-sample clocks.
+FullArrStreamer = {
Class = UDPStreamer
Port = 44502
MaxPayloadSize = 1400
Signals = {
TimeArray = {
Type = uint64
Unit = "ns"
NumberOfDimensions = 1
NumberOfElements = 1000
}
Ch3 = {
Type = float32
Unit = "V"
NumberOfDimensions = 1
NumberOfElements = 1000
TimeMode = FullArray
TimeSignal = TimeArray
}
Ch4 = {
Type = float32
Unit = "V"
NumberOfDimensions = 1
NumberOfElements = 1000
TimeMode = FullArray
TimeSignal = TimeArray
}
}
}
+Timings = {
Class = TimingDataSource
}
}
+States = {
Class = ReferenceContainer
+Running = {
Class = RealTimeState
+Threads = {
Class = ReferenceContainer
// Thread1: scalar signals at 1 kHz
+Thread1 = {
Class = RealTimeThread
CPUs = 0x1
Functions = {TimerGAM SineGAM1 SineGAM2 StreamerGAM}
}
// Thread2: packed arrays at 5 kHz (FirstSample + LastSample)
+Thread2 = {
Class = RealTimeThread
CPUs = 0x2
Functions = {FastTimerGAM SineGAM3 SineGAM4 FastStreamerGAM}
}
// Thread3: packed arrays at 5 kHz (FullArray with explicit timestamps)
+Thread3 = {
Class = RealTimeThread
CPUs = 0x4
Functions = {FullArrTimerGAM SineGAM5 SineGAM6 TimeArrayGAM1 FullArrStreamerGAM}
}
}
}
}
+Scheduler = {
Class = GAMScheduler
TimingDataSource = Timings
}
}
+384
View File
@@ -0,0 +1,384 @@
/**
* Combined integration test configuration.
*
* Exercises all components in the repo simultaneously:
* - SineArrayGAM — array sine wave generation
* - TimeArrayGAM — per-sample timestamp arrays
* - UDPStreamer — UDPS wire protocol (ports 44500, 44501, 44502)
* - DebugService — live signal tracing / forcing / breakpoints (ports 8080-8082)
* TcpLogger is auto-injected by DebugService on port 8082 (log port).
*
* Three real-time threads:
*
* Thread1 1 kHz — scalar signals → UDPStreamer port 44500 (Accumulate/multicast)
* Counter, Time, Sine1 (1 Hz), Sine2 (0.3 Hz)
*
* Thread2 5 kHz — packed arrays → UDPStreamer port 44501
* Ch1 float32[1000] @ 1 kHz (TimeMode = FirstSample)
* Ch2 float32[1000] @ 10 kHz (TimeMode = LastSample)
*
* Thread3 5 kHz — FullArray + explicit timestamps → UDPStreamer port 44502
* Ch3 float32[1000] @ 3 kHz (TimeMode = FullArray)
* Ch4 float32[1000] @ 500 Hz (TimeMode = FullArray)
*/
$App = {
Class = RealTimeApplication
+Functions = {
Class = ReferenceContainer
// ── Thread1: 1 kHz scalar signals ────────────────────────────────────
+TimerGAM = {
Class = IOGAM
InputSignals = {
Counter = {
DataSource = Timer
Type = uint32
Frequency = 1000
}
Time = {
DataSource = Timer
Type = uint32
}
}
OutputSignals = {
Counter = { DataSource = DDB1 Type = uint32 }
Time = { DataSource = DDB1 Type = uint32 }
}
}
+SineGAM1 = {
Class = SineArrayGAM
Frequency = 1.0
Amplitude = 5.0
Phase = 0.0
Offset = 0.0
SamplingRate = 1000.0
OutputSignals = {
Sine1 = { DataSource = DDB1 Type = float32 }
}
}
+SineGAM2 = {
Class = SineArrayGAM
Frequency = 0.3
Amplitude = 3.0
Phase = 1.0472
Offset = 0.0
SamplingRate = 1000.0
OutputSignals = {
Sine2 = { DataSource = DDB1 Type = float32 }
}
}
+StreamerGAM1 = {
Class = IOGAM
InputSignals = {
Counter = { DataSource = DDB1 Type = uint32 }
Time = { DataSource = DDB1 Type = uint32 }
Sine1 = { DataSource = DDB1 Type = float32 }
Sine2 = { DataSource = DDB1 Type = float32 }
}
OutputSignals = {
Counter = { DataSource = Streamer1 Type = uint32 }
Time = { DataSource = Streamer1 Type = uint32 }
Sine1 = { DataSource = Streamer1 Type = float32 }
Sine2 = { DataSource = Streamer1 Type = float32 }
}
}
// ── Thread2: 5 kHz packed arrays (FirstSample / LastSample) ──────────
+FastTimerGAM = {
Class = IOGAM
InputSignals = {
Time = {
DataSource = FastTimer
Type = uint32
Frequency = 5000
}
}
OutputSignals = {
Time = { DataSource = DDB2 Type = uint32 }
}
}
+SineGAM3 = {
Class = SineArrayGAM
Frequency = 1000.0
Amplitude = 1.0
Phase = 0.0
Offset = 0.0
SamplingRate = 5000000.0
OutputSignals = {
Ch1 = {
DataSource = DDB2
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
+SineGAM4 = {
Class = SineArrayGAM
Frequency = 10000.0
Amplitude = 0.5
Phase = 1.5708
Offset = 0.0
SamplingRate = 5000000.0
OutputSignals = {
Ch2 = {
DataSource = DDB2
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
+StreamerGAM2 = {
Class = IOGAM
InputSignals = {
Time = { DataSource = DDB2 Type = uint32 }
Ch1 = { DataSource = DDB2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
Ch2 = { DataSource = DDB2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
}
OutputSignals = {
Time = { DataSource = Streamer2 Type = uint32 }
Ch1 = { DataSource = Streamer2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
Ch2 = { DataSource = Streamer2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
}
}
// ── Thread3: 5 kHz FullArray with per-sample timestamps ──────────────
+FullArrTimerGAM = {
Class = IOGAM
InputSignals = {
Time = {
DataSource = FullArrTimer
Type = uint32
Frequency = 5000
}
}
OutputSignals = {
Time = { DataSource = DDB3 Type = uint32 }
}
}
+SineGAM5 = {
Class = SineArrayGAM
Frequency = 3000.0
Amplitude = 2.0
Phase = 0.0
Offset = 0.0
SamplingRate = 5000000.0
OutputSignals = {
Ch3 = {
DataSource = DDB3
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
+SineGAM6 = {
Class = SineArrayGAM
Frequency = 500.0
Amplitude = 3.0
Phase = 0.7854
Offset = 0.0
SamplingRate = 5000000.0
OutputSignals = {
Ch4 = {
DataSource = DDB3
Type = float32
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
+TimeArrayGAM1 = {
Class = TimeArrayGAM
SamplingRate = 5000000.0
Anchor = FirstSample
InputSignals = {
Time = { DataSource = DDB3 Type = uint32 }
}
OutputSignals = {
TimeArray = {
DataSource = DDB3
Type = uint64
NumberOfDimensions = 1
NumberOfElements = 1000
}
}
}
+StreamerGAM3 = {
Class = IOGAM
InputSignals = {
TimeArray = { DataSource = DDB3 Type = uint64 NumberOfDimensions = 1 NumberOfElements = 1000 }
Ch3 = { DataSource = DDB3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
Ch4 = { DataSource = DDB3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
}
OutputSignals = {
TimeArray = { DataSource = Streamer3 Type = uint64 NumberOfDimensions = 1 NumberOfElements = 1000 }
Ch3 = { DataSource = Streamer3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
Ch4 = { DataSource = Streamer3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 }
}
}
}
+Data = {
Class = ReferenceContainer
DefaultDataSource = DDB1
+DDB1 = { Class = GAMDataSource }
+DDB2 = { Class = GAMDataSource }
+DDB3 = { Class = GAMDataSource }
// ── Timers (one per thread) ───────────────────────────────────────────
+Timer = {
Class = LinuxTimer
SleepNature = "Default"
Signals = {
Counter = { Type = uint32 }
Time = { Type = uint32 }
}
}
+FastTimer = {
Class = LinuxTimer
SleepNature = "Default"
Signals = {
Counter = { Type = uint32 }
Time = { Type = uint32 }
}
}
+FullArrTimer = {
Class = LinuxTimer
SleepNature = "Default"
Signals = {
Counter = { Type = uint32 }
Time = { Type = uint32 }
}
}
// ── UDPStreamer instances ─────────────────────────────────────────────
// Thread1: scalar signals, Accumulate mode, multicast output
+Streamer1 = {
Class = UDPStreamer
Port = 44500
MulticastGroup = "239.0.0.1"
DataPort = 44503
MaxPayloadSize = 1400
PublishingMode = "Accumulate"
MinRefreshRate = 100
Signals = {
Counter = { Type = uint32 }
Time = { Type = uint32 Unit = "us" }
Sine1 = { Type = float32 Unit = "V" RangeMin = -5.0 RangeMax = 5.0 }
Sine2 = { Type = float32 Unit = "V" RangeMin = -3.0 RangeMax = 3.0 }
}
}
// Thread2: packed arrays, FirstSample + LastSample
+Streamer2 = {
Class = UDPStreamer
Port = 44501
MaxPayloadSize = 1400
Signals = {
Time = { Type = uint32 Unit = "us" }
Ch1 = {
Type = float32 Unit = "V"
NumberOfDimensions = 1 NumberOfElements = 1000
TimeMode = FirstSample TimeSignal = Time SamplingRate = 5000000.0
}
Ch2 = {
Type = float32 Unit = "V"
NumberOfDimensions = 1 NumberOfElements = 1000
TimeMode = LastSample TimeSignal = Time SamplingRate = 5000000.0
}
}
}
// Thread3: packed arrays, FullArray (per-sample timestamps)
+Streamer3 = {
Class = UDPStreamer
Port = 44502
MaxPayloadSize = 1400
Signals = {
TimeArray = {
Type = uint64 Unit = "ns"
NumberOfDimensions = 1 NumberOfElements = 1000
}
Ch3 = {
Type = float32 Unit = "V"
NumberOfDimensions = 1 NumberOfElements = 1000
TimeMode = FullArray TimeSignal = TimeArray
}
Ch4 = {
Type = float32 Unit = "V"
NumberOfDimensions = 1 NumberOfElements = 1000
TimeMode = FullArray TimeSignal = TimeArray
}
}
}
+Timings = { Class = TimingDataSource }
}
+States = {
Class = ReferenceContainer
+Running = {
Class = RealTimeState
+Threads = {
Class = ReferenceContainer
+Thread1 = {
Class = RealTimeThread
CPUs = 0x1
Functions = {TimerGAM SineGAM1 SineGAM2 StreamerGAM1}
}
+Thread2 = {
Class = RealTimeThread
CPUs = 0x2
Functions = {FastTimerGAM SineGAM3 SineGAM4 StreamerGAM2}
}
+Thread3 = {
Class = RealTimeThread
CPUs = 0x4
Functions = {FullArrTimerGAM SineGAM5 SineGAM6 TimeArrayGAM1 StreamerGAM3}
}
}
}
}
+Scheduler = {
Class = GAMScheduler
TimingDataSource = Timings
}
}
// ── DebugService ──────────────────────────────────────────────────────────────
// Patches the broker registry at startup so every signal is traceable.
// TcpLogger is auto-injected on LogPort (9090) — no explicit DataSource needed.
// Connect the debugger web UI (./run_combined_test.sh -d) to:
// Host=127.0.0.1 TCP=8080 UDP=8081 Log=9090
+DebugService = {
Class = DebugService
ControlPort = 8080
StreamPort = 8081
LogPort = 9090
StreamIP = "127.0.0.1"
}
+189
View File
@@ -0,0 +1,189 @@
+App = {
Class = RealTimeApplication
+Functions = {
Class = ReferenceContainer
+GAM1 = {
Class = IOGAM
InputSignals = {
Counter = {
DataSource = Timer
Type = uint32
Frequency = 1000
}
Time = {
DataSource = Timer
Type = uint32
}
}
OutputSignals = {
Counter = {
DataSource = SyncDB
Type = uint32
}
Time = {
DataSource = DDB
Type = uint32
}
}
}
+CGAM = {
Class = ConstantGAM
OutputSignals = {
Test = {
DataSource = DDB2
Type = float32
Default = 0.123
}
}
}
+GAM2 = {
Class = IOGAM
InputSignals = {
Counter = {
DataSource = TimerSlow
Frequency = 1
}
Time = {
DataSource = TimerSlow
}
Test = {
DataSource = DDB2
Type = float32
}
}
OutputSignals = {
Counter = {
Type = uint32
DataSource = Logger
}
Time = {
Type = uint32
DataSource = Logger
}
ConstOut = {
DataSource = Logger
Type = float32
}
}
}
+GAM3 = {
Class = IOGAM
InputSignals = {
Counter = {
Frequency = 1
Samples = 100
Type = uint32
DataSource = SyncDB
}
}
OutputSignals = {
Counter = {
DataSource = DDB3
NumberOfElements = 100
Type = uint32
}
}
}
}
+Data = {
Class = ReferenceContainer
DefaultDataSource = DDB
+SyncDB = {
Class = RealTimeThreadSynchronisation
Timeout = 200
Signals = {
Counter = {
Type = uint32
}
}
}
+Timer = {
Class = LinuxTimer
Signals = {
Counter = {
Type = uint32
}
Time = {
Type = uint32
}
}
}
+TimerSlow = {
Class = LinuxTimer
Signals = {
Counter = {
Type = uint32
}
Time = {
Type = uint32
}
}
}
+Logger = {
Class = LoggerDataSource
Signals = {
CounterCopy = {
Type = uint32
}
TimeCopy = {
Type = uint32
}
}
}
+DDB = {
AllowNoProducer = 1
Class = GAMDataSource
Signals = {
Counter= {
Type = uint32
}
}
}
+DDB2 = {
AllowNoProducer = 1
Class = GAMDataSource
}
+DDB3 = {
AllowNoProducer = 1
Class = GAMDataSource
}
+DAMS = {
Class = TimingDataSource
}
}
+States = {
Class = ReferenceContainer
+State1 = {
Class = RealTimeState
+Threads = {
Class = ReferenceContainer
+Thread1 = {
Class = RealTimeThread
Functions = {GAM1}
}
+Thread2 = {
Class = RealTimeThread
Functions = {GAM2 CGAM}
}
+Thread3 = {
Class = RealTimeThread
Functions = {GAM3}
}
}
}
}
+Scheduler = {
Class = GAMScheduler
TimingDataSource = DAMS
}
}
+DebugService = {
Class = DebugService
ControlPort = 8080
UdpPort = 8081
LogPort = 8082
StreamIP = "127.0.0.1"
}
+186
View File
@@ -0,0 +1,186 @@
+App = {
Class = RealTimeApplication
+Functions = {
Class = ReferenceContainer
+GAM1 = {
Class = IOGAM
InputSignals = {
Counter = {
DataSource = Timer
Type = uint32
Frequency = 1000
}
Time = {
DataSource = Timer
Type = uint32
}
}
OutputSignals = {
Counter = {
DataSource = SyncDB
Type = uint32
}
Time = {
DataSource = DDB
Type = uint32
}
}
}
+CGAM = {
Class = ConstantGAM
OutputSignals = {
Test = {
DataSource = DDB2
Type = float32
Default = 0.123
}
}
}
+GAM2 = {
Class = IOGAM
InputSignals = {
Counter = {
DataSource = TimerSlow
Frequency = 1
}
Time = {
DataSource = TimerSlow
}
Test = {
DataSource = DDB2
Type = float32
}
}
OutputSignals = {
Counter = {
Type = uint32
DataSource = Logger
}
Time = {
Type = uint32
DataSource = Logger
}
ConstOut = {
DataSource = Logger
Type = float32
}
}
}
+GAM3 = {
Class = IOGAM
InputSignals = {
Counter = {
Frequency = 1
Samples = 100
Type = uint32
DataSource = SyncDB
}
}
OutputSignals = {
Counter = {
DataSource = DDB3
NumberOfElements = 100
Type = uint32
}
}
}
}
+Data = {
Class = ReferenceContainer
DefaultDataSource = DDB
+SyncDB = {
Class = RealTimeThreadSynchronisation
Timeout = 200
Signals = {
Counter = {
Type = uint32
}
}
}
+Timer = {
Class = LinuxTimer
Signals = {
Counter = {
Type = uint32
}
Time = {
Type = uint32
}
}
}
+TimerSlow = {
Class = LinuxTimer
Signals = {
Counter = {
Type = uint32
}
Time = {
Type = uint32
}
}
}
+Logger = {
Class = LoggerDataSource
Signals = {
CounterCopy = {
Type = uint32
}
TimeCopy = {
Type = uint32
}
}
}
+DDB = {
AllowNoProducer = 1
Class = GAMDataSource
Signals = {
Counter= {
Type = uint32
}
}
}
+DDB2 = {
AllowNoProducer = 1
Class = GAMDataSource
}
+DDB3 = {
AllowNoProducer = 1
Class = GAMDataSource
}
+DAMS = {
Class = TimingDataSource
}
}
+States = {
Class = ReferenceContainer
+State1 = {
Class = RealTimeState
+Threads = {
Class = ReferenceContainer
+Thread1 = {
Class = RealTimeThread
Functions = {GAM1}
}
+Thread2 = {
Class = RealTimeThread
Functions = {GAM2 CGAM}
}
+Thread3 = {
Class = RealTimeThread
Functions = {GAM3}
}
}
}
}
+Scheduler = {
Class = GAMScheduler
TimingDataSource = DAMS
}
}
+DebugService = {
Class = WebDebugService
HttpPort = 8090
}
+29
View File
@@ -0,0 +1,29 @@
/*
* Main_TestAll.cpp
*
* Created on: 31/10/2016
* Author: Andre Neto
*/
#include "ErrorManagement.h"
#include "Object.h"
#include "StreamString.h"
#include "gtest/gtest.h"
#include <limits.h>
void MainGTestComponentsErrorProcessFunction(const MARTe::ErrorManagement::ErrorInformation& errorInfo,
const char* const errorDescription)
{
MARTe::StreamString errorCodeStr;
MARTe::ErrorManagement::ErrorCodeToStream(errorInfo.header.errorType, errorCodeStr);
printf("[%s - %s:%d]: %s\n", errorCodeStr.Buffer(), errorInfo.fileName, errorInfo.header.lineNumber, errorDescription);
}
int main(int argc, char** argv)
{
SetErrorProcessFunction(&MainGTestComponentsErrorProcessFunction);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
+34
View File
@@ -0,0 +1,34 @@
#############################################################
#
# Copyright 2015 F4E | European Joint Undertaking for ITER
# and the Development of Fusion Energy ('Fusion for Energy')
#
# Licensed under the EUPL, Version 1.1 or - as soon they
# will be approved by the European Commission - subsequent
# versions of the EUPL (the "Licence");
# You may not use this work except in compliance with the
# Licence.
# You may obtain a copy of the Licence at:
#
# http://ec.europa.eu/idabc/eupl
#
# Unless required by applicable law or agreed to in
# writing, software distributed under the Licence is
# distributed on an "AS IS" basis,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied.
# See the Licence for the specific language governing
# permissions and limitations under the Licence.
#
#############################################################
include Makefile.inc
LIBRARIES += $(MARTe2_DIR)/Lib/gtest-1.7.0/libgtest.a -lpthread
LIBRARIES += -L$(MARTe2_DIR)/Build/$(TARGET)/Core -lMARTe2
LIBRARIES += -ldl
#Look for all the statically linked files
LIBRARIES_STATIC+=$(shell find $(ROOT_DIR)/Build/$(TARGET) -name "*.a")
+55
View File
@@ -0,0 +1,55 @@
#############################################################
#
# Copyright 2015 F4E | European Joint Undertaking for ITER
# and the Development of Fusion Energy ('Fusion for Energy')
#
# Licensed under the EUPL, Version 1.1 or - as soon they
# will be approved by the European Commission - subsequent
# versions of the EUPL (the "Licence");
# You may not use this work except in compliance with the
# Licence.
# You may obtain a copy of the Licence at:
#
# http://ec.europa.eu/idabc/eupl
#
# Unless required by applicable law or agreed to in
# writing, software distributed under the Licence is
# distributed on an "AS IS" basis,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied.
# See the Licence for the specific language governing
# permissions and limitations under the Licence.
#
#############################################################
PACKAGE=
ROOT_DIR=../..
MAKEDEFAULTDIR=$(MARTe2_DIR)/MakeDefaults
include $(MAKEDEFAULTDIR)/MakeStdLibDefs.$(TARGET)
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L0Types
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L2Objects
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L3Streams
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Messages
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Configuration
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L5GAMs
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L5GAMs
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
INCLUDES += -I$(MARTe2_DIR)/Lib/gtest-1.7.0/include
INCLUDES += -I$(ROOT_DIR)/Common/UDP
INCLUDES += -I$(ROOT_DIR)/Source/Components/DataSources/UDPStreamer
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/DebugService
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/TCPLogger
INCLUDES += -I$(ROOT_DIR)/Test/Components/DataSources/UDPStreamer
all: $(BUILD_DIR)/MainGTest$(EXEEXT)
include depends.$(TARGET)
include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)
+101
View File
@@ -0,0 +1,101 @@
../../Build/x86-linux//GTest/MainGTest.o: MainGTest.cpp \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Introspection.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/IntrospectionEntry.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TypeDescriptor.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/IteratorT.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Iterator.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SortFilter.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SearchFilter.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/LoadableLibrary.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilder.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticList.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItemT.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilderT.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-internal.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-port.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-message.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-string.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-filepath.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-death-test.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-param-test.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-printers.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_prod.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-test-part.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-typed-test.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_pred_impl.h
+101
View File
@@ -0,0 +1,101 @@
MainGTest.o: MainGTest.cpp \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Introspection.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/IntrospectionEntry.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TypeDescriptor.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/IteratorT.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Iterator.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SortFilter.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SearchFilter.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/LoadableLibrary.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilder.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticList.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItemT.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilderT.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-internal.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-port.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-message.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-string.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-filepath.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-death-test.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-param-test.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-printers.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_prod.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-test-part.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-typed-test.h \
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_pred_impl.h
+161
View File
@@ -0,0 +1,161 @@
#include "BasicTCPSocket.h"
#include "DebugService.h"
#include "ObjectRegistryDatabase.h"
#include "StandardParser.h"
#include "StreamString.h"
#include "GlobalObjectsDatabase.h"
#include "RealTimeApplication.h"
#include <assert.h>
#include <stdio.h>
using namespace MARTe;
const char8 * const config_command_text =
"DebugService = {"
" Class = DebugService "
" ControlPort = 8100 "
" UdpPort = 8101 "
" StreamIP = \"127.0.0.1\" "
" MyCustomField = \"HelloConfig\" "
"}"
"App = {"
" Class = RealTimeApplication "
" +Functions = {"
" Class = ReferenceContainer "
" +GAM1 = {"
" Class = IOGAM "
" CustomGAMField = \"GAMValue\" "
" InputSignals = {"
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 PVName = \"PROC:VAR:1\" }"
" Time = { DataSource = Timer Type = uint32 }"
" }"
" OutputSignals = {"
" Counter = { DataSource = DDB Type = uint32 }"
" Time = { DataSource = DDB Type = uint32 }"
" }"
" }"
" }"
" +Data = {"
" Class = ReferenceContainer "
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
" +DAMS = { Class = TimingDataSource }"
" }"
" +States = {"
" Class = ReferenceContainer "
" +State1 = { Class = RealTimeState +Threads = { Class = ReferenceContainer +Thread1 = { Class = RealTimeThread Functions = {GAM1} } } }"
" }"
" +Scheduler = { Class = GAMScheduler TimingDataSource = DAMS }"
"}";
static bool SendCommandAndGetReply(uint16 port, const char8* cmd, StreamString &reply) {
BasicTCPSocket client;
if (!client.Open()) return false;
if (!client.Connect("127.0.0.1", port)) return false;
uint32 s = StringHelper::Length(cmd);
if (!client.Write(cmd, s)) return false;
char buffer[4096];
uint32 size = 4096;
TimeoutType timeout(2000000); // 2s
if (client.Read(buffer, size, timeout)) {
reply.Write(buffer, size);
client.Close();
return true;
}
client.Close();
return false;
}
void TestConfigCommands() {
printf("--- MARTe2 Config & Metadata Enrichment Test ---\n");
ObjectRegistryDatabase::Instance()->Purge();
ConfigurationDatabase cdb;
StreamString ss = config_command_text;
ss.Seek(0);
StandardParser parser(ss, cdb);
assert(parser.Parse());
cdb.MoveToRoot();
uint32 n = cdb.GetNumberOfChildren();
for (uint32 i=0; i<n; i++) {
const char8* name = cdb.GetChildName(i);
ConfigurationDatabase child;
cdb.MoveRelative(name);
cdb.Copy(child);
cdb.MoveToAncestor(1u);
StreamString className;
child.Read("Class", className);
Reference ref(className.Buffer(), GlobalObjectsDatabase::Instance()->GetStandardHeap());
ref->SetName(name);
assert(ref->Initialise(child));
ObjectRegistryDatabase::Instance()->Insert(ref);
}
printf("Application and DebugService (port 8100) initialised.\n");
// Start the application to trigger broker execution and signal registration
ReferenceT<RealTimeApplication> app = ObjectRegistryDatabase::Instance()->Find("App");
assert(app.IsValid());
assert(app->ConfigureApplication());
assert(app->PrepareNextState("State1") == ErrorManagement::NoError);
assert(app->StartNextStateExecution() == ErrorManagement::NoError);
printf("Application started (for signal registration).\n");
Sleep::MSec(500); // Wait for some cycles
ReferenceT<DebugService> service = ObjectRegistryDatabase::Instance()->Find("DebugService");
if (service.IsValid()) {
service->SetFullConfig(cdb);
}
Sleep::MSec(1000);
// 1. Test CONFIG command
{
printf("Testing CONFIG command...\n");
StreamString reply;
assert(SendCommandAndGetReply(8100, "CONFIG\n", reply));
printf("\n%s\n", reply.Buffer());
// Verify it contains some key parts of the config
assert(StringHelper::SearchString(reply.Buffer(), "MyCustomField") != NULL_PTR(const char8*));
assert(StringHelper::SearchString(reply.Buffer(), "HelloConfig") != NULL_PTR(const char8*));
assert(StringHelper::SearchString(reply.Buffer(), "PROC:VAR:1") != NULL_PTR(const char8*));
assert(StringHelper::SearchString(reply.Buffer(), "OK CONFIG") != NULL_PTR(const char8*));
printf("SUCCESS: CONFIG command validated.\n");
}
// 2. Test INFO on object with enrichment
{
printf("Testing INFO on App.Functions.GAM1...\n");
StreamString reply;
assert(SendCommandAndGetReply(8100, "INFO App.Functions.GAM1\n", reply));
// Check standard MARTe fields (Name, Class)
assert(StringHelper::SearchString(reply.Buffer(), "\"Name\": \"GAM1\"") != NULL_PTR(const char8*));
// Check enriched fields from fullConfig
assert(StringHelper::SearchString(reply.Buffer(), "\"CustomGAMField\": \"GAMValue\"") != NULL_PTR(const char8*));
assert(StringHelper::SearchString(reply.Buffer(), "OK INFO") != NULL_PTR(const char8*));
printf("SUCCESS: Object metadata enrichment validated.\n");
}
// 3. Test INFO on signal with enrichment
{
printf("Testing INFO on App.Functions.GAM1.In.Counter...\n");
StreamString reply;
assert(SendCommandAndGetReply(8100, "INFO App.Functions.GAM1.In.Counter\n", reply));
// Check enriched fields from signal configuration
assert(StringHelper::SearchString(reply.Buffer(), "\"Frequency\": \"1000\"") != NULL_PTR(const char8*));
assert(StringHelper::SearchString(reply.Buffer(), "\"PVName\": \"PROC:VAR:1\"") != NULL_PTR(const char8*));
assert(StringHelper::SearchString(reply.Buffer(), "OK INFO") != NULL_PTR(const char8*));
printf("SUCCESS: Signal metadata enrichment validated.\n");
}
if (app.IsValid()) {
app->StopCurrentStateExecution();
}
ObjectRegistryDatabase::Instance()->Purge();
}
+252
View File
@@ -0,0 +1,252 @@
#include "ClassRegistryDatabase.h"
#include "ConfigurationDatabase.h"
#include "DebugService.h"
#include "ObjectRegistryDatabase.h"
#include "ErrorManagement.h"
#include "BasicTCPSocket.h"
#include "BasicUDPSocket.h"
#include "RealTimeApplication.h"
#include "StandardParser.h"
#include "TestCommon.h"
#include <stdio.h>
using namespace MARTe;
#include <signal.h>
#include <unistd.h>
void timeout_handler(int sig) {
printf("Test timed out!\n");
_exit(1);
}
void ErrorProcessFunction(const MARTe::ErrorManagement::ErrorInformation &errorInfo, const char8 * const errorDescription) {
printf("[MARTe Error] %s: %s\n", errorInfo.className, errorDescription);
}
// Forward declarations of other tests
void TestSchedulerControl();
void TestFullTracePipeline();
void RunValidationTest();
void TestConfigCommands();
void TestGAMSignalTracing();
void TestTreeCommand();
int main() {
signal(SIGALRM, timeout_handler);
alarm(180);
MARTe::ErrorManagement::SetErrorProcessFunction(&ErrorProcessFunction);
printf("MARTe2 Debug Suite Integration Tests\n");
printf("\n--- Test 1: Registry Patching ---\n");
{
ObjectRegistryDatabase::Instance()->Purge();
DebugService service;
ConfigurationDatabase serviceData;
serviceData.Write("ControlPort", (uint32)9090);
service.Initialise(serviceData);
printf("DebugService initialized and Registry Patched.\n");
ClassRegistryItem *item =
ClassRegistryDatabase::Instance()->Find("MemoryMapInputBroker");
if (item != NULL_PTR(ClassRegistryItem *)) {
Object *obj = item->GetObjectBuilder()->Build(
GlobalObjectsDatabase::Instance()->GetStandardHeap());
if (obj != NULL_PTR(Object *)) {
printf("Instantiated Broker Class: %s\n",
obj->GetClassProperties()->GetName());
printf("Success: Broker patched and instantiated.\n");
} else {
printf("Failed to build broker\n");
}
} else {
printf("MemoryMapInputBroker not found in registry\n");
}
}
Sleep::MSec(1000);
printf("\n--- Test 2: Full Trace Pipeline ---\n");
TestFullTracePipeline();
Sleep::MSec(1000);
printf("\n--- Test 3: Scheduler Control ---\n");
TestSchedulerControl();
Sleep::MSec(1000);
printf("\n--- Test 4: 1kHz Lossless Trace Validation ---\n");
RunValidationTest();
Sleep::MSec(1000);
printf("\n--- Test 5: Config & Metadata Enrichment ---\n");
TestConfigCommands();
Sleep::MSec(1000);
printf("\n--- Test 6: TREE Command Enhancement ---\n");
TestTreeCommand();
Sleep::MSec(1000);
printf("\n--- Test 7: Custom MARTe Message (MSG) ---\n");
TestMessageCommand();
Sleep::MSec(1000);
printf("\nAll Integration Tests Finished.\n");
return 0;
}
// --- Test Implementation ---
void TestGAMSignalTracing() {
printf("--- Test: GAM Signal Tracing Issue ---\n");
ObjectRegistryDatabase::Instance()->Purge();
ConfigurationDatabase cdb;
StreamString ss = debug_test_config;
ss.Seek(0);
StandardParser parser(ss, cdb);
if (!parser.Parse()) {
printf("ERROR: Failed to parse config\n");
return;
}
cdb.MoveToRoot();
uint32 n = cdb.GetNumberOfChildren();
for (uint32 i=0; i<n; i++) {
const char8* name = cdb.GetChildName(i);
ConfigurationDatabase child;
cdb.MoveRelative(name);
cdb.Copy(child);
cdb.MoveToAncestor(1u);
StreamString className;
child.Read("Class", className);
Reference ref(className.Buffer(), GlobalObjectsDatabase::Instance()->GetStandardHeap());
if (!ref.IsValid()) {
printf("ERROR: Could not create object %s of class %s\n", name, className.Buffer());
continue;
}
ref->SetName(name);
if (!ref->Initialise(child)) {
printf("ERROR: Failed to initialise object %s\n", name);
continue;
}
ObjectRegistryDatabase::Instance()->Insert(ref);
}
ReferenceT<DebugService> service = ObjectRegistryDatabase::Instance()->Find("DebugService");
if (!service.IsValid()) {
printf("ERROR: DebugService not found\n");
return;
}
service->SetFullConfig(cdb);
ReferenceT<RealTimeApplication> app = ObjectRegistryDatabase::Instance()->Find("App");
if (!app.IsValid()) {
printf("ERROR: App not found\n");
return;
}
if (!app->ConfigureApplication()) {
printf("ERROR: ConfigureApplication failed.\n");
return;
}
if (app->PrepareNextState("State1") != ErrorManagement::NoError) {
printf("ERROR: PrepareNextState failed.\n");
return;
}
if (app->StartNextStateExecution() != ErrorManagement::NoError) {
printf("ERROR: StartNextStateExecution failed.\n");
return;
}
printf("Application started.\n");
Sleep::MSec(1000);
// Step 1: Discover signals
{
StreamString reply;
if (SendCommandGAM(8095, "DISCOVER\n", reply)) {
printf("DISCOVER response received (len=%llu)\n", reply.Size());
} else {
printf("ERROR: DISCOVER failed\n");
}
}
Sleep::MSec(500);
// Step 2: Trace a DataSource signal (Timer.Counter)
printf("\n--- Step 1: Trace DataSource signal (Timer.Counter) ---\n");
{
StreamString reply;
if (SendCommandGAM(8095, "TRACE App.Data.Timer.Counter 1\n", reply)) {
printf("TRACE response: %s", reply.Buffer());
} else {
printf("ERROR: TRACE failed\n");
}
}
Sleep::MSec(500);
// Step 3: Trace a GAM input signal (GAM1.In.Counter)
printf("\n--- Step 2: Trace GAM input signal (GAM1.In.Counter) ---\n");
{
StreamString reply;
if (SendCommandGAM(8095, "TRACE App.Functions.GAM1.In.Counter 1\n", reply)) {
printf("TRACE response: %s", reply.Buffer());
} else {
printf("ERROR: TRACE failed\n");
}
}
Sleep::MSec(500);
// Step 4: Try to trace another DataSource signal (TimerSlow.Counter)
printf("\n--- Step 3: Try to trace another signal (TimerSlow.Counter) ---\n");
{
StreamString reply;
if (SendCommandGAM(8095, "TRACE App.Data.TimerSlow.Counter 1\n", reply)) {
printf("TRACE response: %s", reply.Buffer());
} else {
printf("ERROR: TRACE failed\n");
}
}
Sleep::MSec(500);
// Step 5: Check if we can still trace more signals
printf("\n--- Step 4: Try to trace Logger.Counter ---\n");
{
StreamString reply;
if (SendCommandGAM(8095, "TRACE App.Data.Logger.Counter 1\n", reply)) {
printf("TRACE response: %s", reply.Buffer());
} else {
printf("ERROR: TRACE failed\n");
}
}
Sleep::MSec(500);
// Verify UDP is still receiving data
BasicUDPSocket listener;
listener.Open();
listener.Listen(8096);
char buffer[1024];
uint32 size = 1024;
TimeoutType timeout(1000);
int packetCount = 0;
while (listener.Read(buffer, size, timeout)) {
packetCount++;
size = 1024;
}
printf("\n--- Results ---\n");
if (packetCount > 0) {
printf("SUCCESS: Received %d UDP packets.\n", packetCount);
} else {
printf("FAILURE: No UDP packets received. Possible deadlock or crash.\n");
}
app->StopCurrentStateExecution();
}
+1
View File
@@ -0,0 +1 @@
include Makefile.inc
+43
View File
@@ -0,0 +1,43 @@
OBJSX = SchedulerTest.x TraceTest.x ValidationTest.x ConfigCommandTest.x TreeCommandTest.x MessageCommandTest.x TestCommon.x
PACKAGE = Test/Integration
ROOT_DIR = ../..
MAKEDEFAULTDIR=$(MARTe2_DIR)/MakeDefaults
include $(MAKEDEFAULTDIR)/MakeStdLibDefs.$(TARGET)
INCLUDES += -I$(ROOT_DIR)/Common/UDP
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/DebugService
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/TCPLogger
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L0Types
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L2Objects
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L3Streams
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Messages
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Logger
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L4Configuration
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L5GAMs
INCLUDES += -I$(MARTe2_DIR)/Source/Core/BareMetal/L6App
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L3Services
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4Messages
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L4LoggerService
INCLUDES += -I$(MARTe2_DIR)/Source/Core/Scheduler/L5GAMs
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L1Portability
INCLUDES += -I$(MARTe2_DIR)/Source/Core/FileSystem/L3Streams
INCLUDES += -I$(MARTe2_Components_DIR)/Source/Components/GAMs/IOGAM
INCLUDES += -I$(MARTe2_Components_DIR)/Source/Components/DataSources/LinuxTimer
LIBRARIES += -L$(MARTe2_DIR)/Build/$(TARGET)/Core -lMARTe2
LIBRARIES += -L$(MARTe2_Components_DIR)/Build/$(TARGET)/Components/DataSources/LinuxTimer -lLinuxTimer
LIBRARIES += -L$(MARTe2_Components_DIR)/Build/$(TARGET)/Components/GAMs/IOGAM -lIOGAM
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/DebugService -lDebugService
LIBRARIES += -L$(ROOT_DIR)/Build/$(TARGET)/Components/Interfaces/TCPLogger -lTcpLogger
all: $(OBJS) $(BUILD_DIR)/IntegrationTests$(EXEEXT)
echo $(OBJS)
include $(MAKEDEFAULTDIR)/MakeStdLibRules.$(TARGET)
+72
View File
@@ -0,0 +1,72 @@
#include "TestCommon.h"
#include "ObjectRegistryDatabase.h"
#include "DebugService.h"
#include "StandardParser.h"
#include "GlobalObjectsDatabase.h"
#include <stdio.h>
using namespace MARTe;
namespace MARTe {
void TestMessageCommand() {
printf("--- Test: Custom MARTe Message (MSG) ---\n");
ObjectRegistryDatabase::Instance()->Purge();
Sleep::MSec(1000);
ConfigurationDatabase cdb;
const char8 * const msg_test_config =
"DebugService = {"
" Class = DebugService "
" ControlPort = 8120 "
" UdpPort = 8121 "
" StreamIP = \"127.0.0.1\" "
"}";
StreamString ss = msg_test_config;
ss.Seek(0);
StandardParser parser(ss, cdb);
if (!parser.Parse()) {
printf("ERROR: Failed to parse config\n");
return;
}
// Initialize Service
ReferenceT<DebugService> service("DebugService", GlobalObjectsDatabase::Instance()->GetStandardHeap());
service->SetName("DebugService");
cdb.MoveToRoot();
if (cdb.MoveRelative("DebugService")) {
if (!service->Initialise(cdb)) {
printf("ERROR: Failed to initialize DebugService\n");
return;
}
}
ObjectRegistryDatabase::Instance()->Insert(service);
if (ObjectRegistryDatabase::Instance()->Find("DebugService").IsValid()) {
printf("DebugService successfully registered in ORD.\n");
} else {
printf("ERROR: DebugService NOT found in ORD.\n");
}
printf("Service initialized on port 8120.\n");
Sleep::MSec(500);
StreamString reply;
if (SendCommandGAM(8120, "MSG DebugService UnknownFunc 0 Key1=Val1\\nKey2=Val2\n", reply)) {
printf("MSG response received: %s", reply.Buffer());
if (StringHelper::SearchString(reply.Buffer(), "OK MSG") != NULL_PTR(const char8 *)) {
printf("SUCCESS: Asynchronous message dispatched correctly.\n");
} else {
printf("FAILURE: MSG command returned error.\n");
}
} else {
printf("ERROR: MSG command communication failed\n");
}
ObjectRegistryDatabase::Instance()->Purge();
}
} // namespace MARTe
+253
View File
@@ -0,0 +1,253 @@
#include "BasicTCPSocket.h"
#include "BasicUDPSocket.h"
#include "DebugService.h"
#include "ObjectRegistryDatabase.h"
#include "RealTimeApplication.h"
#include "StandardParser.h"
#include "StreamString.h"
#include "GlobalObjectsDatabase.h"
#include <assert.h>
#include <stdio.h>
using namespace MARTe;
const char8 * const scheduler_config_text =
"DebugService = {"
" Class = DebugService "
" ControlPort = 8098 "
" UdpPort = 8099 "
" StreamIP = \"127.0.0.1\" "
"}"
"App = {"
" Class = RealTimeApplication "
" +Functions = {"
" Class = ReferenceContainer "
" +GAM1 = {"
" Class = IOGAM "
" InputSignals = {"
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }"
" Time = { DataSource = Timer Type = uint32 }"
" }"
" OutputSignals = {"
" Counter = { DataSource = DDB Type = uint32 }"
" Time = { DataSource = DDB Type = uint32 }"
" }"
" }"
" }"
" +Data = {"
" Class = ReferenceContainer "
" DefaultDataSource = DDB "
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
" +DAMS = { Class = TimingDataSource }"
" }"
" +States = {"
" Class = ReferenceContainer "
" +State1 = { Class = RealTimeState +Threads = { Class = ReferenceContainer +Thread1 = { Class = RealTimeThread Functions = {GAM1} } } }"
" }"
" +Scheduler = { Class = GAMScheduler TimingDataSource = DAMS }"
"}";
void TestSchedulerControl() {
printf("--- MARTe2 Scheduler Control Test ---\n");
ObjectRegistryDatabase::Instance()->Purge();
ConfigurationDatabase cdb;
StreamString ss = scheduler_config_text;
ss.Seek(0);
StandardParser parser(ss, cdb);
if (!parser.Parse()) {
printf("ERROR: Failed to parse configuration\n");
return;
}
cdb.MoveToRoot();
uint32 n = cdb.GetNumberOfChildren();
for (uint32 i=0; i<n; i++) {
const char8* name = cdb.GetChildName(i);
ConfigurationDatabase child;
cdb.MoveRelative(name);
cdb.Copy(child);
cdb.MoveToAncestor(1u);
StreamString className;
child.Read("Class", className);
Reference ref(className.Buffer(), GlobalObjectsDatabase::Instance()->GetStandardHeap());
if (!ref.IsValid()) {
printf("ERROR: Could not create object %s of class %s\n", name, className.Buffer());
continue;
}
ref->SetName(name);
if (!ref->Initialise(child)) {
printf("ERROR: Failed to initialise object %s\n", name);
continue;
}
ObjectRegistryDatabase::Instance()->Insert(ref);
}
ReferenceT<DebugService> service =
ObjectRegistryDatabase::Instance()->Find("DebugService");
if (!service.IsValid()) {
printf("ERROR: DebugService not found in registry\n");
return;
}
service->SetFullConfig(cdb);
ReferenceT<RealTimeApplication> app =
ObjectRegistryDatabase::Instance()->Find("App");
if (!app.IsValid()) {
printf("ERROR: App not found in registry\n");
return;
}
if (!app->ConfigureApplication()) {
printf("ERROR: ConfigureApplication failed.\n");
return;
}
if (app->PrepareNextState("State1") != ErrorManagement::NoError) {
printf("ERROR: Failed to prepare State1\n");
return;
}
if (app->StartNextStateExecution() != ErrorManagement::NoError) {
printf("ERROR: Failed to start execution\n");
return;
}
printf("Application started. Waiting for cycles...\n");
Sleep::MSec(2000);
// Enable Trace First - with retry logic
{
bool connected = false;
for (int retry=0; retry<10 && !connected; retry++) {
BasicTCPSocket tClient;
if (tClient.Open()) {
if (tClient.Connect("127.0.0.1", 8098)) {
connected = true;
const char *cmd = "TRACE App.Data.Timer.Counter 1\n";
uint32 s = StringHelper::Length(cmd);
tClient.Write(cmd, s);
tClient.Close();
} else {
printf("[SchedulerTest] Connect failed (retry %d)\n", retry);
Sleep::MSec(500);
}
} else {
printf("[SchedulerTest] Open failed (retry %d)\n", retry);
Sleep::MSec(500);
}
}
if (!connected) {
printf("WARNING: Could not connect to DebugService to enable trace.\n");
}
}
BasicUDPSocket listener;
listener.Open();
listener.Listen(8099);
// Read current value
uint32 valBeforePause = 0;
char buffer[2048];
uint32 size = 2048;
TimeoutType timeout(1000);
if (listener.Read(buffer, size, timeout)) {
// [Header][ID][Size][Value]
valBeforePause = *(uint32 *)(&buffer[sizeof(TraceHeader) + 16]);
printf("Value before/at pause: %u\n", valBeforePause);
} else {
printf("WARNING: No data received before pause.\n");
}
// Send PAUSE
printf("Sending PAUSE command...\n");
{
bool connected = false;
for (int retry=0; retry<10 && !connected; retry++) {
BasicTCPSocket client;
if (client.Open()) {
if (client.Connect("127.0.0.1", 8098)) {
connected = true;
const char *cmd = "PAUSE\n";
uint32 s = StringHelper::Length(cmd);
client.Write(cmd, s);
client.Close();
} else {
Sleep::MSec(200);
}
} else {
Sleep::MSec(200);
}
}
if (!connected) {
printf("ERROR: Could not connect to DebugService to send PAUSE.\n");
}
}
Sleep::MSec(2000); // Wait 2 seconds
// Read again - should be same or very close if paused
uint32 valAfterWait = 0;
size = 2048; // Reset size
while (listener.Read(buffer, size, TimeoutType(100))) {
valAfterWait = *(uint32 *)(&buffer[sizeof(TraceHeader) + 16]);
size = 2048;
}
printf("Value after 2s wait (drained): %u\n", valAfterWait);
// Check if truly paused
if (valAfterWait > valBeforePause + 10) {
printf(
"FAILURE: Counter increased significantly while paused! (%u -> %u)\n",
valBeforePause, valAfterWait);
} else {
printf("SUCCESS: Counter held steady (or close) during pause.\n");
}
// Resume
printf("Sending RESUME command...\n");
{
bool connected = false;
for (int retry=0; retry<10 && !connected; retry++) {
BasicTCPSocket rClient;
if (rClient.Open()) {
if (rClient.Connect("127.0.0.1", 8098)) {
connected = true;
const char *cmd = "RESUME\n";
uint32 s = StringHelper::Length(cmd);
rClient.Write(cmd, s);
rClient.Close();
} else {
Sleep::MSec(200);
}
} else {
Sleep::MSec(200);
}
}
}
Sleep::MSec(1000);
// Check if increasing
uint32 valAfterResume = 0;
size = 2048;
if (listener.Read(buffer, size, timeout)) {
valAfterResume = *(uint32 *)(&buffer[sizeof(TraceHeader) + 16]);
printf("Value after resume: %u\n", valAfterResume);
}
if (valAfterResume > valAfterWait) {
printf("SUCCESS: Execution resumed.\n");
} else {
printf("FAILURE: Execution did not resume.\n");
}
app->StopCurrentStateExecution();
}
+74
View File
@@ -0,0 +1,74 @@
#include "TestCommon.h"
#include "BasicTCPSocket.h"
#include "StringHelper.h"
#include "TimeoutType.h"
namespace MARTe {
const char8 * const debug_test_config =
"DebugService = {"
" Class = DebugService "
" ControlPort = 8095 "
" UdpPort = 8096 "
" StreamIP = \"127.0.0.1\" "
"}"
"App = {"
" Class = RealTimeApplication "
" +Functions = {"
" Class = ReferenceContainer "
" +GAM1 = {"
" Class = IOGAM "
" InputSignals = {"
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }"
" }"
" OutputSignals = {"
" Counter = { DataSource = DDB Type = uint32 }"
" }"
" }"
" +GAM2 = {"
" Class = IOGAM "
" InputSignals = {"
" Counter = { DataSource = TimerSlow Type = uint32 Frequency = 10 }"
" }"
" OutputSignals = {"
" Counter = { DataSource = Logger Type = uint32 }"
" }"
" }"
" }"
" +Data = {"
" Class = ReferenceContainer "
" DefaultDataSource = DDB "
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } } }"
" +TimerSlow = { Class = LinuxTimer SleepTime = 100000 Signals = { Counter = { Type = uint32 } } }"
" +Logger = { Class = LoggerDataSource Signals = { Counter = { Type = uint32 } } }"
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } } }"
" +DAMS = { Class = TimingDataSource }"
" }"
" +States = {"
" Class = ReferenceContainer "
" +State1 = { Class = RealTimeState +Threads = { Class = ReferenceContainer +Thread1 = { Class = RealTimeThread Functions = {GAM1 GAM2} } } }"
" }"
" +Scheduler = { Class = GAMScheduler TimingDataSource = DAMS }"
"}";
bool SendCommandGAM(uint16 port, const char8* cmd, StreamString &reply) {
BasicTCPSocket client;
if (!client.Open()) return false;
if (!client.Connect("127.0.0.1", port)) return false;
uint32 s = StringHelper::Length(cmd);
if (!client.Write(cmd, s)) return false;
char buffer[16384];
uint32 size = 16384;
TimeoutType timeout(5000);
if (client.Read(buffer, size, timeout)) {
reply.Write(buffer, size);
client.Close();
return true;
}
client.Close();
return false;
}
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef TESTCOMMON_H
#define TESTCOMMON_H
#include "CompilerTypes.h"
#include "StreamString.h"
namespace MARTe {
extern const char8 * const debug_test_config;
bool SendCommandGAM(uint16 port, const char8* cmd, StreamString &reply);
void TestMessageCommand();
}
#endif
+80
View File
@@ -0,0 +1,80 @@
#include "BasicTCPSocket.h"
#include "BasicUDPSocket.h"
#include "DebugService.h"
#include "ObjectRegistryDatabase.h"
#include "StandardParser.h"
#include "StreamString.h"
#include "HighResolutionTimer.h"
#include <assert.h>
#include <stdio.h>
using namespace MARTe;
void TestFullTracePipeline() {
printf("Starting Full Trace Pipeline Test...\n");
ObjectRegistryDatabase::Instance()->Purge();
// 1. Setup Service
DebugService service;
ConfigurationDatabase config;
config.Write("ControlPort", (uint16)8082);
config.Write("StreamPort", (uint16)8083);
config.Write("LogPort", (uint16)8084);
config.Write("StreamIP", "127.0.0.1");
assert(service.Initialise(config));
Sleep::MSec(500);
// 2. Register a mock signal
uint32 mockValue = 0;
DebugSignalInfo* sig = service.RegisterSignal(&mockValue, UnsignedInteger32Bit, "TraceTest.Signal", 0, 1);
assert(sig != NULL_PTR(DebugSignalInfo*));
printf("Signal registered with ID: %u\n", sig->internalID);
// 3. Enable Trace manually
sig->isTracing = true;
sig->decimationFactor = 1;
// 4. Setup a local UDP listener
BasicUDPSocket listener;
assert(listener.Open());
assert(listener.Listen(8083));
// 5. Simulate cycles
printf("Simulating cycles...\n");
for (int i=0; i<50; i++) {
mockValue = 1000 + i;
uint64 ts = (uint64)((float64)HighResolutionTimer::Counter() * HighResolutionTimer::Period() * 1000000.0);
service.ProcessSignal(sig, sizeof(uint32), ts);
Sleep::MSec(10);
}
// 6. Try to read from UDP
char buffer[2048];
uint32 size = 2048;
TimeoutType timeout(1000); // 1s
if (listener.Read(buffer, size, timeout)) {
printf("SUCCESS: Received %u bytes over UDP!\n", size);
TraceHeader *h = (TraceHeader*)buffer;
printf("Header: Magic=0x%X, Count=%u, Seq=%u\n", h->magic, h->count, h->seq);
uint32 offset = sizeof(TraceHeader);
if (size >= offset + 16) {
uint32 recId = *(uint32*)(&buffer[offset]);
uint64 recTs = *(uint64*)(&buffer[offset + 4]);
uint32 recSize = *(uint32*)(&buffer[offset + 12]);
printf("Data: ID=%u, TS=%llu, Size=%u\n", recId, (unsigned long long)recTs, recSize);
if (size >= offset + 16 + recSize) {
if (recSize == 4) {
uint32 recVal = *(uint32*)(&buffer[offset + 16]);
printf("Value=%u\n", recVal);
}
}
}
} else {
printf("FAILURE: No UDP packets received.\n");
}
listener.Close();
}
+178
View File
@@ -0,0 +1,178 @@
#include "BasicTCPSocket.h"
#include "ConfigurationDatabase.h"
#include "DebugService.h"
#include "GlobalObjectsDatabase.h"
#include "ObjectRegistryDatabase.h"
#include "RealTimeApplication.h"
#include "StandardParser.h"
#include "StreamString.h"
#include "TestCommon.h"
#include "IOGAM.h"
#include "LinuxTimer.h"
#include "GAMDataSource.h"
#include "TimingDataSource.h"
#include "GAMScheduler.h"
#include <stdio.h>
using namespace MARTe;
void TestTreeCommand() {
printf("--- Test: TREE Command Enhancement ---\n");
ObjectRegistryDatabase::Instance()->Purge();
Sleep::MSec(2000); // Wait for sockets from previous tests to clear
ConfigurationDatabase cdb;
// Use unique ports to avoid conflict with other tests
const char8 * const tree_test_config =
"DebugService = {"
" Class = DebugService "
" ControlPort = 8110 "
" UdpPort = 8111 "
" StreamIP = \"127.0.0.1\" "
"}"
"App = {"
" Class = RealTimeApplication "
" +Functions = {"
" Class = ReferenceContainer "
" +GAM1 = {"
" Class = IOGAM "
" InputSignals = {"
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }"
" Time = { DataSource = Timer Type = uint32 }"
" }"
" OutputSignals = {"
" Counter = { DataSource = DDB Type = uint32 }"
" Time = { DataSource = DDB Type = uint32 }"
" }"
" }"
" }"
" +Data = {"
" Class = ReferenceContainer "
" DefaultDataSource = DDB "
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
" +DAMS = { Class = TimingDataSource }"
" }"
" +States = {"
" Class = ReferenceContainer "
" +State1 = { Class = RealTimeState +Threads = { Class = ReferenceContainer +Thread1 = { Class = RealTimeThread Functions = {GAM1} } } }"
" }"
" +Scheduler = { Class = GAMScheduler TimingDataSource = DAMS }"
"}";
StreamString ss = tree_test_config;
ss.Seek(0);
StandardParser parser(ss, cdb);
if (!parser.Parse()) {
printf("ERROR: Failed to parse config\n");
return;
}
cdb.MoveToRoot();
uint32 n = cdb.GetNumberOfChildren();
for (uint32 i = 0; i < n; i++) {
const char8 *name = cdb.GetChildName(i);
ConfigurationDatabase child;
cdb.MoveRelative(name);
cdb.Copy(child);
cdb.MoveToAncestor(1u);
StreamString className;
child.Read("Class", className);
Reference ref(className.Buffer(),
GlobalObjectsDatabase::Instance()->GetStandardHeap());
if (!ref.IsValid()) {
printf("ERROR: Could not create object %s of class %s\n", name,
className.Buffer());
continue;
}
ref->SetName(name);
if (!ref->Initialise(child)) {
printf("ERROR: Failed to initialise object %s\n", name);
continue;
}
ObjectRegistryDatabase::Instance()->Insert(ref);
}
ReferenceT<DebugService> service =
ObjectRegistryDatabase::Instance()->Find("DebugService");
if (!service.IsValid()) {
printf("ERROR: DebugService not found\n");
return;
}
service->SetFullConfig(cdb);
ReferenceT<RealTimeApplication> app =
ObjectRegistryDatabase::Instance()->Find("App");
if (!app.IsValid()) {
printf("ERROR: App not found\n");
return;
}
if (!app->ConfigureApplication()) {
printf("ERROR: ConfigureApplication failed.\n");
return;
}
if (app->PrepareNextState("State1") != ErrorManagement::NoError) {
printf("ERROR: PrepareNextState failed.\n");
return;
}
if (app->StartNextStateExecution() != ErrorManagement::NoError) {
printf("ERROR: StartNextStateExecution failed.\n");
return;
}
printf("Application started.\n");
Sleep::MSec(1000);
// Step 1: Request TREE
StreamString reply;
if (SendCommandGAM(8110, "TREE\n", reply)) {
printf("TREE response received (len=%llu)\n", reply.Size());
// ...
}
// Step 2: SERVICE_INFO
printf("\n--- Step 2: SERVICE_INFO ---\n");
reply = "";
if (SendCommandGAM(8110, "SERVICE_INFO\n", reply)) {
printf("SERVICE_INFO response: %s", reply.Buffer());
if (StringHelper::SearchString(reply.Buffer(), "TCP_CTRL:8110") != NULL_PTR(const char8 *) &&
StringHelper::SearchString(reply.Buffer(), "UDP_STREAM:8111") != NULL_PTR(const char8 *)) {
printf("SUCCESS: SERVICE_INFO returned correct ports.\n");
} else {
printf("FAILURE: SERVICE_INFO returned incorrect data.\n");
}
}
// Step 3: MONITOR
printf("\n--- Step 3: MONITOR SIGNAL ---\n");
reply = "";
if (SendCommandGAM(8110, "MONITOR SIGNAL App.Data.Timer.Counter 10\n", reply)) {
printf("MONITOR response: %s", reply.Buffer());
if (StringHelper::SearchString(reply.Buffer(), "OK MONITOR 1") != NULL_PTR(const char8 *)) {
printf("SUCCESS: Signal monitored.\n");
} else {
printf("FAILURE: Could not monitor signal.\n");
}
}
// Step 4: UNMONITOR
printf("\n--- Step 4: UNMONITOR SIGNAL ---\n");
reply = "";
if (SendCommandGAM(8110, "UNMONITOR SIGNAL App.Data.Timer.Counter\n", reply)) {
printf("UNMONITOR response: %s", reply.Buffer());
if (StringHelper::SearchString(reply.Buffer(), "OK UNMONITOR 1") != NULL_PTR(const char8 *)) {
printf("SUCCESS: Signal unmonitored.\n");
} else {
printf("FAILURE: Could not unmonitor signal.\n");
}
}
app->StopCurrentStateExecution();
ObjectRegistryDatabase::Instance()->Purge();
}
+161
View File
@@ -0,0 +1,161 @@
#include "BasicTCPSocket.h"
#include "BasicUDPSocket.h"
#include "DebugService.h"
#include "ObjectRegistryDatabase.h"
#include "RealTimeApplication.h"
#include "StandardParser.h"
#include "StreamString.h"
#include "GlobalObjectsDatabase.h"
#include <assert.h>
#include <stdio.h>
using namespace MARTe;
const char8 * const validation_config =
"DebugService = {"
" Class = DebugService "
" ControlPort = 8085 "
" UdpPort = 8086 "
" StreamIP = \"127.0.0.1\" "
"}"
"App = {"
" Class = RealTimeApplication "
" +Functions = {"
" Class = ReferenceContainer "
" +GAM1 = {"
" Class = IOGAM "
" InputSignals = {"
" Counter = { DataSource = Timer Type = uint32 Frequency = 1000 }"
" Time = { DataSource = Timer Type = uint32 }"
" }"
" OutputSignals = {"
" Counter = { DataSource = DDB Type = uint32 }"
" Time = { DataSource = DDB Type = uint32 }"
" }"
" }"
" }"
" +Data = {"
" Class = ReferenceContainer "
" DefaultDataSource = DDB "
" +Timer = { Class = LinuxTimer SleepTime = 1000 Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
" +DDB = { Class = GAMDataSource Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } }"
" +DAMS = { Class = TimingDataSource }"
" }"
" +States = {"
" Class = ReferenceContainer "
" +State1 = { Class = RealTimeState +Threads = { Class = ReferenceContainer +Thread1 = { Class = RealTimeThread Functions = {GAM1} } } }"
" }"
" +Scheduler = { Class = GAMScheduler TimingDataSource = DAMS }"
"}";
void RunValidationTest() {
printf("--- MARTe2 1kHz Lossless Trace Validation Test ---\n");
ObjectRegistryDatabase::Instance()->Purge();
ConfigurationDatabase cdb;
StreamString ss = validation_config;
ss.Seek(0);
StandardParser parser(ss, cdb);
assert(parser.Parse());
cdb.MoveToRoot();
uint32 n = cdb.GetNumberOfChildren();
for (uint32 i=0; i<n; i++) {
const char8* name = cdb.GetChildName(i);
ConfigurationDatabase child;
cdb.MoveRelative(name);
cdb.Copy(child);
cdb.MoveToAncestor(1u);
StreamString className;
child.Read("Class", className);
Reference ref(className.Buffer(), GlobalObjectsDatabase::Instance()->GetStandardHeap());
ref->SetName(name);
assert(ref->Initialise(child));
ObjectRegistryDatabase::Instance()->Insert(ref);
}
Reference serviceGeneric = ObjectRegistryDatabase::Instance()->Find("DebugService");
Reference appGeneric = ObjectRegistryDatabase::Instance()->Find("App");
if (!serviceGeneric.IsValid() || !appGeneric.IsValid()) {
printf("ERROR: Objects NOT FOUND in ValidationTest\n");
return;
}
DebugService *service = dynamic_cast<DebugService*>(serviceGeneric.operator->());
RealTimeApplication *app = dynamic_cast<RealTimeApplication*>(appGeneric.operator->());
assert(service);
assert(app);
service->SetFullConfig(cdb);
if (!app->ConfigureApplication()) {
printf("ERROR: ConfigureApplication failed in ValidationTest.\n");
return;
}
assert(app->PrepareNextState("State1") == ErrorManagement::NoError);
assert(app->StartNextStateExecution() == ErrorManagement::NoError);
printf("Application started at 1kHz. Enabling Traces...\n");
Sleep::MSec(1000);
if (service->TraceSignal("App.Data.Timer.Counter", true, 1) == 0) {
printf("ERROR: Failed to enable trace for App.Data.Timer.Counter\n");
}
BasicUDPSocket listener;
listener.Open();
listener.Listen(8086);
printf("Validating for 10 seconds...\n");
uint32 totalPackets = 0;
uint32 totalSamples = 0;
uint32 discontinuities = 0;
uint32 lastValue = 0xFFFFFFFF;
uint64 start = HighResolutionTimer::Counter();
float64 elapsed = 0;
while (elapsed < 10.0) {
char buffer[2048];
uint32 size = 2048;
if (listener.Read(buffer, size, TimeoutType(100))) {
totalPackets++;
TraceHeader *h = (TraceHeader*)buffer;
uint32 offset = sizeof(TraceHeader);
for (uint32 i=0; i<h->count; i++) {
uint32 recId = *(uint32*)(&buffer[offset]);
uint32 recSize = *(uint32*)(&buffer[offset + 12]);
if (recSize == 4) {
uint32 val = *(uint32*)(&buffer[offset + 16]);
totalSamples++;
if (lastValue != 0xFFFFFFFF && val != lastValue + 1) {
discontinuities++;
}
lastValue = val;
}
offset += (16 + recSize);
}
}
elapsed = (float64)(HighResolutionTimer::Counter() - start) * HighResolutionTimer::Period();
}
printf("\n--- Test Results ---\n");
printf("Total UDP Packets: %u\n", totalPackets);
printf("Total Counter Samples: %u\n", totalSamples);
printf("Counter Discontinuities: %u\n", discontinuities);
if (totalSamples < 9000) {
printf("FAILURE: Underflow - samples missing (%u).\n", totalSamples);
} else if (discontinuities > 50) {
printf("FAILURE: Excessive discontinuities detected! (%u)\n", discontinuities);
} else {
printf("VALIDATION SUCCESSFUL: 1kHz Lossless Tracing Verified.\n");
}
app->StopCurrentStateExecution();
}
+9
View File
@@ -0,0 +1,9 @@
all:
$(MAKE) -C GTest -f Makefile.gcc
$(MAKE) -C Integration -f Makefile.gcc
clean:
$(MAKE) -C GTest -f Makefile.gcc clean
$(MAKE) -C Integration -f Makefile.gcc clean
.PHONY: all clean
+1
View File
@@ -0,0 +1 @@
# Test top-level Makefile.inc