Skip to content

Conversation

marenges
Copy link
Contributor

Added unit tests for ble_bas service

@marenges marenges added this to the v0.8.0 milestone Aug 22, 2025
@marenges marenges requested review from a team as code owners August 22, 2025 08:13
@marenges marenges self-assigned this Aug 22, 2025
Copy link

You can find the documentation preview for this PR here.

@marenges marenges force-pushed the ble_bas_unittest branch 2 times, most recently from bc3f68a to 6b6e791 Compare August 22, 2025 08:40
@eivindj-nordic eivindj-nordic removed this from the v0.8.0 milestone Aug 26, 2025
@marenges marenges force-pushed the ble_bas_unittest branch 3 times, most recently from a353f5d to 7d114c2 Compare August 26, 2025 13:43
@eivindj-nordic eivindj-nordic added this to the v0.9.0 milestone Aug 27, 2025
@lemrey lemrey removed this from the v0.9.0 milestone Sep 8, 2025
@lemrey
Copy link
Contributor

lemrey commented Sep 8, 2025

No milestone required for tests

Copy link
Contributor

@lemrey lemrey left a comment

Choose a reason for hiding this comment

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

This looks good but I have an important comment.

We should not try to peek into or manually modify struct ble_bas.
In general that's only used for initial configuration (which may not be the best idea). Afterwards the user is meant to use only the API to interact with the service. So we can't really assume that the values in there have to be set to a certain value, only that the API returns the correct value. Also, we shouldn't manipulate that struct in our tests to put the library in a given state, rather, we should simulate input to the library via BLE events, to confirm that the library is in a certain state (by using API calls).

__cmock_sd_ble_gatts_hvx_ExpectAnyArgsAndReturn(NRF_ERROR_INVALID_STATE);
ret = ble_bas_battery_level_update(&ble_bas, conn_handle, battery_level);
TEST_ASSERT_EQUAL(-EPIPE, ret);
TEST_ASSERT_EQUAL(battery_level, ble_bas.battery_level);
Copy link
Contributor

Choose a reason for hiding this comment

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

We shouldn't test this (you are testing inside ble_bas)

TEST_ASSERT_EQUAL(BLE_GATT_HVX_NOTIFICATION, p_hvx_params->type);
TEST_ASSERT_EQUAL(0, p_hvx_params->offset);
TEST_ASSERT_EQUAL(sizeof(uint8_t), *(p_hvx_params->p_len));
TEST_ASSERT_EQUAL(ble_bas.battery_level, *(uint8_t *)(p_hvx_params->p_data));
Copy link
Contributor

Choose a reason for hiding this comment

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

and here

/* Battery level hasn't change 'Nothing to do' */
ret = ble_bas_battery_level_update(&ble_bas, conn_handle, battery_level);
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(battery_level, ble_bas.battery_level);
Copy link
Contributor

Choose a reason for hiding this comment

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

and here

Comment on lines 161 to 163
TEST_ASSERT_EQUAL(SERVICE_HANDLE, ble_bas.service_handle);
TEST_ASSERT_EQUAL(VALUE_HANDLE, ble_bas.battery_level_handles.value_handle);
TEST_ASSERT_EQUAL(REPORT_REF_HANDLE, ble_bas.report_ref_handle);
Copy link
Contributor

Choose a reason for hiding this comment

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

You can't test these like that-- but you can try to call some API that would pass these values as a parameter to a SoftDevice call to verify that they were set as expected during ble_bas_init()

Copy link
Contributor

Choose a reason for hiding this comment

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

For example ble_bas_battery_level_notify() passes the field battery_level_handles.value_handle to the sd_ble_gatts_hvx() function

ret = ble_bas_init(&ble_bas, &bas_cfg);
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(SERVICE_HANDLE, ble_bas.service_handle);
TEST_ASSERT_EQUAL(VALUE_HANDLE, ble_bas.battery_level_handles.value_handle);
Copy link
Contributor

Choose a reason for hiding this comment

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

Here too, you can call the ble_bas_battery_level_notify() function to see that the hvx parameters have the correct handle for the value.

Comment on lines 354 to 359
/* Change battery level, and ble_bas should update but not notify */
battery_level = 42;
__cmock_sd_ble_gatts_value_set_ExpectAnyArgsAndReturn(NRF_SUCCESS);
ret = ble_bas_battery_level_update(&ble_bas, conn_handle, battery_level);
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(battery_level, ble_bas.battery_level);
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of accepting any arguments to sd_ble_gatts_value_set() you should check that the implementation is passing the value that the user provided when calling ble_bas_battery_level_updated(). The implementation may pass one value to sd_ble_gatts_value_set() and a set different value in ble_bas.battery_level (due to a bug).

@marenges marenges force-pushed the ble_bas_unittest branch 2 times, most recently from 2eba186 to 9e7f915 Compare September 30, 2025 10:36
#include "ble_gatts.h"
#include "cmock_ble_gatts.h"

#define SERVICE_HANDLE 0x1234
Copy link
Contributor

Choose a reason for hiding this comment

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

The alignment here could be improved a bit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see that the alignment is different in my editor. It seems like tabsize is set to 4 in this PR

#define REPORT_REF_HANDLE 0xF8EE
#define INVALID_HANDLE 0xFFFF

BLE_BAS_DEF(ble_bas);
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a newline under this line.

static uint8_t battery_level;
static int evt_handler_called;
static int hvx_stub_called;
static struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

Add some space in between these structs.

bas_cfg.can_notify = false;
bas_init(&bas_cfg);

/* Battery level hasn't change 'Nothing to do' */
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/* Battery level hasn't change 'Nothing to do' */
/* Battery level hasn't changed 'Nothing to do' */

{
memset(&ble_bas, 0, sizeof(ble_bas));
evt_handler_called = false;
battery_level = 55;
Copy link
Contributor

Choose a reason for hiding this comment

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

If 55 is a default/reference value, maybe it can be a macro?

Added unit tests for ble_bas service

Signed-off-by: Martin Engesvold <[email protected]>
Co-authored-by: Andreas Moltumyr <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants