""" All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or its licensors. For complete copyright and license terms please see the LICENSE at the root of this distribution (the "License"). All use of this software is governed by the License, or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Fixture that allows Idle check of the AP GUI """ # Import builtin libraries import pytest import os import time # Import fixtures from . import ap_setup_fixture # Import LyTestTools import ly_test_tools.environment.waiter as waiter from ly_test_tools.lumberyard.ap_log_parser import APLogParser @pytest.mark.usefixtures("test_assets") class TimestampChecker(object): def __init__(self, file_path, timeout) -> None: self.file = file_path self.timeout = timeout self.original_mod_time = int(round(time.time() * 1000)) self.start_time = time.time() self.log = None def set_file_path(self, file_path): self.file = file_path def grab_current_timestamp(self) -> None: self.original_mod_time = int(round(time.time() * 1000)) def check_if_idle(self, timeout=None, starttime=None, updatetime_max=30) -> None: if timeout is None: timeout = self.timeout if starttime: time.sleep(starttime) def log_reports_idle() -> bool: """ Grabs the current log run and reads it line by line from the bottom up Returns whether the idle message appears later in the log than the latest "Processing [...]" message """ if updatetime_max and os.path.exists(self.file): last_file_update = os.path.getmtime(self.file) timedelta = time.time() - last_file_update if timedelta > updatetime_max: # Has the file exceeded the limit # Additionally we want to make sure the test has exceeded the limit so we don't catch # a log from a previous run where our current test hasn't engaged any action from AP if time.time() - self.start_time > updatetime_max: return True self.log = APLogParser(self.file) line_index = len(self.log.runs[-1]["Lines"]) - 1 while line_index > 0: line = self.log.runs[-1]["Lines"][line_index] timestamp = self.log.runs[-1]["Timestamps"][line_index] if self.log.get_line_type(line) == "AssetProcessor": message = self.log.remove_line_type(line) if timestamp <= self.original_mod_time: return False elif message.startswith("Processing"): return False elif "Job processing completed. Asset Processor is currently idle." in message: self.original_mod_time = timestamp return True line_index -= 1 waiter.wait_for(lambda: (log_reports_idle()), timeout=timeout or self.timeout) @pytest.fixture def ap_idle_fixture(request, workspace, timeout: int) -> TimestampChecker: """ Allows checking the GUI for idle by grabbing the initial modified time of the log file and looking for new "idle" messages later """ return TimestampChecker(workspace.paths.ap_gui_log(), timeout, workspace)