xref: /illumos-gate/usr/src/test/header-tests/tests/common/README.md (revision e1e6b944360d951edf36ef4198261818ed2d9b2f)
1861094cfSGordon Ross# tests/common - C and C++ symbol visibility test program
210724642SGordon Ross
310724642SGordon Ross## Overview
410724642SGordon Ross
5861094cfSGordon RossThis directory contains the source for the symbol visibility test program:
610724642SGordon Ross
7861094cfSGordon Ross- `symbol_test.py` - test driver for C and C++ (supports parallel compilation)
8861094cfSGordon Ross- `test_parse_env_cfg.py` - unit test for environment config parser
9861094cfSGordon Ross- `test_parse_sym_cfg.py` - unit test for symbols config parser
10861094cfSGordon Ross- `test_gen_probe.py` - unit test for test/probe program generation
1110724642SGordon Ross
12861094cfSGordon RossThe `symbol_test.py` program:
13861094cfSGordon Ross- reads an `environment config` file
14861094cfSGordon Ross- reads a `symbols config` file
15861094cfSGordon Ross- runs short compiler jobs for each combination of environement and symbol,
16861094cfSGordon Ross  verifying that it exists or does not exist as indicated by the data from
17861094cfSGordon Ross  the `symbols config` file.
18*e1e6b944SGordon Ross- generates include-only tests where needed to ensure the primary header has
19*e1e6b944SGordon Ross  at least one expected-success compilation in each environment selected for
20*e1e6b944SGordon Ross  positive coverage.
21*e1e6b944SGordon Ross
22*e1e6b944SGordon RossThe first header named by a symbols configuration is its primary header.  The
23*e1e6b944SGordon Rossfirst header of later entries is expected to be the same.  Additional headers
24*e1e6b944SGordon Rossafter the first one in an entry are supporting headers and do not affect
25*e1e6b944SGordon Rosspositive coverage.  Multiple symbols configuration files may be supplied;
26*e1e6b944SGordon Rossthey are effectively concatenated and must have the same primary header.
2710724642SGordon Ross
2810724642SGordon RossThe config file format is documented in `../cfg/README`,
2910724642SGordon Ross`../cfg/c-symbols/README`, and `../cfg/cxx-symbols/README`.
3010724642SGordon Ross
31861094cfSGordon Ross## Program Operation
3210724642SGordon Ross
33861094cfSGordon Ross- Compiler discovery: tries `g++` then `clang++`, or accepts `-c compiler`.
34861094cfSGordon Ross- C++ include path setup: queries the compiler for its internal include
35861094cfSGordon Ross  directory and constructs the `-isystem` paths needed to find C++ standard
36861094cfSGordon Ross  headers without picking up GCC's fixincludes copies of system headers.
3710724642SGordon Ross
3810724642SGordon Ross## Probe program generation
3910724642SGordon Ross
40861094cfSGordon RossFor each test entry, the program generates a minimal C or C++ program.
41861094cfSGordon RossFor notes on "probe" program generation, see `test_gen_probe.py`
4210724642SGordon Ross
4310724642SGordon Ross#### `func` - function call test
4410724642SGordon Ross
4510724642SGordon RossConfig line:
4610724642SGordon Ross```
4710724642SGordon Rossfunc | log | double | double | math.h | C99+
4810724642SGordon Ross```
4910724642SGordon RossGenerated program (C):
5010724642SGordon Ross```c
5110724642SGordon Ross#include <math.h>
5210724642SGordon Rossdouble
5310724642SGordon Rosstest_func(double a0)
5410724642SGordon Ross{
5510724642SGordon Ross	return log(a0);
5610724642SGordon Ross}
5710724642SGordon Ross```
5810724642SGordon Ross
5910724642SGordon RossIn the C++ program, the return value uses a `RESULT()` macro that selects
6010724642SGordon Rossbrace-initialisation (C++11 and later) or plain assignment (C++98):
6110724642SGordon Ross```cpp
6210724642SGordon Ross#if __cplusplus >= 201103L
6310724642SGordon Ross#define RESULT(v) result{v}
6410724642SGordon Ross#else
6510724642SGordon Ross#define RESULT(v) result = (v)
6610724642SGordon Ross#endif
6710724642SGordon Rossdouble
6810724642SGordon Rosstest_func(double a0)
6910724642SGordon Ross{
70861094cfSGordon Ross	double RESULT(log(a0));
7110724642SGordon Ross	return result;
7210724642SGordon Ross}
7310724642SGordon Ross```
7410724642SGordon RossBrace-initialisation prohibits narrowing conversions, so a missing `float`
7510724642SGordon Rossor `long double` overload that would silently promote through `double` is
7610724642SGordon Rosscaught as a compile error rather than a silent pass.  C++98 uses plain
7710724642SGordon Rossassignment since brace-init is a C++11 extension.
78861094cfSGordon RossFunction pointer return types use plain `return` in the program since
7910724642SGordon Rossbrace-init does not compose with declarator syntax.
8010724642SGordon Ross
8110724642SGordon Ross#### `type` - type existence test
8210724642SGordon Ross
8310724642SGordon RossConfig line:
8410724642SGordon Ross```
8510724642SGordon Rosstype | size_t | stddef.h | C11+
8610724642SGordon Ross```
8710724642SGordon RossGenerated program:
8810724642SGordon Ross```c
8910724642SGordon Ross#include <stddef.h>
9010724642SGordon Rosssize_t test_type;
9110724642SGordon Ross```
9210724642SGordon Ross
9310724642SGordon Ross#### `value` - constant/variable access test
9410724642SGordon Ross
9510724642SGordon RossConfig line:
9610724642SGordon Ross```
9710724642SGordon Rossvalue | M_PI | double | math.h | C99+
9810724642SGordon Ross```
9910724642SGordon RossGenerated program:
10010724642SGordon Ross```c
10110724642SGordon Ross#include <math.h>
10210724642SGordon Rossdouble test_value;
10310724642SGordon Rossvoid
10410724642SGordon Rosstest_func(void)
10510724642SGordon Ross{
10610724642SGordon Ross	test_value = M_PI;
10710724642SGordon Ross}
10810724642SGordon Ross```
10910724642SGordon Ross
11010724642SGordon Ross#### `define` - preprocessor macro test
11110724642SGordon Ross
11210724642SGordon RossConfig line:
11310724642SGordon Ross```
11410724642SGordon Rossdefine | INFINITY | | math.h | C99+
11510724642SGordon Ross```
11610724642SGordon RossGenerated program:
11710724642SGordon Ross```c
11810724642SGordon Ross#include <math.h>
11910724642SGordon Ross#if !defined(INFINITY)
12010724642SGordon Ross#error INFINITY is not defined or has the wrong value
12110724642SGordon Ross#endif
12210724642SGordon Ross```
12310724642SGordon RossAn optional value field checks strict equality:
12410724642SGordon Ross```
12510724642SGordon Rossdefine | FLT_RADIX | 2 | float.h | C99+
12610724642SGordon Ross```
12710724642SGordon Ross```c
12810724642SGordon Ross#include <float.h>
12910724642SGordon Ross#if !defined(FLT_RADIX) || FLT_RADIX != 2
13010724642SGordon Ross#error FLT_RADIX is not defined or has the wrong value
13110724642SGordon Ross#endif
13210724642SGordon Ross```
13310724642SGordon Ross
13410724642SGordon Ross## Command-line options
13510724642SGordon Ross
136861094cfSGordon Ross### Usage
13710724642SGordon Ross
138861094cfSGordon Ross    python3 symbol_test.py --lang c|c++ -m64|-m32 [options] env_cfg sym_cfg...
139861094cfSGordon Ross
140861094cfSGordon RossRequired arguments:
141861094cfSGordon Ross
142861094cfSGordon Ross    --lang c|c++   Language to test
143861094cfSGordon Ross    -m64 | -m32    Target ABI
144861094cfSGordon Ross
145861094cfSGordon RossOptions:
146861094cfSGordon Ross
147861094cfSGordon Ross    -C          Check compiler only, do not run tests
148861094cfSGordon Ross    -f          Force: continue after failures
149861094cfSGordon Ross    -d          Debug: print probe and compiler output on failures
150f9db9ff7SGordon Ross    -D          Extra debug: also print the compiler command and probe
151f9db9ff7SGordon Ross                program for every test, not just failures (implies -d)
15210724642SGordon Ross    -c compiler Use the specified compiler instead of auto-detecting
153861094cfSGordon Ross    -s sym      Run only the test for the named symbol
154861094cfSGordon Ross    -e ENV      Run only tests for the named environment
155861094cfSGordon Ross    -j N        Number of parallel compile jobs (default: 4 or
156861094cfSGordon Ross                the environment variable SYMBOL_TEST_JOBS)
157*e1e6b944SGordon Ross    --positive-coverage=NAME
158*e1e6b944SGordon Ross                Ensure that at least one expected-success test compiles the
159*e1e6b944SGordon Ross                primary header in every environment named by NAME. Additional
160*e1e6b944SGordon Ross                include-only tests are generated where needed. By default,
161*e1e6b944SGordon Ross                all declared environments require positive coverage.
162f9db9ff7SGordon Ross    -R ROOT     Alternate root directory (e.g. a proto area) whose
163f9db9ff7SGordon Ross                ROOT/usr/include is tested instead of the default
164f9db9ff7SGordon Ross                (default: $HEADER_TEST_ROOT/usr/include if that
165f9db9ff7SGordon Ross                environment variable is set, else /usr/include)
16610724642SGordon Ross
167861094cfSGordon RossWhen running tests by hand (not via the `setup` script), you may
168861094cfSGordon Rosspass `-f` to see all failures instead of stopping on errors.
16910724642SGordon Ross
17010724642SGordon Ross## Extending the tests
17110724642SGordon Ross
17210724642SGordon RossTo add tests for a new header:
17310724642SGordon Ross
17410724642SGordon Ross1. Add a new `.cfg` file in `../cfg/c-symbols/` or `../cfg/cxx-symbols/`.
17510724642SGordon Ross2. Add a wrapper script (hardlink or copy of `setup`) in the corresponding
17610724642SGordon Ross   `../c-symbols/` or `../cxx-symbols/` subdirectory, named after the cfg file
17710724642SGordon Ross   without `.cfg`.
17810724642SGordon Ross3. Add the new files to the `../cfg/Makefile` and the IPS manifest.
17910724642SGordon Ross
18010724642SGordon RossTo add a new compilation environment or group, edit
181861094cfSGordon Ross`../cfg/c-symbols-env.cfg` or `../cfg/cxx-symbols-env.cfg`.
182861094cfSGordon Ross
183861094cfSGordon Ross## Developer Notes
184861094cfSGordon Ross
185861094cfSGordon RossUnit tests for the Python components (`symbol_test.py`) live alongside the
186861094cfSGordon Rosssource in this directory.  They use canned string input and require no
187861094cfSGordon Rossexternal files or build products.
188861094cfSGordon Ross
189861094cfSGordon RossRun individual test modules from `tests/common/`:
190861094cfSGordon Ross
191861094cfSGordon Ross```
192861094cfSGordon Rosspython3 test_parse_env_cfg.py -v
193861094cfSGordon Rosspython3 test_parse_sym_cfg.py -v
194861094cfSGordon Rosspython3 test_gen_probe.py -v
195861094cfSGordon Ross```
196861094cfSGordon Ross
197861094cfSGordon RossOr run all unit tests at once from the repository root:
198861094cfSGordon Ross
199861094cfSGordon Ross```
200861094cfSGordon Rosspython3 -m unittest discover -s usr/src/test/header-tests/tests/common -p 'test_*.py' -v
201861094cfSGordon Ross```
202