tests_finder.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #!/usr/bin/env -S python3 -B
  2. # Copyright (c) 2023 Project CHIP Authors
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import json
  16. import os.path
  17. from typing import List
  18. import click
  19. _JSON_FILE_EXTENSION = '.json'
  20. _YAML_FILE_EXTENSION = '.yaml'
  21. _KNOWN_PREFIX = 'Test_TC_'
  22. _KEYWORD_ALL_TESTS = 'all'
  23. _DEFAULT_DIRECTORY = 'src/app/tests/suites/'
  24. _CI_CONFIGURATION_NAME = 'ciTests'
  25. _MANUAL_CONFIGURATION_NAME = 'manualTests'
  26. class TestsFinder:
  27. def __init__(self, configuration_directory: str = _DEFAULT_DIRECTORY, configuration_name: str = _CI_CONFIGURATION_NAME):
  28. self.__test_directory = _DEFAULT_DIRECTORY
  29. self.__test_collections = self.__get_collections(configuration_directory, configuration_name)
  30. def get_default_configuration_directory() -> str:
  31. return _DEFAULT_DIRECTORY
  32. def get_default_configuration_name() -> str:
  33. return _CI_CONFIGURATION_NAME
  34. def get(self, test_name: str) -> List[str]:
  35. test_names = []
  36. if self.__test_collections and test_name == _KEYWORD_ALL_TESTS:
  37. for collection_name in self.__test_collections.get('collection'):
  38. for name in self.__test_collections.get(collection_name):
  39. test_names.append(name)
  40. elif self.__test_collections and self.__test_collections.get(test_name):
  41. test_names = self.__test_collections.get(test_name)
  42. else:
  43. test_names.append(test_name)
  44. return self.__get_paths(test_names)
  45. def __get_collections(self, configuration_directory: str, configuration_name: str) -> List[str]:
  46. if os.path.isfile(configuration_name):
  47. configuration_filepath = configuration_name
  48. elif os.path.isfile(os.path.join(configuration_directory, configuration_name + _JSON_FILE_EXTENSION)):
  49. configuration_filepath = os.path.join(configuration_directory, configuration_name + _JSON_FILE_EXTENSION)
  50. else:
  51. configuration_filepath = None
  52. collections = None
  53. if configuration_filepath:
  54. with open(configuration_filepath) as file:
  55. data = json.load(file)
  56. if 'include' in data:
  57. include_filepath = os.path.join(os.path.dirname(configuration_filepath), data.get('include'))
  58. with open(include_filepath) as included_file:
  59. collections = json.load(included_file)
  60. else:
  61. collections = data
  62. if collections and 'disable' in data:
  63. disabled_tests = data.get('disable')
  64. for disabled_test in disabled_tests:
  65. for collection in collections:
  66. if disabled_test in collections.get(collection):
  67. collections.get(collection).remove(disabled_test)
  68. return collections
  69. def __get_paths(self, test_names: List[str]) -> List[str]:
  70. paths = []
  71. for name in test_names:
  72. for root, dir, files in os.walk(self.__test_directory):
  73. if name in files:
  74. paths.append(os.path.join(root, name))
  75. elif (name + _YAML_FILE_EXTENSION) in files:
  76. paths.append(os.path.join(root, name + _YAML_FILE_EXTENSION))
  77. elif (_KNOWN_PREFIX + name + _YAML_FILE_EXTENSION) in files:
  78. paths.append(os.path.join(root, _KNOWN_PREFIX + name + _YAML_FILE_EXTENSION))
  79. return paths
  80. def test_finder_options(f):
  81. f = click.option("--configuration_directory", type=click.Path(exists=True), required=True, show_default=True,
  82. default=_DEFAULT_DIRECTORY, help='Path to the directory containing the tests configuration.')(f)
  83. f = click.option("--configuration_name", type=str, required=True, show_default=True,
  84. default=_CI_CONFIGURATION_NAME, help='Name of the collection configuration json file to use.')(f)
  85. return f
  86. @click.command()
  87. @click.argument('test_name')
  88. @test_finder_options
  89. def run(test_name: str, configuration_directory: str, configuration_name: str):
  90. """ Find a test or a set of tests."""
  91. tests_finder = TestsFinder(configuration_directory, configuration_name)
  92. tests = tests_finder.get(test_name)
  93. for test in tests:
  94. print(test)
  95. print(f'{len(tests)} tests found.')
  96. if __name__ == '__main__':
  97. run()