contrib/kyua: update to 0.15.0

This new release contains multiple feature updates and bugfixes. Please
see the release notes mentioned in the merge commit for more details.

MFC after:	1 month
Merge commit '144afd05f8a2300361ec30c1c2020e4022ddd943'

Conflicts:
	contrib/kyua/cli/cmd_debug.cpp
	contrib/kyua/doc/kyua-debug.1.in
	contrib/kyua/doc/kyuafile.5.in
	contrib/kyua/engine/config.cpp
	contrib/kyua/engine/execenv/execenv.cpp
	contrib/kyua/engine/execenv/execenv.hpp
	contrib/kyua/engine/execenv/execenv_host.hpp
	contrib/kyua/engine/requirements.cpp
	contrib/kyua/engine/requirements.hpp
	contrib/kyua/engine/scheduler.cpp
	contrib/kyua/model/metadata.cpp
	contrib/kyua/os/freebsd/execenv_jail.hpp
	contrib/kyua/os/freebsd/execenv_jail_stub.cpp
	contrib/kyua/os/freebsd/main.cpp
	contrib/kyua/os/freebsd/reqs_checker_kmods.cpp
	contrib/kyua/os/freebsd/utils/jail.hpp
	contrib/kyua/utils/fs/directory.cpp
	contrib/kyua/utils/process/executor.cpp
This commit is contained in:
Enji Cooper committed 2026-10-07 10:50:26 -07:00
commit eb8f69902f
147 files changed
+3024 -6888

No files matched your search

-25
View File
@@ -1,25 +0,0 @@
env:
ARCH: amd64
task:
matrix:
- name: 14.0-RELEASE
freebsd_instance:
image_family: freebsd-14-0
- name: 14.0-STABLE
freebsd_instance:
image_family: freebsd-14-0-snap
- name: 13.2-RELEASE
freebsd_instance:
image_family: freebsd-13-2
- name: 13.2-STABLE
freebsd_instance:
image_family: freebsd-13-2-snap
env:
DO: distcheck
install_script:
- sed -i.bak -e 's,pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly,pkg+http://pkg.FreeBSD.org/\${ABI}/latest,' /etc/pkg/FreeBSD.conf
- ASSUME_ALWAYS_YES=yes pkg bootstrap -f
- pkg install -y autoconf automake atf lutok pkgconf sqlite3
script:
- ./admin/travis-build.sh
-23
View File
@@ -1,23 +0,0 @@
*.a
*.o
*_helpers
*_inttest
*_test
*~
.deps
.dirstamp
Doxyfile
Makefile
Makefile.in
aclocal.m4
api-docs
autom4te.cache
config.h
config.h.in
config.log
config.status
configure
kyua
local-kyua
stamp-h1
-49
View File
@@ -1,49 +0,0 @@
language: cpp
sudo: required
before_install:
- ./admin/travis-install-deps.sh
matrix:
include:
- os: linux
dist: xenial
compiler: clang
env: ARCH=amd64 DO=distcheck AS_ROOT=no
- os: linux
dist: xenial
compiler: gcc
env: ARCH=amd64 DO=distcheck AS_ROOT=no
- os: linux
dist: xenial
compiler: clang
env: ARCH=amd64 DO=apidocs
- os: linux
dist: xenial
compiler: clang
env: ARCH=amd64 DO=style
- os: linux
dist: xenial
compiler: clang
env: ARCH=amd64 DO=distcheck AS_ROOT=yes UNPRIVILEGED_USER=no
- os: linux
dist: xenial
compiler: clang
env: ARCH=amd64 DO=distcheck AS_ROOT=yes UNPRIVILEGED_USER=yes
# TODO(ngie): reenable i386; the libraries were not available in the
# Ubuntu Xenial x86_64 docker image.
#- os: linux
# dist: xenial
# compiler: clang
# env: ARCH=i386 DO=distcheck AS_ROOT=no
#- os: linux
# dist: xenial
# compiler: gcc
# env: ARCH=i386 DO=distcheck AS_ROOT=no
script:
- ./admin/travis-build.sh
notifications:
email:
- [email protected]
-1
View File
@@ -45,7 +45,6 @@ JAVADOC_AUTOBRIEF = YES
MACRO_EXPANSION = YES
OUTPUT_DIRECTORY = @top_builddir@/api-docs
OUTPUT_LANGUAGE = English
PREDEFINED += "KYUA_DEFS_NORETURN="
PREDEFINED += "KYUA_DEFS_FORMAT_PRINTF(x, y)="
PROJECT_NAME = "@PACKAGE_NAME@"
PROJECT_NUMBER = @VERSION@
+12
View File
@@ -0,0 +1,12 @@
*/*/Makefile*
*/Makefile*
*/*.m4
*/*.pc.in
INSTALL.md
Makefile*
aclocal.m4
admin/
config.h.in
bootstrap/
configure*
m4/
-268
View File
@@ -1,268 +0,0 @@
Installation instructions
=========================
Kyua uses the GNU Automake, GNU Autoconf and GNU Libtool utilities as
its build system. These are used only when compiling the application
from the source code package. If you want to install Kyua from a binary
package, you do not need to read this document.
For the impatient:
$ ./configure
$ make
$ make check
Gain root privileges
# make install
Drop root privileges
$ make installcheck
Or alternatively, install as a regular user into your home directory:
$ ./configure --prefix ~/local
$ make
$ make check
$ make install
$ make installcheck
Dependencies
------------
To build and use Kyua successfully you need:
* A standards-compliant C and C++ complier.
* Lutok 0.4.
* pkg-config.
* SQLite 3.6.22.
To build the Kyua tests, you optionally need:
* The Automated Testing Framework (ATF), version 0.15 or greater. This
is required if you want to create a distribution file.
If you are building Kyua from the code on the repository, you will also
need the following tools:
* GNU Autoconf.
* GNU Automake.
* GNU Libtool.
Regenerating the build system
-----------------------------
This is not necessary if you are building from a formal release
distribution file.
On the other hand, if you are building Kyua from code extracted from the
repository, you must first regenerate the files used by the build
system. You will also need to do this if you modify `configure.ac`,
`Makefile.am` or any of the other build system files. To do this, simply
run:
$ autoreconf -i -s
If ATF is installed in a different prefix than Autoconf, you will also
need to tell autoreconf where the ATF M4 macros are located. Otherwise,
the configure script will be incomplete and will show confusing syntax
errors mentioning, for example, `ATF_CHECK_SH`. To fix this, you have
to run autoreconf in the following manner, replacing `<atf-prefix>` with
the appropriate path:
$ autoreconf -i -s -I <atf-prefix>/share/aclocal
General build procedure
-----------------------
To build and install the source package, you must follow these steps:
1. Configure the sources to adapt to your operating system. This is
done using the `configure` script located on the sources' top
directory, and it is usually invoked without arguments unless you
want to change the installation prefix. More details on this
procedure are given on a later section.
2. Build the sources to generate the binaries and scripts. Simply run
`make` on the sources' top directory after configuring them. No
problems should arise.
3. Check that the built programs work by running `make check`. You do
not need to be root to do this, but if you are not, some checks will
be skipped.
4. Install the program by running `make install`. You may need to
become root to issue this step.
5. Issue any manual installation steps that may be required. These are
described later in their own section.
6. Check that the installed programs work by running `make
installcheck`. You do not need to be root to do this, but if you are
not, some checks will be skipped.
Configuration flags
-------------------
The most common, standard flags given to `configure` are:
* `--prefix=directory`:
**Possible values:** Any path.
**Default:** `/usr/local`.
Specifies where the program (binaries and all associated files) will
be installed.
* `--sysconfdir=directory`:
**Possible values:** Any path.
**Default:** `/usr/local/etc`.
Specifies where the installed programs will look for configuration
files. `/kyua` will be appended to the given path unless
`KYUA_CONFSUBDIR` is redefined as explained later on.
* `--help`:
Shows information about all available flags and exits immediately,
without running any configuration tasks.
The following environment variables are specific to Kyua's `configure`
script:
* `GDB`:
**Possible values:** empty, absolute path to GNU GDB.
**Default:** empty.
Specifies the path to the GNU GDB binary that Kyua will use to gather a
stack trace of a crashing test program. If empty, the configure script
will try to find a suitable binary for you and, if not found, Kyua will
attempt to do the search at run time.
* `KYUA_ARCHITECTURE`:
**Possible values:** name of a CPU architecture (e.g. `x86_64`, `powerpc`).
**Default:** autodetected; typically the output of `uname -p`.
Specifies the name of the CPU architecture on which Kyua will run.
This value is used at run-time to determine tests that are not
applicable to the host system.
* `KYUA_CONFSUBDIR`:
**Possible values:** empty, a relative path.
**Default:** `kyua`.
Specifies the subdirectory of the configuration directory (given by
the `--sysconfdir` argument) under which Kyua will search for its
configuration files.
* `KYUA_CONFIG_FILE_FOR_CHECK`:
**Possible values:** none, an absolute path to an existing file.
**Default:** none.
Specifies the `kyua.conf` configuration file to use when running any
of the `check`, `installcheck` or `distcheck` targets on this source
tree. This setting is exclusively used to customize the test runs of
Kyua itself and has no effect whatsoever on the built product.
* `KYUA_MACHINE`:
**Possible values:** name of a machine type (e.g. `amd64`, `macppc`).
**Default:** autodetected; typically the output of `uname -m`.
Specifies the name of the machine type on which Kyua will run. This
value is used at run-time to determine tests that are not applicable
to the host system.
* `KYUA_TMPDIR`:
**Possible values:** an absolute path to a temporary directory.
**Default:** `/tmp`.
Specifies the path that Kyua will use to create temporary directories
in by default.
The following flags are specific to Kyua's `configure` script:
* `--enable-developer`:
**Possible values:** `yes`, `no`.
**Default:** `yes` in Git `HEAD` builds; `no` in formal releases.
Enables several features useful for development, such as the inclusion
of debugging symbols in all objects or the enforcement of compilation
warnings.
The compiler will be executed with an exhaustive collection of warning
detection features regardless of the value of this flag. However, such
warnings are only fatal when `--enable-developer` is `yes`.
* `--with-atf`:
**Possible values:** `yes`, `no`, `auto`.
**Default:** `auto`.
Enables usage of ATF to build (and later install) the tests.
Setting this to `yes` causes the configure script to look for ATF
unconditionally and abort if not found. Setting this to `auto` lets
configure perform the best decision based on availability of ATF.
Setting this to `no` explicitly disables ATF usage.
When support for tests is enabled, the build process will generate the
test programs and will later install them into the tests tree.
Running `make check` or `make installcheck` from within the source
directory will cause these tests to be run with Kyua.
* `--with-doxygen`:
**Possible values:** `yes`, `no`, `auto` or a path.
**Default:** `auto`.
Enables usage of Doxygen to generate documentation for internal APIs.
This documentation is *not* installed and is only provided to help the
developer of this package. Therefore, enabling or disabling Doxygen
causes absolutely no differences on the files installed by this
package.
Setting this to `yes` causes the configure script to look for Doxygen
unconditionally and abort if not found. Setting this to `auto` lets
configure perform the best decision based on availability of Doxygen.
Setting this to `no` explicitly disables Doxygen usage. And, lastly,
setting this to a path forces configure to use a specific Doxygen
binary, which must exist.
Post-installation steps
-----------------------
Copy the `Kyuafile.top` file installed in the examples directory to the
root of your tests hierarchy and name it `Kyuafile`. For example:
# cp /usr/local/share/kyua/examples/Kyuafile.top \
/usr/local/tests/Kyuafile
This will allow you to simply go into `/usr/tests` and run the tests
from there.
Run the tests!
--------------
Lastly, after a successful installation, you should periodically run the
tests from the final location to ensure things remain stable. Do so as
follows:
$ cd /usr/local/kyua && kyua test
The following configuration variables are specific to the 'kyua' test
suite and can be given to Kyua with arguments of the form
`-v test_suites.kyua.<variable_name>=<value>`:
* `run_coredump_tests`:
**Possible values:** `true` or `false`.
**Default:** `true`.
Avoids running tests that crash subprocesses on purpose to make them
dump core. Such tests are particularly slow on macOS, and it is
sometimes handy to disable them for quicker development iteration.
If you see any tests fail, do not hesitate to report them in:
https://github.com/jmmv/kyua/issues/
Thank you!
-186
View File
@@ -1,186 +0,0 @@
# Copyright 2010 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ACLOCAL_AMFLAGS = -I m4
CHECK_BOOTSTRAP_DEPS =
CHECK_KYUA_DEPS =
CHECK_LOCAL =
CLEAN_TARGETS =
DIST_HOOKS =
PHONY_TARGETS =
CLEANFILES =
EXTRA_DIST =
noinst_DATA =
noinst_LIBRARIES =
noinst_SCRIPTS =
doc_DATA = AUTHORS CONTRIBUTING.md CONTRIBUTORS LICENSE NEWS.md
noinst_DATA += INSTALL.md README.md
EXTRA_DIST += $(doc_DATA) INSTALL.md README.md
if WITH_ATF
tests_topdir = $(pkgtestsdir)
tests_top_DATA = Kyuafile
EXTRA_DIST += $(tests_top_DATA)
endif
include admin/Makefile.am.inc
include bootstrap/Makefile.am.inc
include cli/Makefile.am.inc
include doc/Makefile.am.inc
include drivers/Makefile.am.inc
include engine/Makefile.am.inc
include examples/Makefile.am.inc
include integration/Makefile.am.inc
include misc/Makefile.am.inc
include model/Makefile.am.inc
include store/Makefile.am.inc
include utils/Makefile.am.inc
bin_PROGRAMS = kyua
kyua_SOURCES = main.cpp
kyua_CXXFLAGS = $(CLI_CFLAGS) $(ENGINE_CFLAGS) $(UTILS_CFLAGS)
kyua_LDADD = $(CLI_LIBS) $(ENGINE_LIBS) $(UTILS_LIBS)
CHECK_ENVIRONMENT = KYUA_CONFDIR="/non-existent" \
KYUA_DOCDIR="$(abs_top_srcdir)" \
KYUA_EXAMPLESDIR="$(abs_top_srcdir)/examples" \
KYUA_MISCDIR="$(abs_top_srcdir)/misc" \
KYUA_STOREDIR="$(abs_top_srcdir)/store" \
KYUA_STORETESTDATADIR="$(abs_top_srcdir)/store" \
PATH="$(abs_top_builddir):$${PATH}"
INSTALLCHECK_ENVIRONMENT = KYUA_CONFDIR="/non-existent" \
PATH="$(prefix)/bin:$${PATH}"
# Generate local-kyua, a wrapper shell script to run the just-built 'kyua'
# binary by pointing it to the possibly not-yet-installed data files in the
# build tree.
noinst_SCRIPTS += local-kyua
CLEANFILES += local-kyua local-kyua.tmp
local-kyua: Makefile
$(AM_V_GEN)echo '#!/bin/sh' >local-kyua.tmp; \
echo 'env $(CHECK_ENVIRONMENT) $(TESTS_ENVIRONMENT)' \
'"$(abs_top_builddir)/kyua" \
--config='$(KYUA_CONFIG_FILE_FOR_CHECK)' \
"$${@}"' >>local-kyua.tmp; \
chmod +x local-kyua.tmp; \
mv -f local-kyua.tmp local-kyua
if WITH_ATF
CHECK_LOCAL += dump-ulimits check-kyua
PHONY_TARGETS += check-kyua
check-kyua: $(CHECK_KYUA_DEPS)
@failed=no; \
./local-kyua test \
--kyuafile='$(top_srcdir)/Kyuafile' --build-root='$(top_builddir)' \
|| failed=yes; \
if [ "$${failed}" = yes ]; then \
./local-kyua report --results-file='$(abs_top_srcdir)' \
--verbose --results-filter=broken,failed; \
exit 1; \
fi
installcheck-local: dump-ulimits installcheck-kyua
PHONY_TARGETS += installcheck-kyua
installcheck-kyua:
@failed=no; \
cd $(pkgtestsdir) && $(INSTALLCHECK_ENVIRONMENT) $(TESTS_ENVIRONMENT) \
kyua --config='$(KYUA_CONFIG_FILE_FOR_CHECK)' test \
|| failed=yes; \
if [ "$${failed}" = yes ]; then \
cd $(pkgtestsdir) && $(INSTALLCHECK_ENVIRONMENT) \
$(TESTS_ENVIRONMENT) \
kyua --config='$(KYUA_CONFIG_FILE_FOR_CHECK)' report \
--verbose --results-filter=broken,failed; \
exit 1; \
fi
# TODO(jmmv): kyua should probably be recording this information itself as part
# of the execution context, just as we record environment variables.
PHONY_TARGETS += dump-ulimits
dump-ulimits:
@echo "Resource limits:"
@{ \
ulimit -a | sed -e 's,$$, (soft),'; \
ulimit -a -H | sed -e 's,$$, (hard),'; \
} | sort | sed -e 's,^, ,'
@echo
else
DIST_HOOKS += forbid-dist
PHONY_TARGETS += forbid-dist
forbid-dist:
@echo "Sorry; cannot make dist without atf."
@false
endif
check-local: $(CHECK_LOCAL)
if WITH_DOXYGEN
# Runs doxygen on the source tree and validates the contents of the docstrings.
# We do not do this by default, even if doxygen has been enabled, because this
# step takes a long time. Instead, we just rely on a Travis CI build to catch
# inconsistencies.
PHONY_TARGETS += check-api-docs
check-api-docs: api-docs/api-docs.tag
@$(AWK) -f $(srcdir)/admin/check-api-docs.awk api-docs/doxygen.out
api-docs/api-docs.tag: $(builddir)/Doxyfile $(SOURCES)
@$(MKDIR_P) api-docs
@rm -f api-docs/doxygen.out api-docs/doxygen.out.tmp
$(AM_V_GEN)$(DOXYGEN) $(builddir)/Doxyfile \
>api-docs/doxygen.out.tmp 2>&1 && \
mv api-docs/doxygen.out.tmp api-docs/doxygen.out
CLEAN_TARGETS += clean-api-docs
clean-api-docs:
rm -rf api-docs
endif
# Replace Automake's builtin check-news functionality so that we can validate
# the NEWS.md file instead of NEWS.
DIST_HOOKS += check-news
PHONY_TARGETS += check-news
check-news:
@case "$$(sed 15q "$(srcdir)/NEWS.md")" in \
*"$(VERSION)"*) : ;; \
*) \
echo "NEWS.md not updated; not releasing" 1>&2; \
exit 1 \
;; \
esac
clean-local: $(CLEAN_TARGETS)
dist-hook: $(DIST_HOOKS)
PHONY_TARGETS += clean-all
clean-all:
GIT="$(GIT)" $(SH) $(srcdir)/admin/clean-all.sh
.PHONY: $(PHONY_TARGETS)
+125 -38
View File
@@ -1,17 +1,119 @@
Major changes between releases
==============================
# Major changes between releases
## Changes in version 0.15.0
Changes in version 0.14
-----------------------
**Released on 2026/10/07.**
**NOT RELEASED YET; STILL UNDER DEVELOPMENT.**
### Bugfixes
* Explicitly require C++11 language features when compiling Kyua.
* #265: Null cleanups
* #271: kyua: Try harder to delete directories.
* #300: Implement utils::config::positive_int_node::deep_copy
### Developer Workflow Changes
Changes in version 0.13
-----------------------
* #254: Add initial GitHub Actions support for kyua
* #288: [CI] remove legacy CI scripts and files
* #291: Remove Travis CI config
* #298: Add sanitizers and code coverage support
* #301: Add FreeBSD CI support via vmactions
* #305: Automate uploading release assets
### Feature Enhancements
* #203: Add GoogleTest support
* #230: Do not count skipped as passed in test cmd
* #260: Support require.diskspace ATF metadata
* #261: Pass unprivileged user config prop to ATF using all known names
* #266: Add "kyua debug -p" option
* #270: Add required_kmods metadata
* #272: Make "test" command actually report about workdir cleanup issues
* #273: Make "debug -p" skip writing stdout/stderr to tmp files
* #277: kyua-debug: Add -P option
* #290: Require C++-20 in order to build kyua
* #307: Upstream multiple items from FreeBSD
### Documentation
* #258: kyuafile.5: Add ATF metadata mapping reference
* #275: kyua manuals: Correct --results-file short form
* #279: docs: Standardize document description tone
### Miscellaneous
* #264: Switch from std::auto_ptr<> to std::unique_ptr<>
* #269: Fix cmd_about_test:topic__version test case
* #297: Reduce overall lutok dependency
* #312: Replace KYUA_ATTRIBUTE_{NORETURN,UNUSED}} with C++ attributes
* #318: utils::fs: remove umount(8) support
**Full Changelog**: https://github.com/freebsd/lutok/compare/kyua-0.14.1...kyua-0.15.0
## Changes in version 0.14.1
**Released on March 29th, 2025.**
* Issue #263: fix release tarball by relying on `make dist`.
* Document ATF to Kyua mappings for metadata properties.
* Support `require.diskspace` ATF metadata property.
* Support backwards compatible `unprivileged_user` metadata property for ease
of use dealing with ATF vs Kyua.
* Fix building from source by tracking `utils/process/Kyuafile.in` and
`engine/execenv/execenv_fwd.hpp` with automake.
## Changes in version 0.14
**Released on December 31st, 2024.**
* Replace `--with-atf` with `--enable-atf`. The latter must be specified
to enable ATF support and the Kyua tests by proxy.
* Require newer versions of ATF (0.21) and Lutok (0.5). This is being done
as part of a multi-phase deprecation of pre-C++11 environments.
* Vendor the ATF m4 files from the freebsd/atf repo.
* Translate `is_exclusive` metadata to its ATF counterpart.
* Issue #236: fix accidental test forkbomb in specific user environments
with `integration` tests by avoiding infinite recursion calling kyua.
* Fix the build on Ubuntu 24.04.
- execenv support added. This FreeBSD-specific feature allows tests to be
executed in jails.
* Issue #169: Remove deprecated `readdir_r` use.
* Fix build issue on more recent versions of MacOS.
* Fix build issue on IllumOS.
* Fix issues with PID reuse in testcases.
* Escape characters captured from stderr and stdout in HTML output.
* `integration/cmd_report_test:verbose`: fix regular expression used in
tests which would break in certain user environments.
* Add Cirrus CI support for testing Kyua on FreeBSD.
* Remove `UTILS_UNUSED_PARAM` macro.
* Fix document rendering with newer versions of doxygen.
* Issue #152: explicitly require C++11 language features when compiling Kyua.
Remove `std::shared_ptr` compatibility header, `utils/shared_ptr.hpp`.
* Fix `igor` and `mandoc -Tlint` reported issues with generated manpages.
* Issue #167: fix typos in kyua(1) manpage.
## Changes in version 0.13
**Released on August 26th, 2016.**
@@ -36,8 +138,7 @@ Changes in version 0.13
timers to control test deadlines.
Changes in version 0.12
-----------------------
## Changes in version 0.12
**Released on November 22nd, 2015.**
@@ -129,8 +230,7 @@ parallelization possibilities.
Markdown for better formatting online.
Changes in version 0.11
-----------------------
## Changes in version 0.11
**Released on October 23rd, 2014.**
@@ -211,8 +311,7 @@ Changes in version 0.11
examples.
Changes in version 0.10
-----------------------
## Changes in version 0.10
**Experimental version released on August 14th, 2014.**
@@ -232,8 +331,7 @@ Changes in version 0.10
prevent triggering a core dump that made the test fail in some platforms.
Changes in kyua-cli version 0.9
-------------------------------
## Changes in kyua-cli version 0.9
**Experimental version released on August 8th, 2014.**
@@ -276,8 +374,7 @@ Changes in more detail:
files.
Changes in kyua-testers version 0.3
-----------------------------------
## Changes in kyua-testers version 0.3
**Experimental version released on August 8th, 2014.**
@@ -293,8 +390,7 @@ Changes in kyua-testers version 0.3
handle test programs that report a pass but exit with a non-zero code.
Changes in kyua-cli version 0.8
-------------------------------
## Changes in kyua-cli version 0.8
**Experimental version released on December 7th, 2013.**
@@ -310,8 +406,7 @@ Changes in kyua-cli version 0.8
the addition of new testers or the selective installation of them.
Changes in kyua-testers version 0.2
-----------------------------------
## Changes in kyua-testers version 0.2
**Experimental version released on December 7th, 2013.**
@@ -326,8 +421,7 @@ Changes in kyua-testers version 0.2
own session instead of just to their own process group.
Changes in kyua-cli version 0.7
-------------------------------
## Changes in kyua-cli version 0.7
**Experimental version released on October 18th, 2013.**
@@ -347,8 +441,7 @@ Changes in kyua-cli version 0.7
LTS, which appears stuck in 1.11.1.
Changes in kyua-cli version 0.6
-------------------------------
## Changes in kyua-cli version 0.6
**Experimental version released on February 22nd, 2013.**
@@ -412,8 +505,7 @@ Changes in kyua-cli version 0.6
executables.
Changes in kyua-testers version 0.1
-----------------------------------
## Changes in kyua-testers version 0.1
**Experimental version released on February 19th, 2013.**
@@ -430,8 +522,7 @@ of `kyua-cli`, which means that the overall build times of Kyua are now
reduced.
Changes in kyua-cli version 0.5
-------------------------------
## Changes in kyua-cli version 0.5
**Experimental version released on July 10th, 2012.**
@@ -454,8 +545,7 @@ Changes in kyua-cli version 0.5
from the repository.
Changes in kyua-cli version 0.4
-------------------------------
## Changes in kyua-cli version 0.4
**Experimental version released on June 6th, 2012.**
@@ -497,8 +587,7 @@ Changes in kyua-cli version 0.4
such tree.
Changes in kyua-cli version 0.3
-------------------------------
## Changes in kyua-cli version 0.3
**Experimental version released on February 24th, 2012.**
@@ -533,8 +622,7 @@ Changes in kyua-cli version 0.3
failing test.
Changes in kyua-cli version 0.2
-------------------------------
## Changes in kyua-cli version 0.2
**Experimental version released on August 24th, 2011.**
@@ -599,8 +687,7 @@ Without further ado, here comes the itemized list of changes:
and Ubuntu 10.04.1 LTS. (Issues #20, #21, #26.)
Changes in kyua-cli version 0.1
-------------------------------
## Changes in kyua-cli version 0.1
**Experimental version released on June 23rd, 2011.**
+14 -19
View File
@@ -1,5 +1,4 @@
Welcome to the Kyua project!
============================
# Welcome to the Kyua project!
Kyua is a **testing framework** for infrastructure software, originally
designed to equip BSD-based operating systems with a test suite. This
@@ -16,7 +15,7 @@ on a production machine.
Kyua is **able to execute test programs written with a plethora of testing
libraries and languages**. The library of choice is
[ATF](https://github.com/jmmv/atf/), for which Kyua was originally
[ATF](https://github.com/freebsd/atf/), for which Kyua was originally
designed, but simple, framework-less test programs and TAP-compliant test
programs can also be executed through Kyua.
@@ -26,25 +25,23 @@ This is not an official Google product.
[Read more about Kyua in the About wiki page.](../../wiki/About)
Download
--------
## Download
The latest version of Kyua is 0.13 and was released on August 26th, 2016.
The latest version of Kyua is 0.14.1 and was released on March 29th, 2025.
Download: [kyua-0.13](../../releases/tag/kyua-0.13).
Download: [kyua-0.14.1](../../releases/tag/kyua-0.14.1).
See the [release notes](NEWS.md) for information about the changes in this
See the [release notes](NEWS) for information about the changes in this
and all previous releases.
Installation
------------
## Installation
You are encouraged to install binary packages for your operating system
wherever available:
* Fedora 20 and above: install the `kyua-cli` package with `yum install
kyua-cli`.
* Fedora 20 and above: install the `kyua` package with `dnf install
kyua`.
* FreeBSD 10.0 and above: install the `kyua` package with `pkg install kyua`.
@@ -52,7 +49,7 @@ wherever available:
* OpenBSD with packages: install the `kyua` package with `pkg_add kyua`.
* OS X (with Homebrew): install the `kyua` package with `brew install kyua`.
* macOS (with Homebrew): install the `kyua` package with `brew install kyua`.
Should you want to build and install Kyua from the source tree provided
here, follow the instructions in the
@@ -60,11 +57,10 @@ here, follow the instructions in the
You should also install the ATF libraries to assist in the development of
test programs. To that end, see the
[ATF project page](https://github.com/jmmv/atf/).
[ATF project page](https://github.com/freebsd/atf/).
Contributing
------------
## Contributing
Want to contribute? Great! But please first read the guidelines provided
in [CONTRIBUTING.md](CONTRIBUTING.md).
@@ -74,11 +70,10 @@ the [list of copyright holders](AUTHORS) and the [list of
individuals](CONTRIBUTORS).
Support
-------
## Support
Please use the [kyua-discuss mailing
list](https://groups.google.com/forum/#!forum/kyua-discuss) for any support
inquiries.
*Homepage:* https://github.com/jmmv/kyua/
*Homepage:* https://github.com/freebsd/kyua/
-6
View File
@@ -1,6 +0,0 @@
ar-lib
compile
depcomp
install-sh
mdate-sh
missing
-41
View File
@@ -1,41 +0,0 @@
# Copyright 2015 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
PHONY_TARGETS += check-style
check-style:
@$(srcdir)/admin/check-style.sh \
-b "$(abs_top_builddir)" \
-s "$(abs_top_srcdir)" \
-t "$(PACKAGE_TARNAME)"
EXTRA_DIST += admin/check-style-common.awk \
admin/check-style-cpp.awk \
admin/check-style-make.awk \
admin/check-style-man.awk \
admin/check-style-shell.awk \
admin/check-style.sh
-131
View File
@@ -1,131 +0,0 @@
#! /bin/sh
# Copyright 2017 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# \file admin/build-bintray-dist.sh
# Builds a full Kyua installation under /usr/local for Ubuntu.
#
# This script is used to create the bintray distribution packages in lieu
# of real Debian packages for Kyua. The result of this script is a
# tarball that provides the contents of /usr/local for Kyua.
set -e -x
err() {
echo "${@}" 1>&2
exit 1
}
install_deps() {
sudo apt-get update -qq
local pkgsuffix=
local packages=
packages="${packages} autoconf"
packages="${packages} automake"
packages="${packages} clang"
packages="${packages} g++"
packages="${packages} gdb"
packages="${packages} git"
packages="${packages} libtool"
packages="${packages} make"
if [ "${ARCH?}" = i386 ]; then
pkgsuffix=:i386
packages="${packages} gcc-multilib"
packages="${packages} g++-multilib"
fi
packages="${packages} liblua5.2-0${pkgsuffix}"
packages="${packages} liblua5.2-dev${pkgsuffix}"
packages="${packages} libsqlite3-0${pkgsuffix}"
packages="${packages} libsqlite3-dev${pkgsuffix}"
packages="${packages} pkg-config${pkgsuffix}"
packages="${packages} sqlite3"
sudo apt-get install -y ${packages}
}
install_from_github() {
local name="${1}"; shift
local release="${1}"; shift
local distname="${name}-${release}"
local baseurl="https://github.com/jmmv/${name}"
wget --no-check-certificate \
"${baseurl}/releases/download/${distname}/${distname}.tar.gz"
tar -xzvf "${distname}.tar.gz"
local archflags=
[ "${ARCH?}" != i386 ] || archflags=-m32
cd "${distname}"
./configure \
--disable-developer \
--without-atf \
--without-doxygen \
CC="${CC?}" \
CFLAGS="${archflags}" \
CPPFLAGS="-I/usr/local/include" \
CXX="${CXX?}" \
CXXFLAGS="${archflags}" \
LDFLAGS="-L/usr/local/lib -Wl,-R/usr/local/lib" \
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"
make
sudo make install
cd -
rm -rf "${distname}" "${distname}.tar.gz"
}
main() {
[ "${ARCH+set}" = set ] || err "ARCH must be set in the environment"
[ "${CC+set}" = set ] || err "CC must be set in the environment"
[ "${CXX+set}" = set ] || err "CXX must be set in the environment"
[ ! -f /root/local.tgz ] || err "/root/local.tgz already exists"
tar -czf /root/local.tgz /usr/local
restore() {
rm -rf /usr/local
tar -xz -C / -f /root/local.tgz
rm /root/local.tgz
}
trap restore EXIT
rm -rf /usr/local
mkdir /usr/local
install_deps
install_from_github atf 0.21
install_from_github lutok 0.4
install_from_github kyua 0.13
local version="$(lsb_release -rs | cut -d . -f 1-2 | tr . -)"
local name="$(date +%Y%m%d)-usr-local-kyua"
name="${name}-ubuntu-${version}-${ARCH?}-${CC?}.tar.gz"
tar -czf "${name}" /usr/local
}
main "${@}"
-72
View File
@@ -1,72 +0,0 @@
#! /bin/sh
# Copyright 2015 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
BEGIN {
failed = 0
}
# Skip empty lines.
/^$/ {next}
# Skip lines that do not directly reference a file.
/^[^\/]/ {next}
# Ignore known problems. As far as I can tell, all the cases listed here are
# well-documented in the code but Doxygen fails, for some reason or another, to
# properly locate the docstrings.
/engine\/kyuafile\.cpp.*no matching class member/ {next}
/engine\/scheduler\.hpp.*Member setup\(void\).*friend/ {next}
/engine\/scheduler\.hpp.*Member wait_any\(void\)/ {next}
/utils\/optional\.ipp.*no matching file member/ {next}
/utils\/optional\.hpp.*Member make_optional\(const T &\)/ {next}
/utils\/config\/nodes\.hpp.*Member set_lua\(lutok::state &, const int\)/ {next}
/utils\/config\/nodes\.hpp.*Member push_lua\(lutok::state &\)/ {next}
/utils\/config\/nodes\.hpp.*Member set_string\(const std::string &\)/ {next}
/utils\/config\/nodes\.hpp.*Member to_string\(void\)/ {next}
/utils\/config\/nodes\.hpp.*Member is_set\(void\)/ {next}
/utils\/process\/executor\.hpp.*Member spawn\(Hook.*\)/ {next}
/utils\/process\/executor\.hpp.*Member spawn_followup\(Hook.*\)/ {next}
/utils\/process\/executor\.hpp.*Member setup\(void\).*friend/ {next}
/utils\/signals\/timer\.hpp.*Member detail::invoke_do_fired.*friend/ {next}
/utils\/stacktrace_test\.cpp.*no matching class member/ {next}
# Dump any other problems and account for the failure.
{
failed = 1
print
}
END {
if (failed) {
print "ERROR: Unexpected docstring problems encountered"
exit 1
} else {
exit 0
}
}
-79
View File
@@ -1,79 +0,0 @@
# Copyright 2015 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function warn(msg) {
print FILENAME "[" FNR "]: " msg > "/dev/stderr"
error = 1
}
BEGIN {
skip = 0
error = 0
}
/CHECK_STYLE_DISABLE/ {
skip = 1
next
}
/CHECK_STYLE_ENABLE/ {
skip = 0
next
}
/CHECK_STYLE_(ENABLE|DISABLE)/ {
next
}
{
if (skip)
next
if (length > 80 && NF > 1)
warn("Line too long to fit on screen")
}
/^ *\t+/ {
if (! match(FILENAME, "Makefile"))
warn("Tab character used for indentation");
}
/[ \t]+$/ {
warn("Trailing spaces or tabs");
}
/^#![^ ]/ {
warn("Missing space after #!");
}
END {
if (skip)
warn("Missing CHECK_STYLE_ENABLE");
if (error)
exit 1
}
-87
View File
@@ -1,87 +0,0 @@
# Copyright 2015 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function warn(msg) {
print FILENAME "[" FNR "]: " msg > "/dev/stderr"
error = 1
}
BEGIN {
skip = 0
error = 0
}
/CHECK_STYLE_DISABLE/ {
skip = 1
next
}
/CHECK_STYLE_ENABLE/ {
skip = 0
next
}
/CHECK_STYLE_(ENABLE|DISABLE)/ {
next
}
{
if (skip)
next
}
/#ifdef/ {
warn("Undesired usage of #ifdef; use #if defined()")
}
/#ifndef/ {
warn("Undesired usage of #ifndef; use #if !defined()")
}
/assert[ \t]*\(/ {
warn("Use the macros in sanity.hpp instead of assert");
}
/#.*include.*assert/ {
warn("Do not include assert.h nor cassert");
}
/std::endl/ {
warn("Use \\n instead of std::endl");
}
/\/\*/ && ! /\*\// {
warn("Do not use multi-line C-style comments");
}
END {
if (skip)
warn("Missing CHECK_STYLE_ENABLE");
if (error)
exit 1
}
-71
View File
@@ -1,71 +0,0 @@
# Copyright 2015 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function warn(msg) {
print FILENAME "[" FNR "]: " msg > "/dev/stderr"
error = 1
}
BEGIN {
skip = 0
error = 0
}
/CHECK_STYLE_DISABLE/ {
skip = 1
next
}
/CHECK_STYLE_ENABLE/ {
skip = 0
next
}
/CHECK_STYLE_(ENABLE|DISABLE)/ {
next
}
{
if (skip)
next
}
/^\t *\t/ {
warn("Continuation lines must use a single tab");
}
/mkdir.*-p/ {
warn("Use $(MKDIR_P) instead of mkdir -p");
}
END {
if (skip)
warn("Missing CHECK_STYLE_ENABLE");
if (error)
exit 1
}
-71
View File
@@ -1,71 +0,0 @@
# Copyright 2015 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function warn(msg) {
print FILENAME "[" FNR "]: " msg > "/dev/stderr"
error = 1
}
BEGIN {
skip = 0
error = 0
}
/CHECK_STYLE_DISABLE|^\.Bd/ {
skip = 1
next
}
/CHECK_STYLE_ENABLE|^\.Ed/ {
skip = 0
next
}
/CHECK_STYLE_(ENABLE|DISABLE)/ {
next
}
/^\.\\"/ {
next
}
{
if (skip)
next
}
/\.\.|e\.g\.|i\.e\./ {
next
}
END {
if (skip)
warn("Missing CHECK_STYLE_ENABLE");
if (error)
exit 1
}
-95
View File
@@ -1,95 +0,0 @@
# Copyright 2015 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function warn(msg) {
print FILENAME "[" FNR "]: " msg > "/dev/stderr"
error = 1
}
BEGIN {
skip = 0
error = 0
}
/CHECK_STYLE_DISABLE/ {
skip = 1
next
}
/CHECK_STYLE_ENABLE/ {
skip = 0
next
}
/CHECK_STYLE_(ENABLE|DISABLE)/ {
next
}
{
if (skip)
next
}
/^[ \t]*#/ {
next
}
/[$ \t]+_[a-zA-Z0-9]+=/ {
warn("Variable should not start with an underline")
}
/[^\\]\$[^0-9!'"$?@#*{}(|\/,]+/ {
warn("Missing braces around variable name")
}
/=(""|'')/ {
warn("Assignment to the empty string does not need quotes");
}
/basename[ \t]+/ {
warn("Use parameter expansion instead of basename");
}
/if[ \t]+(test|![ \t]+test)/ {
warn("Use [ instead of test");
}
/[ \t]+(test|\[).*==/ {
warn("test(1)'s == operator is not portable");
}
/if.*;[ \t]*fi$/ {
warn("Avoid using a single-line if conditional");
}
END {
if (skip)
warn("Missing CHECK_STYLE_ENABLE");
if (error)
exit 1
}
-170
View File
@@ -1,170 +0,0 @@
#! /bin/sh
# Copyright 2011 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# \file admin/check-style.sh
#
# Sanity checks the coding style of all source files in the project tree.
ProgName="${0##*/}"
# Prints an error message and exits.
#
# \param ... Parts of the error message; concatenated using a space as the
# separator.
err() {
echo "${ProgName}:" "${@}" 1>&2
exit 1
}
# Locates all source files within the project directory.
#
# We require the project to have been configured in a directory that is separate
# from the source tree. This is to allow us to easily filter out build
# artifacts from our search.
#
# \param srcdir Absolute path to the source directory.
# \param builddir Absolute path to the build directory.
# \param tarname Basename of the project's tar file, to skip possible distfile
# directories.
find_sources() {
local srcdir="${1}"; shift
local builddir="${1}"; shift
local tarname="${1}"; shift
(
cd "${srcdir}"
find . -type f -a \
\! -path "*/.git/*" \
\! -path "*/.deps/*" \
\! -path "*/autom4te.cache/*" \
\! -path "*/${tarname}-[0-9]*/*" \
\! -path "*/${builddir##*/}/*" \
\! -name "Makefile.in" \
\! -name "aclocal.m4" \
\! -name "config.h.in" \
\! -name "configure" \
\! -name "testsuite"
)
}
# Prints the style rules applicable to a given file.
#
# \param file Path to the source file.
guess_rules() {
local file="${1}"; shift
case "${file}" in
*/ax_cxx_compile_stdcxx.m4) ;;
*/ltmain.sh) ;;
*Makefile*) echo common make ;;
*.[0-9]) echo common man ;;
*.cpp|*.hpp) echo common cpp ;;
*.sh) echo common shell ;;
*) echo common ;;
esac
}
# Validates a given file against the rules that apply to it.
#
# \param srcdir Absolute path to the source directory.
# \param file Name of the file to validate relative to srcdir.
#
# \return 0 if the file is valid; 1 otherwise, in which case the style
# violations are printed to the output.
check_file() {
local srcdir="${1}"; shift
local file="${1}"; shift
local err=0
for rule in $(guess_rules "${file}"); do
awk -f "${srcdir}/admin/check-style-${rule}.awk" \
"${srcdir}/${file}" || err=1
done
return ${err}
}
# Entry point.
main() {
local builddir=.
local srcdir=.
local tarname=UNKNOWN
local arg
while getopts :b:s:t: arg; do
case "${arg}" in
b)
builddir="${OPTARG}"
;;
s)
srcdir="${OPTARG}"
;;
t)
tarname="${OPTARG}"
;;
\?)
err "Unknown option -${OPTARG}"
;;
esac
done
shift $(expr ${OPTIND} - 1)
srcdir="$(cd "${srcdir}" && pwd -P)"
builddir="$(cd "${builddir}" && pwd -P)"
[ "${srcdir}" != "${builddir}" ] || \
err "srcdir and builddir cannot match; reconfigure the package" \
"in a separate directory"
local sources
if [ ${#} -gt 0 ]; then
sources="${@}"
else
sources="$(find_sources "${srcdir}" "${builddir}" "${tarname}")"
fi
local ok=0
for file in ${sources}; do
local file="$(echo ${file} | sed -e "s,\\./,,")"
check_file "${srcdir}" "${file}" || ok=1
done
return "${ok}"
}
main "${@}"
-90
View File
@@ -1,90 +0,0 @@
#! /bin/sh
# Copyright 2010 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Prog_Name=${0##*/}
if [ ! -f ./main.cpp ]; then
echo "${Prog_Name}: must be run from the source top directory" 1>&2
exit 1
fi
if [ ! -f configure ]; then
echo "${Prog_Name}: configure not found; nothing to clean?" 1>&2
exit 1
fi
[ -f Makefile ] || ./configure
make distclean
# Top-level directory.
rm -f Makefile.in
rm -f aclocal.m4
rm -rf autom4te.cache
rm -f config.h.in
rm -f configure
rm -f mkinstalldirs
rm -f kyua-*.tar.gz
# admin directory.
rm -f admin/ar-lib
rm -f admin/compile
rm -f admin/config.guess
rm -f admin/config.sub
rm -f admin/depcomp
rm -f admin/install-sh
rm -f admin/ltmain.sh
rm -f admin/mdate-sh
rm -f admin/missing
# bootstrap directory.
rm -f bootstrap/package.m4
rm -f bootstrap/testsuite
# doc directory.
rm -f doc/*.info
rm -f doc/stamp-vti
rm -f doc/version.texi
# m4 directory.
rm -f m4/libtool.m4
rm -f m4/lt*.m4
# Files and directories spread all around the tree.
find . -name '#*' | xargs rm -rf
find . -name '*~' | xargs rm -rf
find . -name .deps | xargs rm -rf
find . -name .gdb_history | xargs rm -rf
find . -name .libs | xargs rm -rf
find . -name .tmp | xargs rm -rf
# Show remaining files.
if [ -n "${GIT}" ]; then
echo ">>> untracked and ignored files"
"${GIT}" status --porcelain --ignored | grep -E '^(\?\?|!!)' || true
fi
-98
View File
@@ -1,98 +0,0 @@
#! /bin/sh
# Copyright 2014 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -e -x
run_autoreconf() {
if [ -d /usr/local/share/aclocal ]; then
autoreconf -isv -I/usr/local/share/aclocal
else
autoreconf -isv
fi
}
do_apidocs() {
run_autoreconf || return 1
./configure --with-doxygen || return 1
make check-api-docs
}
do_distcheck() {
run_autoreconf || return 1
./configure || return 1
sudo sysctl -w "kernel.core_pattern=core.%p"
local archflags=
[ "${ARCH?}" != i386 ] || archflags=-m32
cat >kyua.conf <<EOF
syntax(2)
-- We do not know how many CPUs the test machine has. However, parallelizing
-- the execution of our tests to _any_ degree speeds up the time it takes to
-- complete a test run because many of our tests are blocking.
parallelism = 4
EOF
[ "${UNPRIVILEGED_USER:-no}" = no ] || \
echo "unprivileged_user = 'nobody'" >>kyua.conf
local f=
f="${f} CFLAGS='${archflags}'"
f="${f} CPPFLAGS='-I/usr/local/include'"
f="${f} CXXFLAGS='${archflags}'"
f="${f} LDFLAGS='-L/usr/local/lib -Wl,-R/usr/local/lib'"
f="${f} PKG_CONFIG_PATH='/usr/local/lib/pkgconfig'"
f="${f} KYUA_CONFIG_FILE_FOR_CHECK=$(pwd)/kyua.conf"
if [ "${AS_ROOT:-no}" = yes ]; then
sudo -H PATH="${PATH}" make distcheck DISTCHECK_CONFIGURE_FLAGS="${f}"
else
make distcheck DISTCHECK_CONFIGURE_FLAGS="${f}"
fi
}
do_style() {
run_autoreconf || return 1
mkdir build
cd build
../configure || return 1
make check-style
}
main() {
if [ -z "${DO}" ]; then
echo "DO must be defined" 1>&2
exit 1
fi
for step in ${DO}; do
"do_${DO}" || exit 1
done
}
main "${@}"
-83
View File
@@ -1,83 +0,0 @@
#! /bin/sh
# Copyright 2014 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -e -x
install_deps() {
local pkgsuffix=
local packages=
if [ "${ARCH?}" = i386 ]; then
pkgsuffix=:i386
packages="${packages} gcc-multilib"
packages="${packages} g++-multilib"
sudo dpkg --add-architecture i386
fi
packages="${packages} gdb"
packages="${packages} liblua5.2-0${pkgsuffix}"
packages="${packages} liblua5.2-dev${pkgsuffix}"
packages="${packages} libsqlite3-0${pkgsuffix}"
packages="${packages} libsqlite3-dev${pkgsuffix}"
packages="${packages} pkg-config${pkgsuffix}"
packages="${packages} sqlite3"
sudo apt-get update -qq
sudo apt-get install -y ${packages}
}
install_kyua() {
local name="20190321-usr-local-kyua-ubuntu-16-04-${ARCH?}-${CC?}.tar.gz"
wget -O "${name}" "http://dl.bintray.com/ngie-eign/kyua/${name}" || return 1
sudo tar -xzvp -C / -f "${name}"
rm -f "${name}"
}
do_apidocs() {
sudo apt-get install -y doxygen
}
do_distcheck() {
:
}
do_style() {
:
}
main() {
if [ -z "${DO}" ]; then
echo "DO must be defined" 1>&2
exit 1
fi
install_deps
install_kyua
for step in ${DO}; do
"do_${DO}" || exit 1
done
}
main "${@}"
-4
View File
@@ -1,4 +0,0 @@
atconfig
package.m4
testsuite
testsuite.log
-5
View File
@@ -1,5 +0,0 @@
syntax(2)
test_suite("kyua")
plain_test_program{name="testsuite"}
-90
View File
@@ -1,90 +0,0 @@
# Copyright 2010 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if WITH_ATF
tests_bootstrapdir = $(pkgtestsdir)/bootstrap
tests_bootstrap_DATA = bootstrap/Kyuafile
EXTRA_DIST += $(tests_bootstrap_DATA)
DISTCLEANFILES = bootstrap/atconfig \
bootstrap/testsuite.lineno \
bootstrap/testsuite.log
distclean-local: distclean-testsuite
distclean-testsuite:
-rm -rf bootstrap/testsuite.dir
EXTRA_DIST += bootstrap/Kyuafile \
bootstrap/testsuite \
bootstrap/package.m4 \
bootstrap/testsuite.at
tests_bootstrap_PROGRAMS = bootstrap/atf_helpers
bootstrap_atf_helpers_SOURCES = bootstrap/atf_helpers.cpp
bootstrap_atf_helpers_CXXFLAGS = $(ATF_CXX_CFLAGS)
bootstrap_atf_helpers_LDADD = $(ATF_CXX_LIBS)
tests_bootstrap_PROGRAMS += bootstrap/plain_helpers
bootstrap_plain_helpers_SOURCES = bootstrap/plain_helpers.cpp
bootstrap_plain_helpers_CXXFLAGS = $(UTILS_CFLAGS)
tests_bootstrap_SCRIPTS = bootstrap/testsuite
@target_srcdir@bootstrap/package.m4: $(top_srcdir)/configure.ac
$(AM_V_GEN){ \
echo '# Signature of the current package.'; \
echo 'm4_define(AT_PACKAGE_NAME, @PACKAGE_NAME@)'; \
echo 'm4_define(AT_PACKAGE_TARNAME, @PACKAGE_TARNAME@)'; \
echo 'm4_define(AT_PACKAGE_VERSION, @PACKAGE_VERSION@)'; \
echo 'm4_define(AT_PACKAGE_STRING, @PACKAGE_STRING@)'; \
echo 'm4_define(AT_PACKAGE_BUGREPORT, @PACKAGE_BUGREPORT@)'; \
} >$(srcdir)/bootstrap/package.m4
@target_srcdir@bootstrap/testsuite: $(srcdir)/bootstrap/testsuite.at \
@target_srcdir@bootstrap/package.m4
$(AM_V_GEN)autom4te --language=Autotest -I $(srcdir) \
-I $(srcdir)/bootstrap \
$(srcdir)/bootstrap/testsuite.at -o $@.tmp; \
mv $@.tmp $@
CHECK_LOCAL += check-bootstrap
PHONY_TARGETS += check-bootstrap
check-bootstrap: @target_srcdir@bootstrap/testsuite $(check_PROGRAMS) \
$(CHECK_BOOTSTRAP_DEPS)
cd bootstrap && $(CHECK_ENVIRONMENT) $(TESTS_ENVIRONMENT) \
./testsuite
if !TARGET_SRCDIR_EMPTY
CHECK_BOOTSTRAP_DEPS += copy-bootstrap-testsuite
CHECK_KYUA_DEPS += copy-bootstrap-testsuite
PHONY_TARGETS += copy-bootstrap-testsuite
copy-bootstrap-testsuite:
cp -f @target_srcdir@bootstrap/testsuite bootstrap/testsuite
CLEANFILES += bootstrap/testsuite
endif
endif
-141
View File
@@ -1,141 +0,0 @@
// Copyright 2010 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdlib>
#include <cstring>
#include <iostream>
#include "utils/defs.hpp"
#include "utils/test_utils.ipp"
namespace {
/// Prints a fake but valid test case list and then aborts.
///
/// \param argv The original arguments of the program.
///
/// \return Nothing because this dies before returning.
static int
helper_abort_test_cases_list(int /* argc */, char** argv)
{
for (const char* const* arg = argv; *arg != NULL; arg++) {
if (std::strcmp(*arg, "-l") == 0) {
std::cout << "Content-Type: application/X-atf-tp; "
"version=\"1\"\n\n";
std::cout << "ident: foo\n";
}
}
utils::abort_without_coredump();
}
/// Just returns without printing anything as the test case list.
///
/// \return Always 0, as required for test programs.
static int
helper_empty_test_cases_list(int /* argc */, char** /* argv */)
{
return EXIT_SUCCESS;
}
/// Prints a correctly-formatted test case list but empty.
///
/// \param argv The original arguments of the program.
///
/// \return Always 0, as required for test programs.
static int
helper_zero_test_cases(int /* argc */, char** argv)
{
for (const char* const* arg = argv; *arg != NULL; arg++) {
if (std::strcmp(*arg, "-l") == 0)
std::cout << "Content-Type: application/X-atf-tp; "
"version=\"1\"\n\n";
}
return EXIT_SUCCESS;
}
/// Mapping of the name of a helper to its implementation.
struct helper {
/// The name of the helper, as will be provided by the user on the CLI.
const char* name;
/// A pointer to the function implementing the helper.
int (*hook)(int, char**);
};
/// NULL-terminated table mapping helper names to their implementations.
static const helper helpers[] = {
{ "abort_test_cases_list", helper_abort_test_cases_list, },
{ "empty_test_cases_list", helper_empty_test_cases_list, },
{ "zero_test_cases", helper_zero_test_cases, },
{ NULL, NULL, },
};
} // anonymous namespace
/// Entry point to the ATF-less helpers.
///
/// The caller must select a helper to execute by defining the HELPER
/// environment variable to the name of the desired helper. Think of this main
/// method as a subprogram dispatcher, to avoid having many individual helper
/// binaries.
///
/// \todo Maybe we should really have individual helper binaries. It would
/// avoid a significant amount of complexity here and in the tests, at the
/// expense of some extra files and extra build logic.
///
/// \param argc The user argument count; delegated to the helper.
/// \param argv The user arguments; delegated to the helper.
///
/// \return The exit code of the helper, which depends on the requested helper.
int
main(int argc, char** argv)
{
const char* command = std::getenv("HELPER");
if (command == NULL) {
std::cerr << "Usage error: HELPER must be set to a helper name\n";
std::exit(EXIT_FAILURE);
}
const struct helper* iter = helpers;
for (; iter->name != NULL && std::strcmp(iter->name, command) != 0; iter++)
;
if (iter->name == NULL) {
std::cerr << "Usage error: unknown command " << command << "\n";
std::exit(EXIT_FAILURE);
}
return iter->hook(argc, argv);
}
-200
View File
@@ -1,200 +0,0 @@
dnl Copyright 2010 The Kyua Authors.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
AT_INIT([bootstrapping tests])
m4_define([GUESS_TOPDIR], {
old=$(pwd)
cd "$(dirname ${as_myself})"
# We need to locate a build product, not a source file, because the
# test suite may be run outside of the source tree (think distcheck).
while test $(pwd) != '/' -a ! -e bootstrap/plain_helpers; do
cd ..
done
topdir=$(pwd)
cd ${old}
echo ${topdir}
})
m4_define([CREATE_ATF_HELPERS], [
AT_DATA([Kyuafile], [
syntax(2)
test_suite("bootstrap")
atf_test_program{name="atf_helpers"}
])
ln -s $(GUESS_TOPDIR)/bootstrap/atf_helpers atf_helpers
])
m4_define([RUN_ATF_HELPERS],
[HOME=$(pwd) TESTS="$1" kyua --config=none \
test --results-file=bootstrap.db $2])
m4_define([CREATE_PLAIN_HELPERS], [
AT_DATA([Kyuafile], [
syntax(2)
test_suite("bootstrap")
atf_test_program{name="plain_helpers"}
])
ln -s $(GUESS_TOPDIR)/bootstrap/plain_helpers plain_helpers
])
m4_define([RUN_PLAIN_HELPER],
[HOME=$(pwd) HELPER="$1" kyua --config=none \
test --results-file=bootstrap.db])
AT_SETUP([test program crashes in test list])
AT_TESTED([kyua])
CREATE_PLAIN_HELPERS
AT_CHECK([RUN_PLAIN_HELPER([abort_test_cases_list])], [1], [stdout], [])
re='plain_helpers:__test_cases_list__.*broken.*Test program received signal'
AT_CHECK([grep "${re}" stdout], [0], [ignore], [])
AT_CLEANUP
AT_SETUP([test program prints an empty test list])
AT_TESTED([kyua])
CREATE_PLAIN_HELPERS
AT_CHECK([RUN_PLAIN_HELPER([empty_test_cases_list])], [1], [stdout], [])
re="plain_helpers:__test_cases_list__.*broken.*Invalid header.*got ''"
AT_CHECK([grep "${re}" stdout], [0], [ignore], [])
AT_CLEANUP
AT_SETUP([test program with zero test cases])
AT_TESTED([kyua])
CREATE_PLAIN_HELPERS
AT_CHECK([RUN_PLAIN_HELPER([zero_test_cases])], [1], [stdout], [])
re='plain_helpers:__test_cases_list__.*broken.*No test cases'
AT_CHECK([grep "${re}" stdout], [0], [ignore], [])
AT_CLEANUP
AT_SETUP([run test case that passes])
AT_TESTED([kyua])
CREATE_ATF_HELPERS
AT_CHECK([RUN_ATF_HELPERS([passes])], [0], [stdout], [])
AT_CHECK([grep "atf_helpers:fails" stdout], [1], [], [])
AT_CHECK([grep "atf_helpers:passes.*passed" stdout], [0], [ignore], [])
AT_CHECK([grep "atf_helpers:skips" stdout], [1], [], [])
AT_CLEANUP
AT_SETUP([run test case that fails])
AT_TESTED([kyua])
CREATE_ATF_HELPERS
AT_CHECK([RUN_ATF_HELPERS([fails])], [1], [stdout], [])
AT_CHECK([grep "atf_helpers:fails.*failed.*Failed on purpose" stdout],
[0], [ignore], [])
AT_CHECK([grep "atf_helpers:passes" stdout], [1], [], [])
AT_CHECK([grep "atf_helpers:skips" stdout], [1], [], [])
AT_CLEANUP
AT_SETUP([run test case that skips])
AT_TESTED([kyua])
CREATE_ATF_HELPERS
AT_CHECK([RUN_ATF_HELPERS([skips])], [0], [stdout], [])
AT_CHECK([grep "atf_helpers:fails" stdout], [1], [], [])
AT_CHECK([grep "atf_helpers:passes" stdout], [1], [], [])
AT_CHECK([grep "atf_helpers:skips.*skipped.*Skipped on purpose" stdout],
[0], [ignore], [])
AT_CLEANUP
AT_SETUP([run two test cases, success])
AT_TESTED([kyua])
CREATE_ATF_HELPERS
AT_CHECK([RUN_ATF_HELPERS([passes skips])], [0], [stdout], [])
AT_CHECK([grep "atf_helpers:fails" stdout], [1], [], [])
AT_CHECK([grep "atf_helpers:passes.*passed" stdout], [0], [ignore], [])
AT_CHECK([grep "atf_helpers:skips.*skipped.*Skipped on purpose" stdout],
[0], [ignore], [])
AT_CLEANUP
AT_SETUP([run two test cases, failure])
AT_TESTED([kyua])
CREATE_ATF_HELPERS
AT_CHECK([RUN_ATF_HELPERS([fails passes])], [1], [stdout], [])
AT_CHECK([grep "atf_helpers:fails.*failure.*Failed on purpose" stdout],
[1], [], [])
AT_CHECK([grep "atf_helpers:passes.*passed" stdout], [0], [ignore], [])
AT_CHECK([grep "atf_helpers:skips" stdout], [1], [], [])
AT_CLEANUP
AT_SETUP([run mixed test cases])
AT_TESTED([kyua])
CREATE_ATF_HELPERS
AT_CHECK([RUN_ATF_HELPERS([fails passes skips])], [1], [stdout], [])
AT_CHECK([grep "atf_helpers:fails.*failure.*Failed on purpose" stdout],
[1], [], [])
AT_CHECK([grep "atf_helpers:passes.*passed" stdout], [0], [ignore], [])
AT_CHECK([grep "atf_helpers:skips.*skipped.*Skipped on purpose" stdout],
[0], [ignore], [])
AT_CLEANUP
AT_SETUP([run tests from build directories])
AT_TESTED([kyua])
CREATE_ATF_HELPERS
AT_CHECK([mkdir src], [0], [], [])
AT_CHECK([mv Kyuafile src], [0], [], [])
AT_CHECK([mkdir obj], [0], [], [])
AT_CHECK([mv atf_helpers obj], [0], [], [])
AT_CHECK([RUN_ATF_HELPERS([fails passes skips],
[--kyuafile=src/Kyuafile --build-root=obj])],
[1], [stdout], [])
AT_CHECK([grep "atf_helpers:fails.*failure.*Failed on purpose" stdout],
[1], [], [])
AT_CHECK([grep "atf_helpers:passes.*passed" stdout], [0], [ignore], [])
AT_CHECK([grep "atf_helpers:skips.*skipped.*Skipped on purpose" stdout],
[0], [ignore], [])
AT_CLEANUP
-123
View File
@@ -1,123 +0,0 @@
# Copyright 2010 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
CLI_CFLAGS = $(DRIVERS_CFLAGS)
CLI_LIBS = libcli.a $(DRIVERS_LIBS)
noinst_LIBRARIES += libcli.a
libcli_a_SOURCES = cli/cmd_about.cpp
libcli_a_SOURCES += cli/cmd_about.hpp
libcli_a_SOURCES += cli/cmd_config.cpp
libcli_a_SOURCES += cli/cmd_config.hpp
libcli_a_SOURCES += cli/cmd_db_exec.cpp
libcli_a_SOURCES += cli/cmd_db_exec.hpp
libcli_a_SOURCES += cli/cmd_db_migrate.cpp
libcli_a_SOURCES += cli/cmd_db_migrate.hpp
libcli_a_SOURCES += cli/cmd_debug.cpp
libcli_a_SOURCES += cli/cmd_debug.hpp
libcli_a_SOURCES += cli/cmd_help.cpp
libcli_a_SOURCES += cli/cmd_help.hpp
libcli_a_SOURCES += cli/cmd_list.cpp
libcli_a_SOURCES += cli/cmd_list.hpp
libcli_a_SOURCES += cli/cmd_report.cpp
libcli_a_SOURCES += cli/cmd_report.hpp
libcli_a_SOURCES += cli/cmd_report_html.cpp
libcli_a_SOURCES += cli/cmd_report_html.hpp
libcli_a_SOURCES += cli/cmd_report_junit.cpp
libcli_a_SOURCES += cli/cmd_report_junit.hpp
libcli_a_SOURCES += cli/cmd_test.cpp
libcli_a_SOURCES += cli/cmd_test.hpp
libcli_a_SOURCES += cli/common.cpp
libcli_a_SOURCES += cli/common.hpp
libcli_a_SOURCES += cli/common.ipp
libcli_a_SOURCES += cli/config.cpp
libcli_a_SOURCES += cli/config.hpp
libcli_a_SOURCES += cli/main.cpp
libcli_a_SOURCES += cli/main.hpp
libcli_a_CPPFLAGS = -DKYUA_CONFDIR="\"$(kyua_confdir)\""
libcli_a_CPPFLAGS += -DKYUA_DOCDIR="\"$(docdir)\""
libcli_a_CPPFLAGS += -DKYUA_MISCDIR="\"$(miscdir)\""
libcli_a_CPPFLAGS += $(DRIVERS_CFLAGS)
libcli_a_LIBADD = libutils.a
if WITH_ATF
tests_clidir = $(pkgtestsdir)/cli
tests_cli_DATA = cli/Kyuafile
EXTRA_DIST += $(tests_cli_DATA)
tests_cli_PROGRAMS = cli/cmd_about_test
cli_cmd_about_test_SOURCES = cli/cmd_about_test.cpp
cli_cmd_about_test_CXXFLAGS = $(CLI_CFLAGS) $(ATF_CXX_CFLAGS)
cli_cmd_about_test_LDADD = $(CLI_LIBS) $(ATF_CXX_LIBS)
tests_cli_PROGRAMS += cli/cmd_config_test
cli_cmd_config_test_SOURCES = cli/cmd_config_test.cpp
cli_cmd_config_test_CXXFLAGS = $(CLI_CFLAGS) $(ATF_CXX_CFLAGS)
cli_cmd_config_test_LDADD = $(CLI_LIBS) $(ATF_CXX_LIBS)
tests_cli_PROGRAMS += cli/cmd_db_exec_test
cli_cmd_db_exec_test_SOURCES = cli/cmd_db_exec_test.cpp
cli_cmd_db_exec_test_CXXFLAGS = $(CLI_CFLAGS) $(ATF_CXX_CFLAGS)
cli_cmd_db_exec_test_LDADD = $(CLI_LIBS) $(ATF_CXX_LIBS)
tests_cli_PROGRAMS += cli/cmd_debug_test
cli_cmd_debug_test_SOURCES = cli/cmd_debug_test.cpp
cli_cmd_debug_test_CXXFLAGS = $(CLI_CFLAGS) $(ATF_CXX_CFLAGS)
cli_cmd_debug_test_LDADD = $(CLI_LIBS) $(ATF_CXX_LIBS)
tests_cli_PROGRAMS += cli/cmd_help_test
cli_cmd_help_test_SOURCES = cli/cmd_help_test.cpp
cli_cmd_help_test_CXXFLAGS = $(CLI_CFLAGS) $(ATF_CXX_CFLAGS)
cli_cmd_help_test_LDADD = $(CLI_LIBS) $(ATF_CXX_LIBS)
tests_cli_PROGRAMS += cli/cmd_list_test
cli_cmd_list_test_SOURCES = cli/cmd_list_test.cpp
cli_cmd_list_test_CXXFLAGS = $(CLI_CFLAGS) $(ATF_CXX_CFLAGS)
cli_cmd_list_test_LDADD = $(CLI_LIBS) $(ATF_CXX_LIBS)
tests_cli_PROGRAMS += cli/cmd_test_test
cli_cmd_test_test_SOURCES = cli/cmd_test_test.cpp
cli_cmd_test_test_CXXFLAGS = $(CLI_CFLAGS) $(ATF_CXX_CFLAGS)
cli_cmd_test_test_LDADD = $(CLI_LIBS) $(ATF_CXX_LIBS)
tests_cli_PROGRAMS += cli/common_test
cli_common_test_SOURCES = cli/common_test.cpp
cli_common_test_CXXFLAGS = $(CLI_CFLAGS) $(ATF_CXX_CFLAGS)
cli_common_test_LDADD = $(CLI_LIBS) $(ATF_CXX_LIBS)
tests_cli_PROGRAMS += cli/config_test
cli_config_test_SOURCES = cli/config_test.cpp
cli_config_test_CXXFLAGS = $(CLI_CFLAGS) $(ATF_CXX_CFLAGS)
cli_config_test_LDADD = $(CLI_LIBS) $(ATF_CXX_LIBS)
tests_cli_PROGRAMS += cli/main_test
cli_main_test_SOURCES = cli/main_test.cpp
cli_main_test_CXXFLAGS = $(CLI_CFLAGS) $(ATF_CXX_CFLAGS)
cli_main_test_LDADD = $(CLI_LIBS) $(ATF_CXX_LIBS)
endif
+4 -3
View File
@@ -33,6 +33,7 @@ extern "C" {
}
#include <cstdlib>
#include <cstring>
#include <iostream>
#include "cli/common.ipp"
@@ -105,7 +106,7 @@ public:
{
if (::chdir(_eh.work_directory().c_str()) == -1) {
std::cerr << "execute: chdir() errors: "
<< strerror(errno) << ".\n";
<< std::strerror(errno) << ".\n";
std::exit(EXIT_FAILURE);
}
@@ -154,14 +155,14 @@ public:
_ui->out("The test failed and paused right before its cleanup "
"routine.");
_ui->out(F("Test work dir: %s") % eh.work_directory().str());
_ui->out("Press <Enter> to continue...");
_ui->out("Press any key to continue...");
(void) std::cin.get();
}
} else if (_cmdline.has_option(pause_before_cleanup_option
.long_name())) {
_ui->out("The test paused right before its cleanup routine.");
_ui->out(F("Test work dir: %s") % eh.work_directory().str());
_ui->out("Press <Enter> to continue...");
_ui->out("Press any key to continue...");
(void) std::cin.get();
}
};
+4
View File
@@ -57,6 +57,7 @@ extern "C" {
#include "cli/common.ipp"
#include "cli/config.hpp"
#include "engine/atf.hpp"
#include "engine/googletest.hpp"
#include "engine/plain.hpp"
#include "engine/scheduler.hpp"
#include "engine/tap.hpp"
@@ -103,6 +104,9 @@ register_scheduler_interfaces(void)
scheduler::register_interface(
"atf", std::shared_ptr< scheduler::interface >(
new engine::atf_interface()));
scheduler::register_interface(
"googletest", std::shared_ptr< scheduler::interface >(
new engine::googletest_interface()));
scheduler::register_interface(
"plain", std::shared_ptr< scheduler::interface >(
new engine::plain_interface()));
+139
View File
@@ -0,0 +1,139 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to the optind value to reset getopt processing */
#define GETOPT_OPTIND_RESET_VALUE 1
/* define if the compiler supports basic C++20 syntax */
#define HAVE_CXX20 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if getcwd(NULL, 0) works */
#define HAVE_GETCWD_DYN 1
/* Define to 1 if getopt allows a + sign for POSIX behavior */
/* #undef HAVE_GETOPT_GNU */
/* Define to 1 if getopt has optreset */
#define HAVE_GETOPT_WITH_OPTRESET 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the 'putenv' function. */
#define HAVE_PUTENV 1
/* Define to 1 if you have the 'setenv' function. */
#define HAVE_SETENV 1
/* Define to 1 if you have the 'statfs' function. */
#define HAVE_STATFS 1
/* Define to 1 if you have the 'statvfs' function. */
#define HAVE_STATVFS 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the 'sysctlbyname' function. */
#define HAVE_SYSCTLBYNAME 1
/* Define to 1 if you have the <sys/mount.h> header file. */
#define HAVE_SYS_MOUNT_H 1
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/statvfs.h> header file. */
#define HAVE_SYS_STATVFS_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/sysctl.h> header file. */
#define HAVE_SYS_SYSCTL_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/vfs.h> header file. */
/* #undef HAVE_SYS_VFS_H */
/* Define to 1 if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 1
/* Define to 1 if you have the 'umount' function. */
/* #undef HAVE_UMOUNT */
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the 'unmount' function. */
#define HAVE_UNMOUNT 1
/* Define to 1 if you have the 'unsetenv' function. */
#define HAVE_UNSETENV 1
/* Define to 1 if your lchmod works */
#define HAVE_WORKING_LCHMOD 1
/* Name of the system architecture (aka processor type) */
/* #undef KYUA_ARCHITECTURE */
/* Name of the system platform (aka machine name) */
/* #undef KYUA_PLATFORM */
/* Define to the last valid signal number */
#define LAST_SIGNO 128
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Define to the name of the sysctl MIB */
#define MEMORY_QUERY_SYSCTL_MIB "hw.usermem"
/* Define to the memory query type */
#define MEMORY_QUERY_TYPE "sysctlbyname"
/* Name of package */
#define PACKAGE "kyua"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "[email protected]"
/* Define to the full name of this package. */
#define PACKAGE_NAME "Kyua"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "Kyua 0.15.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "kyua"
/* Define to the home page for this package. */
#define PACKAGE_URL "https://github.com/freebsd/kyua/"
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.15.0"
/* Define to 1 if all of the C89 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.15.0"
-173
View File
@@ -1,173 +0,0 @@
dnl Copyright 2010 The Kyua Authors.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
AC_INIT([Kyua], [0.14], [[email protected]], [kyua],
[https://github.com/jmmv/kyua/])
AC_PREREQ([2.65])
AC_COPYRIGHT([Copyright 2010 The Kyua Authors.])
AC_CONFIG_AUX_DIR([admin])
AC_CONFIG_FILES([Doxyfile Makefile utils/defs.hpp])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([main.cpp])
AC_CONFIG_TESTDIR([bootstrap])
AM_INIT_AUTOMAKE([1.9 foreign subdir-objects -Wall])
AC_LANG([C++])
AC_PROG_CXX
AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory])
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
KYUA_DEVELOPER_MODE([C++])
KYUA_ATTRIBUTE_NORETURN
KYUA_ATTRIBUTE_PURE
KYUA_ATTRIBUTE_UNUSED
KYUA_FS_MODULE
KYUA_GETOPT
KYUA_LAST_SIGNO
KYUA_MEMORY
AC_CHECK_FUNCS([putenv setenv unsetenv])
AC_CHECK_HEADERS([termios.h])
AC_PROG_RANLIB
m4_ifndef([PKG_CHECK_MODULES],
[m4_fatal([Cannot find pkg.m4; see the INSTALL document for help])])
m4_ifndef([ATF_CHECK_CXX],
[m4_fatal([Cannot find atf-c++.m4; see the INSTALL document for help])])
ATF_CHECK_CXX([>= 0.17])
m4_ifndef([ATF_CHECK_SH],
[m4_fatal([Cannot find atf-sh.m4; see the INSTALL document for help])])
ATF_CHECK_SH([>= 0.15])
m4_ifndef([ATF_ARG_WITH],
[m4_fatal([Cannot find atf-common.m4; see the INSTALL document for help])])
ATF_ARG_WITH
PKG_CHECK_MODULES([LUTOK], [lutok >= 0.4],
[],
AC_MSG_ERROR([lutok (0.4 or newer) is required]))
PKG_CHECK_MODULES([SQLITE3], [sqlite3 >= 3.6.22],
[],
AC_MSG_ERROR([sqlite3 (3.6.22 or newer) is required]))
KYUA_DOXYGEN
AC_PATH_PROG([GDB], [gdb])
test -n "${GDB}" || GDB=gdb
AC_PATH_PROG([GIT], [git])
KYUA_UNAME_ARCHITECTURE
KYUA_UNAME_PLATFORM
AC_ARG_VAR([KYUA_CONFSUBDIR],
[Subdirectory of sysconfdir under which to look for files])
if test x"${KYUA_CONFSUBDIR-unset}" = x"unset"; then
KYUA_CONFSUBDIR=kyua
else
case ${KYUA_CONFSUBDIR} in
/*)
AC_MSG_ERROR([KYUA_CONFSUBDIR must hold a relative path])
;;
*)
;;
esac
fi
if test x"${KYUA_CONFSUBDIR}" = x""; then
AC_SUBST(kyua_confdir, \${sysconfdir})
else
AC_SUBST(kyua_confdir, \${sysconfdir}/${KYUA_CONFSUBDIR})
fi
dnl Allow the caller of 'make check', 'make installcheck' and 'make distcheck'
dnl on the Kyua source tree to override the configuration file passed to our
dnl own test runs. This is for the development of Kyua only and the value of
dnl this setting has no effect on the built product in any way. If we go
dnl through great extents in validating the value of this setting, it is to
dnl minimize the chance of false test run negatives later on.
AC_ARG_VAR([KYUA_CONFIG_FILE_FOR_CHECK],
[kyua.conf file to use at 'make (|dist|install)check' time])
case "${KYUA_CONFIG_FILE_FOR_CHECK-none}" in
none)
KYUA_CONFIG_FILE_FOR_CHECK=none
;;
/*)
if test -f "${KYUA_CONFIG_FILE_FOR_CHECK}"; then
: # All good!
else
AC_MSG_ERROR([KYUA_CONFIG_FILE_FOR_CHECK file does not exist])
fi
;;
*)
AC_MSG_ERROR([KYUA_CONFIG_FILE_FOR_CHECK must hold an absolute path])
;;
esac
AC_ARG_VAR([KYUA_TMPDIR],
[Path to the directory in which to place work directories])
case "${KYUA_TMPDIR:-unset}" in
unset)
KYUA_TMPDIR=/tmp
;;
/*)
;;
*)
AC_MSG_ERROR([KYUA_TMPDIR must be an absolute path])
;;
esac
AC_SUBST(examplesdir, \${pkgdatadir}/examples)
AC_SUBST(luadir, \${pkgdatadir}/lua)
AC_SUBST(miscdir, \${pkgdatadir}/misc)
AC_SUBST(pkgtestsdir, \${testsdir}/kyua)
AC_SUBST(storedir, \${pkgdatadir}/store)
AC_SUBST(testsdir, \${exec_prefix}/tests)
dnl BSD make(1) doesn't deal with targets specified as './foo' well: they
dnl need to be specified as 'foo'. The following hack is to workaround this
dnl issue.
if test "${srcdir}" = .; then
target_srcdir=
else
target_srcdir="${srcdir}/"
fi
AM_CONDITIONAL(TARGET_SRCDIR_EMPTY, [test -z "${target_srcdir}"])
AC_SUBST([target_srcdir])
AC_OUTPUT
-14
View File
@@ -1,14 +0,0 @@
kyua-about.1
kyua-config.1
kyua-db-exec.1
kyua-db-migrate.1
kyua-debug.1
kyua-help.1
kyua-list.1
kyua-report-html.1
kyua-report-junit.1
kyua-report.1
kyua-test.1
kyua.1
kyua.conf.5
kyuafile.5
-152
View File
@@ -1,152 +0,0 @@
# Copyright 2011 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
BUILD_MANPAGE = \
$(MKDIR_P) doc; \
$(SHELL) $(srcdir)/doc/manbuild.sh \
-v "CONFDIR=$(kyua_confdir)" \
-v "DOCDIR=$(docdir)" \
-v "EGDIR=$(examplesdir)" \
-v "MISCDIR=$(miscdir)" \
-v "PACKAGE=$(PACKAGE_TARNAME)" \
-v "STOREDIR=$(storedir)" \
-v "TESTSDIR=$(testsdir)" \
-v "VERSION=$(PACKAGE_VERSION)" \
"$(srcdir)/doc/$${name}.in" "doc/$${name}"
DIST_MAN_DEPS = doc/manbuild.sh \
doc/build-root.mdoc \
doc/results-file-flag-read.mdoc \
doc/results-file-flag-write.mdoc \
doc/results-files.mdoc \
doc/results-files-report-example.mdoc \
doc/test-filters.mdoc \
doc/test-isolation.mdoc
MAN_DEPS = $(DIST_MAN_DEPS) Makefile
EXTRA_DIST += $(DIST_MAN_DEPS)
man_MANS = doc/kyua-about.1
CLEANFILES += doc/kyua-about.1
EXTRA_DIST += doc/kyua-about.1.in
doc/kyua-about.1: $(srcdir)/doc/kyua-about.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua-about.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua-config.1
CLEANFILES += doc/kyua-config.1
EXTRA_DIST += doc/kyua-config.1.in
doc/kyua-config.1: $(srcdir)/doc/kyua-config.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua-config.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua-db-exec.1
CLEANFILES += doc/kyua-db-exec.1
EXTRA_DIST += doc/kyua-db-exec.1.in
doc/kyua-db-exec.1: $(srcdir)/doc/kyua-db-exec.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua-db-exec.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua-db-migrate.1
CLEANFILES += doc/kyua-db-migrate.1
EXTRA_DIST += doc/kyua-db-migrate.1.in
doc/kyua-db-migrate.1: $(srcdir)/doc/kyua-db-migrate.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua-db-migrate.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua-debug.1
CLEANFILES += doc/kyua-debug.1
EXTRA_DIST += doc/kyua-debug.1.in
doc/kyua-debug.1: $(srcdir)/doc/kyua-debug.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua-debug.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua-help.1
CLEANFILES += doc/kyua-help.1
EXTRA_DIST += doc/kyua-help.1.in
doc/kyua-help.1: $(srcdir)/doc/kyua-help.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua-help.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua-list.1
CLEANFILES += doc/kyua-list.1
EXTRA_DIST += doc/kyua-list.1.in
doc/kyua-list.1: $(srcdir)/doc/kyua-list.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua-list.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua-report-html.1
CLEANFILES += doc/kyua-report-html.1
EXTRA_DIST += doc/kyua-report-html.1.in
doc/kyua-report-html.1: $(srcdir)/doc/kyua-report-html.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua-report-html.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua-report-junit.1
CLEANFILES += doc/kyua-report-junit.1
EXTRA_DIST += doc/kyua-report-junit.1.in
doc/kyua-report-junit.1: $(srcdir)/doc/kyua-report-junit.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua-report-junit.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua-report.1
CLEANFILES += doc/kyua-report.1
EXTRA_DIST += doc/kyua-report.1.in
doc/kyua-report.1: $(srcdir)/doc/kyua-report.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua-report.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua-test.1
CLEANFILES += doc/kyua-test.1
EXTRA_DIST += doc/kyua-test.1.in
doc/kyua-test.1: $(srcdir)/doc/kyua-test.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua-test.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua.1
CLEANFILES += doc/kyua.1
EXTRA_DIST += doc/kyua.1.in
doc/kyua.1: $(srcdir)/doc/kyua.1.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua.1; $(BUILD_MANPAGE)
man_MANS += doc/kyua.conf.5
CLEANFILES += doc/kyua.conf.5
EXTRA_DIST += doc/kyua.conf.5.in
doc/kyua.conf.5: $(srcdir)/doc/kyua.conf.5.in $(MAN_DEPS)
$(AM_V_GEN)name=kyua.conf.5; $(BUILD_MANPAGE)
man_MANS += doc/kyuafile.5
CLEANFILES += doc/kyuafile.5
EXTRA_DIST += doc/kyuafile.5.in
doc/kyuafile.5: $(srcdir)/doc/kyuafile.5.in $(MAN_DEPS)
$(AM_V_GEN)name=kyuafile.5; $(BUILD_MANPAGE)
if WITH_ATF
EXTRA_DIST += doc/Kyuafile
noinst_SCRIPTS += doc/manbuild_test
CLEANFILES += doc/manbuild_test
EXTRA_DIST += doc/manbuild_test.sh
doc/manbuild_test: $(srcdir)/doc/manbuild_test.sh Makefile
$(AM_V_GEN)$(MKDIR_P) doc; \
echo "#! $(ATF_SH)" >doc/manbuild_test.tmp; \
echo "# AUTOMATICALLY GENERATED FROM Makefile" \
>>doc/manbuild_test.tmp; \
sed -e 's,__MANBUILD__,$(abs_srcdir)/doc/manbuild.sh,g' \
<$(srcdir)/doc/manbuild_test.sh >>doc/manbuild_test.tmp; \
mv doc/manbuild_test.tmp doc/manbuild_test; \
chmod +x doc/manbuild_test
endif
+1 -1
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm "kyua about"
.Nd Shows detailed authors, license, and version information
.Nd show detailed authors, license, and version information
.Sh SYNOPSIS
.Nm
.Op Ar authors | license | version
+1 -1
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm "kyua config"
.Nd Inspects the values of the loaded configuration
.Nd inspect the values of the loaded configuration
.Sh SYNOPSIS
.Nm
.Op Ar variable1 .. variableN
+1 -1
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm "kyua db-exec"
.Nd Executes a SQL statement in a results file
.Nd execute a SQL statement in a results file
.Sh SYNOPSIS
.Nm
.Op Fl -no-headers
+1 -1
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm "kyua db-migrate"
.Nd Upgrades the schema of an existing results file
.Nd upgrade the schema of an existing results file
.Sh SYNOPSIS
.Nm
.Op Fl -results-file Ar file
+2 -2
View File
@@ -25,12 +25,12 @@
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.Dd July 22, 2026
.Dd April 18, 2026
.Dt KYUA-DEBUG 1
.Os
.Sh NAME
.Nm "kyua debug"
.Nd Executes a single test case with facilities for debugging
.Nd execute a single test case with facilities for debugging
.Sh SYNOPSIS
.Nm
.Op Fl -build-root Ar path
+1 -1
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm "kyua help"
.Nd Shows usage information
.Nd show usage information
.Sh SYNOPSIS
.Nm
.Op Ar command
+1 -1
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm "kyua list"
.Nd Lists test cases and their metadata
.Nd list test cases and their metadata
.Sh SYNOPSIS
.Nm
.Op Fl -build-root Ar path
+1 -1
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm "kyua report-html"
.Nd Generates an HTML report with the results of a test suite run
.Nd generate an HTML report with the results of a test suite run
.Sh SYNOPSIS
.Nm
.Op Fl -force
+1 -1
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm "kyua report-junit"
.Nd Generates a JUnit report with the results of a test suite run
.Nd generate a JUnit report with the results of a test suite run
.Sh SYNOPSIS
.Nm
.Op Fl -output Ar path
+1 -1
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm "kyua report"
.Nd Generates reports with the results of a test suite run
.Nd generate reports with the results of a test suite run
.Sh SYNOPSIS
.Nm
.Op Fl -output Ar path
+1 -1
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm "kyua test"
.Nd Runs tests
.Nd run tests
.Sh SYNOPSIS
.Nm
.Op Fl -build-root Ar path
+3 -3
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm kyua
.Nd Testing framework for infrastructure software
.Nd testing framework for infrastructure software
.Sh SYNOPSIS
.Nm
.Op Fl -config Ar file
@@ -280,13 +280,13 @@ The first step in reporting a bug is to check if there already is a similar
bug in the database.
You can check what issues are currently in the database by going to:
.Bd -literal -offset indent
https://github.com/jmmv/kyua/issues/
https://github.com/freebsd/kyua/issues/
.Ed
.Pp
If there is no existing issue that describes an issue similar to the
one you are experiencing, you can open a new one by visiting:
.Bd -literal -offset indent
https://github.com/jmmv/kyua/issues/new/
https://github.com/freebsd/kyua/issues/new/
.Ed
.Pp
When doing so, please include as much detail as possible.
+1 -1
View File
@@ -30,7 +30,7 @@
.Os
.Sh NAME
.Nm kyua.conf
.Nd Configuration file for the kyua tool
.Nd configuration file for the kyua tool
.Sh SYNOPSIS
.Fn syntax "int version"
.Pp
+16 -3
View File
@@ -25,12 +25,12 @@
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.Dd March 23, 2024
.Dd November 29, 2024
.Dt KYUAFILE 5
.Os
.Sh NAME
.Nm Kyuafile
.Nd Test suite description files
.Nd test suite description files
.Sh SYNOPSIS
.Fn atf_test_program "string name" "[string metadata]"
.Fn current_kyuafile
@@ -40,6 +40,7 @@
.Fn fs.files "string path"
.Fn fs.is_absolute "string path"
.Fn fs.join "string path" "string path"
.Fn googletest_test_program "string name" "[string metadata]"
.Fn include "string path"
.Fn plain_test_program "string name" "[string metadata]"
.Fn syntax "int version"
@@ -124,6 +125,16 @@ Any metadata properties defined by the test cases themselves override the
metadata values defined here.
The mapping to ATF metadata naming for each property is provided below.
.Pp
.Em Google Test test programs
are those that use the Google Test test infrastructure.
They can be registered with the
.Fn googletest_test_program
table constructor.
This function takes the
.Fa name
of the test program, and a collection of optional metadata settings for the
test program.
.Pp
.Em Plain test programs
are those that return 0 on success and non-0 on failure; in general, most test
programs (even those that use fancy unit-testing libraries) behave this way and
@@ -300,7 +311,6 @@ Supported platforms:
.Pp
ATF:
.Va require.kmods
(appends to the list declared at the Kyuafile level instead of overwriting it)
.It Va required_memory
Amount of physical memory that the test needs to run successfully.
.Pp
@@ -459,6 +469,9 @@ syntax(2)
test_suite('second')
googletest_test_program{name='dont_run_as_root_test',
required_user='unprivileged'}
plain_test_program{name='legacy_test',
allowed_architectures='amd64 i386',
required_files='/bin/ls',
-72
View File
@@ -1,72 +0,0 @@
# Copyright 2011 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
DRIVERS_CFLAGS = $(ENGINE_CFLAGS) $(STORE_CFLAGS) $(MODEL_CFLAGS) \
$(UTILS_CFLAGS)
DRIVERS_LIBS = libdrivers.a $(ENGINE_LIBS) $(STORE_LIBS) $(MODEL_LIBS) \
$(UTILS_LIBS)
noinst_LIBRARIES += libdrivers.a
libdrivers_a_CPPFLAGS = $(DRIVERS_CFLAGS)
libdrivers_a_SOURCES = drivers/debug_test.cpp
libdrivers_a_SOURCES += drivers/debug_test.hpp
libdrivers_a_SOURCES += drivers/list_tests.cpp
libdrivers_a_SOURCES += drivers/list_tests.hpp
libdrivers_a_SOURCES += drivers/report_junit.cpp
libdrivers_a_SOURCES += drivers/report_junit.hpp
libdrivers_a_SOURCES += drivers/run_tests.cpp
libdrivers_a_SOURCES += drivers/run_tests.hpp
libdrivers_a_SOURCES += drivers/scan_results.cpp
libdrivers_a_SOURCES += drivers/scan_results.hpp
if WITH_ATF
tests_driversdir = $(pkgtestsdir)/drivers
tests_drivers_DATA = drivers/Kyuafile
EXTRA_DIST += $(tests_drivers_DATA)
tests_drivers_PROGRAMS = drivers/list_tests_helpers
drivers_list_tests_helpers_SOURCES = drivers/list_tests_helpers.cpp
drivers_list_tests_helpers_CXXFLAGS = $(ATF_CXX_CFLAGS)
drivers_list_tests_helpers_LDADD = $(ATF_CXX_LIBS)
tests_drivers_PROGRAMS += drivers/list_tests_test
drivers_list_tests_test_SOURCES = drivers/list_tests_test.cpp
drivers_list_tests_test_CXXFLAGS = $(DRIVERS_CFLAGS) $(ATF_CXX_CFLAGS)
drivers_list_tests_test_LDADD = $(DRIVERS_LIBS) $(ATF_CXX_LIBS)
tests_drivers_PROGRAMS += drivers/report_junit_test
drivers_report_junit_test_SOURCES = drivers/report_junit_test.cpp
drivers_report_junit_test_CXXFLAGS = $(DRIVERS_CFLAGS) $(ATF_CXX_CFLAGS)
drivers_report_junit_test_LDADD = $(DRIVERS_LIBS) $(ATF_CXX_LIBS)
tests_drivers_PROGRAMS += drivers/scan_results_test
drivers_scan_results_test_SOURCES = drivers/scan_results_test.cpp
drivers_scan_results_test_CXXFLAGS = $(DRIVERS_CFLAGS) $(ATF_CXX_CFLAGS)
drivers_scan_results_test_LDADD = $(DRIVERS_LIBS) $(ATF_CXX_LIBS)
endif
+3
View File
@@ -8,6 +8,9 @@ atf_test_program{name="atf_result_test"}
atf_test_program{name="config_test"}
atf_test_program{name="exceptions_test"}
atf_test_program{name="filters_test"}
atf_test_program{name="googletest_test"}
atf_test_program{name="googletest_list_test"}
atf_test_program{name="googletest_result_test"}
atf_test_program{name="kyuafile_test"}
atf_test_program{name="plain_test"}
atf_test_program{name="requirements_test"}
-155
View File
@@ -1,155 +0,0 @@
# Copyright 2010 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ENGINE_CFLAGS = $(STORE_CFLAGS) $(MODEL_CFLAGS) $(UTILS_CFLAGS)
ENGINE_LIBS = libengine.a $(STORE_LIBS) $(MODEL_LIBS) $(UTILS_LIBS)
noinst_LIBRARIES += libengine.a
libengine_a_CPPFLAGS = $(STORE_CFLAGS) $(UTILS_CFLAGS)
libengine_a_SOURCES = engine/atf.cpp
libengine_a_SOURCES += engine/atf.hpp
libengine_a_SOURCES += engine/atf_list.cpp
libengine_a_SOURCES += engine/atf_list.hpp
libengine_a_SOURCES += engine/atf_result.cpp
libengine_a_SOURCES += engine/atf_result.hpp
libengine_a_SOURCES += engine/atf_result_fwd.hpp
libengine_a_SOURCES += engine/config.cpp
libengine_a_SOURCES += engine/config.hpp
libengine_a_SOURCES += engine/config_fwd.hpp
libengine_a_SOURCES += engine/exceptions.cpp
libengine_a_SOURCES += engine/exceptions.hpp
libengine_a_SOURCES += engine/filters.cpp
libengine_a_SOURCES += engine/filters.hpp
libengine_a_SOURCES += engine/filters_fwd.hpp
libengine_a_SOURCES += engine/kyuafile.cpp
libengine_a_SOURCES += engine/kyuafile.hpp
libengine_a_SOURCES += engine/kyuafile_fwd.hpp
libengine_a_SOURCES += engine/plain.cpp
libengine_a_SOURCES += engine/plain.hpp
libengine_a_SOURCES += engine/requirements.cpp
libengine_a_SOURCES += engine/requirements.hpp
libengine_a_SOURCES += engine/scanner.cpp
libengine_a_SOURCES += engine/scanner.hpp
libengine_a_SOURCES += engine/scanner_fwd.hpp
libengine_a_SOURCES += engine/tap.cpp
libengine_a_SOURCES += engine/tap.hpp
libengine_a_SOURCES += engine/tap_parser.cpp
libengine_a_SOURCES += engine/tap_parser.hpp
libengine_a_SOURCES += engine/tap_parser_fwd.hpp
libengine_a_SOURCES += engine/scheduler.cpp
libengine_a_SOURCES += engine/scheduler.hpp
libengine_a_SOURCES += engine/scheduler_fwd.hpp
if WITH_ATF
tests_enginedir = $(pkgtestsdir)/engine
tests_engine_DATA = engine/Kyuafile
EXTRA_DIST += $(tests_engine_DATA)
tests_engine_PROGRAMS = engine/atf_helpers
engine_atf_helpers_SOURCES = engine/atf_helpers.cpp
engine_atf_helpers_CXXFLAGS = $(UTILS_CFLAGS) $(ATF_CXX_CFLAGS)
engine_atf_helpers_LDADD = $(UTILS_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/atf_test
engine_atf_test_SOURCES = engine/atf_test.cpp
engine_atf_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_atf_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/atf_list_test
engine_atf_list_test_SOURCES = engine/atf_list_test.cpp
engine_atf_list_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_atf_list_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/atf_result_test
engine_atf_result_test_SOURCES = engine/atf_result_test.cpp
engine_atf_result_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_atf_result_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/config_test
engine_config_test_SOURCES = engine/config_test.cpp
engine_config_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_config_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/exceptions_test
engine_exceptions_test_SOURCES = engine/exceptions_test.cpp
engine_exceptions_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_exceptions_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/filters_test
engine_filters_test_SOURCES = engine/filters_test.cpp
engine_filters_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_filters_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/kyuafile_test
engine_kyuafile_test_SOURCES = engine/kyuafile_test.cpp
engine_kyuafile_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_kyuafile_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/plain_helpers
engine_plain_helpers_SOURCES = engine/plain_helpers.cpp
engine_plain_helpers_CXXFLAGS = $(UTILS_CFLAGS)
engine_plain_helpers_LDADD = $(UTILS_LIBS)
tests_engine_PROGRAMS += engine/plain_test
engine_plain_test_SOURCES = engine/plain_test.cpp
engine_plain_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_plain_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/requirements_test
engine_requirements_test_SOURCES = engine/requirements_test.cpp
engine_requirements_test_CXXFLAGS = $(ENGINE_CFLAGS) $(UTILS_TEST_CFLAGS) \
$(ATF_CXX_CFLAGS)
engine_requirements_test_LDADD = $(ENGINE_LIBS) $(UTILS_TEST_LIBS) \
$(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/scanner_test
engine_scanner_test_SOURCES = engine/scanner_test.cpp
engine_scanner_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_scanner_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/tap_helpers
engine_tap_helpers_SOURCES = engine/tap_helpers.cpp
engine_tap_helpers_CXXFLAGS = $(UTILS_CFLAGS)
engine_tap_helpers_LDADD = $(UTILS_LIBS)
tests_engine_PROGRAMS += engine/tap_test
engine_tap_test_SOURCES = engine/tap_test.cpp
engine_tap_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_tap_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/tap_parser_test
engine_tap_parser_test_SOURCES = engine/tap_parser_test.cpp
engine_tap_parser_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_tap_parser_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
tests_engine_PROGRAMS += engine/scheduler_test
engine_scheduler_test_SOURCES = engine/scheduler_test.cpp
engine_scheduler_test_CXXFLAGS = $(ENGINE_CFLAGS) $(ATF_CXX_CFLAGS)
engine_scheduler_test_LDADD = $(ENGINE_LIBS) $(ATF_CXX_LIBS)
endif
+11 -10
View File
@@ -40,23 +40,24 @@ namespace engine {
/// Implementation of the scheduler interface for atf test programs.
class atf_interface : public engine::scheduler::interface {
public:
void exec_list(const model::test_program&,
const utils::config::properties_map&) const UTILS_NORETURN;
void exec_list [[noreturn]] (
const model::test_program&,
const utils::config::properties_map&) const;
model::test_cases_map parse_list(
const utils::optional< utils::process::status >&,
const utils::fs::path&,
const utils::fs::path&) const;
void exec_test(const model::test_program&, const std::string&,
const utils::config::properties_map&,
const utils::fs::path&) const
UTILS_NORETURN;
void exec_test [[noreturn]] (
const model::test_program&, const std::string&,
const utils::config::properties_map&,
const utils::fs::path&) const;
void exec_cleanup(const model::test_program&, const std::string&,
const utils::config::properties_map&,
const utils::fs::path&) const
UTILS_NORETURN;
void exec_cleanup [[noreturn]](
const model::test_program&, const std::string&,
const utils::config::properties_map&,
const utils::fs::path&) const;
model::test_result compute_result(
const utils::optional< utils::process::status >&,
+14 -6
View File
@@ -625,13 +625,21 @@ engine::calculate_atf_result(const optional< process::status >& body_status,
try {
result = atf_result::load(results_file);
} catch (const engine::format_error& error) {
result = atf_result(atf_result::broken, error.what());
} catch (const std::runtime_error& error) {
if (body_status)
result = atf_result(
atf_result::broken, F("Premature exit; test case %s") %
if (body_status) {
result = atf_result(atf_result::broken,
F("Error: %s. Test case %s") %
error.what() %
format_status(body_status.get()));
else {
} else {
// The test case timed out. apply() handles this case later.
}
} catch (const std::runtime_error& error) {
if (body_status) {
result = atf_result(
atf_result::broken,
F("Error: Premature exit. Test case %s") %
format_status(body_status.get()));
} else {
// The test case timed out. apply() handles this case later.
}
}
+4 -3
View File
@@ -664,7 +664,7 @@ ATF_TEST_CASE_BODY(calculate_atf_result__missing_file)
const status body_status = status::fake_exited(EXIT_SUCCESS);
const model::test_result expected(
model::test_result_broken,
"Premature exit; test case exited with code 0");
"Error: Premature exit. Test case exited with code 0");
ATF_REQUIRE_EQ(expected, engine::calculate_atf_result(
utils::make_optional(body_status), fs::path("foo")));
}
@@ -677,8 +677,9 @@ ATF_TEST_CASE_BODY(calculate_atf_result__bad_file)
const status body_status = status::fake_exited(EXIT_SUCCESS);
atf::utils::create_file("foo", "invalid\n");
const model::test_result expected(model::test_result_broken,
"Unknown test result 'invalid'");
const model::test_result expected(
model::test_result_broken,
"Error: Unknown test result 'invalid'. Test case exited with code 0");
ATF_REQUIRE_EQ(expected, engine::calculate_atf_result(
utils::make_optional(body_status), fs::path("foo")));
}
+1 -1
View File
@@ -310,7 +310,7 @@ ATF_TEST_CASE_BODY(test__body_only__crashes)
const model::test_result exp_result(
model::test_result_broken,
F("Premature exit; test case received signal %s (core dumped)") %
F("Error: Empty test result or no new line. Test case received signal %s (core dumped)") %
SIGABRT);
run_one(this, "crash", exp_result);
}
+2 -2
View File
@@ -82,7 +82,7 @@ set_defaults(config::tree& tree)
for (auto em : execenv::execenvs())
if (em->is_supported())
supported.insert(em->name());
supported.insert(execenv::default_execenv_name);
supported.insert(DEFAULT_EXECENV_NAME);
tree.set< config::strings_set_node >("execenvs", supported);
// TODO(jmmv): Automatically derive this from the number of CPUs in the
@@ -244,7 +244,7 @@ engine::empty_config(void)
// Tests of Kyua itself tend to use an empty config, i.e. default
// execution environment is used. Let's allow it.
std::set< std::string > supported;
supported.insert(engine::execenv::default_execenv_name);
supported.insert(DEFAULT_EXECENV_NAME);
tree.set< config::strings_set_node >("execenvs", supported);
return tree;
-3
View File
@@ -35,9 +35,6 @@ namespace execenv = engine::execenv;
using utils::none;
const char* execenv::default_execenv_name = "host";
/// List of registered execution environments, except default host one.
///
/// Use register_execenv() to add an entry to this global list.
+2 -4
View File
@@ -32,6 +32,7 @@
#if !defined(ENGINE_EXECENV_EXECENV_HPP)
#define ENGINE_EXECENV_EXECENV_HPP
#include "engine/execenv/execenv_fwd.hpp"
#include "model/test_program.hpp"
#include "utils/optional.ipp"
#include "utils/process/operations_fwd.hpp"
@@ -43,9 +44,6 @@ namespace engine {
namespace execenv {
extern const char* default_execenv_name;
/// Abstract interface of an execution environment.
class interface {
protected:
@@ -85,7 +83,7 @@ public:
/// scheduler::interface::exec_test() or exec_cleanup().
///
/// \param args The arguments to pass to the binary.
virtual void exec(const args_vector& args) const UTILS_NORETURN = 0;
virtual void exec [[noreturn]] (const args_vector& args) const = 0;
};
@@ -0,0 +1,44 @@
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// \file engine/execenv/execenv_fwd.hpp
/// Forward declarations for engine/execenv/execenv.hpp
#if !defined(ENGINE_EXECENV_EXECENV_FWD_HPP)
#define ENGINE_EXECENV_EXECENV_FWD_HPP
#define DEFAULT_EXECENV_NAME "host"
namespace engine {
namespace execenv {
} // namespace execenv
} // namespace engine
#endif // !defined(ENGINE_EXECENV_EXECENV_FWD_HPP)
+1 -1
View File
@@ -53,7 +53,7 @@ public:
void init() const;
void cleanup() const;
void exec(const args_vector& args) const UTILS_NORETURN;
void exec [[noreturn]] (const args_vector& args) const;
};
+219
View File
@@ -0,0 +1,219 @@
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "engine/googletest.hpp"
extern "C" {
#include <unistd.h>
}
#include <cerrno>
#include <cstdlib>
#include <fstream>
#include "engine/googletest_list.hpp"
#include "engine/googletest_result.hpp"
#include "engine/exceptions.hpp"
#include "model/test_case.hpp"
#include "model/test_program.hpp"
#include "model/test_result.hpp"
#include "utils/defs.hpp"
#include "utils/env.hpp"
#include "utils/format/macros.hpp"
#include "utils/fs/path.hpp"
#include "utils/logging/macros.hpp"
#include "utils/optional.ipp"
#include "utils/process/exceptions.hpp"
#include "utils/process/operations.hpp"
#include "utils/process/status.hpp"
#include "utils/stream.hpp"
namespace config = utils::config;
namespace fs = utils::fs;
namespace process = utils::process;
using utils::optional;
namespace {
/// Basename of the file containing the result written by the googletest
/// testcase.
///
/// TODO: Use more structured output format someday, like the googletest's JSON
/// or XML format to avoid dealing with upstream formatting changes, as there's
/// no guarantee that the output format (which is more or less custom/freeform)
/// won't change in the future, making compatibility with all versions
/// potentially difficult to scrape for.
///
/// Using either format will require pulling in a third party library and
/// understanding the schema of the format. As it stands in 1.9.0,
/// googletest doesn't document this expectation very well and instead seems
/// to rely on third-party solutions for doing structured output via the
/// listener interfaces.
/// Magic numbers returned by exec_list when exec(2) fails.
enum list_exit_code {
exit_eacces = 90,
exit_enoent,
exit_enoexec,
};
} // anonymous namespace
/// Executes a test program's list operation.
///
/// This method is intended to be called within a subprocess and is expected
/// to terminate execution either by exec(2)ing the test program or by
/// exiting with a failure.
///
/// \param test_program The test program to execute.
void
engine::googletest_interface::exec_list(
const model::test_program& test_program,
const config::properties_map& /*vars*/) const
{
const process::args_vector args{
"--gtest_color=no",
"--gtest_list_tests",
};
try {
process::exec_unsafe(test_program.absolute_path(), args);
} catch (const process::system_error& e) {
if (e.original_errno() == EACCES)
::_exit(exit_eacces);
else if (e.original_errno() == ENOENT)
::_exit(exit_enoent);
else if (e.original_errno() == ENOEXEC)
::_exit(exit_enoexec);
throw;
}
}
/// Computes the test cases list of a test program.
///
/// \param status The termination status of the subprocess used to execute
/// the exec_test() method or none if the test timed out.
/// \param stdout_path Path to the file containing the stdout of the test.
///
/// \return A list of test cases.
///
/// \throw error If there is a problem parsing the test case list.
model::test_cases_map
engine::googletest_interface::parse_list(
const optional< process::status >& status,
const fs::path& stdout_path,
const fs::path& /* stderr_path */) const
{
if (!status)
throw engine::error("Test case list timed out");
if (status.get().exited()) {
const int exitstatus = status.get().exitstatus();
if (exitstatus == EXIT_SUCCESS) {
// Nothing to do; fall through.
} else if (exitstatus == exit_eacces) {
throw engine::error("Permission denied to run test program");
} else if (exitstatus == exit_enoent) {
throw engine::error("Cannot find test program");
} else if (exitstatus == exit_enoexec) {
throw engine::error("Invalid test program format");
} else {
throw engine::error("Test program did not exit cleanly; exited "
"with status: " + std::to_string(exitstatus));
}
} else {
throw engine::error("Test program received signal");
}
std::ifstream input(stdout_path.c_str());
if (!input)
throw engine::load_error(stdout_path, "Cannot open file for read");
const model::test_cases_map test_cases = parse_googletest_list(input);
return test_cases;
}
/// Executes a test case of the test program.
///
/// This method is intended to be called within a subprocess and is expected
/// to terminate execution either by exec(2)ing the test program or by
/// exiting with a failure.
///
/// \param test_program The test program to execute.
/// \param test_case_name Name of the test case to invoke.
/// \param vars User-provided variables to pass to the test program.
void
engine::googletest_interface::exec_test(
const model::test_program& test_program,
const std::string& test_case_name,
const config::properties_map& vars,
const fs::path& /* control_directory */) const
{
for (config::properties_map::const_iterator iter = vars.begin();
iter != vars.end(); ++iter) {
utils::setenv(F("TEST_ENV_%s") % (*iter).first, (*iter).second);
}
process::args_vector args{
"--gtest_color=no",
F("--gtest_filter=%s") % (test_case_name)
};
process::exec(test_program.absolute_path(), args);
__builtin_unreachable();
}
/// Computes the result of a test case based on its termination status.
///
/// \param status The termination status of the subprocess used to execute
/// the exec_test() method or none if the test timed out.
/// \param stdout_path Path to the file containing the stdout of the
/// test.
///
/// \return A test result.
model::test_result
engine::googletest_interface::compute_result(
const optional< process::status >& status,
const fs::path& /* control_directory */,
const fs::path& stdout_path,
const fs::path& /* stderr_path */) const
{
if (!status) {
return model::test_result(model::test_result_broken,
"Test case body timed out");
}
return calculate_googletest_result(status, stdout_path);
}
+68
View File
@@ -0,0 +1,68 @@
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// \file engine/googletest.hpp
/// Execution engine for test programs that implement the googletest interface.
#if !defined(ENGINE_GOOGLETEST_HPP)
#define ENGINE_GOOGLETEST_HPP
#include "engine/scheduler.hpp"
namespace engine {
/// Implementation of the scheduler interface for googletest test programs.
class googletest_interface : public engine::scheduler::interface {
public:
void exec_list [[noreturn]] (
const model::test_program&,
const utils::config::properties_map&) const;
model::test_cases_map parse_list(
const utils::optional< utils::process::status >&,
const utils::fs::path&,
const utils::fs::path&) const;
void exec_test [[noreturn]] (
const model::test_program&, const std::string&,
const utils::config::properties_map&,
const utils::fs::path&) const;
model::test_result compute_result(
const utils::optional< utils::process::status >&,
const utils::fs::path&,
const utils::fs::path&,
const utils::fs::path&) const;
};
} // namespace engine
#endif // !defined(ENGINE_GOOGLETEST_HPP)
+330
View File
@@ -0,0 +1,330 @@
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
extern "C" {
#include <sys/stat.h>
#include <getopt.h>
#include <signal.h>
#include <unistd.h>
extern char** environ;
}
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include "utils/env.hpp"
#include "utils/cmdline/options.hpp"
#include "utils/cmdline/parser.ipp"
#include "utils/format/containers.ipp"
#include "utils/format/macros.hpp"
#include "utils/fs/path.hpp"
#include "utils/optional.ipp"
#include "utils/test_utils.ipp"
namespace cmdline = utils::cmdline;
namespace fs = utils::fs;
using cmdline::base_option;
using cmdline::bool_option;
using cmdline::parse;
using cmdline::parsed_cmdline;
using cmdline::string_option;
namespace fs = utils::fs;
namespace {
/// Prefix for all testcases.
const char *test_suite = "Suite.";
/// Logs an error message and exits the test with an error code.
///
/// \param str The error message to log.
static void
fail(const std::string& str)
{
std::cerr << str << '\n';
std::exit(EXIT_FAILURE);
}
/// A test scenario that validates the TEST_ENV_* variables.
static void
test_check_configuration_variables(void)
{
std::set< std::string > vars;
char** iter;
for (iter = environ; *iter != NULL; ++iter) {
if (std::strstr(*iter, "TEST_ENV_") == *iter) {
vars.insert(*iter);
}
}
std::set< std::string > exp_vars{
"TEST_ENV_first=some value",
"TEST_ENV_second=some other value"
};
if (vars == exp_vars) {
std::cout <<
"Note: Google Test filter = Suite.check_configuration_variables\n"
"[==========] Running 1 test from 1 test case.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from Suite\n"
"[ RUN ] Suite.check_configuration_variables\n"
"[ OK ] Suite.check_configuration_variables (0 ms)\n"
"[----------] 1 test from PassFailTest (0 ms total)\n"
"\n"
"[----------] Global test environment tear-down\n"
"[==========] 1 test from 1 test case ran. (1 ms total)\n"
"[ PASSED ] 1 test.\n"
;
} else {
std::cout <<
"Note: Google Test filter = Suite.Fails\n"
"[==========] Running 1 test from 1 test case.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from PassFailTest\n"
"[ RUN ] Suite.check_configuration_variables\n"
"pass_fail_demo.cc:12: Failure\n"
"Expected equality of these values:\n"
" false\n"
" true\n"
"[ FAILED ] Suite.check_configuration_variables (0 ms)\n"
"[----------] 1 test from Suite (0 ms total)\n"
"\n"
"[----------] Global test environment tear-down\n"
"[==========] 1 test from 1 test case ran. (0 ms total)\n"
"[ PASSED ] 0 tests.\n"
"[ FAILED ] 1 test, listed below:\n"
"[ FAILED ] Suite.check_configuration_variables\n"
"\n"
" 1 FAILED TEST\n"
<< F(" Expected: %s\nFound: %s\n") % exp_vars % vars;
std::exit(EXIT_FAILURE);
}
}
/// A test scenario that triggers a crash via abort in order to generate a
/// core dump.
static void
test_crash(void)
{
std::abort();
}
/// A test scenario that reports some tests as failed.
static void
test_fail(void)
{
std::cout << (
"Note: Google Test filter = Suite.fail\n"
"[==========] Running 1 test from 1 test suite.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from Suite\n"
"[ RUN ] Suite.fail\n"
"gtest_macros_demo.cc:4: Failure\n"
"Failed\n"
"with a reason\n"
"[ FAILED ] Suite.fail (0 ms)\n"
"[----------] 1 test from Suite (0 ms total)\n"
"\n"
"[----------] Global test environment tear-down\n"
"[==========] 1 test from 1 test suite ran. (0 ms total)\n"
"[ PASSED ] 0 tests.\n"
"[ FAILED ] 1 test, listed below:\n"
"[ FAILED ] Suite.fail\n"
"\n"
" 1 FAILED TEST\n"
);
std::exit(EXIT_FAILURE);
}
/// A test scenario that passes.
static void
test_pass(void)
{
std::cout << (
"Note: Google Test filter = Suite.pass\n"
"[==========] Running 1 test from 1 test suite.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from Suite\n"
"[ RUN ] Suite.pass\n"
"[ OK ] Suite.pass (0 ms)\n"
"[----------] 1 test from Suite (0 ms total)\n"
"\n"
"[----------] Global test environment tear-down\n"
"[==========] 1 test from 1 test suite ran. (0 ms total)\n"
"[ PASSED ] 1 test.\n"
);
}
/// A test scenario that passes but then exits with non-zero.
static void
test_pass_but_exit_failure(void)
{
std::cout << (
"Note: Google Test filter = Suite.pass_but_exit_failure\n"
"[==========] Running 1 test from 1 test suite.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from Suite\n"
"[ RUN ] Suite.pass_but_exit_failure\n"
"[ OK ] Suite.pass_but_exit_failure (0 ms)\n"
"[----------] 1 test from Suite (0 ms total)\n"
"\n"
"[----------] Global test environment tear-down\n"
"[==========] 1 test from 1 test suite ran. (0 ms total)\n"
"[ PASSED ] 1 test.\n"
);
std::exit(70);
}
/// A test scenario that times out.
///
/// Note that the timeout is defined in the Kyuafile, as the TAP interface has
/// no means for test programs to specify this by themselves.
static void
test_timeout(void)
{
std::cout << (
"Note: Google Test filter = Suite.incomplete\n"
"[==========] Running 1 test from 1 test suite.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from Suite\n"
"[ RUN ] Suite.incomplete\n"
);
::sleep(10);
const fs::path control_dir = fs::path(utils::getenv("CONTROL_DIR").get());
std::ofstream file((control_dir / "cookie").c_str());
if (!file)
fail("Failed to create the control cookie");
file.close();
}
/// Prints out program usage and exits with a non-zero exit code.
static void
usage(const char* argv0) {
std::cout << "usage: " << argv0 << " "
<< "[--gtest_color=(auto|yes|no)] "
<< "[--gtest_filter=POSITIVE_PATTERNS] "
<< "[--gtest_list_tests]"
<< "\n\n"
<< "This program mocks a googletest test program."
<< "\n";
std::exit(EXIT_FAILURE);
}
} // anonymous namespace
/// Entry point to the test program.
///
/// The caller can select which test scenario to run by modifying the program's
/// basename on disk (either by a copy or by a hard link).
///
/// \todo It may be worth to split this binary into separate, smaller binaries,
/// one for every "test scenario". We use this program as a dispatcher for
/// different "main"s, the only reason being to keep the amount of helper test
/// programs to a minimum. However, putting this each function in its own
/// binary could simplify many other things.
///
/// \param argc The number of CLI arguments.
/// \param argv The CLI arguments themselves. These are not used because
/// Kyua will not pass any arguments to the plain test program.
int
main(int argc, char** argv)
{
using scenario_fn_t = void (*)(void);
char *argv0 = argv[0];
std::map<std::string, scenario_fn_t> scenarios{
{ "check_configuration_variables", test_check_configuration_variables },
{ "crash", test_crash },
{ "fail", test_fail },
{ "pass", test_pass },
{ "pass_but_exit_failure", test_pass_but_exit_failure },
{ "timeout", test_timeout }
};
const bool_option gtest_list_tests_opt(
"gtest_list_tests", "List tests");
const string_option gtest_color_opt(
"gtest_color", "Enable/disable color support", "auto");
const string_option gtest_filter_opt(
"gtest_filter", "", "POSITIVE_PATTERNS");
std::vector<const base_option*> options;
/// Ignore `--gtest_color=*`.
options.push_back(&gtest_color_opt);
options.push_back(&gtest_filter_opt);
options.push_back(&gtest_list_tests_opt);
const parsed_cmdline cmdline = parse(argc, argv, options);
INV(cmdline.arguments().empty());
if (cmdline.has_option("gtest_list_tests")) {
std::cout << test_suite << "\n";
for (auto it = scenarios.begin(); it != scenarios.end(); it++) {
std::cout << " " << it->first << "\n";
}
return EXIT_SUCCESS;
}
INV(cmdline.has_option("gtest_filter"));
auto gtest_filter_arg = cmdline.get_option<string_option>("gtest_filter");
INV(gtest_filter_arg.find_first_of(test_suite) == 0);
auto testcase = gtest_filter_arg.erase(0, strlen(test_suite));
auto scenario = scenarios.find(testcase);
if (scenario == scenarios.end()) {
/// Mimic googletest test programs by printing out a usage message when
/// a test cannot be found.
usage(argv0);
}
scenario->second();
return EXIT_SUCCESS;
}
+111
View File
@@ -0,0 +1,111 @@
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "engine/googletest_list.hpp"
#include <fstream>
#include <regex>
#include <string>
#include <utility>
#include "engine/exceptions.hpp"
#include "model/metadata.hpp"
#include "model/test_case.hpp"
#include "utils/config/exceptions.hpp"
#include "utils/format/macros.hpp"
namespace config = utils::config;
namespace fs = utils::fs;
namespace {
/// A regular expression that should match either a test suite or a test case.
const std::string name_expr = "([[:alpha:][:digit:]_]+[[:alpha:][:digit:]_/]*)";
/// The separator between a test suite and a test case.
const std::string testsuite_testcase_separator = ".";
} // anonymous namespace
/// Parses the googletest list of test cases from an open stream.
///
/// \param input The stream to read from.
///
/// \return The collection of parsed test cases.
///
/// \throw format_error If there is any problem in the input data.
model::test_cases_map
engine::parse_googletest_list(std::istream& input)
{
std::string line, test_suite;
// TODO: These were moved here from the anonymous namespace because of a
// Doxygen bug that's reproducible with the version used by Travis CI.
//
/// A complete regular expression representing a line with a test case
/// definition, e,g., " TestCase", " TestCase/0", or
/// " TestCase/0 # GetParam() = 4".
const std::regex testcase_re(
" " + name_expr + "([[:space:]]+# GetParam\\(\\) = .+)?");
/// A complete regular expression representing a line with a test suite
/// definition, e,g., * "TestSuite.", "TestSuite/Prefix.", or
/// "TestSuite/Prefix. # TypeParam = .+".
const std::regex testsuite_re(
name_expr + "\\.([[:space:]]+# TypeParam = .+)?");
// END TODO
model::test_cases_map_builder test_cases_builder;
while (std::getline(input, line).good()) {
std::smatch match;
if (std::regex_match(line, match, testcase_re)) {
if (test_suite.empty()) {
throw format_error("Invalid testcase definition: not preceded "
"by a test suite definition");
}
std::string test_case(match[1]);
test_cases_builder.add(test_suite + test_case);
} else if (std::regex_match(line, match, testsuite_re)) {
test_suite = std::string(match[1]) +
testsuite_testcase_separator;
} else {
// Ignore the line; something might have used output a diagnostic
// message to stdout, e.g., gtest_main.
}
}
const model::test_cases_map test_cases = test_cases_builder.build();
if (test_cases.empty()) {
// The scheduler interface also checks for the presence of at least one
// test case. However, because the atf format itself requires one test
// case to be always present, we check for this condition here as well.
throw format_error("No test cases");
}
return test_cases;
}
@@ -1,4 +1,4 @@
// Copyright 2010 The Kyua Authors.
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -26,46 +26,25 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdlib>
#include <string>
/// \file engine/atf_list.hpp
/// Parser of googletest test case lists.
#include <atf-c++.hpp>
#if !defined(ENGINE_GOOGLETEST_LIST_HPP)
#define ENGINE_GOOGLETEST_LIST_HPP
#include <istream>
#include "model/metadata_fwd.hpp"
#include "model/test_case_fwd.hpp"
#include "model/types.hpp"
#include "utils/fs/path_fwd.hpp"
namespace engine {
ATF_TEST_CASE_WITHOUT_HEAD(fails);
ATF_TEST_CASE_BODY(fails)
{
fail("Failed on purpose");
}
model::test_cases_map parse_googletest_list(std::istream&);
ATF_TEST_CASE_WITHOUT_HEAD(passes);
ATF_TEST_CASE_BODY(passes)
{
}
} // namespace engine
ATF_TEST_CASE_WITHOUT_HEAD(skips);
ATF_TEST_CASE_BODY(skips)
{
skip("Skipped on purpose");
}
ATF_INIT_TEST_CASES(tcs)
{
std::string enabled;
const char* tests = std::getenv("TESTS");
if (tests == NULL)
enabled = "fails passes skips";
else
enabled = tests;
if (enabled.find("fails") != std::string::npos)
ATF_ADD_TEST_CASE(tcs, fails);
if (enabled.find("passes") != std::string::npos)
ATF_ADD_TEST_CASE(tcs, passes);
if (enabled.find("skips") != std::string::npos)
ATF_ADD_TEST_CASE(tcs, skips);
}
#endif // !defined(ENGINE_GOOGLETEST_LIST_HPP)
@@ -0,0 +1,208 @@
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "engine/googletest_list.hpp"
#include <sstream>
#include <string>
#include <atf-c++.hpp>
#include "engine/exceptions.hpp"
#include "model/metadata.hpp"
#include "model/test_case.hpp"
#include "model/types.hpp"
#include "utils/datetime.hpp"
#include "utils/format/containers.ipp"
#include "utils/fs/path.hpp"
#include "utils/units.hpp"
namespace datetime = utils::datetime;
namespace fs = utils::fs;
namespace units = utils::units;
ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__invalid_testcase_definition);
ATF_TEST_CASE_BODY(parse_googletest_list__invalid_testcase_definition)
{
std::istringstream input1(" \n");
ATF_REQUIRE_THROW_RE(engine::format_error, "No test cases",
engine::parse_googletest_list(input1));
std::istringstream input2(" TestcaseWithoutSuite\n");
ATF_REQUIRE_THROW_RE(engine::format_error,
"Invalid testcase definition: not preceded by a test suite definition",
engine::parse_googletest_list(input2));
}
ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__invalid_testsuite_definition);
ATF_TEST_CASE_BODY(parse_googletest_list__invalid_testsuite_definition)
{
std::istringstream input1("\n");
ATF_REQUIRE_THROW_RE(engine::format_error, "No test cases",
engine::parse_googletest_list(input1));
std::istringstream input2(
"TestSuiteWithoutSeparator\n"
);
ATF_REQUIRE_THROW_RE(engine::format_error, "No test cases",
engine::parse_googletest_list(input2));
}
ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__no_test_cases);
ATF_TEST_CASE_BODY(parse_googletest_list__no_test_cases)
{
std::istringstream input("");
ATF_REQUIRE_THROW_RE(engine::format_error, "No test cases",
engine::parse_googletest_list(input));
}
ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__one_test_case);
ATF_TEST_CASE_BODY(parse_googletest_list__one_test_case)
{
std::istringstream input(
"TestSuite.\n"
" TestCase\n"
);
const model::test_cases_map tests = engine::parse_googletest_list(input);
const model::test_cases_map exp_tests = model::test_cases_map_builder()
.add("TestSuite.TestCase").build();
ATF_REQUIRE_EQ(exp_tests, tests);
}
ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__one_parameterized_test_case);
ATF_TEST_CASE_BODY(parse_googletest_list__one_parameterized_test_case)
{
std::istringstream input(
"TestSuite.\n"
" TestCase/0 # GetParam() = 'c'\n"
);
const model::test_cases_map tests = engine::parse_googletest_list(input);
const model::test_cases_map exp_tests = model::test_cases_map_builder()
.add("TestSuite.TestCase/0").build();
ATF_REQUIRE_EQ(exp_tests, tests);
}
ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__one_parameterized_test_suite);
ATF_TEST_CASE_BODY(parse_googletest_list__one_parameterized_test_suite)
{
std::string text =
"TestSuite/0. # TypeParam = int\n"
" TestCase\n"
;
std::istringstream input(text);
const model::test_cases_map tests = engine::parse_googletest_list(input);
const model::test_cases_map exp_tests = model::test_cases_map_builder()
.add("TestSuite/0.TestCase").build();
ATF_REQUIRE_EQ(exp_tests, tests);
}
ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__one_parameterized_test_case_and_test_suite);
ATF_TEST_CASE_BODY(parse_googletest_list__one_parameterized_test_case_and_test_suite)
{
std::string text =
"TestSuite/0. # TypeParam = int\n"
" TestCase/0 # GetParam() = \"herp\"\n"
" TestCase/1 # GetParam() = \"derp\"\n"
;
std::istringstream input(text);
const model::test_cases_map tests = engine::parse_googletest_list(input);
const model::test_cases_map exp_tests = model::test_cases_map_builder()
.add("TestSuite/0.TestCase/0")
.add("TestSuite/0.TestCase/1")
.build();
ATF_REQUIRE_EQ(exp_tests, tests);
}
ATF_TEST_CASE_WITHOUT_HEAD(parse_googletest_list__many_test_cases);
ATF_TEST_CASE_BODY(parse_googletest_list__many_test_cases)
{
std::string text =
"FirstTestSuite.\n"
" ATestCase\n"
"SecondTestSuite.\n"
" AnotherTestCase\n"
"ThirdTestSuite.\n"
" _\n"
"FourthTestSuite/0. # TypeParam = std::list<int>\n"
" TestCase\n"
"FourthTestSuite/1. # TypeParam = std::list<int>\n"
" TestCase\n"
"FifthTestSuite.\n"
" TestCase/0 # GetParam() = 0\n"
" TestCase/1 # GetParam() = (1, 2, 3)\n"
" TestCase/2 # GetParam() = \"developers. developers\"\n"
"SixthTestSuite/0. # TypeParam = std::map<std::basic_string, int>\n"
" TestCase/0 # GetParam() = 0\n"
" TestCase/1 # GetParam() = (1, 2, 3)\n"
;
std::istringstream input(text);
const model::test_cases_map tests = engine::parse_googletest_list(input);
const model::test_cases_map exp_tests = model::test_cases_map_builder()
.add("FirstTestSuite.ATestCase", model::metadata_builder()
.build())
.add("SecondTestSuite.AnotherTestCase", model::metadata_builder()
.build())
.add("ThirdTestSuite._")
.add("FourthTestSuite/0.TestCase")
.add("FourthTestSuite/1.TestCase")
.add("FifthTestSuite.TestCase/0")
.add("FifthTestSuite.TestCase/1")
.add("FifthTestSuite.TestCase/2")
.add("SixthTestSuite/0.TestCase/0")
.add("SixthTestSuite/0.TestCase/1")
.build();
ATF_REQUIRE_EQ(exp_tests, tests);
}
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, parse_googletest_list__invalid_testcase_definition);
ATF_ADD_TEST_CASE(tcs, parse_googletest_list__invalid_testsuite_definition);
ATF_ADD_TEST_CASE(tcs, parse_googletest_list__no_test_cases);
ATF_ADD_TEST_CASE(tcs, parse_googletest_list__one_test_case);
ATF_ADD_TEST_CASE(tcs, parse_googletest_list__one_parameterized_test_case);
ATF_ADD_TEST_CASE(tcs, parse_googletest_list__one_parameterized_test_suite);
ATF_ADD_TEST_CASE(tcs,
parse_googletest_list__one_parameterized_test_case_and_test_suite);
ATF_ADD_TEST_CASE(tcs, parse_googletest_list__many_test_cases);
}
+528
View File
@@ -0,0 +1,528 @@
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "engine/googletest_result.hpp"
#include <cstdlib>
#include <fstream>
#include <regex>
#include <utility>
#include "engine/exceptions.hpp"
#include "model/test_result.hpp"
#include "utils/fs/path.hpp"
#include "utils/format/macros.hpp"
#include "utils/optional.ipp"
#include "utils/process/status.hpp"
#include "utils/sanity.hpp"
#include "utils/text/exceptions.hpp"
#include "utils/text/operations.ipp"
namespace fs = utils::fs;
namespace process = utils::process;
namespace text = utils::text;
using utils::none;
using utils::optional;
namespace {
/// Internal string for specifying invalid output.
const std::string invalid_output_message = "invalid output";
/// Regular expression for disabled tests line.
const std::regex disabled_re(
R"RE((YOU HAVE [[:digit:]]+ DISABLED TESTS?))RE"
);
/// Regular expression for starting sentinel of results block.
const std::regex starting_sentinel_re(
R"(\[[[:space:]]+RUN[[:space:]]+\][[:space:]]+[A-Za-z0-9]+\.[A-Za-z0-9]+)"
);
/// Regular expression for ending sentinel of results block.
const std::regex ending_sentinel_re(
R"RE(\[[[:space:]]+(FAILED|OK|SKIPPED)[[:space:]]+\])RE"
);
/// Parses a test result that does not accept a reason.
///
/// \param status The result status name.
/// \param rest The rest of the line after the status name.
///
/// \return An object representing the test result.
///
/// \throw format_error If the result is invalid (i.e. rest is invalid).
///
/// \pre status must be "successful".
static engine::googletest_result
parse_without_reason(const std::string& status, const std::string& rest)
{
if (!rest.empty())
throw engine::format_error(F("%s cannot have a reason") % status);
if (status == "skipped")
return engine::googletest_result(engine::googletest_result::skipped);
else {
INV(status == "successful");
return engine::googletest_result(engine::googletest_result::successful);
}
}
/// Parses a test result that needs a reason.
///
/// \param status The result status name.
/// \param rest The rest of the line after the status name.
///
/// \return An object representing the test result.
///
/// \throw format_error If the result is invalid (i.e. rest is invalid).
///
/// \pre status must be one of "broken", "disabled", "failed", or "skipped".
static engine::googletest_result
parse_with_reason(const std::string& status, const std::string& rest)
{
using engine::googletest_result;
INV(!rest.empty());
if (status == "broken")
return googletest_result(googletest_result::broken, rest);
else if (status == "disabled")
return googletest_result(googletest_result::disabled, rest);
else if (status == "failed")
return googletest_result(googletest_result::failed, rest);
else if (status == "skipped")
return googletest_result(googletest_result::skipped, rest);
else
PRE_MSG(false, "Unexpected status");
}
/// Formats the termination status of a process to be used with validate_result.
///
/// \param status The status to format.
///
/// \return A string describing the status.
static std::string
format_status(const process::status& status)
{
if (status.exited())
return F("exited with code %s") % status.exitstatus();
else if (status.signaled())
return F("received signal %s%s") % status.termsig() %
(status.coredump() ? " (core dumped)" : "");
else
return F("terminated in an unknown manner");
}
} // anonymous namespace
/// Constructs a raw result with a type.
///
/// The reason is left uninitialized.
///
/// \param type_ The type of the result.
engine::googletest_result::googletest_result(const types type_) :
_type(type_)
{
}
/// Constructs a raw result with a type and a reason.
///
/// \param type_ The type of the result.
/// \param reason_ The reason for the result.
engine::googletest_result::googletest_result(
const types type_,
const std::string& reason_) :
_type(type_), _reason(reason_)
{
}
/// Parses an input stream to extract a test result.
///
/// If the parsing fails for any reason, the test result is 'broken' and it
/// contains the reason for the parsing failure. Test cases that report results
/// in an inconsistent state cannot be trusted (e.g. the test program code may
/// have a bug), and thus why they are reported as broken instead of just failed
/// (which is a legitimate result for a test case).
///
/// \param input The stream to read from.
///
/// \return A generic representation of the result of the test case.
///
/// \throw format_error If the input is invalid.
engine::googletest_result
engine::googletest_result::parse(std::istream& input)
{
std::vector<std::string> lines;
do {
std::string line;
std::getline(input, line, '\n');
if (!input.eof())
line.push_back('\n');
lines.push_back(line);
} while (input.good());
bool capture_context = false;
bool valid_output = false;
std::string context, status;
for (auto& line: lines) {
std::smatch matches;
if (regex_search(line, matches, disabled_re)) {
context = matches[1];
status = "disabled";
valid_output = true;
break;
}
if (regex_search(line, matches, starting_sentinel_re)) {
capture_context = true;
context = "";
continue;
}
if (regex_search(line, matches, ending_sentinel_re)) {
std::string googletest_res = matches[1];
if (googletest_res == "OK") {
context = "";
status = "successful";
} else if (googletest_res == "FAILED") {
status = "failed";
} else {
INV(googletest_res == "SKIPPED");
status = "skipped";
}
capture_context = false;
valid_output = true;
}
if (capture_context) {
context += line;
}
}
if (!valid_output) {
context = invalid_output_message;
status = "broken";
}
if (status == "skipped" && context.empty())
context = bogus_googletest_skipped_nul_message;
if (context.empty())
return parse_without_reason(status, context);
else
return parse_with_reason(status, context);
}
/// Loads a test case result from a file.
///
/// \param file The file to parse.
///
/// \return The parsed test case result if all goes well.
///
/// \throw std::runtime_error If the file does not exist.
/// \throw engine::format_error If the contents of the file are bogus.
engine::googletest_result
engine::googletest_result::load(const fs::path& file)
{
std::ifstream input(file.c_str());
if (!input)
throw std::runtime_error("Cannot open results file");
else
return parse(input);
}
/// Gets the type of the result.
///
/// \return A result type.
engine::googletest_result::types
engine::googletest_result::type(void) const
{
return _type;
}
/// Gets the optional reason of the result.
///
/// \return The reason of the result if present; none otherwise.
const optional< std::string >&
engine::googletest_result::reason(void) const
{
return _reason;
}
/// Checks whether the result should be reported as good or not.
///
/// \return True if the result can be considered "good", false otherwise.
bool
engine::googletest_result::good(void) const
{
switch (_type) {
case googletest_result::disabled:
case googletest_result::skipped:
case googletest_result::successful:
return true;
case googletest_result::broken:
case googletest_result::failed:
return false;
default:
UNREACHABLE;
}
}
/// Reinterprets a raw result based on the termination status of the test case.
///
/// This reinterpretation ensures that the termination conditions of the program
/// match what is expected of the paticular result reported by the test program.
/// If such conditions do not match, the test program is considered bogus and is
/// thus reported as broken.
///
/// This is just a helper function for calculate_result(); the real result of
/// the test case cannot be inferred from apply() only.
///
/// \param status The exit status of the test program, or none if the test
/// program timed out.
///
/// \result The adjusted result. The original result is transformed into broken
/// if the exit status of the program does not match our expectations.
engine::googletest_result
engine::googletest_result::apply(const optional< process::status >& status)
const
{
if (!status) {
return *this;
}
auto check_status = [&status](bool expect_pass) -> bool {
if (!status.get().exited()) {
return false;
}
auto exit_status = status.get().exitstatus();
if (expect_pass) {
return exit_status == EXIT_SUCCESS;
} else {
return exit_status == EXIT_FAILURE;
}
};
switch (_type) {
case googletest_result::broken:
return *this;
case googletest_result::disabled:
if (check_status(true)) {
return *this;
}
return googletest_result(googletest_result::broken,
"Disabled test case should have reported success but " +
format_status(status.get()));
case googletest_result::failed:
if (check_status(false)) {
return *this;
}
return googletest_result(googletest_result::broken,
"Failed test case should have reported failure but " +
format_status(status.get()));
case googletest_result::skipped:
if (check_status(true)) {
return *this;
}
return googletest_result(googletest_result::broken,
"Skipped test case should have reported success but " +
format_status(status.get()));
case googletest_result::successful:
if (check_status(true)) {
return *this;
}
return googletest_result(googletest_result::broken,
"Passed test case should have reported success but " +
format_status(status.get()));
}
UNREACHABLE;
}
/// Converts an internal result to the interface-agnostic representation.
///
/// \return A generic result instance representing this result.
model::test_result
engine::googletest_result::externalize(void) const
{
switch (_type) {
case googletest_result::broken:
return model::test_result(model::test_result_broken, _reason.get());
case googletest_result::disabled:
return model::test_result(model::test_result_skipped, _reason.get());
case googletest_result::failed:
return model::test_result(model::test_result_failed, _reason.get());
case googletest_result::skipped:
return model::test_result(model::test_result_skipped, _reason.get());
case googletest_result::successful:
return model::test_result(model::test_result_passed);
default:
UNREACHABLE;
}
}
/// Compares two raw results for equality.
///
/// \param other The result to compare to.
///
/// \return True if the two raw results are equal; false otherwise.
bool
engine::googletest_result::operator==(const googletest_result& other) const
{
return _type == other._type &&
_reason == other._reason;
}
/// Compares two raw results for inequality.
///
/// \param other The result to compare to.
///
/// \return True if the two raw results are different; false otherwise.
bool
engine::googletest_result::operator!=(const googletest_result& other) const
{
return !(*this == other);
}
/// Injects the object into a stream.
///
/// \param output The stream into which to inject the object.
/// \param object The object to format.
///
/// \return The output stream.
std::ostream&
engine::operator<<(std::ostream& output, const googletest_result& object)
{
std::string result_name;
switch (object.type()) {
case googletest_result::broken: result_name = "broken"; break;
case googletest_result::disabled: result_name = "disabled"; break;
case googletest_result::failed: result_name = "failed"; break;
case googletest_result::skipped: result_name = "skipped"; break;
case googletest_result::successful: result_name = "successful"; break;
}
const optional< std::string >& reason = object.reason();
output << F("model::test_result{type=%s, reason=%s}")
% text::quote(result_name, '\'')
% (reason ? text::quote(reason.get(), '\'') : "none");
return output;
}
/// Calculates the user-visible result of a test case.
///
/// This function needs to perform magic to ensure that what the test case
/// reports as its result is what the user should really see: i.e. it adjusts
/// the reported status of the test to the exit conditions of its body and
/// cleanup parts.
///
/// \param body_status The termination status of the process that executed
/// the body of the test. None if the body timed out.
/// \param results_file The path to the results file that the test case body is
/// supposed to have created.
///
/// \return The calculated test case result.
model::test_result
engine::calculate_googletest_result(
const optional< process::status >& body_status,
const fs::path& results_file)
{
using engine::googletest_result;
googletest_result result(googletest_result::broken, "Unknown result");
try {
result = googletest_result::load(results_file);
/// atf_result.cpp handles this by side-effect by setting a broken
/// result with "", which results in a std::runtime_error throw from
/// atf_result::parse(..). googletest_result::parse doesn't do that and
/// instead returns a broken result with a reason of
/// `invalid_output_message`, so that case needs to be tested for after
/// the fact to make sure the reason why `invalid_output_message` was
/// because of a program that crashed or failed.
if (result.type() == googletest_result::broken && body_status) {
const optional< std::string >& reason = result.reason();
if (reason && reason.get() == invalid_output_message) {
result = googletest_result(
googletest_result::broken,
F("Error: Premature exit. Test case %s") %
format_status(body_status.get()));
}
}
} catch (const engine::format_error& error) {
if (body_status)
result = googletest_result(googletest_result::broken,
F("Error: %s. Test case %s") %
error.what() %
format_status(body_status.get()));
else {
// The test case timed out. apply() handles this case later.
}
} catch (const std::runtime_error& error) {
if (body_status)
result = googletest_result(
googletest_result::broken,
F("Error: Premature exit. Test case %s") %
format_status(body_status.get()));
else {
// The test case timed out. apply() handles this case later.
}
}
result = result.apply(body_status);
return result.externalize();
}
+111
View File
@@ -0,0 +1,111 @@
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// \file engine/googletest_result.hpp
/// Functions and types to process the results of googletest-based test cases.
#if !defined(ENGINE_GOOGLETEST_RESULT_HPP)
#define ENGINE_GOOGLETEST_RESULT_HPP
#include "engine/googletest_result_fwd.hpp"
#include <istream>
#include <ostream>
#include "model/test_result_fwd.hpp"
#include "utils/optional.hpp"
#include "utils/fs/path_fwd.hpp"
#include "utils/process/status_fwd.hpp"
namespace engine {
/// Internal representation of the raw result files of googletest-based tests.
///
/// This class is used exclusively to represent the transient result files read
/// from test cases before generating the "public" version of the result. This
/// class should actually not be exposed in the header files, but it is for
/// testing purposes only.
class googletest_result {
public:
/// List of possible types for the test case result.
enum types {
broken,
disabled,
failed,
skipped,
successful,
};
private:
/// The test case result.
types _type;
/// A description of the test case result.
///
/// Should always be present except for the passed type and sometimes with
/// the skipped type.
utils::optional< std::string > _reason;
public:
googletest_result(const types);
googletest_result(const types, const std::string&);
static googletest_result parse(std::istream&);
static googletest_result load(const utils::fs::path&);
types type(void) const;
const utils::optional< std::string >& reason(void) const;
bool good(void) const;
googletest_result apply(
const utils::optional< utils::process::status >&) const;
model::test_result externalize(void) const;
bool operator==(const googletest_result&) const;
bool operator!=(const googletest_result&) const;
};
std::ostream& operator<<(std::ostream&, const googletest_result&);
model::test_result calculate_googletest_result(
const utils::optional< utils::process::status >&,
const utils::fs::path&);
/// A bogus identifier for nul reasons provided by the test writer.
///
/// TODO: Support nul messages with skipped results in the schema, etc.
const std::string bogus_googletest_skipped_nul_message = "\n";
} // namespace engine
#endif // !defined(ENGINE_GOOGLETEST_RESULT_HPP)
@@ -0,0 +1,43 @@
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// \file engine/googletest_result_fwd.hpp
/// Forward declarations for engine/googletest_result.hpp
#if !defined(ENGINE_GOOGLETEST_RESULT_FWD_HPP)
#define ENGINE_GOOGLETEST_RESULT_FWD_HPP
namespace engine {
class googletest_result;
} // namespace engine
#endif // !defined(ENGINE_GOOGLETEST_RESULT_FWD_HPP)
@@ -0,0 +1,427 @@
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "engine/googletest_result.hpp"
extern "C" {
#include <signal.h>
}
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <atf-c++.hpp>
#include "engine/exceptions.hpp"
#include "model/test_result.hpp"
#include "utils/format/macros.hpp"
#include "utils/fs/path.hpp"
#include "utils/process/status.hpp"
namespace fs = utils::fs;
namespace process = utils::process;
using utils::none;
using utils::optional;
namespace {
/// Performs a test for results::parse() that should succeed.
///
/// \param exp_type The expected type of the result.
/// \param exp_reason The expected reason describing the result, if any.
/// \param text The literal input to parse; can include multiple lines.
static void
parse_ok_test(const engine::googletest_result::types& exp_type,
const char* exp_reason, const char* text)
{
std::istringstream input(text);
const engine::googletest_result actual =
engine::googletest_result::parse(input);
ATF_REQUIRE_EQ(exp_type, actual.type());
if (exp_reason != NULL) {
ATF_REQUIRE(actual.reason());
ATF_REQUIRE_EQ(exp_reason, actual.reason().get());
} else {
ATF_REQUIRE(!actual.reason());
}
}
/// Wrapper around parse_ok_test to define a test case.
///
/// \param name The name of the test case; will be prefixed with
/// "googletest_result__parse__".
/// \param exp_type The expected type of the result.
/// \param exp_reason The expected reason describing the result, if any.
/// \param input The literal input to parse.
#define PARSE(name, exp_type, exp_reason, input) \
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__parse__ ## name); \
ATF_TEST_CASE_BODY(googletest_result__parse__ ## name) \
{ \
parse_ok_test(exp_type, exp_reason, input); \
}
} // anonymous namespace
PARSE(broken,
engine::googletest_result::broken, "invalid output",
"invalid input");
const char disabled_context[] = (
"YOU HAVE 1 DISABLED TEST"
);
const char disabled_message[] = (
"[==========] Running 0 tests from 0 test cases.\n"
"[==========] 0 tests from 0 test cases ran. (0 ms total)\n"
"[ PASSED ] 0 tests.\n"
"\n"
" YOU HAVE 1 DISABLED TEST\n"
"\n"
"\n"
);
PARSE(disabled,
engine::googletest_result::disabled, disabled_context,
disabled_message);
const char failed_context[] = (
"pass_fail_demo.cc:8: Failure\n"
"Expected equality of these values:\n"
" false\n"
" true\n"
);
const char failed_message[] = (
"Note: Google Test filter = PassFailTest.Fails\n"
"[==========] Running 1 test from 1 test case.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from PassFailTest\n"
"[ RUN ] PassFailTest.Fails\n"
"pass_fail_demo.cc:8: Failure\n"
"Expected equality of these values:\n"
" false\n"
" true\n"
"[ FAILED ] PassFailTest.Fails (0 ms)\n"
"[----------] 1 test from PassFailTest (0 ms total)\n"
"\n"
"[----------] Global test environment tear-down\n"
"[==========] 1 test from 1 test case ran. (0 ms total)\n"
"[ PASSED ] 0 tests.\n"
"[ FAILED ] 1 test, listed below:\n"
"[ FAILED ] PassFailTest.Fails\n"
"\n"
" 1 FAILED TEST\n"
);
PARSE(failed,
engine::googletest_result::failed, failed_context,
failed_message);
const char skipped_message[] = (
"Note: Google Test filter = SkipTest.DoesSkip\n"
"[==========] Running 1 test from 1 test suite.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from SkipTest\n"
"[ RUN ] SkipTest.DoesSkip\n"
"[ SKIPPED ] SkipTest.DoesSkip (0 ms)\n"
"[----------] 1 test from SkipTest (0 ms total)\n"
"\n"
"[----------] Global test environment tear-down\n"
"[==========] 1 test from 1 test suite ran. (0 ms total)\n"
"[ PASSED ] 0 tests.\n"
"[ SKIPPED ] 1 test, listed below:\n"
"[ SKIPPED ] SkipTest.DoesSkip\n"
);
PARSE(skipped,
engine::googletest_result::skipped,
engine::bogus_googletest_skipped_nul_message.c_str(),
skipped_message
);
const char skipped_with_reason_context[] = (
"This is a reason\n"
);
const char skipped_with_reason_message[] = (
"Note: Google Test filter = SkipTest.SkipWithReason\n"
"[==========] Running 1 test from 1 test suite.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from SkipTest\n"
"[ RUN ] SkipTest.SkipWithReason\n"
"This is a reason\n"
"[ SKIPPED ] SkipTest.SkipWithReason (0 ms)\n"
"[----------] 1 test from SkipTest (0 ms total)\n"
"\n"
"[----------] Global test environment tear-down\n"
"[==========] 1 test from 1 test suite ran. (0 ms total)\n"
"[ PASSED ] 0 tests.\n"
"[ SKIPPED ] 1 test, listed below:\n"
"[ SKIPPED ] SkipTest.SkipWithReason\n"
);
PARSE(skipped_with_reason,
engine::googletest_result::skipped, skipped_with_reason_context,
skipped_with_reason_message);
const char successful_message[] = (
"Note: Google Test filter = PassFailTest.Passes\n"
"[==========] Running 1 test from 1 test case.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from PassFailTest\n"
"[ RUN ] PassFailTest.Passes\n"
"[ OK ] PassFailTest.Passes (0 ms)\n"
"[----------] 1 test from PassFailTest (0 ms total)\n"
"\n"
"[----------] Global test environment tear-down\n"
"[==========] 1 test from 1 test case ran. (0 ms total)\n"
"[ PASSED ] 1 test.\n"
);
PARSE(successful,
engine::googletest_result::successful, NULL,
successful_message);
const char successful_message2[] = (
"Note: Google Test filter = ValuesTest.ValuesWorks\n"
"[==========] Running 1 test from 1 test case.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from ValuesTest\n"
"[ RUN ] ValuesTest.ValuesWorks\n"
"[ OK ] ValuesTest.ValuesWorks (0 ms)\n"
"[----------] 1 test from ValuesTest (0 ms total)\n"
" \n"
"[----------] Global test environment tear-down\n"
"[==========] 1 test from 1 test case ran. (0 ms total)\n"
"[ PASSED ] 1 test.\n"
);
PARSE(successful2,
engine::googletest_result::successful, NULL,
successful_message2);
const char successful_parameterized_message[] = (
"Note: Google Test filter = RangeZeroToFive/ParamDerivedTest/0\n"
"[==========] Running 5 tests from 1 test case.\n"
"[----------] Global test environment set-up.\n"
"[----------] 5 tests from RangeZeroToFive/ParamDerivedTest\n"
"[ RUN ] RangeZeroToFive/ParamDerivedTest.SeesSequence/0\n"
"[ OK ] RangeZeroToFive/ParamDerivedTest.SeesSequence/0 (0 ms)\n"
"[----------] 1 test from RangeZeroToFive/ParamDerivedTest/0 (0 ms total)\n"
"\n"
"[----------] Global test environment tear-down\n"
"[==========] 1 tests from 1 test case ran. (0 ms total)\n"
"[ PASSED ] 1 tests.\n"
);
PARSE(successful_parameterized,
engine::googletest_result::successful, NULL,
successful_parameterized_message);
const char successful_message_with_reason[] = (
"Note: Google Test filter = PassFailTest.PassesWithReason\n"
"[==========] Running 1 test from 1 test suite.\n"
"[----------] Global test environment set-up.\n"
"[----------] 1 test from PassFailTest\n"
"[ RUN ] PassFailTest.PassesWithReason\n"
"This is a reason\n"
"[ OK ] PassFailTest.PassesWithReason (0 ms)\n"
"[----------] 1 test from PassFailTest (0 ms total)\n"
"\n"
"[----------] Global test environment tear-down\n"
"[==========] 1 test from 1 test suite ran. (0 ms total)\n"
"[ PASSED ] 1 tests.\n"
);
PARSE(successful_with_reason,
engine::googletest_result::successful, NULL,
successful_message_with_reason);
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__load__ok);
ATF_TEST_CASE_BODY(googletest_result__load__ok)
{
std::ofstream output("result.txt");
ATF_REQUIRE(output);
output << skipped_with_reason_message;
output.close();
const engine::googletest_result result = engine::googletest_result::load(
utils::fs::path("result.txt"));
ATF_REQUIRE_EQ(engine::googletest_result::skipped, result.type());
ATF_REQUIRE(result.reason());
ATF_REQUIRE_EQ(skipped_with_reason_context, result.reason().get());
}
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__load__missing_file);
ATF_TEST_CASE_BODY(googletest_result__load__missing_file)
{
ATF_REQUIRE_THROW_RE(
std::runtime_error, "Cannot open",
engine::googletest_result::load(utils::fs::path("result.txt")));
}
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__apply__broken);
ATF_TEST_CASE_BODY(googletest_result__apply__broken)
{
const process::status status = process::status::fake_exited(EXIT_FAILURE);
const engine::googletest_result broken(engine::googletest_result::broken,
"The reason");
ATF_REQUIRE_EQ(broken, broken.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__apply__disabled);
ATF_TEST_CASE_BODY(googletest_result__apply__disabled)
{
const process::status status = process::status::fake_exited(EXIT_SUCCESS);
const engine::googletest_result disabled(
engine::googletest_result::disabled, "The reason");
ATF_REQUIRE_EQ(disabled, disabled.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__apply__failed);
ATF_TEST_CASE_BODY(googletest_result__apply__failed)
{
const process::status status = process::status::fake_exited(EXIT_FAILURE);
const engine::googletest_result failed(engine::googletest_result::failed,
"The reason");
ATF_REQUIRE_EQ(failed, failed.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__apply__skipped);
ATF_TEST_CASE_BODY(googletest_result__apply__skipped)
{
const process::status status = process::status::fake_exited(EXIT_SUCCESS);
const engine::googletest_result skipped(engine::googletest_result::skipped,
"The reason");
ATF_REQUIRE_EQ(skipped, skipped.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__apply__successful);
ATF_TEST_CASE_BODY(googletest_result__apply__successful)
{
const process::status status = process::status::fake_exited(EXIT_SUCCESS);
const engine::googletest_result
successful(engine::googletest_result::successful);
ATF_REQUIRE_EQ(successful, successful.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__externalize__broken);
ATF_TEST_CASE_BODY(googletest_result__externalize__broken)
{
const engine::googletest_result raw(engine::googletest_result::broken,
"The reason");
const model::test_result expected(model::test_result_broken,
"The reason");
ATF_REQUIRE(expected == raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__externalize__disabled);
ATF_TEST_CASE_BODY(googletest_result__externalize__disabled)
{
const engine::googletest_result raw(engine::googletest_result::disabled,
"The reason");
const model::test_result expected(model::test_result_skipped,
"The reason");
ATF_REQUIRE(expected == raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__externalize__failed);
ATF_TEST_CASE_BODY(googletest_result__externalize__failed)
{
const engine::googletest_result raw(engine::googletest_result::failed,
"The reason");
const model::test_result expected(model::test_result_failed,
"The reason");
ATF_REQUIRE(expected == raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__externalize__skipped);
ATF_TEST_CASE_BODY(googletest_result__externalize__skipped)
{
const engine::googletest_result raw(engine::googletest_result::skipped,
"The reason");
const model::test_result expected(model::test_result_skipped,
"The reason");
ATF_REQUIRE(expected == raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(googletest_result__externalize__successful);
ATF_TEST_CASE_BODY(googletest_result__externalize__successful)
{
const engine::googletest_result raw(engine::googletest_result::successful);
const model::test_result expected(model::test_result_passed);
ATF_REQUIRE_EQ(expected, raw.externalize());
}
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, googletest_result__parse__broken);
ATF_ADD_TEST_CASE(tcs, googletest_result__parse__disabled);
ATF_ADD_TEST_CASE(tcs, googletest_result__parse__failed);
ATF_ADD_TEST_CASE(tcs, googletest_result__parse__skipped);
ATF_ADD_TEST_CASE(tcs, googletest_result__parse__skipped_with_reason);
ATF_ADD_TEST_CASE(tcs, googletest_result__parse__successful);
ATF_ADD_TEST_CASE(tcs, googletest_result__parse__successful2);
ATF_ADD_TEST_CASE(tcs, googletest_result__parse__successful_parameterized);
ATF_ADD_TEST_CASE(tcs, googletest_result__parse__successful_with_reason);
ATF_ADD_TEST_CASE(tcs, googletest_result__load__ok);
ATF_ADD_TEST_CASE(tcs, googletest_result__load__missing_file);
ATF_ADD_TEST_CASE(tcs, googletest_result__apply__broken);
ATF_ADD_TEST_CASE(tcs, googletest_result__apply__disabled);
ATF_ADD_TEST_CASE(tcs, googletest_result__apply__failed);
ATF_ADD_TEST_CASE(tcs, googletest_result__apply__skipped);
ATF_ADD_TEST_CASE(tcs, googletest_result__apply__successful);
ATF_ADD_TEST_CASE(tcs, googletest_result__externalize__broken);
ATF_ADD_TEST_CASE(tcs, googletest_result__externalize__disabled);
ATF_ADD_TEST_CASE(tcs, googletest_result__externalize__failed);
ATF_ADD_TEST_CASE(tcs, googletest_result__externalize__skipped);
ATF_ADD_TEST_CASE(tcs, googletest_result__externalize__successful);
}
+361
View File
@@ -0,0 +1,361 @@
// Copyright 2024 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "engine/googletest.hpp"
extern "C" {
#include <sys/stat.h>
#include <signal.h>
}
#include <atf-c++.hpp>
#include "engine/config.hpp"
#include "engine/scheduler.hpp"
#include "model/metadata.hpp"
#include "model/test_case.hpp"
#include "model/test_program_fwd.hpp"
#include "model/test_result.hpp"
#include "utils/config/tree.ipp"
#include "utils/datetime.hpp"
#include "utils/env.hpp"
#include "utils/format/containers.ipp"
#include "utils/format/macros.hpp"
#include "utils/fs/operations.hpp"
#include "utils/fs/path.hpp"
#include "utils/optional.ipp"
#include "utils/stacktrace.hpp"
#include "utils/test_utils.ipp"
namespace config = utils::config;
namespace datetime = utils::datetime;
namespace fs = utils::fs;
namespace scheduler = engine::scheduler;
using utils::none;
namespace {
/// Prefix for all testcases.
const std::string test_suite = "Suite.";
/// Runs one googletest test program and checks its result.
///
/// \param program_name Basename of the test program to run.
/// \param root Path to the base of the test suite.
/// \param user_config User-provided configuration.
///
/// \return The list of loaded test cases.
static model::test_cases_map
list(const char* program_name,
const fs::path& root,
config::tree user_config = engine::empty_config())
{
scheduler::scheduler_handle handle = scheduler::setup();
const scheduler::lazy_test_program program(
"googletest", fs::path(program_name), root, "the-suite",
model::metadata_builder().build(), user_config, handle);
const model::test_cases_map test_cases = handle.list_tests(
&program, user_config);
handle.cleanup();
return test_cases;
}
/// Runs a bogus test program and checks the error result.
///
/// \param exp_error Expected error string to find.
/// \param program_name Basename of the test program to run.
/// \param root Path to the base of the test suite.
static void
check_list_fail(const char* exp_error,
const char* program_name,
const fs::path& root)
{
const model::test_cases_map test_cases = list(
program_name, root);
ATF_REQUIRE_EQ(1, test_cases.size());
const model::test_case& test_case = test_cases.begin()->second;
ATF_REQUIRE_EQ("__test_cases_list__", test_case.name());
ATF_REQUIRE(test_case.fake_result());
ATF_REQUIRE_MATCH(exp_error,
test_case.fake_result().get().reason());
}
/// Runs one googletest test program and checks its result.
///
/// \param tc Pointer to the calling test case, to obtain srcdir.
/// \param test_case_name Name of the "test case" to select from the helper
/// program.
/// \param exp_result The expected result.
/// \param metadata The test case metadata.
/// \param user_config User-provided configuration.
static void
run_one(const atf::tests::tc* tc, const char* test_case_name,
const model::test_result& exp_result,
const model::metadata& metadata = model::metadata_builder().build(),
config::tree user_config = engine::empty_config())
{
scheduler::scheduler_handle handle = scheduler::setup();
const std::string test_name = test_suite + std::string(test_case_name);
const model::test_program_ptr program(new scheduler::lazy_test_program(
"googletest", fs::path("googletest_helpers"),
fs::path(tc->get_config_var("srcdir")),
"the-suite", metadata, user_config, handle));
(void)handle.spawn_test(program, test_name.c_str(), user_config);
scheduler::result_handle_ptr result_handle = handle.wait_any();
const scheduler::test_result_handle* test_result_handle =
dynamic_cast< const scheduler::test_result_handle* >(
result_handle.get());
atf::utils::cat_file(result_handle->stdout_file().str(), "stdout: ");
atf::utils::cat_file(result_handle->stderr_file().str(), "stderr: ");
ATF_REQUIRE_EQ(exp_result, test_result_handle->test_result());
result_handle->cleanup();
result_handle.reset();
handle.cleanup();
}
} // anonymous namespace
ATF_TEST_CASE_WITHOUT_HEAD(list__ok);
ATF_TEST_CASE_BODY(list__ok)
{
const model::test_cases_map test_cases = list(
"googletest_helpers", fs::path(get_config_var("srcdir")));
const model::test_cases_map exp_test_cases = model::test_cases_map_builder()
.add(test_suite + "check_configuration_variables")
.add(test_suite + "crash")
.add(test_suite + "fail")
.add(test_suite + "pass")
.add(test_suite + "pass_but_exit_failure")
.add(test_suite + "timeout", model::metadata_builder()
.build())
.build();
ATF_REQUIRE_EQ(exp_test_cases, test_cases);
}
ATF_TEST_CASE_WITHOUT_HEAD(list__current_directory);
ATF_TEST_CASE_BODY(list__current_directory)
{
const fs::path helpers =
fs::path(get_config_var("srcdir")) / "googletest_helpers";
ATF_REQUIRE(::symlink(helpers.c_str(), "googletest_helpers") != -1);
const model::test_cases_map test_cases = list(
"googletest_helpers", fs::path("."));
const model::test_cases_map exp_test_cases = model::test_cases_map_builder()
.add(test_suite + "check_configuration_variables")
.add(test_suite + "crash")
.add(test_suite + "fail")
.add(test_suite + "pass")
.add(test_suite + "pass_but_exit_failure")
.add(test_suite + "timeout", model::metadata_builder()
.build())
.build();
ATF_REQUIRE_EQ(exp_test_cases, test_cases);
}
ATF_TEST_CASE_WITHOUT_HEAD(list__relative_path);
ATF_TEST_CASE_BODY(list__relative_path)
{
const fs::path helpers =
fs::path(get_config_var("srcdir")) / "googletest_helpers";
ATF_REQUIRE(::mkdir("dir1", 0755) != -1);
ATF_REQUIRE(::mkdir("dir1/dir2", 0755) != -1);
ATF_REQUIRE_EQ(::symlink(helpers.c_str(),
"dir1/dir2/googletest_helpers"), 0);
const model::test_cases_map test_cases = list(
"dir2/googletest_helpers", fs::path("dir1"));
const model::test_cases_map exp_test_cases = model::test_cases_map_builder()
.add(test_suite + "check_configuration_variables")
.add(test_suite + "crash")
.add(test_suite + "fail")
.add(test_suite + "pass")
.add(test_suite + "pass_but_exit_failure")
.add(test_suite + "timeout", model::metadata_builder()
.build())
.build();
ATF_REQUIRE_EQ(exp_test_cases, test_cases);
}
ATF_TEST_CASE_WITHOUT_HEAD(list__missing_test_program);
ATF_TEST_CASE_BODY(list__missing_test_program)
{
check_list_fail("Cannot find test program", "non-existent",
fs::current_path());
}
ATF_TEST_CASE_WITHOUT_HEAD(list__not_a_test_program);
ATF_TEST_CASE_BODY(list__not_a_test_program)
{
atf::utils::create_file("not-valid", "garbage\n");
ATF_REQUIRE_EQ(::chmod("not-valid", 0755), 0);
check_list_fail("Invalid test program format", "not-valid",
fs::current_path());
}
ATF_TEST_CASE_WITHOUT_HEAD(list__no_permissions);
ATF_TEST_CASE_BODY(list__no_permissions)
{
atf::utils::create_file("not-executable", "garbage\n");
check_list_fail("Permission denied to run test program",
"not-executable", fs::current_path());
}
ATF_TEST_CASE_WITHOUT_HEAD(list__abort);
ATF_TEST_CASE_BODY(list__abort)
{
atf::utils::create_file("kills_self", "#!/bin/sh\nkill -2 $$\n");
ATF_REQUIRE_EQ(::chmod("kills_self", 0755), 0);
check_list_fail("Test program received signal", "kills_self",
fs::current_path());
}
ATF_TEST_CASE_WITHOUT_HEAD(list__empty);
ATF_TEST_CASE_BODY(list__empty)
{
atf::utils::create_file("empty_list", "#!/bin/sh\n");
ATF_REQUIRE_EQ(::chmod("empty_list", 0755), 0);
check_list_fail("No test cases", "empty_list", fs::current_path());
}
ATF_TEST_CASE_WITHOUT_HEAD(test__body_only__passes);
ATF_TEST_CASE_BODY(test__body_only__passes)
{
const model::test_result exp_result(model::test_result_passed);
run_one(this, "pass", exp_result);
}
ATF_TEST_CASE_WITHOUT_HEAD(test__body_only__fails);
ATF_TEST_CASE_BODY(test__body_only__fails)
{
const std::string failure_message = (
"gtest_macros_demo.cc:4: Failure\n"
"Failed\n"
"with a reason\n"
);
const model::test_result exp_result(model::test_result_failed,
failure_message);
run_one(this, "fail", exp_result);
}
ATF_TEST_CASE_WITHOUT_HEAD(test__body_only__crashes);
ATF_TEST_CASE_BODY(test__body_only__crashes)
{
utils::prepare_coredump_test(this);
const model::test_result exp_result(
model::test_result_broken,
F("Error: Premature exit. Test case received signal %s (core dumped)") %
SIGABRT);
run_one(this, "crash", exp_result);
}
ATF_TEST_CASE(test__body_only__times_out);
ATF_TEST_CASE_HEAD(test__body_only__times_out)
{
set_md_var("timeout", "60");
}
ATF_TEST_CASE_BODY(test__body_only__times_out)
{
config::tree user_config = engine::empty_config();
utils::setenv("CONTROL_DIR", fs::current_path().str());
const model::metadata metadata = model::metadata_builder()
.set_timeout(datetime::delta(1, 0)).build();
const model::test_result exp_result(
model::test_result_broken, "Test case body timed out");
run_one(this, "timeout", exp_result, metadata, user_config);
ATF_REQUIRE(!atf::utils::file_exists("cookie"));
}
ATF_TEST_CASE_WITHOUT_HEAD(test__body_only__configuration_variables);
ATF_TEST_CASE_BODY(test__body_only__configuration_variables)
{
config::tree user_config = engine::empty_config();
user_config.set_string("test_suites.the-suite.first", "some value");
user_config.set_string("test_suites.the-suite.second", "some other value");
const model::test_result exp_result(model::test_result_passed);
run_one(this, "check_configuration_variables", exp_result,
model::metadata_builder().build(), user_config);
}
ATF_INIT_TEST_CASES(tcs)
{
scheduler::register_interface(
"googletest", std::shared_ptr< scheduler::interface >(
new engine::googletest_interface()));
ATF_ADD_TEST_CASE(tcs, list__ok);
ATF_ADD_TEST_CASE(tcs, list__current_directory);
ATF_ADD_TEST_CASE(tcs, list__relative_path);
ATF_ADD_TEST_CASE(tcs, list__missing_test_program);
ATF_ADD_TEST_CASE(tcs, list__not_a_test_program);
ATF_ADD_TEST_CASE(tcs, list__no_permissions);
ATF_ADD_TEST_CASE(tcs, list__abort);
ATF_ADD_TEST_CASE(tcs, list__empty);
ATF_ADD_TEST_CASE(tcs, test__body_only__passes);
ATF_ADD_TEST_CASE(tcs, test__body_only__fails);
ATF_ADD_TEST_CASE(tcs, test__body_only__crashes);
ATF_ADD_TEST_CASE(tcs, test__body_only__times_out);
ATF_ADD_TEST_CASE(tcs, test__body_only__configuration_variables);
}
-5
View File
@@ -34,11 +34,6 @@
#include "engine/kyuafile_fwd.hpp"
#include <string>
#include <vector>
#include <lutok/state.hpp>
#include "engine/scheduler_fwd.hpp"
#include "model/test_program_fwd.hpp"
#include "utils/config/tree_fwd.hpp"
+1 -9
View File
@@ -27,19 +27,11 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "engine/kyuafile.hpp"
#include <memory>
extern "C" {
#include <unistd.h>
}
#include <stdexcept>
#include <typeinfo>
#include <atf-c++.hpp>
#include <lutok/operations.hpp>
#include <lutok/state.ipp>
#include <lutok/test_utils.hpp>
#include "engine/atf.hpp"
#include "engine/exceptions.hpp"
#include "engine/plain.hpp"
+7 -6
View File
@@ -40,18 +40,19 @@ namespace engine {
/// Implementation of the scheduler interface for plain test programs.
class plain_interface : public engine::scheduler::interface {
public:
void exec_list(const model::test_program&,
const utils::config::properties_map&) const UTILS_NORETURN;
void exec_list [[noreturn]] (
const model::test_program&,
const utils::config::properties_map&) const;
model::test_cases_map parse_list(
const utils::optional< utils::process::status >&,
const utils::fs::path&,
const utils::fs::path&) const;
void exec_test(const model::test_program&, const std::string&,
const utils::config::properties_map&,
const utils::fs::path&) const
UTILS_NORETURN;
void exec_test [[noreturn]] (
const model::test_program&, const std::string&,
const utils::config::properties_map&,
const utils::fs::path&) const;
model::test_result compute_result(
const utils::optional< utils::process::status >&,
+2 -2
View File
@@ -112,7 +112,7 @@ check_execenv(const std::string& execenv, const config::tree& user_config)
{
std::string name = execenv;
if (name.empty())
name = engine::execenv::default_execenv_name; // if test claims nothing
name = DEFAULT_EXECENV_NAME; // if test claims nothing
std::set< std::string > execenvs;
try {
@@ -274,7 +274,7 @@ static std::vector< std::shared_ptr< engine::reqs_checker > > _reqs_checkers;
} // anonymous namespace
const std::vector< std::shared_ptr< engine::reqs_checker > >
std::vector< std::shared_ptr< engine::reqs_checker > >
engine::reqs_checkers()
{
return _reqs_checkers;
+3 -1
View File
@@ -32,7 +32,9 @@
#if !defined(ENGINE_REQUIREMENTS_HPP)
#define ENGINE_REQUIREMENTS_HPP
#include <memory>
#include <string>
#include <vector>
#include "model/metadata_fwd.hpp"
#include "utils/config/tree_fwd.hpp"
@@ -68,7 +70,7 @@ void register_reqs_checker(const std::shared_ptr< reqs_checker > checker);
/// Returns the list of registered extra requirement checkers.
///
/// \return A vector of pointers to extra requirement checkers.
const std::vector< std::shared_ptr< reqs_checker > > reqs_checkers();
std::vector< std::shared_ptr< reqs_checker > > reqs_checkers();
} // namespace engine
+2 -2
View File
@@ -1653,8 +1653,8 @@ scheduler::generate_config(const config::tree& user_config,
if (user_config.is_set("unprivileged_user")) {
const passwd::user& user =
user_config.lookup< engine::user_node >("unprivileged_user");
// The property is duplicated using both ATF and Kyua naming styles
// for better UX.
// The property is duplicated using both ATF and Kyua naming styles
// for better UX.
props["unprivileged-user"] = user.name;
props["unprivileged_user"] = user.name;
}
+13 -13
View File
@@ -98,9 +98,9 @@ public:
///
/// \param test_program The test program to execute.
/// \param vars User-provided variables to pass to the test program.
virtual void exec_list(const model::test_program& test_program,
const utils::config::properties_map& vars)
const UTILS_NORETURN = 0;
virtual void exec_list [[noreturn]] (
const model::test_program& test_program,
const utils::config::properties_map& vars) const = 0;
/// Computes the test cases list of a test program.
///
@@ -126,11 +126,11 @@ public:
/// \param vars User-provided variables to pass to the test program.
/// \param control_directory Directory where the interface may place control
/// files.
virtual void exec_test(const model::test_program& test_program,
const std::string& test_case_name,
const utils::config::properties_map& vars,
const utils::fs::path& control_directory)
const UTILS_NORETURN = 0;
virtual void exec_test [[noreturn]] (
const model::test_program& test_program,
const std::string& test_case_name,
const utils::config::properties_map& vars,
const utils::fs::path& control_directory) const = 0;
/// Executes a test cleanup routine of the test program.
///
@@ -143,11 +143,11 @@ public:
/// \param vars User-provided variables to pass to the test program.
/// \param control_directory Directory where the interface may place control
/// files.
virtual void exec_cleanup(const model::test_program& test_program,
const std::string& test_case_name,
const utils::config::properties_map& vars,
const utils::fs::path& control_directory)
const UTILS_NORETURN;
virtual void exec_cleanup [[noreturn]](
const model::test_program& test_program,
const std::string& test_case_name,
const utils::config::properties_map& vars,
const utils::fs::path& control_directory) const;
/// Computes the result of a test case based on its termination status.
///
+12 -12
View File
@@ -131,7 +131,7 @@ class mock_interface : public scheduler::interface {
///
/// \param exit_code Exit code.
void
do_exit(const int exit_code) const UTILS_NORETURN
do_exit [[noreturn]] (const int exit_code) const
{
std::cout.flush();
std::cerr.flush();
@@ -140,7 +140,7 @@ class mock_interface : public scheduler::interface {
/// Executes a test case that creates various files and then fails.
void
exec_create_files_and_fail(void) const UTILS_NORETURN
exec_create_files_and_fail [[noreturn]] (void) const
{
std::cerr << "This should not be clobbered\n";
atf::utils::create_file("first file", "");
@@ -155,7 +155,7 @@ class mock_interface : public scheduler::interface {
/// This is intended to validate that the test runs in an empty directory,
/// separate from any control files that the scheduler may have created.
void
exec_delete_all(void) const UTILS_NORETURN
exec_delete_all [[noreturn]] (void) const
{
const int exit_code = ::system("rm *") == -1
? EXIT_FAILURE : EXIT_SUCCESS;
@@ -170,14 +170,14 @@ class mock_interface : public scheduler::interface {
///
/// \param exit_code Exit status to terminate the program with.
void
exec_exit(const int exit_code) const UTILS_NORETURN
exec_exit [[noreturn]] (const int exit_code) const
{
do_exit(exit_code);
}
/// Executes a test case that just fails.
void
exec_fail(void) const UTILS_NORETURN
exec_fail [[noreturn]] (void) const
{
std::cerr << "This should not be clobbered\n";
::kill(::getpid(), SIGTERM);
@@ -191,10 +191,10 @@ class mock_interface : public scheduler::interface {
/// number.
/// \param vars User-provided variables to pass to the test program.
void
exec_print_params(const model::test_program& test_program,
const std::string& test_case_name,
const config::properties_map& vars) const
UTILS_NORETURN
exec_print_params [[noreturn]] (
const model::test_program& test_program,
const std::string& test_case_name,
const config::properties_map& vars) const
{
std::cout << F("Test program: %s\n") % test_program.relative_path();
std::cout << F("Test case: %s\n") % test_case_name;
@@ -218,9 +218,9 @@ public:
/// \param test_program The test program to execute.
/// \param vars User-provided variables to pass to the test program.
void
exec_list(const model::test_program& test_program,
const config::properties_map& vars)
const UTILS_NORETURN
exec_list [[noreturn]] (
const model::test_program& test_program,
const config::properties_map& vars) const
{
const std::string name = test_program.absolute_path().leaf_name();
+7 -6
View File
@@ -40,18 +40,19 @@ namespace engine {
/// Implementation of the scheduler interface for tap test programs.
class tap_interface : public engine::scheduler::interface {
public:
void exec_list(const model::test_program&,
const utils::config::properties_map&) const UTILS_NORETURN;
void exec_list [[noreturn]] (
const model::test_program&,
const utils::config::properties_map&) const;
model::test_cases_map parse_list(
const utils::optional< utils::process::status >&,
const utils::fs::path&,
const utils::fs::path&) const;
void exec_test(const model::test_program&, const std::string&,
const utils::config::properties_map&,
const utils::fs::path&) const
UTILS_NORETURN;
void exec_test [[noreturn]] (
const model::test_program&, const std::string&,
const utils::config::properties_map&,
const utils::fs::path&) const;
model::test_result compute_result(
const utils::optional< utils::process::status >&,
-45
View File
@@ -1,45 +0,0 @@
# Copyright 2011 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dist_examples_DATA = examples/Kyuafile.top
dist_examples_DATA += examples/kyua.conf
if WITH_ATF
tests_examplesdir = $(pkgtestsdir)/examples
tests_examples_DATA = examples/Kyuafile
EXTRA_DIST += $(tests_examples_DATA)
tests_examples_PROGRAMS = examples/syntax_test
examples_syntax_test_SOURCES = examples/syntax_test.cpp
examples_syntax_test_CPPFLAGS = -DKYUA_EXAMPLESDIR="\"$(examplesdir)\""
examples_syntax_test_CXXFLAGS = $(ENGINE_CFLAGS) $(UTILS_CFLAGS) \
$(ATF_CXX_CFLAGS)
examples_syntax_test_LDADD = $(ENGINE_LIBS) $(UTILS_LIBS) \
$(ATF_CXX_LIBS)
endif
-150
View File
@@ -1,150 +0,0 @@
# Copyright 2011 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if WITH_ATF
tests_integrationdir = $(pkgtestsdir)/integration
tests_integration_DATA = integration/Kyuafile
EXTRA_DIST += $(tests_integration_DATA)
ATF_SH_BUILD = \
$(MKDIR_P) integration; \
echo "\#! $(ATF_SH)" >integration/$${name}; \
echo "\# AUTOMATICALLY GENERATED FROM Makefile" >>integration/$${name}; \
if [ -n "$${substs}" ]; then \
cat $(srcdir)/integration/utils.sh $(srcdir)/integration/$${name}.sh \
| sed "$${substs}" >>integration/$${name}; \
else \
cat $(srcdir)/integration/utils.sh $(srcdir)/integration/$${name}.sh \
>>integration/$${name}; \
fi; \
chmod +x integration/$${name}
ATF_SH_DEPS = \
$(srcdir)/integration/utils.sh \
Makefile
EXTRA_DIST += integration/utils.sh
tests_integration_SCRIPTS = integration/cmd_about_test
CLEANFILES += integration/cmd_about_test
EXTRA_DIST += integration/cmd_about_test.sh
integration/cmd_about_test: $(srcdir)/integration/cmd_about_test.sh \
$(ATF_SH_DEPS)
$(AM_V_GEN)name="cmd_about_test"; \
substs='s,__KYUA_DOCDIR__,$(docdir),g'; \
$(ATF_SH_BUILD)
tests_integration_SCRIPTS += integration/cmd_config_test
CLEANFILES += integration/cmd_config_test
EXTRA_DIST += integration/cmd_config_test.sh
integration/cmd_config_test: $(srcdir)/integration/cmd_config_test.sh \
$(ATF_SH_DEPS)
$(AM_V_GEN)name="cmd_config_test"; \
$(ATF_SH_BUILD)
tests_integration_SCRIPTS += integration/cmd_db_exec_test
CLEANFILES += integration/cmd_db_exec_test
EXTRA_DIST += integration/cmd_db_exec_test.sh
integration/cmd_db_exec_test: $(srcdir)/integration/cmd_db_exec_test.sh \
$(ATF_SH_DEPS)
$(AM_V_GEN)name="cmd_db_exec_test"; \
$(ATF_SH_BUILD)
tests_integration_SCRIPTS += integration/cmd_db_migrate_test
CLEANFILES += integration/cmd_db_migrate_test
EXTRA_DIST += integration/cmd_db_migrate_test.sh
integration/cmd_db_migrate_test: $(srcdir)/integration/cmd_db_migrate_test.sh \
$(ATF_SH_DEPS)
$(AM_V_GEN)name="cmd_db_migrate_test"; \
substs='s,__KYUA_STOREDIR__,$(storedir),g'; \
substs="$${substs};s,__KYUA_STORETESTDATADIR__,$(tests_storedir),g"; \
$(ATF_SH_BUILD)
tests_integration_SCRIPTS += integration/cmd_debug_test
CLEANFILES += integration/cmd_debug_test
EXTRA_DIST += integration/cmd_debug_test.sh
integration/cmd_debug_test: $(srcdir)/integration/cmd_debug_test.sh \
$(ATF_SH_DEPS)
$(AM_V_GEN)name="cmd_debug_test"; \
$(ATF_SH_BUILD)
tests_integration_SCRIPTS += integration/cmd_help_test
CLEANFILES += integration/cmd_help_test
EXTRA_DIST += integration/cmd_help_test.sh
integration/cmd_help_test: $(srcdir)/integration/cmd_help_test.sh $(ATF_SH_DEPS)
$(AM_V_GEN)name="cmd_help_test"; \
$(ATF_SH_BUILD)
tests_integration_SCRIPTS += integration/cmd_list_test
CLEANFILES += integration/cmd_list_test
EXTRA_DIST += integration/cmd_list_test.sh
integration/cmd_list_test: $(srcdir)/integration/cmd_list_test.sh $(ATF_SH_DEPS)
$(AM_V_GEN)name="cmd_list_test"; \
$(ATF_SH_BUILD)
tests_integration_SCRIPTS += integration/cmd_report_test
CLEANFILES += integration/cmd_report_test
EXTRA_DIST += integration/cmd_report_test.sh
integration/cmd_report_test: $(srcdir)/integration/cmd_report_test.sh \
$(ATF_SH_DEPS)
$(AM_V_GEN)name="cmd_report_test"; \
$(ATF_SH_BUILD)
tests_integration_SCRIPTS += integration/cmd_report_html_test
CLEANFILES += integration/cmd_report_html_test
EXTRA_DIST += integration/cmd_report_html_test.sh
integration/cmd_report_html_test: \
$(srcdir)/integration/cmd_report_html_test.sh $(ATF_SH_DEPS)
$(AM_V_GEN)name="cmd_report_html_test"; \
$(ATF_SH_BUILD)
tests_integration_SCRIPTS += integration/cmd_report_junit_test
CLEANFILES += integration/cmd_report_junit_test
EXTRA_DIST += integration/cmd_report_junit_test.sh
integration/cmd_report_junit_test: \
$(srcdir)/integration/cmd_report_junit_test.sh $(ATF_SH_DEPS)
$(AM_V_GEN)name="cmd_report_junit_test"; \
$(ATF_SH_BUILD)
tests_integration_SCRIPTS += integration/cmd_test_test
CLEANFILES += integration/cmd_test_test
EXTRA_DIST += integration/cmd_test_test.sh
integration/cmd_test_test: $(srcdir)/integration/cmd_test_test.sh $(ATF_SH_DEPS)
$(AM_V_GEN)name="cmd_test_test"; \
$(ATF_SH_BUILD)
tests_integration_SCRIPTS += integration/global_test
CLEANFILES += integration/global_test
EXTRA_DIST += integration/global_test.sh
integration/global_test: $(srcdir)/integration/global_test.sh $(ATF_SH_DEPS)
$(AM_V_GEN)name="global_test"; \
$(ATF_SH_BUILD)
endif
include integration/helpers/Makefile.am.inc
+1 -1
View File
@@ -119,7 +119,7 @@ topic__version_body() {
local lines="$(wc -l stdout | awk '{ print $1 }')"
[ "${lines}" -eq 1 ] || atf_fail "Version query returned more than one line"
grep -E '^kyua (.*) [0-9]+\.[0-9]+$' stdout || \
grep -E '^kyua (.*) [0-9]+\.[0-9]+(\.[0-9]+)?$' stdout || \
atf_fail "Invalid version message"
}
+1 -1
View File
@@ -217,7 +217,7 @@ verbose_body() {
# Switch to the current directory using its physical location and update
# HOME accordingly. Otherwise, the test below where we compare the value
# of HOME in the output might fail if the path to HOME contains a symlink
# (as is the case in OS X when HOME points to the temporary directory.)
# (as is the case in macOS when HOME points to the temporary directory.)
local real_cwd="$(pwd -P)"
cd "${real_cwd}"
HOME="${real_cwd}"
+2 -2
View File
@@ -224,8 +224,8 @@ EOF
# CHECK_STYLE_DISABLE
cat >expout <<EOF
bogus_test_cases:die -> broken: Premature exit; test case received signal 9 [S.UUUs]
bogus_test_cases:exit -> broken: Premature exit; test case exited with code 0 [S.UUUs]
bogus_test_cases:die -> broken: Error: Empty test result or no new line. Test case received signal 9 [S.UUUs]
bogus_test_cases:exit -> broken: Error: Empty test result or no new line. Test case exited with code 0 [S.UUUs]
bogus_test_cases:pass -> passed [S.UUUs]
Results file id is $(utils_results_id)
@@ -1,11 +0,0 @@
bad_test_program
bogus_test_cases
config
dump_env
expect_all_pass
expect_some_fail
interrupts
metadata
race
simple_all_pass
simple_some_fail
@@ -1,90 +0,0 @@
# Copyright 2011 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if WITH_ATF
tests_integration_helpersdir = $(pkgtestsdir)/integration/helpers
tests_integration_helpers_PROGRAMS = integration/helpers/bad_test_program
integration_helpers_bad_test_program_SOURCES = \
integration/helpers/bad_test_program.cpp
tests_integration_helpers_PROGRAMS += integration/helpers/bogus_test_cases
integration_helpers_bogus_test_cases_SOURCES = \
integration/helpers/bogus_test_cases.cpp
integration_helpers_bogus_test_cases_CXXFLAGS = $(ATF_CXX_CFLAGS)
integration_helpers_bogus_test_cases_LDADD = $(ATF_CXX_LIBS)
tests_integration_helpers_PROGRAMS += integration/helpers/config
integration_helpers_config_SOURCES = integration/helpers/config.cpp
integration_helpers_config_CXXFLAGS = $(ATF_CXX_CFLAGS)
integration_helpers_config_LDADD = $(ATF_CXX_LIBS)
tests_integration_helpers_PROGRAMS += integration/helpers/dump_env
integration_helpers_dump_env_SOURCES = integration/helpers/dump_env.cpp
integration_helpers_dump_env_CXXFLAGS = $(UTILS_CFLAGS)
integration_helpers_dump_env_LDADD = $(UTILS_LIBS)
tests_integration_helpers_PROGRAMS += integration/helpers/expect_all_pass
integration_helpers_expect_all_pass_SOURCES = \
integration/helpers/expect_all_pass.cpp
integration_helpers_expect_all_pass_CXXFLAGS = $(ATF_CXX_CFLAGS)
integration_helpers_expect_all_pass_LDADD = $(ATF_CXX_LIBS)
tests_integration_helpers_PROGRAMS += integration/helpers/expect_some_fail
integration_helpers_expect_some_fail_SOURCES = \
integration/helpers/expect_some_fail.cpp
integration_helpers_expect_some_fail_CXXFLAGS = $(ATF_CXX_CFLAGS)
integration_helpers_expect_some_fail_LDADD = $(ATF_CXX_LIBS)
tests_integration_helpers_PROGRAMS += integration/helpers/interrupts
integration_helpers_interrupts_SOURCES = integration/helpers/interrupts.cpp
integration_helpers_interrupts_CXXFLAGS = $(ATF_CXX_CFLAGS)
integration_helpers_interrupts_LDADD = $(ATF_CXX_LIBS)
tests_integration_helpers_PROGRAMS += integration/helpers/metadata
integration_helpers_metadata_SOURCES = integration/helpers/metadata.cpp
integration_helpers_metadata_CXXFLAGS = $(ATF_CXX_CFLAGS)
integration_helpers_metadata_LDADD = $(ATF_CXX_LIBS)
tests_integration_helpers_PROGRAMS += integration/helpers/race
integration_helpers_race_SOURCES = integration/helpers/race.cpp
integration_helpers_race_CXXFLAGS = $(UTILS_CFLAGS)
integration_helpers_race_LDADD = $(UTILS_LIBS)
tests_integration_helpers_PROGRAMS += integration/helpers/simple_all_pass
integration_helpers_simple_all_pass_SOURCES = \
integration/helpers/simple_all_pass.cpp
integration_helpers_simple_all_pass_CXXFLAGS = $(ATF_CXX_CFLAGS)
integration_helpers_simple_all_pass_LDADD = $(ATF_CXX_LIBS)
tests_integration_helpers_PROGRAMS += integration/helpers/simple_some_fail
integration_helpers_simple_some_fail_SOURCES = \
integration/helpers/simple_some_fail.cpp
integration_helpers_simple_some_fail_CXXFLAGS = $(ATF_CXX_CFLAGS)
integration_helpers_simple_some_fail_LDADD = $(ATF_CXX_LIBS)
endif
+20 -14
View File
@@ -106,19 +106,22 @@ utils_cp_helper() {
# Kyua with the deterministic strings. This is to be used by tests that
# validate the 'test' and 'report' subcommands.
utils_install_times_wrapper() {
[ ! -x kyua ] || return
cat >kyua <<EOF
local DUMMY_KYUA_BINDIR=$(pwd)
local DUMMY_KYUA_BIN="$DUMMY_KYUA_BINDIR/kyua"
[ ! -x "$DUMMY_KYUA_BIN" ] || return
local ORIG_KYUA_BIN=$(which kyua)
cat >"$DUMMY_KYUA_BIN" <<EOF
#! /bin/sh
PATH=${PATH}
kyua "\${@}" >kyua.tmpout
$ORIG_KYUA_BIN "\${@}" >kyua.tmpout
result=\${?}
cat kyua.tmpout | ${utils_strip_times}
exit \${result}
EOF
chmod +x kyua
PATH="$(pwd):${PATH}"
chmod +x "$DUMMY_KYUA_BIN"
export PATH="$DUMMY_KYUA_BINDIR:${PATH}"
}
@@ -130,13 +133,16 @@ EOF
# execution so that the output can be verified. For these reasons, this is to
# be used exclusively by tests that validate the 'test' subcommand.
utils_install_stable_test_wrapper() {
[ ! -x kyua ] || return
cat >kyua <<EOF
local DUMMY_KYUA_BINDIR=$(pwd)
local DUMMY_KYUA_BIN="$DUMMY_KYUA_BINDIR/kyua"
[ ! -x "$DUMMY_KYUA_BIN" ] || return
local ORIG_KYUA_BIN=$(which kyua)
cat >"$DUMMY_KYUA_BIN" <<EOF
#! /bin/sh
PATH=${PATH}
kyua "\${@}" >kyua.tmpout
$ORIG_KYUA_BIN "\${@}" >kyua.tmpout
result=\${?}
cat kyua.tmpout | ${utils_strip_times} >kyua.tmpout2
@@ -147,8 +153,8 @@ cat kyua.tmpout3 kyua.tmpout4
exit \${result}
EOF
chmod +x kyua
PATH="$(pwd):${PATH}"
chmod +x "$DUMMY_KYUA_BIN"
export PATH="$DUMMY_KYUA_BINDIR:${PATH}"
}
-951
View File
@@ -1,951 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the specified
# version of the C++ standard. If necessary, add switches to CXX and
# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
# or '14' (for the C++14 standard).
#
# The second argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The third argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline support for the specified C++ standard is
# required and that the macro should error out if no mode with that
# support is found. If specified 'optional', then configuration proceeds
# regardless, after defining HAVE_CXX${VERSION} if and only if a
# supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <[email protected]>
# Copyright (c) 2012 Zack Weinberg <[email protected]>
# Copyright (c) 2013 Roy Stogner <[email protected]>
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <[email protected]>
# Copyright (c) 2015 Paul Norman <[email protected]>
# Copyright (c) 2015 Moritz Klammler <[email protected]>
# Copyright (c) 2016, 2018 Krzesimir Nowak <[email protected]>
# Copyright (c) 2019 Enji Cooper <[email protected]>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 11
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
dnl (serial version number 13).
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$2], [], [],
[$2], [ext], [],
[$2], [noext], [],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
[$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
[$3], [optional], [ax_cxx_compile_cxx$1_required=false],
[m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
AC_LANG_PUSH([C++])dnl
ac_success=no
m4_if([$2], [noext], [], [dnl
if test x$ac_success = xno; then
for alternative in ${ax_cxx_compile_alternatives}; do
switch="-std=gnu++${alternative}"
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
ac_success=yes
break
fi
done
fi])
m4_if([$2], [ext], [], [dnl
if test x$ac_success = xno; then
dnl HP's aCC needs +std=c++11 according to:
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
dnl Cray's crayCC needs "-h std=c++11"
for alternative in ${ax_cxx_compile_alternatives}; do
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
ac_success=yes
break
fi
done
if test x$ac_success = xyes; then
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx$1_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
fi
fi
if test x$ac_success = xno; then
HAVE_CXX$1=0
AC_MSG_NOTICE([No compiler with C++$1 support was found])
else
HAVE_CXX$1=1
AC_DEFINE(HAVE_CXX$1,1,
[define if the compiler supports basic C++$1 syntax])
fi
AC_SUBST(HAVE_CXX$1)
])
dnl Test body for checking C++11 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
)
dnl Test body for checking C++14 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
)
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
)
dnl Tests for new features in C++11
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
// If the compiler admits that it is not ready for C++11, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201103L
#error "This is not a C++11 compiler"
#else
namespace cxx11
{
namespace test_static_assert
{
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
}
namespace test_final_override
{
struct Base
{
virtual ~Base() {}
virtual void f() {}
};
struct Derived : public Base
{
virtual ~Derived() override {}
virtual void f() override {}
};
}
namespace test_double_right_angle_brackets
{
template < typename T >
struct check {};
typedef check<void> single_type;
typedef check<check<void>> double_type;
typedef check<check<check<void>>> triple_type;
typedef check<check<check<check<void>>>> quadruple_type;
}
namespace test_decltype
{
int
f()
{
int a = 1;
decltype(a) b = 2;
return a + b;
}
}
namespace test_type_deduction
{
template < typename T1, typename T2 >
struct is_same
{
static const bool value = false;
};
template < typename T >
struct is_same<T, T>
{
static const bool value = true;
};
template < typename T1, typename T2 >
auto
add(T1 a1, T2 a2) -> decltype(a1 + a2)
{
return a1 + a2;
}
int
test(const int c, volatile int v)
{
static_assert(is_same<int, decltype(0)>::value == true, "");
static_assert(is_same<int, decltype(c)>::value == false, "");
static_assert(is_same<int, decltype(v)>::value == false, "");
auto ac = c;
auto av = v;
auto sumi = ac + av + 'x';
auto sumf = ac + av + 1.0;
static_assert(is_same<int, decltype(ac)>::value == true, "");
static_assert(is_same<int, decltype(av)>::value == true, "");
static_assert(is_same<int, decltype(sumi)>::value == true, "");
static_assert(is_same<int, decltype(sumf)>::value == false, "");
static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
return (sumf > 0.0) ? sumi : add(c, v);
}
}
namespace test_noexcept
{
int f() { return 0; }
int g() noexcept { return 0; }
static_assert(noexcept(f()) == false, "");
static_assert(noexcept(g()) == true, "");
}
namespace test_constexpr
{
template < typename CharT >
unsigned long constexpr
strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
{
return *s ? strlen_c_r(s + 1, acc + 1) : acc;
}
template < typename CharT >
unsigned long constexpr
strlen_c(const CharT *const s) noexcept
{
return strlen_c_r(s, 0UL);
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("1") == 1UL, "");
static_assert(strlen_c("example") == 7UL, "");
static_assert(strlen_c("another\0example") == 7UL, "");
}
namespace test_rvalue_references
{
template < int N >
struct answer
{
static constexpr int value = N;
};
answer<1> f(int&) { return answer<1>(); }
answer<2> f(const int&) { return answer<2>(); }
answer<3> f(int&&) { return answer<3>(); }
void
test()
{
int i = 0;
const int c = 0;
static_assert(decltype(f(i))::value == 1, "");
static_assert(decltype(f(c))::value == 2, "");
static_assert(decltype(f(0))::value == 3, "");
}
}
namespace test_uniform_initialization
{
struct test
{
static const int zero {};
static const int one {1};
};
static_assert(test::zero == 0, "");
static_assert(test::one == 1, "");
}
namespace test_lambdas
{
void
test1()
{
auto lambda1 = [](){};
auto lambda2 = lambda1;
lambda1();
lambda2();
}
int
test2()
{
auto a = [](int i, int j){ return i + j; }(1, 2);
auto b = []() -> int { return '0'; }();
auto c = [=](){ return a + b; }();
auto d = [&](){ return c; }();
auto e = [a, &b](int x) mutable {
const auto identity = [](int y){ return y; };
for (auto i = 0; i < a; ++i)
a += b--;
return x + identity(a + b);
}(0);
return a + b + c + d + e;
}
int
test3()
{
const auto nullary = [](){ return 0; };
const auto unary = [](int x){ return x; };
using nullary_t = decltype(nullary);
using unary_t = decltype(unary);
const auto higher1st = [](nullary_t f){ return f(); };
const auto higher2nd = [unary](nullary_t f1){
return [unary, f1](unary_t f2){ return f2(unary(f1())); };
};
return higher1st(nullary) + higher2nd(nullary)(unary);
}
}
namespace test_variadic_templates
{
template <int...>
struct sum;
template <int N0, int... N1toN>
struct sum<N0, N1toN...>
{
static constexpr auto value = N0 + sum<N1toN...>::value;
};
template <>
struct sum<>
{
static constexpr auto value = 0;
};
static_assert(sum<>::value == 0, "");
static_assert(sum<1>::value == 1, "");
static_assert(sum<23>::value == 23, "");
static_assert(sum<1, 2>::value == 3, "");
static_assert(sum<5, 5, 11>::value == 21, "");
static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
}
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
// because of this.
namespace test_template_alias_sfinae
{
struct foo {};
template<typename T>
using member = typename T::member_type;
template<typename T>
void func(...) {}
template<typename T>
void func(member<T>*) {}
void test();
void test() { func<foo>(0); }
}
} // namespace cxx11
#endif // __cplusplus >= 201103L
]])
dnl Tests for new features in C++14
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
// If the compiler admits that it is not ready for C++14, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201402L
#error "This is not a C++14 compiler"
#else
namespace cxx14
{
namespace test_polymorphic_lambdas
{
int
test()
{
const auto lambda = [](auto&&... args){
const auto istiny = [](auto x){
return (sizeof(x) == 1UL) ? 1 : 0;
};
const int aretiny[] = { istiny(args)... };
return aretiny[0];
};
return lambda(1, 1L, 1.0f, '1');
}
}
namespace test_binary_literals
{
constexpr auto ivii = 0b0000000000101010;
static_assert(ivii == 42, "wrong value");
}
namespace test_generalized_constexpr
{
template < typename CharT >
constexpr unsigned long
strlen_c(const CharT *const s) noexcept
{
auto length = 0UL;
for (auto p = s; *p; ++p)
++length;
return length;
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("x") == 1UL, "");
static_assert(strlen_c("test") == 4UL, "");
static_assert(strlen_c("another\0test") == 7UL, "");
}
namespace test_lambda_init_capture
{
int
test()
{
auto x = 0;
const auto lambda1 = [a = x](int b){ return a + b; };
const auto lambda2 = [a = lambda1(x)](){ return a; };
return lambda2();
}
}
namespace test_digit_separators
{
constexpr auto ten_million = 100'000'000;
static_assert(ten_million == 100000000, "");
}
namespace test_return_type_deduction
{
auto f(int& x) { return x; }
decltype(auto) g(int& x) { return x; }
template < typename T1, typename T2 >
struct is_same
{
static constexpr auto value = false;
};
template < typename T >
struct is_same<T, T>
{
static constexpr auto value = true;
};
int
test()
{
auto x = 0;
static_assert(is_same<int, decltype(f(x))>::value, "");
static_assert(is_same<int&, decltype(g(x))>::value, "");
return x;
}
}
} // namespace cxx14
#endif // __cplusplus >= 201402L
]])
dnl Tests for new features in C++17
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
// If the compiler admits that it is not ready for C++17, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201703L
#error "This is not a C++17 compiler"
#else
#include <initializer_list>
#include <utility>
#include <type_traits>
namespace cxx17
{
namespace test_constexpr_lambdas
{
constexpr int foo = [](){return 42;}();
}
namespace test::nested_namespace::definitions
{
}
namespace test_fold_expression
{
template<typename... Args>
int multiply(Args... args)
{
return (args * ... * 1);
}
template<typename... Args>
bool all(Args... args)
{
return (args && ...);
}
}
namespace test_extended_static_assert
{
static_assert (true);
}
namespace test_auto_brace_init_list
{
auto foo = {5};
auto bar {5};
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
static_assert(std::is_same<int, decltype(bar)>::value);
}
namespace test_typename_in_template_template_parameter
{
template<template<typename> typename X> struct D;
}
namespace test_fallthrough_nodiscard_maybe_unused_attributes
{
int f1()
{
return 42;
}
[[nodiscard]] int f2()
{
[[maybe_unused]] auto unused = f1();
switch (f1())
{
case 17:
f1();
[[fallthrough]];
case 42:
f1();
}
return f1();
}
}
namespace test_extended_aggregate_initialization
{
struct base1
{
int b1, b2 = 42;
};
struct base2
{
base2() {
b3 = 42;
}
int b3;
};
struct derived : base1, base2
{
int d;
};
derived d1 {{1, 2}, {}, 4}; // full initialization
derived d2 {{}, {}, 4}; // value-initialized bases
}
namespace test_general_range_based_for_loop
{
struct iter
{
int i;
int& operator* ()
{
return i;
}
const int& operator* () const
{
return i;
}
iter& operator++()
{
++i;
return *this;
}
};
struct sentinel
{
int i;
};
bool operator== (const iter& i, const sentinel& s)
{
return i.i == s.i;
}
bool operator!= (const iter& i, const sentinel& s)
{
return !(i == s);
}
struct range
{
iter begin() const
{
return {0};
}
sentinel end() const
{
return {5};
}
};
void f()
{
range r {};
for (auto i : r)
{
[[maybe_unused]] auto v = i;
}
}
}
namespace test_lambda_capture_asterisk_this_by_value
{
struct t
{
int i;
int foo()
{
return [*this]()
{
return i;
}();
}
};
}
namespace test_enum_class_construction
{
enum class byte : unsigned char
{};
byte foo {42};
}
namespace test_constexpr_if
{
template <bool cond>
int f ()
{
if constexpr(cond)
{
return 13;
}
else
{
return 42;
}
}
}
namespace test_selection_statement_with_initializer
{
int f()
{
return 13;
}
int f2()
{
if (auto i = f(); i > 0)
{
return 3;
}
switch (auto i = f(); i + 4)
{
case 17:
return 2;
default:
return 1;
}
}
}
namespace test_template_argument_deduction_for_class_templates
{
template <typename T1, typename T2>
struct pair
{
pair (T1 p1, T2 p2)
: m1 {p1},
m2 {p2}
{}
T1 m1;
T2 m2;
};
void f()
{
[[maybe_unused]] auto p = pair{13, 42u};
}
}
namespace test_non_type_auto_template_parameters
{
template <auto n>
struct B
{};
B<5> b1;
B<'a'> b2;
}
namespace test_structured_bindings
{
int arr[2] = { 1, 2 };
std::pair<int, int> pr = { 1, 2 };
auto f1() -> int(&)[2]
{
return arr;
}
auto f2() -> std::pair<int, int>&
{
return pr;
}
struct S
{
int x1 : 2;
volatile double y1;
};
S f3()
{
return {};
}
auto [ x1, y1 ] = f1();
auto& [ xr1, yr1 ] = f1();
auto [ x2, y2 ] = f2();
auto& [ xr2, yr2 ] = f2();
const auto [ x3, y3 ] = f3();
}
namespace test_exception_spec_type_system
{
struct Good {};
struct Bad {};
void g1() noexcept;
void g2();
template<typename T>
Bad
f(T*, T*);
template<typename T1, typename T2>
Good
f(T1*, T2*);
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
}
namespace test_inline_variables
{
template<class T> void f(T)
{}
template<class T> inline T g(T)
{
return T{};
}
template<> inline void f<>(int)
{}
template<> int g<>(int)
{
return 5;
}
}
} // namespace cxx17
#endif // __cplusplus < 201703L
]])
-122
View File
@@ -1,122 +0,0 @@
dnl Copyright 2010 The Kyua Authors.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dnl
dnl KYUA_ATTRIBUTE_NORETURN
dnl
dnl Checks if the current compiler has a way to mark functions that do not
dnl return and defines ATTRIBUTE_NORETURN to the appropriate string.
dnl
AC_DEFUN([KYUA_ATTRIBUTE_NORETURN], [
dnl This check is overly simple and should be fixed. For example,
dnl Sun's cc does support the noreturn attribute but CC (the C++
dnl compiler) does not. And in that case, CC just raises a warning
dnl during compilation, not an error.
AC_CACHE_CHECK(
[whether __attribute__((noreturn)) is supported],
[kyua_cv_attribute_noreturn], [
AC_RUN_IFELSE([AC_LANG_PROGRAM([], [
#if ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
return 0;
#else
return 1;
#endif
])],
[kyua_cv_attribute_noreturn=yes],
[kyua_cv_attribute_noreturn=no])
])
if test "${kyua_cv_attribute_noreturn}" = yes; then
attribute_value="__attribute__((noreturn))"
else
attribute_value=""
fi
AC_SUBST([ATTRIBUTE_NORETURN], [${attribute_value}])
])
dnl
dnl KYUA_ATTRIBUTE_PURE
dnl
dnl Checks if the current compiler has a way to mark functions as pure.
dnl
AC_DEFUN([KYUA_ATTRIBUTE_PURE], [
AC_CACHE_CHECK(
[whether __attribute__((__pure__)) is supported],
[kyua_cv_attribute_pure], [
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([
static int function(int, int) __attribute__((__pure__));
static int
function(int a, int b)
{
return a + b;
}], [
return function(3, 4);
])],
[kyua_cv_attribute_pure=yes],
[kyua_cv_attribute_pure=no])
])
if test "${kyua_cv_attribute_pure}" = yes; then
attribute_value="__attribute__((__pure__))"
else
attribute_value=""
fi
AC_SUBST([ATTRIBUTE_PURE], [${attribute_value}])
])
dnl
dnl KYUA_ATTRIBUTE_UNUSED
dnl
dnl Checks if the current compiler has a way to mark parameters as unused
dnl so that the -Wunused-parameter warning can be avoided.
dnl
AC_DEFUN([KYUA_ATTRIBUTE_UNUSED], [
AC_CACHE_CHECK(
[whether __attribute__((__unused__)) is supported],
[kyua_cv_attribute_unused], [
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([
static void
function(int a __attribute__((__unused__)))
{
}], [
function(3);
return 0;
])],
[kyua_cv_attribute_unused=yes],
[kyua_cv_attribute_unused=no])
])
if test "${kyua_cv_attribute_unused}" = yes; then
attribute_value="__attribute__((__unused__))"
else
attribute_value=""
fi
AC_SUBST([ATTRIBUTE_UNUSED], [${attribute_value}])
])
-169
View File
@@ -1,169 +0,0 @@
dnl Copyright 2010 The Kyua Authors.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dnl \file compiler-flags.m4
dnl
dnl Macros to check for the existence of compiler flags. The macros in this
dnl file support both C and C++.
dnl
dnl Be aware that, in order to detect a flag accurately, we may need to enable
dnl strict warning checking in the compiler (i.e. enable -Werror). Some
dnl compilers, e.g. Clang, report unknown -W flags as warnings unless -Werror is
dnl selected. This fact would confuse the flag checks below because we would
dnl conclude that a flag is valid while in reality it is not. To resolve this,
dnl the macros below will pass -Werror to the compiler along with any other flag
dnl being checked.
dnl Checks for a compiler flag and sets a result variable.
dnl
dnl This is an auxiliary macro for the implementation of _KYUA_FLAG.
dnl
dnl \param 1 The shell variable containing the compiler name. Used for
dnl reporting purposes only. C or CXX.
dnl \param 2 The shell variable containing the flags for the compiler.
dnl CFLAGS or CXXFLAGS.
dnl \param 3 The name of the compiler flag to check for.
dnl \param 4 The shell variable to set with the result of the test. Will
dnl be set to 'yes' if the flag is valid, 'no' otherwise.
dnl \param 5 Additional, optional flags to pass to the C compiler while
dnl looking for the flag in $3. We use this here to pass -Werror to the
dnl flag checks (unless we are checking for -Werror already).
AC_DEFUN([_KYUA_FLAG_AUX], [
if test x"${$4-unset}" = xunset; then
AC_MSG_CHECKING(whether ${$1} supports $3)
saved_flags="${$2}"
$4=no
$2="${$2} $5 $3"
# The inclusion of a header file in the test program below is needed
# because some compiler flags that we test for may actually not be
# compatible with other flags, and such compatibility checks are
# performed within the system header files.
#
# As an example, if we are testing for -D_FORTIFY_SOURCE=2 and the
# compilation is being done with -O2, Linux's /usr/include/features.h
# will abort the compilation of our code later on. By including a
# generic header file here that pulls in features.h we ensure that
# this test is accurate for the build stage.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [return 0;])],
AC_MSG_RESULT(yes)
$4=yes,
AC_MSG_RESULT(no))
$2="${saved_flags}"
fi
])
dnl Checks for a compiler flag and appends it to a result variable.
dnl
dnl \param 1 The shell variable containing the compiler name. Used for
dnl reporting purposes only. CC or CXX.
dnl \param 2 The shell variable containing the flags for the compiler.
dnl CFLAGS or CXXFLAGS.
dnl \param 3 The name of the compiler flag to check for.
dnl \param 4 The shell variable to which to append $3 if the flag is valid.
AC_DEFUN([_KYUA_FLAG], [
_KYUA_FLAG_AUX([$1], [$2], [-Werror], [kyua_$1_has_werror])
if test "$3" = "-Werror"; then
found=${kyua_$1_has_werror}
else
found=unset
if test ${kyua_$1_has_werror} = yes; then
_KYUA_FLAG_AUX([$1], [$2], [$3], [found], [-Werror])
else
_KYUA_FLAG_AUX([$1], [$2], [$3], [found], [])
fi
fi
if test ${found} = yes; then
$4="${$4} $3"
fi
])
dnl Checks for a C compiler flag and appends it to a variable.
dnl
dnl \pre The current language is C.
dnl
dnl \param 1 The name of the compiler flag to check for.
dnl \param 2 The shell variable to which to append $1 if the flag is valid.
AC_DEFUN([KYUA_CC_FLAG], [
AC_LANG_ASSERT([C])
_KYUA_FLAG([CC], [CFLAGS], [$1], [$2])
])
dnl Checks for a C++ compiler flag and appends it to a variable.
dnl
dnl \pre The current language is C++.
dnl
dnl \param 1 The name of the compiler flag to check for.
dnl \param 2 The shell variable to which to append $1 if the flag is valid.
AC_DEFUN([KYUA_CXX_FLAG], [
AC_LANG_ASSERT([C++])
_KYUA_FLAG([CXX], [CXXFLAGS], [$1], [$2])
])
dnl Checks for a set of C compiler flags and appends them to CFLAGS.
dnl
dnl The checks are performed independently and only when all the checks are
dnl done, the output variable is modified.
dnl
dnl \param 1 Whitespace-separated list of C flags to check.
AC_DEFUN([KYUA_CC_FLAGS], [
AC_LANG_PUSH([C])
valid_cflags=
for f in $1; do
KYUA_CC_FLAG(${f}, valid_cflags)
done
if test -n "${valid_cflags}"; then
CFLAGS="${CFLAGS} ${valid_cflags}"
fi
AC_LANG_POP([C])
])
dnl Checks for a set of C++ compiler flags and appends them to CXXFLAGS.
dnl
dnl The checks are performed independently and only when all the checks are
dnl done, the output variable is modified.
dnl
dnl \pre The current language is C++.
dnl
dnl \param 1 Whitespace-separated list of C flags to check.
AC_DEFUN([KYUA_CXX_FLAGS], [
AC_LANG_PUSH([C++])
valid_cxxflags=
for f in $1; do
KYUA_CXX_FLAG(${f}, valid_cxxflags)
done
if test -n "${valid_cxxflags}"; then
CXXFLAGS="${CXXFLAGS} ${valid_cxxflags}"
fi
AC_LANG_POP([C++])
])
-112
View File
@@ -1,112 +0,0 @@
dnl Copyright 2010 The Kyua Authors.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dnl \file developer-mode.m4
dnl
dnl "Developer mode" is a mode in which the build system reports any
dnl build-time warnings as fatal errors. This helps in minimizing the
dnl amount of trivial coding problems introduced in the code.
dnl Unfortunately, this is not bullet-proof due to the wide variety of
dnl compilers available and their different warning diagnostics.
dnl
dnl When developer mode support is added to a package, the compilation will
dnl gain a bunch of extra warning diagnostics. These will NOT be enforced
dnl unless developer mode is enabled.
dnl
dnl Developer mode is enabled when the user requests it through the
dnl configure command line, or when building from the repository. The
dnl latter is to minimize the risk of committing new code with warnings
dnl into the tree.
dnl Adds "developer mode" support to the package.
dnl
dnl This macro performs the actual definition of the --enable-developer
dnl flag and implements all of its logic. See the file-level comment for
dnl details as to what this implies.
AC_DEFUN([KYUA_DEVELOPER_MODE], [
m4_foreach([language], [$1], [m4_set_add([languages], language)])
AC_ARG_ENABLE(
[developer],
AS_HELP_STRING([--enable-developer], [enable developer features]),,
[if test -d "${srcdir}/.git"; then
AC_MSG_NOTICE([building from HEAD; developer mode autoenabled])
enable_developer=yes
else
enable_developer=no
fi])
#
# The following warning flags should also be enabled but cannot be.
# Reasons given below.
#
# -Wold-style-cast: Raises errors when using TIOCGWINSZ, at least under
# Mac OS X. This is due to the way _IOR is defined.
#
try_c_cxx_flags="-D_FORTIFY_SOURCE=2 \
-Wall \
-Wcast-qual \
-Wextra \
-Wpointer-arith \
-Wredundant-decls \
-Wreturn-type \
-Wshadow \
-Wsign-compare \
-Wswitch \
-Wwrite-strings"
try_c_flags="-Wmissing-prototypes \
-Wno-traditional \
-Wstrict-prototypes"
try_cxx_flags="-Wabi \
-Wctor-dtor-privacy \
-Wno-deprecated \
-Wno-non-template-friend \
-Wno-pmf-conversions \
-Wnon-virtual-dtor \
-Woverloaded-virtual \
-Wreorder \
-Wsign-promo \
-Wsynth"
if test ${enable_developer} = yes; then
try_werror=yes
try_c_cxx_flags="${try_c_cxx_flags} -g -Werror"
else
try_werror=no
try_c_cxx_flags="${try_c_cxx_flags} -DNDEBUG"
fi
m4_set_contains([languages], [C],
[KYUA_CC_FLAGS(${try_c_cxx_flags} ${try_c_flags})])
m4_set_contains([languages], [C++],
[KYUA_CXX_FLAGS(${try_c_cxx_flags} ${try_cxx_flags})])
])
-62
View File
@@ -1,62 +0,0 @@
dnl Copyright 2010 The Kyua Authors.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dnl
dnl KYUA_DOXYGEN
dnl
dnl Adds a --with-doxygen flag to the configure script and, when Doxygen support
dnl is requested by the user, sets DOXYGEN to the path of the Doxygen binary and
dnl enables the WITH_DOXYGEN Automake conditional.
dnl
AC_DEFUN([KYUA_DOXYGEN], [
AC_ARG_WITH([doxygen],
AS_HELP_STRING([--with-doxygen],
[build documentation for internal APIs]),
[],
[with_doxygen=auto])
if test "${with_doxygen}" = yes; then
AC_PATH_PROG([DOXYGEN], [doxygen], [])
if test -z "${DOXYGEN}"; then
AC_MSG_ERROR([Doxygen explicitly requested but not found])
fi
elif test "${with_doxygen}" = auto; then
AC_PATH_PROG([DOXYGEN], [doxygen], [])
elif test "${with_doxygen}" = no; then
DOXYGEN=
else
AC_MSG_CHECKING([for doxygen])
DOXYGEN="${with_doxygen}"
AC_MSG_RESULT([${DOXYGEN}])
if test ! -x "${DOXYGEN}"; then
AC_MSG_ERROR([Doxygen binary ${DOXYGEN} is not executable])
fi
fi
AM_CONDITIONAL([WITH_DOXYGEN], [test -n "${DOXYGEN}"])
AC_SUBST([DOXYGEN])
])
-125
View File
@@ -1,125 +0,0 @@
dnl Copyright 2011 The Kyua Authors.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dnl \file m4/fs.m4
dnl File system related checks.
dnl
dnl The macros in this file check for features required in the utils/fs
dnl module. The global KYUA_FS_MODULE macro will call all checks required
dnl for the library.
dnl KYUA_FS_GETCWD_DYN
dnl
dnl Checks whether getcwd(NULL, 0) works; i.e. if getcwd(3) can dynamically
dnl allocate the output buffer to fit the whole current path.
AC_DEFUN([KYUA_FS_GETCWD_DYN], [
AC_CACHE_CHECK(
[whether getcwd(NULL, 0) works],
[kyua_cv_getcwd_dyn], [
AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdlib.h>
#include <unistd.h>
], [
char *cwd = getcwd(NULL, 0);
return (cwd != NULL) ? EXIT_SUCCESS : EXIT_FAILURE;
])],
[kyua_cv_getcwd_dyn=yes],
[kyua_cv_getcwd_dyn=no])
])
if test "${kyua_cv_getcwd_dyn}" = yes; then
AC_DEFINE_UNQUOTED([HAVE_GETCWD_DYN], [1],
[Define to 1 if getcwd(NULL, 0) works])
fi
])
dnl KYUA_FS_LCHMOD
dnl
dnl Checks whether lchmod(3) exists and if it works. Some systems, such as
dnl Ubuntu 10.04.1 LTS, provide a lchmod(3) stub that is not implemented yet
dnl allows programs to compile cleanly (albeit for a warning). It would be
dnl nice to detect if lchmod(3) works at run time to prevent side-effects of
dnl this test but doing so means we will keep receiving a noisy compiler
dnl warning.
AC_DEFUN([KYUA_FS_LCHMOD], [
AC_CACHE_CHECK(
[for a working lchmod],
[kyua_cv_lchmod_works], [
AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
], [
int fd = open("conftest.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("creation of conftest.txt failed");
return EXIT_FAILURE;
}
return lchmod("conftest.txt", 0640) != -1 ? EXIT_SUCCESS : EXIT_FAILURE;
])],
[kyua_cv_lchmod_works=yes],
[kyua_cv_lchmod_works=no])
])
rm -f conftest.txt
if test "${kyua_cv_lchmod_works}" = yes; then
AC_DEFINE_UNQUOTED([HAVE_WORKING_LCHMOD], [1],
[Define to 1 if your lchmod works])
fi
])
dnl KYUA_FS_UNMOUNT
dnl
dnl Detect the correct method to unmount a file system.
AC_DEFUN([KYUA_FS_UNMOUNT], [
AC_CHECK_FUNCS([unmount], [have_unmount2=yes], [have_unmount2=no])
if test "${have_unmount2}" = no; then
have_umount8=yes
AC_PATH_PROG([UMOUNT], [umount], [have_umount8=no])
if test "${have_umount8}" = yes; then
AC_DEFINE_UNQUOTED([UMOUNT], ["${UMOUNT}"],
[Set to the path of umount(8)])
else
AC_MSG_ERROR([Don't know how to unmount a file system])
fi
fi
])
dnl KYUA_FS_MODULE
dnl
dnl Performs all checks needed by the utils/fs library.
AC_DEFUN([KYUA_FS_MODULE], [
AC_CHECK_HEADERS([sys/mount.h sys/statvfs.h sys/vfs.h])
AC_CHECK_FUNCS([statfs statvfs])
KYUA_FS_GETCWD_DYN
KYUA_FS_LCHMOD
KYUA_FS_UNMOUNT
])
-213
View File
@@ -1,213 +0,0 @@
dnl Copyright 2010 The Kyua Authors.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dnl Checks if getopt(3) supports a + sign to enforce POSIX correctness.
dnl
dnl In the GNU implementation of getopt(3), we need to pass a + sign at
dnl the beginning of the options string to request POSIX behavior.
dnl
dnl Defines HAVE_GETOPT_GNU if a + sign is supported.
AC_DEFUN([_KYUA_GETOPT_GNU], [
AC_CACHE_CHECK(
[whether getopt allows a + sign for POSIX behavior optreset],
[kyua_cv_getopt_gnu], [
AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdlib.h>
#include <string.h>
#include <unistd.h>], [
int argc = 4;
char* argv@<:@5@:>@ = {
strdup("conftest"),
strdup("-+"),
strdup("-a"),
strdup("bar"),
NULL
};
int ch;
int seen_a = 0, seen_plus = 0;
while ((ch = getopt(argc, argv, "+a:")) != -1) {
switch (ch) {
case 'a':
seen_a = 1;
break;
case '+':
seen_plus = 1;
break;
case '?':
default:
;
}
}
return (seen_a && !seen_plus) ? EXIT_SUCCESS : EXIT_FAILURE;
])],
[kyua_cv_getopt_gnu=yes],
[kyua_cv_getopt_gnu=no])
])
if test "${kyua_cv_getopt_gnu}" = yes; then
AC_DEFINE([HAVE_GETOPT_GNU], [1],
[Define to 1 if getopt allows a + sign for POSIX behavior])
fi
])
dnl Checks if optreset exists to reset the processing of getopt(3) options.
dnl
dnl getopt(3) has an optreset global variable to reset internal state
dnl before calling getopt(3) again. However, optreset is not standard and
dnl is only present in the BSD versions of getopt(3).
dnl
dnl Defines HAVE_GETOPT_WITH_OPTRESET if optreset exists.
AC_DEFUN([_KYUA_GETOPT_WITH_OPTRESET], [
AC_CACHE_CHECK(
[whether getopt has optreset],
[kyua_cv_getopt_optreset], [
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <stdlib.h>
#include <unistd.h>
int
main(void)
{
optreset = 1;
return EXIT_SUCCESS;
}
])],
[kyua_cv_getopt_optreset=yes],
[kyua_cv_getopt_optreset=no])
])
if test "${kyua_cv_getopt_optreset}" = yes; then
AC_DEFINE([HAVE_GETOPT_WITH_OPTRESET], [1],
[Define to 1 if getopt has optreset])
fi
])
dnl Checks the value to pass to optind to reset getopt(3) processing.
dnl
dnl The standard value to pass to optind to reset the processing of command
dnl lines with getopt(3) is 1. However, the GNU extensions to getopt_long(3)
dnl are not properly reset unless optind is set to 0, causing crashes later
dnl on and incorrect option processing behavior.
dnl
dnl Sets the GETOPT_OPTIND_RESET_VALUE macro to the integer value that has to
dnl be passed to optind to reset option processing.
AC_DEFUN([_KYUA_GETOPT_OPTIND_RESET_VALUE], [
AC_CACHE_CHECK(
[for the optind value to reset getopt processing],
[kyua_cv_getopt_optind_reset_value], [
AC_RUN_IFELSE([AC_LANG_SOURCE([
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static void
first_pass(void)
{
int argc, ch, flag;
char* argv@<:@5@:>@;
argc = 4;
argv@<:@0@:>@ = strdup("progname");
argv@<:@1@:>@ = strdup("-a");
argv@<:@2@:>@ = strdup("foo");
argv@<:@3@:>@ = strdup("bar");
argv@<:@4@:>@ = NULL;
flag = 0;
while ((ch = getopt(argc, argv, "+:a")) != -1) {
switch (ch) {
case 'a':
flag = 1;
break;
default:
break;
}
}
if (!flag) {
exit(EXIT_FAILURE);
}
}
static void
second_pass(void)
{
int argc, ch, flag;
char* argv@<:@5@:>@;
argc = 4;
argv@<:@0@:>@ = strdup("progname");
argv@<:@1@:>@ = strdup("-b");
argv@<:@2@:>@ = strdup("foo");
argv@<:@3@:>@ = strdup("bar");
argv@<:@4@:>@ = NULL;
flag = 0;
while ((ch = getopt(argc, argv, "b")) != -1) {
switch (ch) {
case 'b':
flag = 1;
break;
default:
break;
}
}
if (!flag) {
exit(EXIT_FAILURE);
}
}
int
main(void)
{
/* We do two passes in two different functions to prevent the reuse of
* variables and, specially, to force the use of two different argument
* vectors. */
first_pass();
optind = 0;
second_pass();
return EXIT_SUCCESS;
}
])],
[kyua_cv_getopt_optind_reset_value=0],
[kyua_cv_getopt_optind_reset_value=1])
])
AC_DEFINE_UNQUOTED([GETOPT_OPTIND_RESET_VALUE],
[${kyua_cv_getopt_optind_reset_value}],
[Define to the optind value to reset getopt processing])
])
dnl Wrapper macro to detect all getopt(3) necessary features.
AC_DEFUN([KYUA_GETOPT], [
_KYUA_GETOPT_GNU
_KYUA_GETOPT_OPTIND_RESET_VALUE
_KYUA_GETOPT_WITH_OPTRESET
])
-122
View File
@@ -1,122 +0,0 @@
dnl Copyright 2012 The Kyua Authors.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dnl \file m4/memory.m4
dnl
dnl Macros to configure the utils::memory module.
dnl Entry point to detect all features needed by utils::memory.
dnl
dnl This looks for a mechanism to check the available physical memory in the
dnl system.
AC_DEFUN([KYUA_MEMORY], [
memory_query=unknown
memory_mib=none
_KYUA_SYSCTLBYNAME([have_sysctlbyname=yes], [have_sysctlbyname=no])
if test "${have_sysctlbyname}" = yes; then
_KYUA_SYSCTL_MIB([hw.usermem64], [hw_usermem64],
[memory_mib="hw.usermem64"], [])
if test "${memory_mib}" = none; then
_KYUA_SYSCTL_MIB([hw.usermem], [hw_usermem],
[memory_mib="hw.usermem"], [])
fi
if test "${memory_mib}" != none; then
memory_query=sysctlbyname
fi
fi
if test "${memory_query}" = unknown; then
AC_MSG_WARN([Don't know how to query the amount of physical memory])
AC_MSG_WARN([The test case's require.memory property will not work])
fi
AC_DEFINE_UNQUOTED([MEMORY_QUERY_TYPE], ["${memory_query}"],
[Define to the memory query type])
AC_DEFINE_UNQUOTED([MEMORY_QUERY_SYSCTL_MIB], ["${memory_mib}"],
[Define to the name of the sysctl MIB])
])
dnl Detects the availability of the sysctlbyname(3) function.
dnl
dnl \param action_if_found Code to run if the function is found.
dnl \param action_if_not_found Code to run if the function is not found.
AC_DEFUN([_KYUA_SYSCTLBYNAME], [
AC_CHECK_HEADERS([sys/types.h sys/sysctl.h]) dnl Darwin 11.2
AC_CHECK_HEADERS([sys/param.h sys/sysctl.h]) dnl NetBSD 6.0
AC_CHECK_FUNCS([sysctlbyname], [$1], [$2])
])
dnl Looks for a specific sysctl MIB.
dnl
dnl \pre sysctlbyname(3) must be present in the system.
dnl
dnl \param mib_name The name of the MIB to check for.
dnl \param flat_mib_name The name of the MIB as a shell variable, for use in
dnl cache variable names. This should be automatically computed with
dnl m4_bpatsubst or similar, but my inability to make the code readable
dnl made me add this parameter instead.
dnl \param action_if_found Code to run if the MIB is found.
dnl \param action_if_not_found Code to run if the MIB is not found.
AC_DEFUN([_KYUA_SYSCTL_MIB], [
AC_CACHE_CHECK(
[if the $1 sysctl MIB exists],
[kyua_cv_sysctl_$2], [
AC_RUN_IFELSE([AC_LANG_PROGRAM([
#if defined(HAVE_SYS_TYPES_H)
# include <sys/types.h>
#endif
#if defined(HAVE_SYS_PARAM_H)
# include <sys/param.h>
#endif
#if defined(HAVE_SYS_SYSCTL_H)
# include <sys/sysctl.h>
#endif
#include <stdint.h>
#include <stdlib.h>
], [
int64_t memory;
size_t memory_length = sizeof(memory);
if (sysctlbyname("$1", &memory, &memory_length, NULL, 0) == -1)
return EXIT_FAILURE;
else
return EXIT_SUCCESS;
])],
[kyua_cv_sysctl_$2=yes],
[kyua_cv_sysctl_$2=no])
])
if test "${kyua_cv_sysctl_$2}" = yes; then
m4_default([$3], [:])
else
m4_default([$4], [:])
fi
])
-92
View File
@@ -1,92 +0,0 @@
dnl Copyright 2010 The Kyua Authors.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dnl
dnl KYUA_LAST_SIGNO
dnl
dnl Detect the last valid signal number.
dnl
AC_DEFUN([KYUA_LAST_SIGNO], [
AC_CACHE_CHECK(
[for the last valid signal],
[kyua_cv_signals_lastno], [
AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <err.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>], [
static const int max_signals = 256;
int i;
FILE *f;
i = 0;
while (i < max_signals) {
i++;
if (i != SIGKILL && i != SIGSTOP) {
struct sigaction sa;
int ret;
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
ret = sigaction(i, &sa, NULL);
if (ret == -1) {
warn("sigaction(%d) failed", i);
if (errno == EINVAL) {
i--;
break;
} else
err(EXIT_FAILURE, "sigaction failed");
}
}
}
if (i == max_signals)
errx(EXIT_FAILURE, "too many signals");
f = fopen("conftest.cnt", "w");
if (f == NULL)
err(EXIT_FAILURE, "failed to open file");
fprintf(f, "%d\n", i);
fclose(f);
return EXIT_SUCCESS;
])],
[if test ! -f conftest.cnt; then
kyua_cv_signals_lastno=15
else
kyua_cv_signals_lastno=$(cat conftest.cnt)
rm -f conftest.cnt
fi],
[kyua_cv_signals_lastno=15])
])
AC_DEFINE_UNQUOTED([LAST_SIGNO], [${kyua_cv_signals_lastno}],
[Define to the last valid signal number])
])
-63
View File
@@ -1,63 +0,0 @@
dnl Copyright 2010 The Kyua Authors.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that the following conditions are
dnl met:
dnl
dnl * Redistributions of source code must retain the above copyright
dnl notice, this list of conditions and the following disclaimer.
dnl * Redistributions in binary form must reproduce the above copyright
dnl notice, this list of conditions and the following disclaimer in the
dnl documentation and/or other materials provided with the distribution.
dnl * Neither the name of Google Inc. nor the names of its contributors
dnl may be used to endorse or promote products derived from this software
dnl without specific prior written permission.
dnl
dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dnl "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dnl A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dnl OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dnl LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dnl DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dnl THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dnl (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dnl OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dnl
dnl KYUA_UNAME_ARCHITECTURE
dnl
dnl Checks for the current architecture name (aka processor type) and defines
dnl the KYUA_ARCHITECTURE macro to its value.
dnl
AC_DEFUN([KYUA_UNAME_ARCHITECTURE], [
AC_MSG_CHECKING([for architecture name])
AC_ARG_VAR([KYUA_ARCHITECTURE],
[Name of the system architecture (aka processor type)])
if test x"${KYUA_ARCHITECTURE-unset}" = x"unset"; then
KYUA_ARCHITECTURE="$(uname -p)"
fi
AC_DEFINE_UNQUOTED([KYUA_ARCHITECTURE], "${KYUA_ARCHITECTURE}",
[Name of the system architecture (aka processor type)])
AC_MSG_RESULT([${KYUA_ARCHITECTURE}])
])
dnl
dnl KYUA_UNAME_PLATFORM
dnl
dnl Checks for the current platform name (aka machine name) and defines
dnl the KYUA_PLATFORM macro to its value.
dnl
AC_DEFUN([KYUA_UNAME_PLATFORM], [
AC_MSG_CHECKING([for platform name])
AC_ARG_VAR([KYUA_PLATFORM],
[Name of the system platform (aka machine name)])
if test x"${KYUA_PLATFORM-unset}" = x"unset"; then
KYUA_PLATFORM="$(uname -m)"
fi
AC_DEFINE_UNQUOTED([KYUA_PLATFORM], "${KYUA_PLATFORM}",
[Name of the system platform (aka machine name)])
AC_MSG_RESULT([${KYUA_PLATFORM}])
])
-32
View File
@@ -1,32 +0,0 @@
# Copyright 2011 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dist_misc_DATA = misc/context.html
dist_misc_DATA += misc/index.html
dist_misc_DATA += misc/report.css
dist_misc_DATA += misc/test_result.html
-89
View File
@@ -1,89 +0,0 @@
# Copyright 2014 The Kyua Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MODEL_CFLAGS = $(UTILS_CFLAGS)
MODEL_LIBS = libmodel.a $(UTILS_LIBS)
noinst_LIBRARIES += libmodel.a
libmodel_a_CPPFLAGS = $(UTILS_CFLAGS)
libmodel_a_SOURCES = model/context.cpp
libmodel_a_SOURCES += model/context.hpp
libmodel_a_SOURCES += model/context_fwd.hpp
libmodel_a_SOURCES += model/exceptions.cpp
libmodel_a_SOURCES += model/exceptions.hpp
libmodel_a_SOURCES += model/metadata.cpp
libmodel_a_SOURCES += model/metadata.hpp
libmodel_a_SOURCES += model/metadata_fwd.hpp
libmodel_a_SOURCES += model/test_case.cpp
libmodel_a_SOURCES += model/test_case.hpp
libmodel_a_SOURCES += model/test_case_fwd.hpp
libmodel_a_SOURCES += model/test_program.cpp
libmodel_a_SOURCES += model/test_program.hpp
libmodel_a_SOURCES += model/test_program_fwd.hpp
libmodel_a_SOURCES += model/test_result.cpp
libmodel_a_SOURCES += model/test_result.hpp
libmodel_a_SOURCES += model/test_result_fwd.hpp
libmodel_a_SOURCES += model/types.hpp
if WITH_ATF
tests_modeldir = $(pkgtestsdir)/model
tests_model_DATA = model/Kyuafile
EXTRA_DIST += $(tests_model_DATA)
tests_model_PROGRAMS = model/context_test
model_context_test_SOURCES = model/context_test.cpp
model_context_test_CXXFLAGS = $(MODEL_CFLAGS) $(ATF_CXX_CFLAGS)
model_context_test_LDADD = $(MODEL_LIBS) $(ATF_CXX_LIBS)
tests_model_PROGRAMS += model/exceptions_test
model_exceptions_test_SOURCES = model/exceptions_test.cpp
model_exceptions_test_CXXFLAGS = $(MODEL_CFLAGS) $(ATF_CXX_CFLAGS)
model_exceptions_test_LDADD = $(MODEL_LIBS) $(ATF_CXX_LIBS)
tests_model_PROGRAMS += model/metadata_test
model_metadata_test_SOURCES = model/metadata_test.cpp
model_metadata_test_CXXFLAGS = $(MODEL_CFLAGS) $(ATF_CXX_CFLAGS)
model_metadata_test_LDADD = $(MODEL_LIBS) $(ATF_CXX_LIBS)
tests_model_PROGRAMS += model/test_case_test
model_test_case_test_SOURCES = model/test_case_test.cpp
model_test_case_test_CXXFLAGS = $(MODEL_CFLAGS) $(ATF_CXX_CFLAGS)
model_test_case_test_LDADD = $(MODEL_LIBS) $(ATF_CXX_LIBS)
tests_model_PROGRAMS += model/test_program_test
model_test_program_test_SOURCES = model/test_program_test.cpp
model_test_program_test_CXXFLAGS = $(MODEL_CFLAGS) $(ATF_CXX_CFLAGS)
model_test_program_test_LDADD = $(MODEL_LIBS) $(ATF_CXX_LIBS)
tests_model_PROGRAMS += model/test_result_test
model_test_result_test_SOURCES = model/test_result_test.cpp
model_test_result_test_CXXFLAGS = $(MODEL_CFLAGS) $(ATF_CXX_CFLAGS)
model_test_result_test_LDADD = $(MODEL_LIBS) $(ATF_CXX_LIBS)
endif
Loaded 100 of 147 files, more files were not shown because too many files have changed in this diff. Show more