8000 Increase unit test code coverage of `ble/` by 1.9% by AniDashyan · Pull Request #39890 · project-chip/connectedhomeip · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Increase unit test code coverage of ble/ by 1.9% #39890

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/ble/BleLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
#include "BleUUID.h"

namespace chip {

namespace Test {
// Forward declaration of BleLayerTestAccess class tests to allow it to be friends with BleLayer
class BleLayerTestAccess;
} // namespace Test
namespace Ble {

/**
Expand Down Expand Up @@ -216,6 +221,7 @@ class BleTransportCapabilitiesResponseMessage
class DLL_EXPORT BleLayer
{
friend class BLEEndPoint;
friend class Test::BleLayerTestAccess;

public:
// Public data members:
Expand All @@ -224,7 +230,7 @@ class DLL_EXPORT BleLayer
kState_NotInitialized = 0,
kState_Initialized = 1,
kState_Disconnecting = 2
} mState; ///< [READ-ONLY] external access is deprecated, use IsInitialized() / IsBleClosing()
} mState; ///< [READ-ONLY] external access is deprecated, use IsInitialized() / IsBleClosing()

// This app state is not used by ble transport etc, it will be used by external ble implementation like Android
void * mAppState = nullptr;
Expand Down Expand Up @@ -355,6 +361,5 @@ class DLL_EXPORT BleLayer
static void OnConnectionComplete(void * appState, BLE_CONNECTION_OBJECT connObj);
static void OnConnectionError(void * appState, CHIP_ERROR err);
};

} /* namespace Ble */
} /* namespace chip */
2 changes: 2 additions & 0 deletions src/ble/tests/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ chip_test_suite("tests") {
"TestBtpEngine.cpp",
]

sources = [ "BleLayerTestAccess.h" ]

cflags = [ "-Wconversion" ]

public_deps = [
Expand Down
49 changes: 49 additions & 0 deletions src/ble/tests/BleLayerTestAccess.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
*
* Copyright (c) 2024 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <ble/Ble.h>
#include <ble/BleLayer.h>

namespace chip {
namespace Test {
/**
* @brief Class acts as an accessor to private methods of the BleLayer class without needing to give friend access to
* each individual test.
*/
class BleLayerTestAccess
{
public:
BleLayerTestAccess() = delete;
BleLayerTestAccess(Ble::BleLayer * layer) : mLayer(layer) {}

void SetConnectionDelegate(Ble::BleConnectionDelegate * delegate) { mLayer->mConnectionDelegate = delegate; }

// Wrapper for OnConnectionComplete private method
void CallOnConnectionComplete(void * appState, BLE_CONNECTION_OBJECT connObj)
{
mLayer->OnConnectionComplete(appState, connObj);
}

void CallOnConnectionError(void * appState, CHIP_ERROR err) { mLayer->OnConnectionError(appState, err); }

private:
Ble::BleLayer * mLayer = nullptr;
};
} // namespace Test
} // namespace chip
156 changes: 154 additions & 2 deletions src/ble/tests/TestBleLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <lib/core/CHIPError.h>
#include <lib/core/StringBuilderAdapters.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/SetupDiscriminator.h>
#include <lib/support/Span.h>
#include <lib/support/TypeTraits.h>
#include <lib/support/logging/CHIPLogging.h>
Expand All @@ -35,10 +36,13 @@

#define _CHIP_BLE_BLE_H
#include <ble/BleApplicationDelegate.h>
#include <ble/BleConnectionDelegate.h>
#include <ble/BleLayer.h>
#include <ble/BleLayerDelegate.h>
#include <ble/BlePlatformDelegate.h>

#include <ble/tests/BleLayerTestAccess.h>

namespace chip {
namespace Ble {

Expand All @@ -52,9 +56,12 @@ class TestBleLayer : public BleLayer,
private BleApplicationDelegate,
private BleLayerDelegate,
private BlePlatformDelegate,
public BleConnectionDelegate,
public ::testing::Test
{
public:
int mOnConnectionCompleteCount = 0;
int mOnConnectionErrorCount = 0;
static void SetUpTestSuite()
{
ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR);
Expand All @@ -69,6 +76,8 @@ class TestBleLayer : public BleLayer,

void SetUp() override
{
mOnConnectionCompleteCount = 0;
mOnConnectionErrorCount = 0;
ASSERT_EQ(Init(this, this, &DeviceLayer::SystemLayer()), CHIP_NO_ERROR);
mBleTransport = this;
}
Expand Down Expand Up @@ -122,8 +131,8 @@ class TestBleLayer : public BleLayer,
///
// Implementation of BleLayerDelegate

void OnBleConnectionComplete(BLEEndPoint * endpoint) override {}
void OnBleConnectionError(CHIP_ERROR err) override {}
void OnBleConnectionComplete(BLEEndPoint * endpoint) override { mOnConnectionCompleteCount++; }
void OnBleConnectionError(CHIP_ERROR err) override { mOnConnectionErrorCount++; }
void OnEndPointConnectComplete(BLEEndPoint * endPoint, CHIP_ERROR err) override {}
void OnEndPointMessageReceived(BLEEndPoint * endPoint, System::PacketBufferHandle && msg) override {}
void OnEndPointConnectionClosed(BLEEndPoint * endPoint, CHIP_ERROR err) override {}
Expand Down Expand Up @@ -151,6 +160,22 @@ class TestBleLayer : public BleLayer,
return CHIP_NO_ERROR;
}

///
// Implementation of BleConnectionDelegate
void NewConnection(BleLayer * bleLayer, void * appState, const SetupDiscriminator & connDiscriminator) override {}
void NewConnection(BleLayer * bleLayer, void * appState, BLE_CONNECTION_OBJECT connObj) override {}
CHIP_ERROR CancelConnection() override { return CHIP_NO_ERROR; }
CHIP_ERROR NewConnection(BleLayer * bleLayer, void * appState, const Span<const SetupDiscriminator> & discriminators,
OnConnectionByDiscriminatorsCompleteFunct onConnectionComplete,
OnConnectionErrorFunct onConnectionError) override
{
if (discriminators.empty())
{
return CHIP_ERROR_INVALID_ARGUMENT;
}
return CHIP_NO_ERROR;
}

private:
unsigned int mNumConnection = 0;
};
Expand Down Expand Up @@ -383,5 +408,132 @@ TEST_F(TestBleLayer, ExceedBleConnectionEndPointLimit)
EXPECT_FALSE(HandleWriteReceivedCapabilitiesRequest(connObj));
}

// Verify connection attempt fails when BleLayer is unitialized
TEST_F(TestBleLayer, NewBleConnectionByDiscriminatorsNotInitialized)
{
// Simulate BleLayer not being initialized by calling Shutdown
Shutdown();

// Create a list of discriminators
SetupDiscriminator discriminators[] = { SetupDiscriminator(), SetupDiscriminator() };
Span<const SetupDiscriminator> discriminatorsSpan(discriminators);

// Define success and error callbacks
auto * appState, uint16_t matchedLongDiscriminator, BLE_CONNECTION_OBJECT connObj) {};
auto * appState, CHIP_ERROR err) {};

EXPECT_EQ(NewBleConnectionByDiscriminators(discriminatorsSpan, this, OnSuccess, OnError), CHIP_ERROR_INCORRECT_STATE);
}

// Verify connection attempt fails when there is no BleConnectionDelegate
TEST_F(TestBleLayer, NewBleConnectionByDiscriminatorsNoConnectionDelegate)
{
// Set up the BleLayerTestAccess accessor class to manipulate the BleConnectionDelegate of BleLayer
chip::Test::BleLayerTestAccess access(this);
access.SetConnectionDelegate(nullptr);

SetupDiscriminator discriminators[] = { SetupDiscriminator(), SetupDiscriminator() };
Span<const SetupDiscriminator> discriminatorsSpan(discriminators);

auto * appState, uint16_t matchedLongDiscriminator, BLE_CONNECTION_OBJECT connObj) {};
auto * appState, CHIP_ERROR err) {};

EXPECT_EQ(NewBleConnectionByDiscriminators(discriminatorsSpan, this, OnSuccess, OnError), CHIP_ERROR_INCORRECT_STATE);
}

// Verify connection fails when Ble Transport Layer is missing
TEST_F(TestBleLayer, NewBleConnectionByDiscriminatorsNoBleTransportLayer)
{
chip::Test::BleLayerTestAccess access(this);
access.SetConnectionDelegate(this);
mBleTransport = nullptr;

SetupDiscriminator discriminators[] = { SetupDiscriminator(), SetupDiscriminator() };
Span<const SetupDiscriminator> discriminatorsSpan(discriminators);

auto * appState, uint16_t matchedLongDiscriminator, BLE_CONNECTION_OBJECT connObj) {};
auto * appState, CHIP_ERROR err) {};

EXPECT_EQ(NewBleConnectionByDiscriminators(discriminatorsSpan, this, OnSuccess, OnError), CHIP_ERROR_INCORRECT_STATE);
}

// Simulate successfull connection callback from delegate
TEST_F(TestBleLayer, NewConnectionByDiscriminatorsSuccess)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe consider adding a comment.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

{
chip::Test::BleLayerTestAccess access(this);
access.SetConnectionDelegate(this);

SetupDiscriminator discriminators[] = { SetupDiscriminator(), SetupDiscriminator() };
discriminators[0].SetLongValue(1234);
discriminators[1].SetLongValue(3333);
Span<const SetupDiscriminator> discriminatorsSpan(discriminators);

auto * appState, uint16_t matchedLongDiscriminator, BLE_CONNECTION_OBJECT connObj) {
BleLayer * testLayer = static_cast<BleLayer *>(appState);
chip::Test::BleLayerTestAccess tempAccess(testLayer);

tempAccess.CallOnConnectionComplete(appState, connObj);
};
auto * appState, CHIP_ERROR err) { FAIL() << "OnError should not be called in this test"; };
BleLayer * bleLayerState = this;

EXPECT_EQ(NewBleConnectionByDiscriminators(discriminatorsSpan, this, OnSuccess, OnError), CHIP_NO_ERROR);

// Simulate a successful connection by calling the success callback directly
OnSuccess(bleLayerState, discriminatorsSpan[0].GetLongValue(), GetConnectionObject());

// Verify that the success callback was called
EXPECT_EQ(mOnConnectionCompleteCount, 1);
EXPECT_EQ(mOnConnectionErrorCount, 0);
}

// Checks that the connection could not be established due to an error
TEST_F(TestBleLayer, NewConnectionByDiscriminatorsError)
{
chip::Test::BleLayerTestAccess access(this);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the chip:: prefix here and elsewhere in this PR? Is this not all inside namespace chip?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The chip:: prefix here is needed, because otherwise compiler identifies Test as pw::unit_test::internal::Test.


access.SetConnectionDelegate(this);

SetupDiscriminator discriminators[] = { SetupDiscriminator(), SetupDiscriminator() };
discriminators[0].SetLongValue(1234);
discriminators[1].SetLongValue(3333);
Span<const SetupDiscriminator> discriminatorsSpan(discriminators);

auto * appState, uint16_t matchedLongDiscriminator, BLE_CONNECTION_OBJECT connObj) {
FAIL() << "OnSuccess should not be called in this test";
};

auto * appState, CHIP_ERROR err) {
BleLayer * testLayer = static_cast<BleLayer *>(appState);
chip::Test::BleLayerTestAccess tempAccess(testLayer);

tempAccess.CallOnConnectionError(appState, err);
};
BleLayer * bleLayerState = this;

EXPECT_EQ(NewBleConnectionByDiscriminators(discriminatorsSpan, this, OnSuccess, OnError), CHIP_NO_ERROR);

// Call the error callback directly to simulate an error
OnError(bleLayerState, CHIP_ERROR_CONNECTION_ABORTED);

// Verify that the error callback was called
EXPECT_EQ(mOnConnectionCompleteCount, 0);
EXPECT_EQ(mOnConnectionErrorCount, 1);
}

// Connection attempt with empty list of discriminators
TEST_F(TestBleLayer, NewConnectionByDiscriminatorsEmptySpan)
{
chip::Test::BleLayerTestAccess access(this);
access.SetConnectionDelegate(this);

Span<const SetupDiscriminator> discriminatorsSpan;

auto * appState, uint16_t matchedLongDiscriminator, BLE_CONNECTION_OBJECT connObj) {};
auto * appState, CHIP_ERROR err) {};

EXPECT_NE(NewBleConnectionByDiscriminators(discriminatorsSpan, this, OnSuccess, OnError), CHIP_NO_ERROR);
}

}; // namespace Ble
}; // namespace chip
Loading
0