contrib/atf: upgrade to 0.26

This new version gets contrib/atf in line with the published version of
the package up on [GitHub][github].

Please note that this release is a major update: it contains several
bugfixes and feature enhancements. Most were already present in the
FreeBSD src repo, but there were a large number of changes made in
addition to what was already present.

MFC after:      1 month

Merge commit '9c78088348bcf1059d82a62bb57a0746309d4312'

Conflicts:
        contrib/atf/.cirrus.yml
        contrib/atf/Makefile.am
        contrib/atf/Makefile.in
        contrib/atf/aclocal.m4
        contrib/atf/admin/ar-lib
        contrib/atf/admin/check-style-common.awk
        contrib/atf/admin/check-style.sh
        contrib/atf/admin/compile
        contrib/atf/admin/config.guess
        contrib/atf/admin/config.sub
        contrib/atf/admin/depcomp
        contrib/atf/admin/install-sh
        contrib/atf/admin/ltmain.sh
        contrib/atf/admin/missing
        contrib/atf/atf-c++/Makefile.am.inc
        contrib/atf/atf-c++/atf-c++.3
        contrib/atf/atf-c++/atf-c++.pc.in
        contrib/atf/atf-c++/check.cpp
        contrib/atf/atf-c++/check.hpp
        contrib/atf/atf-c++/detail/Makefile.am.inc
        contrib/atf/atf-c++/detail/process_test.cpp
        contrib/atf/atf-c/Makefile.am.inc
        contrib/atf/atf-c/atf-c.3
        contrib/atf/atf-c/atf-c.pc.in
        contrib/atf/atf-c/detail/Makefile.am.inc
        contrib/atf/atf-c/detail/fs.c
        contrib/atf/atf-c/detail/fs_test.c
        contrib/atf/atf-c/detail/process_test.c
        contrib/atf/atf-c/tc.c
        contrib/atf/atf-c/tc.h
        contrib/atf/atf-sh/Makefile.am.inc
        contrib/atf/atf-sh/atf-check.cpp
        contrib/atf/atf-sh/atf-check_test.sh
        contrib/atf/bootstrap/Makefile.am.inc
        contrib/atf/bootstrap/package.m4
        contrib/atf/bootstrap/testsuite
        contrib/atf/config.h
        contrib/atf/configure
        contrib/atf/configure.ac
        contrib/atf/doc/Makefile.am.inc
        contrib/atf/doc/atf-test-case.7
        contrib/atf/m4/developer-mode.m4
        contrib/atf/m4/libtool.m4
        contrib/atf/m4/ltoptions.m4
        contrib/atf/m4/ltsugar.m4
        contrib/atf/m4/ltversion.m4
        contrib/atf/m4/lt~obsolete.m4
        contrib/atf/m4/module-defs.m4
        contrib/atf/test-programs/Makefile.am.inc

[github]: https://github.com/freebsd/atf
This commit is contained in:
Enji Cooper committed 2026-09-22 08:23:32 -07:00
commit 9522310861
75 files changed
+939 -1209

No files matched your search

+3
View File
@@ -55,6 +55,9 @@
OLD_FILES+=usr/bin/lesskey
OLD_FILES+=usr/share/man/man1/lesskey.1.gz
# 20260921: atf-0.26 release
OLD_FILES+=usr/share/doc/atf/README
# 20260813: lib9p.so becomes a private library
OLD_LIBS+=usr/lib/lib9p.so.1
-26
View File
@@ -1,26 +0,0 @@
env:
CIRRUS_CLONE_DEPTH: 1
ARCH: amd64
task:
matrix:
- name: 13.0-CURRENT
freebsd_instance:
image_family: freebsd-13-0-snap
- name: 12.2-STABLE
freebsd_instance:
image_family: freebsd-12-2-snap
- name: 12.1-RELEASE
freebsd_instance:
image_family: freebsd-12-1
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 libtool kyua
script:
- env JUNIT_OUTPUT=$(pwd)/test-results.xml ./admin/travis-build.sh
always:
junit_artifacts:
path: "test-results.xml"
type: text/xml
format: junit
-25
View File
@@ -1,25 +0,0 @@
*.la
*.lo
*.o
*.pc
*_helper
*_helpers
*_test
.deps
.dirstamp
.libs
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.h
config.h.in
config.h.in~
config.log
config.status
configure
installcheck.log
libtool
stamp-h1
testsuite.log
-25
View File
@@ -1,25 +0,0 @@
language: cpp
compiler:
- gcc
- clang
before_install:
- ./admin/travis-install-deps.sh
env:
- ARCH=amd64 AS_ROOT=no
- ARCH=amd64 AS_ROOT=yes
- ARCH=i386 AS_ROOT=no
matrix:
exclude:
- compiler: clang
env: ARCH=i386 AS_ROOT=no
script:
- ./admin/travis-build.sh
notifications:
email:
- [email protected]
+1 -1
View File
@@ -2,7 +2,7 @@
*/Makefile*
*/*.m4
*/*.pc.in
INSTALL
INSTALL.md
Makefile*
aclocal.m4
admin/
+147 -53
View File
@@ -1,26 +1,140 @@
Major changes between releases Automated Testing Framework
===========================================================================
# Major changes between releases
Changes in version 0.22
***********************
## Changes in version 0.26
STILL UNDER DEVELOPMENT; NOT RELEASED YET.
DON'T FORGET TO BUMP THE -version-info PRE-RELEASE IF NECESSARY!
Released on 2026/09/22.
### Developer Workflow Changes
* #189: Automate uploading release assets
* #190: INSTALL.md: sync content with version from lutok
* #191: [CI] Minor tweaks
### Feature Enhancements
* #192: Add kmod support on FreeBSD
**Full Changelog**: https://github.com/freebsd/atf/compare/atf-0.25...atf-0.26
## Changes in version 0.25
Released on 2026/09/02.
### Bugfixes
* #187: Fix the build on NetBSD by renaming a variable added in version 0.24.
### Developer Workflow Changes
* #185: The version of LLVM used in macOS runners was bumped from 19 to 20
**Full Changelog**: https://github.com/freebsd/atf/compare/atf-0.24...atf-0.25
## Changes in version 0.24
Released on August, 17, 2026
### Major Changes
* This version of ATF requires C++-20 to build/function.
* This version of ATF focused heavily on correctness and memory management
issues discussed in #77. While most of the issues are believed to be resolved,
some issues may still remain.
* The `atf::text::duplicate(..)` API and tests were removed.
### Feature Enhancements
* Issue #105: Widen our process status capabilties
### Docs
* Issue #107: Clarify the semantics of ATF_{CHECK,REQUIRE}_ERRNO()
* Issue #124: atf-check.1: Add missing -r flag to synopsis
* Issue #127: atf-c.3: Fix test case addition in ATF_TP_ADD_TCS synopsis example
### Developer Workflow Changes
* GitHub Actions support was added.
* Cirrus CI support was removed.
* FreeBSD vmactions CI support was added.
* ASAN/LSAN/UBSAN support was added for Linux and macOS.
* (Initial) runtime code coverage support was added.
* (Initial) pre-commit support was added.
**Full Changelog**: https://github.com/freebsd/atf/compare/atf-0.23...atf-0.24
## Changes in version 0.23
Released on March, 29, 2025
* Issue #101: fix release tarballs by using `make dist` instead of
alternative ad hoc method.
* Issue #76: `atf_check`: fix `std::length_error` thrown from `temp_file`.
* #87: Update documentation/build files to point to FreeBSD repo/mailing lists.
* #86: Improve diagnostics when paths cannot be opened
* #85: various build-related changes. Highlights:
* Remove leftover references of `auto_array` (bugfix).
* Remove the `atf-*-api` manpages (enhancement).
* Require -std=C++14 with ATF (enhancement).
* Expose `WCOREDUMP(..)` on platforms that support it (bugfix).
* Add `__attribute__((nonnull))` support (enhancement).
* Restore `AC_PROG_CPP` (bugfix).
### General fixes
* Fix various style issues which were blocking `make dist` from completing
cleanly.
* Fix `atf_utils_file_exists` declaration in atf-c(3).
* Fix various memory leaks and logic errors.
* `atf-test-case(4)`: update reference to the "descr" metadata property so it's
marked Optional.
* `atf-check.cpp`: remove unnecessary data copy in `temp_file`.
## Changes in version 0.22
Released on November 25th, 2024.
* Issue #23: Fix double-free triggered by atf_map_insert in low memory
scenarios, caused by an overlook in the atf_list code.
* Issue #29: Fixed various typos and formatting errors in manual pages.
* Issue #31: Added require.progs metadata properties to the tests that
need a compiler to run.
* Added the atf_check_not_equal function to atf-sh to check for
unequal values.
* Add `-r timeout` flag to `atf-check`.
Changes in version 0.21
***********************
* Open results files before executing tests to fix an issue ATF tests that
adjust the processes' Capsicum rights as part of the testcase(s)
executed.
* Add Cirrus CI integration for FreeBSD CI/CD support.
* Address compilation issues on OpenSolaris distributions.
* Replace `auto_array` with `std::vector` (fixes modern C++ compliance).
* Replace `auto_ptr` with `std::unique_ptr` (fixes modern C++ compliance).
* Update autotools idioms and requirements. The minimum required version of
autoconf is now 2.68.
* Modify `ATF_CHECK*` and `ATF_REQUIRE*` macros to avoid double
evaluation/allow the gcc toolchain to detect accidental single
assignment typos.
* Always define CPP to fix use of ATF_BUILD_CPP when the user did not
define CPP when invoking the configure script.
### General fixes
* Fix various typos and formatting errors in manual pages and markdown
documents.
## Changes in version 0.21
Released on October 23rd, 2014.
@@ -76,8 +190,7 @@ Released on October 23rd, 2014.
* Issue #19: Removed stale references to atf-config and atf-run.
Changes in version 0.20
***********************
## Changes in version 0.20
Experimental version released on February 7th, 2014.
@@ -92,8 +205,7 @@ the 'tools' directory for your own consumption.
that ships with FreeBSD 11.0-CURRENT.
Changes in version 0.19
***********************
## Changes in version 0.19
Experimental version released on February 7th, 2014.
@@ -112,7 +224,7 @@ does not depend on any internal details of atf-c++ any longer.
* Project hosting moved from Google Code (as a subproject of Kyua) to
GitHub (as a first-class project). The main reason for the change is
the suppression of binary downloads in Google Code on Jan 15th, 2014.
See https://github.com/jmmv/atf/
See https://github.com/freebsd/atf/
* Removed builtin help from atf-sh(1) and atf-check(1) for simplicity
reasons. In other words, their -h option is gone.
@@ -124,8 +236,7 @@ does not depend on any internal details of atf-c++ any longer.
atf-c++ would break the stale tools.
Changes in version 0.18
***********************
## Changes in version 0.18
Experimental version released on November 16th, 2013.
@@ -142,8 +253,7 @@ Experimental version released on November 16th, 2013.
* NetBSD PR bin/48285: Fixed atf_check examples in atf-sh-api(3).
Changes in version 0.17
***********************
## Changes in version 0.17
Experimental version released on February 14th, 2013.
@@ -176,8 +286,7 @@ Experimental version released on February 14th, 2013.
cases from breaking xsltproc later.
Changes in version 0.16
***********************
## Changes in version 0.16
Experimental version released on July 10th, 2012.
@@ -211,8 +320,7 @@ Experimental version released on July 10th, 2012.
lives in a subcomponent of the Kyua project.
Changes in version 0.15
***********************
## Changes in version 0.15
Experimental version released on January 16th, 2012.
@@ -248,8 +356,7 @@ Experimental version released on January 16th, 2012.
mangle our report.
Changes in version 0.14
***********************
## Changes in version 0.14
Experimental version released on June 14th, 2011.
@@ -277,8 +384,7 @@ Experimental version released on June 14th, 2011.
case to run.
Changes in version 0.13
***********************
## Changes in version 0.13
Experimental version released on March 31st, 2011.
@@ -323,8 +429,7 @@ The changes in this release are:
instead of just listing them as having 0 test cases.
Changes in version 0.12
***********************
## Changes in version 0.12
Experimental version released on November 7th, 2010.
@@ -359,8 +464,7 @@ Experimental version released on November 7th, 2010.
general, not be blindly run as root in the first place.
Changes in version 0.11
***********************
## Changes in version 0.11
Experimental version released on October 20th, 2010.
@@ -382,8 +486,7 @@ Experimental version released on October 20th, 2010.
* Fixed the XSTL and CSS stylesheets to support expected failures.
Changes in version 0.10
***********************
## Changes in version 0.10
Experimental version released on July 2nd, 2010.
@@ -410,7 +513,7 @@ Miscellaneous features
take the expected exception as the first argument and the statement to
execute as the second argument.
Changes in atf-check
### Changes in atf-check
* Changed atf-check to support negating the status and output checks by
prefixing them with not- and added support to specify multiple checkers
@@ -463,8 +566,7 @@ Code simplifications and cleanups
easier to maintain.
Changes in version 0.9
**********************
## Changes in version 0.9
Experimental version released on June 3rd, 2010.
@@ -491,8 +593,7 @@ Experimental version released on June 3rd, 2010.
ATF_TEST_CASE_WITHOUT_HEAD.
Changes in version 0.8
**********************
## Changes in version 0.8
Experimental version released on May 7th, 2010.
@@ -541,8 +642,7 @@ Experimental version released on May 7th, 2010.
name of their own.
Changes in version 0.7
**********************
## Changes in version 0.7
Experimental version released on December 22nd, 2009.
@@ -571,8 +671,7 @@ Experimental version released on December 22nd, 2009.
* Fixed many memory and object leaks.
Changes in version 0.6
**********************
## Changes in version 0.6
Experimental version released on January 18th, 2009.
@@ -605,8 +704,7 @@ Experimental version released on January 18th, 2009.
_STREQ_MSG.
Changes in version 0.5
**********************
## Changes in version 0.5
Experimental version released on May 1st, 2008.
@@ -632,8 +730,7 @@ Experimental version released on May 1st, 2008.
executed multiple times to comply with the user's requests.
Changes in version 0.4
**********************
## Changes in version 0.4
Experimental version released on February 4th, 2008.
@@ -665,8 +762,7 @@ Experimental version released on February 4th, 2008.
were likely affected too.
Changes in version 0.3
**********************
## Changes in version 0.3
Experimental version released on November 11th, 2007.
@@ -699,8 +795,7 @@ Experimental version released on November 11th, 2007.
incomplete.
Changes in version 0.2
**********************
## Changes in version 0.2
Experimental version released on September 20th, 2007.
@@ -731,8 +826,7 @@ Experimental version released on September 20th, 2007.
* Multiple bug fixes and improvements all around.
Changes in version 0.1
**********************
## Changes in version 0.1
Experimental version released on August 20th, 2007.
@@ -741,4 +835,4 @@ Experimental version released on August 20th, 2007.
===========================================================================
vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2
# vim: syntax=markdown:textwidth=75:expandtab:shiftwidth=2:softtabstop=2
-37
View File
@@ -1,37 +0,0 @@
Introductory information Automated Testing Framework
===========================================================================
Introduction
************
The Automated Testing Framework (ATF) is a collection of libraries to
implement test programs in a variety of languages. At the moment, ATF
offers C, C++ and POSIX shell bindings with which to implement tests.
These bindings all offer a similar set of functionality and any test
program written with them exposes a consistent user interface.
ATF-based test programs rely on a separate runtime engine to execute them.
The runtime engine is in charge of isolating the test programs from the
rest of the system to ensure that their results are deterministic and that
they cannot affect the running system. The runtime engine is also
responsible for gathering the results of all tests and composing reports.
The current runtime of choice is Kyua.
Other documents
***************
* AUTHORS: List of authors and contributors for this project.
* COPYING: License information.
* INSTALL: Compilation and installation instructions. These is not the
standard document shipped with many packages, so be sure to read it for
things that are specific to ATF's build.
* NEWS: List of major changes between formal, published releases.
===========================================================================
vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2
+32 -11
View File
@@ -12,36 +12,57 @@ interface** to allow both humans and automation to run the tests.
ATF-based test programs **rely on an execution engine** to be run and
this execution engine is *not* shipped with ATF.
**[Kyua](https://github.com/jmmv/kyua/) is the engine of choice.**
**[Kyua](https://github.com/freebsd/kyua/) is the engine of choice.**
## Download
Formal releases for source files are available for download from GitHub:
* [atf 0.20](../../releases/tag/atf-0.20), released on February 7th, 2014.
* [atf 0.25](../../releases/tag/atf-0.25), released on September 2nd, 2026.
## Installation
You are encouraged to install binary packages for your operating system
wherever available:
* Fedora 20 and above: install the `atf` package with `yum install atf`.
* FreeBSD 10.0 and above: install the `atf` package with `pkg install atf`.
* NetBSD with pkgsrc: install the `pkgsrc/devel/atf` package.
* OpenBSD: install the `devel/atf` package with `pkg_add atf`.
* Ubuntu: install the `libatf-dev` and `atf-sh` packages with
`apt install libatf-dev atf-sh`.
Should you want to build and install ATF from the source tree provided
here, follow the instructions in the [INSTALL file](INSTALL).
here, follow the instructions in the [INSTALL file](INSTALL.md).
## More Reading
* AUTHORS: List of authors and contributors for this project.
* COPYING: License information.
* INSTALL.md: Compilation and installation instructions. These is not the
standard document shipped with many packages, so be sure to read it for
things that are specific to ATF's build.
* NEWS.md: List of major changes between formal, published releases.
## Other documents
* `AUTHORS`: List of authors and contributors for this project.
* `COPYING`: License information.
* `INSTALL.md`: Compilation and installation instructions. These is not the
standard document shipped with many packages, so be sure to read it for
things that are specific to ATF's build.
* `NEWS.md`: List of major changes between formal, published releases.
## Support
Please use the
[atf-discuss mailing list](https://groups.google.com/forum/#!forum/atf-discuss)
for any support inquiries related to `atf-c`, `atf-c++` or `atf-sh`.
If you have any questions on Kyua proper, please use the
[kyua-discuss mailing list](https://groups.google.com/forum/#!forum/kyua-discuss)
instead.
[[email protected]](mailto:[email protected]) mailing list
for any support inquiries related to `atf-c`, `atf-c++`, `atf-sh`, or `kyua`.
+3 -1
View File
@@ -22,7 +22,7 @@
.\" 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 May 11, 2025
.Dd October 13, 2014
.Dt ATF-C++ 3
.Os
.Sh NAME
@@ -285,6 +285,8 @@ additional kernel modules in the test case's body by using the
.Fn require_kmod
function, which takes the name of a single module.
If it is not found, the test case will be automatically skipped.
This feature is only available on
.Fx .
.Ss Requiring programs
Aside from the
.Va require.progs
+2 -1
View File
@@ -150,5 +150,6 @@ impl::exec(const atf::process::argv_array& argva)
if (atf_is_error(err))
throw_atf_error(err);
return std::unique_ptr< impl::check_result >(new impl::check_result(&result));
return std::unique_ptr< impl::check_result >(
new impl::check_result(&result));
}
+2 -1
View File
@@ -71,7 +71,8 @@ class check_result {
check_result(const atf_check_result_t* result);
friend check_result test_constructor(const char* const*);
friend std::unique_ptr< check_result > exec(const atf::process::argv_array&);
friend std::unique_ptr< check_result >
exec(const atf::process::argv_array&);
public:
//!
-1
View File
@@ -3,7 +3,6 @@ syntax("kyuafile", 1)
test_suite("atf")
atf_test_program{name="application_test"}
atf_test_program{name="auto_array_test"}
atf_test_program{name="env_test"}
atf_test_program{name="exceptions_test"}
atf_test_program{name="fs_test"}
+3 -13
View File
@@ -37,6 +37,7 @@ extern "C" {
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <iostream>
extern "C" {
@@ -205,19 +206,8 @@ impl::app::run(int argc, char* const* argv)
m_argc = argc;
m_argv = argv;
m_argv0 = m_argv[0];
m_prog_name = std::strrchr(m_argv[0], '/');
if (m_prog_name == NULL)
m_prog_name = m_argv[0];
else
m_prog_name++;
// Libtool workaround: if running from within the source tree (binaries
// that are not installed yet), skip the "lt-" prefix added to files in
// the ".libs" directory to show the real (not temporary) name.
if (std::strncmp(m_prog_name, "lt-", 3) == 0)
m_prog_name += 3;
auto m_prog_filename = std::filesystem::path(m_argv[0]).filename();
m_prog_name = m_prog_filename.c_str();
const std::string bug =
std::string("This is probably a bug in ") + m_prog_name +
@@ -81,7 +81,6 @@ protected:
int m_argc;
char* const* m_argv;
const char* m_argv0;
const char* m_prog_name;
std::string m_description;
std::string m_manpage;
-175
View File
@@ -1,175 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. 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.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 !defined(ATF_CXX_DETAIL_AUTO_ARRAY_HPP)
#define ATF_CXX_DETAIL_AUTO_ARRAY_HPP
#include <cstddef>
namespace atf {
// ------------------------------------------------------------------------
// The "auto_array" class.
// ------------------------------------------------------------------------
template< class T >
struct auto_array_ref {
T* m_ptr;
explicit auto_array_ref(T*);
};
template< class T >
auto_array_ref< T >::auto_array_ref(T* ptr) :
m_ptr(ptr)
{
}
template< class T >
class auto_array {
T* m_ptr;
public:
auto_array(T* = NULL) throw();
auto_array(auto_array< T >&) throw();
auto_array(auto_array_ref< T >) throw();
~auto_array(void) throw();
T* get(void) throw();
const T* get(void) const throw();
T* release(void) throw();
void reset(T* = NULL) throw();
auto_array< T >& operator=(auto_array< T >&) throw();
auto_array< T >& operator=(auto_array_ref< T >) throw();
T& operator[](int) throw();
operator auto_array_ref< T >(void) throw();
};
template< class T >
auto_array< T >::auto_array(T* ptr)
throw() :
m_ptr(ptr)
{
}
template< class T >
auto_array< T >::auto_array(auto_array< T >& ptr)
throw() :
m_ptr(ptr.release())
{
}
template< class T >
auto_array< T >::auto_array(auto_array_ref< T > ref)
throw() :
m_ptr(ref.m_ptr)
{
}
template< class T >
auto_array< T >::~auto_array(void)
throw()
{
if (m_ptr != NULL)
delete [] m_ptr;
}
template< class T >
T*
auto_array< T >::get(void)
throw()
{
return m_ptr;
}
template< class T >
const T*
auto_array< T >::get(void)
const throw()
{
return m_ptr;
}
template< class T >
T*
auto_array< T >::release(void)
throw()
{
T* ptr = m_ptr;
m_ptr = NULL;
return ptr;
}
template< class T >
void
auto_array< T >::reset(T* ptr)
throw()
{
if (m_ptr != NULL)
delete [] m_ptr;
m_ptr = ptr;
}
template< class T >
auto_array< T >&
auto_array< T >::operator=(auto_array< T >& ptr)
throw()
{
reset(ptr.release());
return *this;
}
template< class T >
auto_array< T >&
auto_array< T >::operator=(auto_array_ref< T > ref)
throw()
{
if (m_ptr != ref.m_ptr) {
delete [] m_ptr;
m_ptr = ref.m_ptr;
}
return *this;
}
template< class T >
T&
auto_array< T >::operator[](int pos)
throw()
{
return m_ptr[pos];
}
template< class T >
auto_array< T >::operator auto_array_ref< T >(void)
throw()
{
return auto_array_ref< T >(release());
}
} // namespace atf
#endif // !defined(ATF_CXX_DETAIL_AUTO_ARRAY_HPP)
@@ -1,302 +0,0 @@
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. 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.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "atf-c++/detail/auto_array.hpp"
extern "C" {
#include <sys/types.h>
}
#include <iostream>
#include <atf-c++.hpp>
extern "C" {
#include "atf-c/defs.h"
}
// ------------------------------------------------------------------------
// Tests for the "auto_array" class.
// ------------------------------------------------------------------------
class test_array {
public:
int m_value;
static ssize_t m_nblocks;
static
atf::auto_array< test_array >
do_copy(atf::auto_array< test_array >& ta)
{
return atf::auto_array< test_array >(ta);
}
void* operator new(size_t size ATF_DEFS_ATTRIBUTE_UNUSED)
{
ATF_FAIL("New called but should have been new[]");
return new int(5);
}
void* operator new[](size_t size)
{
m_nblocks++;
void* mem = ::operator new(size);
std::cout << "Allocated 'test_array' object " << mem << "\n";
return mem;
}
void operator delete(void* mem ATF_DEFS_ATTRIBUTE_UNUSED)
{
ATF_FAIL("Delete called but should have been delete[]");
}
void operator delete[](void* mem)
{
std::cout << "Releasing 'test_array' object " << mem << "\n";
if (m_nblocks == 0)
ATF_FAIL("Unbalanced delete[]");
m_nblocks--;
::operator delete(mem);
}
};
ssize_t test_array::m_nblocks = 0;
ATF_TEST_CASE(auto_array_scope);
ATF_TEST_CASE_HEAD(auto_array_scope)
{
set_md_var("descr", "Tests the automatic scope handling in the "
"auto_array smart pointer class");
}
ATF_TEST_CASE_BODY(auto_array_scope)
{
using atf::auto_array;
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
{
auto_array< test_array > t(new test_array[10]);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_copy);
ATF_TEST_CASE_HEAD(auto_array_copy)
{
set_md_var("descr", "Tests the auto_array smart pointer class' copy "
"constructor");
}
ATF_TEST_CASE_BODY(auto_array_copy)
{
using atf::auto_array;
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
{
auto_array< test_array > t1(new test_array[10]);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
{
auto_array< test_array > t2(t1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_copy_ref);
ATF_TEST_CASE_HEAD(auto_array_copy_ref)
{
set_md_var("descr", "Tests the auto_array smart pointer class' copy "
"constructor through the auxiliary auto_array_ref object");
}
ATF_TEST_CASE_BODY(auto_array_copy_ref)
{
using atf::auto_array;
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
{
auto_array< test_array > t1(new test_array[10]);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
{
auto_array< test_array > t2 = test_array::do_copy(t1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_get);
ATF_TEST_CASE_HEAD(auto_array_get)
{
set_md_var("descr", "Tests the auto_array smart pointer class' get "
"method");
}
ATF_TEST_CASE_BODY(auto_array_get)
{
using atf::auto_array;
test_array* ta = new test_array[10];
auto_array< test_array > t(ta);
ATF_REQUIRE_EQ(t.get(), ta);
}
ATF_TEST_CASE(auto_array_release);
ATF_TEST_CASE_HEAD(auto_array_release)
{
set_md_var("descr", "Tests the auto_array smart pointer class' release "
"method");
}
ATF_TEST_CASE_BODY(auto_array_release)
{
using atf::auto_array;
test_array* ta1 = new test_array[10];
{
auto_array< test_array > t(ta1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
test_array* ta2 = t.release();
ATF_REQUIRE_EQ(ta2, ta1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
delete [] ta1;
}
ATF_TEST_CASE(auto_array_reset);
ATF_TEST_CASE_HEAD(auto_array_reset)
{
set_md_var("descr", "Tests the auto_array smart pointer class' reset "
"method");
}
ATF_TEST_CASE_BODY(auto_array_reset)
{
using atf::auto_array;
test_array* ta1 = new test_array[10];
test_array* ta2 = new test_array[10];
ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
{
auto_array< test_array > t(ta1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
t.reset(ta2);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
t.reset();
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_assign);
ATF_TEST_CASE_HEAD(auto_array_assign)
{
set_md_var("descr", "Tests the auto_array smart pointer class' "
"assignment operator");
}
ATF_TEST_CASE_BODY(auto_array_assign)
{
using atf::auto_array;
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
{
auto_array< test_array > t1(new test_array[10]);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
{
auto_array< test_array > t2;
t2 = t1;
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_assign_ref);
ATF_TEST_CASE_HEAD(auto_array_assign_ref)
{
set_md_var("descr", "Tests the auto_array smart pointer class' "
"assignment operator through the auxiliary auto_array_ref "
"object");
}
ATF_TEST_CASE_BODY(auto_array_assign_ref)
{
using atf::auto_array;
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
{
auto_array< test_array > t1(new test_array[10]);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
{
auto_array< test_array > t2;
t2 = test_array::do_copy(t1);
ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
}
ATF_TEST_CASE(auto_array_access);
ATF_TEST_CASE_HEAD(auto_array_access)
{
set_md_var("descr", "Tests the auto_array smart pointer class' access "
"operator");
}
ATF_TEST_CASE_BODY(auto_array_access)
{
using atf::auto_array;
auto_array< test_array > t(new test_array[10]);
for (int i = 0; i < 10; i++)
t[i].m_value = i * 2;
for (int i = 0; i < 10; i++)
ATF_REQUIRE_EQ(t[i].m_value, i * 2);
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
ATF_INIT_TEST_CASES(tcs)
{
// Add the test for the "auto_array" class.
ATF_ADD_TEST_CASE(tcs, auto_array_scope);
ATF_ADD_TEST_CASE(tcs, auto_array_copy);
ATF_ADD_TEST_CASE(tcs, auto_array_copy_ref);
ATF_ADD_TEST_CASE(tcs, auto_array_get);
ATF_ADD_TEST_CASE(tcs, auto_array_release);
ATF_ADD_TEST_CASE(tcs, auto_array_reset);
ATF_ADD_TEST_CASE(tcs, auto_array_assign);
ATF_ADD_TEST_CASE(tcs, auto_array_assign_ref);
ATF_ADD_TEST_CASE(tcs, auto_array_access);
}
-1
View File
@@ -32,7 +32,6 @@
extern "C" {
#include <sys/param.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dirent.h>
+10 -12
View File
@@ -46,31 +46,29 @@ namespace impl = atf::process;
// ------------------------------------------------------------------------
template< class C >
atf::auto_array< const char* >
std::vector<const char*>
collection_to_argv(const C& c)
{
atf::auto_array< const char* > argv(new const char*[c.size() + 1]);
std::vector<const char*> argv;
argv.reserve(c.size() + 1);
std::size_t pos = 0;
for (typename C::const_iterator iter = c.begin(); iter != c.end();
iter++) {
argv[pos] = (*iter).c_str();
pos++;
for (const auto& item : c) {
argv.push_back(item.c_str());
}
INV(pos == c.size());
argv[pos] = NULL;
argv.push_back(nullptr);
return argv;
}
template< class C >
template<class C>
C
argv_to_collection(const char* const* argv)
{
C c;
for (const char* const* iter = argv; *iter != NULL; iter++)
for (const char* const* iter = argv; *iter != nullptr; iter++) {
c.push_back(std::string(*iter));
}
return c;
}
@@ -123,7 +121,7 @@ const char* const*
impl::argv_array::exec_argv(void)
const
{
return m_exec_argv.get();
return m_exec_argv.data();
}
impl::argv_array::size_type
+1 -2
View File
@@ -36,7 +36,6 @@ extern "C" {
#include <string>
#include <vector>
#include <atf-c++/detail/auto_array.hpp>
#include <atf-c++/detail/exceptions.hpp>
#include <atf-c++/detail/fs.hpp>
@@ -58,7 +57,7 @@ class argv_array {
// std::tr1::shared_array instead when it becomes widely available.
// The reason would be to remove all copy constructors and assignment
// operators from this class.
auto_array< const char* > m_exec_argv;
std::vector< const char* > m_exec_argv;
void ctor_init_exec_argv(void);
public:
+13 -19
View File
@@ -196,22 +196,19 @@ ATF_TEST_CASE_BODY(argv_array_assign)
const char* const carray1[] = { "arg1", NULL };
const char* const carray2[] = { "arg1", "arg2", NULL };
std::unique_ptr< argv_array > argv1(new argv_array(carray1));
std::unique_ptr< argv_array > argv2(new argv_array(carray2));
argv_array argv1 = argv_array(carray1);
argv_array argv2 = argv_array(carray2);
*argv2 = *argv1;
ATF_REQUIRE_EQ(argv2->size(), argv1->size());
ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
argv2 = argv1;
ATF_REQUIRE_EQ(argv2.size(), argv1.size());
ATF_REQUIRE(std::strcmp(argv2[0], argv1[0]) == 0);
ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv());
argv1.release();
ATF_REQUIRE(argv2.exec_argv() != argv1.exec_argv());
{
const char* const* eargv2 = argv2->exec_argv();
const char* const* eargv2 = argv2.exec_argv();
ATF_REQUIRE(std::strcmp(eargv2[0], carray1[0]) == 0);
ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL));
}
argv2.release();
}
ATF_TEST_CASE(argv_array_copy);
@@ -226,21 +223,18 @@ ATF_TEST_CASE_BODY(argv_array_copy)
const char* const carray[] = { "arg0", NULL };
std::unique_ptr< argv_array > argv1(new argv_array(carray));
std::unique_ptr< argv_array > argv2(new argv_array(*argv1));
argv_array argv1 = argv_array(carray);
argv_array argv2 = argv1;
ATF_REQUIRE_EQ(argv2->size(), argv1->size());
ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
ATF_REQUIRE_EQ(argv2.size(), argv1.size());
ATF_REQUIRE(std::strcmp(argv2[0], argv1[0]) == 0);
ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv());
argv1.release();
ATF_REQUIRE(argv2.exec_argv() != argv1.exec_argv());
{
const char* const* eargv2 = argv2->exec_argv();
const char* const* eargv2 = argv2.exec_argv();
ATF_REQUIRE(std::strcmp(eargv2[0], carray[0]) == 0);
ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL));
}
argv2.release();
}
ATF_TEST_CASE(argv_array_exec_argv);
@@ -45,8 +45,6 @@
{ \
set_md_var("descr", "Tests that the " hdrname " file can be " \
"included on its own, without any prerequisites"); \
const std::string cxx = atf::env::get("ATF_BUILD_CXX", ATF_BUILD_CXX); \
set_md_var("require.progs", cxx); \
} \
ATF_TEST_CASE_BODY(name) \
{ \
@@ -58,8 +56,6 @@
ATF_TEST_CASE_HEAD(name) \
{ \
set_md_var("descr", descr); \
const std::string cxx = atf::env::get("ATF_BUILD_CXX", ATF_BUILD_CXX); \
set_md_var("require.progs", cxx); \
} \
ATF_TEST_CASE_BODY(name) \
{ \
-8
View File
@@ -42,14 +42,6 @@ extern "C" {
namespace impl = atf::text;
#define IMPL_NAME "atf::text"
char*
impl::duplicate(const char* str)
{
char* copy = new char[std::strlen(str) + 1];
std::strcpy(copy, str);
return copy;
}
bool
impl::match(const std::string& str, const std::string& regex)
{
-8
View File
@@ -38,14 +38,6 @@ extern "C" {
namespace atf {
namespace text {
//!
//! \brief Duplicates a C string using the new[] allocator.
//!
//! Replaces the functionality of strdup by using the new[] allocator and
//! thus allowing the resulting memory to be managed by utils::auto_array.
//!
char* duplicate(const char*);
//!
//! \brief Joins multiple words into a string.
//!
-21
View File
@@ -35,26 +35,6 @@
// Test cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE(duplicate);
ATF_TEST_CASE_HEAD(duplicate)
{
set_md_var("descr", "Tests the duplicate function");
}
ATF_TEST_CASE_BODY(duplicate)
{
using atf::text::duplicate;
const char* orig = "foo";
char* copy = duplicate(orig);
ATF_REQUIRE_EQ(std::strlen(copy), 3);
ATF_REQUIRE(std::strcmp(copy, "foo") == 0);
std::strcpy(copy, "bar");
ATF_REQUIRE(std::strcmp(copy, "bar") == 0);
ATF_REQUIRE(std::strcmp(orig, "foo") == 0);
}
ATF_TEST_CASE(join);
ATF_TEST_CASE_HEAD(join)
{
@@ -373,7 +353,6 @@ ATF_TEST_CASE_BODY(to_type)
ATF_INIT_TEST_CASES(tcs)
{
// Add the test cases for the free functions.
ATF_ADD_TEST_CASE(tcs, duplicate);
ATF_ADD_TEST_CASE(tcs, join);
ATF_ADD_TEST_CASE(tcs, match);
ATF_ADD_TEST_CASE(tcs, split);
+19 -29
View File
@@ -58,7 +58,6 @@ extern "C" {
}
#include "atf-c++/detail/application.hpp"
#include "atf-c++/detail/auto_array.hpp"
#include "atf-c++/detail/env.hpp"
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/fs.hpp"
@@ -123,13 +122,7 @@ static void
set_program_name(const char* argv0)
{
const std::string program_name = atf::fs::path(argv0).leaf_name();
// Libtool workaround: if running from within the source tree (binaries
// that are not installed yet), skip the "lt-" prefix added to files in
// the ".libs" directory to show the real (not temporary) name.
if (program_name.substr(0, 3) == "lt-")
Program_Name = program_name.substr(3);
else
Program_Name = program_name;
Program_Name = program_name;
}
bool
@@ -207,22 +200,22 @@ impl::tc::init(const vars_map& config)
{
atf_error_t err;
auto_array< const char * > array(new const char*[(config.size() * 2) + 1]);
const char **ptr = array.get();
std::vector< const char * > array;
array.reserve((config.size() * 2) + 1);
for (vars_map::const_iterator iter = config.begin();
iter != config.end(); iter++) {
*ptr = (*iter).first.c_str();
*(ptr + 1) = (*iter).second.c_str();
ptr += 2;
array.push_back((*iter).first.c_str());
array.push_back((*iter).second.c_str());
}
*ptr = NULL;
array.push_back(nullptr);
wraps[&pimpl->m_tc] = this;
cwraps[&pimpl->m_tc] = this;
err = atf_tc_init(&pimpl->m_tc, pimpl->m_ident.c_str(), pimpl->wrap_head,
pimpl->wrap_body, pimpl->m_has_cleanup ? pimpl->wrap_cleanup : NULL,
array.get());
array.data());
if (atf_is_error(err))
throw_atf_error(err);
}
@@ -273,6 +266,7 @@ impl::tc::get_md_vars(void)
char **ptr;
for (ptr = array; *ptr != NULL; ptr += 2)
vars[*ptr] = *(ptr + 1);
atf_utils_free_charpp(array);
} catch (...) {
atf_utils_free_charpp(array);
throw;
@@ -461,9 +455,7 @@ init_tcs(void (*add_tcs)(tc_vector&), tc_vector& tcs,
const atf::tests::vars_map& vars)
{
add_tcs(tcs);
for (tc_vector::iterator iter = tcs.begin(); iter != tcs.end(); iter++) {
impl::tc* tc = *iter;
for (auto& tc : tcs) {
tc->init(vars);
}
}
@@ -616,27 +608,25 @@ safe_main(int argc, char** argv, void (*add_tcs)(tc_vector&))
int errcode;
tc_vector tcs;
if (lflag) {
if (argc > 0)
throw usage_error("Cannot provide test case names with -l");
init_tcs(add_tcs, tcs, vars);
errcode = list_tcs(tcs);
} else {
if (argc == 0)
throw usage_error("Must provide a test case name");
else if (argc > 1)
throw usage_error("Cannot provide more than one test case name");
INV(argc == 1);
init_tcs(add_tcs, tcs, vars);
errcode = run_tc(tcs, argv[0], resfile);
}
for (tc_vector::iterator iter = tcs.begin(); iter != tcs.end(); iter++) {
impl::tc* tc = *iter;
delete tc;
tc_vector tcs;
try {
init_tcs(add_tcs, tcs, vars);
errcode = lflag ? list_tcs(tcs) : run_tc(tcs, argv[0], resfile);
} catch (...) {
for (auto& tc: tcs) {
delete tc;
}
throw;
}
return errcode;
+4
View File
@@ -163,6 +163,10 @@ ATF_TEST_CASE_BODY(atf_tp_writer)
expss << "descr: second test case\n";
CHECK;
w.tc_meta_data("require.kmods", "/nonexistent");
expss << "require.kmods: /nonexistent\n";
CHECK;
w.tc_meta_data("require.progs", "/bin/cp");
expss << "require.progs: /bin/cp\n";
CHECK;
-1
View File
@@ -1 +0,0 @@
defs.h
+11 -11
View File
@@ -22,7 +22,7 @@
.\" 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 June 12, 2025
.Dd October 10, 2025
.Dt ATF-C 3
.Os
.Sh NAME
@@ -244,7 +244,7 @@
.Fa "const char *contents"
.Fa "..."
.Fc
.Ft void
.Ft bool
.Fo atf_utils_file_exists
.Fa "const char *file"
.Fc
@@ -326,9 +326,9 @@ ATF_TC_BODY(tc3, tc)
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tcs, tc1);
ATF_TP_ADD_TC(tcs, tc2);
ATF_TP_ADD_TC(tcs, tc3);
ATF_TP_ADD_TC(tp, tc1);
ATF_TP_ADD_TC(tp, tc2);
ATF_TP_ADD_TC(tp, tc3);
... add additional test cases ...
return atf_no_error();
@@ -447,6 +447,8 @@ additional kernel modules in the test case's body by using the
.Fn atf_tc_require_kmod
function, which takes the name of a single kernel module.
If it is not found, the test case will be automatically skipped.
This feature is only available on
.Fx .
.Ss Requiring programs
Aside from the
.Va require.progs
@@ -620,12 +622,10 @@ observed integer in the second parameter.
.Fn ATF_CHECK_ERRNO
and
.Fn ATF_REQUIRE_ERRNO
take, first, the error code that the check is expecting to find in the
take an expected error code and a boolean expression, and fail the
test if either the expression is false or
.Va errno
variable and, second, a boolean expression that, if evaluates to true,
means that a call failed and
.Va errno
has to be checked against the first value.
is not equal to the expected error code.
.Ss Utility functions
The following functions are provided as part of the
.Nm
@@ -782,7 +782,7 @@ those spawned by
.Fc
.Bd -ragged -offset indent
Waits and validates the result of a subprocess spawned with
.Fn atf_utils_fork .
.Fn atf_utils_wait .
The validation involves checking that the subprocess exited cleanly and returned
the code specified in
.Fa expected_exit_status
+1 -1
View File
@@ -83,7 +83,7 @@ append_optargs(const char *const optargs[], atf_list_t *argv)
err = atf_no_error();
while (*optargs != NULL && !atf_is_error(err)) {
err = append_arg1(strdup(*optargs), argv);
err = append_arg1(*optargs, argv);
optargs++;
}
+1
View File
@@ -348,6 +348,7 @@ atf_check_result_fini(atf_check_result_t *r)
atf_list_fini(&r->pimpl->m_argv);
free(r->pimpl);
r->pimpl = NULL;
}
const char *
+1
View File
@@ -27,6 +27,7 @@
#define ATF_C_DEFS_H
#define ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(a, b) @ATTRIBUTE_FORMAT_PRINTF@
#define ATF_DEFS_ATTRIBUTE_NONNULL @ATTRIBUTE_NONNULL@
#define ATF_DEFS_ATTRIBUTE_NORETURN @ATTRIBUTE_NORETURN@
#define ATF_DEFS_ATTRIBUTE_UNUSED @ATTRIBUTE_UNUSED@
+14 -21
View File
@@ -45,22 +45,18 @@ atf_error_t
resize(atf_dynstr_t *ad, size_t newsize)
{
char *newdata;
atf_error_t err;
PRE(newsize > ad->m_datasize);
newdata = (char *)malloc(newsize);
if (newdata == NULL) {
err = atf_no_memory_error();
} else {
strcpy(newdata, ad->m_data);
free(ad->m_data);
ad->m_data = newdata;
ad->m_datasize = newsize;
err = atf_no_error();
}
newdata = realloc(ad->m_data, newsize);
if (newdata == NULL)
return atf_no_memory_error();
return err;
newdata[newsize - 1] = '\0';
ad->m_data = newdata;
ad->m_datasize = newsize;
return atf_no_error();
}
static
@@ -117,21 +113,16 @@ const size_t atf_dynstr_npos = SIZE_MAX;
atf_error_t
atf_dynstr_init(atf_dynstr_t *ad)
{
atf_error_t err;
ad->m_data = (char *)malloc(sizeof(char));
if (ad->m_data == NULL) {
err = atf_no_memory_error();
goto out;
}
ad->m_data = malloc(sizeof(char));
if (ad->m_data == NULL)
return atf_no_memory_error();
ad->m_data[0] = '\0';
ad->m_datasize = 1;
ad->m_length = 0;
err = atf_no_error();
out:
return err;
return atf_no_error();
}
atf_error_t
@@ -158,6 +149,7 @@ atf_dynstr_init_ap(atf_dynstr_t *ad, const char *fmt, va_list ap)
va_end(ap2);
if (ret < 0) {
free(ad->m_data);
ad->m_data = NULL;
err = atf_libc_error(errno, "Cannot format string");
goto out;
}
@@ -278,6 +270,7 @@ atf_dynstr_fini(atf_dynstr_t *ad)
{
INV(ad->m_data != NULL);
free(ad->m_data);
ad->m_data = NULL;
}
char *
+10 -11
View File
@@ -43,6 +43,8 @@
* Constructors and destructors.
*/
#define MAXLEN 8192
ATF_TC(init);
ATF_TC_HEAD(init, tc)
{
@@ -173,13 +175,12 @@ ATF_TC_HEAD(init_rep, tc)
}
ATF_TC_BODY(init_rep, tc)
{
const size_t maxlen = 8192;
char buf[maxlen + 1];
char buf[MAXLEN + 1];
size_t i;
buf[0] = '\0';
for (i = 0; i < maxlen; i++) {
for (i = 0; i < MAXLEN; i++) {
atf_dynstr_t str;
RE(atf_dynstr_init_rep(&str, i, 'a'));
@@ -371,15 +372,14 @@ static
void
check_append(atf_error_t (*append)(atf_dynstr_t *, const char *, ...))
{
const size_t maxlen = 8192;
char buf[maxlen + 1];
char buf[MAXLEN + 1];
size_t i;
atf_dynstr_t str;
printf("Appending with plain string\n");
buf[0] = '\0';
RE(atf_dynstr_init(&str));
for (i = 0; i < maxlen; i++) {
for (i = 0; i < MAXLEN; i++) {
if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
fprintf(stderr, "Failed at iteration %zd\n", i);
atf_tc_fail("Failed to append character at iteration %zd", i);
@@ -393,7 +393,7 @@ check_append(atf_error_t (*append)(atf_dynstr_t *, const char *, ...))
printf("Appending with formatted string\n");
buf[0] = '\0';
RE(atf_dynstr_init(&str));
for (i = 0; i < maxlen; i++) {
for (i = 0; i < MAXLEN; i++) {
if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
fprintf(stderr, "Failed at iteration %zd\n", i);
atf_tc_fail("Failed to append character at iteration %zd", i);
@@ -471,15 +471,14 @@ static
void
check_prepend(atf_error_t (*prepend)(atf_dynstr_t *, const char *, ...))
{
const size_t maxlen = 8192;
char buf[maxlen + 1];
char buf[MAXLEN + 1];
size_t i;
atf_dynstr_t str;
printf("Prepending with plain string\n");
buf[0] = '\0';
RE(atf_dynstr_init(&str));
for (i = 0; i < maxlen; i++) {
for (i = 0; i < MAXLEN; i++) {
if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
fprintf(stderr, "Failed at iteration %zd\n", i);
atf_tc_fail("Failed to prepend character at iteration %zd", i);
@@ -499,7 +498,7 @@ check_prepend(atf_error_t (*prepend)(atf_dynstr_t *, const char *, ...))
printf("Prepending with formatted string\n");
buf[0] = '\0';
RE(atf_dynstr_init(&str));
for (i = 0; i < maxlen; i++) {
for (i = 0; i < MAXLEN; i++) {
if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
fprintf(stderr, "Failed at iteration %zd\n", i);
atf_tc_fail("Failed to prepend character at iteration %zd", i);
+3 -38
View File
@@ -25,10 +25,6 @@
#include "atf-c/detail/env.h"
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#include <errno.h>
#include <stdlib.h>
@@ -65,25 +61,11 @@ atf_env_set(const char *name, const char *val)
{
atf_error_t err;
#if defined(HAVE_SETENV)
if (setenv(name, val, 1) == -1)
err = atf_libc_error(errno, "Cannot set environment variable "
"'%s' to '%s'", name, val);
err = atf_libc_error(errno,
"Cannot set environment variable '%s' to '%s'", name, val);
else
err = atf_no_error();
#elif defined(HAVE_PUTENV)
char *buf;
err = atf_text_format(&buf, "%s=%s", name, val);
if (!atf_is_error(err)) {
if (putenv(buf) == -1)
err = atf_libc_error(errno, "Cannot set environment variable "
"'%s' to '%s'", name, val);
free(buf);
}
#else
# error "Don't know how to set an environment variable."
#endif
return err;
}
@@ -91,24 +73,7 @@ atf_env_set(const char *name, const char *val)
atf_error_t
atf_env_unset(const char *name)
{
atf_error_t err;
#if defined(HAVE_UNSETENV)
unsetenv(name);
err = atf_no_error();
#elif defined(HAVE_PUTENV)
char *buf;
err = atf_text_format(&buf, "%s=", name);
if (!atf_is_error(err)) {
if (putenv(buf) == -1)
err = atf_libc_error(errno, "Cannot unset environment variable"
" '%s'", name);
free(buf);
}
#else
# error "Don't know how to unset an environment variable."
#endif
return err;
return (atf_no_error());
}
+10 -47
View File
@@ -31,7 +31,6 @@
#include <sys/types.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
@@ -59,7 +58,6 @@ static atf_error_t do_mkdtemp(char *);
static atf_error_t normalize(atf_dynstr_t *, char *);
static atf_error_t normalize_ap(atf_dynstr_t *, const char *, va_list);
static void replace_contents(atf_fs_path_t *, const char *);
static const char *stat_type_to_string(const int);
/* ---------------------------------------------------------------------
* The "unknown_file_type" error type.
@@ -109,16 +107,12 @@ atf_error_t
copy_contents(const atf_fs_path_t *p, char **buf)
{
atf_error_t err;
char *str;
str = (char *)malloc(atf_dynstr_length(&p->m_data) + 1);
if (str == NULL)
*buf = strdup(atf_fs_path_cstring(p));
if (*buf == NULL)
err = atf_no_memory_error();
else {
strcpy(str, atf_dynstr_cstring(&p->m_data));
*buf = str;
else
err = atf_no_error();
}
return err;
}
@@ -211,6 +205,7 @@ normalize_ap(atf_dynstr_t *d, const char *p, va_list ap)
else {
err = normalize(d, str);
free(str);
str = NULL;
}
out:
@@ -231,36 +226,6 @@ replace_contents(atf_fs_path_t *p, const char *buf)
INV(!atf_is_error(err));
}
static
const char *
stat_type_to_string(const int type)
{
const char *str;
if (type == atf_fs_stat_blk_type)
str = "block device";
else if (type == atf_fs_stat_chr_type)
str = "character device";
else if (type == atf_fs_stat_dir_type)
str = "directory";
else if (type == atf_fs_stat_fifo_type)
str = "named pipe";
else if (type == atf_fs_stat_lnk_type)
str = "symbolic link";
else if (type == atf_fs_stat_reg_type)
str = "regular file";
else if (type == atf_fs_stat_sock_type)
str = "socket";
else if (type == atf_fs_stat_wht_type)
str = "whiteout";
else {
UNREACHABLE;
str = NULL;
}
return str;
}
/* ---------------------------------------------------------------------
* The "atf_fs_path" type.
* --------------------------------------------------------------------- */
@@ -730,15 +695,14 @@ atf_fs_mkdtemp(atf_fs_path_t *p)
err = do_mkdtemp(buf);
if (atf_is_error(err))
goto out_buf;
goto out;
replace_contents(p, buf);
INV(!atf_is_error(err));
out_buf:
free(buf);
out:
umask(mask);
(void)umask(mask);
free(buf);
return err;
}
@@ -759,16 +723,15 @@ atf_fs_mkstemp(atf_fs_path_t *p, int *fdout)
err = do_mkstemp(buf, &fd);
if (atf_is_error(err))
goto out_buf;
goto out;
replace_contents(p, buf);
*fdout = fd;
INV(!atf_is_error(err));
out_buf:
free(buf);
out:
umask(mask);
(void)umask(mask);
free(buf);
return err;
}
+7 -4
View File
@@ -901,8 +901,8 @@ do_umask_check(atf_error_t (*const mk_func)(atf_fs_path_t *),
const char *exp_name)
{
atf_fs_path_t path;
int pre_mask, post_mask;
atf_error_t err;
mode_t pre_mask, post_mask;
printf("Creating temporary %s with umask %05o\n", exp_name, test_mask);
@@ -1039,9 +1039,12 @@ ATF_TC_BODY(mkstemp_umask, tc)
RE(atf_fs_path_init_fmt(&p, "testfile.XXXXXX"));
do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00100, "regular file");
do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00200, "regular file");
do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00400, "regular file");
do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00100,
"regular file");
do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00200,
"regular file");
do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00400,
"regular file");
atf_fs_path_fini(&p);
}
+4 -1
View File
@@ -84,8 +84,10 @@ static
void
delete_entry(struct list_entry *le)
{
if (le->m_managed)
if (le->m_managed) {
free(le->m_object);
le->m_object = NULL;
}
free(le);
}
@@ -204,6 +206,7 @@ atf_list_init(atf_list_t *l)
leend = new_entry(NULL, false);
if (leend == NULL) {
free(lebeg);
lebeg = NULL;
return atf_no_memory_error();
}
+17 -5
View File
@@ -188,7 +188,12 @@ atf_map_init_charpp(atf_map_t *m, const char *const *array)
}
ptr++;
err = atf_map_insert(m, key, strdup(value), true);
char *tmp_value = strdup(value);
if (tmp_value == NULL) {
err = atf_no_memory_error();
break;
}
err = atf_map_insert(m, key, tmp_value, true);
}
}
@@ -206,9 +211,12 @@ atf_map_fini(atf_map_t *m)
atf_list_for_each(iter, &m->m_list) {
struct map_entry *me = atf_list_iter_data(iter);
if (me->m_managed)
if (me->m_managed) {
free(me->m_value);
me->m_value = NULL;
}
free(me->m_key);
me->m_key = NULL;
free(me);
}
atf_list_fini(&m->m_list);
@@ -353,9 +361,11 @@ atf_map_insert(atf_map_t *m, const char *key, void *value, bool managed)
iter = atf_map_find(m, key);
if (atf_equal_map_iter_map_iter(iter, atf_map_end(m))) {
me = new_entry(key, value, managed);
if (me == NULL)
if (me == NULL) {
err = atf_no_memory_error();
else {
if (managed)
free(value);
} else {
err = atf_list_append(&m->m_list, me, false);
if (atf_is_error(err)) {
if (managed)
@@ -364,8 +374,10 @@ atf_map_insert(atf_map_t *m, const char *key, void *value, bool managed)
}
} else {
me = iter.m_entry;
if (me->m_managed)
if (me->m_managed) {
free(me->m_value);
me->m_value = NULL;
}
INV(strcmp(me->m_key, key) == 0);
me->m_value = value;
+1
View File
@@ -108,6 +108,7 @@ ATF_TC_BODY(map_init_charpp_short, tc)
atf_error_t err = atf_map_init_charpp(&map, array);
ATF_REQUIRE(atf_is_error(err));
ATF_REQUIRE(atf_error_is(err, "libc"));
atf_error_free(err);
}
/*
+24 -35
View File
@@ -23,6 +23,8 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include "config.h"
#include "atf-c/detail/process.h"
#include <sys/types.h>
@@ -42,7 +44,7 @@
/* This prototype is not in the header file because this is a private
* function; however, we need to access it during testing. */
atf_error_t atf_process_status_init(atf_process_status_t *, int);
atf_error_t atf_process_status_init(atf_process_status_t *, siginfo_t *);
/* ---------------------------------------------------------------------
* The "stream_prepare" auxiliary type.
@@ -65,6 +67,8 @@ stream_prepare_init(stream_prepare_t *sp, const atf_process_stream_t *sb)
const int type = atf_process_stream_type(sb);
sp->m_sb = sb;
sp->m_pipefds[0] = -1;
sp->m_pipefds[1] = -1;
sp->m_pipefds_ok = false;
if (type == atf_process_stream_type_capture) {
@@ -186,10 +190,10 @@ atf_process_stream_type(const atf_process_stream_t *sb)
* --------------------------------------------------------------------- */
atf_error_t
atf_process_status_init(atf_process_status_t *s, int status)
atf_process_status_init(atf_process_status_t *s, siginfo_t *info)
{
s->m_status = status;
s->m_info = *info;
return atf_no_error();
}
@@ -201,43 +205,36 @@ atf_process_status_fini(atf_process_status_t *s ATF_DEFS_ATTRIBUTE_UNUSED)
bool
atf_process_status_exited(const atf_process_status_t *s)
{
int mutable_status = s->m_status;
return WIFEXITED(mutable_status);
return s->m_info.si_code == CLD_EXITED;
}
int
atf_process_status_exitstatus(const atf_process_status_t *s)
{
PRE(atf_process_status_exited(s));
int mutable_status = s->m_status;
return WEXITSTATUS(mutable_status);
return s->m_info.si_status;
}
bool
atf_process_status_signaled(const atf_process_status_t *s)
{
int mutable_status = s->m_status;
return WIFSIGNALED(mutable_status);
/* Issue #187: `si_code` is a macro on NetBSD. */
int code = s->m_info.si_code;
return code == CLD_KILLED || code == CLD_DUMPED;
}
int
atf_process_status_termsig(const atf_process_status_t *s)
{
PRE(atf_process_status_signaled(s));
int mutable_status = s->m_status;
return WTERMSIG(mutable_status);
return s->m_info.si_status;
}
bool
atf_process_status_coredump(const atf_process_status_t *s)
{
PRE(atf_process_status_signaled(s));
#if defined(WCOREDUMP)
int mutable_status = s->m_status;
return WCOREDUMP(mutable_status);
#else
return false;
#endif
return s->m_info.si_code == CLD_DUMPED;
}
/* ---------------------------------------------------------------------
@@ -245,14 +242,12 @@ atf_process_status_coredump(const atf_process_status_t *s)
* --------------------------------------------------------------------- */
static
atf_error_t
void
atf_process_child_init(atf_process_child_t *c)
{
c->m_pid = 0;
c->m_stdout = -1;
c->m_stderr = -1;
return atf_no_error();
}
static
@@ -269,14 +264,14 @@ atf_error_t
atf_process_child_wait(atf_process_child_t *c, atf_process_status_t *s)
{
atf_error_t err;
int status;
siginfo_t info;
if (waitpid(c->m_pid, &status, 0) == -1)
if (waitid(P_PID, c->m_pid, &info, WEXITED) == -1)
err = atf_libc_error(errno, "Failed waiting for process %d",
c->m_pid);
else {
atf_process_child_fini(c);
err = atf_process_status_init(s, status);
err = atf_process_status_init(s, &info);
}
return err;
@@ -347,7 +342,7 @@ child_connect(const stream_prepare_t *sp, int procfd)
err = safe_dup(sp->m_sb->m_fd, procfd);
} else if (type == atf_process_stream_type_redirect_path) {
int aux = open(atf_fs_path_cstring(sp->m_sb->m_path),
O_WRONLY | O_CREAT | O_TRUNC, 0644);
O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
if (aux == -1)
err = atf_libc_error(errno, "Could not create %s",
atf_fs_path_cstring(sp->m_sb->m_path));
@@ -387,25 +382,17 @@ parent_connect(const stream_prepare_t *sp, int *fd)
}
static
atf_error_t
void
do_parent(atf_process_child_t *c,
const pid_t pid,
const stream_prepare_t *outsp,
const stream_prepare_t *errsp)
{
atf_error_t err;
err = atf_process_child_init(c);
if (atf_is_error(err))
goto out;
c->m_pid = pid;
parent_connect(outsp, &c->m_stdout);
parent_connect(errsp, &c->m_stderr);
out:
return err;
}
static
@@ -481,7 +468,7 @@ fork_with_streams(atf_process_child_t *c,
abort();
err = atf_no_error();
} else {
err = do_parent(c, pid, &outsp, &errsp);
do_parent(c, pid, &outsp, &errsp);
if (atf_is_error(err))
goto err_errpipe;
}
@@ -528,6 +515,8 @@ atf_process_fork(atf_process_child_t *c,
atf_process_stream_t inherit_outsb, inherit_errsb;
const atf_process_stream_t *real_outsb, *real_errsb;
atf_process_child_init(c);
real_outsb = NULL; /* Shut up GCC warning. */
err = init_stream_w_default(outsb, &inherit_outsb, &real_outsb);
if (atf_is_error(err))
@@ -665,7 +654,7 @@ atf_process_exec_list(atf_process_status_t *s,
err = atf_process_exec_array(s, prog, argv2, outsb, errsb, prehook);
free(argv2);
out:
free(argv2);
return err;
}
+2 -1
View File
@@ -28,6 +28,7 @@
#include <sys/types.h>
#include <signal.h>
#include <stdbool.h>
#include <atf-c/detail/fs.h>
@@ -76,7 +77,7 @@ int atf_process_stream_type(const atf_process_stream_t *);
* --------------------------------------------------------------------- */
struct atf_process_status {
int m_status;
siginfo_t m_info;
};
typedef struct atf_process_status atf_process_status_t;
+30 -27
View File
@@ -26,9 +26,6 @@
#include "atf-c/detail/process.h"
#include <sys/types.h>
#ifdef __FreeBSD__
#include <sys/sysctl.h>
#endif
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
@@ -47,7 +44,7 @@
#include "atf-c/detail/sanity.h"
#include "atf-c/detail/test_helpers.h"
atf_error_t atf_process_status_init(atf_process_status_t *, int);
atf_error_t atf_process_status_init(atf_process_status_t *, siginfo_t *);
/* ---------------------------------------------------------------------
* Auxiliary functions for testing of 'atf_process_fork'.
@@ -166,6 +163,7 @@ capture_stream_fini(void *v)
}
free(s->m_msg);
s->m_msg = NULL;
atf_process_stream_fini(&s->m_base.m_sb);
}
@@ -576,23 +574,19 @@ child_sigterm(void)
}
static
int
fork_and_wait_child(void (*child_func)(void))
void
fork_and_wait_child(void (*child_func)(void), siginfo_t *info)
{
pid_t pid;
int status;
pid = fork();
ATF_REQUIRE(pid != -1);
if (pid == 0) {
status = 0; /* Silence compiler warnings */
child_func();
UNREACHABLE;
} else {
ATF_REQUIRE(waitpid(pid, &status, 0) != 0);
ATF_REQUIRE(waitid(P_PID, pid, info, WEXITED) != -1);
}
return status;
}
ATF_TC(status_exited);
@@ -603,10 +597,12 @@ ATF_TC_HEAD(status_exited, tc)
}
ATF_TC_BODY(status_exited, tc)
{
siginfo_t info;
{
const int rawstatus = fork_and_wait_child(child_exit_success);
fork_and_wait_child(child_exit_success, &info);
atf_process_status_t s;
RE(atf_process_status_init(&s, rawstatus));
RE(atf_process_status_init(&s, &info));
ATF_CHECK(atf_process_status_exited(&s));
ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_SUCCESS);
ATF_CHECK(!atf_process_status_signaled(&s));
@@ -614,9 +610,9 @@ ATF_TC_BODY(status_exited, tc)
}
{
const int rawstatus = fork_and_wait_child(child_exit_failure);
fork_and_wait_child(child_exit_failure, &info);
atf_process_status_t s;
RE(atf_process_status_init(&s, rawstatus));
RE(atf_process_status_init(&s, &info));
ATF_CHECK(atf_process_status_exited(&s));
ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_FAILURE);
ATF_CHECK(!atf_process_status_signaled(&s));
@@ -632,10 +628,12 @@ ATF_TC_HEAD(status_signaled, tc)
}
ATF_TC_BODY(status_signaled, tc)
{
siginfo_t info;
{
const int rawstatus = fork_and_wait_child(child_sigkill);
fork_and_wait_child(child_sigkill, &info);
atf_process_status_t s;
RE(atf_process_status_init(&s, rawstatus));
RE(atf_process_status_init(&s, &info));
ATF_CHECK(!atf_process_status_exited(&s));
ATF_CHECK(atf_process_status_signaled(&s));
ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGKILL);
@@ -644,9 +642,9 @@ ATF_TC_BODY(status_signaled, tc)
}
{
const int rawstatus = fork_and_wait_child(child_sigterm);
fork_and_wait_child(child_sigterm, &info);
atf_process_status_t s;
RE(atf_process_status_init(&s, rawstatus));
RE(atf_process_status_init(&s, &info));
ATF_CHECK(!atf_process_status_exited(&s));
ATF_CHECK(atf_process_status_signaled(&s));
ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGTERM);
@@ -670,17 +668,22 @@ ATF_TC_BODY(status_coredump, tc)
atf_tc_skip("Cannot unlimit the core file size; check limits "
"manually");
#ifdef __FreeBSD__
int coredump_enabled;
size_t ce_len = sizeof(coredump_enabled);
if (sysctlbyname("kern.coredump", &coredump_enabled, &ce_len, NULL,
0) == 0 && !coredump_enabled)
atf_tc_skip("Coredumps disabled");
#if defined(__APPLE__)
/*
* The default security policy on macOS prevents this check from being
* tested (coredumps aren't generated for unsigned binaries).
*
* TODO(ngie,144): this test fails when run locally on my machines, but not
* in the GHA container images.
*/
atf_tc_skip(
"atf_process_status_coredump check fails on macOS");
#endif
const int rawstatus = fork_and_wait_child(child_sigquit);
siginfo_t info;
fork_and_wait_child(child_sigquit, &info);
atf_process_status_t s;
RE(atf_process_status_init(&s, rawstatus));
RE(atf_process_status_init(&s, &info));
ATF_CHECK(!atf_process_status_exited(&s));
ATF_CHECK(atf_process_status_signaled(&s));
ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGQUIT);
+6 -3
View File
@@ -85,6 +85,8 @@ do_test_child(void *v)
exit(EXIT_SUCCESS);
}
#define MAX_LINES 3
static
void
do_test(enum type t, bool cond)
@@ -92,7 +94,7 @@ do_test(enum type t, bool cond)
atf_process_child_t child;
atf_process_status_t status;
int nlines;
char *lines[3];
char *lines[MAX_LINES] = { 0 };
{
atf_process_stream_t outsb, errsb;
@@ -106,16 +108,17 @@ do_test(enum type t, bool cond)
}
nlines = 0;
while (nlines < 3 && (lines[nlines] =
while (nlines < MAX_LINES && (lines[nlines] =
atf_utils_readline(atf_process_child_stderr(&child))) != NULL)
nlines++;
ATF_REQUIRE(nlines == 0 || nlines == 3);
RE(atf_process_child_wait(&child, &status));
if (!cond) {
ATF_REQUIRE(nlines == MAX_LINES);
ATF_REQUIRE(atf_process_status_signaled(&status));
ATF_REQUIRE(atf_process_status_termsig(&status) == SIGABRT);
} else {
ATF_REQUIRE(nlines == 0);
ATF_REQUIRE(atf_process_status_exited(&status));
ATF_REQUIRE(atf_process_status_exitstatus(&status) == EXIT_SUCCESS);
}
+1
View File
@@ -56,6 +56,7 @@ atf_text_for_each_word(const char *instr, const char *sep,
}
free(str);
str = NULL;
out:
return err;
}
+26 -33
View File
@@ -198,8 +198,8 @@ params_fini(struct params *p)
atf_map_fini(&p->m_config);
atf_fs_path_fini(&p->m_resfile);
atf_fs_path_fini(&p->m_srcdir);
if (p->m_tcname != NULL)
free(p->m_tcname);
free(p->m_tcname);
p->m_tcname = NULL;
}
static
@@ -248,7 +248,7 @@ static
void
list_tcs(const atf_tp_t *tp)
{
const atf_tc_t *const *tcs;
const atf_tc_t **tcs;
const atf_tc_t *const *tcsptr;
printf("Content-Type: application/X-atf-tp; version=\"1\"\n\n");
@@ -280,6 +280,8 @@ list_tcs(const atf_tp_t *tp)
atf_utils_free_charpp(vars);
}
free(tcs);
tcs = NULL;
}
/* ---------------------------------------------------------------------
@@ -288,19 +290,20 @@ list_tcs(const atf_tp_t *tp)
static
atf_error_t
handle_tcarg(const char *tcarg, char **tcname, enum tc_part *tcpart)
handle_tcarg(const char *tcarg, char **tcname_out, enum tc_part *tcpart)
{
char *delim, *tcname;
atf_error_t err;
*tcname_out = NULL;
tcname = strdup(tcarg);
if (tcname == NULL) {
return atf_no_memory_error();
}
err = atf_no_error();
*tcname = strdup(tcarg);
if (*tcname == NULL) {
err = atf_no_memory_error();
goto out;
}
char *delim = strchr(*tcname, ':');
delim = strchr(tcname, ':');
if (delim != NULL) {
*delim = '\0';
@@ -311,11 +314,12 @@ handle_tcarg(const char *tcarg, char **tcname, enum tc_part *tcpart)
*tcpart = CLEANUP;
} else {
err = usage_error("Invalid test case part `%s'", delim);
goto out;
free(tcname);
}
}
out:
if (!atf_is_error(err))
*tcname_out = tcname;
return err;
}
@@ -327,9 +331,7 @@ process_params(int argc, char **argv, struct params *p)
int ch;
int old_opterr;
err = params_init(p, argv[0]);
if (atf_is_error(err))
goto out;
err = atf_no_error();
old_opterr = opterr;
opterr = 0;
@@ -387,10 +389,6 @@ process_params(int argc, char **argv, struct params *p)
}
}
if (atf_is_error(err))
params_fini(p);
out:
return err;
}
@@ -484,12 +482,10 @@ run_tc(const atf_tp_t *tp, struct params *p, int *exitcode)
{
atf_error_t err;
err = atf_no_error();
if (!atf_tp_has_tc(tp, p->m_tcname))
return usage_error("Unknown test case `%s'", p->m_tcname);
if (!atf_tp_has_tc(tp, p->m_tcname)) {
err = usage_error("Unknown test case `%s'", p->m_tcname);
goto out;
}
err = atf_no_error();
if (!atf_env_has("__RUNNING_INSIDE_ATF_RUN") || strcmp(atf_env_get(
"__RUNNING_INSIDE_ATF_RUN"), "internal-yes-value") != 0)
@@ -529,7 +525,6 @@ run_tc(const atf_tp_t *tp, struct params *p, int *exitcode)
}
INV(!atf_is_error(err));
out:
return err;
}
@@ -544,10 +539,14 @@ controlled_main(int argc, char **argv,
atf_tp_t tp;
char **raw_config;
err = process_params(argc, argv, &p);
err = params_init(&p, argv[0]);
if (atf_is_error(err))
goto out;
err = process_params(argc, argv, &p);
if (atf_is_error(err))
goto out_p;
err = handle_srcdir(&p);
if (atf_is_error(err))
goto out_p;
@@ -594,12 +593,6 @@ atf_tp_main(int argc, char **argv, atf_error_t (*add_tcs_hook)(atf_tp_t *))
else
progname++;
/* Libtool workaround: if running from within the source tree (binaries
* that are not installed yet), skip the "lt-" prefix added to files in
* the ".libs" directory to show the real (not temporary) name. */
if (strncmp(progname, "lt-", 3) == 0)
progname += 3;
exitcode = EXIT_FAILURE; /* Silence GCC warning. */
err = controlled_main(argc, argv, add_tcs_hook, &exitcode);
if (atf_is_error(err)) {
+6 -4
View File
@@ -32,7 +32,7 @@
#include "atf-c/detail/sanity.h"
/* Theoretically, there can only be a single error intance at any given
/* Theoretically, there can only be a single error instance at any given
* point in time, because errors are raised at one point and must be
* handled immediately. If another error has to be raised during the
* handling process, something else has to be done with the previous
@@ -124,11 +124,13 @@ atf_error_free(atf_error_t err)
freeit = err->m_free;
if (err->m_data != NULL)
free(err->m_data);
free(err->m_data);
err->m_data = NULL;
if (freeit)
if (freeit) {
free(err);
err = NULL;
}
error_on_flight = false;
}
+4 -4
View File
@@ -129,26 +129,26 @@
#define ATF_REQUIRE_MSG(expression, fmt, ...) \
do { \
if (!(expression)) \
if (expression) {} else \
atf_tc_fail_requirement(__FILE__, __LINE__, fmt, ##__VA_ARGS__); \
} while(0)
#define ATF_CHECK_MSG(expression, fmt, ...) \
do { \
if (!(expression)) \
if (expression) {} else \
atf_tc_fail_check(__FILE__, __LINE__, fmt, ##__VA_ARGS__); \
} while(0)
#define ATF_REQUIRE(expression) \
do { \
if (!(expression)) \
if (expression) {} else \
atf_tc_fail_requirement(__FILE__, __LINE__, "%s", \
#expression " not met"); \
} while(0)
#define ATF_CHECK(expression) \
do { \
if (!(expression)) \
if (expression) {} else \
atf_tc_fail_check(__FILE__, __LINE__, "%s", \
#expression " not met"); \
} while(0)
+41 -30
View File
@@ -26,7 +26,7 @@
#include "atf-c/tc.h"
#include <sys/types.h>
#ifdef __FreeBSD__
#if defined(__FreeBSD__)
#include <sys/linker.h>
#include <sys/module.h>
#endif
@@ -107,9 +107,7 @@ static void format_reason_fmt(atf_dynstr_t *, const char *, const size_t,
static void errno_test(struct context *, const char *, const size_t,
const int, const char *, const bool,
void (*)(struct context *, atf_dynstr_t *));
#ifdef __FreeBSD__
static atf_error_t check_kmod(struct context *, const char *);
#endif
static atf_error_t check_prog_in_dir(const char *, void *);
static atf_error_t check_prog(struct context *, const char *);
@@ -144,7 +142,7 @@ context_set_resfile(struct context *ctx, const char *resfile)
else if (strcmp(resfile, "/dev/stderr") == 0)
ctx->resfilefd = STDERR_FILENO;
else
ctx->resfilefd = open(resfile, O_WRONLY | O_CREAT | O_TRUNC,
ctx->resfilefd = open(resfile, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (ctx->resfilefd == -1) {
err = atf_libc_error(errno,
@@ -467,8 +465,8 @@ errno_test(struct context *ctx, const char *file, const size_t line,
}
}
#ifdef __FreeBSD__
static atf_error_t
#if defined(__FreeBSD__)
atf_error_t
check_kmod(struct context *ctx, const char *kmod)
{
struct kld_file_stat fstat = { .version = sizeof(fstat) };
@@ -478,26 +476,41 @@ check_kmod(struct context *ctx, const char *kmod)
int fid, mid;
for (fid = kldnext(0); fid > 0; fid = kldnext(fid)) {
if (kldstat(fid, &fstat) != 0)
continue;
if (strcmp(fstat.name, kmod) == 0)
goto done;
if (strncmp(fstat.name, kmod, len) == 0 &&
strcmp(fstat.name + len, ".ko") == 0)
goto done;
for (mid = kldfirstmod(fid); mid > 0; mid = modfnext(mid)) {
if (modstat(mid, &mstat) != 0)
continue;
if (strcmp(mstat.name, kmod) == 0)
goto done;
}
if (kldstat(fid, &fstat) != 0)
continue;
if (strcmp(fstat.name, kmod) == 0)
goto done;
if (strncmp(fstat.name, kmod, len) == 0 &&
strcmp(fstat.name + len, ".ko") == 0)
goto done;
for (mid = kldfirstmod(fid); mid > 0; mid = modfnext(mid)) {
if (modstat(mid, &mstat) != 0)
continue;
if (strcmp(mstat.name, kmod) == 0)
goto done;
}
}
format_reason_fmt(&reason, NULL, 0, "The required kmod %s "
"is not loaded", kmod);
format_reason_fmt(&reason, NULL, 0,
"The required kmod %s is not loaded", kmod);
fail_requirement(ctx, &reason);
done:
return atf_no_error();
}
#else
atf_error_t
check_kmod(struct context *ctx, const char *kmod ATF_DEFS_ATTRIBUTE_UNUSED)
{
atf_dynstr_t reason;
format_reason_fmt(&reason, NULL, 0,
"This API is only available on FreeBSD");
fail_requirement(ctx, &reason);
return atf_no_error();
}
#endif
struct prog_found_pair {
@@ -688,8 +701,10 @@ atf_tc_init_pack(atf_tc_t *tc, const atf_tc_pack_t *pack,
void
atf_tc_fini(atf_tc_t *tc)
{
atf_map_fini(&tc->pimpl->m_config);
atf_map_fini(&tc->pimpl->m_vars);
free(tc->pimpl);
tc->pimpl = NULL;
}
/*
@@ -851,8 +866,10 @@ atf_tc_set_md_var(atf_tc_t *tc, const char *name, const char *fmt, ...)
if (!atf_is_error(err))
err = atf_map_insert(&tc->pimpl->m_vars, name, value, true);
else
else {
free(value);
value = NULL;
}
return err;
}
@@ -869,9 +886,7 @@ static void _atf_tc_fail_check(struct context *, const char *, const size_t,
static void _atf_tc_fail_requirement(struct context *, const char *,
const size_t, const char *, va_list) ATF_DEFS_ATTRIBUTE_NORETURN;
static void _atf_tc_pass(struct context *) ATF_DEFS_ATTRIBUTE_NORETURN;
#ifdef __FreeBSD__
static void _atf_tc_require_kmod(struct context *, const char *);
#endif
static void _atf_tc_require_prog(struct context *, const char *);
static void _atf_tc_skip(struct context *, const char *, va_list)
ATF_DEFS_ATTRIBUTE_NORETURN;
@@ -951,13 +966,11 @@ _atf_tc_pass(struct context *ctx)
UNREACHABLE;
}
#ifdef __FreeBSD__
static void
_atf_tc_require_kmod(struct context *ctx, const char *kmod)
_atf_tc_require_kmod(struct context *ctx, const char *prog)
{
check_fatal_error(check_kmod(ctx, kmod));
check_fatal_error(check_kmod(ctx, prog));
}
#endif
static void
_atf_tc_require_prog(struct context *ctx, const char *prog)
@@ -1205,7 +1218,6 @@ atf_tc_pass(void)
_atf_tc_pass(&Current);
}
#ifdef __FreeBSD__
void
atf_tc_require_kmod(const char *kmod)
{
@@ -1213,7 +1225,6 @@ atf_tc_require_kmod(const char *kmod)
_atf_tc_require_kmod(&Current, kmod);
}
#endif
void
atf_tc_require_prog(const char *prog)
-2
View File
@@ -106,9 +106,7 @@ void atf_tc_fail_nonfatal(const char *, ...)
ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 2);
void atf_tc_pass(void)
ATF_DEFS_ATTRIBUTE_NORETURN;
#ifdef __FreeBSD__
void atf_tc_require_kmod(const char *);
#endif
void atf_tc_require_prog(const char *);
void atf_tc_skip(const char *, ...)
ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 2)
+86
View File
@@ -156,6 +156,84 @@ ATF_TC_BODY(config, tcin)
atf_tc_fini(&tc);
}
#if defined(__FreeBSD__)
ATF_TC(require_kmod_basic);
ATF_TC_HEAD(require_kmod_basic, tc)
{
atf_tc_set_md_var(tc, "descr",
"atf_require_kmod: ensures that a test continues if the target kmod "
"is found.");
}
ATF_TC_BODY(require_kmod_basic, tc)
{
#if 0
atf_tc_require_kmod("kernel");
#endif
}
ATF_TC(require_kmod_negative);
ATF_TC_HEAD(require_kmod_negative, tc)
{
atf_tc_set_md_var(tc, "descr",
"atf_require_kmod: skips test if the target kmod is not found.");
}
ATF_TC_BODY(require_kmod_negative, tc)
{
atf_tc_expect_fail("This should fail.");
atf_tc_require_kmod("nonexistent");
}
#endif
ATF_TC(require_prog_absolute);
ATF_TC_HEAD(require_prog_absolute, tc)
{
atf_tc_set_md_var(tc, "descr",
"atf_require_prog: ensures that a test continues if the target program "
"is found (absolute).");
}
ATF_TC_BODY(require_prog_absolute, tc)
{
atf_tc_require_prog("/bin/sh");
}
ATF_TC(require_prog_negative_absolute);
ATF_TC_HEAD(require_prog_negative_absolute, tc)
{
atf_tc_set_md_var(tc, "descr",
"atf_require_prog: skips test if the target program is not found "
"(absolute).");
}
ATF_TC_BODY(require_prog_negative_absolute, tc)
{
atf_tc_expect_fail("This should fail.");
atf_tc_require_prog("/nonexistent");
}
ATF_TC(require_prog_negative_nonabsolute);
ATF_TC_HEAD(require_prog_negative_nonabsolute, tc)
{
atf_tc_set_md_var(tc, "descr",
"atf_require_prog: skips test if the target program is not found "
"(non-absolute).");
}
ATF_TC_BODY(require_prog_negative_nonabsolute, tc)
{
atf_tc_expect_fail("This should fail.");
atf_tc_require_prog("nonexistent");
}
ATF_TC(require_prog_nonabsolute);
ATF_TC_HEAD(require_prog_nonabsolute, tc)
{
atf_tc_set_md_var(tc, "descr",
"atf_require_prog: ensures that a test continues if the target program "
"is found (non-absolute).");
}
ATF_TC_BODY(require_prog_nonabsolute, tc)
{
atf_tc_require_prog("true");
}
/* ---------------------------------------------------------------------
* Test cases for the free functions.
* --------------------------------------------------------------------- */
@@ -175,6 +253,14 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, init_pack);
ATF_TP_ADD_TC(tp, vars);
ATF_TP_ADD_TC(tp, config);
#if defined(__FreeBSD__)
ATF_TP_ADD_TC(tp, require_kmod_basic);
ATF_TP_ADD_TC(tp, require_kmod_negative);
#endif
ATF_TP_ADD_TC(tp, require_prog_absolute);
ATF_TP_ADD_TC(tp, require_prog_negative_absolute);
ATF_TP_ADD_TC(tp, require_prog_negative_nonabsolute);
ATF_TP_ADD_TC(tp, require_prog_nonabsolute);
/* Add the test cases for the free functions. */
/* TODO */
+2 -1
View File
@@ -112,6 +112,7 @@ atf_tp_fini(atf_tp_t *tp)
atf_list_fini(&tp->pimpl->m_tcs);
free(tp->pimpl);
tp->pimpl = NULL;
}
/*
@@ -139,7 +140,7 @@ atf_tp_get_tc(const atf_tp_t *tp, const char *id)
return tc;
}
const atf_tc_t *const *
const atf_tc_t **
atf_tp_get_tcs(const atf_tp_t *tp)
{
const atf_tc_t **array;
+1 -1
View File
@@ -50,7 +50,7 @@ void atf_tp_fini(atf_tp_t *);
char **atf_tp_get_config(const atf_tp_t *);
bool atf_tp_has_tc(const atf_tp_t *, const char *);
const struct atf_tc *atf_tp_get_tc(const atf_tp_t *, const char *);
const struct atf_tc *const *atf_tp_get_tcs(const atf_tp_t *);
const struct atf_tc **atf_tp_get_tcs(const atf_tp_t *);
/* Modifiers. */
atf_error_t atf_tp_add_tc(atf_tp_t *, struct atf_tc *);
+1
View File
@@ -23,6 +23,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#include "config.h"
#include "atf-c/tp.h"
#include <string.h>
+42 -30
View File
@@ -32,6 +32,7 @@
#include <errno.h>
#include <fcntl.h>
#include <regex.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -59,16 +60,19 @@ init_out_filename(atf_dynstr_t *name, const pid_t pid, const char *suffix,
{
atf_error_t error;
error = atf_dynstr_init_fmt(name, "atf_utils_fork_%d_%s.txt",
(int)pid, suffix);
if (atf_is_error(error)) {
char buffer[1024];
atf_error_format(error, buffer, sizeof(buffer));
if (in_parent) {
atf_tc_fail("Failed to create output file: %s", buffer);
} else {
err(EXIT_FAILURE, "Failed to create output file: %s", buffer);
}
error = atf_dynstr_init_fmt(name, "atf_utils_fork_%d_%s.txt", pid, suffix);
if (!atf_is_error(error))
return;
char buffer[1024];
atf_error_format(error, buffer, sizeof(buffer));
atf_error_free(error);
if (in_parent) {
atf_tc_fail("Failed to create output file: %s", buffer);
} else {
err(EXIT_FAILURE, "Failed to create output file: %s", buffer);
}
}
@@ -104,8 +108,8 @@ grep_string(const char *regex, const char *str)
void
atf_utils_cat_file(const char *name, const char *prefix)
{
const int fd = open(name, O_RDONLY);
ATF_REQUIRE_MSG(fd != -1, "Cannot open %s", name);
const int fd = open(name, O_RDONLY | O_CLOEXEC);
ATF_REQUIRE_MSG(fd != -1, "Cannot open %s: %s", name, strerror(errno));
char buffer[1024];
ssize_t count;
@@ -145,7 +149,7 @@ atf_utils_cat_file(const char *name, const char *prefix)
bool
atf_utils_compare_file(const char *name, const char *contents)
{
const int fd = open(name, O_RDONLY);
const int fd = open(name, O_RDONLY | O_CLOEXEC);
ATF_REQUIRE_MSG(fd != -1, "Cannot open %s", name);
const char *pos = contents;
@@ -173,11 +177,12 @@ atf_utils_compare_file(const char *name, const char *contents)
void
atf_utils_copy_file(const char *source, const char *destination)
{
const int input = open(source, O_RDONLY);
const int input = open(source, O_RDONLY | O_CLOEXEC);
ATF_REQUIRE_MSG(input != -1, "Failed to open source file during "
"copy (%s)", source);
const int output = open(destination, O_WRONLY | O_CREAT | O_TRUNC, 0777);
const int output = open(destination,
O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0777);
ATF_REQUIRE_MSG(output != -1, "Failed to open destination file during "
"copy (%s)", destination);
@@ -216,7 +221,7 @@ atf_utils_create_file(const char *name, const char *contents, ...)
va_end(ap);
ATF_REQUIRE(!atf_is_error(error));
const int fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
const int fd = open(name, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
ATF_REQUIRE_MSG(fd != -1, "Cannot create file %s", name);
ATF_REQUIRE(write(fd, atf_dynstr_cstring(&formatted),
atf_dynstr_length(&formatted)) != -1);
@@ -234,14 +239,12 @@ bool
atf_utils_file_exists(const char *path)
{
const int ret = access(path, F_OK);
if (ret == -1) {
if (errno != ENOENT)
atf_tc_fail("Failed to check the existence of %s: %s", path,
strerror(errno));
else
return false;
} else
if (ret != -1)
return true;
if (errno != ENOENT)
atf_tc_fail("Failed to check the existence of %s: %s", path,
strerror(errno));
return false;
}
/** Spawns a subprocess and redirects its output to files.
@@ -290,10 +293,13 @@ atf_utils_free_charpp(char **argv)
{
char **ptr;
for (ptr = argv; *ptr != NULL; ptr++)
for (ptr = argv; *ptr != NULL; ptr++) {
free(*ptr);
*ptr = NULL;
}
free(argv);
argv = NULL;
}
/** Searches for a regexp in a file.
@@ -316,7 +322,8 @@ atf_utils_grep_file(const char *regex, const char *file, ...)
va_end(ap);
ATF_REQUIRE(!atf_is_error(error));
ATF_REQUIRE((fd = open(file, O_RDONLY)) != -1);
fd = open(file, O_RDONLY | O_CLOEXEC);
ATF_REQUIRE_MSG(fd != -1, "Cannot open %s: %s", file, strerror(errno));
bool found = false;
char *line = NULL;
while (!found && (line = atf_utils_readline(fd)) != NULL) {
@@ -404,7 +411,8 @@ atf_utils_redirect(const int target_fd, const char *name)
else if (target_fd == STDERR_FILENO)
fflush(stderr);
const int new_fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
const int new_fd = open(name, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
0644);
if (new_fd == -1)
err(EXIT_FAILURE, "Cannot create %s", name);
if (new_fd != target_fd) {
@@ -425,8 +433,9 @@ void
atf_utils_wait(const pid_t pid, const int exitstatus, const char *expout,
const char *experr)
{
int status;
ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
siginfo_t info;
ATF_REQUIRE(waitid(P_PID, pid, &info, WEXITED) != -1);
ATF_REQUIRE(info.si_pid == pid);
atf_dynstr_t out_name;
init_out_filename(&out_name, pid, "out", true);
@@ -437,8 +446,8 @@ atf_utils_wait(const pid_t pid, const int exitstatus, const char *expout,
atf_utils_cat_file(atf_dynstr_cstring(&out_name), "subprocess stdout: ");
atf_utils_cat_file(atf_dynstr_cstring(&err_name), "subprocess stderr: ");
ATF_REQUIRE(WIFEXITED(status));
ATF_REQUIRE_EQ(exitstatus, WEXITSTATUS(status));
ATF_REQUIRE(info.si_code == CLD_EXITED);
ATF_REQUIRE_EQ(exitstatus, info.si_status);
const char *save_prefix = "save:";
const size_t save_prefix_length = strlen(save_prefix);
@@ -463,4 +472,7 @@ atf_utils_wait(const pid_t pid, const int exitstatus, const char *expout,
ATF_REQUIRE(unlink(atf_dynstr_cstring(&out_name)) != -1);
ATF_REQUIRE(unlink(atf_dynstr_cstring(&err_name)) != -1);
atf_dynstr_fini(&out_name);
atf_dynstr_fini(&err_name);
}
+1
View File
@@ -26,6 +26,7 @@
#if !defined(ATF_C_UTILS_H)
#define ATF_C_UTILS_H
#include <sys/types.h>
#include <stdbool.h>
#include <unistd.h>
-2
View File
@@ -1,2 +0,0 @@
atf-check
atf-sh
+1
View File
@@ -9,3 +9,4 @@ atf_test_program{name="config_test"}
atf_test_program{name="atf-check_test"}
atf_test_program{name="atf_check_test"}
atf_test_program{name="integration_test"}
atf_test_program{name="kmod_test"}
+11
View File
@@ -0,0 +1,11 @@
syntax("kyuafile", 1)
test_suite("atf")
atf_test_program{name="tc_test"}
atf_test_program{name="tp_test"}
atf_test_program{name="normalize_test"}
atf_test_program{name="config_test"}
atf_test_program{name="atf-check_test"}
atf_test_program{name="atf_check_test"}
atf_test_program{name="integration_test"}
+24 -18
View File
@@ -22,7 +22,7 @@
.\" 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 June 21, 2020
.Dd August 13, 2026
.Dt ATF-CHECK 1
.Os
.Sh NAME
@@ -34,11 +34,12 @@
.Op Fl o Ar action:arg ...
.Op Fl e Ar action:arg ...
.Op Fl x
.Op Fl r Ar timeout[:interval]
.Ar command
.Sh DESCRIPTION
.Nm
executes a given command and analyzes its results, including
exit code, stdout and stderr.
exit code, stdout, and stderr.
.Pp
.Bf Em
Test cases must use
@@ -47,24 +48,27 @@ Test cases must use
builtin function instead of calling this utility directly.
.Ef
.Pp
In the first synopsis form,
.Nm
will execute the provided command and apply checks specified
by arguments.
By default it will act as if it was run with
By default
.Nm
acts as if it was run with
.Fl s
.Ar exit:0
.Fl o
.Ar empty
.Fl e
.Ar empty .
Multiple checks for the same output channel are allowed and, if specified,
their results will be combined as a logical and (meaning that the output must
match all the provided checks).
.Pp
In the second synopsis form,
.Nm
will print information about all supported options and their purpose.
.Fl o
.Ar empty
and
.Fl e
.Ar empty
may be specified multiple times.
If they are specified multiple times, the checks will be applied to
the appropriate stream in the order they were provided.
.Pp
The following options are available:
.Bl -tag -width XqualXvalueXX
@@ -80,11 +84,11 @@ accepted.
.It Ar ignore
ignores the exit check.
.It Ar signal:<value>
checks that the program exited due to a signal and that the signal that
terminated it is
checks that the program exited due to a signal, and (optionally) checks that the
signal which terminated the process is
.Va value .
The signal can be specified both as a number or as a name, or it can also
be omitted altogether, in which case any signal is accepted.
The signal can be specified as a number, a name, or it can be omitted
altogether (in which case any signal is accepted).
.El
.Pp
Most of these checkers can be prefixed by the
@@ -112,7 +116,9 @@ Most of these checkers can be prefixed by the
.Sq not-
string, which effectively reverses the check.
.It Fl e Ar action:arg
Analyzes standard error (syntax identical to above)
Analyzes standard error.
The usage is identical to
.Fl o .
.It Fl x
Executes
.Ar command
@@ -150,15 +156,15 @@ instead of executing
directly:
.Bd -literal -offset indent
# Exit code 0, nothing on stdout/stderr
atf_check 'true'
atf_check true
# Typical usage if failure is expected
atf_check -s not-exit:0 'false'
atf_check -s not-exit:0 false
# Checking stdout/stderr
echo foobar >expout
atf_check -o file:expout -e inline:"xx\etyy\en" \e
'echo foobar ; printf "xx\etyy\en" >&2'
-x 'echo foobar ; printf "xx\etyy\en" >&2'
# Checking for a crash
atf_check -s signal:sigsegv my_program
+40 -27
View File
@@ -30,6 +30,7 @@ extern "C" {
#include <limits.h>
#include <signal.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>
}
@@ -46,7 +47,6 @@ extern "C" {
#include "atf-c++/check.hpp"
#include "atf-c++/detail/application.hpp"
#include "atf-c++/detail/auto_array.hpp"
#include "atf-c++/detail/env.hpp"
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/fs.hpp"
@@ -74,12 +74,14 @@ struct status_check {
status_check_t type;
bool negated;
int value;
bool empty;
status_check(const status_check_t& p_type, const bool p_negated,
const int p_value) :
const int p_value, const bool p_empty) :
type(p_type),
negated(p_negated),
value(p_value)
value(p_value),
empty(p_empty)
{
}
};
@@ -119,23 +121,30 @@ public:
const atf::fs::path file = atf::fs::path(
atf::env::get("TMPDIR", "/tmp")) / pattern;
atf::auto_array< char > buf(new char[file.str().length() + 1]);
std::strcpy(buf.get(), file.c_str());
m_fd = ::mkstemp(buf.get());
std::string file_s = file.str();
// C++14 returns const char* with `std::string::data()`.
//
// TODO(ngie): remove the else block and simplify once we are on C++17
// or later.
#if __cplusplus >= 201703L
char *file_ch_arr = file_s.data();
#else
char *file_ch_arr = &file_s[0];
#endif
m_fd = ::mkstemp(file_ch_arr);
if (m_fd == -1)
throw atf::system_error("atf_check::temp_file::temp_file(" +
file.str() + ")", "mkstemp(3) failed",
file_s + ")", "mkstemp(3) failed",
errno);
m_path.reset(new atf::fs::path(buf.get()));
m_path.reset(new atf::fs::path(file_ch_arr));
}
~temp_file(void)
{
close();
try {
remove(*m_path);
atf::fs::remove(*m_path);
} catch (const atf::system_error&) {
// Ignore deletion errors.
}
@@ -200,11 +209,11 @@ parse_exit_code(const std::string& str)
try {
const int value = atf::text::to_type< int >(str);
if (value < 0 || value > 255)
throw std::runtime_error("Unused reason");
throw std::range_error("Unused reason");
return value;
} catch (const std::runtime_error&) {
} catch (const std::range_error&) {
throw atf::application::usage_error("Invalid exit code for -s option; "
"must be an integer in range 0-255");
"must be an integer in the range [0, 255]");
}
}
@@ -267,6 +276,7 @@ parse_status_check_arg(const std::string& arg)
const std::string value_str = (
delimiter == std::string::npos ? "" : arg.substr(delimiter + 1));
int value;
bool empty = false;
status_check_t type;
if (action == "eq") {
@@ -278,9 +288,10 @@ parse_status_check_arg(const std::string& arg)
value = parse_exit_code(value_str);
} else if (action == "exit") {
type = sc_exit;
if (value_str.empty())
if (value_str.empty()) {
value = INT_MIN;
else
empty = true;
} else
value = parse_exit_code(value_str);
} else if (action == "ignore") {
if (negated)
@@ -296,14 +307,15 @@ parse_status_check_arg(const std::string& arg)
value = parse_exit_code(value_str);
} else if (action == "signal") {
type = sc_signal;
if (value_str.empty())
if (value_str.empty()) {
value = INT_MIN;
else
empty = true;
} else
value = parse_signal(value_str);
} else
throw atf::application::usage_error("Invalid status checker");
return status_check(type, negated, value);
return status_check(type, negated, value, empty);
}
static
@@ -435,8 +447,8 @@ execute_with_shell(char* const* argv)
{
const std::string cmd = flatten_argv(argv);
const std::string shell = atf::env::get("ATF_SHELL", ATF_SHELL);
const char* sh_argv[4];
sh_argv[0] = shell.c_str();
sh_argv[1] = "-c";
sh_argv[2] = cmd.c_str();
@@ -599,7 +611,7 @@ run_status_check(const status_check& sc, const atf::check::check_result& cr)
bool result;
if (sc.type == sc_exit) {
if (cr.exited() && sc.value != INT_MIN) {
if (cr.exited() && !sc.empty) {
const int status = cr.exitcode();
if (!sc.negated && sc.value != status) {
@@ -614,7 +626,7 @@ run_status_check(const status_check& sc, const atf::check::check_result& cr)
result = false;
} else
result = true;
} else if (cr.exited() && sc.value == INT_MIN) {
} else if (cr.exited() && sc.empty) {
result = true;
} else {
std::cerr << "Fail: program did not exit cleanly\n";
@@ -623,7 +635,7 @@ run_status_check(const status_check& sc, const atf::check::check_result& cr)
} else if (sc.type == sc_ignore) {
result = true;
} else if (sc.type == sc_signal) {
if (cr.signaled() && sc.value != INT_MIN) {
if (cr.signaled() && !sc.empty) {
const int status = cr.termsig();
if (!sc.negated && sc.value != status) {
@@ -637,7 +649,7 @@ run_status_check(const status_check& sc, const atf::check::check_result& cr)
result = false;
} else
result = true;
} else if (cr.signaled() && sc.value == INT_MIN) {
} else if (cr.signaled() && sc.empty) {
result = true;
} else {
std::cerr << "Fail: program did not receive a signal\n";
@@ -678,7 +690,7 @@ run_status_checks(const std::vector< status_check >& checks,
static
bool
run_output_check(const output_check oc, const atf::fs::path& path,
run_output_check(const output_check& oc, const atf::fs::path& path,
const std::string& stdxxx)
{
bool result;
@@ -903,9 +915,10 @@ atf_check::main(void)
int status = EXIT_FAILURE;
if (m_status_checks.empty())
m_status_checks.push_back(status_check(sc_exit, false, EXIT_SUCCESS));
else if (m_status_checks.size() > 1) {
if (m_status_checks.empty()) {
m_status_checks.push_back(status_check(sc_exit, false, EXIT_SUCCESS,
false));
} else if (m_status_checks.size() > 1) {
// TODO: Remove this restriction.
throw atf::application::usage_error("Cannot specify -s more than once");
}
+2 -2
View File
@@ -397,9 +397,9 @@ unusual_umask_head()
unusual_umask_body()
{
for mask in 022 027 0222 0177 0777 ; do
umask $mask
umask ${mask}
${Atf_Check} true || \
atf_fail "atf-check failed with umask $mask"
atf_fail "atf-check failed with umask ${mask}"
done
umask 022
}
+1 -1
View File
@@ -383,7 +383,7 @@ atf_check -s exit:0 -o file:expout -e empty echo foo
# Generate a file for later inspection
atf_check -s exit:0 -o save:stdout -e empty ls
grep foo ls || atf_fail "foo file not found in listing"
grep foo stdout || atf_fail "foo file not found in listing"
# Or just do the match along the way
atf_check -s exit:0 -o match:"^foo$" -e empty ls
+29 -23
View File
@@ -31,6 +31,8 @@ extern "C" {
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <utility>
#include <vector>
#include "atf-c++/detail/application.hpp"
#include "atf-c++/detail/env.hpp"
@@ -55,7 +57,7 @@ fix_plain_name(const char *filename)
}
static
std::string*
std::string
construct_script(const char* filename)
{
const std::string libexecdir = atf::env::get(
@@ -64,37 +66,35 @@ construct_script(const char* filename)
"ATF_PKGDATADIR", ATF_PKGDATADIR);
const std::string shell = atf::env::get("ATF_SHELL", ATF_SHELL);
std::string* command = new std::string();
command->reserve(512);
(*command) += ("Atf_Check='" + libexecdir + "/atf-check' ; " +
"Atf_Shell='" + shell + "' ; " +
". " + pkgdatadir + "/libatf-sh.subr ; " +
". " + fix_plain_name(filename) + " ; " +
"main \"${@}\"");
std::string command;
command += ("Atf_Check='" + libexecdir + "/atf-check' ; " +
"Atf_Shell='" + shell + "' ; " +
". " + pkgdatadir + "/libatf-sh.subr ; " +
". " + fix_plain_name(filename) + " ; " +
"main \"${@}\"");
return command;
}
static
const char**
std::vector<std::string>
construct_argv(const std::string& shell, const int interpreter_argc,
const char* const* interpreter_argv)
{
PRE(interpreter_argc >= 1);
PRE(interpreter_argv[0] != NULL);
const std::string* script = construct_script(interpreter_argv[0]);
std::string script = construct_script(interpreter_argv[0]);
const int count = 4 + (interpreter_argc - 1) + 1;
const char** argv = new const char*[count];
argv[0] = shell.c_str();
argv[1] = "-c";
argv[2] = script->c_str();
argv[3] = interpreter_argv[0];
std::vector<std::string> argv;
argv.push_back(shell);
argv.push_back(std::string("-c"));
argv.push_back(std::move(script));
argv.push_back(std::string(interpreter_argv[0]));
for (int i = 1; i < interpreter_argc; i++)
argv[4 + i - 1] = interpreter_argv[i];
argv[count - 1] = NULL;
argv.push_back(interpreter_argv[i]);
return argv;
}
@@ -167,12 +167,18 @@ atf_sh::main(void)
throw std::runtime_error("The test program '" + script.str() + "' "
"does not exist");
const char** argv = construct_argv(m_shell.str(), m_argc, m_argv);
// Don't bother keeping track of the memory allocated by construct_argv:
// we are going to exec or die immediately.
std::vector<std::string> argvv = construct_argv(m_shell.str(), m_argc,
m_argv);
std::vector<const char *> argv;
const int ret = execv(m_shell.c_str(), const_cast< char** >(argv));
for (std::size_t i = 0; i < argvv.size(); i++)
argv.push_back(argvv[i].c_str());
argv.push_back(NULL);
const int ret = execv(m_shell.c_str(),
const_cast<char* const *>(argv.data()));
INV(ret == -1);
std::cerr << "Failed to execute " << m_shell.str() << ": "
<< std::strerror(errno) << "\n";
return EXIT_FAILURE;
+19
View File
@@ -147,6 +147,24 @@ EOF
"${ATF_SH}" -s ./custom-shell tp helper
}
atf_test_case require_progs
require_progs_body()
{
cat | create_test_program tp <<EOF
atf_test_case helper
helper_head() {
atf_set "require.progs" "true"
}
helper_body() {
true
}
atf_init_test_cases() {
atf_add_test_case helper
}
EOF
atf_check -s eq:0 -o match:passed ./tp helper
}
atf_init_test_cases()
{
atf_add_test_case no_args
@@ -155,6 +173,7 @@ atf_init_test_cases()
atf_add_test_case custom_shell__command_line
atf_add_test_case custom_shell__shebang
atf_add_test_case set_e
atf_add_test_case require_progs
}
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
+55
View File
@@ -0,0 +1,55 @@
# Copyright (c) 2026 Enji Cooper <[email protected]>.
# All Rights Reserved.
#
# SPDX-License-Identifier: BSD-2-Clause
atf_test_case atf_require_kmod_basic
atf_require_kmod_basic_head()
{
atf_set "descr" \
"Verifies that 'atf_require_kmod' functions in the positive case."
}
atf_require_kmod_basic_body()
{
kldstat() {
true
}
atf_require_kmod "bogus"
}
atf_test_case atf_require_kmod_skip
atf_require_kmod_skip_head()
{
atf_set "descr" \
"atf_require_kmod: verifies the test is skipped when the kmods are " \
"not loaded."
}
atf_require_kmod_skip_body()
{
kldstat() {
false
}
atf_expect_skip "Testcase should skip."
atf_require_kmod "bogus"
}
atf_test_case require_kmods_skip
require_kmods_skip_head()
{
atf_set "descr" \
"Verifies tests are skipped when the dependency isn't already loaded."
atf_set "require.kmods" "nonexistent"
}
require_kmods_skip_body()
{
atf_fail "This should never be reached."
}
atf_init_test_cases()
{
atf_add_test_case atf_require_kmod_basic
atf_add_test_case atf_require_kmod_skip
atf_add_test_case require_kmods_skip
}
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
+40
View File
@@ -209,6 +209,19 @@ atf_expect_fail()
Expect_Reason="${*}"
}
#
# atf_expect_skip reason
#
# Sets the expectations to 'skip'.
#
atf_expect_skip()
{
_atf_validate_expect
Expect=skip
Expect_Reason="${*}"
}
#
# atf_expect_pass
#
@@ -716,6 +729,11 @@ _atf_validate_expect()
atf_fail "Test case was expected to receive a termination signal" \
"but it continued execution"
;;
skip)
Expect=pass
atf_fail "Test case was supposed to be skipped but it continued " \
"execution"
;;
timeout)
Expect=pass
atf_fail "Test case was expected to hang but it continued execution"
@@ -808,3 +826,25 @@ main()
}
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
# BEGIN `FreeBSD.subr`.
#
# Copyright (c) 2026 Enji Cooper <[email protected]>.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause
atf_require_kmod_supported()
{
true
}
# \brief FreeBSD specific helper routine for ensuring that a kmod has been
# loaded.
#
# \param kmod a target kmod.
atf_require_kmod()
{
kldstat -q -m "${1}" || \
atf_skip "The required kmod ${1} is not loaded"
}
# END `FreeBSD.subr`.
+115 -17
View File
@@ -7,6 +7,9 @@
/* Define to 1 if dirname takes a constant pointer */
/* #undef HAVE_CONST_DIRNAME */
/* 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
@@ -19,21 +22,18 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <minix/config.h> header file. */
/* #undef HAVE_MINIX_CONFIG_H */
/* Define to 1 if getopt has optreset */
#define HAVE_OPTRESET 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 <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
@@ -52,12 +52,12 @@
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `unsetenv' function. */
#define HAVE_UNSETENV 1
/* Define to 1 if vsnprintf is in std */
/* #undef HAVE_VSNPRINTF_IN_STD */
/* Define to 1 if you have the <wchar.h> header file. */
#define HAVE_WCHAR_H 1
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
@@ -65,7 +65,7 @@
#define PACKAGE "atf"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "[email protected]"
#define PACKAGE_BUGREPORT "[email protected]"
/* Define to the copyright string applicable to this package. */
#define PACKAGE_COPYRIGHT "Copyright (c) 2007-2012 The NetBSD Foundation, Inc."
@@ -74,19 +74,117 @@
#define PACKAGE_NAME "Automated Testing Framework"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "Automated Testing Framework 0.21"
#define PACKAGE_STRING "Automated Testing Framework 0.26"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "atf"
/* Define to the home page for this package. */
#define PACKAGE_URL "https://github.com/jmmv/atf/"
#define PACKAGE_URL "https://github.com/freebsd/atf/"
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.21"
#define PACKAGE_VERSION "0.26"
/* Define to 1 if you have the ANSI C header files. */
/* 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
/* Enable extensions on AIX, Interix, z/OS. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable extensions on Cosmopolitan Libc. */
#ifndef _COSMO_SOURCE
# define _COSMO_SOURCE 1
#endif
/* Enable general extensions on macOS. */
#ifndef _DARWIN_C_SOURCE
# define _DARWIN_C_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable X/Open compliant socket functions that do not require linking
with -lxnet on HP-UX 11.11. */
#ifndef _HPUX_ALT_XOPEN_SOCKET_API
# define _HPUX_ALT_XOPEN_SOCKET_API 1
#endif
/* Identify the host operating system as Minix.
This macro does not affect the system headers' behavior.
A future release of Autoconf may stop defining this macro. */
#ifndef _MINIX
/* # undef _MINIX */
#endif
/* Enable general extensions on NetBSD.
Enable NetBSD compatibility extensions on Minix. */
#ifndef _NETBSD_SOURCE
# define _NETBSD_SOURCE 1
#endif
/* Enable OpenBSD compatibility extensions on NetBSD.
Oddly enough, this does nothing on OpenBSD. */
#ifndef _OPENBSD_SOURCE
# define _OPENBSD_SOURCE 1
#endif
/* Define to 1 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_SOURCE
/* # undef _POSIX_SOURCE */
#endif
/* Define to 2 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_1_SOURCE
/* # undef _POSIX_1_SOURCE */
#endif
/* Enable POSIX-compatible threading on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
# define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1
#endif
/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
# define __STDC_WANT_IEC_60559_BFP_EXT__ 1
#endif
/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
# define __STDC_WANT_IEC_60559_DFP_EXT__ 1
#endif
/* Enable extensions specified by C23 Annex F. */
#ifndef __STDC_WANT_IEC_60559_EXT__
# define __STDC_WANT_IEC_60559_EXT__ 1
#endif
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
# define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1
#endif
/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
# define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
#endif
/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
#ifndef __STDC_WANT_LIB_EXT2__
# define __STDC_WANT_LIB_EXT2__ 1
#endif
/* Enable extensions specified by ISO/IEC 24747:2009. */
#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
# define __STDC_WANT_MATH_SPEC_FUNCS__ 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable X/Open extensions. Define to 500 only if necessary
to make mbstate_t available. */
#ifndef _XOPEN_SOURCE
/* # undef _XOPEN_SOURCE */
#endif
/* Version number of package */
#define VERSION "0.21"
#define VERSION "0.26"
-1
View File
@@ -1 +0,0 @@
atf.7
@@ -22,8 +22,8 @@
.\" 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 May 11, 2025
.Dt ATF-TEST-CASE 4
.Dd August 5, 2025
.Dt ATF-TEST-CASE 7
.Os
.Sh NAME
.Nm atf-test-case
@@ -153,7 +153,7 @@ The following metadata properties can be exposed via the test case's head:
.Bl -tag -width requireXmachineXX
.It descr
Type: textual.
Required.
Optional.
.Pp
A brief textual description of the test case's purpose.
Will be shown to the user in reports.
@@ -223,14 +223,6 @@ The value can have a size suffix such as
or
.Sq T
to make the amount of bytes easier to type and read.
.It require.kmods
Type: textual.
Optional.
.Pp
A whitespace separated list of kernel modules that must be present to
execute the test case.
If any of the required kernel modules is not found, the test case is
.Em skipped .
.It require.progs
Type: textual.
Optional.
-10
View File
@@ -70,16 +70,6 @@ libtool_body()
atf_check -s eq:1 -o empty -e ignore "${hp}" -r res srcdir_exists
atf_check -s eq:0 -o ignore -e empty grep "Cannot find datafile" res
done
for hp in $(get_helpers c_helpers cpp_helpers); do
h=${hp##*/}
cp ${hp} tmp
cp ${hp} tmp/.libs/lt-${h}
atf_check -s eq:0 -o ignore -e ignore -x \
"cd tmp && ./.libs/lt-${h} srcdir_exists"
atf_check -s eq:1 -o empty -e ignore "${hp}" -r res srcdir_exists
atf_check -s eq:0 -o ignore -e empty grep "Cannot find datafile" res
done
}
atf_test_case sflag
+2
View File
@@ -28,4 +28,6 @@ PACKAGE?= atf
LIB_PACKAGE=
CFLAGS+= -DHAVE_CONFIG_H
CXXSTD= gnu++20
WARNS?= 3
+2
View File
@@ -28,6 +28,8 @@ PACKAGE?= atf
LIB_PACKAGE=
CFLAGS+= -DHAVE_CONFIG_H
CXXSTD= gnu++20
WARNS?= 3
.include "../Makefile.inc"
+1 -1
View File
@@ -30,7 +30,7 @@ ATFTOP= ${SRCTOP}/contrib/atf
FILESGROUPS= ATF
ATFDIR= ${SHAREDIR}/doc/atf
ATF= AUTHORS COPYING NEWS README
ATF= AUTHORS COPYING NEWS README.md
ATFPACKAGE= atf
.include <bsd.prog.mk>
-8
View File
@@ -1090,14 +1090,6 @@ MAN+= mlx5ib.4
MAN+= mlx5io.4
.endif
.if ${MK_TESTS} != "no"
MANGROUPS+= ATF
ATFTOP= ${SRCTOP}/contrib/atf
.PATH: ${ATFTOP}/doc
ATF= atf-test-case.4
ATFPACKAGE= atf
.endif
.if ${MK_PF} != "no"
_pf.4= pf.4
_pflog.4= pflog.4
+1
View File
@@ -67,6 +67,7 @@ TESTS= tests.7
TESTSPACKAGE= tests
ATF= atf.7
ATF= atf-test-case.7
ATFPACKAGE= atf
ATFPATH= ${SRCTOP}/contrib/atf