mirror of
https://github.com/esphome/esphome.git
synced 2026-10-21 21:36:14 +00:00
A read cuts a datagram longer than the buffer to fit, so a 600 byte datagram arrived as a valid looking 508 byte packet. The buffer is now one byte longer, and a read that fills it is dropped. The split packet test also checks the bytes joined in the copy buffer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
77 lines
2.5 KiB
C++
77 lines
2.5 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
#include "esphome/components/udp/packet_interface/udp_packet_interface.h"
|
|
|
|
#ifdef USE_NETWORK
|
|
|
|
namespace esphome::udp::testing {
|
|
|
|
// Copies a packet into a vector, for comparing in tests
|
|
static std::vector<uint8_t> to_vector(const esphome::packet_interface::PacketBuffer &data) {
|
|
std::vector<uint8_t> result(data.size());
|
|
data.copy_to(result.data(), result.size());
|
|
return result;
|
|
}
|
|
|
|
using packet_interface::PacketBuffer;
|
|
using packet_interface::PacketMetaData;
|
|
using Packet = std::vector<uint8_t>;
|
|
|
|
class TestUdp : public UdpPacketInterface {
|
|
public:
|
|
explicit TestUdp(UDPComponent *udp) : UdpPacketInterface(udp, this->tx_buffer_storage) {
|
|
this->set_max_packet_size(8);
|
|
this->add_packet_interface_listener(
|
|
[this](const PacketBuffer &data, const PacketMetaData &) { this->received.push_back(to_vector(data)); });
|
|
}
|
|
using UdpPacketInterface::receive_;
|
|
|
|
// The base class only keeps the pointer, so the storage can be a member set up after it
|
|
uint8_t tx_buffer_storage[8]{};
|
|
std::vector<Packet> received;
|
|
};
|
|
|
|
// The udp component is not set up, so it has no destinations and a send does nothing
|
|
class UdpPacketInterfaceTest : public ::testing::Test {
|
|
protected:
|
|
UDPComponent udp_;
|
|
TestUdp link_{&this->udp_};
|
|
};
|
|
|
|
TEST_F(UdpPacketInterfaceTest, ReceivedPacketsUpToMaxPassedUp) {
|
|
Packet packet{1, 2, 3, 4, 5, 6, 7, 8};
|
|
this->link_.receive_(packet);
|
|
Packet oversized{1, 2, 3, 4, 5, 6, 7, 8, 9};
|
|
this->link_.receive_(oversized);
|
|
EXPECT_EQ(this->link_.received, std::vector<Packet>{packet});
|
|
}
|
|
|
|
TEST_F(UdpPacketInterfaceTest, SendsContiguousAndSplitPackets) {
|
|
this->link_.setup();
|
|
Packet packet{1, 2, 3, 4};
|
|
EXPECT_TRUE(this->link_.send_to_interface(PacketBuffer(packet), {}));
|
|
uint8_t header = 0;
|
|
PacketBuffer body(packet);
|
|
EXPECT_TRUE(this->link_.send_to_interface(PacketBuffer(&header, 1, &body, nullptr, 0), {}));
|
|
// A packet split across buffers is joined in the copy buffer before it is sent
|
|
const auto *storage = this->link_.tx_buffer_storage;
|
|
EXPECT_EQ(Packet(storage, storage + 5), (Packet{0, 1, 2, 3, 4}));
|
|
}
|
|
|
|
TEST_F(UdpPacketInterfaceTest, OversizedPacketNotSent) {
|
|
this->link_.setup();
|
|
Packet packet{1, 2, 3, 4, 5, 6, 7, 8, 9};
|
|
EXPECT_FALSE(this->link_.send_to_interface(PacketBuffer(packet), {}));
|
|
uint8_t header = 0;
|
|
Packet body_data{1, 2, 3, 4, 5, 6, 7, 8};
|
|
PacketBuffer body(body_data);
|
|
EXPECT_FALSE(this->link_.send_to_interface(PacketBuffer(&header, 1, &body, nullptr, 0), {}));
|
|
}
|
|
|
|
} // namespace esphome::udp::testing
|
|
|
|
#endif
|