hydra_test_utils.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. """
  2. All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
  3. its licensors.
  4. For complete copyright and license terms please see the LICENSE at the root of this
  5. distribution (the "License"). All use of this software is governed by the License,
  6. or, if provided, by the license below or the license accompanying this file. Do not
  7. remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. """
  10. import logging
  11. import os
  12. import tempfile
  13. import ly_test_tools.log.log_monitor
  14. import ly_test_tools.environment.process_utils as process_utils
  15. import ly_test_tools.environment.waiter as waiter
  16. from automatedtesting_shared.network_utils import check_for_listening_port
  17. from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole
  18. from ly_remote_console.remote_console_commands import send_command_and_expect_response as send_command_and_expect_response
  19. logger = logging.getLogger(__name__)
  20. def teardown_editor(editor):
  21. """
  22. :param editor: Configured editor object
  23. :return:
  24. """
  25. process_utils.kill_processes_named('AssetProcessor.exe')
  26. logger.debug('Ensuring Editor is stopped')
  27. editor.ensure_stopped()
  28. def launch_and_validate_results(request, test_directory, editor, editor_script, expected_lines, unexpected_lines=[],
  29. halt_on_unexpected=False, run_python="--runpythontest", auto_test_mode=True, null_renderer=False, cfg_args=[],
  30. timeout=300):
  31. """
  32. Runs the Editor with the specified script, and monitors for expected log lines.
  33. :param request: Special fixture providing information of the requesting test function.
  34. :param test_directory: Path to test directory that editor_script lives in.
  35. :param editor: Configured editor object to run test against.
  36. :param editor_script: Name of script that will execute in the Editor.
  37. :param expected_lines: Expected lines to search log for.
  38. :param unexpected_lines: Unexpected lines to search log for. Defaults to none.
  39. :param halt_on_unexpected: Halts test if unexpected lines are found. Defaults to False.
  40. :param run_python: Defaults to "--runpythontest", other option is "--runpython".
  41. :param auto_test_mode: Determines if Editor will launch in autotest_mode, suppressing modal dialogs. Defaults to True.
  42. :param null_renderer: Specifies the test does not require the renderer. Defaults to True.
  43. :param cfg_args: Additional arguments for CFG, such as LevelName.
  44. :param timeout: Length of time for test to run. Default is 60.
  45. """
  46. test_case = os.path.join(test_directory, editor_script)
  47. request.addfinalizer(lambda: teardown_editor(editor))
  48. logger.debug("Running automated test: {}".format(editor_script))
  49. editor.args.extend(["--skipWelcomeScreenDialog", "--regset=/Amazon/Settings/EnableSourceControl=false",
  50. "--regset=/Amazon/Preferences/EnablePrefabSystem=false", run_python, test_case,
  51. "--runpythonargs", " ".join(cfg_args)])
  52. if auto_test_mode:
  53. editor.args.extend(["--autotest_mode"])
  54. if null_renderer:
  55. editor.args.extend(["-NullRenderer"])
  56. with editor.start():
  57. editorlog_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log')
  58. # Initialize the log monitor and set time to wait for log creation
  59. log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=editor, log_file_path=editorlog_file)
  60. log_monitor.log_creation_max_wait_time = timeout
  61. # Check for expected/unexpected lines
  62. log_monitor.monitor_log_for_lines(expected_lines=expected_lines, unexpected_lines=unexpected_lines,
  63. halt_on_unexpected=halt_on_unexpected, timeout=timeout)
  64. def launch_and_validate_results_launcher(launcher, level, remote_console_instance, expected_lines, null_renderer=True,
  65. port_listener_timeout=120, log_monitor_timeout=300, remote_console_port=4600):
  66. """
  67. Runs the launcher with the specified level, and monitors Game.log for expected lines.
  68. :param launcher: Configured launcher object to run test against.
  69. :param level: The level to load in the launcher.
  70. :param remote_console_instance: Configured Remote Console object.
  71. :param expected_lines: Expected lines to search log for.
  72. :oaram null_renderer: Specifies the test does not require the renderer. Defaults to True.
  73. :param port_listener_timeout: Timeout for verifying successful connection to Remote Console.
  74. :param log_monitor_timeout: Timeout for monitoring for lines in Game.log
  75. :param remote_console_port: The port used to communicate with the Remote Console.
  76. """
  77. if null_renderer:
  78. launcher.args.extend(["-NullRenderer"])
  79. # Start the Launcher
  80. with launcher.start():
  81. # Ensure Remote Console can be reached
  82. waiter.wait_for(
  83. lambda: check_for_listening_port(remote_console_port),
  84. port_listener_timeout,
  85. exc=AssertionError("Port {} not listening.".format(remote_console_port)),
  86. )
  87. remote_console_instance.start(timeout=30)
  88. # Load the specified level in the launcher
  89. send_command_and_expect_response(remote_console_instance,
  90. f"map {level}",
  91. "LEVEL_LOAD_COMPLETE", timeout=30)
  92. # Monitor the console for expected lines
  93. for line in expected_lines:
  94. assert remote_console_instance.expect_log_line(line, log_monitor_timeout), f"Expected line not found: {line}"
  95. def remove_files(artifact_path, suffix):
  96. """
  97. Removes files with the specified suffix from the specified path
  98. :param artifact_path: Path to search for files
  99. :param suffix: File extension to remove
  100. """
  101. if not os.path.isdir(artifact_path):
  102. return
  103. for file_name in os.listdir(artifact_path):
  104. if file_name.endswith(suffix):
  105. os.remove(os.path.join(artifact_path, file_name))