# HG changeset patch # User Edouard Tisserant # Date 1679904740 -7200 # Node ID a811e1ff718a5c5afb25e29033b23d0d746f2b84 # Parent 1db10e9df8824b6fd07e2ab883932902f147637b Tests: Add time emulation feature for tests with BEREMIZ_TEST_CYCLES CFLAG. Adding BEREMIZ_TEST_CYCLES=1000 in a project's CFLAGS will: - run 1000 cycles with no pause - emulate time flowing normaly for PLC code - exit PLC thread This allows: - testing standard library blocks that deal with time without having to wait - unit testing and code coverage with POUs that uses time diff -r 1db10e9df882 -r a811e1ff718a targets/Linux/plc_Linux_main.c --- a/targets/Linux/plc_Linux_main.c Sun Mar 12 00:55:19 2023 +0100 +++ b/targets/Linux/plc_Linux_main.c Mon Mar 27 10:12:20 2023 +0200 @@ -117,6 +117,11 @@ struct timespec plc_start_time; #endif +// BEREMIZ_TEST_CYCLES is defined in tests that need to emulate time: +// - all BEREMIZ_TEST_CYCLES cycles are executed in a row with no pause +// - __CURRENT_TIME is incremented each cycle according to emulated cycle period + +#ifndef BEREMIZ_TEST_CYCLES // Sleep until next PLC run res = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_cycle_time, NULL); if(res==EINTR){ @@ -126,6 +131,7 @@ _LogError("PLC thread timer returned error %d \n", res); return; } +#endif // BEREMIZ_TEST_CYCLES #ifdef REALTIME_LINUX // timer overrun detection @@ -137,12 +143,30 @@ } #endif +#ifdef BEREMIZ_TEST_CYCLES +#define xstr(s) str(s) +#define str(arg) #arg + // fake current time + __CURRENT_TIME.tv_sec = next_cycle_time.tv_sec; + __CURRENT_TIME.tv_nsec = next_cycle_time.tv_nsec; + // exit loop when enough cycles + if(__tick >= BEREMIZ_TEST_CYCLES) { + _LogWarning("TEST PLC thread ended after "xstr(BEREMIZ_TEST_CYCLES)" cycles.\n"); + // After pre-defined test cycles count, PLC thread exits. + // Remaining PLC runtime is expected to be cleaned-up/killed by test script + return; + } +#else PLC_GetTime(&__CURRENT_TIME); +#endif __run(); +#ifndef BEREMIZ_TEST_CYCLES // ensure next PLC cycle occurence is in the future clock_gettime(CLOCK_MONOTONIC, &plc_end_time); - while(timespec_gt(plc_end_time, next_cycle_time)){ + while(timespec_gt(plc_end_time, next_cycle_time)) +#endif + { periods += 1; inc_timespec(&next_cycle_time, period_ns); }