check_index.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import sys
  2. import os
  3. import json
  4. import re
  5. if sys.version_info[0] >= 3:
  6. unicode = str
  7. def is_bool(x, val=None):
  8. return isinstance(x, bool) and (val is None or x == val)
  9. def is_dict(x):
  10. return isinstance(x, dict)
  11. def is_list(x):
  12. return isinstance(x, list)
  13. def is_int(x, val=None):
  14. return (isinstance(x, int) or isinstance(x, long)) and (val is None or x == val)
  15. def is_string(x, val=None):
  16. return (isinstance(x, str) or isinstance(x, unicode)) and (val is None or x == val)
  17. def matches(s, pattern):
  18. return is_string(s) and bool(re.search(pattern, s))
  19. def check_list_match(match, actual, expected, check=None, check_exception=None, missing_exception=None, extra_exception=None, allow_extra=False):
  20. """
  21. Handle the common pattern of making sure every actual item "matches" some
  22. item in the expected list, and that neither list has extra items after
  23. matching is completed.
  24. @param match: Callback to check if an actual item matches an expected
  25. item. Return True if the item matches, return False if the item doesn't
  26. match.
  27. @param actual: List of actual items to search.
  28. @param expected: List of expected items to match.
  29. @param check: Optional function to check that the actual item is valid by
  30. comparing it to the expected item.
  31. @param check_exception: Optional function that returns an argument to
  32. append to any exception thrown by the check function.
  33. @param missing_exception: Optional function that returns an argument to
  34. append to the exception thrown when an item is not found.
  35. @param extra_exception: Optional function that returns an argument to
  36. append to the exception thrown when an extra item is found.
  37. @param allow_extra: Optional parameter allowing there to be extra actual
  38. items after all the expected items have been found.
  39. """
  40. assert is_list(actual)
  41. _actual = actual[:]
  42. for expected_item in expected:
  43. found = False
  44. for i, actual_item in enumerate(_actual):
  45. if match(actual_item, expected_item):
  46. if check:
  47. try:
  48. check(actual_item, expected_item)
  49. except BaseException as e:
  50. if check_exception:
  51. e.args += (check_exception(actual_item, expected_item),)
  52. raise
  53. found = True
  54. del _actual[i]
  55. break
  56. if missing_exception:
  57. assert found, missing_exception(expected_item)
  58. else:
  59. assert found
  60. if not allow_extra:
  61. if extra_exception:
  62. assert len(_actual) == 0, [extra_exception(a) for a in _actual]
  63. else:
  64. assert len(_actual) == 0
  65. def filter_list(f, l):
  66. if l is not None:
  67. l = list(filter(f, l))
  68. if l == []:
  69. l = None
  70. return l
  71. def check_cmake(cmake):
  72. assert is_dict(cmake)
  73. assert sorted(cmake.keys()) == ["generator", "paths", "version"]
  74. check_cmake_version(cmake["version"])
  75. check_cmake_paths(cmake["paths"])
  76. check_cmake_generator(cmake["generator"])
  77. def check_cmake_version(v):
  78. assert is_dict(v)
  79. assert sorted(v.keys()) == ["isDirty", "major", "minor", "patch", "string", "suffix"]
  80. assert is_string(v["string"])
  81. assert is_int(v["major"])
  82. assert is_int(v["minor"])
  83. assert is_int(v["patch"])
  84. assert is_string(v["suffix"])
  85. assert is_bool(v["isDirty"])
  86. def check_cmake_paths(v):
  87. assert is_dict(v)
  88. assert sorted(v.keys()) == ["cmake", "cpack", "ctest", "root"]
  89. assert is_string(v["cmake"])
  90. assert is_string(v["cpack"])
  91. assert is_string(v["ctest"])
  92. assert is_string(v["root"])
  93. def check_cmake_generator(g):
  94. assert is_dict(g)
  95. name = g.get("name", None)
  96. assert is_string(name)
  97. if name.startswith("Visual Studio"):
  98. assert sorted(g.keys()) == ["multiConfig", "name", "platform"]
  99. assert is_string(g["platform"])
  100. else:
  101. assert sorted(g.keys()) == ["multiConfig", "name"]
  102. assert is_bool(g["multiConfig"], matches(name, "^(Visual Studio |Xcode$|Ninja Multi-Config$)"))
  103. def check_index_object(indexEntry, kind, major, minor, check):
  104. assert is_dict(indexEntry)
  105. assert sorted(indexEntry.keys()) == ["jsonFile", "kind", "version"]
  106. assert is_string(indexEntry["kind"])
  107. assert indexEntry["kind"] == kind
  108. assert is_dict(indexEntry["version"])
  109. assert sorted(indexEntry["version"].keys()) == ["major", "minor"]
  110. assert indexEntry["version"]["major"] == major
  111. assert indexEntry["version"]["minor"] == minor
  112. assert is_string(indexEntry["jsonFile"])
  113. filepath = os.path.join(reply_dir, indexEntry["jsonFile"])
  114. with open(filepath) as f:
  115. object = json.load(f)
  116. assert is_dict(object)
  117. assert "kind" in object
  118. assert is_string(object["kind"])
  119. assert object["kind"] == kind
  120. assert "version" in object
  121. assert is_dict(object["version"])
  122. assert sorted(object["version"].keys()) == ["major", "minor"]
  123. assert object["version"]["major"] == major
  124. assert object["version"]["minor"] == minor
  125. if check:
  126. check(object)
  127. def check_index__test(indexEntry, major, minor):
  128. def check(object):
  129. assert sorted(object.keys()) == ["kind", "version"]
  130. check_index_object(indexEntry, "__test", major, minor, check)
  131. def check_error(value, error):
  132. assert is_dict(value)
  133. assert sorted(value.keys()) == ["error"]
  134. assert is_string(value["error"])
  135. assert value["error"] == error
  136. def check_error_re(value, error):
  137. assert is_dict(value)
  138. assert sorted(value.keys()) == ["error"]
  139. assert is_string(value["error"])
  140. assert re.search(error, value["error"])
  141. reply_index = sys.argv[1]
  142. reply_dir = os.path.dirname(reply_index)
  143. with open(reply_index) as f:
  144. index = json.load(f)