ap_idle_fixture.py 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. """
  2. Copyright (c) Contributors to the Open 3D Engine Project.
  3. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. SPDX-License-Identifier: Apache-2.0 OR MIT
  5. Fixture that allows Idle check of the AP GUI
  6. """
  7. # Import builtin libraries
  8. import pytest
  9. import os
  10. import time
  11. # Import fixtures
  12. from . import ap_setup_fixture
  13. # Import LyTestTools
  14. import ly_test_tools.environment.waiter as waiter
  15. from ly_test_tools.o3de.ap_log_parser import APLogParser
  16. @pytest.mark.usefixtures("test_assets")
  17. class TimestampChecker(object):
  18. def __init__(self, file_path, timeout) -> None:
  19. self.file = file_path
  20. self.timeout = timeout
  21. self.original_mod_time = int(round(time.time() * 1000))
  22. self.start_time = time.time()
  23. self.log = None
  24. def set_file_path(self, file_path):
  25. self.file = file_path
  26. def grab_current_timestamp(self) -> None:
  27. self.original_mod_time = int(round(time.time() * 1000))
  28. def check_if_idle(self, timeout=None, starttime=None, updatetime_max=30) -> None:
  29. if timeout is None:
  30. timeout = self.timeout
  31. if starttime:
  32. time.sleep(starttime)
  33. def log_reports_idle() -> bool:
  34. """
  35. Grabs the current log run and reads it line by line from the bottom up
  36. Returns whether the idle message appears later in the log than the latest "Processing [...]" message
  37. """
  38. if updatetime_max and os.path.exists(self.file):
  39. last_file_update = os.path.getmtime(self.file)
  40. timedelta = time.time() - last_file_update
  41. if timedelta > updatetime_max: # Has the file exceeded the limit
  42. # Additionally we want to make sure the test has exceeded the limit so we don't catch
  43. # a log from a previous run where our current test hasn't engaged any action from AP
  44. if time.time() - self.start_time > updatetime_max:
  45. return True
  46. self.log = APLogParser(self.file)
  47. line_index = len(self.log.runs[-1]["Lines"]) - 1
  48. while line_index > 0:
  49. line = self.log.runs[-1]["Lines"][line_index]
  50. timestamp = self.log.runs[-1]["Timestamps"][line_index]
  51. if self.log.get_line_type(line) == "AssetProcessor":
  52. message = self.log.remove_line_type(line)
  53. if timestamp <= self.original_mod_time:
  54. return False
  55. elif message.startswith("Processing"):
  56. return False
  57. elif "Job processing completed. Asset Processor is currently idle." in message:
  58. self.original_mod_time = timestamp
  59. return True
  60. line_index -= 1
  61. waiter.wait_for(lambda: (log_reports_idle()), timeout=timeout or self.timeout)
  62. @pytest.fixture
  63. def ap_idle_fixture(request, workspace, timeout: int) -> TimestampChecker:
  64. """
  65. Allows checking the GUI for idle by grabbing the initial modified time of the log file
  66. and looking for new "idle" messages later
  67. """
  68. return TimestampChecker(workspace.paths.ap_gui_log(), timeout, workspace)