@@ -143,7 +143,9 @@ static K_SEM_DEFINE(cloud_disconnected, 0, 1);
143143static K_SEM_DEFINE (cloud_connected , 0 , 1 ) ;
144144static K_SEM_DEFINE (data_sent , 0 , 1 ) ;
145145static K_SEM_DEFINE (cloud_module_response_recv_sem , 0 , 1 ) ;
146+ static K_SEM_DEFINE (storage_batch_closed , 0 , 1 ) ;
146147static struct cloud_msg last_shadow_response ;
148+ static struct storage_msg last_storage_msg ;
147149
148150static nrf_provisioning_event_cb_t handler ;
149151
@@ -248,12 +250,13 @@ static void setup_cloud_and_passthrough(void)
248250 };
249251
250252 /* Connect to cloud */
251- zbus_chan_pub (& NETWORK_CHAN , & network_msg , K_NO_WAIT );
253+ err = zbus_chan_pub (& NETWORK_CHAN , & network_msg , K_SECONDS (1 ));
254+ TEST_ASSERT_EQUAL (0 , err );
252255 err = k_sem_take (& cloud_connected , K_SECONDS (WAIT_TIMEOUT ));
253256 TEST_ASSERT_EQUAL (0 , err );
254257
255258 /* Enable passthrough mode */
256- err = zbus_chan_pub (& STORAGE_CHAN , & passthrough_msg , K_NO_WAIT );
259+ err = zbus_chan_pub (& STORAGE_CHAN , & passthrough_msg , K_SECONDS ( 1 ) );
257260 TEST_ASSERT_EQUAL (0 , err );
258261 k_sleep (K_MSEC (PROCESSING_DELAY_MS ));
259262}
@@ -281,8 +284,13 @@ static void cloud_chan_cb(const struct zbus_channel *chan)
281284 status == CLOUD_SHADOW_RESPONSE_DELTA ) {
282285 memcpy (& last_shadow_response , cloud_msg , sizeof (struct cloud_msg ));
283286 k_sem_give (& cloud_module_response_recv_sem );
287+ }
288+ } else if (chan == & STORAGE_CHAN ) {
289+ const struct storage_msg * storage_msg = zbus_chan_const_msg (chan );
284290
285- printk ("cloud_chan_cb: received cloud message of type %d\n" , status );
291+ if (storage_msg -> type == STORAGE_BATCH_CLOSE ) {
292+ memcpy (& last_storage_msg , storage_msg , sizeof (struct storage_msg ));
293+ k_sem_give (& storage_batch_closed );
286294 }
287295 }
288296}
@@ -328,7 +336,7 @@ static void publish_and_assert(const struct zbus_channel *chan, const void *msg)
328336{
329337 int err ;
330338
331- err = zbus_chan_pub (chan , msg , K_NO_WAIT );
339+ err = zbus_chan_pub (chan , msg , K_SECONDS ( 1 ) );
332340 TEST_ASSERT_EQUAL (0 , err );
333341}
334342
@@ -404,6 +412,7 @@ void setUp(void)
404412 k_sem_reset (& cloud_connected );
405413 k_sem_reset (& data_sent );
406414 k_sem_reset (& cloud_module_response_recv_sem );
415+ k_sem_reset (& storage_batch_closed );
407416
408417 /* Set default return values */
409418 nrf_cloud_coap_location_send_fake .return_val = 0 ;
@@ -1322,6 +1331,115 @@ void test_location_cloud_request_wifi_data_excessive_ap_count(void)
13221331
13231332 /* Verify that nrf_cloud_coap_location_get was NOT called due to validation failure. */
13241333 TEST_ASSERT_EQUAL (0 , nrf_cloud_coap_location_get_fake .call_count );
1334+
1335+ /* 10 second sleep is needed to wait for the sleep in SEND_FATAL_ERROR to time out */
1336+ k_sleep (K_SECONDS (10 ));
1337+ }
1338+
1339+ /* Helper to get cloud into paused state (connected but network disconnected) */
1340+ static void setup_cloud_paused (void )
1341+ {
1342+ struct network_msg network_msg = {
1343+ .type = NETWORK_CONNECTED
1344+ };
1345+
1346+ /* Connect to cloud */
1347+ publish_and_assert (& NETWORK_CHAN , & network_msg );
1348+ wait_for_cloud_connected (K_SECONDS (WAIT_TIMEOUT ));
1349+ wait_for_processing ();
1350+
1351+ /* Disconnect network to enter paused state */
1352+ network_msg .type = NETWORK_DISCONNECTED ;
1353+
1354+ publish_and_assert (& NETWORK_CHAN , & network_msg );
1355+ wait_for_cloud_disconnected (K_SECONDS (WAIT_TIMEOUT ));
1356+ wait_for_processing ();
1357+ }
1358+
1359+ /* Helper to wait for storage batch close message */
1360+ static void wait_for_storage_batch_close (k_timeout_t timeout )
1361+ {
1362+ int err ;
1363+
1364+ err = k_sem_take (& storage_batch_closed , timeout );
1365+ TEST_ASSERT_EQUAL (0 , err );
1366+ }
1367+
1368+ void test_storage_batch_available_when_paused_should_close_session (void )
1369+ {
1370+ struct storage_msg batch_available = {
1371+ .type = STORAGE_BATCH_AVAILABLE ,
1372+ .data_len = 5 ,
1373+ .session_id = 0x12345678 ,
1374+ .more_data = false,
1375+ };
1376+
1377+ setup_cloud_paused ();
1378+
1379+ publish_and_assert (& STORAGE_CHAN , & batch_available );
1380+ wait_for_processing ();
1381+
1382+ wait_for_storage_batch_close (K_SECONDS (WAIT_TIMEOUT ));
1383+
1384+ TEST_ASSERT_EQUAL (STORAGE_BATCH_CLOSE , last_storage_msg .type );
1385+ TEST_ASSERT_EQUAL (batch_available .session_id , last_storage_msg .session_id );
1386+ }
1387+
1388+ void test_storage_batch_empty_when_paused_should_close_session (void )
1389+ {
1390+ struct storage_msg batch_empty = {
1391+ .type = STORAGE_BATCH_EMPTY ,
1392+ .session_id = 0x87654321 ,
1393+ };
1394+
1395+ setup_cloud_paused ();
1396+
1397+ publish_and_assert (& STORAGE_CHAN , & batch_empty );
1398+ wait_for_processing ();
1399+
1400+ wait_for_storage_batch_close (K_SECONDS (WAIT_TIMEOUT ));
1401+
1402+ TEST_ASSERT_EQUAL (STORAGE_BATCH_CLOSE , last_storage_msg .type );
1403+ TEST_ASSERT_EQUAL (batch_empty .session_id , last_storage_msg .session_id );
1404+ }
1405+
1406+ void test_storage_batch_error_when_paused_should_close_session (void )
1407+ {
1408+ struct storage_msg batch_error = {
1409+ .type = STORAGE_BATCH_ERROR ,
1410+ .session_id = 0xAABBCCDD ,
1411+ };
1412+
1413+ setup_cloud_paused ();
1414+
1415+ publish_and_assert (& STORAGE_CHAN , & batch_error );
1416+ wait_for_processing ();
1417+
1418+ wait_for_storage_batch_close (K_SECONDS (WAIT_TIMEOUT ));
1419+
1420+ TEST_ASSERT_EQUAL (STORAGE_BATCH_CLOSE , last_storage_msg .type );
1421+ TEST_ASSERT_EQUAL (batch_error .session_id , last_storage_msg .session_id );
1422+ }
1423+
1424+ void test_storage_batch_busy_when_paused_should_handle (void )
1425+ {
1426+ struct storage_msg batch_busy = {
1427+ .type = STORAGE_BATCH_BUSY ,
1428+ .session_id = 0xDDCCBBAA ,
1429+ };
1430+
1431+ setup_cloud_paused ();
1432+
1433+ publish_and_assert (& STORAGE_CHAN , & batch_busy );
1434+ wait_for_processing ();
1435+
1436+ /* BUSY message should be handled but not close the session
1437+ * Give some time to ensure no close message is sent.
1438+ */
1439+ k_sleep (K_MSEC (PROCESSING_DELAY_MS ));
1440+
1441+ /* Verify no close message was sent */
1442+ TEST_ASSERT_EQUAL (0 , k_sem_count_get (& storage_batch_closed ));
13251443}
13261444
13271445/* This is required to be added to each test. That is because unity's
0 commit comments