foxBMS - Unit Tests  1.6.0
The foxBMS Unit Tests API Documentation
test_algorithm.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_algorithm.c
44  * @author foxBMS Team
45  * @date 2020-06-30 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup UNIT_TEST_IMPLEMENTATION
49  * @prefix TEST
50  *
51  * @brief Test of the algorithm module
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "unity.h"
57 #include "Mockalgorithm_cfg.h"
58 #include "Mockos.h"
59 #include "Mocktest_algorithm_stubs.h"
60 
61 #include "algorithm.h"
62 #include "fstd_types.h"
63 #include "test_assert_helper.h"
64 
65 /*========== Unit Testing Framework Directives ==============================*/
66 TEST_INCLUDE_PATH("../../src/app/application/algorithm")
67 TEST_INCLUDE_PATH("../../src/app/application/algorithm/config")
68 
69 /*========== Definitions and Implementations for Unit Test ==================*/
73 };
74 
75 const uint16_t algo_length = sizeof(algo_algorithms) / sizeof(algo_algorithms[0]);
76 
77 /*========== Setup and Teardown =============================================*/
78 void setUp(void) {
79  /* uninitialize everything */
80  for (uint16_t i = 0u; i < algo_length; i++) {
82  }
83 
84  /* relock initialization */
86 }
87 
88 void tearDown(void) {
89 }
90 
91 /*========== Test Cases =====================================================*/
92 /* TODO: check behavior when timer flows over for the runtime analysis */
93 
95  /* when no algorithm is initialized and init is not unlocked then nothing should be called */
96  OS_EnterTaskCritical_Ignore();
97  OS_ExitTaskCritical_Ignore();
99  TEST_ASSERT_EQUAL(ALGO_UNINITIALIZED, algo_algorithms[0].state);
100  TEST_ASSERT_EQUAL(ALGO_UNINITIALIZED, algo_algorithms[1].state);
101 }
102 
104  /* when no algorithm is initialized and init is not unlocked then nothing should be called */
105  OS_EnterTaskCritical_Ignore();
106  OS_ExitTaskCritical_Ignore();
108  TEST_ASSERT_EQUAL(ALGO_UNINITIALIZED, algo_algorithms[0].state);
109  TEST_ASSERT_EQUAL(ALGO_UNINITIALIZED, algo_algorithms[1].state);
110 
111  /* after that if we unlock, then the init process will be handled and the
112  first calculation computed */
114 
115  /* call to the init function of the second entry (first one has no init) */
116  TEST_AlgorithmInitializationFunction_ExpectAndReturn(STD_OK);
117 
118  /* this is the retrieval of the start time for both algorithms and
119  after that both algorithms should be called */
120  OS_GetTickCount_ExpectAndReturn(0u);
121  TEST_AlgorithmComputeFunction_Expect();
122  ALGO_MarkAsDone_Expect(0u);
123  OS_GetTickCount_ExpectAndReturn(0u);
124  TEST_AlgorithmComputeFunction_Expect();
125  ALGO_MarkAsDone_Expect(1u);
126 
128 
129  /* afterwards the algorithms should have switched to running as we are
130  mocking ALGO_MarkAsDone without function
131  (normally the algorithm would then switch back its state upon completion) */
132  TEST_ASSERT_EQUAL(ALGO_RUNNING, algo_algorithms[0].state);
133  TEST_ASSERT_EQUAL(ALGO_RUNNING, algo_algorithms[1].state);
134 }
135 
137  /* after that if we unlock, then the init process will be handled and the
138  first calculation computed */
139  OS_EnterTaskCritical_Ignore();
140  OS_ExitTaskCritical_Ignore();
142 
143  const uint32_t storeCycleTime = algo_algorithms[0].cycleTime_ms;
144  /* set to an invalid cycle time */
146 
148 
149  TEST_ASSERT_EQUAL(ALGO_UNINITIALIZED, algo_algorithms[0].state);
150  TEST_ASSERT_EQUAL(ALGO_UNINITIALIZED, algo_algorithms[1].state);
151 
152  /* restore cycle time for other tests */
153  algo_algorithms[0].cycleTime_ms = storeCycleTime;
154 }
155 
157  /* unlock so that we can continue */
158  OS_EnterTaskCritical_Ignore();
159  OS_ExitTaskCritical_Ignore();
161 
162  /* call to the init function of the second entry (first one has no init)
163  this time we indicate a failure */
164  TEST_AlgorithmInitializationFunction_ExpectAndReturn(STD_NOT_OK);
165 
166  /* now the algorithm without init should be running and the other one in
167  error state */
168  OS_GetTickCount_ExpectAndReturn(0u);
169  TEST_AlgorithmComputeFunction_Expect();
170  ALGO_MarkAsDone_Expect(0u);
171 
173 
174  /* afterwards the algorithms should have switched to running and failure state */
175  TEST_ASSERT_EQUAL(ALGO_RUNNING, algo_algorithms[0].state);
176  TEST_ASSERT_EQUAL(ALGO_FAILED_INIT, algo_algorithms[1].state);
177 
178  /* subsequent calls after that should not change anything */
180 
181  TEST_ASSERT_EQUAL(ALGO_RUNNING, algo_algorithms[0].state);
182  TEST_ASSERT_EQUAL(ALGO_FAILED_INIT, algo_algorithms[1].state);
183 }
184 
186  OS_EnterTaskCritical_Ignore();
187  OS_ExitTaskCritical_Ignore();
188  OS_GetTickCount_IgnoreAndReturn(0u);
189  TEST_AlgorithmComputeFunction_Ignore();
190  ALGO_MarkAsDone_Ignore();
191 
192  /* unlock so that we can continue */
194 
195  /* call to the init function of the second entry (first one has no init)
196  this time we indicate a failure */
197  TEST_AlgorithmInitializationFunction_ExpectAndReturn(STD_OK);
198 
200 
201  /* afterwards the algorithms should have switched to running and failure state */
202  TEST_ASSERT_EQUAL(ALGO_RUNNING, algo_algorithms[0].state);
203  TEST_ASSERT_EQUAL(ALGO_RUNNING, algo_algorithms[1].state);
204 
205  /* unlock so that we can continue */
207 
208  /* subsequent calls after that should not change anything */
210 
211  TEST_ASSERT_EQUAL(ALGO_RUNNING, algo_algorithms[0].state);
212  TEST_ASSERT_EQUAL(ALGO_RUNNING, algo_algorithms[1].state);
213 }
214 
216  /* unlock so that we can continue */
217  OS_EnterTaskCritical_Ignore();
218  OS_ExitTaskCritical_Ignore();
220 
221  /* call to the init function of the second entry (first one has no init)
222  this time we send something that cannot be returned normally */
223  TEST_AlgorithmInitializationFunction_ExpectAndReturn(42u);
224 
225  /* as a result the system will fail on init and assert */
227 }
228 
229 void testCycleTimeZero(void) {
230  /* this test aims to test what a cycle time of zero does */
231 
232  /* unlock so that we can continue */
233  OS_EnterTaskCritical_Ignore();
234  OS_ExitTaskCritical_Ignore();
236 
237  /* inject a cycle time of zero */
239 
240  /* call the main function;
241  if this crashes we ran probably into a division by zero;*/
242  TEST_AlgorithmInitializationFunction_ExpectAndReturn(STD_OK);
243  OS_GetTickCount_ExpectAndReturn(0u);
244  TEST_AlgorithmComputeFunction_Expect();
245  ALGO_MarkAsDone_Expect(0u);
246  OS_GetTickCount_ExpectAndReturn(0u);
247  TEST_AlgorithmComputeFunction_Expect();
248  ALGO_MarkAsDone_Expect(1u);
250 }
251 
253  const uint32_t startTime = 500u;
254  const uint32_t currentTime = 0u;
255  const ALGO_STATE_e state = ALGO_READY;
256 
257  algo_algorithms[0].startTime = startTime;
258  algo_algorithms[0].state = state;
259  OS_GetTickCount_ExpectAndReturn(currentTime);
261  TEST_ASSERT_EQUAL(state, algo_algorithms[0].state);
262 }
263 
265  const uint32_t startTime = 500u;
266  const uint32_t currentTime = 500u;
267  const ALGO_STATE_e state = ALGO_RUNNING;
268 
269  algo_algorithms[0].startTime = startTime;
270  algo_algorithms[0].state = state;
271  OS_GetTickCount_ExpectAndReturn(currentTime);
273  TEST_ASSERT_EQUAL(state, algo_algorithms[0].state);
274 }
275 
277  const uint32_t startTime = 500u;
278  const uint32_t currentTime = 50000u;
279  const ALGO_STATE_e state = ALGO_RUNNING;
280 
281  algo_algorithms[0].startTime = startTime;
282  algo_algorithms[0].state = state;
283  OS_GetTickCount_ExpectAndReturn(currentTime);
285  TEST_ASSERT_EQUAL(ALGO_BLOCKED, algo_algorithms[0].state);
286 }
void ALGO_UnlockInitialization(void)
Calling this function sets a signal that lets ALGO_Initialization() know that the initialization has ...
Definition: algorithm.c:110
void TEST_ALGO_ResetInitializationRequest()
Definition: algorithm.c:171
void ALGO_MainFunction(void)
handles the call of different algorithm functions when cycle time has expired
Definition: algorithm.c:116
void ALGO_MonitorExecutionTime(void)
monitors the calculation duration of the different algorithms
Definition: algorithm.c:155
Headers for the driver for the storage in the EEPROM memory.
ALGO_STATE_e
Definition: algorithm_cfg.h:83
@ ALGO_UNINITIALIZED
Definition: algorithm_cfg.h:84
@ ALGO_RUNNING
Definition: algorithm_cfg.h:86
@ ALGO_FAILED_INIT
Definition: algorithm_cfg.h:89
@ ALGO_READY
Definition: algorithm_cfg.h:85
@ ALGO_BLOCKED
Definition: algorithm_cfg.h:88
#define ALGO_TICK_ms
Definition: algorithm_cfg.h:69
Definition of foxBMS standard types.
@ STD_NOT_OK
Definition: fstd_types.h:84
@ STD_OK
Definition: fstd_types.h:83
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
uint32_t cycleTime_ms
Definition: algorithm_cfg.h:96
uint32_t startTime
Definition: algorithm_cfg.h:98
ALGO_STATE_e state
Definition: algorithm_cfg.h:95
void testUninitializedCallsNothing(void)
const uint16_t algo_length
void testUnlockInitializationInvalidAlgorithmConfiguration(void)
void testUnlockInitialization(void)
void testMonitorFunctionPassBecauseInTime(void)
void testCycleTimeZero(void)
void testTwoTimesInitialization(void)
void testMonitorFunctionStopBecauseOutOfTime(void)
void testUnsuccessfulInitialization(void)
void setUp(void)
void tearDown(void)
ALGO_TASKS_s algo_algorithms[]
void testWrongInitializationImplementation(void)
void testMonitorFunctionPassBecauseNotRunning(void)
STD_RETURN_TYPE_e TEST_AlgorithmInitializationFunction(void)
void TEST_AlgorithmComputeFunction(void)
Helper for unit tests.
#define TEST_ASSERT_FAIL_ASSERT(_code_under_test)
assert whether assert macro has failed