|
PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
|
Integration-style tests for PROFINET DCE/RPC RPCCon. More...
#include <array>#include <asio.hpp>#include <atomic>#include <chrono>#include <cstdint>#include <cstring>#include <functional>#include <mutex>#include <optional>#include <ranges>#include <string>#include <thread>#include <utility>#include <vector>#include "profinet/exceptions.h"#include "profinet/protocol.h"#include "profinet/rpc.h"
Include dependency graph for test_rpc_Integration.cpp:Go to the source code of this file.
Classes | |
| struct | BlockView |
| class | TestRpcDevice |
| struct | TestRpcDevice::ControlRequest |
| struct | TestRpcDevice::ControlResponse |
| class | RpcConIntegrationTest |
Functions | |
| MacAddress | TestMac () |
| dcp::DCPDeviceDescription | MakeTestDeviceDescription () |
| Bytes | MakeNrdResponse (const Bytes &payload) |
| PNRPCHeader | MakeRpcResponse (const PNRPCHeader &request, const Bytes &payload) |
| PNRPCHeader | MakeRpcFault (const PNRPCHeader &request) |
| PNRPCHeader | MakeRpcReject (const PNRPCHeader &request) |
| Bytes | MakePnioStatusResponse (std::uint32_t argsMaximumStatus, const Bytes &payload={}) |
| Bytes | ExtractNrdPayload (const PNRPCHeader &request) |
| std::vector< BlockView > | FindBlocks (const Bytes &data) |
| Bytes | GetBlock (const Bytes &data, const BlockView &block) |
| bool | ContainsBlockType (const Bytes &data, std::uint16_t blockType) |
| std::size_t | CountBlockType (const Bytes &data, std::uint16_t blockType) |
| IOCRSetup | MakeAumaLikeIocrSetup () |
| TEST_F (RpcConIntegrationTest, ConnectEstablishesApplicationRelationship) | |
| TEST_F (RpcConIntegrationTest, ConnectRequiresSourceMac) | |
| TEST_F (RpcConIntegrationTest, ConnectConvertsPnioErrorToRpcConnectionError) | |
| TEST_F (RpcConIntegrationTest, ConnectConvertsRpcFault) | |
| TEST_F (RpcConIntegrationTest, ConnectConvertsRpcReject) | |
| TEST_F (RpcConIntegrationTest, IgnoresIncomingRpcRequestBeforeResponse) | |
| TEST_F (RpcConIntegrationTest, ConnectTimesOutWhenDeviceDoesNotRespond) | |
| TEST_F (RpcConIntegrationTest, ConnectWithAlarmCrSendsAlarmCrBlock) | |
| TEST_F (RpcConIntegrationTest, ConnectWithIocrSendsIocrAndExpectedSubmoduleBlocks) | |
| TEST_F (RpcConIntegrationTest, ReadSendsIodReadAndReturnsPayload) | |
| TEST_F (RpcConIntegrationTest, WriteSendsIodWritePayload) | |
| TEST_F (RpcConIntegrationTest, ImplicitReadRequiresStatefulSimulatedDevice) | |
| TEST_F (RpcConIntegrationTest, DisconnectClosesApplicationRelationship) | |
| TEST_F (RpcConIntegrationTest, CloseIsIdempotent) | |
| TEST_F (RpcConIntegrationTest, ExposesIoContext) | |
| TEST_F (RpcConIntegrationTest, AumaLikeIocrConfigurationHasExpectedSlots) | |
| TEST_F (RpcConIntegrationTest, ApplicationReady) | |
| Verifies the complete CControl ApplicationReady request/response exchange. | |
| TEST_F (RpcConIntegrationTest, ApplicationReadyReceivesCorrectRequest) | |
| Verifies that ApplicationReady receives the expected PROFINET ApplicationReady control request. | |
| TEST_F (RpcConIntegrationTest, ApplicationReadyResponseMatchesRequest) | |
| Verifies that the RPC response generated for ApplicationReady preserves the required DCE/RPC correlation fields. | |
| TEST_F (RpcConIntegrationTest, ApplicationReadyResponseHasSuccessfulNrdStatus) | |
| Verifies that the ApplicationReady response contains a successful NRD/PNIO status and internally consistent count fields. | |
| TEST_F (RpcConIntegrationTest, ApplicationReadyTimesOut) | |
| Verifies that ApplicationReady throws RPCTimeoutError when the device does not send an ApplicationReady request. | |
| TEST_F (RpcConIntegrationTest, ApplicationReadyIgnoresNonControlRequest) | |
| Verifies that ApplicationReady ignores incoming RPC REQUEST packets for operations other than CONTROL. | |
| TEST_F (RpcConIntegrationTest, ApplicationReadyIgnoresRpcResponse) | |
| Verifies that ApplicationReady ignores an incoming RPC RESPONSE packet and continues waiting for the device's REQUEST. | |
| TEST_F (RpcConIntegrationTest, ApplicationReadyIgnoresOtherControlBlock) | |
| Verifies that ApplicationReady ignores CONTROL requests containing a control block other than ApplicationReady. | |
| TEST_F (RpcConIntegrationTest, ApplicationReadyAcceptsUnexpectedControlCommand) | |
| Verifies the current compatibility behavior where an ApplicationReady request is accepted even if the control command is not CONTROL_CMD_APP_READY. | |
Variables | |
| constexpr std::uint16_t | kTestRpcPort = RPC_PORT |
| constexpr std::uint32_t | kTestApi = 0 |
| constexpr std::uint16_t | kTestSlot = 0 |
| constexpr std::uint16_t | kTestSubslot = 1 |
| constexpr std::uint16_t | kTestReadIndex = 0xAFF0 |
| constexpr std::uint16_t | kTestWriteIndex = 0xAFF1 |
| constexpr std::uint16_t | kTestAlarmReference = 0x1234 |
Integration-style tests for PROFINET DCE/RPC RPCCon.
These tests use a real UDP socket on localhost as a simulated PROFINET IO-device. RPCCon and RpcTransport are therefore exercised without mocking the transport layer.
The tests validate:
NOTE: ApplicationReady() is currently disabled because the implementation in RPCCon sends an empty datagram via SendReceive() instead of first receiving the device request. See DISABLED_ApplicationReady below.
Definition in file test_rpc_Integration.cpp.
| bool ContainsBlockType | ( | const Bytes & | data, |
| std::uint16_t | blockType | ||
| ) |
Definition at line 317 of file test_rpc_Integration.cpp.
References FindBlocks().
Referenced by TestRpcDevice::HandleConnect().
Here is the call graph for this function:
Here is the caller graph for this function:| std::size_t CountBlockType | ( | const Bytes & | data, |
| std::uint16_t | blockType | ||
| ) |
Definition at line 334 of file test_rpc_Integration.cpp.
References FindBlocks().
Here is the call graph for this function:| Bytes ExtractNrdPayload | ( | const PNRPCHeader & | request | ) |
Definition at line 234 of file test_rpc_Integration.cpp.
References profinet::PNNRDData::Parse(), profinet::PNRPCHeader::payload, and profinet::PNNRDData::payload.
Referenced by TestRpcDevice::HandleConnect(), TestRpcDevice::HandleRead(), and TestRpcDevice::HandleWrite().
Here is the call graph for this function:
Here is the caller graph for this function:Definition at line 276 of file test_rpc_Integration.cpp.
References profinet::rpc::BlockHeaderView::blockLength, profinet::rpc::BlockHeaderView::blockType, and profinet::rpc::PeekBlockHeader().
Referenced by ContainsBlockType(), and CountBlockType().
Here is the call graph for this function:
Here is the caller graph for this function:Definition at line 307 of file test_rpc_Integration.cpp.
References BlockView::blockLength, and BlockView::offset.
| IOCRSetup MakeAumaLikeIocrSetup | ( | ) |
Definition at line 1621 of file test_rpc_Integration.cpp.
References profinet::rpc::IOSlot::slot.
Referenced by TEST_F(), and TEST_F().
Here is the caller graph for this function:Definition at line 163 of file test_rpc_Integration.cpp.
References profinet::PNNRDData::actualCount, profinet::PNNRDData::argsLength, profinet::PNNRDData::argsMaximumStatus, profinet::PNNRDData::maximumCount, profinet::PNNRDData::offset, profinet::PNNRDData::payload, payload, and profinet::PNNRDData::ToBytes().
Referenced by TestRpcDevice::HandleConnect(), and TestRpcDevice::SendControlRequest().
Here is the call graph for this function:
Here is the caller graph for this function:Definition at line 219 of file test_rpc_Integration.cpp.
Referenced by TestRpcDevice::HandleConnectPnioError(), TestRpcDevice::HandleRead(), and TestRpcDevice::HandleWrite().
Here is the caller graph for this function:| PNRPCHeader MakeRpcFault | ( | const PNRPCHeader & | request | ) |
Definition at line 191 of file test_rpc_Integration.cpp.
References profinet::PNRPCHeader::FAULT, profinet::PNRPCHeader::flags1, profinet::PNRPCHeader::flags2, profinet::PNRPCHeader::lengthOfBody, profinet::PNRPCHeader::packetType, and profinet::PNRPCHeader::payload.
Referenced by TestRpcDevice::HandleRpcFault().
Here is the caller graph for this function:| PNRPCHeader MakeRpcReject | ( | const PNRPCHeader & | request | ) |
Definition at line 205 of file test_rpc_Integration.cpp.
References profinet::PNRPCHeader::flags1, profinet::PNRPCHeader::flags2, profinet::PNRPCHeader::lengthOfBody, profinet::PNRPCHeader::packetType, profinet::PNRPCHeader::payload, and profinet::PNRPCHeader::REJECT.
Referenced by TestRpcDevice::HandleRpcReject().
Here is the caller graph for this function:| PNRPCHeader MakeRpcResponse | ( | const PNRPCHeader & | request, |
| const Bytes & | payload | ||
| ) |
Definition at line 176 of file test_rpc_Integration.cpp.
References profinet::PNRPCHeader::flags1, profinet::PNRPCHeader::flags2, profinet::PNRPCHeader::lengthOfBody, profinet::PNRPCHeader::packetType, profinet::PNRPCHeader::payload, payload, and profinet::PNRPCHeader::RESPONSE.
Referenced by TestRpcDevice::HandleConnect(), TestRpcDevice::HandleConnectPnioError(), TestRpcDevice::HandleRead(), and TestRpcDevice::HandleWrite().
Here is the caller graph for this function:| dcp::DCPDeviceDescription MakeTestDeviceDescription | ( | ) |
Definition at line 142 of file test_rpc_Integration.cpp.
References profinet::dcp::DCPDeviceDescription::name, and profinet::String2Mac().
Referenced by RpcConIntegrationTest::SetUp(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().
Here is the call graph for this function:
Here is the caller graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| ApplicationReady | |||
| ) |
Verifies the complete CControl ApplicationReady request/response exchange.
The simulated IO-device sends an ApplicationReady request using the connected AR UUID and session key. RPCCon must receive the request and return a CONTROL response containing the DONE command.
Definition at line 2216 of file test_rpc_Integration.cpp.
References profinet::rpc::BLOCK_IOD_CONTROL_APP_READY_RES, and profinet::rpc::CONTROL_CMD_DONE.
| TEST_F | ( | RpcConIntegrationTest | , |
| ApplicationReadyAcceptsUnexpectedControlCommand | |||
| ) |
Verifies the current compatibility behavior where an ApplicationReady request is accepted even if the control command is not CONTROL_CMD_APP_READY.
The ApplicationReady implementation currently validates the block type but intentionally does not reject a deviating control command.
Definition at line 2582 of file test_rpc_Integration.cpp.
References profinet::rpc::BLOCK_IOD_CONTROL_APP_READY_REQ, profinet::rpc::BLOCK_IOD_CONTROL_APP_READY_RES, and profinet::rpc::CONTROL_CMD_DONE.
| TEST_F | ( | RpcConIntegrationTest | , |
| ApplicationReadyIgnoresNonControlRequest | |||
| ) |
Verifies that ApplicationReady ignores incoming RPC REQUEST packets for operations other than CONTROL.
A non-CONTROL request is followed by a valid ApplicationReady request. The valid request must still be processed.
Definition at line 2461 of file test_rpc_Integration.cpp.
References profinet::PNRPCHeader::CONTROL, profinet::rpc::CONTROL_CMD_DONE, profinet::PNRPCHeader::operationNumber, and profinet::PNRPCHeader::READ.
| TEST_F | ( | RpcConIntegrationTest | , |
| ApplicationReadyIgnoresOtherControlBlock | |||
| ) |
Verifies that ApplicationReady ignores CONTROL requests containing a control block other than ApplicationReady.
The test uses a parameterization/control block request for which the ApplicationReady implementation must continue waiting until its timeout.
Definition at line 2550 of file test_rpc_Integration.cpp.
References profinet::rpc::BLOCK_IOD_CONTROL_PRM_END_REQ, and profinet::rpc::CONTROL_CMD_PRM_END.
| TEST_F | ( | RpcConIntegrationTest | , |
| ApplicationReadyIgnoresRpcResponse | |||
| ) |
Verifies that ApplicationReady ignores an incoming RPC RESPONSE packet and continues waiting for the device's REQUEST.
Definition at line 2502 of file test_rpc_Integration.cpp.
References profinet::PNRPCHeader::CONTROL, profinet::rpc::CONTROL_CMD_DONE, profinet::PNRPCHeader::operationNumber, profinet::PNRPCHeader::packetType, and profinet::PNRPCHeader::RESPONSE.
| TEST_F | ( | RpcConIntegrationTest | , |
| ApplicationReadyReceivesCorrectRequest | |||
| ) |
Verifies that ApplicationReady receives the expected PROFINET ApplicationReady control request.
The test validates the block type, command, AR UUID, session key and control block properties received by RPCCon.
Definition at line 2269 of file test_rpc_Integration.cpp.
References profinet::rpc::BLOCK_IOD_CONTROL_APP_READY_REQ, and profinet::rpc::CONTROL_CMD_APP_READY.
| TEST_F | ( | RpcConIntegrationTest | , |
| ApplicationReadyResponseHasSuccessfulNrdStatus | |||
| ) |
Verifies that the ApplicationReady response contains a successful NRD/PNIO status and internally consistent count fields.
Definition at line 2395 of file test_rpc_Integration.cpp.
References profinet::PNNRDData::actualCount, profinet::PNNRDData::argsLength, profinet::PNNRDData::argsMaximumStatus, profinet::PNNRDData::maximumCount, and profinet::PNNRDData::offset.
| TEST_F | ( | RpcConIntegrationTest | , |
| ApplicationReadyResponseMatchesRequest | |||
| ) |
Verifies that the RPC response generated for ApplicationReady preserves the required DCE/RPC correlation fields.
The response must use the same DREP, UUIDs, sequence number and operation number as the incoming request.
Definition at line 2320 of file test_rpc_Integration.cpp.
References profinet::PNRPCHeader::activityHint, profinet::PNRPCHeader::activityUuid, profinet::PNRPCHeader::CONTROL, profinet::PNRPCHeader::interfaceHint, profinet::PNRPCHeader::interfaceUuid, profinet::PNRPCHeader::objectUuid, profinet::PNRPCHeader::operationNumber, profinet::PNRPCHeader::packetType, profinet::PNRPCHeader::RESPONSE, profinet::PNRPCHeader::sequenceNumber, and profinet::PNRPCHeader::version.
| TEST_F | ( | RpcConIntegrationTest | , |
| ApplicationReadyTimesOut | |||
| ) |
Verifies that ApplicationReady throws RPCTimeoutError when the device does not send an ApplicationReady request.
Definition at line 2439 of file test_rpc_Integration.cpp.
| TEST_F | ( | RpcConIntegrationTest | , |
| AumaLikeIocrConfigurationHasExpectedSlots | |||
| ) |
Definition at line 2145 of file test_rpc_Integration.cpp.
References MakeAumaLikeIocrSetup(), and profinet::rpc::IOCRSetup::slots.
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| CloseIsIdempotent | |||
| ) |
Definition at line 2089 of file test_rpc_Integration.cpp.
References profinet::rpc::RPCCon::Close(), profinet::rpc::RPCCon::Connect(), TestRpcDevice::ConnectOk, profinet::rpc::RPCCon::IsConnected(), MakeTestDeviceDescription(), TestRpcDevice::Start(), and TestMac().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| ConnectConvertsPnioErrorToRpcConnectionError | |||
| ) |
Definition at line 1773 of file test_rpc_Integration.cpp.
References profinet::rpc::RPCCon::Connect(), TestRpcDevice::ConnectPnioError, profinet::rpc::RPCCon::IsConnected(), MakeTestDeviceDescription(), TestRpcDevice::SawExpectedConnect(), TestRpcDevice::Start(), and TestMac().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| ConnectConvertsRpcFault | |||
| ) |
Definition at line 1799 of file test_rpc_Integration.cpp.
References profinet::rpc::RPCCon::Connect(), profinet::rpc::RPCCon::IsConnected(), MakeTestDeviceDescription(), TestRpcDevice::RpcFault, TestRpcDevice::Start(), and TestMac().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| ConnectConvertsRpcReject | |||
| ) |
Definition at line 1822 of file test_rpc_Integration.cpp.
References profinet::rpc::RPCCon::Connect(), profinet::rpc::RPCCon::IsConnected(), MakeTestDeviceDescription(), TestRpcDevice::RpcReject, TestRpcDevice::Start(), and TestMac().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| ConnectEstablishesApplicationRelationship | |||
| ) |
Definition at line 1710 of file test_rpc_Integration.cpp.
References profinet::rpc::RPCCon::Connect(), TestRpcDevice::ConnectOk, profinet::rpc::RPCCon::Disconnect(), profinet::rpc::RPCCon::Info(), profinet::rpc::RPCCon::IsConnected(), MakeTestDeviceDescription(), profinet::dcp::DCPDeviceDescription::name, TestRpcDevice::SawExpectedConnect(), profinet::rpc::RPCCon::SessionKey(), TestRpcDevice::Start(), and TestMac().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| ConnectRequiresSourceMac | |||
| ) |
Definition at line 1752 of file test_rpc_Integration.cpp.
References profinet::rpc::RPCCon::Connect(), TestRpcDevice::ConnectOk, profinet::rpc::RPCCon::IsConnected(), MakeTestDeviceDescription(), and TestRpcDevice::Start().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| ConnectTimesOutWhenDeviceDoesNotRespond | |||
| ) |
Definition at line 1877 of file test_rpc_Integration.cpp.
References profinet::rpc::RPCCon::Connect(), TestRpcDevice::ConnectTimeout, profinet::rpc::RPCCon::IsConnected(), MakeTestDeviceDescription(), TestRpcDevice::RequestCount(), TestRpcDevice::Start(), TestMac(), and profinet::rpc::RPCConOptions::timeoutSec.
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| ConnectWithAlarmCrSendsAlarmCrBlock | |||
| ) |
Definition at line 1905 of file test_rpc_Integration.cpp.
References TestRpcDevice::AlarmCr, profinet::rpc::RPCCon::Connect(), profinet::rpc::RPCCon::HasAlarmCr(), profinet::rpc::RPCCon::IsConnected(), MakeTestDeviceDescription(), TestRpcDevice::SawAlarmCr(), TestRpcDevice::SawExpectedConnect(), TestRpcDevice::Start(), and TestMac().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| ConnectWithIocrSendsIocrAndExpectedSubmoduleBlocks | |||
| ) |
Definition at line 1944 of file test_rpc_Integration.cpp.
References profinet::rpc::RPCCon::ArUuid(), profinet::rpc::RPCCon::Connect(), TestRpcDevice::Iocr, profinet::rpc::RPCCon::IsConnected(), MakeAumaLikeIocrSetup(), MakeTestDeviceDescription(), TestRpcDevice::SawExpectedConnect(), TestRpcDevice::SawExpectedSubmodule(), TestRpcDevice::SawInputIocr(), TestRpcDevice::SawOutputIocr(), profinet::rpc::RPCCon::SessionKey(), TestRpcDevice::Start(), and TestMac().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| DisconnectClosesApplicationRelationship | |||
| ) |
Definition at line 2058 of file test_rpc_Integration.cpp.
References profinet::rpc::RPCCon::Connect(), TestRpcDevice::ConnectOk, profinet::rpc::RPCCon::Disconnect(), profinet::rpc::RPCCon::IsConnected(), MakeTestDeviceDescription(), TestRpcDevice::Start(), and TestMac().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| ExposesIoContext | |||
| ) |
Definition at line 2124 of file test_rpc_Integration.cpp.
References MakeTestDeviceDescription().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| IgnoresIncomingRpcRequestBeforeResponse | |||
| ) |
Definition at line 1848 of file test_rpc_Integration.cpp.
References profinet::rpc::RPCCon::Connect(), TestRpcDevice::ConnectIgnoreRequestThenRespond, profinet::rpc::RPCCon::IsConnected(), MakeTestDeviceDescription(), TestRpcDevice::RequestCount(), TestRpcDevice::SawExpectedConnect(), TestRpcDevice::Start(), and TestMac().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| ImplicitReadRequiresStatefulSimulatedDevice | |||
| ) |
Definition at line 2047 of file test_rpc_Integration.cpp.
| TEST_F | ( | RpcConIntegrationTest | , |
| ReadSendsIodReadAndReturnsPayload | |||
| ) |
Definition at line 1994 of file test_rpc_Integration.cpp.
References profinet::rpc::RPCCon::Connect(), TestRpcDevice::ConnectOk, MakeTestDeviceDescription(), TestRpcDevice::Start(), TestRpcDevice::Stop(), and TestMac().
Here is the call graph for this function:| TEST_F | ( | RpcConIntegrationTest | , |
| WriteSendsIodWritePayload | |||
| ) |
Definition at line 2036 of file test_rpc_Integration.cpp.
| MacAddress TestMac | ( | ) |
|
constexpr |
Definition at line 118 of file test_rpc_Integration.cpp.
|
constexpr |
Definition at line 110 of file test_rpc_Integration.cpp.
|
constexpr |
Definition at line 115 of file test_rpc_Integration.cpp.
|
constexpr |
Definition at line 108 of file test_rpc_Integration.cpp.
|
constexpr |
Definition at line 112 of file test_rpc_Integration.cpp.
|
constexpr |
Definition at line 113 of file test_rpc_Integration.cpp.
|
constexpr |
Definition at line 116 of file test_rpc_Integration.cpp.