xref: /aosp_15_r20/art/tools/checker/common/logger.py (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker# Copyright (C) 2014 The Android Open Source Project
2*795d594fSAndroid Build Coastguard Worker#
3*795d594fSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*795d594fSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*795d594fSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*795d594fSAndroid Build Coastguard Worker#
7*795d594fSAndroid Build Coastguard Worker#   http://www.apache.org/licenses/LICENSE-2.0
8*795d594fSAndroid Build Coastguard Worker#
9*795d594fSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*795d594fSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*795d594fSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*795d594fSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*795d594fSAndroid Build Coastguard Worker# limitations under the License.
14*795d594fSAndroid Build Coastguard Worker
15*795d594fSAndroid Build Coastguard Workerimport collections
16*795d594fSAndroid Build Coastguard Workerimport enum
17*795d594fSAndroid Build Coastguard Workerimport sys
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Workerclass Logger:
21*795d594fSAndroid Build Coastguard Worker  class Level(enum.IntEnum):
22*795d594fSAndroid Build Coastguard Worker    NO_OUTPUT, ERROR, INFO = range(3)
23*795d594fSAndroid Build Coastguard Worker
24*795d594fSAndroid Build Coastguard Worker  class Color(enum.Enum):
25*795d594fSAndroid Build Coastguard Worker    DEFAULT, BLUE, GRAY, PURPLE, RED, GREEN = range(6)
26*795d594fSAndroid Build Coastguard Worker
27*795d594fSAndroid Build Coastguard Worker    @staticmethod
28*795d594fSAndroid Build Coastguard Worker    def terminal_code(color, out=sys.stdout):
29*795d594fSAndroid Build Coastguard Worker      if not out.isatty():
30*795d594fSAndroid Build Coastguard Worker        return ""
31*795d594fSAndroid Build Coastguard Worker      elif color == Logger.Color.BLUE:
32*795d594fSAndroid Build Coastguard Worker        return "\033[94m"
33*795d594fSAndroid Build Coastguard Worker      elif color == Logger.Color.GRAY:
34*795d594fSAndroid Build Coastguard Worker        return "\033[37m"
35*795d594fSAndroid Build Coastguard Worker      elif color == Logger.Color.PURPLE:
36*795d594fSAndroid Build Coastguard Worker        return "\033[95m"
37*795d594fSAndroid Build Coastguard Worker      elif color == Logger.Color.RED:
38*795d594fSAndroid Build Coastguard Worker        return "\033[91m"
39*795d594fSAndroid Build Coastguard Worker      elif color == Logger.Color.GREEN:
40*795d594fSAndroid Build Coastguard Worker        return "\033[32m"
41*795d594fSAndroid Build Coastguard Worker      else:
42*795d594fSAndroid Build Coastguard Worker        return "\033[0m"
43*795d594fSAndroid Build Coastguard Worker
44*795d594fSAndroid Build Coastguard Worker  Verbosity = Level.INFO
45*795d594fSAndroid Build Coastguard Worker
46*795d594fSAndroid Build Coastguard Worker  @staticmethod
47*795d594fSAndroid Build Coastguard Worker  def log(content, level=Level.INFO, color=Color.DEFAULT, new_line=True, out=sys.stdout):
48*795d594fSAndroid Build Coastguard Worker    if level <= Logger.Verbosity:
49*795d594fSAndroid Build Coastguard Worker      content = "{}{}{}".format(Logger.Color.terminal_code(color, out), content,
50*795d594fSAndroid Build Coastguard Worker                                Logger.Color.terminal_code(Logger.Color.DEFAULT, out))
51*795d594fSAndroid Build Coastguard Worker      if new_line:
52*795d594fSAndroid Build Coastguard Worker        print(content, file=out)
53*795d594fSAndroid Build Coastguard Worker      else:
54*795d594fSAndroid Build Coastguard Worker        print(content, end="", file=out)
55*795d594fSAndroid Build Coastguard Worker      out.flush()
56*795d594fSAndroid Build Coastguard Worker
57*795d594fSAndroid Build Coastguard Worker  @staticmethod
58*795d594fSAndroid Build Coastguard Worker  def fail(msg, file=None, line=-1, line_text=None, variables=None):
59*795d594fSAndroid Build Coastguard Worker    Logger.log("error: ", Logger.Level.ERROR, color=Logger.Color.RED, new_line=False,
60*795d594fSAndroid Build Coastguard Worker               out=sys.stderr)
61*795d594fSAndroid Build Coastguard Worker    Logger.log(msg, Logger.Level.ERROR, out=sys.stderr)
62*795d594fSAndroid Build Coastguard Worker
63*795d594fSAndroid Build Coastguard Worker    if line_text:
64*795d594fSAndroid Build Coastguard Worker      loc = ""
65*795d594fSAndroid Build Coastguard Worker      if file:
66*795d594fSAndroid Build Coastguard Worker        loc += file + ":"
67*795d594fSAndroid Build Coastguard Worker      if line > 0:
68*795d594fSAndroid Build Coastguard Worker        loc += str(line) + ":"
69*795d594fSAndroid Build Coastguard Worker      if loc:
70*795d594fSAndroid Build Coastguard Worker        loc += " "
71*795d594fSAndroid Build Coastguard Worker      Logger.log(loc, Logger.Level.ERROR, color=Logger.Color.GRAY, new_line=False,
72*795d594fSAndroid Build Coastguard Worker                 out=sys.stderr)
73*795d594fSAndroid Build Coastguard Worker      Logger.log(line_text, Logger.Level.ERROR, out=sys.stderr)
74*795d594fSAndroid Build Coastguard Worker
75*795d594fSAndroid Build Coastguard Worker    if variables:
76*795d594fSAndroid Build Coastguard Worker      longest_name = max(len(var) for var in variables)
77*795d594fSAndroid Build Coastguard Worker
78*795d594fSAndroid Build Coastguard Worker      for var in collections.OrderedDict(sorted(variables.items())):
79*795d594fSAndroid Build Coastguard Worker        padding = " " * (longest_name - len(var))
80*795d594fSAndroid Build Coastguard Worker        Logger.log(var, Logger.Level.ERROR, color=Logger.Color.GREEN, new_line=False,
81*795d594fSAndroid Build Coastguard Worker                   out=sys.stderr)
82*795d594fSAndroid Build Coastguard Worker        Logger.log(padding, Logger.Level.ERROR, new_line=False, out=sys.stderr)
83*795d594fSAndroid Build Coastguard Worker        Logger.log(" = ", Logger.Level.ERROR, new_line=False, out=sys.stderr)
84*795d594fSAndroid Build Coastguard Worker        Logger.log(variables[var], Logger.Level.ERROR, out=sys.stderr)
85*795d594fSAndroid Build Coastguard Worker
86*795d594fSAndroid Build Coastguard Worker    sys.exit(1)
87*795d594fSAndroid Build Coastguard Worker
88*795d594fSAndroid Build Coastguard Worker  @staticmethod
89*795d594fSAndroid Build Coastguard Worker  def start_test(name):
90*795d594fSAndroid Build Coastguard Worker    Logger.log("TEST ", color=Logger.Color.PURPLE, new_line=False)
91*795d594fSAndroid Build Coastguard Worker    Logger.log(name + "... ", new_line=False)
92*795d594fSAndroid Build Coastguard Worker
93*795d594fSAndroid Build Coastguard Worker  @staticmethod
94*795d594fSAndroid Build Coastguard Worker  def test_passed():
95*795d594fSAndroid Build Coastguard Worker    Logger.log("PASS", color=Logger.Color.BLUE)
96*795d594fSAndroid Build Coastguard Worker
97*795d594fSAndroid Build Coastguard Worker  @staticmethod
98*795d594fSAndroid Build Coastguard Worker  def test_failed(msg, statement, variables):
99*795d594fSAndroid Build Coastguard Worker    Logger.log("FAIL", color=Logger.Color.RED)
100*795d594fSAndroid Build Coastguard Worker    Logger.fail(msg, statement.filename, statement.line_no, statement.original_text, variables)
101