arduino_ci icon indicating copy to clipboard operation
arduino_ci copied to clipboard

Add unittest compilation tests for libraries that include only parts of Arduino

Open ianfixes opened this issue 6 years ago • 4 comments

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.

ianfixes avatar Feb 25 '19 13:02 ianfixes

This also applies to: #include <avr/sleep.h> #include <avr/wdt.h>

PRosenb avatar Feb 25 '19 20:02 PRosenb

Excellent! I'll make tests for each of these.

ianfixes avatar Feb 25 '19 20:02 ianfixes

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

hlovdal avatar Feb 26 '19 00:02 hlovdal

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).

ianfixes avatar Feb 26 '19 12:02 ianfixes