@@ -13,6 +13,8 @@ CC ?= gcc
1313PKG_CFG ?= pkg-config
1414CMOCKA_CFLAGS := $(shell $(PKG_CFG ) --cflags cmocka)
1515CMOCKA_LIBS := $(shell $(PKG_CFG ) --libs cmocka)
16+ DPDK_CFLAGS := $(shell $(PKG_CFG ) --cflags libdpdk 2>/dev/null)
17+ DPDK_LIBS := $(shell $(PKG_CFG ) --libs libdpdk 2>/dev/null)
1618
1719# Versions guard (R-U-3 mitigation)
1820CMOCKA_VER := $(shell $(PKG_CFG ) --modversion cmocka 2>/dev/null)
@@ -43,7 +45,8 @@ WRAP_FF_LOG := -Wl,--wrap=rte_openlog_stream \
4345SANITY_TESTS := test_hello
4446P0_TESTS := test_ff_ini_parser test_ff_log
4547P1_TESTS := test_ff_host_interface test_ff_epoll test_ff_config
46- ALL_TESTS := $(SANITY_TESTS ) $(P0_TESTS ) $(P1_TESTS )
48+ P2_TESTS := test_ff_thread test_ff_init test_ff_dpdk_pcap test_ff_dpdk_if
49+ ALL_TESTS := $(SANITY_TESTS ) $(P0_TESTS ) $(P1_TESTS ) $(P2_TESTS )
4750
4851# Common stub objects
4952COMMON_OBJS := $(COMMON_DIR ) /ff_log_stub.o $(COMMON_DIR ) /rte_stub.o
@@ -63,24 +66,33 @@ help:
6366 @echo " make coverage - build with gcov + run tests + emit lcov HTML report"
6467 @echo " make coverage_clean - remove gcov/.gcda/.gcno + coverage_report/"
6568
69+ # Runtime LD path for DPDK shared libs (test_ff_dpdk_if depends on them)
70+ DPDK_RUNPATH := /usr/local/lib64
71+ RUN_ENV := LD_LIBRARY_PATH=$(DPDK_RUNPATH ) :$$LD_LIBRARY_PATH
72+
6673test_sanity : $(SANITY_TESTS )
6774 @for t in $(SANITY_TESTS ) ; do \
68- echo " ==> running $$ t" ; ./$$ t || exit 1; \
75+ echo " ==> running $$ t" ; $( RUN_ENV ) ./$$ t || exit 1; \
6976 done
7077
7178test_p0 : $(P0_TESTS )
7279 @for t in $(P0_TESTS ) ; do \
73- echo " ==> running $$ t" ; ./$$ t || exit 1; \
80+ echo " ==> running $$ t" ; $( RUN_ENV ) ./$$ t || exit 1; \
7481 done
7582
7683test_p1 : $(P1_TESTS )
7784 @for t in $(P1_TESTS ) ; do \
78- echo " ==> running $$ t" ; ./$$ t || exit 1; \
85+ echo " ==> running $$ t" ; $(RUN_ENV ) ./$$ t || exit 1; \
86+ done
87+
88+ test_p2 : $(P2_TESTS )
89+ @for t in $(P2_TESTS ) ; do \
90+ echo " ==> running $$ t" ; $(RUN_ENV ) ./$$ t || exit 1; \
7991 done
8092
8193test : all
8294 @for t in $(ALL_TESTS ) ; do \
83- echo " ==> running $$ t" ; ./$$ t || exit 1; \
95+ echo " ==> running $$ t" ; $( RUN_ENV ) ./$$ t || exit 1; \
8496 done
8597 @echo " ALL TESTS PASS ($( words $( ALL_TESTS) ) binaries)"
8698
@@ -92,7 +104,7 @@ $(LIB_OBJS_DIR):
92104 @mkdir -p $@
93105
94106$(LIB_OBJS_DIR ) /% .o : $(LIB_DIR ) /% .c | $(LIB_OBJS_DIR )
95- $(CC ) $(CFLAGS ) -c $< -o $@
107+ $(CC ) $(CFLAGS ) $( DPDK_CFLAGS ) -c $< -o $@
96108
97109# ----- common stubs -----
98110$(COMMON_DIR ) /% .o : $(COMMON_DIR ) /% .c
@@ -129,6 +141,31 @@ test_ff_epoll: test_ff_epoll.o $(LIB_OBJS_DIR)/ff_epoll.o $(COMMON_OBJS)
129141test_ff_config : test_ff_config.o $(LIB_OBJS_DIR ) /ff_config.o $(LIB_OBJS_DIR ) /ff_ini_parser.o $(COMMON_DIR ) /rte_stub.o
130142 $(CC ) -o $@ $^ $(LDFLAGS_BASE ) $(BASE_WRAPS )
131143
144+ # P2 #1 ff_thread (links real pthread + ff_host_interface for ff_malloc/free;
145+ # the test file ships its own `__thread struct thread *pcurthread` storage)
146+ test_ff_thread : test_ff_thread.o $(LIB_OBJS_DIR ) /ff_thread.o $(LIB_OBJS_DIR ) /ff_host_interface.o $(COMMON_OBJS )
147+ $(CC ) -o $@ $^ $(LDFLAGS_BASE ) $(BASE_WRAPS ) -lpthread -lcrypto
148+
149+ # P2 #2 ff_init (4 init step stubs in test file; exit() wrapped so failure
150+ # paths surface as cmocka assertion failures rather than process death)
151+ WRAP_FF_INIT := -Wl,--wrap=exit
152+ test_ff_init : test_ff_init.o $(LIB_OBJS_DIR ) /ff_init.o
153+ $(CC ) -o $@ $^ $(LDFLAGS_BASE ) $(WRAP_FF_INIT )
154+
155+ # P2 #3 ff_dpdk_pcap (rte_lcore_id is inline, intercepted via TLS variable
156+ # definition in the test file; rte_exit covered by BASE_WRAPS)
157+ test_ff_dpdk_pcap : test_ff_dpdk_pcap.o $(LIB_OBJS_DIR ) /ff_dpdk_pcap.o $(COMMON_DIR ) /rte_stub.o
158+ $(CC ) -o $@ $^ $(LDFLAGS_BASE ) $(BASE_WRAPS ) -lpthread
159+
160+ # P2 #4 ff_dpdk_if (trivial 7-function subset; rte_get_tsc_hz wrapped;
161+ # many dpdk/ff_* refs stubbed in the test file. We DO link the real DPDK
162+ # shared libraries to resolve the bulk of rte_eth_*/rte_timer_*/etc. that
163+ # ff_dpdk_if.o references but our 7 tests never invoke. -lrte_net_bond
164+ # pulls in the bond PMD which is not in the default libdpdk umbrella.)
165+ WRAP_FF_DPDKIF := -Wl,--wrap=rte_get_tsc_hz
166+ test_ff_dpdk_if : test_ff_dpdk_if.o $(LIB_OBJS_DIR ) /ff_dpdk_if.o $(COMMON_DIR ) /rte_stub.o
167+ $(CC ) -o $@ $^ $(LDFLAGS_BASE ) $(BASE_WRAPS ) $(WRAP_FF_DPDKIF ) $(DPDK_LIBS ) -lrte_net_bond -Wl,-rpath=/usr/local/lib64 -lpthread -lcrypto -ldl -lm
168+
132169# ----- clean (NFR-U-7: must use workspace wrapper, no direct rm) -----
133170clean :
134171 @find . -name ' *.o' -type f -print 2> /dev/null | while read f; do \
0 commit comments