tests/api is one binary compiled in every CI configuration, so a test calling
an API the build did not compile is not a test failure -- it is a link error
that takes the whole binary down. It is also invisible to header inspection,
because wolfSSL declares plenty of API unconditionally and implements it under
a narrower condition. That combination broke CI four separate times on this
branch, each time found by CI rather than locally, and each time the fix was
the same: name what the build provides, not what the test needs.
check-api-guards.py walks the enclosing #if chain of every call site and
requires the macros the IMPLEMENTATION carries. It is a whitelist rather than
a parse of ssl.h on purpose: the mapping from symbol to implementation guard
cannot be derived from the declaration, which is the whole problem.
Two things make it usable rather than noisy:
It only looks at call sites this branch changed. Run over everything it
reports 28 long-standing sites that are fine in practice because the
configurations that would break them are not built; auditing those is a
different job, and --all still does it.
It knows which macros imply TLS. A block under WOLFSSL_TLS13 or HAVE_SNI
cannot also need !defined(NO_TLS) spelled out, and comments and string
literals are blanked before matching, since these files discuss the very
API names being searched for.
It refuses to run against a ref it cannot resolve rather than reporting
success, because a shallow checkout would otherwise make every diff empty and
the check would pass without looking at anything. The workflow checks out with
fetch-depth: 0 for that reason, and runs the check before the smoke build --
it needs no build and costs a second.
Verified both directions: clean on this branch, and it reports the exact site
when !defined(NO_TLS) is removed from a guard that needs it.