xref: /illumos-gate/usr/src/test/header-tests/tests/common/test_gen_probe.py (revision e1e6b944360d951edf36ef4198261818ed2d9b2f)
1#!/usr/bin/python3
2#
3# This file and its contents are supplied under the terms of the
4# Common Development and Distribution License ("CDDL"), version 1.0.
5# You may only use this file in accordance with the terms of version
6# 1.0 of the CDDL.
7#
8# A full copy of the text of the CDDL should have accompanied this
9# source.  A copy of the CDDL is also available via the Internet at
10# http://www.illumos.org/license/CDDL.
11#
12
13#
14# Copyright 2026 Gordon W. Ross
15#
16
17"""
18Unit tests for ProbeGen.gen_probe() - probe program source generation.
19
20Expected outputs were captured from the previous implementation.
21"""
22
23import unittest
24
25from symbol_test import ProbeGen, SymEntry
26
27
28def make_entry(directive, symbol, headers, rtype=None, atypes=None, defval=None):
29    return SymEntry(
30        directive=directive,
31        symbol=symbol,
32        env_spec='',
33        headers=headers,
34        rtype=rtype,
35        atypes=atypes or [],
36        defval=defval,
37    )
38
39
40class TestGenProbeC(unittest.TestCase):
41    """Probe generation for lang='c'."""
42
43    def test_include_only(self):
44        e = make_entry('include-only', 'include-only <test.h>', ['test.h'])
45        expected = (
46            '#include <test.h>\n'
47            'int header_compile_test;\n'
48        )
49        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
50
51    def test_type(self):
52        e = make_entry('type', 'size_t', ['stddef.h'], rtype='size_t')
53        expected = (
54            '#include <stddef.h>\n'
55            'size_t test_type;\n'
56        )
57        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
58
59    def test_value(self):
60        e = make_entry('value', 'M_PI', ['math.h'], rtype='double')
61        expected = (
62            '#include <math.h>\n'
63            'double test_value;\n'
64            'void\n'
65            'test_func(void)\n'
66            '{\n'
67            '\ttest_value = M_PI;\n'
68            '}\n'
69        )
70        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
71
72    def test_define_no_value(self):
73        e = make_entry('define', 'INFINITY', ['math.h'])
74        expected = (
75            '#include <math.h>\n'
76            '#if !defined(INFINITY)\n'
77            '#error INFINITY is not defined or has the wrong value\n'
78            '#endif\n'
79            '\n'
80        )
81        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
82
83    def test_define_with_value(self):
84        e = make_entry('define', 'FLT_RADIX', ['float.h'], defval='2')
85        expected = (
86            '#include <float.h>\n'
87            '#if !defined(FLT_RADIX) || FLT_RADIX != 2\n'
88            '#error FLT_RADIX is not defined or has the wrong value\n'
89            '#endif\n'
90            '\n'
91        )
92        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
93
94    def test_func_single_arg(self):
95        e = make_entry('func', 'log', ['math.h'], rtype='double', atypes=['double'])
96        expected = (
97            '#include <math.h>\n'
98            'double \n'
99            'test_func(double a0)\n'
100            '{\n'
101            '\treturn log(a0);\n'
102            '}\n'
103        )
104        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
105
106    def test_func_multi_arg(self):
107        e = make_entry('func', 'hypot', ['math.h'], rtype='double',
108                       atypes=['double', 'double'])
109        expected = (
110            '#include <math.h>\n'
111            'double \n'
112            'test_func(double a0, double a1)\n'
113            '{\n'
114            '\treturn hypot(a0, a1);\n'
115            '}\n'
116        )
117        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
118
119    def test_func_void_return(self):
120        e = make_entry('func', 'free', ['stdlib.h'], rtype='void',
121                       atypes=['void *'])
122        expected = (
123            '#include <stdlib.h>\n'
124            'void \n'
125            'test_func(void * a0)\n'
126            '{\n'
127            '\tfree(a0);\n'
128            '}\n'
129        )
130        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
131
132
133class TestGenProbeCxx(unittest.TestCase):
134    """Probe generation for lang='c++'."""
135
136    def test_func_result_macro(self):
137        """Non-void non-fnptr return: RESULT() macro must be emitted."""
138        e = make_entry('func', 'log', ['cmath'], rtype='double', atypes=['double'])
139        expected = (
140            '#include <cmath>\n'
141            '#if __cplusplus >= 201103L\n'
142            '#define RESULT(v) result{v}\n'
143            '#else\n'
144            '#define RESULT(v) result = (v)\n'
145            '#endif\n'
146            'double \n'
147            'test_func(double a0)\n'
148            '{\n'
149            '\tdouble RESULT(log(a0));\n'
150            '\treturn result;\n'
151            '}\n'
152        )
153        self.assertEqual(ProbeGen.gen_probe(e, 'c++'), expected)
154
155    def test_func_void_return(self):
156        """void return: no RESULT() macro; same form as C."""
157        e = make_entry('func', 'free', ['cstdlib'], rtype='void',
158                       atypes=['void *'])
159        expected = (
160            '#include <cstdlib>\n'
161            'void \n'
162            'test_func(void * a0)\n'
163            '{\n'
164            '\tfree(a0);\n'
165            '}\n'
166        )
167        self.assertEqual(ProbeGen.gen_probe(e, 'c++'), expected)
168
169
170if __name__ == '__main__':
171    unittest.main()
172