xref: /llvm-project/clang/utils/check_cfc/test_check_cfc.py (revision dd3c26a045c081620375a878159f536758baba6e)
19dd02c6cSSerge Guelton#!/usr/bin/env python
2b9e15b2eSRussell Gallop
3b9e15b2eSRussell Gallop"""Test internal functions within check_cfc.py."""
4b9e15b2eSRussell Gallop
5b9e15b2eSRussell Gallopimport check_cfc
6b9e15b2eSRussell Gallopimport os
7b9e15b2eSRussell Gallopimport platform
8b9e15b2eSRussell Gallopimport unittest
9b9e15b2eSRussell Gallop
10b9e15b2eSRussell Gallop
11b9e15b2eSRussell Gallopclass TestCheckCFC(unittest.TestCase):
12b9e15b2eSRussell Gallop    def test_flip_dash_g(self):
13*dd3c26a0STobias Hieta        self.assertIn("-g", check_cfc.flip_dash_g(["clang", "-c"]))
14*dd3c26a0STobias Hieta        self.assertNotIn("-g", check_cfc.flip_dash_g(["clang", "-c", "-g"]))
15*dd3c26a0STobias Hieta        self.assertNotIn("-g", check_cfc.flip_dash_g(["clang", "-g", "-c", "-g"]))
16b9e15b2eSRussell Gallop
17b9e15b2eSRussell Gallop    def test_remove_dir_from_path(self):
18*dd3c26a0STobias Hieta        bin_path = r"/usr/bin"
19*dd3c26a0STobias Hieta        space_path = r"/home/user/space in path"
20*dd3c26a0STobias Hieta        superstring_path = r"/usr/bin/local"
21b9e15b2eSRussell Gallop
22b9e15b2eSRussell Gallop        # Test removing last thing in path
23*dd3c26a0STobias Hieta        self.assertNotIn(bin_path, check_cfc.remove_dir_from_path(bin_path, bin_path))
24b9e15b2eSRussell Gallop
25b9e15b2eSRussell Gallop        # Test removing one entry and leaving others
26b9e15b2eSRussell Gallop        # Also tests removing repeated path
27*dd3c26a0STobias Hieta        path_var = os.pathsep.join([superstring_path, bin_path, space_path, bin_path])
28b9e15b2eSRussell Gallop        stripped_path_var = check_cfc.remove_dir_from_path(path_var, bin_path)
29b9e15b2eSRussell Gallop        self.assertIn(superstring_path, stripped_path_var)
30b9e15b2eSRussell Gallop        self.assertNotIn(bin_path, stripped_path_var.split(os.pathsep))
31b9e15b2eSRussell Gallop        self.assertIn(space_path, stripped_path_var)
32b9e15b2eSRussell Gallop
33b9e15b2eSRussell Gallop        # Test removing non-canonical path
34*dd3c26a0STobias Hieta        self.assertNotIn(
35*dd3c26a0STobias Hieta            r"/usr//bin", check_cfc.remove_dir_from_path(r"/usr//bin", bin_path)
36*dd3c26a0STobias Hieta        )
37b9e15b2eSRussell Gallop
38*dd3c26a0STobias Hieta        if platform == "Windows":
39b9e15b2eSRussell Gallop            # Windows is case insensitive so should remove a different case
40b9e15b2eSRussell Gallop            # path
41b9e15b2eSRussell Gallop            self.assertNotIn(
42*dd3c26a0STobias Hieta                bin_path, check_cfc.remove_dir_from_path(path_var, r"/USR/BIN")
43*dd3c26a0STobias Hieta            )
44b9e15b2eSRussell Gallop        else:
45b9e15b2eSRussell Gallop            # Case sensitive so will not remove different case path
46b9e15b2eSRussell Gallop            self.assertIn(
47*dd3c26a0STobias Hieta                bin_path, check_cfc.remove_dir_from_path(path_var, r"/USR/BIN")
48*dd3c26a0STobias Hieta            )
49b9e15b2eSRussell Gallop
50b9e15b2eSRussell Gallop    def test_is_output_specified(self):
51*dd3c26a0STobias Hieta        self.assertTrue(check_cfc.is_output_specified(["clang", "-o", "test.o"]))
52*dd3c26a0STobias Hieta        self.assertTrue(check_cfc.is_output_specified(["clang", "-otest.o"]))
53*dd3c26a0STobias Hieta        self.assertFalse(check_cfc.is_output_specified(["clang", "-gline-tables-only"]))
54b9e15b2eSRussell Gallop        # Not specified for implied output file name
55*dd3c26a0STobias Hieta        self.assertFalse(check_cfc.is_output_specified(["clang", "test.c"]))
56b9e15b2eSRussell Gallop
57b9e15b2eSRussell Gallop    def test_get_output_file(self):
58*dd3c26a0STobias Hieta        self.assertEqual(check_cfc.get_output_file(["clang", "-o", "test.o"]), "test.o")
59*dd3c26a0STobias Hieta        self.assertEqual(check_cfc.get_output_file(["clang", "-otest.o"]), "test.o")
60*dd3c26a0STobias Hieta        self.assertIsNone(check_cfc.get_output_file(["clang", "-gline-tables-only"]))
61b9e15b2eSRussell Gallop        # Can't get output file if more than one input file
62b9e15b2eSRussell Gallop        self.assertIsNone(
63*dd3c26a0STobias Hieta            check_cfc.get_output_file(["clang", "-c", "test.cpp", "test2.cpp"])
64*dd3c26a0STobias Hieta        )
65b9e15b2eSRussell Gallop        # No output file specified
66*dd3c26a0STobias Hieta        self.assertIsNone(check_cfc.get_output_file(["clang", "-c", "test.c"]))
67b9e15b2eSRussell Gallop
68b9e15b2eSRussell Gallop    def test_derive_output_file(self):
69b9e15b2eSRussell Gallop        # Test getting implicit output file
70b9e15b2eSRussell Gallop        self.assertEqual(
71*dd3c26a0STobias Hieta            check_cfc.derive_output_file(["clang", "-c", "test.c"]), "test.o"
72*dd3c26a0STobias Hieta        )
73b9e15b2eSRussell Gallop        self.assertEqual(
74*dd3c26a0STobias Hieta            check_cfc.derive_output_file(["clang", "-c", "test.cpp"]), "test.o"
75*dd3c26a0STobias Hieta        )
76*dd3c26a0STobias Hieta        self.assertIsNone(check_cfc.derive_output_file(["clang", "--version"]))
77b9e15b2eSRussell Gallop
78b9e15b2eSRussell Gallop    def test_is_normal_compile(self):
79b9e15b2eSRussell Gallop        self.assertTrue(
80*dd3c26a0STobias Hieta            check_cfc.is_normal_compile(["clang", "-c", "test.cpp", "-o", "test2.o"])
81*dd3c26a0STobias Hieta        )
82*dd3c26a0STobias Hieta        self.assertTrue(check_cfc.is_normal_compile(["clang", "-c", "test.cpp"]))
83b9e15b2eSRussell Gallop        # Outputting bitcode is not a normal compile
84b9e15b2eSRussell Gallop        self.assertFalse(
85*dd3c26a0STobias Hieta            check_cfc.is_normal_compile(["clang", "-c", "test.cpp", "-flto"])
86*dd3c26a0STobias Hieta        )
87b9e15b2eSRussell Gallop        self.assertFalse(
88*dd3c26a0STobias Hieta            check_cfc.is_normal_compile(["clang", "-c", "test.cpp", "-emit-llvm"])
89*dd3c26a0STobias Hieta        )
90b9e15b2eSRussell Gallop        # Outputting preprocessed output or assembly is not a normal compile
91b9e15b2eSRussell Gallop        self.assertFalse(
92*dd3c26a0STobias Hieta            check_cfc.is_normal_compile(["clang", "-E", "test.cpp", "-o", "test.ii"])
93*dd3c26a0STobias Hieta        )
94b9e15b2eSRussell Gallop        self.assertFalse(
95*dd3c26a0STobias Hieta            check_cfc.is_normal_compile(["clang", "-S", "test.cpp", "-o", "test.s"])
96*dd3c26a0STobias Hieta        )
97b9e15b2eSRussell Gallop        # Input of preprocessed or assembly is not a "normal compile"
98b9e15b2eSRussell Gallop        self.assertFalse(
99*dd3c26a0STobias Hieta            check_cfc.is_normal_compile(["clang", "-c", "test.s", "-o", "test.o"])
100*dd3c26a0STobias Hieta        )
101b9e15b2eSRussell Gallop        self.assertFalse(
102*dd3c26a0STobias Hieta            check_cfc.is_normal_compile(["clang", "-c", "test.ii", "-o", "test.o"])
103*dd3c26a0STobias Hieta        )
104b9e15b2eSRussell Gallop        # Specifying --version and -c is not a normal compile
105b9e15b2eSRussell Gallop        self.assertFalse(
106*dd3c26a0STobias Hieta            check_cfc.is_normal_compile(["clang", "-c", "test.cpp", "--version"])
107*dd3c26a0STobias Hieta        )
108b9e15b2eSRussell Gallop        self.assertFalse(
109*dd3c26a0STobias Hieta            check_cfc.is_normal_compile(["clang", "-c", "test.cpp", "--help"])
110*dd3c26a0STobias Hieta        )
11114c4dab6SRussell Gallop        # Outputting dependency files is not a normal compile
112*dd3c26a0STobias Hieta        self.assertFalse(check_cfc.is_normal_compile(["clang", "-c", "-M", "test.cpp"]))
11314c4dab6SRussell Gallop        self.assertFalse(
114*dd3c26a0STobias Hieta            check_cfc.is_normal_compile(["clang", "-c", "-MM", "test.cpp"])
115*dd3c26a0STobias Hieta        )
11614c4dab6SRussell Gallop        # Creating a dependency file as a side effect still outputs an object file
117*dd3c26a0STobias Hieta        self.assertTrue(check_cfc.is_normal_compile(["clang", "-c", "-MD", "test.cpp"]))
11814c4dab6SRussell Gallop        self.assertTrue(
119*dd3c26a0STobias Hieta            check_cfc.is_normal_compile(["clang", "-c", "-MMD", "test.cpp"])
120*dd3c26a0STobias Hieta        )
121b9e15b2eSRussell Gallop
122b9e15b2eSRussell Gallop    def test_replace_output_file(self):
123*dd3c26a0STobias Hieta        self.assertEqual(
124*dd3c26a0STobias Hieta            check_cfc.replace_output_file(["clang", "-o", "test.o"], "testg.o"),
125*dd3c26a0STobias Hieta            ["clang", "-o", "testg.o"],
126*dd3c26a0STobias Hieta        )
127*dd3c26a0STobias Hieta        self.assertEqual(
128*dd3c26a0STobias Hieta            check_cfc.replace_output_file(["clang", "-otest.o"], "testg.o"),
129*dd3c26a0STobias Hieta            ["clang", "-otestg.o"],
130*dd3c26a0STobias Hieta        )
131b9e15b2eSRussell Gallop        with self.assertRaises(Exception):
132*dd3c26a0STobias Hieta            check_cfc.replace_output_file(["clang"], "testg.o")
133b9e15b2eSRussell Gallop
134b9e15b2eSRussell Gallop    def test_add_output_file(self):
135*dd3c26a0STobias Hieta        self.assertEqual(
136*dd3c26a0STobias Hieta            check_cfc.add_output_file(["clang"], "testg.o"), ["clang", "-o", "testg.o"]
137*dd3c26a0STobias Hieta        )
138b9e15b2eSRussell Gallop
139b9e15b2eSRussell Gallop    def test_set_output_file(self):
140b9e15b2eSRussell Gallop        # Test output not specified
141b9e15b2eSRussell Gallop        self.assertEqual(
142*dd3c26a0STobias Hieta            check_cfc.set_output_file(["clang"], "test.o"), ["clang", "-o", "test.o"]
143*dd3c26a0STobias Hieta        )
144b9e15b2eSRussell Gallop        # Test output is specified
145*dd3c26a0STobias Hieta        self.assertEqual(
146*dd3c26a0STobias Hieta            check_cfc.set_output_file(["clang", "-o", "test.o"], "testb.o"),
147*dd3c26a0STobias Hieta            ["clang", "-o", "testb.o"],
148*dd3c26a0STobias Hieta        )
149b9e15b2eSRussell Gallop
150b9e15b2eSRussell Gallop    def test_get_input_file(self):
151b9e15b2eSRussell Gallop        # No input file
152*dd3c26a0STobias Hieta        self.assertIsNone(check_cfc.get_input_file(["clang"]))
153b9e15b2eSRussell Gallop        # Input C file
154*dd3c26a0STobias Hieta        self.assertEqual(check_cfc.get_input_file(["clang", "test.c"]), "test.c")
155b9e15b2eSRussell Gallop        # Input C++ file
156*dd3c26a0STobias Hieta        self.assertEqual(check_cfc.get_input_file(["clang", "test.cpp"]), "test.cpp")
157b9e15b2eSRussell Gallop        # Multiple input files
158*dd3c26a0STobias Hieta        self.assertIsNone(check_cfc.get_input_file(["clang", "test.c", "test2.cpp"]))
159*dd3c26a0STobias Hieta        self.assertIsNone(check_cfc.get_input_file(["clang", "test.c", "test2.c"]))
160b9e15b2eSRussell Gallop        # Don't handle preprocessed files
161*dd3c26a0STobias Hieta        self.assertIsNone(check_cfc.get_input_file(["clang", "test.i"]))
162*dd3c26a0STobias Hieta        self.assertIsNone(check_cfc.get_input_file(["clang", "test.ii"]))
163b9e15b2eSRussell Gallop        # Test identifying input file with quotes
164*dd3c26a0STobias Hieta        self.assertEqual(check_cfc.get_input_file(["clang", '"test.c"']), '"test.c"')
165*dd3c26a0STobias Hieta        self.assertEqual(check_cfc.get_input_file(["clang", "'test.c'"]), "'test.c'")
166b9e15b2eSRussell Gallop        # Test multiple quotes
167b9e15b2eSRussell Gallop        self.assertEqual(
168*dd3c26a0STobias Hieta            check_cfc.get_input_file(["clang", "\"'test.c'\""]), "\"'test.c'\""
169*dd3c26a0STobias Hieta        )
170b9e15b2eSRussell Gallop
171b9e15b2eSRussell Gallop    def test_set_input_file(self):
172*dd3c26a0STobias Hieta        self.assertEqual(
173*dd3c26a0STobias Hieta            check_cfc.set_input_file(["clang", "test.c"], "test.s"), ["clang", "test.s"]
174*dd3c26a0STobias Hieta        )
175b9e15b2eSRussell Gallop
176*dd3c26a0STobias Hieta
177*dd3c26a0STobias Hietaif __name__ == "__main__":
178b9e15b2eSRussell Gallop    unittest.main()
179