"""Run the actual GNSS parser and power-state paths with logging off and on.""" from pathlib import Path import re import subprocess import tempfile root = Path(__file__).resolve().parents[1] app = root / 'ql-application/threadx/interface/custom_app' source = (app / 'gnss.c').read_text() source = re.sub(r'^#include "(?!app_gnss_log.h")[^"]+"\n', '', source, flags=re.M) harness = r''' #include #include #include #include #include #include #include typedef unsigned int u32; typedef unsigned char u8; typedef void *ql_task_t; typedef enum { GNSS_MODE_FAST, GNSS_MODE_SLOW } gnss_mode_t; typedef struct { double latitude, longitude; int is_valid; char raw_nmea[512]; } gps_location_info_t; enum { AGPS_GNSS_ENABLE, APFLASH_GNSS_ENABLE, PACKET_MODE }; static unsigned int now; static int scenario, opened, closed, printed; static jmp_buf stop; static unsigned int hal_os_up_time_ms(void) { return now; } static int test_printf(const char *format, ...) { (void)format; printed++; return 0; } #define printf test_printf static int ql_gnss_close(void) { closed++; return 0; } static int ql_gnss_open(void (*cb)(char *, int)) { (void)cb; opened++; return 0; } static void app_set_app_operation(int value) { assert(value == 1); } static void ql_gnss_cfgsys_set(int value) { (void)value; } static void ql_gnss_cfgmsg_set(int value) { (void)value; } static void ql_gnss_agps_cfg(int value, int extra) { (void)value; (void)extra; } static void ql_gnss_apflash_cfg(int value) { (void)value; } static void ql_set_gnss_nmea_mode(int value) { (void)value; } static void ql_rtos_task_sleep_s(int seconds); static void ql_rtos_task_create(ql_task_t *task, int stack, int priority, char *name, void (*entry)(void *), void *arg) { (void)task; (void)stack; (void)priority; (void)name; (void)entry; (void)arg; } ''' harness += source harness += r''' #undef printf static void ql_rtos_task_sleep_s(int seconds) { if (closed) longjmp(stop, 1); now += (unsigned int)seconds * 1000; if (scenario == 1) g_gnss_sat_count = 2; if (scenario == 2) { g_gnss_sat_count = 4; g_gps_location.is_valid = 1; } assert(now < 1000000); } int main(void) { (void)test_printf; char data[] = "$GPGGA,120000,2311.71298,N,11328.63118,E,1,08,0.9,10,M,0,M,0,0*00\r\n" "$GPGSV,1,1,08,01,10,10,30*00\r\n"; quec_gnss_callback(data, (int)strlen(data)); assert(g_gps_location.is_valid && g_gnss_sat_count == 8); assert(fabs(g_gps_location.latitude - 23.1952163333) < 0.000001); assert(fabs(g_gps_location.longitude - 113.4771863333) < 0.000001); assert(strncmp(g_gps_location.raw_nmea, "$GPGGA,", 7) == 0); print_gps_location_info(); set_gnss_mode(GNSS_MODE_FAST); assert(get_gnss_mode() == GNSS_MODE_FAST && get_gnss_interval() == 180); for (scenario = 0; scenario < 4; scenario++) { now = 1; opened = closed = 0; gnss_is_open = 0; g_gnss_mode = scenario == 3 ? GNSS_MODE_FAST : GNSS_MODE_SLOW; if (!setjmp(stop)) quec_gnss_test(NULL); assert(opened == 1 && closed == 1 && get_gnss_open_status() == 0); } #if APP_GNSS_LOG_ENABLED assert(printed > 0); #else assert(printed == 0); #endif puts("PASS: GNSS parsing and all four hardware-close paths preserved; expected log visibility"); } ''' with tempfile.TemporaryDirectory(prefix='banban-gnss-log-') as directory: cfile = Path(directory) / 'gnss-test.c' cfile.write_text(harness) for enabled in (0, 1): exe = Path(directory) / f'gnss-test-{enabled}' subprocess.run(['cc', '-std=c99', '-Wall', '-Wextra', '-Werror', '-Wno-unused-parameter', '-Wno-unused-variable', '-Wno-sign-compare', '-fsanitize=address,undefined', f'-DAPP_GNSS_LOG_ENABLED={enabled}', '-I' + str(app / 'inc'), str(cfile), '-o', str(exe)], check=True) subprocess.run([str(exe)], check=True)