Skip to content

Commit 0974c6b

Browse files
committed
fix(mdns): Add receiver unit tests
1 parent 6db95af commit 0974c6b

File tree

12 files changed

+611
-258
lines changed

12 files changed

+611
-258
lines changed

.github/workflows/mdns__host-tests.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,33 @@ jobs:
7272
echo "OK"
7373
done
7474
75+
host_unit_test:
76+
if: contains(github.event.pull_request.labels.*.name, 'mdns') || github.event_name == 'push'
77+
name: Unit tests on host
78+
strategy:
79+
matrix:
80+
idf_ver: ["latest"]
81+
82+
runs-on: ubuntu-22.04
83+
container: espressif/idf:${{ matrix.idf_ver }}
84+
steps:
85+
- name: Checkout esp-protocols
86+
uses: actions/checkout@v4
87+
- name: Install bsdlib and ruby
88+
run: |
89+
apt-get update -y
90+
apt-get install -y libbsd-dev ruby
91+
- name: Build and run unit tests
92+
shell: bash
93+
run: |
94+
. ${IDF_PATH}/export.sh
95+
cd components/mdns/tests/host_unit_test/
96+
idf.py reconfigure
97+
mkdir build2 && cd build2
98+
cmake -DUNIT_TESTS=test_receiver ..
99+
cmake --build .
100+
ctest --extra-verbose
101+
75102
76103
fuzz_test:
77104
if: contains(github.event.pull_request.labels.*.name, 'mdns-fuzz') || github.event_name == 'push'
Lines changed: 31 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,35 @@
11
cmake_minimum_required(VERSION 3.5)
22
if(ESP_PLATFORM)
3+
# Used for reconfiguration of the project
4+
# Executed by idf.py reconfigure
35
set(EXTRA_COMPONENT_DIRS ../../)
46
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
57
project(mdns_host_unit_test_config)
68
return()
7-
endif ()
9+
endif()
810

911
project(mdns_host_unit_test C)
1012

13+
# Set ENABLE_UNIT_TESTS with a default of OFF
14+
if(NOT DEFINED UNIT_TESTS)
15+
set(UNIT_TESTS "OFF" CACHE STRING "Unit tests: OFF, test_receiver, test_sender")
16+
else()
17+
set(ENABLE_UNIT_TESTS 1)
18+
message(STATUS "Unit testing enabled with UNIT_TESTS=${UNIT_TESTS}")
19+
endif()
20+
1121
# Set variables for directories
1222
set(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR})
23+
set(STUB_DIR ${TEST_DIR}/stubs)
24+
set(MDNS_DIR ${TEST_DIR}/../../)
1325
set(COMPONENT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../)
1426
set(ESP_NETIF_LINUX_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../host_test/components/esp_netif_linux/include)
1527
set(COMMON_COMPONENTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../common_components/linux_compat/)
1628
set(IDF_COMPONENTS_DIR "$ENV{IDF_PATH}/components")
1729

18-
# Debug prints to see directory values
19-
message(STATUS "TEST_DIR: ${TEST_DIR}")
20-
message(STATUS "COMPONENT_DIR: ${COMPONENT_DIR}")
21-
22-
# Include directories for the test files and other required files
2330
include_directories(
2431
${TEST_DIR}
25-
${TEST_DIR}/stubs
32+
${STUB_DIR}
2633
${TEST_DIR}/build/config
2734
${COMMON_COMPONENTS_DIR}/freertos/include
2835
${COMMON_COMPONENTS_DIR}/esp_timer/include
@@ -40,175 +47,39 @@ include_directories(
4047
${COMPONENT_DIR}/private_include
4148
)
4249

43-
# Unity testing framework
44-
set(UNITY_DIR "$ENV{IDF_PATH}/components/unity")
45-
include_directories(${UNITY_DIR}/unity/src)
46-
47-
# Add option to enable unit testing
48-
option(ENABLE_UNIT_TESTS "Enable Unity-based unit tests" OFF)
49-
50-
# Add preprocessor definition based on the option
51-
if(ENABLE_UNIT_TESTS)
52-
add_definitions(-DENABLE_UNIT_TESTS)
53-
endif()
54-
55-
# Add CMock options
56-
if(ENABLE_UNIT_TESTS)
57-
# CMock paths
58-
set(CMOCK_DIR "$ENV{IDF_PATH}/components/cmock")
59-
60-
# Use ruby command directly instead of looking for ruby.exe
61-
find_program(RUBY_EXECUTABLE ruby)
62-
if(NOT RUBY_EXECUTABLE)
63-
message(FATAL_ERROR "Ruby is required for CMock but was not found!")
64-
endif()
65-
66-
# Define list of files to mock
67-
set(MOCK_FILES
68-
"mdns_pcb"
69-
"mdns_send"
70-
# Add more files here as needed, without .h extension
71-
)
72-
73-
# Verify headers exist and create mock commands for each
74-
foreach(mock_file ${MOCK_FILES})
75-
set(header_path "${COMPONENT_DIR}/private_include/${mock_file}.h")
76-
if(NOT EXISTS ${header_path})
77-
message(FATAL_ERROR "Cannot find ${mock_file}.h at ${header_path}")
78-
endif()
79-
80-
list(APPEND MOCK_OUTPUTS
81-
${CMAKE_CURRENT_BINARY_DIR}/mocks/mock_${mock_file}.c
82-
${CMAKE_CURRENT_BINARY_DIR}/mocks/mock_${mock_file}.h
83-
)
84-
85-
add_custom_command(
86-
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mocks/mock_${mock_file}.c
87-
${CMAKE_CURRENT_BINARY_DIR}/mocks/mock_${mock_file}.h
88-
COMMAND ${RUBY_EXECUTABLE}
89-
${CMOCK_DIR}/CMock/lib/cmock.rb
90-
-o${CMAKE_CURRENT_SOURCE_DIR}/cmock_config.yml
91-
${header_path}
92-
DEPENDS ${header_path}
93-
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
94-
COMMENT "Generating mock for ${mock_file}.h"
95-
)
96-
endforeach()
97-
98-
# Include CMock headers
99-
include_directories(
100-
${CMOCK_DIR}/CMock/src
101-
${CMAKE_CURRENT_BINARY_DIR}/mocks
102-
${UNITY_DIR}/unity/src
103-
${UNITY_DIR}/include
104-
)
105-
106-
# Create directory for generated mocks
107-
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mocks)
108-
109-
# Create CMock config file if it doesn't exist
110-
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/cmock_config.yml)
111-
file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/cmock_config.yml
112-
"---
113-
:cmock:
114-
:mock_prefix: mock_
115-
:plugins:
116-
- :callback
117-
- :ignore
118-
- :expect_any_args
119-
- :array
120-
- :return_thru_ptr
121-
:strippables:
122-
- '(?:extern|static)\\s+'
123-
:treat_as:
124-
uint8_t: HEX8
125-
uint16_t: HEX16
126-
uint32_t: UINT32
127-
int8_t: INT8
128-
bool: UINT8"
129-
)
130-
endif()
131-
endif()
132-
13350
# Source files
13451
set(SOURCES
135-
${CMAKE_CURRENT_SOURCE_DIR}/main.c
136-
${CMAKE_CURRENT_SOURCE_DIR}/stubs/mdns_mem_caps.c
137-
${CMAKE_CURRENT_SOURCE_DIR}/stubs/esp_idf.c
138-
${CMAKE_CURRENT_SOURCE_DIR}/stubs/mdns_networking.c
139-
${CMAKE_CURRENT_SOURCE_DIR}/stubs/mdns_engine.c
140-
${CMAKE_CURRENT_SOURCE_DIR}/../../mdns_receive.c
141-
${CMAKE_CURRENT_SOURCE_DIR}/../../mdns_utils.c
142-
${CMAKE_CURRENT_SOURCE_DIR}/../../mdns_browser.c
143-
${CMAKE_CURRENT_SOURCE_DIR}/../../mdns_querier.c
144-
${CMAKE_CURRENT_SOURCE_DIR}/../../mdns_responder.c
145-
${CMAKE_CURRENT_SOURCE_DIR}/../../mdns_send.c
146-
${CMAKE_CURRENT_SOURCE_DIR}/../../mdns_pcb.c
147-
${CMAKE_CURRENT_SOURCE_DIR}/../../mdns_netif.c
52+
${STUB_DIR}/mdns_mem_caps.c
53+
${STUB_DIR}/esp_idf.c
54+
${STUB_DIR}/mdns_networking.c
55+
${STUB_DIR}/mdns_engine.c
56+
${MDNS_DIR}/mdns_receive.c
57+
${MDNS_DIR}/mdns_utils.c
58+
${MDNS_DIR}/mdns_browser.c
59+
${MDNS_DIR}/mdns_querier.c
60+
${MDNS_DIR}/mdns_responder.c
61+
${MDNS_DIR}/mdns_send.c
62+
${MDNS_DIR}/mdns_pcb.c
63+
${MDNS_DIR}/mdns_netif.c
14864
)
14965

15066
if(ENABLE_UNIT_TESTS)
151-
# Remove real implementations of mocked files
152-
foreach(mock_file ${MOCK_FILES})
153-
list(REMOVE_ITEM SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../../${mock_file}.c)
154-
endforeach()
155-
156-
# Add test-related sources
157-
list(APPEND SOURCES
158-
${UNITY_DIR}/unity/src/unity.c
159-
${CMOCK_DIR}/CMock/src/cmock.c
160-
)
161-
162-
# Add all generated mock files
163-
foreach(mock_file ${MOCK_FILES})
164-
list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/mocks/mock_${mock_file}.c)
165-
endforeach()
67+
include(unity/unit_test.cmake)
68+
else()
69+
list(APPEND SOURCES main.c)
16670
endif()
16771

168-
# Enable sanitizers
169-
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
170-
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
171-
172-
# Setting C flags with debug symbols and disable optimization for better debugging
173-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0")
174-
175-
# Create the test executable
17672
add_executable(${PROJECT_NAME} ${SOURCES})
17773

74+
# Add libbsd if available
17875
find_library(LIB_BSD bsd)
17976
if(LIB_BSD)
18077
target_link_libraries(${PROJECT_NAME} PRIVATE ${LIB_BSD})
18178
elseif(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
18279
message(WARNING "Missing LIBBSD library. Install libbsd-dev package and/or check linker directories.")
18380
endif()
184-
# Setting C flags
185-
#set_target_properties(${PROJECT_NAME} PROPERTIES
186-
# C_STANDARD 99
187-
# COMPILE_FLAGS "-Wall -Werror"
188-
#)
18981

19082
# Enable testing if unit tests are enabled
19183
if(ENABLE_UNIT_TESTS)
192-
enable_testing()
193-
add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME} --test)
194-
endif()
195-
196-
# Add libbsd dependency
197-
#find_package(PkgConfig REQUIRED)
198-
#pkg_check_modules(LIBBSD REQUIRED libbsd-overlay)
199-
200-
# Link against libbsd for strlcat
201-
#target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBBSD_LIBRARIES})
202-
#target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=address -fsanitize=undefined)
203-
#target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=address -fsanitize=undefined)
204-
205-
# Add include directories if needed
206-
#target_include_directories(${PROJECT_NAME} PRIVATE ${LIBBSD_INCLUDE_DIRS})
207-
208-
# Add mock generation as dependency
209-
if(ENABLE_UNIT_TESTS)
210-
add_custom_target(generate_mocks
211-
DEPENDS ${MOCK_OUTPUTS}
212-
)
213-
add_dependencies(${PROJECT_NAME} generate_mocks)
84+
include(unity/enable_testing.cmake)
21485
endif()

components/mdns/tests/host_unit_test/main.c

Lines changed: 0 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,9 @@
88
#include <stdint.h>
99
#include <unistd.h>
1010
#include "esp_err.h"
11-
#include "unity.h"
1211
#include "mdns_receive.h"
1312
#include "mdns_responder.h"
1413
#include "mdns_mem_caps.h"
15-
#ifdef ENABLE_UNIT_TESTS
16-
#include "mock_mdns_pcb.h"
17-
#include "mock_mdns_send.h"
18-
19-
void setUp(void)
20-
{
21-
}
22-
23-
void tearDown(void)
24-
{
25-
}
26-
27-
// Sample test case - update based on the actual functionality in mdns_receive.c
28-
void test_mdns_receive_initialization(void)
29-
{
30-
// mdns_priv_probe_all_pcbs_ExpectAnyArgs();
31-
// Example of using mocks
32-
// mock_mdns_pcb_init_ExpectAndReturn(ESP_OK);
33-
// Add more mock expectations as needed
34-
}
35-
36-
#endif
3714

3815
esp_err_t mdns_packet_push(esp_ip_addr_t *addr, int port, mdns_if_t tcpip_if, uint8_t*data, size_t len);
3916

@@ -71,7 +48,6 @@ void init_responder(void)
7148
s_ptr = mdns_query_async_new("minifritz", "_http", "_tcp", MDNS_TYPE_PTR, 1000, 1, NULL);
7249
s_srv = mdns_query_async_new("fritz", "_http", "_tcp", MDNS_TYPE_SRV, 1000, 1, NULL);
7350
s_txt = mdns_query_async_new("fritz", "_http", "_tcp", MDNS_TYPE_TXT, 1000, 1, NULL);
74-
7551
}
7652

7753
void deinit_responder(void)
@@ -97,80 +73,8 @@ static void send_packet(bool ip4, bool mdns_port, uint8_t*data, size_t len)
9773
}
9874
}
9975

100-
#ifdef ENABLE_UNIT_TESTS
101-
// Add new test cases for mdns_receive
102-
void test_mdns_receive_from_file(const char* filename)
103-
{
104-
uint8_t buf[1460];
105-
FILE *file = fopen(filename, "r");
106-
TEST_ASSERT_NOT_NULL_MESSAGE(file, "Failed to open test packet file");
107-
108-
size_t len = fread(buf, 1, 1460, file);
109-
fclose(file);
110-
111-
// Test with different packet configurations
112-
send_packet(true, true, buf, len);
113-
send_packet(true, false, buf, len);
114-
send_packet(false, true, buf, len);
115-
send_packet(false, false, buf, len);
116-
117-
// Add assertions here based on expected behavior
118-
// For example:
119-
// TEST_ASSERT_EQUAL(expected_result, actual_result);
120-
}
121-
122-
void run_unity_tests(int argc, char **argv)
123-
{
124-
UNITY_BEGIN();
125-
126-
// Run basic initialization test
127-
RUN_TEST(test_mdns_receive_initialization);
128-
129-
// If a packet file is provided as argument, run packet-based tests
130-
if (argc > 2 && strcmp(argv[1], "--test") == 0) {
131-
for (int i = 2; i < argc; i++) {
132-
printf("Testing with packet file: %s\n", argv[i]);
133-
test_mdns_receive_from_file(argv[i]);
134-
}
135-
}
136-
137-
UNITY_END();
138-
}
139-
140-
void mdns_priv_probe_all_pcbs_Callback(mdns_srv_item_t** services, size_t len, bool probe_ip, bool clear_old_probe, int cmock_num_calls)
141-
{
142-
143-
}
144-
145-
void mdns_priv_create_answer_from_parsed_packet_Callback(mdns_parsed_packet_t* parsed_packet, int cmock_num_calls)
146-
{
147-
printf("callback\n");
148-
}
149-
#endif
150-
15176
int main(int argc, char **argv)
15277
{
153-
#ifdef ENABLE_UNIT_TESTS
154-
if (argc >= 2 && strcmp(argv[1], "--test") == 0) {
155-
mdns_priv_probe_all_pcbs_CMockIgnore();
156-
mdns_priv_pcb_announce_CMockIgnore();
157-
mdns_priv_pcb_send_bye_service_CMockIgnore();
158-
mdns_priv_pcb_check_probing_services_CMockIgnore();
159-
mdns_priv_pcb_is_after_probing_IgnoreAndReturn(true);
160-
161-
_mdns_clear_tx_queue_head_CMockIgnore();
162-
_mdns_remove_scheduled_service_packets_CMockIgnore();
163-
mdns_priv_create_answer_from_parsed_packet_Stub(mdns_priv_create_answer_from_parsed_packet_Callback);
164-
// mdns_priv_probe_all_pcbs_AddCallback(mdns_priv_probe_all_pcbs_Callback);
165-
// mdns_priv_probe_all_pcbs_ExpectAnyArgs();
166-
167-
init_responder();
168-
run_unity_tests(argc, argv);
169-
deinit_responder();
170-
return 0;
171-
}
172-
#endif
173-
17478
init_responder();
17579

17680
// Original fuzzing code
@@ -202,7 +106,5 @@ int main(int argc, char **argv)
202106
}
203107
deinit_responder();
204108

205-
// ... rest of the existing fuzzing code ...
206-
207109
return 0;
208110
}

0 commit comments

Comments
 (0)