Skip to content

Commit 34d129f

Browse files
committed
Use user-provided configuration to add tests
Using the new user-defined compiler functionality for these tests allows us to test both the ability to define specific compiler behaviors, and our ability to detect incorrectly defined compilers. Signed-off-by: John Pennycook <john.pennycook@intel.com>
1 parent 3cb70b9 commit 34d129f

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

tests/compilers/test_compilers.py

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,182 @@ def test_user_options(self):
197197

198198
tmp.cleanup()
199199

200+
def test_user_alias(self):
201+
"""Check that we import user-defined aliases"""
202+
tmp = tempfile.TemporaryDirectory()
203+
path = Path(tmp.name)
204+
os.chdir(tmp.name)
205+
os.mkdir(".cbi")
206+
with open(path / ".cbi" / "config", mode="w") as f:
207+
f.write('[compiler."c++"]\n')
208+
f.write('alias_of = "clang"\n')
209+
config._load_compilers()
210+
211+
parser = ArgumentParser("c++")
212+
passes = parser.parse_args(["-fopenmp", "test.cpp"])
213+
214+
self.assertEqual(len(passes), 1)
215+
self.assertCountEqual(passes[0].defines, ["_OPENMP"])
216+
217+
tmp.cleanup()
218+
219+
def test_nested_aliases(self):
220+
"""Check that we handle user-defined aliases to aliases"""
221+
tmp = tempfile.TemporaryDirectory()
222+
path = Path(tmp.name)
223+
os.chdir(tmp.name)
224+
os.mkdir(".cbi")
225+
with open(path / ".cbi" / "config", mode="w") as f:
226+
f.write('[compiler."c++"]\n')
227+
f.write('alias_of = "g++"\n')
228+
config._load_compilers()
229+
230+
parser = ArgumentParser("c++")
231+
passes = parser.parse_args(["-fopenmp", "test.cpp"])
232+
233+
self.assertEqual(len(passes), 1)
234+
self.assertCountEqual(passes[0].defines, ["_OPENMP"])
235+
236+
tmp.cleanup()
237+
238+
def test_alias_loops(self):
239+
"""Check that we identify and complain about alias loops"""
240+
tmp = tempfile.TemporaryDirectory()
241+
path = Path(tmp.name)
242+
os.chdir(tmp.name)
243+
os.mkdir(".cbi")
244+
with open(path / ".cbi" / "config", mode="w") as f:
245+
f.write("[compiler.foo]\n")
246+
f.write('alias_of = "bar"\n')
247+
f.write("[compiler.bar]\n")
248+
f.write('alias_of = "foo"\n')
249+
config._load_compilers()
250+
251+
logging.disable(logging.NOTSET)
252+
with self.assertLogs("codebasin", level=logging.ERROR):
253+
_ = ArgumentParser("foo")
254+
logging.disable()
255+
256+
tmp.cleanup()
257+
258+
def test_user_parser(self):
259+
"""Check that we import user-defined parser"""
260+
tmp = tempfile.TemporaryDirectory()
261+
path = Path(tmp.name)
262+
os.chdir(tmp.name)
263+
os.mkdir(".cbi")
264+
with open(path / ".cbi" / "config", mode="w") as f:
265+
f.write('[[compiler."c++".parser]]\n')
266+
f.write('flags = ["-fasdf"]\n')
267+
f.write('action = "append_const"\n')
268+
f.write('dest = "passes"\n')
269+
f.write('const = "asdf-pass"\n')
270+
f.write('[[compiler."c++".modes]]\n')
271+
f.write('name = "asdf-mode"\n')
272+
f.write('defines = ["ASDF"]\n')
273+
f.write('[[compiler."c++".passes]]\n')
274+
f.write('name = "asdf-pass"\n')
275+
f.write('modes = ["asdf-mode"]\n')
276+
277+
config._load_compilers()
278+
279+
parser = ArgumentParser("c++")
280+
passes = parser.parse_args(["-fasdf", "test.cpp"])
281+
282+
self.assertEqual(len(passes), 2)
283+
pass_names = {p.pass_name for p in passes}
284+
self.assertCountEqual(pass_names, {"default", "asdf-pass"})
285+
286+
for p in passes:
287+
if p.pass_name == "default":
288+
expected = []
289+
elif p.pass_name == "asdf-pass":
290+
expected = ["ASDF"]
291+
self.assertCountEqual(p.defines, expected)
292+
293+
tmp.cleanup()
294+
295+
def test_user_overrides(self):
296+
"""Check that we can merge user-defined overrides"""
297+
tmp = tempfile.TemporaryDirectory()
298+
path = Path(tmp.name)
299+
os.chdir(tmp.name)
300+
os.mkdir(".cbi")
301+
with open(path / ".cbi" / "config", mode="w") as f:
302+
f.write('[[compiler."g++".parser]]\n')
303+
f.write('flags = ["-fopenmp"]\n')
304+
f.write('action = "append_const"\n')
305+
f.write('dest = "passes"\n')
306+
f.write('const = "new-openmp-pass"\n')
307+
f.write("\n")
308+
f.write('[[compiler."g++".passes]]\n')
309+
f.write('name = "new-openmp-pass"\n')
310+
f.write('modes = ["new-openmp-mode"]\n')
311+
f.write("\n")
312+
f.write('[[compiler."g++".modes]]\n')
313+
f.write('name = "new-openmp-mode"\n')
314+
f.write('defines = ["_NEW_OPENMP"]\n')
315+
f.write("\n")
316+
f.write('[compiler."g++"]\n')
317+
f.write('options = ["-D", "EXTRA_DEFINE"]\n')
318+
f.write("\n")
319+
f.write("[[compiler.clang.modes]]\n")
320+
f.write('name = "openmp"\n')
321+
f.write("defines = []\n")
322+
f.write("\n")
323+
f.write("[[compiler.icx.passes]]\n")
324+
f.write('name = "sycl-spir64"\n')
325+
f.write("defines = []\n")
326+
f.write("\n")
327+
f.write("[compiler.nvcc]\n")
328+
f.write('alias_of = "unknown"\n')
329+
330+
# Verify that the correct warnings are generated when loading the file.
331+
logging.disable(logging.NOTSET)
332+
with self.assertLogs("codebasin", level=logging.WARNING) as cm:
333+
config._load_compilers()
334+
logging.disable()
335+
336+
self.assertEqual(
337+
cm.output,
338+
[
339+
"WARNING:codebasin.config:definition of g++ in .cbi/config overrides alias.",
340+
"WARNING:codebasin.config:compiler mode 'openmp' redefined",
341+
"WARNING:codebasin.config:compiler pass 'sycl-spir64' redefined",
342+
"WARNING:codebasin.config:nvcc redefined as alias of unknown.",
343+
],
344+
)
345+
346+
# Verify that user-defined overrides affect passes, etc.
347+
parser = ArgumentParser("g++")
348+
argv = ["-fopenmp"]
349+
passes = parser.parse_args(argv)
350+
351+
pass_names = {p.pass_name for p in passes}
352+
self.assertCountEqual(pass_names, {"default", "new-openmp-pass"})
353+
354+
for p in passes:
355+
if p.pass_name == "default":
356+
expected = ["EXTRA_DEFINE"]
357+
else:
358+
expected = ["EXTRA_DEFINE", "_NEW_OPENMP"]
359+
self.assertCountEqual(p.defines, expected)
360+
361+
# Verify that invalid aliases are identified.
362+
logging.disable(logging.NOTSET)
363+
with self.assertLogs("codebasin", level=logging.ERROR) as cm:
364+
_ = ArgumentParser("nvcc")
365+
logging.disable()
366+
367+
self.assertEqual(
368+
cm.output,
369+
[
370+
"ERROR:codebasin.config:Compiler 'nvcc' aliases unrecognized 'unknown'.",
371+
],
372+
)
373+
374+
tmp.cleanup()
375+
200376

201377
if __name__ == "__main__":
202378
unittest.main()

0 commit comments

Comments
 (0)