Tests are build in "unity"-style, by including sources into an umbrella
C files (similar to how CMake unity works). This does not play well with
clang-tidy, which seems to unconditionally ignore C sources included
like this. To fix it, curl's CMake implements a manual clang-tidy
support for tests, which compiles sources one-by-one, while also making
sure sources compile cleanly standalone (e.g. all sources need to
include `first.h`). The manual clang-tidy implementation is fragile, and
performance, in particular when targeting Windows, is abysmal.
This patch introduces an alternate solution, enabled by the
`_CURL_TESTS_CONCAT=ON` option. In this mode, umbrella sources include
the actual sources instead of `#including` them. Allowing to use CMake's
built-in clang-tidy support to compile them, with clang-tidy actually
checking the sources. Making the manual clang-tidy support unnecessary.
In the Windows CI job it results in a 4x performance improvement (4m ->
1m), making it practical to run clang-tidy on tests on Windows, in CI.
The main downside is that clang-tidy doesn't understand the `#line`
directive. Meaning issues found show the wrong filename and line number
next to them. It's not impossible to locate errors this way, but also
not convenient.
Minor/potential downside is that the concatenated source needs to be
reassembled each time an original source is updated. This may result in
more copying on the disk when used in local development. The largest
source is 1.4MB, so probably not a show-stopper on most machines.
Another is the complexity of maintaining two methods in parallel, which
may be necessary till clang-tidy understands `#line`:
https://github.com/llvm/llvm-project/issues/62405
This solution may in theory also enable adding clang-tidy support for
tests in autotools, though I haven't tried.
Targeted for curl CI for now, and used in a GHA/windows job. 100%
experimental, not recommended outside these.
Closes#20667
Replace existing `mk-unity.pl` `--embed` workaround with running
`clang-tidy` manually on individual test source instead. This aligns
with how clang-tidy works and removes `mk-unity.pl` from the solution.
Also:
- mqttd: fix potentially uninitialized buffer by zero filling it.
```
tests/server/mqttd.c:484:41: error: The left operand of '<<' is a garbage value
[clang-analyzer-core.UndefinedBinaryOperatorResult,-warnings-as-errors]
484 | payload_len = (size_t)(buffer[10] << 8) | buffer[11];
| ^
[...]
tests/server/mqttd.c:606:45: error: The left operand of '<<' is a garbage value
[clang-analyzer-core.UndefinedBinaryOperatorResult,-warnings-as-errors]
606 | topiclen = (size_t)(buffer[1 + bytes] << 8) | buffer[2 + bytes];
| ^
```
- sockfilt: fix potential out-of-bound pointer:
```
tests/server/sockfilt.c:1128:33: error: The 2nd argument to 'send' is a buffer
with size 17010 but should be a buffer with size equal to or greater than
the value of the 3rd argument (which is 18446744073709551615)
[clang-analyzer-unix.StdCLibraryFunctions,-warnings-as-errors]
1128 | ssize_t bytes_written = swrite(sockfd, buffer, buffer_len);
| ^
```
- clang-tidy: suppress bogus `bzero()` warnings that happens
inside the notorious `FD_ZERO()` macros, on macOS.
Ref: https://github.com/curl/curl/pull/17680#issuecomment-2991730158Closes#17705
Tidy up headers and includes to ensure all individual test source
compile cleanly (but not link). To allow running clang-tidy (and
possibly other static analyzers) on them. It also improves readability
and allows to verify them locally, without the bundle logic.
clang-tidy ignores #included C files, so it's blind to bundle C files
the include these tests. The current workaround of embedding has
a couple of downsides:. meaningless filenames and line numbers,
missing issues, messing up self header paths. Thus, running it on
individual sources would be beneficial.
Also:
- de-duplicate includes.
- untangle some includes.
- formatting/indentation fixes.
- merge `getpart.h` into `first.h`.
Ref: https://github.com/curl/curl/pull/17680#issuecomment-2991730158Closes#17703
To make building the http client tests faster, with no duplication, by
using the build method that other test binaries already use.
The difference compared to other tests is that these don't use internal
libcurl headers or code. With the exception of `curl_config.h`, for
a feature macro.
Before this patch, these tests were built like examples.
Also:
- de-duplicate code and give unique names to colliding symbols.
- add local getopt implementation and enable all code for MSVC.
Adapted for curl via Public Domain source:
4e618ef782/getopt.h
Credits-to: Christopher Wellons
Thanks!
Closes#17627
Before this patch `memdebug.c` was compiled as a separate source in
unity builds. This was necessary because `memdebug.c` failed to compile
if `memdebug.h` was included before it, in `CURLDEBUG` mode. This patch
fixes this issue and allows to compile `memdebug.c` as part of the unity
source batch. This removes an exception and makes builds perform a notch
better.
- introduce `CURL_SCLOSE()` macro as an immutable synonym of `sclose()`.
- memdebug: replace `sclose()` reference with `CURL_SCLOSE()` to compile
as expected when `sclose()` is overridden by `memdebug.h`.
- memdebug: make it not break when including `memdebug.h` before it in
`CURLDEBUG` mode. Do this by calling low-level functions as
`(function)`.
- autotools, cmake: drop memdebug exception, include it like any other
source file. This is now possible because `memdebug.c` doesn't break
if `memdebug.h` was included before it, in `CURLDEBUG` builds.
- mk-unity: drop `--exclude` option. No longer used after this patch.
- drop `MEMDEBUG_NODEFINES` macro hack. No longer necessary.
Ref: #16747Closes#16746Closes#16738Closes#17631
Instead of relying on CMake's built-in unity feature, use `mk-unity.pl`,
as already done with autotools. It simplified the build, shortens logs
and makes debugging easier because of the fewer build variations.
It also allows testing / fixing with cmake and those automatically apply
to autotools builds too. cmake builds can be much-much faster, esp.
when working the builds themselves.
It also enables "unity" in old cmake versions. Basically every test
target is a single generated .c source.
Also:
- drop a `lib` unity workaround for libtests with autotools after fixing
the issue in libtests itself. It drops a few exceptions and makes
libcurl build faster (in autotools unity).
- fix another `lib` autotools unity issue and drop the workaround for it
from `mk-unity.pl`. `srcdir` was missing from the header path.
- simplify `mk-unity.pl` command-lines, drop exclusions.
Follow-up to 2c27a67daa#17590Closes#17628
Make test bundles the default. Drop non-bundle build mode.
Also do all the optimizations and tidy-ups this allows, simpler builds,
less bundle exceptions, streamlined build mechanics.
Also rework the init/deinit macro magic for unit tests. The new method
allows using unique init/deinit function names, and calling them with
arguments. This is in turn makes it possible to reduce the use of global
variables.
Note this drop existing build options `-DCURL_TEST_BUNDLES=` from cmake
and `--enable-test-bundles` / `--disable-test-bundles` from autotools.
Also:
- rename test entry functions to have unique names: `test_<testname>`
This removes the last exception that was handled in the generator.
- fix `make dist` to not miss test sources with test bundles enabled.
- sync and merge `tests/mk-bundle.pl` into `scripts/mk-unity.pl`.
- mk-unity.pl: add `--embed` option and use it when `CURL_CLANG_TIDY=ON`
to ensure that `clang-tidy` does not miss external test C sources.
(because `clang-tidy` ignores code that's #included.)
- tests/unit: drop no-op setup/stop functions.
- tests: reduce symbol scopes, global macros, other fixes and tidy-ups.
- tool1621: fix to run, also fix it to pass.
- sockfilt: fix Windows compiler warning in certain unity include order,
by explicitly including `warnless.h`.
Follow-up to 6897aeb105#17468Closes#17590
by including headers using "../[header]" when done from C files in
subdirectories, we do not need to specify the lib source dir as an
include path and we reduce the risk of header name collisions with
headers in the SDK using the same file names.
Idea-by: Kai Pastor
Ref: #16949Closes#16991