9#include <gtest/gtest.h>
27class UtilMoreTests :
public ::testing::Test
33TEST_F(UtilMoreTests, HexFormattersHandleBoundaries)
35 EXPECT_EQ(
Hex4(0),
"0x0000");
36 EXPECT_EQ(
Hex4(0x000F),
"0x000F");
37 EXPECT_EQ(
Hex4(0xFFFF),
"0xFFFF");
39 EXPECT_EQ(
Hex2(0),
"0x00");
40 EXPECT_EQ(
Hex2(0x0F),
"0x0F");
41 EXPECT_EQ(
Hex2(0xFF),
"0xFF");
45TEST_F(UtilMoreTests, ToVecConvertsStringBytes)
47 const auto bytes =
ToVec(std::string{
"A\x00\xFF", 3});
49 ASSERT_EQ(bytes.size(), 3U);
50 EXPECT_EQ(bytes[0],
static_cast<std::uint8_t
>(
'A'));
51 EXPECT_EQ(bytes[1], 0U);
52 EXPECT_EQ(bytes[2], 0xFFU);
56TEST_F(UtilMoreTests, ToHexHandlesRawPointerAndEmptyInput)
58 const std::uint8_t bytes[] = {0x00, 0x01, 0xAB, 0xFF};
60 EXPECT_EQ(
ToHex(bytes, 4),
"0001abff");
61 EXPECT_EQ(
ToHex(bytes, 0),
"");
62 EXPECT_EQ(
ToHex(std::vector<std::uint8_t>{}),
"");
66TEST_F(UtilMoreTests, DecodeBytesPreservesEmbeddedNul)
68 const std::vector<std::uint8_t> bytes{
'A', 0,
'B', 0, 0};
70 EXPECT_EQ(
DecodeBytes(bytes), std::string(
"A\0B", 3));
71 EXPECT_EQ(
DecodeBytes(
static_cast<const std::uint8_t*
>(
nullptr), 0),
"");
75TEST_F(UtilMoreTests, String2MacAcceptsCanonicalHexDigits)
77 const auto expectedMac =
MacAddress{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
78 EXPECT_EQ(
String2Mac(
"AA:bb:CC:dd:EE:ff"), expectedMac);
82TEST_F(UtilMoreTests, String2MacRejectsMalformedVariants)
84 EXPECT_THROW(
String2Mac(
"aa-bb-cc-dd-ee-ff"), std::exception);
85 EXPECT_THROW(
String2Mac(
"aa:bb:cc:dd:ee:ff:00"), std::exception);
86 EXPECT_THROW(
String2Mac(
"a:bb:cc:dd:ee:ff"), std::exception);
87 EXPECT_THROW(
String2Mac(
"aa:bb:cc:dd:ee:fg"), std::exception);
91TEST_F(UtilMoreTests, IpConversionHandlesBoundaryAddresses)
98TEST_F(UtilMoreTests, String2IpRejectsInvalidLength)
100 const std::array<std::uint8_t, 3> shortIp{1, 2, 3};
101 EXPECT_THROW(
String2Ip(shortIp.data(), shortIp.size()), std::exception);
105TEST_F(UtilMoreTests, Ip2StringRejectsExtraComponents)
107 EXPECT_THROW(
Ip2String(
"1.2.3.4.5"), std::exception);
111TEST_F(UtilMoreTests, SkipVlanTagsHandlesTruncatedTag)
121TEST_F(UtilMoreTests, SkipVlanTagsLeavesOrdinaryEtherTypeUntouched)
131TEST_F(UtilMoreTests, SkipVlanTagsHandlesTripleTaggedFrame)
135 const std::array<std::uint8_t, 4> outer{0x88, 0xA8, 0, 1};
136 const std::array<std::uint8_t, 4> middle{0x81, 0x00, 0, 2};
137 const std::array<std::uint8_t, 4> inner{0x81, 0x00, 0, 3};
139 frame.insert(
frame.end(), outer.begin(), outer.end());
140 frame.insert(
frame.end(), middle.begin(), middle.end());
141 frame.insert(
frame.end(), inner.begin(), inner.end());
142 frame.push_back(0x88);
143 frame.push_back(0x92);
149TEST_F(UtilMoreTests, MaxTimeoutRemainingIsPositiveBeforeExpiry)
151 const MaxTimeout timeout(std::chrono::duration<double>(1.0));
153 EXPECT_GT(timeout.
Remaining().count(), 0.0);
158TEST_F(UtilMoreTests, MaxTimeoutRemainingIsZeroAfterExpiry)
160 const MaxTimeout timeout(std::chrono::duration<double>(-1.0));
163 EXPECT_EQ(timeout.
Remaining().count(), 0.0);
167TEST_F(UtilMoreTests, MaxTimeoutHandlesPastDeadline)
169 const MaxTimeout timeout(std::chrono::duration<double>(-0.001));
175TEST_F(UtilMoreTests, GetExecutableDirectoryReturnsExistingDirectory)
179 EXPECT_TRUE(directory.is_absolute());
180 EXPECT_TRUE(std::filesystem::exists(directory));
181 EXPECT_TRUE(std::filesystem::is_directory(directory));
185TEST_F(UtilMoreTests, GetMacRejectsUnknownInterface)
187 EXPECT_THROW(
GetInterfaceMac(
"this-interface-does-not-exist"), std::exception);
191TEST_F(UtilMoreTests, GetMacReadsLoopbackInterface)
198TEST_F(UtilMoreTests, SkipVlanTagsRecognizesSupportedTpids)
200 for (
const auto tpid : std::array<std::array<std::uint8_t, 2>, 3>{
201 std::array<std::uint8_t, 2>{0x81, 0x00},
202 std::array<std::uint8_t, 2>{0x88, 0xA8},
203 std::array<std::uint8_t, 2>{0x91, 0x00}})
206 frame.push_back(tpid[0]);
207 frame.push_back(tpid[1]);
208 frame.push_back(0x00);
209 frame.push_back(0x01);
216TEST_F(UtilMoreTests, SkipVlanTagsStopsAfterSupportedTag)
220 frame.insert(
frame.end(), {0x81, 0x00, 0xC0, 0x00});
227TEST_F(UtilMoreTests, SkipVlanTagsHandlesShortFrame)
233TEST_F(UtilMoreTests, SkipVlanTagsHandlesIncompleteVlanHeader)
243TEST_F(UtilMoreTests, String2MacHandlesBoundaryValues)
247 (
MacAddress{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}));
251 (
MacAddress{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}));
255TEST_F(UtilMoreTests, String2MacRejectsWrongDelimiterPosition)
261TEST_F(UtilMoreTests, String2MacRejectsWhitespace)
266TEST_F(UtilMoreTests, Mac2StringRejectsInvalidLength)
268 const std::array<std::uint8_t, 5> shortMac{1, 2, 3, 4, 5};
273TEST_F(UtilMoreTests, String2IpHandlesExactAndExtendedInput)
275 EXPECT_EQ(
String2Ip(std::array<std::uint8_t, 4>{192, 168, 1, 42}),
"192.168.1.42");
277 const std::array<std::uint8_t, 6> extended{192, 168, 1, 42, 0xAA, 0xBB};
278 EXPECT_EQ(
String2Ip(extended),
"192.168.1.42");
281TEST_F(UtilMoreTests, DecodeBytesPreservesNonPaddedData)
283 const std::vector<std::uint8_t> data{
'a',
'b',
'c'};
289TEST_F(UtilMoreTests, DecodeBytesHandlesAllNuls)
291 const std::vector<std::uint8_t> data(8U, 0);
Invalid MAC address format.
Time-limited-operation helper.
bool TimedOut() const
Whether the countdown has elapsed.
std::chrono::duration< double > Remaining() const
Time left before the countdown elapses.
Declares exceptions and error types used by the PROFINET IO controller stack.
std::string Hex2(std::uint8_t value)
Format an 8-bit unsigned integer as a 2-digit hexadecimal string.
TEST_F(AlarmListenerTests, InitializesWithEndpoint)
MacAddress GetInterfaceMac(const std::string &interface)
Get the MAC address assigned to a network interface.
std::vector< std::uint8_t > ToVec(const std::string &input)
Convert a string into a vector of raw bytes.
std::string String2Ip(std::span< const std::uint8_t > ipBytes)
Format raw IPv4 address bytes as a dotted string.
std::array< std::uint8_t, macAddressLength > MacAddress
A 6-byte Ethernet MAC address.
std::array< std::uint8_t, 4 > Ip2String(const std::string &ipStr)
Parse a dotted-decimal IPv4 address string.
std::filesystem::path GetExecutableDirectory()
Retrieves the absolute directory path of the currently running executable.
MacAddress String2Mac(const std::string &macStr)
Parse a colon-separated MAC address string.
std::size_t SkipVlanTags(std::span< const std::uint8_t > frame) noexcept
Return the byte offset of the real EtherType in a raw Ethernet frame.
constexpr int macAddressLength
Constant lenght of a mac address.
std::string ToHex(const std::uint8_t *data, std::size_t len)
Hex-encode a byte buffer.
std::string Hex4(std::uint16_t value)
Format a 16-bit unsigned integer as a 4-digit hexadecimal string.
std::vector< std::uint8_t > Bytes
Generic byte buffer alias used throughout the library for raw wire data.
std::string Mac2String(const MacAddress &mac)
Format a MAC address as a colon-separated string.
std::string DecodeBytes(const std::uint8_t *data, std::size_t len)
Decode bytes to a UTF-8 string, stripping trailing NUL bytes.
PROFINET protocol wire-format structures and serialization helpers.
Declares the portable IPv4 UDP socket implementation.
Declares Linux Ethernet, addressing, timing, and utility helpers used by the PROFINET stack.