xref: /aosp_15_r20/tools/asuite/atest/banner.py (revision c2e18aaa1096c836b086f94603d04f4eb9cf37f5)
1*c2e18aaaSAndroid Build Coastguard Worker# Copyright 2024, The Android Open Source Project
2*c2e18aaaSAndroid Build Coastguard Worker#
3*c2e18aaaSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*c2e18aaaSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*c2e18aaaSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*c2e18aaaSAndroid Build Coastguard Worker#
7*c2e18aaaSAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
8*c2e18aaaSAndroid Build Coastguard Worker#
9*c2e18aaaSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*c2e18aaaSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*c2e18aaaSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*c2e18aaaSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*c2e18aaaSAndroid Build Coastguard Worker# limitations under the License.
14*c2e18aaaSAndroid Build Coastguard Worker
15*c2e18aaaSAndroid Build Coastguard Worker"""Classes used to handle banners."""
16*c2e18aaaSAndroid Build Coastguard Worker
17*c2e18aaaSAndroid Build Coastguard Workerfrom __future__ import annotations
18*c2e18aaaSAndroid Build Coastguard Worker
19*c2e18aaaSAndroid Build Coastguard Workerfrom datetime import date
20*c2e18aaaSAndroid Build Coastguard Workerimport json
21*c2e18aaaSAndroid Build Coastguard Workerimport logging
22*c2e18aaaSAndroid Build Coastguard Workerfrom pathlib import Path
23*c2e18aaaSAndroid Build Coastguard Workerfrom typing import Any, Callable
24*c2e18aaaSAndroid Build Coastguard Worker
25*c2e18aaaSAndroid Build Coastguard Workerfrom atest import atest_utils
26*c2e18aaaSAndroid Build Coastguard Workerfrom atest import constants
27*c2e18aaaSAndroid Build Coastguard Worker
28*c2e18aaaSAndroid Build Coastguard Worker
29*c2e18aaaSAndroid Build Coastguard Workerclass BannerHistory:
30*c2e18aaaSAndroid Build Coastguard Worker  """A history for banner handling."""
31*c2e18aaaSAndroid Build Coastguard Worker
32*c2e18aaaSAndroid Build Coastguard Worker  _LAST_BANNER_PROMPT_DATE = 'last_banner_prompt_date'
33*c2e18aaaSAndroid Build Coastguard Worker
34*c2e18aaaSAndroid Build Coastguard Worker  @staticmethod
35*c2e18aaaSAndroid Build Coastguard Worker  def create(config_dir: Path) -> BannerHistory:
36*c2e18aaaSAndroid Build Coastguard Worker    config_dir.mkdir(parents=True, exist_ok=True)
37*c2e18aaaSAndroid Build Coastguard Worker    history_file = config_dir.joinpath('banner.json')
38*c2e18aaaSAndroid Build Coastguard Worker
39*c2e18aaaSAndroid Build Coastguard Worker    if not history_file.exists():
40*c2e18aaaSAndroid Build Coastguard Worker      history_file.touch()
41*c2e18aaaSAndroid Build Coastguard Worker      history = {}
42*c2e18aaaSAndroid Build Coastguard Worker    else:
43*c2e18aaaSAndroid Build Coastguard Worker      try:
44*c2e18aaaSAndroid Build Coastguard Worker        history = json.loads(history_file.read_text())
45*c2e18aaaSAndroid Build Coastguard Worker      except json.JSONDecodeError as e:
46*c2e18aaaSAndroid Build Coastguard Worker        atest_utils.print_and_log_error(
47*c2e18aaaSAndroid Build Coastguard Worker            'Banner history json file is in a bad format: %s', e
48*c2e18aaaSAndroid Build Coastguard Worker        )
49*c2e18aaaSAndroid Build Coastguard Worker        history = {}
50*c2e18aaaSAndroid Build Coastguard Worker
51*c2e18aaaSAndroid Build Coastguard Worker    return BannerHistory(history_file, history)
52*c2e18aaaSAndroid Build Coastguard Worker
53*c2e18aaaSAndroid Build Coastguard Worker  def __init__(self, history_file: Path, history: dict):
54*c2e18aaaSAndroid Build Coastguard Worker    self._history_file = history_file
55*c2e18aaaSAndroid Build Coastguard Worker    self._history = history
56*c2e18aaaSAndroid Build Coastguard Worker
57*c2e18aaaSAndroid Build Coastguard Worker  def get_last_banner_prompt_date(self) -> str:
58*c2e18aaaSAndroid Build Coastguard Worker    """Get the last date when banner was prompt."""
59*c2e18aaaSAndroid Build Coastguard Worker    return self._history.get(BannerHistory._LAST_BANNER_PROMPT_DATE, '')
60*c2e18aaaSAndroid Build Coastguard Worker
61*c2e18aaaSAndroid Build Coastguard Worker  def set_last_banner_prompt_date(self, date: str):
62*c2e18aaaSAndroid Build Coastguard Worker    """Set the last date when banner was prompt."""
63*c2e18aaaSAndroid Build Coastguard Worker    self._history[BannerHistory._LAST_BANNER_PROMPT_DATE] = date
64*c2e18aaaSAndroid Build Coastguard Worker    self._history_file.write_text(json.dumps(self._history))
65*c2e18aaaSAndroid Build Coastguard Worker
66*c2e18aaaSAndroid Build Coastguard Worker
67*c2e18aaaSAndroid Build Coastguard Workerclass BannerPrinter:
68*c2e18aaaSAndroid Build Coastguard Worker  """A printer used to collect and print banners."""
69*c2e18aaaSAndroid Build Coastguard Worker
70*c2e18aaaSAndroid Build Coastguard Worker  @staticmethod
71*c2e18aaaSAndroid Build Coastguard Worker  def create() -> BannerPrinter:
72*c2e18aaaSAndroid Build Coastguard Worker    return BannerPrinter(atest_utils.get_config_folder())
73*c2e18aaaSAndroid Build Coastguard Worker
74*c2e18aaaSAndroid Build Coastguard Worker  def __init__(self, config_dir: Path):
75*c2e18aaaSAndroid Build Coastguard Worker    self._messages = []
76*c2e18aaaSAndroid Build Coastguard Worker    self._config_dir = config_dir
77*c2e18aaaSAndroid Build Coastguard Worker
78*c2e18aaaSAndroid Build Coastguard Worker  def register(self, message: str):
79*c2e18aaaSAndroid Build Coastguard Worker    """Register a banner message."""
80*c2e18aaaSAndroid Build Coastguard Worker    self._messages.append(message)
81*c2e18aaaSAndroid Build Coastguard Worker
82*c2e18aaaSAndroid Build Coastguard Worker  def print(self, print_func: Callable = None, date_supplier: Callable = None):
83*c2e18aaaSAndroid Build Coastguard Worker    """Print the banners."""
84*c2e18aaaSAndroid Build Coastguard Worker
85*c2e18aaaSAndroid Build Coastguard Worker    if not self._messages:
86*c2e18aaaSAndroid Build Coastguard Worker      return
87*c2e18aaaSAndroid Build Coastguard Worker
88*c2e18aaaSAndroid Build Coastguard Worker    if not print_func:
89*c2e18aaaSAndroid Build Coastguard Worker      print_func = lambda m: atest_utils.colorful_print(m, constants.MAGENTA)
90*c2e18aaaSAndroid Build Coastguard Worker
91*c2e18aaaSAndroid Build Coastguard Worker    if not date_supplier:
92*c2e18aaaSAndroid Build Coastguard Worker      date_supplier = lambda: str(date.today())
93*c2e18aaaSAndroid Build Coastguard Worker
94*c2e18aaaSAndroid Build Coastguard Worker    today = date_supplier()
95*c2e18aaaSAndroid Build Coastguard Worker    history = BannerHistory.create(self._config_dir)
96*c2e18aaaSAndroid Build Coastguard Worker    if history.get_last_banner_prompt_date() != today:
97*c2e18aaaSAndroid Build Coastguard Worker      for message in self._messages:
98*c2e18aaaSAndroid Build Coastguard Worker        print_func(message)
99*c2e18aaaSAndroid Build Coastguard Worker
100*c2e18aaaSAndroid Build Coastguard Worker      history.set_last_banner_prompt_date(today)
101