]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
tests/server: support bundle binary
authorViktor Szakats <commit@vsz.me>
Sun, 8 Sep 2024 22:33:04 +0000 (00:33 +0200)
committerViktor Szakats <commit@vsz.me>
Sun, 16 Mar 2025 13:02:08 +0000 (14:02 +0100)
Extend existing `--enable-test-bundles` and `-DCURL_TEST_BUNDLES=ON`
options to also bundle test server programs into a single binary. With
autotools, also bundle auxiliary libcurl sources for a "unity"-style
build.

It saves almost 10 minutes per run, across all CI jobs.
On average it makes `build tests` steps 25% faster.

With CMake, it brings down `testdeps` build steps to 32 to 37, from
45 to 64 before this patch, with unity. Without unity it brings it down
from 400-420 to 280-300. For comparison, without unity and bundles,
the number of build steps is around 1850.

With autotools the gain is possibly larger because this patch does unity
and bundle for test servers.

The total reduction of build steps / log lines is 12000. It's 44% of
reduction on average across all CI jobs.

Follow-up to 77401af4852103b215fe74989e89be61bbf435d2 #16695
Follow-up to 71cf0d1fca9e1f53524e1545ef0c08d174458d80 #14772

Comparison of 'build tests' targets in S(econds) and L(ines/steps),
between before and after this patch:

CI job                                    |BefS|AftS|Gain|BefL|AftL|Gain| Comments
:---------------------------------------- | -: | -: | -: | --:| --:| --:| :-------
GHA/windows                               |    |    |    |    |    |    |
Cygwin AM                                 |110 | 95 | 15 | 237|  88| 149| l(ines)
Cygwin CM                                 | 34 | 27 |  7 |  63|  36|  27| s(teps, with Ninja)
msys2, AM x86_64 !proxy                   | 35 | 21 | 14 | 255| 108| 147| l
msys2, AM x86_64 default                  | 35 | 22 | 13 | 255| 108| 147| l
msys2, CM x86_64 default                  | 14 | 11 |  3 |  63|  36|  27| s
msys2, AM x86_64 default R                | 41 | 29 | 12 | 245|  96| 149| l
mingw, AM x86_64 default                  | 69 | 33 | 36 | 331| 156| 175| l
mingw, AM x86_64 c-ares U                 | 69 | 33 | 36 | 331| 156| 175| l
mingw, CM x86_64 schannel c-ares U        | 32 | 24 |  8 |  63|  36|  27| s
mingw, CM clang-x86_64 gnutls             |  9 |  6 |  3 |  63|  36|  27| s
mingw, CM ucrt-x86_64 schannel R TrackMem | 43 | 35 |  8 |  64|  37|  27| s
mingw, CM clang-x86_64 openssl            | 20 | 18 |  2 |  63|  36|  27| s
mingw, CM ucrt-x86_64 schannel uwp        | 36 | 34 |  2 |  47|  34|  13| s
mingw, CM x86_64 schannel dev debug       | 32 | 24 |  8 |  64|  37|  27| s
mingw, CM i686 schannel R                 | 38 | 37 |  1 |  47|  34|  13| s
dl-mingw, CM 9.5.0-x86_64 schan           |102 | 94 |  8 |  63|  36|  27| s
dl-mingw, CM 7.3.0-x86_64 schan mbedtls U | 32 | 24 |  8 |  94|  60|  34| l
dl-mingw, CM 6.4.0-i686 schannel !unity   | 42 | 31 | 11 | 427| 297| 130| l (no unity, yes bundle)
linux-mingw, AM gcc                       |  - |  - |    |   -|   -|    |
linux-mingw, CM gcc                       | 12 | 10 |  2 |  46|  33|  13| s
mingw32ce, AM 4.4.0-arm schannel          |  - |  - |    |   -|   -|    |
mingw32ce, CM 4.4.0-arm schannel          | 30 | 31 | -1 |  81|  61|  20| l
msvc, CM x64-uwp openssl +examples        | 13 | 10 |  3 | 102|  68|  34| l
msvc, CM x64-windows openssl              | 13 | 10 |  3 | 102|  68|  34| l
msvc, CM x64-windows schannel MultiSSL U  | 13 | 10 |  3 | 102|  68|  34| l
msvc, CM x64-windows libressl             | 14 | 13 |  1 | 102|  68|  34| l
msvc, CM x64-windows boringssl            | 11 | 11 |  0 |  84|  64|  20| l
msvc, CM x64-windows wolfssl +examples    | 13 | 10 |  3 | 102|  68|  34| l
msvc, CM x64-windows mbedtls libssh       | 14 | 10 |  4 | 102|  68|  34| l
GHA/old-linux:                            |    |    |    |    |    |    |
linux (cmake & autoconf) AM               | 14 | 11 |  3 | 217|  75| 142| l
linux (cmake & autoconf) CM               | 15 | 13 |  2 | 545| 380| 165| l
GHA/non-native:                           |    |    |    |    |    |    |
AmigaOS, AM gcc AmiSSL m68k               |  - |  - |    |   -|   -|    |
AmigaOS, CM gcc AmiSSL m68k               |  8 |  7 |  1 |  78|  58|  20| l
Android 21, AM openssl arm64              |  7 |  5 |  2 | 222|  80| 142| l
Android 21, CM openssl arm64              |  4 |  5 | -1 |  81|  61|  20| l
Android 35, AM openssl arm64              |  7 |  5 |  2 | 222|  80| 142| l
Android 35, CM boringssl !zstd arm64      |  4 |  3 |  1 |  81|  61|  20| l
Android 35, CM openssl arm64              |  5 |  4 |  1 |  81|  61|  20| l
FreeBSD, AM clang openssl arm64           |  - |  - |    |   -|   -|    |
FreeBSD, AM clang openssl x86_64          |  7 |  3 |  4 | 513| 133| 380| l
FreeBSD, CM clang openssl !unity !bundle..| 49 | 47 |  2 |1841|1841|    | s (no unity, no bundle)
FreeBSD, CM clang openssl arm64           |  - |  - |    |   -|   -|    |
MS-DOS, AM djgpp openssl i586             |  - |  - |    |   -|   -|    |
MS-DOS, CM djgpp openssl i586             |  6 |  7 | -1 |  45|  32|  13| s
NetBSD, CM clang openssl x86_64           | 15 | 13 |  2 |  62|  35|  27| s
OmniOS, AM gcc openssl amd64              | 20 | 11 |  9 | 216|  74| 142| l
OpenBSD, CM clang libressl x86_64         |  9 |  7 |  2 |  62|  35|  27| s
iOS, AM libressl arm64                    |  6 |  3 |  3 | 217|  68| 149| l
iOS, CM libressl arm64                    | 10 | 10 |  0 | 236| 175|  61| l
iOS, CM-Xcode libressl arm64              | 13 |  8 |  5 | 899| 627| 272| l
GHA/linux:                                |    |    |    |    |    |    |
AM bearssl                                |  9 |  8 |  1 | 258| 111| 147| l
AM bearssl clang                          |  6 |  4 |  2 | 258| 111| 147| l
AM libressl heimdal                       | 11 |  8 |  3 | 267| 120| 147| l
CM libressl heimdal valgrind              |  8 |  5 |  3 |  62|  35|  27| s
AM libressl clang                         |  7 |  4 |  3 | 258| 111| 147| l
AM wolfssl-all                            | 11 |  8 |  3 | 258| 111| 147| l
AM wolfssl-opensslextra valgrind          | 11 |  7 |  4 | 258| 111| 147| l
AM mbedtls valgrind                       | 10 |  7 |  3 | 258| 111| 147| l
AM mbedtls clang                          |  6 |  3 |  3 | 258| 111| 147| l
CM mbedtls                                |  7 |  6 |  1 |  62|  35|  27| s
CM mbedtls-pkg                            |  7 |  7 |  0 |  62|  35|  27| s
CM mbedtls-pkg !pc                        |  - |  - |    |   -|   -|    |
AM msh3                                   | 10 |  7 |  3 | 258| 111| 147| l
CM msh3                                   |  7 |  7 |  0 |  62|  35|  27| s
AM awslc                                  | 18 | 15 |  3 | 247|  98| 149| l
CM awslc                                  | 13 | 11 |  2 | 400| 277| 123| s (no unity, yes bundle)
AM openssl default                        | 10 |  7 |  3 | 258| 111| 147| l
AM openssl libssh2 sync-resolver valgrind | 10 |  7 |  3 | 258| 111| 147| l
AM openssl                                | 11 |  7 |  4 | 258| 111| 147| l
AM openssl -O3 valgrind                   | 26 | 21 |  5 | 258| 111| 147| l
AM openssl clang krb5                     |  7 |  3 |  4 | 265| 118| 147| l
CM openssl clang krb5 LTO                 |  - |  - |    |   -|   -|    |
AM openssl !ipv6 !--libcurl               | 10 |  7 |  3 | 258| 111| 147| l
AM openssl https-only                     | 11 |  8 |  3 | 258| 111| 147| l
CM openssl torture !FTP                   |  7 |  6 |  1 |  62|  35|  27| s
CM openssl torture FTP                    |  8 |  6 |  2 |  62|  35|  27| s
AM openssl i686                           | 12 |  9 |  3 | 258| 111| 147| l
AM !ssl !http !smtp !imap                 | 10 |  7 |  3 | 258| 111| 147| l
AM clang-tidy                             |  - |  - |    |   -|   -|    |
AM scanbuild                              |  - |  - |    |   -|   -|    |
AM address-sanitizer                      | 10 |  6 |  4 | 258| 111| 147| l
AM thread-sanitizer                       |  7 |  4 |  3 | 258| 111| 147| l
AM memory-sanitizer                       | 10 |  6 |  4 | 258| 111| 147| l
AM event-based                            | 10 |  7 |  3 | 253| 106| 147| l
AM duphandle                              | 10 |  8 |  2 | 253| 106| 147| l
AM rustls valgrind                        | 10 |  8 |  2 | 258| 111| 147| l
CM rustls                                 |  7 |  5 |  2 |  62|  35|  27| s
AM IntelC openssl                         | 18 | 14 |  4 | 572| 282| 290| l
AM Slackware openssl gssapi gcc           | 17 | 14 |  3 | 252| 103| 149| l
AM Alpine MUSL https-rr                   | 15 | 11 |  4 | 266| 119| 147| l
AM Alpine MUSL c-ares https-rr            | 15 | 11 |  4 | 266| 119| 147| l
GHA/linux-http3:                          |    |    |    |    |    |    |
AM quictls                                | 12 |  8 |  4 | 258| 111| 147| l
AM gnutls                                 | 11 |  8 |  3 | 257| 110| 147| l
AM wolfssl                                | 11 |  9 |  2 | 257| 110| 147| l
CM wolfssl                                |  8 |  7 |  1 |  62|  35|  27| s
AM openssl-quic                           | 11 |  8 |  3 | 257| 110| 147| l
AM quiche                                 | 11 |  9 |  2 | 257| 110| 147| l
CM quiche                                 |  8 |  6 |  2 |  62|  35|  27| s
GHA/macos:                                |    |    |    |    |    |    |
AM clang !ssl !debug brotli zstd          |  5 |  3 |  2 | 218|  69| 149| l
AM clang !ssl                             |  4 |  5 | -1 | 227|  80| 147| l
AM clang !ssl libssh2 AppleIDN            |  5 |  1 |  4 | 227|  80| 147| l
AM clang OpenSSL libssh c-ares            |  4 |  2 |  2 | 227|  80| 147| l
AM clang !ssl c-ares                      |  4 |  5 | -1 | 227|  80| 147| l
AM clang !ssl HTTP-only                   |  4 |  2 |  2 | 222|  75| 147| l
AM clang SecureTransport libssh2          |  3 |  3 |  0 | 227|  80| 147| l
AM clang SecureTransport libssh2 10.12    |  4 |  2 |  2 | 227|  80| 147| l
AM clang LibreSSL +examples               |  5 |  2 |  3 | 227|  80| 147| l
AM clang OpenSSL                          |  6 |  1 |  5 | 227|  80| 147| l
AM clang OpenSSL event-based              |  5 |  3 |  2 | 227|  80| 147| l
AM clang quictls libssh2 !ldap 10.15      |  4 |  2 |  2 | 227|  80| 147| l
CM clang OpenSSL gsasl rtmp AppleIDN      |  2 |  2 |  0 |  45|  32|  13| s
CM clang OpenSSL AppleIDN clang-tidy +e   |150 | 76 | 74 | 400| 277| 123| s (clang-tidy)
CM clang quictls +static libssh +examples |  2 |  2 |  0 |  45|  32|  13| s
CM clang SecureTransport debug            |  2 |  2 |  0 |  62|  35|  27| s
CM clang LibreSSL !ldap heimdal c-ares +e |  4 |  2 |  2 |  45|  32|  13| s
CM clang wolfSSL !ldap brotli zstd        |  1 |  2 | -1 |  45|  32|  13| s
CM clang mbedTLS openldap brotli zstd     |  1 |  2 | -1 |  45|  32|  13| s
CM clang GnuTLS !ldap krb5                |  0 |  1 |  0 |  45|  32|  13| s
CM clang OpenSSL torture !FTP             |  2 |  1 |  1 |  61|  34|  27| s
CM clang OpenSSL torture FTP              |  2 |  1 |  1 |  61|  34|  27| s
AM llvm@15 OpenSSL libssh                 |  5 |  4 |  1 | 227|  80| 147| l
CM llvm@15 OpenSSL gsasl rtmp AppleIDN    |  3 |  2 |  1 |  45|  32|  13| s
CM llvm@15 quictls +static libssh +e      |  2 |  2 |  0 |  45|  32|  13| s
CM llvm@15 SecureTransport debug          |  3 |  2 |  1 |  62|  35|  27| s
CM llvm@15 LibreSSL !ldap heimdal c-ares..|  3 |  1 |  2 |  45|  32|  13| s
CM llvm@15 wolfSSL !ldap brotli zstd      |  3 |  2 |  1 |  45|  32|  13| s
CM llvm@15 mbedTLS openldap brotli zstd   |  2 |  2 |  0 |  45|  32|  13| s
CM llvm@15 GnuTLS !ldap krb5              |  2 |  1 |  1 |  45|  32|  13| s
AM gcc-12 !ssl !debug                     | 18 | 12 |  6 | 218|  69| 149| l
AM gcc-12 SecureTransport libssh2         | 13 |  6 |  7 | 227|  80| 147| l
CM gcc-12 OpenSSL gsasl rtmp AppleIDN     |  7 |  5 |  2 |  45|  32|  13| s
CM gcc-12 quictls +static libssh +e       |  8 |  6 |  2 |  45|  32|  13| s
CM gcc-12 SecureTransport debug           |  8 |  6 |  2 |  62|  35|  27| s
CM gcc-12 LibreSSL !ldap heimdal c-ares...|  7 |  6 |  1 |  45|  32|  13| s
CM gcc-12 wolfSSL !ldap brotli zstd       | 16 |  6 | 10 |  45|  32|  13| s
CM gcc-12 mbedTLS openldap brotli zstd    | 11 |  6 |  5 |  45|  32|  13| s
CM gcc-12 GnuTLS !ldap krb5               |  7 |  5 |  2 |  45|  32|  13| s
AppVeyor:                                 |    |    |    |    |    |    |
VS2008 D x86 OpenSSL + Schannel SH +e     | 56 | 39 | 17 |  21|  14|   7| s (VCBuild)
VS2010 D x64 Schannel SH +e               | 14 | 12 |  2 | 105|  78|  27| l
VS2012 R x86 OpenSSL + Schannel SH        | 23 | 21 |  2 |  84|  64|  20| l
VS2013 D x64 OpenSSL SH Build-only        |  - |  - |    |   -|   -|    | (no build tests)
VS2015 D x64 OpenSSL ST Build-only        |  - |  - |    |   -|   -|    | (no build tests)
VS2017 D x64 OpenSSL SH Build-only        |  - |  - |    |   -|   -|    | (no build tests)
VS2019 D x64 OpenSSL + Schannel SH        | 33 | 26 |  7 |  81|  61|  20| l
VS2022 D x64 !SSL ST                      | 32 | 25 |  7 |  79|  59|  20| l
VS2022 D x64 !SSL ST HTTP-only            | 33 | 22 | 11 |  79|  59|  20| l
VS2022 R arm64 Schannel ST                | 74 | 69 |  5 |  79|  59|  20| l
VS2022 R x64 Schannel SH U DBGBLD !CURLDBG| 66 | 61 |  5 |  78|  58|  20| l
VS2022 D x64 Schannel ST U                | 34 | 25 |  9 |  79|  59|  20| l
VS2022 D x64 Schannel ST U clang-cl +e    | 42 | 34 |  8 |  53|  40|  13| l
VS2022 R x64 OpenSSL SH                   | 60 | 58 |  2 |  83|  63|  20| l
Total                                     |2394|1807|-587| 26k| 14k|-12k|
in %                                      |    |    |-24%|    |    |-45%|
in minutes                                |    |    |9m47|    |    |    |

Before:
GHA/windows: https://github.com/curl/curl/actions/runs/13854983424
GHA/old-linux: https://github.com/curl/curl/actions/runs/13854983399
GHA/non-native: https://github.com/curl/curl/actions/runs/13854983427
GHA/linux-http3: https://github.com/curl/curl/actions/runs/13854983409
GHA/linux: https://github.com/curl/curl/actions/runs/13854983406
GHA/macos: https://github.com/curl/curl/actions/runs/13854983401
Appveyor: https://ci.appveyor.com/project/curlorg/curl/builds/51703551

After:
GHA/windows: https://github.com/curl/curl/actions/runs/13860433850?pr=15000
GHA/old-linux: https://github.com/curl/curl/actions/runs/13860433809?pr=15000
GHA/non-native: https://github.com/curl/curl/actions/runs/13860433828?pr=15000
GHA/linux-http3: https://github.com/curl/curl/actions/runs/13860433806?pr=15000
GHA/linux: https://github.com/curl/curl/actions/runs/13860433848?pr=15000
GHA/macos: https://github.com/curl/curl/actions/runs/13860433835?pr=15000
Appveyor: https://ci.appveyor.com/project/curlorg/curl/builds/51704222

Closes #15000

tests/ftpserver.pl
tests/runtests.pl
tests/server/.gitignore
tests/server/CMakeLists.txt
tests/server/Makefile.am
tests/server/Makefile.inc
tests/server/first.c [new file with mode: 0644]
tests/server/first.h [new file with mode: 0644]
tests/server/mk-bundle.pl [new file with mode: 0755]
tests/serverhelp.pm

index afdd80e80f64e69a663ac7114643827ec3f4128b..d4cd0f4172c5b6d0931ceca2ff065cab3d5a9466 100755 (executable)
@@ -68,7 +68,7 @@ use serverhelp qw(
     servername_str
     server_pidfilename
     server_logfilename
-    server_exe
+    server_exe_args
     mainsockf_pidfilename
     mainsockf_logfilename
     datasockf_pidfilename
@@ -407,7 +407,7 @@ sub sysread_or_die {
 }
 
 sub startsf {
-    my @mainsockfcmd = (server_exe('sockfilt'),
+    my @mainsockfcmd = (server_exe_args('sockfilt'),
         "--ipv$ipvnum",
         "--port", $port,
         "--pidfile", $mainsockf_pidfile,
@@ -2469,7 +2469,7 @@ sub PASV_ftp {
     logmsg "DATA sockfilt for passive data channel starting...\n";
 
     # We fire up a new sockfilt to do the data transfer for us.
-    my @datasockfcmd = (server_exe('sockfilt'),
+    my @datasockfcmd = (server_exe_args('sockfilt'),
         "--ipv$ipvnum", "--port", 0,
         "--pidfile", $datasockf_pidfile,
         "--logfile", $datasockf_logfile);
@@ -2691,7 +2691,7 @@ sub PORT_ftp {
     logmsg "DATA sockfilt for active data channel starting...\n";
 
     # We fire up a new sockfilt to do the data transfer for us.
-    my @datasockfcmd = (server_exe('sockfilt'),
+    my @datasockfcmd = (server_exe_args('sockfilt'),
         "--ipv$ipvnum", "--connect", $port, "--addr", $addr,
         "--pidfile", $datasockf_pidfile,
         "--logfile", $datasockf_logfile);
index 0ab2c95303148d9f93ab98c1cbdd6693e4448b3c..f3916738d94c63d094f662dba47652d1a7adaae1 100755 (executable)
@@ -2268,6 +2268,7 @@ while(@ARGV) {
     elsif ($ARGV[0] eq "-bundle") {
         # use test bundles
         $bundle=1;
+        $ENV{'CURL_TEST_BUNDLES'} = 1;
     }
     elsif ($ARGV[0] eq "-d") {
         # have the servers display protocol output
index 034fe9c5f7595afcb12a4324dadf9e16f5e7062c..aa226a094eb53d2ac1efd0224fa1108d19a7cdcd 100644 (file)
@@ -2,6 +2,8 @@
 #
 # SPDX-License-Identifier: curl
 
+server_bundle.c
+
 disabled
 mqttd
 resolve
index d0c1b9e0e440d14210d983bc7e3408b9252464d8..1a60a931a54c17404e90b88ba3a3e217889017cf 100644 (file)
@@ -22,7 +22,7 @@
 #
 ###########################################################################
 
-# Get 'noinst_PROGRAMS', '<target>_SOURCES' variables
+# Get 'SERVERPROGS', '<target>_SOURCES' variables, 'MEMDEBUG', 'CURLX_SRCS', 'USEFUL', 'INET_PTON', 'UTIL', 'FIRSTFILES'
 curl_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
 include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
 
@@ -30,14 +30,28 @@ if(ENABLE_SERVER_DEBUG AND ENABLE_CURLDEBUG)
   set_source_files_properties("../../lib/memdebug.c" "../../lib/curl_multibyte.c" PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
 endif()
 
-foreach(_target IN LISTS noinst_PROGRAMS)
+if(CURL_TEST_BUNDLES)
+  add_custom_command(
+    OUTPUT "server_bundle.c"
+    COMMAND ${PERL_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/mk-bundle.pl" ${SERVERPROGS} > "server_bundle.c"
+    DEPENDS
+      "${CMAKE_CURRENT_SOURCE_DIR}/mk-bundle.pl" ${FIRSTFILES}
+      "${CMAKE_CURRENT_SOURCE_DIR}/Makefile.inc"
+    VERBATIM)
+
+  set(SERVERPROGS "servers")
+  set(servers_SOURCES ${MEMDEBUG} ${CURLX_SRCS} ${USEFUL} ${INET_PTON} ${UTIL} "server_bundle.c")
+endif()
+
+foreach(_target IN LISTS SERVERPROGS)
   set(_target_name "${_target}")
   add_executable(${_target_name} EXCLUDE_FROM_ALL ${${_target}_SOURCES})
   add_dependencies(testdeps ${_target_name})
   target_include_directories(${_target_name} PRIVATE
-    "${PROJECT_BINARY_DIR}/lib"  # for "curl_config.h"
-    "${PROJECT_SOURCE_DIR}/lib"  # for "curl_setup.h"
-    "${PROJECT_SOURCE_DIR}/src"  # for "tool_binmod.h", "tool_xattr.h"
+    "${PROJECT_BINARY_DIR}/lib"           # for "curl_config.h"
+    "${PROJECT_SOURCE_DIR}/lib"           # for "curl_setup.h"
+    "${PROJECT_SOURCE_DIR}/src"           # for "tool_binmode.h", "tool_xattr.h"
+    "${PROJECT_SOURCE_DIR}/tests/server"  # for "first.h"
   )
   target_link_libraries(${_target_name} ${CURL_LIBS})
   if(ENABLE_SERVER_DEBUG)
index b256ecfa42e0e1cd22ac4a36d858c8d782cb9364..cee7f81c5eb02f7412bb0c74a823ace377e29da9 100644 (file)
@@ -31,11 +31,13 @@ AUTOMAKE_OPTIONS = foreign nostdinc
 # $(top_srcdir)/include is for libcurl's external include files
 # $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file
 # $(top_srcdir)/lib for libcurl's lib/curl_setup.h and other "borrowed" files
+# $(top_srcdir)/src for "tool_binmode.h", "tool_xattr.h"
 
 AM_CPPFLAGS = -I$(top_srcdir)/include        \
               -I$(top_builddir)/lib          \
               -I$(top_srcdir)/lib            \
-              -I$(top_srcdir)/src
+              -I$(top_srcdir)/src            \
+              -I$(top_srcdir)/tests/server
 
 # Prevent LIBS from being used for all link targets
 LIBS = $(BLANK_AT_MAKETIME)
@@ -57,15 +59,38 @@ endif
 # Makefile.inc provides neat definitions
 include Makefile.inc
 
-EXTRA_DIST = CMakeLists.txt .checksrc
+EXTRA_DIST = CMakeLists.txt .checksrc mk-bundle.pl $(FIRSTFILES)
+
+if USE_TEST_BUNDLES
+server_EXCLUDE =
+if ENABLE_SERVER_DEBUG
+if CURLDEBUG
+server_EXCLUDE += $(MEMDEBUG)
+endif
+endif
+server_bundle.c: $(top_srcdir)/tests/server/mk-bundle.pl $(MEMDEBUG) $(CURLX_SRCS) $(USEFUL) $(INET_PTON) $(UTIL) $(FIRSTFILES)
+       @PERL@ $(top_srcdir)/tests/server/mk-bundle.pl $(MEMDEBUG) $(CURLX_SRCS) $(USEFUL) $(INET_PTON) $(UTIL) $(SERVERPROGS) --exclude $(server_EXCLUDE) > server_bundle.c
+
+noinst_PROGRAMS = servers
+nodist_servers_SOURCES = server_bundle.c
+servers_SOURCES = $(server_EXCLUDE)
+servers_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
+servers_CFLAGS = $(AM_CFLAGS)
+CLEANFILES = server_bundle.c
+else
+noinst_PROGRAMS = $(SERVERPROGS)
+endif
 
 CHECKSRC = $(CS_$(V))
 CS_0 = @echo "  RUN     " $@;
 CS_1 =
 CS_ = $(CS_0)
 
+# ignore generated C files since they play by slightly different rules!
 checksrc:
-       $(CHECKSRC)@PERL@ $(top_srcdir)/scripts/checksrc.pl $(srcdir)/*.[ch]
+       $(CHECKSRC)(@PERL@ $(top_srcdir)/scripts/checksrc.pl -D$(srcdir) \
+         -W$(srcdir)/server_bundle.c \
+         $(srcdir)/*.[ch])
 
 if DEBUGBUILD
 # for debug builds, we scan the sources on all regular make invokes
index 532984913caf1463769c4d9a3cfaeeae32e81d83..f3062c8d34670c36888e067024ad4d431f530899 100644 (file)
 #
 ###########################################################################
 
-noinst_PROGRAMS = resolve rtspd sockfilt sws tftpd socksd disabled mqttd
+SERVERPROGS = resolve rtspd sockfilt sws tftpd socksd disabled mqttd
+
+MEMDEBUG = \
+  ../../lib/curl_multibyte.c \
+  ../../lib/curl_multibyte.h \
+  ../../lib/memdebug.c \
+  ../../lib/memdebug.h
 
 CURLX_SRCS = \
   ../../lib/mprintf.c \
@@ -36,7 +42,6 @@ CURLX_SRCS = \
   ../../lib/strcase.c \
   ../../lib/strdup.c \
   ../../lib/curl_get_line.c \
-  ../../lib/curl_multibyte.c \
   ../../lib/version_win32.c
 
 CURLX_HDRS = \
@@ -51,7 +56,6 @@ CURLX_HDRS = \
   ../../lib/strcase.h \
   ../../lib/strdup.h \
   ../../lib/curl_get_line.h \
-  ../../lib/curl_multibyte.h \
   ../../lib/version_win32.h
 
 UTIL = \
@@ -62,50 +66,52 @@ UTIL = \
   server_setup.h \
   ../../lib/base64.c \
   ../../lib/curl_base64.h \
-  ../../lib/memdebug.c \
-  ../../lib/memdebug.h \
   ../../lib/strerror.c \
   ../../lib/strerror.h
 
+FIRSTFILES = \
+  first.c \
+  first.h
+
 INET_PTON = \
   ../../lib/inet_pton.c
 
-resolve_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) \
+resolve_SOURCES = $(MEMDEBUG) $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) \
   resolve.c
 resolve_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
 resolve_CFLAGS = $(AM_CFLAGS)
 
-rtspd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) \
+rtspd_SOURCES = $(MEMDEBUG) $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) \
   server_sockaddr.h \
   rtspd.c
 rtspd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
 rtspd_CFLAGS = $(AM_CFLAGS)
 
-sockfilt_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) $(INET_PTON) \
+sockfilt_SOURCES = $(MEMDEBUG) $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) $(INET_PTON) \
   server_sockaddr.h \
   sockfilt.c
 sockfilt_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
 sockfilt_CFLAGS = $(AM_CFLAGS)
 
-socksd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) $(INET_PTON) \
+socksd_SOURCES = $(MEMDEBUG) $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) $(INET_PTON) \
   server_sockaddr.h \
   socksd.c
 socksd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
 socksd_CFLAGS = $(AM_CFLAGS)
 
-mqttd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) \
+mqttd_SOURCES = $(MEMDEBUG) $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) \
   server_sockaddr.h \
   mqttd.c
 mqttd_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
 mqttd_CFLAGS = $(AM_CFLAGS)
 
-sws_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) $(INET_PTON) \
+sws_SOURCES = $(MEMDEBUG) $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) $(INET_PTON) \
   server_sockaddr.h \
   sws.c
 sws_LDADD = @CURL_NETWORK_AND_TIME_LIBS@
 sws_CFLAGS = $(AM_CFLAGS)
 
-tftpd_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) \
+tftpd_SOURCES = $(MEMDEBUG) $(CURLX_SRCS) $(CURLX_HDRS) $(UTIL) \
   server_sockaddr.h \
   tftpd.c \
   tftp.h
diff --git a/tests/server/first.c b/tests/server/first.c
new file mode 100644 (file)
index 0000000..13b02d4
--- /dev/null
@@ -0,0 +1,59 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include "first.h"
+
+int main(int argc, char **argv)
+{
+  main_func_t main_func;
+  char *main_name;
+
+  if(argc < 2) {
+    fprintf(stderr, "Pass servername as first argument\n");
+    return 1;
+  }
+
+  main_name = argv[1];
+  main_func = NULL;
+  {
+    size_t tmp;
+    for(tmp = 0; s_mains[tmp].ptr; ++tmp) {
+      if(strcmp(main_name, s_mains[tmp].name) == 0) {
+        main_func = s_mains[tmp].ptr;
+        break;
+      }
+    }
+  }
+
+  if(!main_func) {
+    fprintf(stderr, "Test '%s' not found.\n", main_name);
+    return 99;
+  }
+
+  --argc;
+  ++argv;
+
+  return main_func(argc, argv);
+}
diff --git a/tests/server/first.h b/tests/server/first.h
new file mode 100644 (file)
index 0000000..54863cd
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef HEADER_SERVER_FIRST_H
+#define HEADER_SERVER_FIRST_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+typedef int (*main_func_t)(int, char **);
+
+struct onemain {
+  const char *name;
+  main_func_t ptr;
+};
+
+#endif /* HEADER_SERVER_FIRST_H */
diff --git a/tests/server/mk-bundle.pl b/tests/server/mk-bundle.pl
new file mode 100755 (executable)
index 0000000..321709b
--- /dev/null
@@ -0,0 +1,90 @@
+#!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) Viktor Szakats
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+
+# Bundle up individual tests into a single binary. The resulting binary can run
+# individual tests by passing their name (without '.c') as the first argument.
+#
+# Usage: mk-bundle.pl [<server_c>]
+
+use strict;
+use warnings;
+
+if(!@ARGV) {
+    die "Usage: $0 [<inputs>] [--exclude <exclude-c-sources>]\n";
+}
+
+# Specific sources to exclude or add as an extra source file
+my @src;
+my %exclude;
+my $in_exclude = 0;
+foreach my $src (@ARGV) {
+    if($in_exclude) {
+        $exclude{$src} = 1;
+    }
+    elsif($src eq "--exclude") {
+        $in_exclude = 1;
+    }
+    else {
+        push @src, $src;
+    }
+}
+
+print <<HEADER
+/* !checksrc! disable COPYRIGHT all */
+
+#include "first.h"
+
+HEADER
+    ;
+
+my $tlist = "";
+
+foreach my $src (@src) {
+    if($src =~ /\.c$/) {
+        if(!exists $exclude{$src}) {
+            # Misc .c source to include
+            print "#include \"$src\"\n\n";
+        }
+    }
+    elsif($src !~ /\.h$/) {
+        # Make 'main' unique across server sources
+        print "#undef main\n";
+        print "#define main main_$src\n";
+        print "int main_$src(int argc, char **argv);\n";
+        print "#include \"$src.c\"\n";
+        print "#undef main\n";
+        print "\n";
+        $tlist .= "  {\"$src\", main_$src},\n";
+    }
+}
+
+print <<FOOTER
+static const struct onemain s_mains[] = {
+${tlist}  {NULL, NULL}
+};
+
+#include "first.c"
+FOOTER
+    ;
index 7eb9a2b4954524e97aea2981cddae1aced2653a1..89cca15dc95d3960216e7c46870559c18a360f0e 100644 (file)
@@ -46,6 +46,7 @@ BEGIN {
         server_inputfilename
         server_outputfilename
         server_exe
+        server_exe_args
         mainsockf_pidfilename
         mainsockf_logfilename
         datasockf_pidfilename
@@ -243,7 +244,33 @@ sub server_exe {
     if(!defined $ext) {
         $ext = 'SRV';
     }
-    return $SRVDIR . $name . exe_ext($ext);
+    my $cmd;
+    if($ENV{'CURL_TEST_BUNDLES'}) {
+        $cmd = $SRVDIR . "servers" . exe_ext($ext) . " $name";
+    }
+    else {
+        $cmd = $SRVDIR . $name . exe_ext($ext);
+    }
+    return "$cmd";
+}
+
+
+#***************************************************************************
+# Return filename for a server executable as an argument list
+#
+sub server_exe_args {
+    my ($name, $ext) = @_;
+    if(!defined $ext) {
+        $ext = 'SRV';
+    }
+    my @cmd;
+    if($ENV{'CURL_TEST_BUNDLES'}) {
+        @cmd = ($SRVDIR . "servers" . exe_ext($ext), $name);
+    }
+    else {
+        @cmd = ($SRVDIR . $name . exe_ext($ext));
+    }
+    return @cmd;
 }