Python Library Unittest
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

jsonlog.py 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. import json
  5. import os
  6. import subprocess
  7. import fstools
  8. from unittest.output import STATUS_AVAILABLE, STATUS_CHANGED, STATUS_CLEAN, STATUS_EXISTS, STATUS_IN_WORK, STATUS_MISSING, STATUS_OLD, STATUS_RELEASED, STATUS_UNKNOWN
  9. JSONLOG_FNAME = 'unittest.json'
  10. #
  11. # MAIN KEYS
  12. #
  13. MAIN_KEY_COVERAGE_INFO = 'coverage_information'
  14. MAIN_KEY_LOST_SOULS = "lost_souls"
  15. MAIN_KEY_SPECIFICATION = 'specification'
  16. MAIN_KEY_SYSTEM_INFO = 'system_information'
  17. MAIN_KEY_TESTOBJECT_INFO = 'testobject_information'
  18. MAIN_KEY_TESTRUNS = 'testrun_list'
  19. MAIN_KEY_UNITTEST_INFO = 'unittest_information'
  20. #
  21. # SUBKEYS FOR MAIN_KEY_COVERAGE_INFO
  22. #
  23. COVI_KEY_NAME = 'name'
  24. COVI_KEY_FILEPATH = 'filepath'
  25. COVI_KEY_LINE_COVERAGE = 'line_coverage'
  26. COVI_KEY_BRANCH_COVERAGE = 'branch_coverage'
  27. COVI_KEY_FILES = 'files'
  28. #
  29. # SUBKEYS FOR MAIN_KEY_LOST_SOULS
  30. #
  31. LOST_ITEMLIST = "item_list"
  32. LOST_TESTCASELIST = "testcase_list"
  33. #
  34. # SUBKEYS FOR MAIN_KEY_SPECIFICATION
  35. #
  36. SPEC_ITEM_DICT = 'item_dict'
  37. #
  38. # SUBKEYS FOR MAIN_KEY_SYSTEM_INFO
  39. #
  40. SYSI_ARCHITECTURE = "Architecture"
  41. SYSI_DISTRIBUTION = "Distribution"
  42. SYSI_HOSTNAME = "Hostname"
  43. SYSI_KERNEL = "Kernel"
  44. SYSI_MACHINE = "Machine"
  45. SYSI_PATH = "Path"
  46. SYSI_SYSTEM = "System"
  47. SYSI_USERNAME = "Username"
  48. #
  49. # SUBKEYS FOR MAIN_KEY_TESTOBJECT_INFO
  50. #
  51. TOBI_DEPENDENCIES = "Dependencies"
  52. TOBI_DESCRIPTION = "Description"
  53. TOBI_NAME = "Name"
  54. TOBI_STATE = "State"
  55. TOBI_STATE_RELESED = 'Released'
  56. TOBI_STATE_IN_DEVELOPMENT = 'In development'
  57. TOBI_SUPP_INTERP = "Supported Interpreters"
  58. TOBI_VERSION = "Version"
  59. #
  60. # SUBKEYS FOR MAIN_KEY_TESTRUNS
  61. #
  62. TRUN_TESTCASES = 'testcases'
  63. #
  64. # SUBKEYS FOR MAIN_KEY_UNITTEST_INFO
  65. #
  66. UTEI_VERSION = TOBI_VERSION
  67. def get_lib_folder(ut_folder):
  68. return os.path.join(ut_folder, 'pylibs', os.path.basename(ut_folder))
  69. def get_ut_config(ut_folder):
  70. return os.path.join(get_ut_src_folder(ut_folder), 'config.py')
  71. def get_ut_testcase_folder(ut_folder):
  72. return os.path.join(get_ut_src_folder(ut_folder), 'tests')
  73. def get_ut_testresult_folder(ut_folder):
  74. return os.path.join(get_ut_subfolder(ut_folder), 'testresults')
  75. def get_lib_testresult_folder(ut_folder):
  76. return os.path.join(get_lib_folder(ut_folder), '_testresults_')
  77. def get_lib_jsonlog(ut_folder):
  78. return os.path.join(get_lib_testresult_folder(ut_folder), JSONLOG_FNAME)
  79. def get_ut_jsonlog(ut_folder):
  80. return os.path.join(get_ut_testresult_folder(ut_folder), JSONLOG_FNAME)
  81. def get_ut_src_folder(ut_folder):
  82. return os.path.join(get_ut_subfolder(ut_folder), 'src')
  83. def get_ut_subfolder(ut_folder):
  84. return os.path.join(ut_folder, 'unittest')
  85. def module_uid(path):
  86. return fstools.uid_filelist(path, '*.py', rekursive=True)
  87. def __get_release_state__(ut_folder, lib):
  88. if lib:
  89. fn = get_lib_jsonlog(ut_folder)
  90. else:
  91. fn = get_ut_jsonlog(ut_folder)
  92. try:
  93. with open(fn, 'r') as fh:
  94. ut_data = json.loads(fh.read())
  95. except IOError:
  96. return STATUS_MISSING
  97. else:
  98. ut_status = ut_data.get(MAIN_KEY_TESTOBJECT_INFO, {}).get(TOBI_STATE, 'unknown')
  99. if 'released' in ut_status.lower():
  100. return STATUS_RELEASED
  101. elif 'work' in ut_status.lower():
  102. return STATUS_IN_WORK
  103. else:
  104. return STATUS_UNKNOWN
  105. def get_lib_release_state(ut_folder):
  106. return __get_release_state__(ut_folder, True)
  107. def get_ut_release_state(ut_folder):
  108. return __get_release_state__(ut_folder, False)
  109. def __get_testcase_integrity__(ut_folder, lib):
  110. if lib:
  111. fn = get_lib_jsonlog(ut_folder)
  112. else:
  113. fn = get_ut_jsonlog(ut_folder)
  114. try:
  115. with open(fn, 'r') as fh:
  116. ut_data = json.loads(fh.read())
  117. except IOError:
  118. return STATUS_MISSING
  119. else:
  120. tc_version = ut_data.get(MAIN_KEY_UNITTEST_INFO, {}).get(UTEI_VERSION)
  121. current_version = module_uid(get_ut_testcase_folder(ut_folder))
  122. if tc_version == current_version:
  123. return STATUS_CLEAN
  124. else:
  125. return STATUS_CHANGED
  126. def get_lib_testcase_integrity(ut_folder):
  127. return __get_testcase_integrity__(ut_folder, True)
  128. def get_ut_testcase_integrity(ut_folder):
  129. return __get_testcase_integrity__(ut_folder, False)
  130. def __get_src_integrity__(ut_folder, lib):
  131. if lib:
  132. fn = get_lib_jsonlog(ut_folder)
  133. else:
  134. fn = get_ut_jsonlog(ut_folder)
  135. try:
  136. with open(fn, 'r') as fh:
  137. ut_data = json.loads(fh.read())
  138. except IOError:
  139. return STATUS_MISSING
  140. else:
  141. tested_version = ut_data.get(MAIN_KEY_TESTOBJECT_INFO, {}).get(TOBI_VERSION)
  142. current_version = module_uid(get_lib_folder(ut_folder))
  143. if tested_version == current_version:
  144. return STATUS_CLEAN
  145. else:
  146. return STATUS_CHANGED
  147. def get_lib_src_integrity(ut_folder):
  148. return __get_src_integrity__(ut_folder, True)
  149. def get_ut_src_integrity(ut_folder):
  150. return __get_src_integrity__(ut_folder, False)
  151. def status_module(ut_folder):
  152. try:
  153. with open(get_lib_jsonlog(ut_folder), 'r') as fh:
  154. ut_lib = json.loads(fh.read())
  155. except IOError:
  156. return STATUS_MISSING
  157. else:
  158. try:
  159. with open(get_ut_jsonlog(ut_folder), 'r') as fh:
  160. ut_ut = json.loads(fh.read())
  161. except IOError:
  162. return STATUS_UNKNOWN
  163. else:
  164. tested_version = ut_lib.get(MAIN_KEY_TESTOBJECT_INFO, {}).get(TOBI_VERSION)
  165. current_version = module_uid(get_lib_folder(ut_folder))
  166. if ut_ut[MAIN_KEY_TESTOBJECT_INFO] != ut_lib[MAIN_KEY_TESTOBJECT_INFO] or ut_ut[MAIN_KEY_UNITTEST_INFO] != ut_lib[MAIN_KEY_UNITTEST_INFO] or tested_version != current_version:
  167. return STATUS_OLD
  168. else:
  169. ut_status = ut_lib.get(MAIN_KEY_TESTOBJECT_INFO, {}).get(TOBI_STATE, 'unknown')
  170. if 'released' in ut_status.lower():
  171. return STATUS_RELEASED
  172. elif 'work' in ut_status.lower():
  173. return STATUS_IN_WORK
  174. else:
  175. return STATUS_UNKNOWN
  176. def versions_module(ut_folder):
  177. try:
  178. with open(get_ut_jsonlog(ut_folder), 'r') as fh:
  179. ut = json.loads(fh.read())
  180. except IOError:
  181. return STATUS_UNKNOWN
  182. else:
  183. interpreters = ut.get(MAIN_KEY_TESTOBJECT_INFO, {}).get(TOBI_SUPP_INTERP, '')
  184. interpreters = interpreters.split(',')
  185. for i in range(len(interpreters)):
  186. interpreters[i] = interpreters[i].strip()
  187. interpreters[i] = interpreters[i][6:]
  188. return ', '.join(interpreters)
  189. def __get_coverage__(ut_folder, lib):
  190. if lib:
  191. fn = get_lib_jsonlog(ut_folder)
  192. else:
  193. fn = get_ut_jsonlog(ut_folder)
  194. try:
  195. with open(fn, 'r') as fh:
  196. ut = json.loads(fh.read())
  197. except IOError:
  198. return None, None
  199. else:
  200. lcov = ut.get(MAIN_KEY_COVERAGE_INFO, [{}])[0].get(COVI_KEY_LINE_COVERAGE)
  201. bcov = ut.get(MAIN_KEY_COVERAGE_INFO, [{}])[0].get(COVI_KEY_BRANCH_COVERAGE)
  202. return lcov, bcov
  203. def lib_coverage(ut_folder):
  204. return __get_coverage__(ut_folder, True)
  205. def ut_coverage(ut_folder):
  206. return __get_coverage__(ut_folder, False)
  207. def status_git(ut_folder):
  208. p = subprocess.Popen("git -C %s status 2> /dev/null" % ut_folder, stdout=subprocess.PIPE, shell=True)
  209. output = p.communicate()[0]
  210. p_status = p.wait()
  211. if p_status == 0:
  212. if b"nichts zu committen" in output and b"um lokale Commits zu publizieren" not in output:
  213. return STATUS_CLEAN
  214. else:
  215. return STATUS_CHANGED
  216. else:
  217. return STATUS_UNKNOWN
  218. def status_doc(ut_folder):
  219. if os.path.exists(os.path.join(get_lib_folder(ut_folder), '_docs_', 'index.html')):
  220. return STATUS_AVAILABLE
  221. else:
  222. if os.path.exists(os.path.join(ut_folder, 'docs', 'index.rst')):
  223. return STATUS_IN_WORK
  224. else:
  225. return STATUS_MISSING
  226. def status_spec(ut_folder):
  227. if os.path.exists(os.path.join(ut_folder, 'requirements', 'specification.reqif')):
  228. try:
  229. with open(get_ut_jsonlog(ut_folder), 'r') as fh:
  230. ut = json.loads(fh.read())
  231. if len(ut[MAIN_KEY_LOST_SOULS][LOST_ITEMLIST]) > 0 or len(ut[MAIN_KEY_LOST_SOULS][LOST_TESTCASELIST]) > 0:
  232. return STATUS_IN_WORK
  233. else:
  234. return STATUS_CLEAN
  235. except IOError:
  236. return STATUS_EXISTS
  237. else:
  238. return STATUS_MISSING