| # Copyright (C) 2014 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import collections |
| import enum |
| import sys |
| |
| |
| class Logger: |
| class Level(enum.IntEnum): |
| NO_OUTPUT, ERROR, INFO = range(3) |
| |
| class Color(enum.Enum): |
| DEFAULT, BLUE, GRAY, PURPLE, RED, GREEN = range(6) |
| |
| @staticmethod |
| def terminal_code(color, out=sys.stdout): |
| if not out.isatty(): |
| return "" |
| elif color == Logger.Color.BLUE: |
| return "\033[94m" |
| elif color == Logger.Color.GRAY: |
| return "\033[37m" |
| elif color == Logger.Color.PURPLE: |
| return "\033[95m" |
| elif color == Logger.Color.RED: |
| return "\033[91m" |
| elif color == Logger.Color.GREEN: |
| return "\033[32m" |
| else: |
| return "\033[0m" |
| |
| Verbosity = Level.INFO |
| |
| @staticmethod |
| def log(content, level=Level.INFO, color=Color.DEFAULT, new_line=True, out=sys.stdout): |
| if level <= Logger.Verbosity: |
| content = "{}{}{}".format(Logger.Color.terminal_code(color, out), content, |
| Logger.Color.terminal_code(Logger.Color.DEFAULT, out)) |
| if new_line: |
| print(content, file=out) |
| else: |
| print(content, end="", file=out) |
| out.flush() |
| |
| @staticmethod |
| def fail(msg, file=None, line=-1, line_text=None, variables=None): |
| Logger.log("error: ", Logger.Level.ERROR, color=Logger.Color.RED, new_line=False, |
| out=sys.stderr) |
| Logger.log(msg, Logger.Level.ERROR, out=sys.stderr) |
| |
| if line_text: |
| loc = "" |
| if file: |
| loc += file + ":" |
| if line > 0: |
| loc += str(line) + ":" |
| if loc: |
| loc += " " |
| Logger.log(loc, Logger.Level.ERROR, color=Logger.Color.GRAY, new_line=False, |
| out=sys.stderr) |
| Logger.log(line_text, Logger.Level.ERROR, out=sys.stderr) |
| |
| if variables: |
| longest_name = max(len(var) for var in variables) |
| |
| for var in collections.OrderedDict(sorted(variables.items())): |
| padding = " " * (longest_name - len(var)) |
| Logger.log(var, Logger.Level.ERROR, color=Logger.Color.GREEN, new_line=False, |
| out=sys.stderr) |
| Logger.log(padding, Logger.Level.ERROR, new_line=False, out=sys.stderr) |
| Logger.log(" = ", Logger.Level.ERROR, new_line=False, out=sys.stderr) |
| Logger.log(variables[var], Logger.Level.ERROR, out=sys.stderr) |
| |
| sys.exit(1) |
| |
| @staticmethod |
| def start_test(name): |
| Logger.log("TEST ", color=Logger.Color.PURPLE, new_line=False) |
| Logger.log(name + "... ", new_line=False) |
| |
| @staticmethod |
| def test_passed(): |
| Logger.log("PASS", color=Logger.Color.BLUE) |
| |
| @staticmethod |
| def test_failed(msg, statement, variables): |
| Logger.log("FAIL", color=Logger.Color.RED) |
| Logger.fail(msg, statement.filename, statement.line_no, statement.original_text, variables) |