Python Library Unittest
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

jsonlog.py 8.2KB

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