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