Skip to content

Commit dc14833

Browse files
zgrigoryanandy31415Copilot
authored
Increase unit test code coverage of ble/ by 9.4% (project-chip#39663)
* Add unit tests for BLEEndPoint.cpp * move endpoint-specific tests into TestBleEndPoint.cpp * Remove redundant tests * Update to handle cases when is not of pointer type * Update reinterpret_cast to handle cases when BLE_CONNECTION_OBJECT is not of pointer type * Make BLE test connection handle generation portable for pointer/integer types * Refactor BLE endpoint test to use inline ASSERT_EQ for init functions Co-authored-by: Andrei Litvin <[email protected]> * Replace magic numbers with named constants in TestBleEndPoint (per review suggestion) * Remove double white space in TestBleLayer.cpp * Resolve CI Linux build fail * Resolve TEST_F nesting issue and restore build * Address Gemini comment about mBleTransport not being used * Update src/ble/tests/TestBleEndPoint.cpp Co-authored-by: Copilot <[email protected]> * Fix CI restyle fail * Fix CI restyle fail * Fix CI restyle fail * Clean up: remove named constant argument for consistency --------- Co-authored-by: Andrei Litvin <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent a208a88 commit dc14833

File tree

3 files changed

+244
-0
lines changed

3 files changed

+244
-0
lines changed

src/ble/tests/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ chip_test_suite("tests") {
2121
output_name = "libBleLayerTests"
2222

2323
test_sources = [
24+
"TestBleEndPoint.cpp",
2425
"TestBleErrorStr.cpp",
2526
"TestBleLayer.cpp",
2627
"TestBleUUID.cpp",

src/ble/tests/TestBleEndPoint.cpp

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
#include <cstdint>
2+
#include <type_traits>
3+
#include <utility>
4+
5+
#include <pw_unit_test/framework.h>
6+
7+
#include <lib/core/CHIPError.h>
8+
#include <lib/support/CHIPMem.h>
9+
#include <lib/support/DLLUtil.h>
10+
#include <lib/support/logging/CHIPLogging.h>
11+
#include <platform/CHIPDeviceLayer.h>
12+
#include <system/SystemLayer.h>
13+
#include <system/SystemPacketBuffer.h>
14+
15+
#include <ble/BleApplicationDelegate.h>
16+
#include <ble/BleLayer.h>
17+
#include <ble/BleLayerDelegate.h>
18+
#include <ble/BlePlatformDelegate.h>
19+
20+
namespace { // === test‑only constants ===
21+
constexpr uint16_t kBleTestMtu = 247;
22+
constexpr uint16_t kBleTestFragmentSize = 100;
23+
constexpr uint16_t kBleTestScratchBufLen = 16;
24+
} // namespace
25+
26+
namespace chip {
27+
namespace Ble {
28+
29+
DLL_EXPORT BleLayerDelegate * mBleTransport = nullptr;
30+
31+
static unsigned int gConnCounter = 0;
32+
template <typename T>
33+
static inline typename std::enable_if<std::is_integral<T>::value, T>::type MakeConnObj(unsigned int n)
34+
{
35+
return static_cast<T>(n);
36+
}
37+
template <typename T>
38+
static inline typename std::enable_if<std::is_pointer<T>::value, T>::type MakeConnObj(unsigned int n)
39+
{
40+
return reinterpret_cast<T>(static_cast<uintptr_t>(n));
41+
}
42+
43+
static BLE_CONNECTION_OBJECT NextConnectionObject()
44+
{
45+
return MakeConnObj<BLE_CONNECTION_OBJECT>(++gConnCounter);
46+
}
47+
48+
/* Test fixture for testing BLEEndPoint behavior */
49+
class TestBleEndPoint : public ::testing::Test, public BleApplicationDelegate, public BleLayerDelegate, public BlePlatformDelegate
50+
{
51+
public:
52+
static void SetUpTestSuite()
53+
{
54+
ASSERT_EQ(Platform::MemoryInit(), CHIP_NO_ERROR);
55+
ASSERT_EQ(DeviceLayer::SystemLayer().Init(), CHIP_NO_ERROR);
56+
}
57+
static void TearDownTestSuite()
58+
{
59+
DeviceLayer::SystemLayer().Shutdown();
60+
Platform::MemoryShutdown();
61+
}
62+
void SetUp() override
63+
{
64+
CHIP_ERROR err = mBleLayer.Init(/* platformDelegate */ this, /* appDelegate */ this, &DeviceLayer::SystemLayer());
65+
ASSERT_EQ(err, CHIP_NO_ERROR);
66+
mBleLayer.mBleTransport = this;
67+
mBleTransport = this;
68+
ResetCounters();
69+
}
70+
void TearDown() override
71+
{
72+
mBleTransport = nullptr;
73+
mBleLayer.Shutdown();
74+
}
75+
76+
BLEEndPoint * CreateCentralEndPoint()
77+
{
78+
BLEEndPoint * ep = nullptr;
79+
BLE_CONNECTION_OBJECT connObj = NextConnectionObject();
80+
CHIP_ERROR err = mBleLayer.NewBleEndPoint(&ep, connObj, kBleRole_Central, /* autoClose */ true);
81+
EXPECT_EQ(err, CHIP_NO_ERROR);
82+
EXPECT_NE(ep, nullptr);
83+
return ep;
84+
}
85+
86+
CHIP_ERROR CompleteCentralHandshake(BLEEndPoint * ep)
87+
{
88+
ReturnErrorOnFailure(ep->StartConnect());
89+
90+
bool ok = mBleLayer.HandleWriteConfirmation(mPendingConnObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_1_UUID);
91+
VerifyOrReturnError(ok, CHIP_ERROR_INTERNAL);
92+
93+
ok = mBleLayer.HandleSubscribeComplete(mPendingConnObj, &CHIP_BLE_SVC_ID, &CHIP_BLE_CHAR_2_UUID);
94+
VerifyOrReturnError(ok, CHIP_ERROR_INTERNAL);
95+
96+
BleTransportCapabilitiesResponseMessage resp;
97+
resp.mSelectedProtocolVersion = CHIP_BLE_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION;
98+
resp.mFragmentSize = kBleTestFragmentSize;
99+
resp.mWindowSize = BLE_MAX_RECEIVE_WINDOW_SIZE;
100+
101+
System::PacketBufferHandle buf = System::PacketBufferHandle::New(kBleTestScratchBufLen);
102+
ReturnErrorOnFailure(resp.Encode(buf));
103+
ReturnErrorOnFailure(ep->Receive(std::move(buf)));
104+
return CHIP_NO_ERROR;
105+
}
106+
107+
protected:
108+
void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT) override {}
109+
void OnBleConnectionComplete(BLEEndPoint *) override {}
110+
void OnBleConnectionError(CHIP_ERROR) override {}
111+
void OnEndPointConnectComplete(BLEEndPoint * endPoint, CHIP_ERROR err) override
112+
{
113+
mLastEndPoint = endPoint;
114+
mLastConnectErr = err;
115+
mConnectCompleteCalls++;
116+
EXPECT_EQ(err, CHIP_NO_ERROR);
117+
}
118+
void OnEndPointMessageReceived(BLEEndPoint * endPoint, System::PacketBufferHandle && msg) override {}
119+
void OnEndPointConnectionClosed(BLEEndPoint * endPoint, CHIP_ERROR err) override
120+
{
121+
mLastCloseErr = err;
122+
mConnectionClosedCalls++;
123+
}
124+
CHIP_ERROR SetEndPoint(BLEEndPoint * endPoint) override
125+
{
126+
// This is called when a peripheral-side handshake is completed (on receiving Subscribe request).
127+
// We save the endpoint so we can test it in the future
128+
mLastEndPoint = endPoint;
129+
return CHIP_NO_ERROR;
130+
}
131+
132+
uint16_t GetMTU(BLE_CONNECTION_OBJECT) const override { return kBleTestMtu; }
133+
CHIP_ERROR SubscribeCharacteristic(BLE_CONNECTION_OBJECT, const ChipBleUUID *, const ChipBleUUID *) override
134+
{
135+
return CHIP_NO_ERROR;
136+
}
137+
CHIP_ERROR UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT, const ChipBleUUID *, const ChipBleUUID *) override
138+
{
139+
return CHIP_NO_ERROR;
140+
}
141+
CHIP_ERROR CloseConnection(BLE_CONNECTION_OBJECT) override { return CHIP_NO_ERROR; }
142+
CHIP_ERROR SendWriteRequest(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID *, const ChipBleUUID *,
143+
System::PacketBufferHandle buf) override
144+
{
145+
mPendingConnObj = connObj;
146+
mLastWriteBuf = buf.Retain();
147+
return CHIP_NO_ERROR;
148+
}
149+
CHIP_ERROR SendIndication(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID *, const ChipBleUUID *,
150+
System::PacketBufferHandle) override
151+
{
152+
mPendingConnObj = connObj;
153+
return CHIP_NO_ERROR;
154+
}
155+
CHIP_ERROR mLastConnectErr = CHIP_NO_ERROR;
156+
CHIP_ERROR mLastCloseErr = CHIP_NO_ERROR;
157+
void ResetCounters()
158+
{
159+
mConnectCompleteCalls = 0;
160+
mConnectionClosedCalls = 0;
161+
mLastEndPoint = nullptr;
162+
mLastWriteBuf = nullptr;
163+
mPendingConnObj = BLE_CONNECTION_UNINITIALIZED;
164+
mLastConnectErr = CHIP_NO_ERROR;
165+
mLastCloseErr = CHIP_NO_ERROR;
166+
}
167+
168+
// Fixture state
169+
BleLayer mBleLayer;
170+
BLEEndPoint * mLastEndPoint = nullptr; // last endpoint delivered via delegate
171+
System::PacketBufferHandle mLastWriteBuf; // last buffer captured from a Write request
172+
BLE_CONNECTION_OBJECT mPendingConnObj = BLE_CONNECTION_UNINITIALIZED; // last connObj used in a platform callback
173+
int mConnectCompleteCalls = 0;
174+
int mConnectionClosedCalls = 0;
175+
};
176+
177+
/* ==================== Test Cases ==================== */
178+
179+
// Verify capability request is formed correctly on connect
180+
TEST_F(TestBleEndPoint, StartConnectSendsCapabilitiesRequest)
181+
{
182+
BLEEndPoint * ep = CreateCentralEndPoint();
183+
ASSERT_NE(ep, nullptr);
184+
EXPECT_EQ(ep->StartConnect(), CHIP_NO_ERROR);
185+
ASSERT_FALSE(mLastWriteBuf.IsNull());
186+
BleTransportCapabilitiesRequestMessage req;
187+
ASSERT_EQ(BleTransportCapabilitiesRequestMessage::Decode(mLastWriteBuf, req), CHIP_NO_ERROR);
188+
EXPECT_EQ(req.mWindowSize, BLE_MAX_RECEIVE_WINDOW_SIZE);
189+
EXPECT_EQ(req.mMtu, static_cast<uint16_t>(kBleTestMtu));
190+
uint8_t majorSupported = req.mSupportedProtocolVersions[0] & 0x0F; // lower 4 bits of first byte
191+
EXPECT_EQ(majorSupported, static_cast<uint8_t>(CHIP_BLE_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION));
192+
193+
ep->Abort(); // Abort the connection to clean up (since we didn't finish the handshake here)
194+
}
195+
196+
// Confirm connect completion triggers delegate callback
197+
TEST_F(TestBleEndPoint, HandleConnectCompleteTriggersCallback)
198+
{
199+
BLEEndPoint * ep = CreateCentralEndPoint();
200+
ASSERT_NE(ep, nullptr);
201+
ASSERT_EQ(CompleteCentralHandshake(ep), CHIP_NO_ERROR);
202+
EXPECT_EQ(mConnectCompleteCalls, 1);
203+
EXPECT_EQ(mConnectionClosedCalls, 0);
204+
EXPECT_EQ(ep->Send(System::PacketBufferHandle::New(0)), CHIP_NO_ERROR);
205+
ep->Abort();
206+
}
207+
208+
// Ensure connection closure invokes proper cleanup callback
209+
TEST_F(TestBleEndPoint, CloseFiresConnectionClosedCallback)
210+
{
211+
BLEEndPoint * ep = CreateCentralEndPoint();
212+
ASSERT_NE(ep, nullptr);
213+
ASSERT_EQ(CompleteCentralHandshake(ep), CHIP_NO_ERROR);
214+
ep->Close();
215+
EXPECT_EQ(mConnectionClosedCalls, 1);
216+
}
217+
218+
} // namespace Ble
219+
} // namespace chip

src/ble/tests/TestBleLayer.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ class TestBleLayer : public BleLayer,
176176
{
177177
return CHIP_NO_ERROR;
178178
}
179+
179180
CHIP_ERROR SendWriteRequest(BLE_CONNECTION_OBJECT, const ChipBleUUID *, const ChipBleUUID *, PacketBufferHandle) override
180181
{
181182
return CHIP_NO_ERROR;
@@ -413,6 +414,29 @@ TEST_F(TestBleLayer, ExceedBleConnectionEndPointLimit)
413414
EXPECT_FALSE(HandleWriteReceivedCapabilitiesRequest(connObj));
414415
}
415416

417+
namespace {
418+
BLEEndPoint * MakeCentralEndPoint(TestBleLayer & ble, BLE_CONNECTION_OBJECT connObj)
419+
{
420+
BLEEndPoint * ep = nullptr;
421+
EXPECT_EQ(ble.NewBleEndPoint(&ep, connObj, kBleRole_Central, true), CHIP_NO_ERROR);
422+
EXPECT_NE(ep, nullptr);
423+
424+
return ep;
425+
}
426+
} // namespace
427+
428+
TEST_F(TestBleLayer, StartConnectFailsIfCalledTwice)
429+
{
430+
const auto connObj = GetConnectionObject();
431+
BLEEndPoint * ep = MakeCentralEndPoint(*this, connObj);
432+
ASSERT_NE(ep, nullptr);
433+
434+
ASSERT_EQ(ep->StartConnect(), CHIP_NO_ERROR); // first call OK
435+
EXPECT_EQ(ep->StartConnect(), CHIP_ERROR_INCORRECT_STATE); // second should fail
436+
437+
ep->Abort();
438+
}
439+
416440
// This test checks that the BLE layer can handle a new connection
417441
// and that the connection complete callback is invoked.
418442
TEST_F(TestBleLayer, OnConnectionCompleteCallbackPath)

0 commit comments

Comments
 (0)