xref: /illumos-gate/usr/src/test/header-tests/tests/common/README.md (revision ac2250cb76bb32944fd2c8a3ba2cd3f79747748d)
1# tests/common - C and C++ symbol visibility test program
2
3## Overview
4
5This directory contains the source for the symbol visibility test program:
6
7- `symbol_test.py` - test driver for C and C++ (supports parallel compilation)
8- `test_parse_env_cfg.py` - unit test for environment config parser
9- `test_parse_sym_cfg.py` - unit test for symbols config parser
10- `test_gen_probe.py` - unit test for test/probe program generation
11
12The `symbol_test.py` program:
13- reads an `environment config` file
14- reads a `symbols config` file
15- runs short compiler jobs for each combination of environement and symbol,
16  verifying that it exists or does not exist as indicated by the data from
17  the `symbols config` file.
18
19The config file format is documented in `../cfg/README`,
20`../cfg/c-symbols/README`, and `../cfg/cxx-symbols/README`.
21
22## Program Operation
23
24- Compiler discovery: tries `g++` then `clang++`, or accepts `-c compiler`.
25- C++ include path setup: queries the compiler for its internal include
26  directory and constructs the `-isystem` paths needed to find C++ standard
27  headers without picking up GCC's fixincludes copies of system headers.
28
29## Probe program generation
30
31For each test entry, the program generates a minimal C or C++ program.
32For notes on "probe" program generation, see `test_gen_probe.py`
33
34#### `func` - function call test
35
36Config line:
37```
38func | log | double | double | math.h | C99+
39```
40Generated program (C):
41```c
42#include <math.h>
43double
44test_func(double a0)
45{
46	return log(a0);
47}
48```
49
50In the C++ program, the return value uses a `RESULT()` macro that selects
51brace-initialisation (C++11 and later) or plain assignment (C++98):
52```cpp
53#if __cplusplus >= 201103L
54#define RESULT(v) result{v}
55#else
56#define RESULT(v) result = (v)
57#endif
58double
59test_func(double a0)
60{
61	double RESULT(log(a0));
62	return result;
63}
64```
65Brace-initialisation prohibits narrowing conversions, so a missing `float`
66or `long double` overload that would silently promote through `double` is
67caught as a compile error rather than a silent pass.  C++98 uses plain
68assignment since brace-init is a C++11 extension.
69Function pointer return types use plain `return` in the program since
70brace-init does not compose with declarator syntax.
71
72#### `type` - type existence test
73
74Config line:
75```
76type | size_t | stddef.h | C11+
77```
78Generated program:
79```c
80#include <stddef.h>
81size_t test_type;
82```
83
84#### `value` - constant/variable access test
85
86Config line:
87```
88value | M_PI | double | math.h | C99+
89```
90Generated program:
91```c
92#include <math.h>
93double test_value;
94void
95test_func(void)
96{
97	test_value = M_PI;
98}
99```
100
101#### `define` - preprocessor macro test
102
103Config line:
104```
105define | INFINITY | | math.h | C99+
106```
107Generated program:
108```c
109#include <math.h>
110#if !defined(INFINITY)
111#error INFINITY is not defined or has the wrong value
112#endif
113```
114An optional value field checks strict equality:
115```
116define | FLT_RADIX | 2 | float.h | C99+
117```
118```c
119#include <float.h>
120#if !defined(FLT_RADIX) || FLT_RADIX != 2
121#error FLT_RADIX is not defined or has the wrong value
122#endif
123```
124
125## Command-line options
126
127### Usage
128
129    python3 symbol_test.py --lang c|c++ -m64|-m32 [options] env_cfg sym_cfg...
130
131Required arguments:
132
133    --lang c|c++   Language to test
134    -m64 | -m32    Target ABI
135
136Options:
137
138    -C          Check compiler only, do not run tests
139    -f          Force: continue after failures
140    -d          Debug: print probe and compiler output on failures
141    -D          Extra debug: also print the compiler command (implies -d)
142    -c compiler Use the specified compiler instead of auto-detecting
143    -s sym      Run only the test for the named symbol
144    -e ENV      Run only tests for the named environment
145    -j N        Number of parallel compile jobs (default: 4 or
146                the environment variable SYMBOL_TEST_JOBS)
147
148When running tests by hand (not via the `setup` script), you may
149pass `-f` to see all failures instead of stopping on errors.
150
151## Extending the tests
152
153To add tests for a new header:
154
1551. Add a new `.cfg` file in `../cfg/c-symbols/` or `../cfg/cxx-symbols/`.
1562. Add a wrapper script (hardlink or copy of `setup`) in the corresponding
157   `../c-symbols/` or `../cxx-symbols/` subdirectory, named after the cfg file
158   without `.cfg`.
1593. Add the new files to the `../cfg/Makefile` and the IPS manifest.
160
161To add a new compilation environment or group, edit
162`../cfg/c-symbols-env.cfg` or `../cfg/cxx-symbols-env.cfg`.
163
164## Developer Notes
165
166Unit tests for the Python components (`symbol_test.py`) live alongside the
167source in this directory.  They use canned string input and require no
168external files or build products.
169
170Run individual test modules from `tests/common/`:
171
172```
173python3 test_parse_env_cfg.py -v
174python3 test_parse_sym_cfg.py -v
175python3 test_gen_probe.py -v
176```
177
178Or run all unit tests at once from the repository root:
179
180```
181python3 -m unittest discover -s usr/src/test/header-tests/tests/common -p 'test_*.py' -v
182```
183