xref: /illumos-gate/usr/src/test/header-tests/tests/common/test_parse_env_cfg.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 EnvConfig._parse() - the environment config file parser.
19
20Tests use canned string input via io.StringIO so no external files are needed.
21"""
22
23import io
24import unittest
25
26from symbol_test import EnvConfig, CompileEnv
27
28# ---------------------------------------------------------------------------
29# Canned input: a realistic slice of cxx-symbols-env.cfg.
30# Exercises: comment lines, blank lines, env with empty defs, env with defs,
31# env_group referencing multiple envs.
32# ---------------------------------------------------------------------------
33
34CANNED_CXX = """\
35#
36# Compilation environments for C++ symbol visibility tests.
37#
38
39# Plain C++ standards - no extra defines.
40env | CXX98\t\t| c++98 |
41env | CXX11\t\t| c++11 |
42env | CXX17\t\t| c++17 |
43
44# _C99 variants add -D_STDC_C99.
45env | CXX98_C99\t\t| c++98 | -D_STDC_C99
46env | CXX11_C99\t\t| c++11 | -D_STDC_C99
47
48env_group | CXX98+\t| CXX17 CXX11 CXX98
49env_group | CXX_C99+\t| CXX11_C99 CXX98_C99
50env_group | ALL\t\t| CXX98+
51"""
52
53# Expected envs: name -> (lang, defs)
54EXPECTED_ENVS = {
55    'CXX98':     ('c++98', ''),
56    'CXX11':     ('c++11', ''),
57    'CXX17':     ('c++17', ''),
58    'CXX98_C99': ('c++98', '-D_STDC_C99'),
59    'CXX11_C99': ('c++11', '-D_STDC_C99'),
60}
61
62# Expected groups: name -> frozenset of member env names
63EXPECTED_GROUPS = {
64    'CXX98+':   frozenset({'CXX17', 'CXX11', 'CXX98'}),
65    'CXX_C99+': frozenset({'CXX11_C99', 'CXX98_C99'}),
66    'ALL':       frozenset({'CXX17', 'CXX11', 'CXX98'}),
67}
68
69
70class TestParseEnvCfg(unittest.TestCase):
71
72    def setUp(self):
73        self.cfg = EnvConfig('c++')
74        self.cfg._parse(io.StringIO(CANNED_CXX), filename='<test>')
75
76    def test_env_count(self):
77        self.assertEqual(len(self.cfg.envs), len(EXPECTED_ENVS))
78
79    def test_env_names(self):
80        self.assertEqual(set(self.cfg.envs.keys()), set(EXPECTED_ENVS.keys()))
81
82    def test_env_lang_and_defs(self):
83        for name, (lang, defs) in EXPECTED_ENVS.items():
84            with self.subTest(env=name):
85                env = self.cfg.envs[name]
86                self.assertEqual(env.lang, lang)
87                self.assertEqual(env.defs, defs)
88
89    def test_group_count(self):
90        self.assertEqual(len(self.cfg.groups), len(EXPECTED_GROUPS))
91
92    def test_group_names(self):
93        self.assertEqual(set(self.cfg.groups.keys()),
94                         set(EXPECTED_GROUPS.keys()))
95
96    def test_group_members(self):
97        for name, members in EXPECTED_GROUPS.items():
98            with self.subTest(group=name):
99                self.assertEqual(self.cfg.groups[name], members)
100
101    def test_positive_coverage_sets(self):
102        self.assertEqual(set(self.cfg.envs), set(EXPECTED_ENVS))
103        self.assertEqual(self.cfg.expand('ALL'), set(EXPECTED_GROUPS['ALL']))
104        self.assertNotEqual(set(self.cfg.envs), self.cfg.expand('ALL'))
105
106    def test_resolve_expected_success(self):
107        test_set, need_set = self.cfg.resolve('-CXX98+ +CXX11')
108        self.assertEqual(test_set, set(EXPECTED_GROUPS['CXX98+']))
109        self.assertEqual(need_set, {'CXX11'})
110
111    def test_lang_mismatch_raises(self):
112        """--lang=c should be rejected when env lines use c++ standards."""
113        cfg = EnvConfig('c')
114        with self.assertRaises(SystemExit):
115            cfg._parse(io.StringIO(CANNED_CXX), filename='<test>')
116
117    def test_group_undefined_member_raises(self):
118        """A group referencing an undefined env name should raise."""
119        bad = "env | FOO | c++11 |\nenv_group | BAR | FOO NOSUCHENV\n"
120        cfg = EnvConfig('c++')
121        with self.assertRaises(SystemExit):
122            cfg._parse(io.StringIO(bad), filename='<test>')
123
124
125if __name__ == '__main__':
126    unittest.main()
127