Add basic test harness using munit

This commit is contained in:
CinderSocket
2026-03-08 18:39:39 -07:00
parent 5426d47f1f
commit 54c20878ec
14 changed files with 620 additions and 11 deletions
+11 -8
View File
@@ -1,4 +1,4 @@
name: "FAP: Build and lint"
name: "FAP: Build, test, and lint"
on: [push, pull_request]
jobs:
ufbt-build-action:
@@ -9,20 +9,23 @@ jobs:
uses: actions/checkout@v3
with:
submodules: 'true'
- name: Setup ufbt
uses: flipperdevices/flipperzero-ufbt-action@v0.1.2
with:
sdk-channel: release
task: setup
- name: Run host tests
run: make test-host
- name: Lint sources
run: ufbt lint ARGS="!./tests/host/vendor/munit"
- name: Build with ufbt
uses: flipperdevices/flipperzero-ufbt-action@v0.1.2
id: build-app
with:
skip-setup: true
sdk-channel: release
- name: Upload app artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ github.event.repository.name }}-${{ steps.build-app.outputs.suffix }}
path: ${{ steps.build-app.outputs.fap-artifacts }}
# You can remove this step if you don't want to check source code formatting
- name: Lint sources
uses: flipperdevices/flipperzero-ufbt-action@v0.1.2
with:
# skip SDK setup, we already did it in previous step
skip-setup: true
task: lint
+3 -2
View File
@@ -1,5 +1,6 @@
.vscode/
dist/
examples/*
logs
examples/
logs/
credential/
build/
+3
View File
@@ -1,3 +1,6 @@
[submodule "plugin"]
path = plugin
url = https://gitlab.com/bettse/flipper-wiegand-plugin.git
[submodule "tests/host/vendor/munit"]
path = tests/host/vendor/munit
url = https://github.com/nemequ/munit.git
+16 -1
View File
@@ -9,11 +9,26 @@ asn1:
build:
ufbt
test-host:
mkdir -p build/host_tests
cc -std=c11 -Wall -Wextra -Werror -DSEADER_HOST_TEST -Itests/host/vendor/munit -Itests/host -I. \
tests/host/vendor/munit/munit.c \
tests/host/test_main.c \
tests/host/test_lrc.c \
tests/host/test_t1_existing.c \
tests/host/t1_test_stubs.c \
tests/host/bit_buffer_mock.c \
lrc.c \
t_1.c \
-o build/host_tests/seader_tests
./build/host_tests/seader_tests
launch:
ufbt launch
format:
ufbt format
ufbt format ARGS="!./tests/host/vendor/munit"
clean:
rm -rf dist
rm -rf build/host_tests
+1
View File
@@ -21,6 +21,7 @@ App(
"*.c",
"aeabi_uldivmod.sx",
"!plugin/*.c",
"!tests",
],
fap_icon="icons/logo.png",
fap_category="NFC",
+4
View File
@@ -1,4 +1,8 @@
#ifdef SEADER_HOST_TEST
#include "tests/host/t_1_host_env.h"
#else
#include "t_1.h"
#endif
#define TAG "Seader:T=1"
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
typedef struct BitBuffer BitBuffer;
BitBuffer* bit_buffer_alloc(size_t capacity_bytes);
void bit_buffer_free(BitBuffer* buf);
void bit_buffer_reset(BitBuffer* buf);
void bit_buffer_copy_bytes(BitBuffer* buf, const uint8_t* data, size_t size_bytes);
size_t bit_buffer_get_size_bytes(const BitBuffer* buf);
const uint8_t* bit_buffer_get_data(const BitBuffer* buf);
void bit_buffer_append_bytes(BitBuffer* buf, const uint8_t* data, size_t size_bytes);
+48
View File
@@ -0,0 +1,48 @@
#include "bit_buffer.h"
#include <stdlib.h>
#include <string.h>
struct BitBuffer {
uint8_t* data;
size_t size_bits;
size_t capacity_bytes;
};
BitBuffer* bit_buffer_alloc(size_t capacity_bytes) {
BitBuffer* buf = malloc(sizeof(BitBuffer));
buf->data = calloc(1, capacity_bytes);
buf->size_bits = 0;
buf->capacity_bytes = capacity_bytes;
return buf;
}
void bit_buffer_free(BitBuffer* buf) {
if(buf) {
free(buf->data);
free(buf);
}
}
void bit_buffer_reset(BitBuffer* buf) {
buf->size_bits = 0;
}
void bit_buffer_copy_bytes(BitBuffer* buf, const uint8_t* data, size_t size_bytes) {
memcpy(buf->data, data, size_bytes);
buf->size_bits = size_bytes * 8;
}
size_t bit_buffer_get_size_bytes(const BitBuffer* buf) {
return (buf->size_bits + 7) / 8;
}
const uint8_t* bit_buffer_get_data(const BitBuffer* buf) {
return buf->data;
}
void bit_buffer_append_bytes(BitBuffer* buf, const uint8_t* data, size_t size_bytes) {
size_t current_bytes = bit_buffer_get_size_bytes(buf);
memcpy(buf->data + current_bytes, data, size_bytes);
buf->size_bits += size_bytes * 8;
}
+31
View File
@@ -0,0 +1,31 @@
#include "t_1_host_env.h"
T1HostTestState g_t1_host_test_state = {0};
void t1_host_test_reset(void) {
/* Default to success so tests opt into failure only when needed. */
memset(&g_t1_host_test_state, 0, sizeof(g_t1_host_test_state));
g_t1_host_test_state.process_return_value = true;
}
void seader_ccid_XfrBlock(SeaderUartBridge* seader_uart, uint8_t* data, size_t len) {
(void)seader_uart;
/* Record the exact frame the production code asked CCID to transmit. */
g_t1_host_test_state.xfrblock_call_count++;
g_t1_host_test_state.last_frame_len = len;
memcpy(g_t1_host_test_state.last_frame, data, len);
}
bool seader_worker_process_sam_message(Seader* seader, uint8_t* apdu, uint32_t len) {
(void)seader;
/* Capture the final APDU bytes that would be handed to the worker layer. */
g_t1_host_test_state.process_call_count++;
g_t1_host_test_state.last_apdu_len = len;
memcpy(g_t1_host_test_state.last_apdu, apdu, len);
return g_t1_host_test_state.process_return_value;
}
void seader_worker_send_version(Seader* seader) {
(void)seader;
g_t1_host_test_state.send_version_call_count++;
}
+103
View File
@@ -0,0 +1,103 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bit_buffer.h"
#include "lrc.h"
/* Keep the host harness aligned with the production UART scratchpad size. */
#define SEADER_UART_RX_BUF_SIZE (300)
#define FURI_LOG_W(tag, fmt, ...) ((void)0)
typedef struct BitBuffer BitBuffer;
typedef struct Seader Seader;
typedef struct SeaderWorker SeaderWorker;
typedef struct SeaderUartBridge SeaderUartBridge;
typedef enum {
SeaderWorkerEventSamPresent = 53,
} SeaderWorkerEvent;
typedef void (*SeaderWorkerCallback)(uint32_t event, void* context);
typedef enum {
SEADER_T1_PCB_I_BLOCK_MORE = 0x20,
SEADER_T1_PCB_SEQUENCE_BIT = 0x40,
SEADER_T1_PCB_R_BLOCK = 0x80,
SEADER_T1_PCB_S_BLOCK = 0xC0,
SEADER_T1_R_BLOCK_SEQUENCE_MASK = 0x10,
SEADER_T1_S_BLOCK_IFS = 0x01,
} SeaderT1Constant;
typedef struct {
uint8_t ifsc;
uint8_t nad;
uint8_t send_pcb;
uint8_t recv_pcb;
BitBuffer* tx_buffer;
size_t tx_buffer_offset;
BitBuffer* rx_buffer;
} SeaderT1State;
struct SeaderUartBridge {
uint8_t rx_buf[SEADER_UART_RX_BUF_SIZE];
uint8_t tx_buf[SEADER_UART_RX_BUF_SIZE];
size_t tx_len;
uint8_t T;
SeaderT1State t1;
};
struct SeaderWorker {
SeaderUartBridge* uart;
SeaderWorkerCallback callback;
void* context;
};
struct Seader {
SeaderWorker* worker;
};
typedef struct CCID_Message {
uint8_t bMessageType;
uint32_t dwLength;
uint8_t bSlot;
uint8_t bSeq;
uint8_t bStatus;
uint8_t bError;
uint8_t* payload;
size_t consumed;
} CCID_Message;
void seader_ccid_XfrBlock(SeaderUartBridge* seader_uart, uint8_t* data, size_t len);
bool seader_worker_process_sam_message(Seader* seader, uint8_t* apdu, uint32_t len);
void seader_worker_send_version(Seader* seader);
typedef struct {
/* Captured outbound CCID payload emitted by the T=1 implementation. */
size_t xfrblock_call_count;
uint8_t last_frame[SEADER_UART_RX_BUF_SIZE];
size_t last_frame_len;
/* Captured inbound APDU delivered upward to the SAM worker boundary. */
size_t process_call_count;
uint8_t last_apdu[SEADER_UART_RX_BUF_SIZE];
size_t last_apdu_len;
bool process_return_value;
/* Side effects used by the IFS response path. */
size_t send_version_call_count;
size_t callback_call_count;
uint32_t last_callback_event;
} T1HostTestState;
extern T1HostTestState g_t1_host_test_state;
void t1_host_test_reset(void);
void seader_send_t1(SeaderUartBridge* seader_uart, uint8_t* apdu, size_t len);
bool seader_recv_t1(Seader* seader, CCID_Message* message);
void seader_t_1_set_IFSD(Seader* seader);
void seader_t_1_reset(SeaderUartBridge* seader_uart);
+52
View File
@@ -0,0 +1,52 @@
#include <stdint.h>
#include "lrc.h"
#include "munit.h"
static MunitResult test_calc_lrc(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
uint8_t bytes[] = {0x03, 0x06, 0x62, 0x00};
munit_assert_uint8(
seader_calc_lrc(bytes, sizeof(bytes)), ==, (uint8_t)(0x03 ^ 0x06 ^ 0x62 ^ 0x00));
return MUNIT_OK;
}
static MunitResult test_add_and_validate_lrc(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
uint8_t frame[8] = {0x03, 0x06, 0x62, 0x00, 0x01, 0x02, 0x00, 0x00};
size_t len = seader_add_lrc(frame, 6);
munit_assert_size(len, ==, 7);
munit_assert_true(seader_validate_lrc(frame, len));
frame[2] ^= 0x80;
munit_assert_false(seader_validate_lrc(frame, len));
return MUNIT_OK;
}
static MunitResult test_validate_nak_triplet(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
uint8_t nak_triplet[] = {0x03, 0x15, 0x16};
munit_assert_true(seader_validate_lrc(nak_triplet, 3));
return MUNIT_OK;
}
static MunitTest test_lrc_cases[] = {
{(char*)"/calc", test_calc_lrc, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{(char*)"/roundtrip", test_add_and_validate_lrc, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{(char*)"/nak-triplet", test_validate_nak_triplet, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{NULL, NULL, NULL, NULL, 0, NULL},
};
MunitSuite test_lrc_suite = {
"",
test_lrc_cases,
NULL,
1,
MUNIT_SUITE_OPTION_NONE,
};
+20
View File
@@ -0,0 +1,20 @@
#include "munit.h"
extern MunitSuite test_lrc_suite;
extern MunitSuite test_t1_existing_suite;
int main(int argc, char* argv[]) {
MunitSuite child_suites[] = {
{"/lrc", test_lrc_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
{"/t1", test_t1_existing_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
{NULL, NULL, NULL, 0, 0},
};
MunitSuite main_suite = {
"",
NULL,
child_suites,
1,
MUNIT_SUITE_OPTION_NONE,
};
return munit_suite_main(&main_suite, NULL, argc, argv);
}
+312
View File
@@ -0,0 +1,312 @@
#include <string.h>
#include "munit.h"
#include "t_1_host_env.h"
/* The production worker reports SAM-present through a callback; the harness just records it. */
static void test_callback(uint32_t event, void* context) {
(void)context;
g_t1_host_test_state.callback_call_count++;
g_t1_host_test_state.last_callback_event = event;
}
static Seader make_test_seader(SeaderUartBridge* uart, SeaderWorker* worker) {
memset(uart, 0, sizeof(*uart));
memset(worker, 0, sizeof(*worker));
worker->uart = uart;
worker->callback = test_callback;
Seader seader = {.worker = worker};
return seader;
}
static bool last_frame_prefix_matches(const uint8_t* expected, size_t len) {
return g_t1_host_test_state.last_frame_len >= len &&
memcmp(g_t1_host_test_state.last_frame, expected, len) == 0;
}
static bool last_apdu_matches(const uint8_t* expected, size_t len) {
return g_t1_host_test_state.last_apdu_len == len &&
memcmp(g_t1_host_test_state.last_apdu, expected, len) == 0;
}
static MunitResult test_send_ifs_request(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
SeaderUartBridge uart = {0};
SeaderWorker worker = {0};
Seader seader = make_test_seader(&uart, &worker);
t1_host_test_reset();
uart.t1.ifsc = 0x20;
uart.t1.nad = 0x00;
uart.t1.send_pcb = SEADER_T1_PCB_SEQUENCE_BIT;
seader_t_1_set_IFSD(&seader);
munit_assert_size(g_t1_host_test_state.xfrblock_call_count, ==, 1);
munit_assert_size(g_t1_host_test_state.last_frame_len, ==, 5);
munit_assert_true(last_frame_prefix_matches((const uint8_t*)"\x00\xC1\x01\x20", 4));
munit_assert_true(
seader_validate_lrc(g_t1_host_test_state.last_frame, g_t1_host_test_state.last_frame_len));
return MUNIT_OK;
}
static MunitResult test_send_single_block(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
SeaderUartBridge uart = {0};
SeaderWorker worker = {0};
make_test_seader(&uart, &worker);
t1_host_test_reset();
uart.t1.ifsc = 0x20;
uart.t1.send_pcb = SEADER_T1_PCB_SEQUENCE_BIT;
uint8_t apdu_short[] = {0xDE, 0xAD, 0xBE};
seader_send_t1(&uart, apdu_short, sizeof(apdu_short));
munit_assert_size(g_t1_host_test_state.xfrblock_call_count, ==, 1);
munit_assert_size(g_t1_host_test_state.last_frame_len, ==, 7);
munit_assert_true(last_frame_prefix_matches((const uint8_t*)"\x00\x00\x03", 3));
munit_assert_memory_equal(sizeof(apdu_short), g_t1_host_test_state.last_frame + 3, apdu_short);
munit_assert_uint8(uart.t1.send_pcb, ==, 0x00);
return MUNIT_OK;
}
static MunitResult test_send_scratchpad_block(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
SeaderUartBridge uart = {0};
SeaderWorker worker = {0};
make_test_seader(&uart, &worker);
t1_host_test_reset();
uart.t1.ifsc = 0x20;
uart.t1.send_pcb = SEADER_T1_PCB_SEQUENCE_BIT;
uint8_t* scratchpad_apdu = uart.tx_buf + 3;
scratchpad_apdu[0] = 0x01;
scratchpad_apdu[1] = 0x02;
seader_send_t1(&uart, scratchpad_apdu, 2);
munit_assert_size(g_t1_host_test_state.xfrblock_call_count, ==, 1);
munit_assert_true(last_frame_prefix_matches((const uint8_t*)"\x00\x00\x02\x01\x02", 5));
return MUNIT_OK;
}
static MunitResult test_send_chained_block(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
SeaderUartBridge uart = {0};
SeaderWorker worker = {0};
make_test_seader(&uart, &worker);
t1_host_test_reset();
uart.t1.send_pcb = SEADER_T1_PCB_SEQUENCE_BIT;
uart.t1.ifsc = 2;
uint8_t apdu_long[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE};
seader_send_t1(&uart, apdu_long, sizeof(apdu_long));
munit_assert_size(g_t1_host_test_state.xfrblock_call_count, ==, 1);
munit_assert_uint8(
g_t1_host_test_state.last_frame[1], ==, (SEADER_T1_PCB_I_BLOCK_MORE | 0x00));
munit_assert_uint8(g_t1_host_test_state.last_frame[2], ==, 2);
munit_assert_not_null(uart.t1.tx_buffer);
munit_assert_size(uart.t1.tx_buffer_offset, ==, 2);
bit_buffer_free(uart.t1.tx_buffer);
return MUNIT_OK;
}
static MunitResult test_recv_ifs_response(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
SeaderUartBridge uart = {0};
SeaderWorker worker = {0};
Seader seader = make_test_seader(&uart, &worker);
t1_host_test_reset();
uint8_t ifs_response[] = {0x00, 0xE1, 0x01, 0x20, 0x00};
seader_add_lrc(ifs_response, 4);
CCID_Message ifs_message = {.payload = ifs_response, .dwLength = 5};
munit_assert_false(seader_recv_t1(&seader, &ifs_message));
munit_assert_size(g_t1_host_test_state.send_version_call_count, ==, 1);
munit_assert_size(g_t1_host_test_state.callback_call_count, ==, 1);
munit_assert_uint32(g_t1_host_test_state.last_callback_event, ==, SeaderWorkerEventSamPresent);
return MUNIT_OK;
}
static MunitResult test_recv_single_i_block(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
SeaderUartBridge uart = {0};
SeaderWorker worker = {0};
Seader seader = make_test_seader(&uart, &worker);
t1_host_test_reset();
uart.t1.recv_pcb = 0x00;
uint8_t i_block[] = {0x00, 0x00, 0x03, 0x11, 0x22, 0x33, 0x00};
seader_add_lrc(i_block, 6);
CCID_Message i_message = {.payload = i_block, .dwLength = 7};
munit_assert_true(seader_recv_t1(&seader, &i_message));
munit_assert_size(g_t1_host_test_state.process_call_count, ==, 1);
munit_assert_true(last_apdu_matches((const uint8_t*)"\x11\x22\x33", 3));
munit_assert_uint8(uart.t1.recv_pcb, ==, 0x40);
return MUNIT_OK;
}
static MunitResult test_recv_chained_i_blocks(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
SeaderUartBridge uart = {0};
SeaderWorker worker = {0};
Seader seader = make_test_seader(&uart, &worker);
t1_host_test_reset();
uart.t1.recv_pcb = 0x00;
uint8_t i_more[] = {0x00, 0x20, 0x03, 0x44, 0x55, 0x66, 0x00};
seader_add_lrc(i_more, 6);
CCID_Message more_message = {.payload = i_more, .dwLength = 7};
munit_assert_false(seader_recv_t1(&seader, &more_message));
munit_assert_size(g_t1_host_test_state.xfrblock_call_count, ==, 1);
munit_assert_not_null(uart.t1.rx_buffer);
munit_assert_uint8(uart.t1.recv_pcb, ==, 0x40);
t1_host_test_reset();
uint8_t i_final[] = {0x00, 0x40, 0x02, 0x77, 0x88, 0x00};
seader_add_lrc(i_final, 5);
CCID_Message final_message = {.payload = i_final, .dwLength = 6};
munit_assert_true(seader_recv_t1(&seader, &final_message));
munit_assert_size(g_t1_host_test_state.process_call_count, ==, 1);
munit_assert_true(last_apdu_matches((const uint8_t*)"\x44\x55\x66\x77\x88", 5));
munit_assert_null(uart.t1.rx_buffer);
return MUNIT_OK;
}
static MunitResult test_recv_ifs_request(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
SeaderUartBridge uart = {0};
SeaderWorker worker = {0};
Seader seader = make_test_seader(&uart, &worker);
t1_host_test_reset();
uart.t1.ifsc = 0x33;
uint8_t ifs_request[] = {0x00, 0xC1, 0x01, 0x20, 0x00};
seader_add_lrc(ifs_request, 4);
CCID_Message ifs_request_message = {.payload = ifs_request, .dwLength = 5};
munit_assert_false(seader_recv_t1(&seader, &ifs_request_message));
munit_assert_size(g_t1_host_test_state.xfrblock_call_count, ==, 1);
munit_assert_true(last_frame_prefix_matches((const uint8_t*)"\x00\xE1\x01\x33", 4));
return MUNIT_OK;
}
static MunitResult test_recv_r_block_resends_buffer(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
SeaderUartBridge uart = {0};
SeaderWorker worker = {0};
Seader seader = make_test_seader(&uart, &worker);
t1_host_test_reset();
uart.t1.send_pcb = 0x00;
uart.t1.tx_buffer = bit_buffer_alloc(8);
bit_buffer_copy_bytes(uart.t1.tx_buffer, (const uint8_t*)"\xA0\xA1\xA2", 3);
uart.t1.tx_buffer_offset = 0;
uart.t1.ifsc = 4;
uint8_t r_block[] = {0x00, 0x90, 0x00, 0x00};
seader_add_lrc(r_block, 3);
CCID_Message r_message = {.payload = r_block, .dwLength = 4};
munit_assert_false(seader_recv_t1(&seader, &r_message));
munit_assert_size(g_t1_host_test_state.xfrblock_call_count, ==, 1);
munit_assert_not_null(uart.t1.tx_buffer);
bit_buffer_free(uart.t1.tx_buffer);
return MUNIT_OK;
}
static MunitResult test_reset_clears_state(const MunitParameter params[], void* fixture) {
(void)params;
(void)fixture;
SeaderUartBridge uart = {0};
uart.t1.nad = 0x77;
uart.t1.send_pcb = 0x00;
uart.t1.recv_pcb = 0x40;
uart.t1.tx_buffer = bit_buffer_alloc(8);
uart.t1.rx_buffer = bit_buffer_alloc(8);
uart.t1.tx_buffer_offset = 3;
seader_t_1_reset(&uart);
munit_assert_uint8(uart.t1.nad, ==, 0x00);
munit_assert_uint8(uart.t1.send_pcb, ==, SEADER_T1_PCB_SEQUENCE_BIT);
munit_assert_uint8(uart.t1.recv_pcb, ==, 0x00);
munit_assert_null(uart.t1.tx_buffer);
munit_assert_null(uart.t1.rx_buffer);
munit_assert_size(uart.t1.tx_buffer_offset, ==, 0);
return MUNIT_OK;
}
static MunitTest test_t1_cases[] = {
{(char*)"/send/ifs-request", test_send_ifs_request, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{(char*)"/send/single-block", test_send_single_block, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{(char*)"/send/scratchpad-block",
test_send_scratchpad_block,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL},
{(char*)"/send/chained-block",
test_send_chained_block,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL},
{(char*)"/recv/ifs-response", test_recv_ifs_response, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{(char*)"/recv/single-i-block",
test_recv_single_i_block,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL},
{(char*)"/recv/chained-i-blocks",
test_recv_chained_i_blocks,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL},
{(char*)"/recv/ifs-request", test_recv_ifs_request, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{(char*)"/recv/r-block-resends-buffer",
test_recv_r_block_resends_buffer,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL},
{(char*)"/reset/clears-state",
test_reset_clears_state,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL},
{NULL, NULL, NULL, NULL, 0, NULL},
};
MunitSuite test_t1_existing_suite = {
"",
test_t1_cases,
NULL,
1,
MUNIT_SUITE_OPTION_NONE,
};
Vendored Submodule
+1
Submodule tests/host/vendor/munit added at fbbdf1467e