xref: /illumos-gate/usr/src/test/header-tests/tests/common/test_gen_probe.py (revision ac2250cb76bb32944fd2c8a3ba2cd3f79747748d)
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_type(self):
44        e = make_entry('type', 'size_t', ['stddef.h'], rtype='size_t')
45        expected = (
46            '#include <stddef.h>\n'
47            'size_t test_type;\n'
48        )
49        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
50
51    def test_value(self):
52        e = make_entry('value', 'M_PI', ['math.h'], rtype='double')
53        expected = (
54            '#include <math.h>\n'
55            'double test_value;\n'
56            'void\n'
57            'test_func(void)\n'
58            '{\n'
59            '\ttest_value = M_PI;\n'
60            '}\n'
61        )
62        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
63
64    def test_define_no_value(self):
65        e = make_entry('define', 'INFINITY', ['math.h'])
66        expected = (
67            '#include <math.h>\n'
68            '#if !defined(INFINITY)\n'
69            '#error INFINITY is not defined or has the wrong value\n'
70            '#endif\n'
71            '\n'
72        )
73        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
74
75    def test_define_with_value(self):
76        e = make_entry('define', 'FLT_RADIX', ['float.h'], defval='2')
77        expected = (
78            '#include <float.h>\n'
79            '#if !defined(FLT_RADIX) || FLT_RADIX != 2\n'
80            '#error FLT_RADIX is not defined or has the wrong value\n'
81            '#endif\n'
82            '\n'
83        )
84        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
85
86    def test_func_single_arg(self):
87        e = make_entry('func', 'log', ['math.h'], rtype='double', atypes=['double'])
88        expected = (
89            '#include <math.h>\n'
90            'double \n'
91            'test_func(double a0)\n'
92            '{\n'
93            '\treturn log(a0);\n'
94            '}\n'
95        )
96        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
97
98    def test_func_multi_arg(self):
99        e = make_entry('func', 'hypot', ['math.h'], rtype='double',
100                       atypes=['double', 'double'])
101        expected = (
102            '#include <math.h>\n'
103            'double \n'
104            'test_func(double a0, double a1)\n'
105            '{\n'
106            '\treturn hypot(a0, a1);\n'
107            '}\n'
108        )
109        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
110
111    def test_func_void_return(self):
112        e = make_entry('func', 'free', ['stdlib.h'], rtype='void',
113                       atypes=['void *'])
114        expected = (
115            '#include <stdlib.h>\n'
116            'void \n'
117            'test_func(void * a0)\n'
118            '{\n'
119            '\tfree(a0);\n'
120            '}\n'
121        )
122        self.assertEqual(ProbeGen.gen_probe(e, 'c'), expected)
123
124
125class TestGenProbeCxx(unittest.TestCase):
126    """Probe generation for lang='c++'."""
127
128    def test_func_result_macro(self):
129        """Non-void non-fnptr return: RESULT() macro must be emitted."""
130        e = make_entry('func', 'log', ['cmath'], rtype='double', atypes=['double'])
131        expected = (
132            '#include <cmath>\n'
133            '#if __cplusplus >= 201103L\n'
134            '#define RESULT(v) result{v}\n'
135            '#else\n'
136            '#define RESULT(v) result = (v)\n'
137            '#endif\n'
138            'double \n'
139            'test_func(double a0)\n'
140            '{\n'
141            '\tdouble RESULT(log(a0));\n'
142            '\treturn result;\n'
143            '}\n'
144        )
145        self.assertEqual(ProbeGen.gen_probe(e, 'c++'), expected)
146
147    def test_func_void_return(self):
148        """void return: no RESULT() macro; same form as C."""
149        e = make_entry('func', 'free', ['cstdlib'], rtype='void',
150                       atypes=['void *'])
151        expected = (
152            '#include <cstdlib>\n'
153            'void \n'
154            'test_func(void * a0)\n'
155            '{\n'
156            '\tfree(a0);\n'
157            '}\n'
158        )
159        self.assertEqual(ProbeGen.gen_probe(e, 'c++'), expected)
160
161
162if __name__ == '__main__':
163    unittest.main()
164