test_entity.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. #
  4. # SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
  5. # SPDX-License-Identifier: Apache-2.0
  6. #
  7. import os
  8. import sys
  9. import unittest
  10. try:
  11. from ldgen.entity import Entity, EntityDB
  12. except ImportError:
  13. sys.path.append(os.path.dirname(os.path.dirname(__file__)))
  14. from ldgen.entity import Entity, EntityDB
  15. class EntityTest(unittest.TestCase):
  16. def test_create_none(self):
  17. entity = Entity(Entity.ALL)
  18. self.assertEqual(Entity.Specificity.NONE, entity.specificity)
  19. entity = Entity(None)
  20. self.assertEqual(Entity.Specificity.NONE, entity.specificity)
  21. entity = Entity()
  22. self.assertEqual(Entity.Specificity.NONE, entity.specificity)
  23. def test_create_archive(self):
  24. entity = Entity('libfreertos.a')
  25. self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
  26. entity = Entity('libfreertos.a', Entity.ALL, Entity.ALL)
  27. self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
  28. entity = Entity('libfreertos.a', None, None)
  29. self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
  30. entity = Entity('libfreertos.a', Entity.ALL, None)
  31. self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
  32. entity = Entity('libfreertos.a', None, Entity.ALL)
  33. self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
  34. def test_create_obj(self):
  35. entity = Entity('libfreertos.a', 'croutine')
  36. self.assertEqual(Entity.Specificity.OBJ, entity.specificity)
  37. entity = Entity('libfreertos.a', 'croutine', Entity.ALL)
  38. self.assertEqual(Entity.Specificity.OBJ, entity.specificity)
  39. entity = Entity('libfreertos.a', 'croutine', None)
  40. self.assertEqual(Entity.Specificity.OBJ, entity.specificity)
  41. def test_create_symbol(self):
  42. entity = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
  43. self.assertEqual(Entity.Specificity.SYMBOL, entity.specificity)
  44. def test_create_invalid(self):
  45. with self.assertRaises(ValueError):
  46. Entity(None, 'croutine')
  47. with self.assertRaises(ValueError):
  48. Entity(Entity.ALL, 'croutine')
  49. with self.assertRaises(ValueError):
  50. Entity(None, None, 'prvCheckPendingReadyList')
  51. with self.assertRaises(ValueError):
  52. Entity(Entity.ALL, Entity.ALL, 'prvCheckPendingReadyList')
  53. with self.assertRaises(ValueError):
  54. Entity(None, Entity.ALL, 'prvCheckPendingReadyList')
  55. with self.assertRaises(ValueError):
  56. Entity(Entity.ALL, None, 'prvCheckPendingReadyList')
  57. with self.assertRaises(ValueError):
  58. Entity('libfreertos.a', None, 'prvCheckPendingReadyList')
  59. with self.assertRaises(ValueError):
  60. Entity('libfreertos.a', Entity.ALL, 'prvCheckPendingReadyList')
  61. def test_compare_different_specificity(self):
  62. # Different specificity: NONE < ARCHIVE < OBJ < SYMBOL
  63. entity_a = Entity()
  64. entity_b = Entity('libfreertos.a')
  65. self.assertLess(entity_a, entity_b)
  66. entity_a = Entity('libfreertos.a')
  67. entity_b = Entity('libfreertos.a', 'croutine')
  68. self.assertLess(entity_a, entity_b)
  69. entity_a = Entity('libfreertos.a', 'croutine')
  70. entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
  71. self.assertLess(entity_a, entity_b)
  72. entity_a = Entity(Entity.ALL)
  73. entity_b = Entity('libfreertos.a')
  74. self.assertLess(entity_a, entity_b)
  75. entity_a = Entity('libfreertos.a', Entity.ALL)
  76. entity_b = Entity('libfreertos.a', 'croutine')
  77. self.assertLess(entity_a, entity_b)
  78. entity_a = Entity('libfreertos.a', 'croutine', Entity.ALL)
  79. entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
  80. self.assertLess(entity_a, entity_b)
  81. def test_compare_equal(self):
  82. # Compare equal specificities and members
  83. entity_a = Entity()
  84. entity_b = Entity()
  85. self.assertEqual(entity_a, entity_b)
  86. entity_a = Entity('libfreertos.a')
  87. entity_b = Entity('libfreertos.a')
  88. self.assertEqual(entity_a, entity_b)
  89. entity_a = Entity('libfreertos.a', 'croutine')
  90. entity_b = Entity('libfreertos.a', 'croutine')
  91. self.assertEqual(entity_a, entity_b)
  92. entity_a = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
  93. entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
  94. self.assertEqual(entity_a, entity_b)
  95. def test_compare_none_vs_all(self):
  96. # Two entities might have the same specifity whether
  97. # Entity.ALL is used or not specified; the latter is
  98. # considered less than the former.
  99. entity_a = Entity()
  100. entity_b = Entity(Entity.ALL)
  101. self.assertLess(entity_a, entity_b)
  102. entity_a = Entity('libfreertos.a')
  103. entity_b = Entity('libfreertos.a', Entity.ALL, Entity.ALL)
  104. self.assertLess(entity_a, entity_b)
  105. entity_a = Entity('libfreertos.a', 'croutine')
  106. entity_b = Entity('libfreertos.a', 'croutine', Entity.ALL)
  107. self.assertLess(entity_a, entity_b)
  108. def test_compare_same_specificity(self):
  109. # Test that entities will be compared alphabetically
  110. # when the specificities are the same.
  111. entity_a = Entity('libfreertos_a.a')
  112. entity_b = Entity('libfreertos_b.a')
  113. self.assertLess(entity_a, entity_b)
  114. entity_a = Entity('libfreertos_b.a', 'croutine_a')
  115. entity_b = Entity('libfreertos_a.a', 'croutine_b')
  116. self.assertLess(entity_b, entity_a)
  117. entity_a = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList_a')
  118. entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList_b')
  119. self.assertLess(entity_a, entity_b)
  120. entity_a = Entity('libfreertos.a', 'croutine_b', 'prvCheckPendingReadyList_a')
  121. entity_b = Entity('libfreertos.a', 'croutine_a', 'prvCheckPendingReadyList_b')
  122. self.assertLess(entity_b, entity_a)
  123. entity_a = Entity('libfreertos_a.a', 'croutine_b', 'prvCheckPendingReadyList_a')
  124. entity_b = Entity('libfreertos_b.a', 'croutine_a', 'prvCheckPendingReadyList_b')
  125. self.assertLess(entity_a, entity_b)
  126. def test_compare_all_non_character(self):
  127. # Test that Entity.ALL is not treated as an
  128. # ordinary character in comparisons.
  129. entity_a = Entity(Entity.ALL)
  130. entity_b = Entity(chr(ord(Entity.ALL[0]) - 1))
  131. self.assertLess(entity_a, entity_b)
  132. entity_a = Entity('libfreertos.a', Entity.ALL)
  133. entity_b = Entity('libfreertos.a', chr(ord(Entity.ALL[0]) - 1))
  134. self.assertLess(entity_a, entity_b)
  135. entity_a = Entity('libfreertos.a', 'croutine', '*')
  136. entity_b = Entity('libfreertos.a', 'croutine', chr(ord(Entity.ALL[0]) - 1))
  137. self.assertLess(entity_a, entity_b)
  138. class EntityDBTest(unittest.TestCase):
  139. def setUp(self):
  140. self.entities = EntityDB()
  141. with open('data/test_entity/libfreertos.a.txt') as objdump:
  142. self.entities.add_sections_info(objdump)
  143. def test_get_archives(self):
  144. archives = self.entities.get_archives()
  145. self.assertEqual(set(archives), set(['libfreertos.a']))
  146. def test_get_objs(self):
  147. objs = self.entities.get_objects('libfreertos.a')
  148. self.assertEqual(set(objs), set(['croutine.S.obj', 'croutine.c.obj', 'croutine.cpp.obj', 'timers.o']))
  149. def test_get_sections(self):
  150. # Needs disambugation between possible matches: croutine.S, croutine.c, croutine.cpp
  151. with self.assertRaises(ValueError):
  152. self.entities.get_sections('libfreertos.a', 'croutine')
  153. # Test disambugation works
  154. sections = self.entities.get_sections('libfreertos.a', 'croutine.c')
  155. expected = set(['.literal.prvCheckPendingReadyList', '.literal.prvCheckDelayedList'])
  156. self.assertEqual(set(sections), expected)
  157. sections = self.entities.get_sections('libfreertos.a', 'croutine.S')
  158. expected = set(['.debug_frame', '.debug_info', '.debug_abbrev'])
  159. self.assertEqual(set(sections), expected)
  160. # Test .o extension works
  161. sections = self.entities.get_sections('libfreertos.a', 'timers')
  162. expected = set(['.literal.prvGetNextExpireTime', '.literal.prvInsertTimerInActiveList'])
  163. self.assertEqual(set(sections), expected)
  164. def test_parsing(self):
  165. # Tests parsing objdump with the following:
  166. #
  167. # - non-ascii characters
  168. # - different architecture string
  169. # - different column entries for each sections
  170. # - unexpected 'comments'
  171. with open('data/test_entity/parse_test.txt') as objdump:
  172. self.entities.add_sections_info(objdump)
  173. sections = self.entities.get_sections('ěščřžýáíé.a', 'croutine')
  174. self.assertEqual(set(sections), set(['.text', '.data', '.bss']))
  175. sections = self.entities.get_sections('ěščřžýáíé.a', 'FreeRTOS-ěščřžýáíé')
  176. self.assertEqual(set(sections), set(['.literal.ěščřžýáíé']))
  177. if __name__ == '__main__':
  178. unittest.main()