github.com/phuslu/log@v1.0.100/console_test.go (about)

     1  package log
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"runtime"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  func TestIsTerminal(t *testing.T) {
    14  	file, _ := os.Open(os.DevNull)
    15  
    16  	if IsTerminal(file.Fd()) {
    17  		t.Errorf("test %s terminal mode failed", os.DevNull)
    18  	}
    19  
    20  	// The SIGSYS signal would be triggered for errors like "function not implemented".
    21  	// The process would crash for SIGSYS on some platforms (eg. Darwin), so we need to
    22  	// ignore the signal to make sure this test runs correctly on all platforms.
    23  	// signal.Ignore(syscall.SIGSYS)
    24  
    25  	// Mute "function not implemented" and "undefined: syscall.SIGSYS" for non linux_amd64 platforms
    26  	if !(runtime.GOOS == "linux" && runtime.GOARCH == "amd64") {
    27  		return
    28  	}
    29  
    30  	cases := []struct {
    31  		GOOS   string
    32  		GOARCH string
    33  	}{
    34  		{"plan9", "amd64"},
    35  		{"js", "wasm"},
    36  		{"nacl", "amd64"},
    37  		{"linux", "amd64"},
    38  		{"linux", "arm64"},
    39  		{"linux", "mips"},
    40  		{"linux", "mipsle"},
    41  		{"linux", "mips64"},
    42  		{"linux", "mips64le"},
    43  		{"linux", "ppc64"},
    44  		{"linux", "ppc64le"},
    45  		{"linux", "386"},
    46  		{"darwin", "amd64"},
    47  		{"darwin", "386"},
    48  		{"darwin", "arm64"},
    49  		{"windows", "amd64"},
    50  		{"windows", "386"},
    51  		{"windows", "arm64"},
    52  	}
    53  
    54  	for _, c := range cases {
    55  		t.Logf("isTerminal(%s, %s) return %+v", c.GOOS, c.GOARCH, isTerminal(file.Fd(), c.GOOS, c.GOARCH))
    56  	}
    57  
    58  }
    59  
    60  func TestConsoleWriter(t *testing.T) {
    61  	w := &ConsoleWriter{}
    62  
    63  	for _, level := range []string{"trace", "debug", "info", "warning", "error", "fatal", "panic", "hahaha"} {
    64  		_, err := wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"%s","caller":"test.go:42","error":"i am test error","foo":"bar","n":42,"message":"hello json console writer"}`+"\n", level)
    65  		if err != nil {
    66  			t.Errorf("test json console writer error: %+v", err)
    67  		}
    68  	}
    69  }
    70  
    71  func TestConsoleWriterColor(t *testing.T) {
    72  	w := &ConsoleWriter{
    73  		ColorOutput: true,
    74  	}
    75  
    76  	for _, level := range []string{"trace", "debug", "info", "warning", "error", "fatal", "panic", "hahaha"} {
    77  		_, err := wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"%s","caller":"pretty.go:42","error":"i am test error","foo":"bar","n":42,"message":"hello json console color writer"}`+"\n", level)
    78  		if err != nil {
    79  			t.Errorf("test json color console writer error: %+v", err)
    80  		}
    81  	}
    82  }
    83  
    84  func TestConsoleWriterNewline(t *testing.T) {
    85  	w := &ConsoleWriter{
    86  		ColorOutput: true,
    87  	}
    88  
    89  	_, err := wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"info","caller":"pretty.go:42","error":"i am test error","foo":"bar","n":42,"a":[1,2,3],"obj":{"a":[1,2], "b":{"c":3}},"message":"hello json console color writer"}`)
    90  	if err != nil {
    91  		t.Errorf("test plain text console writer error: %+v", err)
    92  	}
    93  }
    94  
    95  func TestConsoleWriterQuote(t *testing.T) {
    96  	w := &ConsoleWriter{
    97  		ColorOutput: true,
    98  		QuoteString: false,
    99  	}
   100  
   101  	_, err := wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"info","caller":"pretty.go:42","error":"i am test error","foo":"bar","n":42,"a":[1,2,3],"obj":{"a":[1], "b":{}},"message":"hello json console color writer"}`)
   102  	if err != nil {
   103  		t.Errorf("test plain text console writer error: %+v", err)
   104  	}
   105  
   106  	w.QuoteString = true
   107  
   108  	_, err = wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"info","caller":"pretty.go:42","error":"i am test error","foo":"bar","n":42,"a":[1,2,"foo"],"obj":{"a":["1"], "b":{"1":"2"}},"message":"hello json console color writer"}`)
   109  	if err != nil {
   110  		t.Errorf("test plain text console writer error: %+v", err)
   111  	}
   112  }
   113  
   114  func TestConsoleWriterMessage(t *testing.T) {
   115  	w := &ConsoleWriter{
   116  		ColorOutput:    true,
   117  		EndWithMessage: true,
   118  	}
   119  
   120  	_, err := wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"info","caller":"pretty.go:42","error":"i am test error","foo":"bar","n":42,"a":[1,2,3],"obj":{"a":[1], "b":{}},"message":"hello json console color writer"}`)
   121  	if err != nil {
   122  		t.Errorf("test plain text console writer error: %+v", err)
   123  	}
   124  
   125  	_, err = wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"info","caller":"pretty.go:42","error":"i am test error","foo":"bar","n":42,"a":[1,2,3],"obj":{"a":[1], "b":{}},"msg":"hello json msg color writer"}`)
   126  	if err != nil {
   127  		t.Errorf("test plain text console writer error: %+v", err)
   128  	}
   129  
   130  	w.ColorOutput = false
   131  	w.ColorOutput = false
   132  
   133  	_, err = wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"info","caller":"pretty.go:42","error":"i am test error","foo":"bar","n":42,"a":[1,2,"foo"],"obj":{"a":["1"], "b":{"1":"2"}},"message":"hello json console color writer"}`)
   134  	if err != nil {
   135  		t.Errorf("test plain text console writer error: %+v", err)
   136  	}
   137  
   138  	_, err = wlprintf(w, InfoLevel, "{\"msg\":\"hello world\\n\"}\n")
   139  	if err != nil {
   140  		t.Errorf("test plain text console writer error: %+v", err)
   141  	}
   142  }
   143  
   144  func TestConsoleWriterStack(t *testing.T) {
   145  	w := &ConsoleWriter{
   146  		ColorOutput: true,
   147  	}
   148  
   149  	_, err := wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"info","caller":"pretty.go:42","error":"i am test error","stack":"stack1\n\tstack2\n\t\tstack3\n","message":"hello console stack writer"}`)
   150  	if err != nil {
   151  		t.Errorf("test plain text console writer error: %+v", err)
   152  	}
   153  
   154  	_, err = wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"info","caller":"pretty.go:42","error":"i am test error","foo":"bar","n":42,"a":[1,2,3],"stack":{"a":[1,2], "b":{"c":3}},"message":"hello json console color writer"}`)
   155  	if err != nil {
   156  		t.Errorf("test plain text console writer error: %+v", err)
   157  	}
   158  }
   159  
   160  func TestConsoleWriterFormatter(t *testing.T) {
   161  	w := &ConsoleWriter{
   162  		Formatter: func(w io.Writer, a *FormatterArgs) (int, error) {
   163  			n, _ := fmt.Fprintf(w, "%c%s %s %s] %s", a.Level[0]-32, a.Time, a.Goid, a.Caller, a.Message)
   164  			for _, kv := range a.KeyValues {
   165  				i, _ := fmt.Fprintf(w, " %s=%s", kv.Key, kv.Value)
   166  				n += i
   167  			}
   168  			i, err := fmt.Fprintf(w, "\n")
   169  			return n + i, err
   170  		},
   171  	}
   172  
   173  	_, err := wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"info","caller":"pretty.go:42","goid":123,"error":"i am test error","stack":"stack1\n\tstack2\n\t\tstack3\n","message":"hello console stack writer"}`)
   174  	if err != nil {
   175  		t.Errorf("test plain text console writer error: %+v", err)
   176  	}
   177  
   178  	_, err = wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"debug","caller":"pretty.go:42","foo":"bar","n":42,"a":[1,2,3],"message":"hello json console color writer"}`)
   179  	if err != nil {
   180  		t.Errorf("test plain text console writer error: %+v", err)
   181  	}
   182  
   183  	_, err = wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"error","caller":"pretty.go:42","goid":0,"error":"i am test error","foo":"bar","n":42,"a":[1,2,3],"stack":{"a":[1,2], "b":{"c":3}},"message":"hello json console color writer"}`)
   184  	if err != nil {
   185  		t.Errorf("test plain text console writer error: %+v", err)
   186  	}
   187  
   188  	_, err = wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"hahaha","caller":"pretty.go:42","error":"i am test error","foo":"bar","n":42,"a":[1,2,3],"stack":{"a":[1,2], "b":{"c":3}},"message":"hello json console color writer"}`)
   189  	if err != nil {
   190  		t.Errorf("test plain text console writer error: %+v", err)
   191  	}
   192  
   193  	w.QuoteString = true
   194  
   195  	_, err = wlprintf(w, InfoLevel, `{"time":"2019-07-10T05:35:54.277Z","level":"hahaha","caller":"pretty.go:42","error":"i am test error","foo":"bar","n":42,"a":[1,2,3],"stack":{"a":[1,2], "b":{"c":3}},"msg":"hello json console color writer\n"}`)
   196  	if err != nil {
   197  		t.Errorf("test plain text console writer error: %+v", err)
   198  	}
   199  
   200  	_, err = wlprintf(w, InfoLevel, `{"ts":1234567890,"level":"hahaha","caller":"pretty.go:42","error":"i am test error","foo":"bar","n":42,"a":[1,2,3],"stack":{"a":[1,2], "b":{"c":3}},"msg":"hello json console color writer\n"}`)
   201  	if err != nil {
   202  		t.Errorf("test plain text console writer error: %+v", err)
   203  	}
   204  
   205  	_, err = wlprintf(w, InfoLevel, "a long long message not a json format\n")
   206  	if err != nil {
   207  		t.Errorf("test plain text console writer error: %+v", err)
   208  	}
   209  }
   210  
   211  func TestConsoleWriterGlog(t *testing.T) {
   212  	notTest = false
   213  
   214  	glog := (&Logger{
   215  		Level:      InfoLevel,
   216  		Caller:     1,
   217  		TimeFormat: "0102 15:04:05.999999",
   218  		Writer: &ConsoleWriter{
   219  			Formatter: func(w io.Writer, a *FormatterArgs) (int, error) {
   220  				return fmt.Fprintf(w, "%c%s %s %s] %s\n", a.Level[0]-32, a.Time, a.Goid, a.Caller, a.Message)
   221  			},
   222  		},
   223  	})
   224  
   225  	glog.Info().Msgf("hello glog %s", "Info")
   226  	glog.Warn().Msgf("hello glog %s", "Earn")
   227  	glog.Error().Msgf("hello glog %s", "Error")
   228  	glog.Fatal().Msgf("hello glog %s", "Fatal")
   229  }
   230  
   231  func TestConsoleWriterTime(t *testing.T) {
   232  	w := &ConsoleWriter{
   233  		ColorOutput: true,
   234  	}
   235  
   236  	_, err := wlprintf(w, InfoLevel, `{"ts":1594828508,"level":"info","caller":"pretty.go:42","goid":123,"error":"i am test error","message":"hello console time writer\n"}`)
   237  	if err != nil {
   238  		t.Errorf("test plain text console writer error: %+v", err)
   239  	}
   240  }
   241  
   242  func TestConsoleWriterInvaild(t *testing.T) {
   243  	w := &ConsoleWriter{
   244  		ColorOutput: true,
   245  	}
   246  
   247  	_, err := wlprintf(w, InfoLevel, "a long long long long plain text\n")
   248  	if err != nil {
   249  		t.Errorf("test plain text console writer error: %+v", err)
   250  	}
   251  }
   252  
   253  func TestConsoleWriterLogfmt(t *testing.T) {
   254  	DefaultLogger.Writer = &ConsoleWriter{
   255  		Formatter: LogfmtFormatter{"time"}.Formatter,
   256  	}
   257  
   258  	Info().
   259  		Caller(-1).
   260  		Bool("bool", true).
   261  		Bools("bools", []bool{false}).
   262  		Bools("bools", []bool{true, false}).
   263  		Dur("1_sec", time.Second+2*time.Millisecond+30*time.Microsecond+400*time.Nanosecond).
   264  		Dur("1_sec", -time.Second+2*time.Millisecond+30*time.Microsecond+400*time.Nanosecond).
   265  		Durs("hour_minute_second", []time.Duration{time.Hour, time.Minute, time.Second, -time.Second}).
   266  		Err(errors.New("test error")).
   267  		Err(nil).
   268  		AnErr("an_error", fmt.Errorf("an %w", errors.New("test error"))).
   269  		AnErr("an_error", nil).
   270  		Int64("goid", Goid()).
   271  		Float32("float32", 1.111).
   272  		Floats32("float32", []float32{1.111}).
   273  		Floats32("float32", []float32{1.111, 2.222}).
   274  		Float64("float64", 1.111).
   275  		Floats64("float64", []float64{1.111, 2.222}).
   276  		Uint64("uint64", 1234567890).
   277  		Uint32("uint32", 123).
   278  		Uint16("uint16", 123).
   279  		Uint8("uint8", 123).
   280  		Int64("int64", 1234567890).
   281  		Int32("int32", 123).
   282  		Int16("int16", 123).
   283  		Int8("int8", 123).
   284  		Int("int", 123).
   285  		Uints64("uints64", []uint64{1234567890, 1234567890}).
   286  		Uints32("uints32", []uint32{123, 123}).
   287  		Uints16("uints16", []uint16{123, 123}).
   288  		Uints8("uints8", []uint8{123, 123}).
   289  		Uints("uints", []uint{123, 123}).
   290  		Ints64("ints64", []int64{1234567890, 1234567890}).
   291  		Ints32("ints32", []int32{123, 123}).
   292  		Ints16("ints16", []int16{123, 123}).
   293  		Ints8("ints8", []int8{123, 123}).
   294  		Ints("ints", []int{123, 123}).
   295  		Func(func(e *Entry) { e.Str("func", "func_output") }).
   296  		RawJSON("raw_json", []byte("{\"a\":1,\"b\":2}")).
   297  		RawJSONStr("raw_json", "{\"c\":1,\"d\":2}").
   298  		Hex("hex", []byte("\"<>?'")).
   299  		Bytes("bytes1", []byte("bytes1")).
   300  		Bytes("bytes2", []byte("\"<>?'")).
   301  		BytesOrNil("bytes3", []byte("\"<>?'")).
   302  		Bytes("nil_bytes_1", nil).
   303  		BytesOrNil("nil_bytes_2", nil).
   304  		Str("foobar", "\"\\\t\r\n\f\b\x00<>?'").
   305  		Strs("strings", []string{"a", "b", "\"<>?'"}).
   306  		Stringer("stringer", nil).
   307  		GoStringer("gostringer", nil).
   308  		Time("now_1", timeNow().In(time.FixedZone("UTC-7", -7*60*60))).
   309  		Times("now_2", []time.Time{timeNow(), timeNow()}).
   310  		TimeFormat("now_3", time.RFC3339, timeNow()).
   311  		TimeFormat("now_3_1", TimeFormatUnix, timeNow()).
   312  		TimeFormat("now_3_2", TimeFormatUnixMs, timeNow()).
   313  		TimeFormat("now_3_3", TimeFormatUnixWithMs, timeNow()).
   314  		TimesFormat("now_4", time.RFC3339, []time.Time{timeNow(), timeNow()}).
   315  		TimeDiff("time_diff_1", timeNow().Add(time.Second), timeNow()).
   316  		TimeDiff("time_diff_2", time.Time{}, timeNow()).
   317  		Xid("xid", NewXID()).
   318  		Errs("errors", []error{errors.New("error1"), nil, errors.New("error3")}).
   319  		Interface("console_writer", ConsoleWriter{ColorOutput: true}).
   320  		Interface("time.Time", timeNow()).
   321  		KeysAndValues("foo", "bar", "number", 42).
   322  		Msg("aaaa 'b' cccc")
   323  }