diff --git a/Makefile.in b/Makefile.in index cd5903aa1cc..74e6dae6b75 100644 --- a/Makefile.in +++ b/Makefile.in @@ -34,7 +34,7 @@ DISTCLEAN_TARGETS = include/ap_config_auto.h include/ap_config_layout.h \ build/pkg/pkginfo build/config_vars.sh bsd_converted EXTRACLEAN_TARGETS = configure include/ap_config_auto.h.in generated_lists \ httpd.spec -PHONY_TARGETS := check check-conf check-dirs check-include check-pytest check-all-pytest unittest-objdir +PHONY_TARGETS := check check-conf check-dirs check-include check-pytest check-all-pytest unittest-objdir test-apps TESTS = TEST_CONFIG = @@ -527,6 +527,10 @@ check-all-pytest: check-tree check/bin/apachectl check/config.ini check/modules/ # Runs all configured/available test targets. check: $(CHECK_TARGETS) +# Build test binaries/modules (enabled by --enable-test-apps) +test-apps: + cd test && $(MAKE) $(MFLAGS) test-apps + # # Unit Test Suite # diff --git a/configure.in b/configure.in index 58e996c4537..d06ce3e98b5 100644 --- a/configure.in +++ b/configure.in @@ -793,6 +793,14 @@ if test -d "./test"; then fi APACHE_SUBST(PYTEST3) +dnl Enable building test binaries/modules at make time +AC_ARG_ENABLE(test-apps, +APACHE_HELP_STRING(--enable-test-apps,Build test binaries and modules at make time),[ + enable_test_apps=$enableval +],[ + enable_test_apps=no +]) + prefix="$orig_prefix" APACHE_ENABLE_MODULES @@ -808,6 +816,30 @@ APACHE_SUBST(OS_SPECIFIC_VARS) APACHE_SUBST(HTTPD_LIBS) APACHE_SUBST(CHECK_TARGETS) +dnl Resolve --enable-test-apps after module config stubs have run +dnl (nghttp2 detection for h2ws happens in modules/http2/config2.m4) +if test "$enable_test_apps" = "yes" -a -d "./test"; then + + AC_MSG_CHECKING([for nghttp2 to build h2ws test client]) + if test "x$ac_cv_nghttp2" != "xyes"; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([--enable-test-apps requires nghttp2 for h2ws client (use --with-nghttp2=PATH)]) + fi + AC_MSG_RESULT([yes]) + + AC_MSG_CHECKING([for DSO support to build test modules]) + if test "$enable_so" != "yes" -a "$enable_so" != "static"; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([--enable-test-apps requires DSO support (--enable-so)]) + fi + AC_MSG_RESULT([yes]) + + TEST_APPS_SUMMARY="yes (mod_aptest, mod_h1test, mod_h2test, h2ws)" + other_targets="$other_targets test-apps" +else + TEST_APPS_SUMMARY="no" +fi + PRE_SHARED_CMDS='echo ""' POST_SHARED_CMDS='echo ""' @@ -1132,4 +1164,5 @@ AC_MSG_NOTICE([summary of build options: LDFLAGS: ${APACHE_CONF_SEL_LDFLAGS} LIBS: ${APACHE_CONF_SEL_LIBS} C preprocessor: ${APACHE_CONF_SEL_CPP} + Test apps: ${TEST_APPS_SUMMARY} ]) diff --git a/test/Makefile.in b/test/Makefile.in index ae5bf2b8c98..c224250a5d3 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -19,8 +19,58 @@ test: $(bin_PROGRAMS) # dbu: $(dbu_OBJECTS) # $(LINK) $(dbu_OBJECTS) $(PROGRAM_LDADD) +# --- Test module builds (used by --enable-test-apps) --- +# Builds each module into its source directory, matching apxs -c output locations. + +mod_aptest_DIR = $(top_srcdir)/test/pyhttpd/mod_aptest +mod_aptest_SRC = $(mod_aptest_DIR)/mod_aptest.c + +$(mod_aptest_DIR)/mod_aptest.slo: $(mod_aptest_SRC) + $(LIBTOOL) --mode=compile $(BASE_CC) $(SHLTCFLAGS) \ + -c $(mod_aptest_SRC) -o $(mod_aptest_DIR)/mod_aptest.lo && touch $@ + +$(mod_aptest_DIR)/mod_aptest.la: $(mod_aptest_DIR)/mod_aptest.slo + $(SH_LINK) -rpath $(libexecdir) -module -avoid-version \ + $(mod_aptest_DIR)/mod_aptest.lo + +mod_h1test_DIR = $(top_srcdir)/test/modules/http1/mod_h1test +mod_h1test_SRC = $(mod_h1test_DIR)/mod_h1test.c + +$(mod_h1test_DIR)/mod_h1test.slo: $(mod_h1test_SRC) + $(LIBTOOL) --mode=compile $(BASE_CC) $(SHLTCFLAGS) \ + -c $(mod_h1test_SRC) -o $(mod_h1test_DIR)/mod_h1test.lo && touch $@ + +$(mod_h1test_DIR)/mod_h1test.la: $(mod_h1test_DIR)/mod_h1test.slo + $(SH_LINK) -rpath $(libexecdir) -module -avoid-version \ + $(mod_h1test_DIR)/mod_h1test.lo + +mod_h2test_DIR = $(top_srcdir)/test/modules/http2/mod_h2test +mod_h2test_SRC = $(mod_h2test_DIR)/mod_h2test.c + +$(mod_h2test_DIR)/mod_h2test.slo: $(mod_h2test_SRC) + $(LIBTOOL) --mode=compile $(BASE_CC) $(SHLTCFLAGS) \ + -I$(mod_h2test_DIR) \ + -c $(mod_h2test_SRC) -o $(mod_h2test_DIR)/mod_h2test.lo && touch $@ + +$(mod_h2test_DIR)/mod_h2test.la: $(mod_h2test_DIR)/mod_h2test.slo + $(SH_LINK) -rpath $(libexecdir) -module -avoid-version \ + $(mod_h2test_DIR)/mod_h2test.lo + +test-modules: $(mod_aptest_DIR)/mod_aptest.la $(mod_h1test_DIR)/mod_h1test.la $(mod_h2test_DIR)/mod_h2test.la + +h2ws-client: + cd clients && $(MAKE) $(MFLAGS) h2ws + +.PHONY: test-apps test-modules h2ws-client + +test-apps: test-modules h2ws-client + clean: - rm -rf gen + rm -rf gen test-modules + cd clients && $(MAKE) $(MFLAGS) clean + rm -rf pyhttpd/mod_aptest/.libs pyhttpd/mod_aptest/*.o pyhttpd/mod_aptest/*.lo pyhttpd/mod_aptest/*.slo pyhttpd/mod_aptest/*.la + rm -rf modules/http1/mod_h1test/.libs modules/http1/mod_h1test/*.o modules/http1/mod_h1test/*.lo modules/http1/mod_h1test/*.slo modules/http1/mod_h1test/*.la + rm -rf modules/http2/mod_h2test/.libs modules/http2/mod_h2test/*.o modules/http2/mod_h2test/*.lo modules/http2/mod_h2test/*.slo modules/http2/mod_h2test/*.la find . -name __pycache__ | xargs rm -rf distclean: diff --git a/test/modules/http1/env.py b/test/modules/http1/env.py index 1a88e3b032f..f54fcf690e6 100644 --- a/test/modules/http1/env.py +++ b/test/modules/http1/env.py @@ -25,18 +25,18 @@ def make(self): def _add_h1test(self): module_dir = self.env.test_modules_dir - if not self.env.isWindows: + if not module_dir and not self.env.isWindows: local_dir = os.path.dirname(inspect.getfile(H1TestSetup)) - p = subprocess.run([self.env.apxs, '-c', 'mod_h1test.c'], - capture_output=True, - cwd=os.path.join(local_dir, 'mod_h1test')) - - rv = p.returncode - if rv != 0: - log.error(f"compiling md_h1test failed: {p.stderr}") - raise Exception(f"compiling md_h1test failed: {p.stderr}") - module_dir = f"{local_dir}/mod_h1test/.libs" + if not os.path.exists(f"{module_dir}/mod_h1test.so"): + p = subprocess.run([self.env.apxs, '-c', 'mod_h1test.c'], + capture_output=True, + cwd=os.path.join(local_dir, 'mod_h1test')) + + rv = p.returncode + if rv != 0: + log.error(f"compiling md_h1test failed: {p.stderr}") + raise Exception(f"compiling md_h1test failed: {p.stderr}") modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf') with open(modules_conf, 'a') as fd: diff --git a/test/modules/http2/env.py b/test/modules/http2/env.py index fe690bf9811..0e41a2fa135 100644 --- a/test/modules/http2/env.py +++ b/test/modules/http2/env.py @@ -26,18 +26,18 @@ def make(self): def _add_h2test(self): module_dir = self.env.test_modules_dir - if not self.env.isWindows: + if not module_dir and not self.env.isWindows: local_dir = os.path.dirname(inspect.getfile(H2TestSetup)) - p = subprocess.run([self.env.apxs, '-c', 'mod_h2test.c'], - capture_output=True, - cwd=os.path.join(local_dir, 'mod_h2test')) - - rv = p.returncode - if rv != 0: - log.error(f"compiling md_h2test failed: {p.stderr}") - raise Exception(f"compiling md_h2test failed: {p.stderr}") - module_dir = f"{local_dir}/mod_h2test/.libs" + if not os.path.exists(f"{module_dir}/mod_h2test.so"): + p = subprocess.run([self.env.apxs, '-c', 'mod_h2test.c'], + capture_output=True, + cwd=os.path.join(local_dir, 'mod_h2test')) + + rv = p.returncode + if rv != 0: + log.error(f"compiling md_h2test failed: {p.stderr}") + raise Exception(f"compiling md_h2test failed: {p.stderr}") modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf') with open(modules_conf, 'a') as fd: diff --git a/test/pyhttpd/env.py b/test/pyhttpd/env.py index 521c16124d7..ef006a62d88 100644 --- a/test/pyhttpd/env.py +++ b/test/pyhttpd/env.py @@ -240,17 +240,17 @@ def _fix_shebang(py_file): def _add_aptest(self): module_dir = self.env.test_modules_dir - if not self.env.isWindows: + if not module_dir and not self.env.isWindows: local_dir = os.path.dirname(inspect.getfile(HttpdTestSetup)) - p = subprocess.run([self.env.apxs, '-c', 'mod_aptest.c'], - capture_output=True, - cwd=os.path.join(local_dir, 'mod_aptest')) - rv = p.returncode - if rv != 0: - log.error(f"compiling mod_aptest failed: {p.stderr}") - raise Exception(f"compiling mod_aptest failed: {p.stderr}") - module_dir = os.path.join(local_dir, "mod_aptest", ".libs") + if not os.path.exists(os.path.join(module_dir, "mod_aptest.so")): + p = subprocess.run([self.env.apxs, '-c', 'mod_aptest.c'], + capture_output=True, + cwd=os.path.join(local_dir, 'mod_aptest')) + rv = p.returncode + if rv != 0: + log.error(f"compiling mod_aptest failed: {p.stderr}") + raise Exception(f"compiling mod_aptest failed: {p.stderr}") modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf') with open(modules_conf, 'a') as fd: