Makefile
1 ################################################################################ 2 # Makefile -- MCU firmware unit test harness for AERIS-10 3 # 4 # Builds and runs host-side (macOS) tests for all discovered firmware bugs. 5 # Uses mock HAL + spy/recording pattern to test real firmware code without 6 # hardware. 7 # 8 # Usage: 9 # make -- build and run all tests 10 # make build -- build all tests without running 11 # make test -- run all tests 12 # make clean -- remove build artifacts 13 # make test_bug1 -- build and run just bug1 test 14 # 15 # Requirements: Apple Clang or gcc (any C11-capable compiler) 16 ################################################################################ 17 18 CC := cc 19 CFLAGS := -std=c11 -Wall -Wextra -Wno-unused-parameter -g -O0 20 # Shim headers come FIRST so they override real headers 21 INCLUDES := -Ishims -I. -I../9_1_1_C_Cpp_Libraries 22 23 # Real source files compiled against mock headers 24 REAL_SRC := ../9_1_1_C_Cpp_Libraries/adf4382a_manager.c 25 26 # Mock/stub object files (shared across tests) 27 MOCK_SRCS := stm32_hal_mock.c ad_driver_mock.c 28 MOCK_OBJS := $(MOCK_SRCS:.c=.o) 29 30 # Real source compiled as object (for tests that need it) 31 REAL_OBJ := adf4382a_manager.o 32 33 # Platform source compiled with shim headers 34 PLATFORM_SRC := ../9_1_1_C_Cpp_Libraries/platform_noos_stm32.c 35 PLATFORM_OBJ := platform_noos_stm32.o 36 37 # Tests that link against real adf4382a_manager.c + mocks 38 TESTS_WITH_REAL := test_bug1_timed_sync_init_ordering \ 39 test_bug3_timed_sync_noop \ 40 test_bug4_phase_shift_before_check \ 41 test_bug5_fine_phase_gpio_only \ 42 test_bug9_platform_ops_null \ 43 test_bug10_spi_cs_not_toggled \ 44 test_bug15_htim3_dangling_extern 45 46 # Tests that only need mocks (extracted patterns / static analysis) 47 TESTS_MOCK_ONLY := test_bug2_ad9523_double_setup \ 48 test_bug6_timer_variable_collision \ 49 test_bug7_gpio_pin_conflict \ 50 test_bug8_uart_commented_out \ 51 test_bug14_diag_section_args \ 52 test_gap3_emergency_stop_rails 53 54 # Tests that are standalone (no mocks needed, pure logic) 55 TESTS_STANDALONE := test_bug12_pa_cal_loop_inverted \ 56 test_bug13_dac2_adc_buffer_mismatch \ 57 test_gap3_iwdg_config \ 58 test_gap3_temperature_max \ 59 test_gap3_idq_periodic_reread \ 60 test_gap3_emergency_state_ordering 61 62 # Tests that need platform_noos_stm32.o + mocks 63 TESTS_WITH_PLATFORM := test_bug11_platform_spi_transmit_only 64 65 ALL_TESTS := $(TESTS_WITH_REAL) $(TESTS_MOCK_ONLY) $(TESTS_STANDALONE) $(TESTS_WITH_PLATFORM) 66 67 .PHONY: all build test clean \ 68 $(addprefix test_,bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 bug14 bug15) \ 69 test_gap3_estop test_gap3_iwdg test_gap3_temp test_gap3_idq test_gap3_order 70 71 all: build test 72 73 build: $(ALL_TESTS) 74 75 test: build 76 @echo "===============================================" 77 @echo " Running all $(words $(ALL_TESTS)) bug tests..." 78 @echo "===============================================" 79 @pass=0; fail=0; \ 80 for t in $(ALL_TESTS); do \ 81 echo "--- Running $$t ---"; \ 82 ./$$t; \ 83 if [ $$? -eq 0 ]; then \ 84 pass=$$((pass + 1)); \ 85 else \ 86 fail=$$((fail + 1)); \ 87 echo "*** FAILED: $$t ***"; \ 88 fi; \ 89 done; \ 90 echo "==============================================="; \ 91 echo " Results: $$pass passed, $$fail failed (of $(words $(ALL_TESTS)) total)"; \ 92 echo "==============================================="; \ 93 [ $$fail -eq 0 ] 94 95 # --- Object file rules --- 96 97 %.o: %.c 98 $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ 99 100 # Real source compiled with shim headers 101 $(REAL_OBJ): $(REAL_SRC) $(MOCK_OBJS) 102 $(CC) $(CFLAGS) $(INCLUDES) -c $(REAL_SRC) -o $@ 103 104 # Platform source compiled with shim headers 105 $(PLATFORM_OBJ): $(PLATFORM_SRC) $(MOCK_OBJS) 106 $(CC) $(CFLAGS) $(INCLUDES) -c $(PLATFORM_SRC) -o $@ 107 108 # --- Test binary rules --- 109 110 # Tests that need real adf4382a_manager.o + mocks 111 $(TESTS_WITH_REAL): %: %.c $(MOCK_OBJS) $(REAL_OBJ) 112 $(CC) $(CFLAGS) $(INCLUDES) $< $(MOCK_OBJS) $(REAL_OBJ) -o $@ 113 114 # Tests that only need mocks 115 test_bug2_ad9523_double_setup: test_bug2_ad9523_double_setup.c $(MOCK_OBJS) 116 $(CC) $(CFLAGS) $(INCLUDES) $< $(MOCK_OBJS) -o $@ 117 118 test_bug6_timer_variable_collision: test_bug6_timer_variable_collision.c $(MOCK_OBJS) 119 $(CC) $(CFLAGS) $(INCLUDES) $< $(MOCK_OBJS) -o $@ 120 121 # Bug 7 needs shim headers + mock objects (post-fix test includes shim adf4382a_manager.h) 122 test_bug7_gpio_pin_conflict: test_bug7_gpio_pin_conflict.c $(MOCK_OBJS) 123 $(CC) $(CFLAGS) $(INCLUDES) $< $(MOCK_OBJS) -o $@ 124 125 test_bug8_uart_commented_out: test_bug8_uart_commented_out.c 126 $(CC) $(CFLAGS) -I. $< -o $@ 127 128 test_bug14_diag_section_args: test_bug14_diag_section_args.c $(MOCK_OBJS) 129 $(CC) $(CFLAGS) $(INCLUDES) $< $(MOCK_OBJS) -o $@ 130 131 # Standalone tests (pure logic, no mocks) 132 test_bug12_pa_cal_loop_inverted: test_bug12_pa_cal_loop_inverted.c 133 $(CC) $(CFLAGS) $< -lm -o $@ 134 135 test_bug13_dac2_adc_buffer_mismatch: test_bug13_dac2_adc_buffer_mismatch.c 136 $(CC) $(CFLAGS) $< -lm -o $@ 137 138 # Gap-3 safety tests -- mock-only (needs spy log for GPIO sequence) 139 test_gap3_emergency_stop_rails: test_gap3_emergency_stop_rails.c $(MOCK_OBJS) 140 $(CC) $(CFLAGS) $(INCLUDES) $< $(MOCK_OBJS) -o $@ 141 142 # Gap-3 safety tests -- standalone (pure logic) 143 test_gap3_iwdg_config: test_gap3_iwdg_config.c 144 $(CC) $(CFLAGS) $< -lm -o $@ 145 146 test_gap3_temperature_max: test_gap3_temperature_max.c 147 $(CC) $(CFLAGS) $< -lm -o $@ 148 149 test_gap3_idq_periodic_reread: test_gap3_idq_periodic_reread.c 150 $(CC) $(CFLAGS) $< -lm -o $@ 151 152 test_gap3_emergency_state_ordering: test_gap3_emergency_state_ordering.c 153 $(CC) $(CFLAGS) $< -o $@ 154 155 # Tests that need platform_noos_stm32.o + mocks 156 $(TESTS_WITH_PLATFORM): %: %.c $(MOCK_OBJS) $(PLATFORM_OBJ) 157 $(CC) $(CFLAGS) $(INCLUDES) $< $(MOCK_OBJS) $(PLATFORM_OBJ) -o $@ 158 159 # --- Individual test targets --- 160 161 test_bug1: test_bug1_timed_sync_init_ordering 162 ./test_bug1_timed_sync_init_ordering 163 164 test_bug2: test_bug2_ad9523_double_setup 165 ./test_bug2_ad9523_double_setup 166 167 test_bug3: test_bug3_timed_sync_noop 168 ./test_bug3_timed_sync_noop 169 170 test_bug4: test_bug4_phase_shift_before_check 171 ./test_bug4_phase_shift_before_check 172 173 test_bug5: test_bug5_fine_phase_gpio_only 174 ./test_bug5_fine_phase_gpio_only 175 176 test_bug6: test_bug6_timer_variable_collision 177 ./test_bug6_timer_variable_collision 178 179 test_bug7: test_bug7_gpio_pin_conflict 180 ./test_bug7_gpio_pin_conflict 181 182 test_bug8: test_bug8_uart_commented_out 183 ./test_bug8_uart_commented_out 184 185 test_bug9: test_bug9_platform_ops_null 186 ./test_bug9_platform_ops_null 187 188 test_bug10: test_bug10_spi_cs_not_toggled 189 ./test_bug10_spi_cs_not_toggled 190 191 test_bug11: test_bug11_platform_spi_transmit_only 192 ./test_bug11_platform_spi_transmit_only 193 194 test_bug12: test_bug12_pa_cal_loop_inverted 195 ./test_bug12_pa_cal_loop_inverted 196 197 test_bug13: test_bug13_dac2_adc_buffer_mismatch 198 ./test_bug13_dac2_adc_buffer_mismatch 199 200 test_bug14: test_bug14_diag_section_args 201 ./test_bug14_diag_section_args 202 203 test_bug15: test_bug15_htim3_dangling_extern 204 ./test_bug15_htim3_dangling_extern 205 206 test_gap3_estop: test_gap3_emergency_stop_rails 207 ./test_gap3_emergency_stop_rails 208 209 test_gap3_iwdg: test_gap3_iwdg_config 210 ./test_gap3_iwdg_config 211 212 test_gap3_temp: test_gap3_temperature_max 213 ./test_gap3_temperature_max 214 215 test_gap3_idq: test_gap3_idq_periodic_reread 216 ./test_gap3_idq_periodic_reread 217 218 test_gap3_order: test_gap3_emergency_state_ordering 219 ./test_gap3_emergency_state_ordering 220 221 # --- Clean --- 222 223 clean: 224 rm -f *.o $(ALL_TESTS) 225 @echo "Clean complete"