upload
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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

test_webapi.py 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. """
  2. mbed SDK
  3. Copyright (c) 2011-2014 ARM Limited
  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. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. Author: Przemyslaw Wirkus <[email protected]>
  14. """
  15. import sys
  16. import json
  17. import optparse
  18. from flask import Flask
  19. from os.path import join, abspath, dirname
  20. # Be sure that the tools directory is in the search path
  21. ROOT = abspath(join(dirname(__file__), ".."))
  22. sys.path.insert(0, ROOT)
  23. # Imports related to mbed build api
  24. from workspace_tools.utils import construct_enum
  25. from workspace_tools.build_api import mcu_toolchain_matrix
  26. # Imports from TEST API
  27. from test_api import SingleTestRunner
  28. from test_api import SingleTestExecutor
  29. from test_api import get_json_data_from_file
  30. from test_api import print_muts_configuration_from_json
  31. from test_api import print_test_configuration_from_json
  32. from test_api import get_avail_tests_summary_table
  33. from test_api import get_default_test_options_parser
  34. class SingleTestRunnerWebService(SingleTestRunner):
  35. def __init__(self):
  36. super(SingleTestRunnerWebService, self).__init__()
  37. # With this lock we should control access to certain resources inside this class
  38. self.resource_lock = thread.allocate_lock()
  39. self.RestRequest = construct_enum(REST_MUTS='muts',
  40. REST_TEST_SPEC='test_spec',
  41. REST_TEST_RESULTS='test_results')
  42. def get_rest_result_template(self, result, command, success_code):
  43. """ Returns common part of every web service request
  44. """
  45. result = {"result" : result,
  46. "command" : command,
  47. "success_code": success_code} # 0 - OK, >0 - Error number
  48. return result
  49. # REST API handlers for Flask framework
  50. def rest_api_status(self):
  51. """ Returns current test execution status. E.g. running / finished etc.
  52. """
  53. with self.resource_lock:
  54. pass
  55. def rest_api_config(self):
  56. """ Returns configuration passed to SingleTest executor
  57. """
  58. with self.resource_lock:
  59. pass
  60. def rest_api_log(self):
  61. """ Returns current test log """
  62. with self.resource_lock:
  63. pass
  64. def rest_api_request_handler(self, request_type):
  65. """ Returns various data structures. Both static and mutable during test
  66. """
  67. result = {}
  68. success_code = 0
  69. with self.resource_lock:
  70. if request_type == self.RestRequest.REST_MUTS:
  71. result = self.muts # Returns MUTs
  72. elif request_type == self.RestRequest.REST_TEST_SPEC:
  73. result = self.test_spec # Returns Test Specification
  74. elif request_type == self.RestRequest.REST_TEST_RESULTS:
  75. pass # Returns test results
  76. else:
  77. success_code = -1
  78. return json.dumps(self.get_rest_result_template(result, 'request/' + request_type, success_code), indent=4)
  79. def singletest_in_webservice_mode():
  80. # TODO Implement this web service functionality
  81. pass
  82. def get_default_test_webservice_options_parser():
  83. """ Get test script web service options used by CLI, webservices etc.
  84. """
  85. parser = get_default_test_options_parser()
  86. # Things related to web services offered by test suite scripts
  87. parser.add_option('', '--rest-api',
  88. dest='rest_api_enabled',
  89. default=False,
  90. action="store_true",
  91. help='Enables REST API.')
  92. parser.add_option('', '--rest-api-port',
  93. dest='rest_api_port_no',
  94. help='Sets port for REST API interface')
  95. return parser
  96. '''
  97. if __name__ == '__main__':
  98. # Command line options
  99. parser = get_default_test_options_parser()
  100. parser.description = """This script allows you to run mbed defined test cases for particular MCU(s) and corresponding toolchain(s)."""
  101. parser.epilog = """Example: singletest.py -i test_spec.json -M muts_all.json"""
  102. (opts, args) = parser.parse_args()
  103. # Print summary / information about automation test status
  104. if opts.test_automation_report:
  105. print get_avail_tests_summary_table()
  106. exit(0)
  107. # Print summary / information about automation test status
  108. if opts.test_case_report:
  109. test_case_report_cols = ['id', 'automated', 'description', 'peripherals', 'host_test', 'duration', 'source_dir']
  110. print get_avail_tests_summary_table(cols=test_case_report_cols, result_summary=False, join_delim='\n')
  111. exit(0)
  112. # Only prints matrix of supported toolchains
  113. if opts.supported_toolchains:
  114. print mcu_toolchain_matrix(platform_filter=opts.general_filter_regex)
  115. exit(0)
  116. # Open file with test specification
  117. # test_spec_filename tells script which targets and their toolchain(s)
  118. # should be covered by the test scenario
  119. test_spec = get_json_data_from_file(opts.test_spec_filename) if opts.test_spec_filename else None
  120. if test_spec is None:
  121. if not opts.test_spec_filename:
  122. parser.print_help()
  123. exit(-1)
  124. # Get extra MUTs if applicable
  125. MUTs = get_json_data_from_file(opts.muts_spec_filename) if opts.muts_spec_filename else None
  126. if MUTs is None:
  127. if not opts.muts_spec_filename:
  128. parser.print_help()
  129. exit(-1)
  130. # Only prints read MUTs configuration
  131. if MUTs and opts.verbose_test_configuration_only:
  132. print "MUTs configuration in %s:"% opts.muts_spec_filename
  133. print print_muts_configuration_from_json(MUTs)
  134. print
  135. print "Test specification in %s:"% opts.test_spec_filename
  136. print print_test_configuration_from_json(test_spec)
  137. exit(0)
  138. # Verbose test specification and MUTs configuration
  139. if MUTs and opts.verbose:
  140. print print_muts_configuration_from_json(MUTs)
  141. if test_spec and opts.verbose:
  142. print print_test_configuration_from_json(test_spec)
  143. if opts.only_build_tests:
  144. # We are skipping testing phase, and suppress summary
  145. opts.suppress_summary = True
  146. single_test = SingleTestRunner(_global_loops_count=opts.test_global_loops_value,
  147. _test_loops_list=opts.test_loops_list,
  148. _muts=MUTs,
  149. _test_spec=test_spec,
  150. _opts_goanna_for_mbed_sdk=opts.goanna_for_mbed_sdk,
  151. _opts_goanna_for_tests=opts.goanna_for_tests,
  152. _opts_shuffle_test_order=opts.shuffle_test_order,
  153. _opts_shuffle_test_seed=opts.shuffle_test_seed,
  154. _opts_test_by_names=opts.test_by_names,
  155. _opts_test_only_peripheral=opts.test_only_peripheral,
  156. _opts_test_only_common=opts.test_only_common,
  157. _opts_verbose_skipped_tests=opts.verbose_skipped_tests,
  158. _opts_verbose_test_result_only=opts.verbose_test_result_only,
  159. _opts_verbose=opts.verbose,
  160. _opts_firmware_global_name=opts.firmware_global_name,
  161. _opts_only_build_tests=opts.only_build_tests,
  162. _opts_suppress_summary=opts.suppress_summary,
  163. _opts_test_x_toolchain_summary=opts.test_x_toolchain_summary,
  164. _opts_copy_method=opts.copy_method
  165. )
  166. try:
  167. st_exec_thread = SingleTestExecutor(single_test)
  168. except KeyboardInterrupt, e:
  169. print "\n[CTRL+c] exit"
  170. st_exec_thread.start()
  171. if opts.rest_api_enabled:
  172. # Enable REST API
  173. app = Flask(__name__)
  174. @app.route('/')
  175. def hello_world():
  176. return 'Hello World!'
  177. @app.route('/status')
  178. def rest_api_status():
  179. return single_test.rest_api_status() # TODO
  180. @app.route('/config')
  181. def rest_api_config():
  182. return single_test.rest_api_config() # TODO
  183. @app.route('/log')
  184. def rest_api_log():
  185. return single_test.rest_api_log() # TODO
  186. @app.route('/request/<request_type>') # 'muts', 'test_spec', 'test_results'
  187. def rest_api_request_handler(request_type):
  188. result = single_test.rest_api_request_handler(request_type) # TODO
  189. return result
  190. rest_api_port = int(opts.rest_api_port_no) if opts.rest_api_port_no else 5555
  191. app.debug = False
  192. app.run(port=rest_api_port) # Blocking Flask REST API web service
  193. else:
  194. st_exec_thread.join()
  195. '''