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