test_check_cfc.py 7.3 KB

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