test_case.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. """Library for generating Mbed TLS test data.
  2. """
  3. # Copyright The Mbed TLS Contributors
  4. # SPDX-License-Identifier: Apache-2.0
  5. #
  6. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  7. # not use this file except in compliance with the License.
  8. # You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  14. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. import binascii
  18. import os
  19. import sys
  20. from typing import Iterable, List, Optional
  21. from mbedtls_dev import typing_util
  22. def hex_string(data: bytes) -> str:
  23. return '"' + binascii.hexlify(data).decode('ascii') + '"'
  24. class MissingDescription(Exception):
  25. pass
  26. class MissingFunction(Exception):
  27. pass
  28. class TestCase:
  29. """An Mbed TLS test case."""
  30. def __init__(self, description: Optional[str] = None):
  31. self.comments = [] #type: List[str]
  32. self.description = description #type: Optional[str]
  33. self.dependencies = [] #type: List[str]
  34. self.function = None #type: Optional[str]
  35. self.arguments = [] #type: List[str]
  36. def add_comment(self, *lines: str) -> None:
  37. self.comments += lines
  38. def set_description(self, description: str) -> None:
  39. self.description = description
  40. def set_dependencies(self, dependencies: List[str]) -> None:
  41. self.dependencies = dependencies
  42. def set_function(self, function: str) -> None:
  43. self.function = function
  44. def set_arguments(self, arguments: List[str]) -> None:
  45. self.arguments = arguments
  46. def check_completeness(self) -> None:
  47. if self.description is None:
  48. raise MissingDescription
  49. if self.function is None:
  50. raise MissingFunction
  51. def write(self, out: typing_util.Writable) -> None:
  52. """Write the .data file paragraph for this test case.
  53. The output starts and ends with a single newline character. If the
  54. surrounding code writes lines (consisting of non-newline characters
  55. and a final newline), you will end up with a blank line before, but
  56. not after the test case.
  57. """
  58. self.check_completeness()
  59. assert self.description is not None # guide mypy
  60. assert self.function is not None # guide mypy
  61. out.write('\n')
  62. for line in self.comments:
  63. out.write('# ' + line + '\n')
  64. out.write(self.description + '\n')
  65. if self.dependencies:
  66. out.write('depends_on:' + ':'.join(self.dependencies) + '\n')
  67. out.write(self.function + ':' + ':'.join(self.arguments) + '\n')
  68. def write_data_file(filename: str,
  69. test_cases: Iterable[TestCase],
  70. caller: Optional[str] = None) -> None:
  71. """Write the test cases to the specified file.
  72. If the file already exists, it is overwritten.
  73. """
  74. if caller is None:
  75. caller = os.path.basename(sys.argv[0])
  76. with open(filename, 'w') as out:
  77. out.write('# Automatically generated by {}. Do not edit!\n'
  78. .format(caller))
  79. for tc in test_cases:
  80. tc.write(out)
  81. out.write('\n# End of automatically generated file.\n')