arduino_ci
arduino_ci copied to clipboard
Add unittest compilation tests for libraries that include only parts of Arduino
Feature Request
Libraries may include some/all of the following, without the full Arduino headers:
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
Further discussion in https://github.com/ianfixes/arduino_ci/pull/115#issuecomment-466802772
These libraries need to be unit tested by arduino_ci's own CI, to ensure that they properly compile.
Most likely, this would involve additional example libraries that include those features. InterruptSomething, IOSomething, PGMSomething are possible library names.
This also applies to:
#include <avr/sleep.h>
#include <avr/wdt.h>
Excellent! I'll make tests for each of these.
Actually, this can be generalized because in principle any header file should be possible to include just by itself, and thus tests for that can be generated just by iterating the header file names.
Now there are some of <avr/io.h>'s sub header files that are not supposed to be included directly and many of them will explicitly fail to compile. But that is fine, we just1 exclude testing those since they are not relevant for such testing.
1With "just" not being that trivial since some of them are just wrapper includes that contain nothing to directly indicate the file it includes are one of those not intended for direct inclusion. But it is doable, here is a script that generates test files with explicit blacklist of those not easily detectable:
#!/bin/bash
rm -f header_test_*.cpp
i=0
for file in `find ../../../cpp/arduino -name '*.hpp' -print -o -name '*.h' -print | cut -d/ -f6-`
do
if egrep -q "Include <avr/io.h> instead of this file|Attempt to include more than one <avr/ioXXX.h>" ../../../cpp/arduino/$file
then
continue
fi
# Wrapper files
case $file in
avr/iocan128.h) continue ;;
avr/iocan32.h) continue ;;
avr/iocan64.h) continue ;;
avr/iom1280.h) continue ;;
avr/iom1281.h) continue ;;
avr/iom164.h) continue ;;
avr/iom164a.h) continue ;;
avr/iom164p.h) continue ;;
avr/iom168.h) continue ;;
avr/iom168a.h) continue ;;
avr/iom169a.h) continue ;;
avr/iom16hva.h) continue ;;
avr/iom2560.h) continue ;;
avr/iom2561.h) continue ;;
avr/iom3250a.h) continue ;;
avr/iom3250p.h) continue ;;
avr/iom325a.h) continue ;;
avr/iom325p.h) continue ;;
avr/iom328.h) continue ;;
avr/iom3290a.h) continue ;;
avr/iom329a.h) continue ;;
avr/iom329pa.h) continue ;;
avr/iom48.h) continue ;;
avr/iom48a.h) continue ;;
avr/iom640.h) continue ;;
avr/iom644.h) continue ;;
avr/iom644a.h) continue ;;
avr/iom644p.h) continue ;;
avr/iom6450a.h) continue ;;
avr/iom6450p.h) continue ;;
avr/iom645a.h) continue ;;
avr/iom645p.h) continue ;;
avr/iom6490a.h) continue ;;
avr/iom6490p.h) continue ;;
avr/iom649a.h) continue ;;
avr/iom88.h) continue ;;
avr/iom88a.h) continue ;;
avr/iom8hva.h) continue ;;
avr/iotn24.h) continue ;;
avr/iotn25.h) continue ;;
avr/iotn261.h) continue ;;
avr/iotn44.h) continue ;;
avr/iotn45.h) continue ;;
avr/iotn461.h) continue ;;
avr/iotn84.h) continue ;;
avr/iotn85.h) continue ;;
avr/iotn861.h) continue ;;
avr/iousb1286.h) continue ;;
avr/iousb1287.h) continue ;;
avr/iousb162.h) continue ;;
avr/iousb646.h) continue ;;
avr/iousb647.h) continue ;;
avr/iousb82.h) continue ;;
*)
;;
esac
i=$(($i + 1))
(
echo "#include <ArduinoUnitTests.h>"
echo "#include <$file>"
echo "unittest(compile_with_header_$i) { assertEqual(1, 1); } unittest_main()"
) > header_test_$i.cpp
done
It did occur to me after writing this issue that I may not need to package a full library to do the compilation test. It will depend on where I hook things in on the Ruby side (in order to generate the proper compiler command).
I will probably end up iterating over an array of specifically-defined header files (like the ones listed in the top) than just globbing and excluding. Although via Ruby, I will have the ability to just check STDOUT/STDERR for the compiler warning (which should be a more robust way to detect/ignore the wrapper files).