`cannot move location counter backwards (from 0000000020020018 to 0000000020020000)`
This means that rusEFI is out of memory.
Down at the end of engine_controller.cpp there's a dummy array that keeps track of how much free space we have. You can shrink that to give your code room to fit.
All tests are run in one instance, but each test gets its own EngineTestHelper, which calls commonInitEngineController, so your objects need to gracefully handle being initiated multiple times.
For CONFIG(...) to work in tests, you need a DECLARE_ENGINE_PTR; in the class declaration, then an INJECT_ENGINE_REFERENCE(&myObject), at some point during init.
Time doesn't pass in tests. If you need time to pass, you have to do it manually.
Unit tests will run under various tools that check for memory or other violations ("Sanitizers" such as AddressSanitizer or Valgrind). For performance reasons, some of these are only run at GitHub actions, but if you need to you can run them yourself.
* Unit tests by default are built for AddressSanitizer. You can disable this by running `make SANITIZE=no`. This will detect memory overruns and underruns, although it won't detect overruns within a struct (for example, running off the end of an array that happens to land on some unrelated-but-valid memory after the array but is still in the struct).
* Unit tests on GitHub are also built for AddressSanitizer, but add an additional check for stack use after free. You can mimic this yourself by running tests as `ASAN_OPTIONS=detect_stack_use_after_return=1 build/rusefi_test`
* Unit tests on GitHub are also run under Valgrind. This helps detect using uninitialized memory, among other differences. In order to run under Valgrind, you must first compile without ASAN: `make SANITIZE=no` then run as `valgrind build/rusefi_test`. You have to scan through stderr to find the errors of interest, so you can run: `valgrind build/rusefi_test > /dev/null`.