added seperate cmake project for utest

this project uses a fake rtos, and compiles for native test
this is to test some lib seperate form the rest of the system
This commit is contained in:
2024-02-02 19:52:53 +01:00
parent f59fdea76f
commit 83830808a9
7 changed files with 398 additions and 0 deletions

1
tests/native/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
build/

26
tests/native/.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,26 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [ {
"name": "Debug CLS_Master_Test",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/CLS_Master_Unity",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
//"preLaunchTask": "build" // If you have a build task setup
}]
}

View File

@@ -0,0 +1,34 @@
cmake_minimum_required(VERSION 3.10)
# set the project name
project(CLS_Master_Unity)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
add_executable(${CMAKE_PROJECT_NAME})
target_sources(${CMAKE_PROJECT_NAME} PUBLIC
tests.c
mock_os/mock_os.c
../lib/Unity/src/unity.c
)
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC
./
../lib/Unity/src
)
include_directories(mock_os)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/nanopb/extra)
find_package(Nanopb REQUIRED)
include_directories(${NANOPB_INCLUDE_DIRS})
nanopb_generate_cpp(PROTO_SRCS PROTO_HDRS RELPATH proto ../../proto/firmware.proto)
add_library(PROTOS ${PROTO_SRCS} ${PROTO_HDRS})
target_include_directories(PROTOS PUBLIC ${NANOPB_INCLUDE_DIRS} ${PROJECT_BINARY_DIR})
include_directories(${PROJECT_BINARY_DIR})
add_subdirectory(../../Application/Tasks Tasks)
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Tasks)

View File

@@ -0,0 +1,107 @@
#include "stdint.h"
#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value.
/// Status code values returned by CMSIS-RTOS functions.
typedef enum {
osOK = 0, ///< Operation completed successfully.
osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits.
osErrorTimeout = -2, ///< Operation not completed within the timeout period.
osErrorResource = -3, ///< Resource not available.
osErrorParameter = -4, ///< Parameter error.
osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation.
osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines.
osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization.
} osStatus_t;
/// Priority values.
typedef enum {
osPriorityNone = 0, ///< No priority (not initialized).
osPriorityIdle = 1, ///< Reserved for Idle thread.
osPriorityLow = 8, ///< Priority: low
osPriorityLow1 = 8+1, ///< Priority: low + 1
osPriorityLow2 = 8+2, ///< Priority: low + 2
osPriorityLow3 = 8+3, ///< Priority: low + 3
osPriorityLow4 = 8+4, ///< Priority: low + 4
osPriorityLow5 = 8+5, ///< Priority: low + 5
osPriorityLow6 = 8+6, ///< Priority: low + 6
osPriorityLow7 = 8+7, ///< Priority: low + 7
osPriorityBelowNormal = 16, ///< Priority: below normal
osPriorityBelowNormal1 = 16+1, ///< Priority: below normal + 1
osPriorityBelowNormal2 = 16+2, ///< Priority: below normal + 2
osPriorityBelowNormal3 = 16+3, ///< Priority: below normal + 3
osPriorityBelowNormal4 = 16+4, ///< Priority: below normal + 4
osPriorityBelowNormal5 = 16+5, ///< Priority: below normal + 5
osPriorityBelowNormal6 = 16+6, ///< Priority: below normal + 6
osPriorityBelowNormal7 = 16+7, ///< Priority: below normal + 7
osPriorityNormal = 24, ///< Priority: normal
osPriorityNormal1 = 24+1, ///< Priority: normal + 1
osPriorityNormal2 = 24+2, ///< Priority: normal + 2
osPriorityNormal3 = 24+3, ///< Priority: normal + 3
osPriorityNormal4 = 24+4, ///< Priority: normal + 4
osPriorityNormal5 = 24+5, ///< Priority: normal + 5
osPriorityNormal6 = 24+6, ///< Priority: normal + 6
osPriorityNormal7 = 24+7, ///< Priority: normal + 7
osPriorityAboveNormal = 32, ///< Priority: above normal
osPriorityAboveNormal1 = 32+1, ///< Priority: above normal + 1
osPriorityAboveNormal2 = 32+2, ///< Priority: above normal + 2
osPriorityAboveNormal3 = 32+3, ///< Priority: above normal + 3
osPriorityAboveNormal4 = 32+4, ///< Priority: above normal + 4
osPriorityAboveNormal5 = 32+5, ///< Priority: above normal + 5
osPriorityAboveNormal6 = 32+6, ///< Priority: above normal + 6
osPriorityAboveNormal7 = 32+7, ///< Priority: above normal + 7
osPriorityHigh = 40, ///< Priority: high
osPriorityHigh1 = 40+1, ///< Priority: high + 1
osPriorityHigh2 = 40+2, ///< Priority: high + 2
osPriorityHigh3 = 40+3, ///< Priority: high + 3
osPriorityHigh4 = 40+4, ///< Priority: high + 4
osPriorityHigh5 = 40+5, ///< Priority: high + 5
osPriorityHigh6 = 40+6, ///< Priority: high + 6
osPriorityHigh7 = 40+7, ///< Priority: high + 7
osPriorityRealtime = 48, ///< Priority: realtime
osPriorityRealtime1 = 48+1, ///< Priority: realtime + 1
osPriorityRealtime2 = 48+2, ///< Priority: realtime + 2
osPriorityRealtime3 = 48+3, ///< Priority: realtime + 3
osPriorityRealtime4 = 48+4, ///< Priority: realtime + 4
osPriorityRealtime5 = 48+5, ///< Priority: realtime + 5
osPriorityRealtime6 = 48+6, ///< Priority: realtime + 6
osPriorityRealtime7 = 48+7, ///< Priority: realtime + 7
osPriorityISR = 56, ///< Reserved for ISR deferred thread.
osPriorityError = -1, ///< System cannot determine priority or illegal priority.
osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization.
} osPriority_t;
typedef struct {
const char *name; ///< name of the thread
uint32_t attr_bits; ///< attribute bits
void *cb_mem; ///< memory for control block
uint32_t cb_size; ///< size of provided memory for control block
void *stack_mem; ///< memory for stack
uint32_t stack_size; ///< size of stack
osPriority_t priority; ///< initial thread priority (default: osPriorityNormal)
uint32_t reserved; ///< reserved (must be 0)
} osThreadAttr_t;
/// Attributes structure for message queue.
typedef struct {
const char *name; ///< name of the message queue
uint32_t attr_bits; ///< attribute bits
void *cb_mem; ///< memory for control block
uint32_t cb_size; ///< size of provided memory for control block
void *mq_mem; ///< memory for data storage
uint32_t mq_size; ///< size of provided memory for data storage
} osMessageQueueAttr_t;
typedef void (*osThreadFunc_t) (void *argument);
typedef void* osMessageQueueId_t;
typedef void* osThreadId_t;
void Error_Handler();
osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout);
osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout);
osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) ;

View File

@@ -0,0 +1,63 @@
#include "cmsis_os2.h"
#include <stdbool.h>
void Error_Handler() {
}
void MX_USB_DEVICE_Init() {
}
#define NUM_BUFFERS 10
static uint32_t mockQueue[NUM_BUFFERS];
static int mockQueueFront = 0;
static int mockQueueBack = 0;
static bool mockQueueEmpty = true;
osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr)
{
return (osThreadId_t)1;
}
osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) {
if (!mockQueueEmpty)
{
// Remove the message from the queue
*(uint32_t *)msg_ptr = mockQueue[mockQueueFront];
mockQueueFront = (mockQueueFront + 1) % NUM_BUFFERS;
if (mockQueueFront == mockQueueBack)
{
mockQueueEmpty = true;
}
return osOK;
}
else
{
// The queue is empty
return osErrorResource;
}
}
osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) {
if (mockQueueEmpty || mockQueueBack != mockQueueFront)
{
// Add the message to the queue
mockQueue[mockQueueBack] = *(uint32_t *)msg_ptr;
mockQueueBack = (mockQueueBack + 1) % NUM_BUFFERS;
mockQueueEmpty = false;
return osOK;
}
else
{
// The queue is full
return osErrorResource;
}
}
osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
return &mockQueue;
}

View File

@@ -0,0 +1 @@
void MX_USB_DEVICE_Init();

166
tests/native/tests.c Normal file
View File

@@ -0,0 +1,166 @@
#include "unity.h"
#include "UsbDataHandler.h"
#include "pb_encode.h"
#include "firmware.pb.h"
void setUp() {
}
#define START_PACKAES 10
#define START_SIZE 123456
#define START_CRC 0xffff
#define START_DEVICE 0x04
#define START_NAME "slave0x04.bin"
#define PACK_COUTNER 3
#define PACK_CRC 0xabcd
#define PACK_DEVICE 0x04
#define PACK_DATA_SIZE 50
#define ACK_COUTNER 43
#define ACK_CRC 0xabcdef
#define ACK_DEVICE 0x9
#define DONE_CRC 0xffffffff
#define DONE_DEVICE 0xf
#define DONE_SIZE 1024 * 65
uint16_t StartCounter = 0;
uint16_t PackageCounter = 0;
uint16_t AckCounter = 0;
uint16_t DoneCounter = 0;
void transmit_package(uint16_t id, const pb_msgdesc_t *fields , const void* msg){
UsbDataPacket buffer = {0};
buffer.head.type = id;
pb_ostream_t ostream = pb_ostream_from_buffer(buffer.data, sizeof(buffer.data));
pb_encode(&ostream, fields, msg);
buffer.head.length= ostream.bytes_written;
buffer.head.check = UsbDataPacket_head_sum(&buffer);
UsbDataHandler_RxCallback((uint8_t*)(&buffer), buffer.head.length+sizeof(UsbDataPacketHead));
}
void test_UsbDataHandler(void) {
// Set up the module
UsbDataHandler_Start();
// Call the runner with no messages this should do nothing
UsbDataHandler_Runner();
FirmwareStart start ={
.name=START_NAME,
.packages=START_PACKAES,
.size=START_SIZE,
.crc_fw=START_CRC,
.device_id=START_DEVICE,
};
transmit_package(0xf01, FirmwareStart_fields, &start);
// Call the runner with start message in the queue
UsbDataHandler_Runner();
TEST_ASSERT_EQUAL(StartCounter,1);
//Put 2 packages in the buffer an parse them
transmit_package(0xf01, FirmwareStart_fields, &start);
transmit_package(0xf01, FirmwareStart_fields, &start);
UsbDataHandler_Runner();
UsbDataHandler_Runner();
TEST_ASSERT_EQUAL(StartCounter,3);
FirmwarePackage pack = {
.counter =PACK_COUTNER ,
.crc_pac = PACK_CRC,
.device_id= PACK_DEVICE,
.data={.size = PACK_DATA_SIZE,
.bytes={0}
},
};
transmit_package(0xf02, FirmwarePackage_fields, &pack);
UsbDataHandler_Runner();
TEST_ASSERT_EQUAL(PackageCounter,1);
FirmwarePackageAck ack = {
.ack =true,
.counter = ACK_COUTNER,
.crc_pac = ACK_CRC,
.device_id = ACK_DEVICE,
};
transmit_package(0xf04, FirmwarePackageAck_fields, &ack);
UsbDataHandler_Runner();
TEST_ASSERT_EQUAL(PackageCounter,1);
FirmwareDone done = {
.crc_fw = DONE_CRC,
.device_id = DONE_DEVICE,
.size = DONE_SIZE,
};
transmit_package(0xf03, FirmwareDone_fields, &done);
UsbDataHandler_Runner();
TEST_ASSERT_EQUAL(DoneCounter,1);
}
void tearDown() {
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_UsbDataHandler);
return UNITY_END();
}
void DataClbk_FirmwareStart(void * msg, uint32_t length) {
FirmwareStart start;
memcpy(&start,msg,sizeof(start));
TEST_ASSERT_EQUAL(START_SIZE, start.size);
TEST_ASSERT_EQUAL(START_PACKAES, start.packages);
TEST_ASSERT_EQUAL(START_CRC, start.crc_fw);
TEST_ASSERT_EQUAL(START_DEVICE, start.device_id);
TEST_ASSERT_EQUAL_STRING(START_NAME,start.name);
StartCounter++;
}
void DataClbk_FirmwarePackage(void * msg, uint32_t length) {
FirmwarePackage pack;
memcpy(&pack,msg,sizeof(pack));
TEST_ASSERT_EQUAL(FirmwarePackage_size, length);
TEST_ASSERT_EQUAL(PACK_COUTNER, pack.counter);
TEST_ASSERT_EQUAL(PACK_CRC, pack.crc_pac);
TEST_ASSERT_EQUAL(PACK_DEVICE, pack.device_id);
TEST_ASSERT_EQUAL(PACK_DATA_SIZE, pack.data.size);
PackageCounter++;
}
void DataClbk_FirmwarePackageAck(void * msg, uint32_t length) {
FirmwarePackageAck ack;
memcpy(&ack,msg,sizeof(ack));
TEST_ASSERT_EQUAL(FirmwarePackageAck_size, length);
TEST_ASSERT(ack.ack);
TEST_ASSERT_EQUAL(ACK_COUTNER, ack.counter);
TEST_ASSERT_EQUAL(ACK_CRC, ack.crc_pac);
TEST_ASSERT_EQUAL(ACK_DEVICE, ack.device_id);
AckCounter++;
}
void DataClbk_FirmwareDone(void * msg, uint32_t length) {
FirmwareDone done;
memcpy(&done,msg,sizeof(done));
TEST_ASSERT_EQUAL(FirmwareDone_size, length);
TEST_ASSERT_EQUAL(DONE_CRC,done.crc_fw);
TEST_ASSERT_EQUAL(DONE_DEVICE,done.device_id);
TEST_ASSERT_EQUAL(DONE_SIZE,done.size);
DoneCounter++;
}