foxBMS - Unit Tests  1.5.0
The foxBMS Unit Tests API Documentation
test_bms.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2023, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file test_bms.c
44  * @author foxBMS Team
45  * @date 2020-04-01 (date of creation)
46  * @updated 2023-02-03 (date of last update)
47  * @version v1.5.0
48  * @ingroup UNIT_TEST_IMPLEMENTATION
49  * @prefix TEST
50  *
51  * @brief Tests for the bms driver implementation
52  */
53 
54 /*========== Includes =======================================================*/
55 #include "unity.h"
56 #include "Mockafe.h"
57 #include "Mockbal.h"
58 #include "Mockbattery_system_cfg.h"
59 #include "Mockcontactor.h"
60 #include "Mockdatabase.h"
61 #include "Mockdiag.h"
62 #include "Mockfassert.h"
63 #include "Mockimd.h"
64 #include "Mockinterlock.h"
65 #include "Mockled.h"
66 #include "Mockmeas.h"
67 #include "Mockos.h"
68 #include "Mockplausibility.h"
69 #include "Mocksoa.h"
70 
71 #include "sps_cfg.h"
72 
73 #include "bms.h"
74 #include "foxmath.h"
75 #include "test_assert_helper.h"
76 
77 #include <stdbool.h>
78 
79 /*========== Definitions and Implementations for Unit Test ==================*/
81 
84  .pConfigurationOfDiagnosisEntries = &diag_diagnosisIdConfiguration[0],
85  .numberOfFatalErrors = 0u,
86 };
87 
90 };
91 
93  /* String contactors configuration */
97  BS_STRING0,
98  CONT_PLUS,
104  BS_STRING0,
105  CONT_MINUS,
108  /* Precharge contactors configuration */
112  BS_STRING0,
116 };
117 
118 /*========== Setup and Teardown =============================================*/
119 void setUp(void) {
120 }
121 
122 void tearDown(void) {
123 }
124 
125 /*========== Test Cases =====================================================*/
126 #define NUM_PRECHARGE_TESTS 13
128 /*
129  * mock callback in order to provide custom values to current_tab
130  */
131 STD_RETURN_TYPE_e MockDATA_ReadBlock_Callback(void *pDataToReceiver, int num_calls) {
132  int32_t current = 0;
133  int32_t voltage_1 = 0;
134  int32_t voltage_2 = 0;
135 
136  /* determine a value depending on num_calls (has to be synchronized with test) */
137  switch (num_calls) {
138  case 0:
140  /* no current, no voltage difference --> expect OK */
141  current = 0;
142  voltage_1 = 0;
143  voltage_2 = 0;
144  break;
145  case 1:
147  /* INT32_MAX current, no voltage difference --> expect NOK */
148  current = INT32_MAX;
149  voltage_1 = 0;
150  voltage_2 = 0;
151  break;
152  case 2:
154  /* INT32_MIN current, no voltage difference --> expect NOK */
155  current = INT32_MIN;
156  voltage_1 = 0;
157  voltage_2 = 0;
158  break;
159  case 3:
161  /* no current, no voltage difference --> expect OK */
162  current = 0;
163  voltage_1 = INT32_MAX;
164  voltage_2 = INT32_MAX;
165  break;
166  case 4:
168  /* no current, no voltage difference --> expect OK */
169  current = 0;
170  voltage_1 = INT32_MIN;
171  voltage_2 = INT32_MIN;
172  break;
173  case 5:
175  /* no current, maximum voltage difference --> expect NOK */
176  current = 0;
177  voltage_1 = INT32_MAX;
178  voltage_2 = INT32_MIN;
179  break;
180  case 6:
182  /* no current, maximum voltage difference --> expect NOK */
183  current = 0;
184  voltage_1 = INT32_MIN;
185  voltage_2 = INT32_MAX;
186  break;
187  case 7:
189  /* current exactly at threshold, no voltage difference --> expect NOK */
191  voltage_1 = 0;
192  voltage_2 = 0;
193  break;
194  case 8:
196  /* no current, voltage difference exactly at threshold --> expect NOK */
197  current = 0;
199  voltage_2 = 0;
200  break;
201  case 9:
203  /* no current, voltage difference exactly at threshold --> expect NOK */
204  current = 0;
205  voltage_1 = 0;
207  break;
208  case 10:
210  /* current exactly 1 below threshold, no voltage difference --> expect OK */
212  voltage_1 = 0;
213  voltage_2 = 0;
214  break;
215  case 11:
217  /* no current, voltage difference exactly 1 below threshold --> expect OK */
218  current = 0;
219  voltage_1 = BMS_PRECHARGE_VOLTAGE_THRESHOLD_mV - 1;
220  voltage_2 = 0;
221  break;
222  case 12:
224  /* no current, voltage difference exactly 1 below threshold --> expect OK */
225  current = 0;
226  voltage_1 = 0;
227  voltage_2 = BMS_PRECHARGE_VOLTAGE_THRESHOLD_mV - 1;
228  break;
229  default:
230  TEST_FAIL_MESSAGE("DATA_ReadBlock_Callback was called too often");
231  }
232  /* ENTER HIGHEST CASE NUMBER IN EXPECT; checks whether all cases are used */
233  TEST_ASSERT_EQUAL_MESSAGE(12, (NUM_PRECHARGE_TESTS - 1), "Check code of stub. Something does not fit.");
234 
235  if (num_calls >= NUM_PRECHARGE_TESTS) {
236  TEST_FAIL_MESSAGE("This stub is fishy, prechargeExpectedResults is too short for the number of calls");
237  }
238 
239  /* cast to correct struct in order to properly write current and other values */
240  for (uint8_t s = 0; s < BS_NR_OF_STRINGS; s++) {
241  for (uint8_t testNumber = 0; testNumber < NUM_PRECHARGE_TESTS; testNumber++) {
242  prechargeExpectedResults[s][testNumber] = prechargeExpectedResults[0][testNumber];
243  }
244 
245  ((DATA_BLOCK_PACK_VALUES_s *)pDataToReceiver)->stringCurrent_mA[0] = current;
246  ((DATA_BLOCK_PACK_VALUES_s *)pDataToReceiver)->stringVoltage_mV[0] = voltage_1;
247  }
248  ((DATA_BLOCK_PACK_VALUES_s *)pDataToReceiver)->highVoltageBusVoltage_mV = voltage_2;
249 
250  return STD_OK;
251 }
252 
253 /**
254  * @brief Iterate over a callback that supplies various scenarios and check if they work as expected
255  * @details This function uses the callback #MockDATA_ReadBlock_Callback() in order to inject
256  * current tables and voltage tables into the returned database tables. The array
257  * #prechargeExpectedResults contains prepared return values against which the output
258  * of #TEST_BMS_CheckPrecharge() is compared.
259  */
261  /* tell CMock to use our callback */
262  DATA_Read1DataBlock_Stub(MockDATA_ReadBlock_Callback);
263 
265 
266  /* iterate until we have all covered cases from our stub processed */
267  for (uint8_t i = 0u; i < NUM_PRECHARGE_TESTS; i++) {
268  char buffer[30];
269  snprintf(buffer, 30, "Loop iteration %d.", i);
270  for (uint8_t s = 0; s < BS_NR_OF_STRINGS; s++) {
271  DIAG_Handler_IgnoreAndReturn(DIAG_HANDLER_RETURN_OK);
272  DIAG_Handler_IgnoreAndReturn(DIAG_HANDLER_RETURN_OK);
273  TEST_ASSERT_EQUAL_MESSAGE(
274  prechargeExpectedResults[s][i], TEST_BMS_CheckPrecharge(s, &tablePackValues), buffer);
275  }
276  }
277 }
278 
280  /*
281  WARNING: the function under test has code that is unaccessible
282  in order to solve this situation it has to be refactored
283  so that the branch in it does not always evaluate to true.
284 
285  However, the way it is implemented now, the unit test will be
286  always valid for the currently active defines.
287  */
288 
289 #if (BS_POSITIVE_DISCHARGE_CURRENT == true)
290  /* discharge is positive */
291 
292  /* maximum positive current has to be discharge */
293  TEST_ASSERT_EQUAL(BMS_DISCHARGING, BMS_GetCurrentFlowDirection(INT32_MAX));
294 
295  /* maximum negative current has to be charge */
296  TEST_ASSERT_EQUAL(BMS_CHARGING, BMS_GetCurrentFlowDirection(INT32_MIN));
297 #else
298  /* discharge is negative */
299 
300  /* maximum positive current has to be charge */
301  TEST_ASSERT_EQUAL(BMS_CHARGING, BMS_GetCurrentFlowDirection(INT32_MAX));
302 
303  /* maximum negative current has to be discharge */
304  TEST_ASSERT_EQUAL(BMS_DISCHARGING, BMS_GetCurrentFlowDirection(INT32_MIN));
305 #endif
306 
307  /* zero current has to be no charge */
308  TEST_ASSERT_EQUAL(BMS_AT_REST, BMS_GetCurrentFlowDirection(0));
309 
310  /* positive current below/equal to resting current is no current too */
311  TEST_ASSERT_EQUAL(BMS_AT_REST, BMS_GetCurrentFlowDirection(0 + BS_REST_CURRENT_mA - 1));
312 
313  /* negative current below/equal to resting current is no current too */
314  TEST_ASSERT_EQUAL(BMS_AT_REST, BMS_GetCurrentFlowDirection(0 - BS_REST_CURRENT_mA + 1));
315 
316  /* function should have same behavior for #BS_CS_THRESHOLD_NO_CURRENT_mA */
317  TEST_ASSERT_EQUAL(
320 }
321 
323  /* Set the current to 0 */
324  TEST_ASSERT_EQUAL(BMS_AT_REST, BMS_GetCurrentFlowDirection(0u));
325 
326  /* Set the current to #INT32_MAX */
327 #if (BS_POSITIVE_DISCHARGE_CURRENT == true)
328  TEST_ASSERT_EQUAL(BMS_DISCHARGING, BMS_GetCurrentFlowDirection(INT32_MAX));
329 #else
330  TEST_ASSERT_EQUAL(BMS_CHARGING, BMS_GetCurrentFlowDirection(INT32_MAX));
331 #endif
332 
333  /* Set the current to #INT32_MIN */
334 #if (BS_POSITIVE_DISCHARGE_CURRENT == true)
335  TEST_ASSERT_EQUAL(BMS_CHARGING, BMS_GetCurrentFlowDirection(INT32_MIN));
336 #else
337  TEST_ASSERT_EQUAL(BMS_DISCHARGING, BMS_GetCurrentFlowDirection(INT32_MIN));
338 #endif
339 }
340 
341 /** check that invalid values to BMS_CheckPrecharge trip an assertion
342  *
343  * invalid values are all those that do not fall into
344  * 0 <= stringNumber < #BS_NR_OF_STRINGS
345  */
348 
349  /* Invalid string number */
350  DIAG_Handler_IgnoreAndReturn(DIAG_HANDLER_RETURN_OK);
351  DIAG_Handler_IgnoreAndReturn(DIAG_HANDLER_RETURN_OK);
353 
354  /* Invalid string number */
355  DIAG_Handler_IgnoreAndReturn(DIAG_HANDLER_RETURN_OK);
356  DIAG_Handler_IgnoreAndReturn(DIAG_HANDLER_RETURN_OK);
358 
359  /* Invalid string number */
360  DIAG_Handler_IgnoreAndReturn(DIAG_HANDLER_RETURN_OK);
361  DIAG_Handler_IgnoreAndReturn(DIAG_HANDLER_RETURN_OK);
362  TEST_ASSERT_FAIL_ASSERT(TEST_BMS_CheckPrecharge(UINT8_MAX, &tablePackValues));
363 
364  /* Valid string number */
365  DIAG_Handler_IgnoreAndReturn(DIAG_HANDLER_RETURN_OK);
366  DIAG_Handler_IgnoreAndReturn(DIAG_HANDLER_RETURN_OK);
367  TEST_ASSERT_PASS_ASSERT(TEST_BMS_CheckPrecharge(0u, &tablePackValues));
368 }
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
#define BS_REST_CURRENT_mA
current threshold for determining rest state of battery. If absolute current is below this limit valu...
BS_STRING_PRECHARGE_PRESENT_e
@ BS_STRING_WITH_PRECHARGE
@ BS_STRING0
#define BS_CS_THRESHOLD_NO_CURRENT_mA
current sensor threshold for 0 current in mA as the sensor has a jitter.
STD_RETURN_TYPE_e TEST_BMS_CheckPrecharge(uint8_t stringNumber, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1666
BMS_CURRENT_FLOW_STATE_e BMS_GetCurrentFlowDirection(int32_t current_mA)
Get current flow direction, current value as function parameter.
Definition: bms.c:1590
bms driver header
@ BMS_AT_REST
Definition: bms.h:76
@ BMS_DISCHARGING
Definition: bms.h:74
@ BMS_CHARGING
Definition: bms.h:73
#define BMS_PRECHARGE_VOLTAGE_THRESHOLD_mV
Definition: bms_cfg.h:169
#define BMS_PRECHARGE_CURRENT_THRESHOLD_mA
Definition: bms_cfg.h:172
@ CONT_HAS_NO_FEEDBACK
Definition: contactor_cfg.h:81
@ CONT_FEEDBACK_NORMALLY_OPEN
Definition: contactor_cfg.h:78
@ CONT_PRECHARGE
Definition: contactor_cfg.h:88
@ CONT_MINUS
Definition: contactor_cfg.h:87
@ CONT_PLUS
Definition: contactor_cfg.h:86
@ CONT_SWITCH_OFF
Definition: contactor_cfg.h:71
@ CONT_BIDIRECTIONAL
@ CONT_CHARGING_DIRECTION
@ CONT_DISCHARGING_DIRECTION
@ DATA_BLOCK_ID_PACK_VALUES
Definition: database_cfg.h:108
@ DIAG_HANDLER_RETURN_OK
Definition: diag.h:69
math library for often used math functions
STD_RETURN_TYPE_e
Definition: fstd_types.h:82
@ STD_NOT_OK
Definition: fstd_types.h:84
@ STD_OK
Definition: fstd_types.h:83
Header for the configuration for the driver for the smart power switches.
#define SPS_CHANNEL_2
Definition: sps_cfg.h:90
#define SPS_CHANNEL_0
Definition: sps_cfg.h:88
#define SPS_CHANNEL_1
Definition: sps_cfg.h:89
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:122
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:190
uint8_t nrOfConfiguredDiagnosisEntries
Definition: diag_cfg.h:351
Helper for unit tests.
#define TEST_ASSERT_PASS_ASSERT(_code_under_test)
assert whether assert macro has passed
#define TEST_ASSERT_FAIL_ASSERT(_code_under_test)
assert whether assert macro has failed
BS_STRING_PRECHARGE_PRESENT_e bs_stringsWithPrecharge[BS_NR_OF_STRINGS]
Definition: test_bms.c:88
#define NUM_PRECHARGE_TESTS
Definition: test_bms.c:126
STD_RETURN_TYPE_e prechargeExpectedResults[BS_NR_OF_STRINGS][NUM_PRECHARGE_TESTS]
Definition: test_bms.c:127
void testBMS_CheckPrechargeInvalidStringNumber(void)
Definition: test_bms.c:346
CONT_CONTACTOR_STATE_s cont_contactorStates[]
Definition: test_bms.c:92
void testCheckPrechargeIterateStub(void)
Iterate over a callback that supplies various scenarios and check if they work as expected.
Definition: test_bms.c:260
void setUp(void)
Definition: test_bms.c:119
void tearDown(void)
Definition: test_bms.c:122
void testBMS_GetCurrentFlowDirectionWithTypicalValues(void)
Definition: test_bms.c:279
STD_RETURN_TYPE_e MockDATA_ReadBlock_Callback(void *pDataToReceiver, int num_calls)
Definition: test_bms.c:131
void testCheckCurrentValueDirectionWithCurrentZeroMaxAndMin(void)
Definition: test_bms.c:322
DIAG_ID_CFG_s diag_diagnosisIdConfiguration[]
Definition: test_bms.c:80
DIAG_DEV_s diag_device
Definition: test_bms.c:82