| /* |
| * |
| * Copyright 2018 gRPC authors. |
| * |
| * 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. |
| * |
| */ |
| |
| package binarylog |
| |
| import ( |
| "fmt" |
| "testing" |
| ) |
| |
| // This tests that when multiple configs are specified, all methods loggers will |
| // be set correctly. Correctness of each logger is covered by other unit tests. |
| func TestNewLoggerFromConfigString(t *testing.T) { |
| const ( |
| s1 = "s1" |
| m1 = "m1" |
| m2 = "m2" |
| fullM1 = s1 + "/" + m1 |
| fullM2 = s1 + "/" + m2 |
| ) |
| c := fmt.Sprintf("*{h:1;m:2},%s{h},%s{m},%s{h;m}", s1+"/*", fullM1, fullM2) |
| l := NewLoggerFromConfigString(c).(*logger) |
| |
| if l.all.hdr != 1 || l.all.msg != 2 { |
| t.Errorf("l.all = %#v, want headerLen: 1, messageLen: 2", l.all) |
| } |
| |
| if ml, ok := l.services[s1]; ok { |
| if ml.hdr != maxUInt || ml.msg != 0 { |
| t.Errorf("want maxUInt header, 0 message, got header: %v, message: %v", ml.hdr, ml.msg) |
| } |
| } else { |
| t.Errorf("service/* is not set") |
| } |
| |
| if ml, ok := l.methods[fullM1]; ok { |
| if ml.hdr != 0 || ml.msg != maxUInt { |
| t.Errorf("want 0 header, maxUInt message, got header: %v, message: %v", ml.hdr, ml.msg) |
| } |
| } else { |
| t.Errorf("service/method{h} is not set") |
| } |
| |
| if ml, ok := l.methods[fullM2]; ok { |
| if ml.hdr != maxUInt || ml.msg != maxUInt { |
| t.Errorf("want maxUInt header, maxUInt message, got header: %v, message: %v", ml.hdr, ml.msg) |
| } |
| } else { |
| t.Errorf("service/method{h;m} is not set") |
| } |
| } |
| |
| func TestNewLoggerFromConfigStringInvalid(t *testing.T) { |
| testCases := []string{ |
| "", |
| "*{}", |
| "s/m,*{}", |
| "s/m,s/m{a}", |
| |
| // Duplciate rules. |
| "s/m,-s/m", |
| "-s/m,s/m", |
| "s/m,s/m", |
| "s/m,s/m{h:1;m:1}", |
| "s/m{h:1;m:1},s/m", |
| "-s/m,-s/m", |
| "s/*,s/*{h:1;m:1}", |
| "*,*{h:1;m:1}", |
| } |
| for _, tc := range testCases { |
| l := NewLoggerFromConfigString(tc) |
| if l != nil { |
| t.Errorf("With config %q, want logger %v, got %v", tc, nil, l) |
| } |
| } |
| } |
| |
| func TestParseMethodConfigAndSuffix(t *testing.T) { |
| testCases := []struct { |
| in, service, method, suffix string |
| }{ |
| { |
| in: "p.s/m", |
| service: "p.s", method: "m", suffix: "", |
| }, |
| { |
| in: "p.s/m{h,m}", |
| service: "p.s", method: "m", suffix: "{h,m}", |
| }, |
| { |
| in: "p.s/*", |
| service: "p.s", method: "*", suffix: "", |
| }, |
| { |
| in: "p.s/*{h,m}", |
| service: "p.s", method: "*", suffix: "{h,m}", |
| }, |
| |
| // invalid suffix will be detected by another function. |
| { |
| in: "p.s/m{invalidsuffix}", |
| service: "p.s", method: "m", suffix: "{invalidsuffix}", |
| }, |
| { |
| in: "p.s/*{invalidsuffix}", |
| service: "p.s", method: "*", suffix: "{invalidsuffix}", |
| }, |
| { |
| in: "s/m*", |
| service: "s", method: "m", suffix: "*", |
| }, |
| { |
| in: "s/*m", |
| service: "s", method: "*", suffix: "m", |
| }, |
| { |
| in: "s/**", |
| service: "s", method: "*", suffix: "*", |
| }, |
| } |
| for _, tc := range testCases { |
| t.Logf("testing parseMethodConfigAndSuffix(%q)", tc.in) |
| s, m, suffix, err := parseMethodConfigAndSuffix(tc.in) |
| if err != nil { |
| t.Errorf("returned error %v, want nil", err) |
| continue |
| } |
| if s != tc.service { |
| t.Errorf("service = %q, want %q", s, tc.service) |
| } |
| if m != tc.method { |
| t.Errorf("method = %q, want %q", m, tc.method) |
| } |
| if suffix != tc.suffix { |
| t.Errorf("suffix = %q, want %q", suffix, tc.suffix) |
| } |
| } |
| } |
| |
| func TestParseMethodConfigAndSuffixInvalid(t *testing.T) { |
| testCases := []string{ |
| "*/m", |
| "*/m{}", |
| } |
| for _, tc := range testCases { |
| s, m, suffix, err := parseMethodConfigAndSuffix(tc) |
| if err == nil { |
| t.Errorf("Parsing %q got nil error with %q, %q, %q, want non-nil error", tc, s, m, suffix) |
| } |
| } |
| } |
| |
| func TestParseHeaderMessageLengthConfig(t *testing.T) { |
| testCases := []struct { |
| in string |
| hdr, msg uint64 |
| }{ |
| { |
| in: "", |
| hdr: maxUInt, msg: maxUInt, |
| }, |
| { |
| in: "{h}", |
| hdr: maxUInt, msg: 0, |
| }, |
| { |
| in: "{h:314}", |
| hdr: 314, msg: 0, |
| }, |
| { |
| in: "{m}", |
| hdr: 0, msg: maxUInt, |
| }, |
| { |
| in: "{m:213}", |
| hdr: 0, msg: 213, |
| }, |
| { |
| in: "{h;m}", |
| hdr: maxUInt, msg: maxUInt, |
| }, |
| { |
| in: "{h:314;m}", |
| hdr: 314, msg: maxUInt, |
| }, |
| { |
| in: "{h;m:213}", |
| hdr: maxUInt, msg: 213, |
| }, |
| { |
| in: "{h:314;m:213}", |
| hdr: 314, msg: 213, |
| }, |
| } |
| for _, tc := range testCases { |
| t.Logf("testing parseHeaderMessageLengthConfig(%q)", tc.in) |
| hdr, msg, err := parseHeaderMessageLengthConfig(tc.in) |
| if err != nil { |
| t.Errorf("returned error %v, want nil", err) |
| continue |
| } |
| if hdr != tc.hdr { |
| t.Errorf("header length = %v, want %v", hdr, tc.hdr) |
| } |
| if msg != tc.msg { |
| t.Errorf("message length = %v, want %v", msg, tc.msg) |
| } |
| } |
| } |
| func TestParseHeaderMessageLengthConfigInvalid(t *testing.T) { |
| testCases := []string{ |
| "{}", |
| "{h;a}", |
| "{h;m;b}", |
| } |
| for _, tc := range testCases { |
| _, _, err := parseHeaderMessageLengthConfig(tc) |
| if err == nil { |
| t.Errorf("Parsing %q got nil error, want non-nil error", tc) |
| } |
| } |
| } |
| |
| func TestFillMethodLoggerWithConfigStringBlacklist(t *testing.T) { |
| testCases := []string{ |
| "p.s/m", |
| "service/method", |
| } |
| for _, tc := range testCases { |
| c := "-" + tc |
| t.Logf("testing fillMethodLoggerWithConfigString(%q)", c) |
| l := newEmptyLogger() |
| if err := l.fillMethodLoggerWithConfigString(c); err != nil { |
| t.Errorf("returned err %v, want nil", err) |
| continue |
| } |
| _, ok := l.blacklist[tc] |
| if !ok { |
| t.Errorf("blacklist[%q] is not set", tc) |
| } |
| } |
| } |
| |
| func TestFillMethodLoggerWithConfigStringGlobal(t *testing.T) { |
| testCases := []struct { |
| in string |
| hdr, msg uint64 |
| }{ |
| { |
| in: "", |
| hdr: maxUInt, msg: maxUInt, |
| }, |
| { |
| in: "{h}", |
| hdr: maxUInt, msg: 0, |
| }, |
| { |
| in: "{h:314}", |
| hdr: 314, msg: 0, |
| }, |
| { |
| in: "{m}", |
| hdr: 0, msg: maxUInt, |
| }, |
| { |
| in: "{m:213}", |
| hdr: 0, msg: 213, |
| }, |
| { |
| in: "{h;m}", |
| hdr: maxUInt, msg: maxUInt, |
| }, |
| { |
| in: "{h:314;m}", |
| hdr: 314, msg: maxUInt, |
| }, |
| { |
| in: "{h;m:213}", |
| hdr: maxUInt, msg: 213, |
| }, |
| { |
| in: "{h:314;m:213}", |
| hdr: 314, msg: 213, |
| }, |
| } |
| for _, tc := range testCases { |
| c := "*" + tc.in |
| t.Logf("testing fillMethodLoggerWithConfigString(%q)", c) |
| l := newEmptyLogger() |
| if err := l.fillMethodLoggerWithConfigString(c); err != nil { |
| t.Errorf("returned err %v, want nil", err) |
| continue |
| } |
| if l.all == nil { |
| t.Errorf("l.all is not set") |
| continue |
| } |
| if hdr := l.all.hdr; hdr != tc.hdr { |
| t.Errorf("header length = %v, want %v", hdr, tc.hdr) |
| |
| } |
| if msg := l.all.msg; msg != tc.msg { |
| t.Errorf("message length = %v, want %v", msg, tc.msg) |
| } |
| } |
| } |
| |
| func TestFillMethodLoggerWithConfigStringPerService(t *testing.T) { |
| testCases := []struct { |
| in string |
| hdr, msg uint64 |
| }{ |
| { |
| in: "", |
| hdr: maxUInt, msg: maxUInt, |
| }, |
| { |
| in: "{h}", |
| hdr: maxUInt, msg: 0, |
| }, |
| { |
| in: "{h:314}", |
| hdr: 314, msg: 0, |
| }, |
| { |
| in: "{m}", |
| hdr: 0, msg: maxUInt, |
| }, |
| { |
| in: "{m:213}", |
| hdr: 0, msg: 213, |
| }, |
| { |
| in: "{h;m}", |
| hdr: maxUInt, msg: maxUInt, |
| }, |
| { |
| in: "{h:314;m}", |
| hdr: 314, msg: maxUInt, |
| }, |
| { |
| in: "{h;m:213}", |
| hdr: maxUInt, msg: 213, |
| }, |
| { |
| in: "{h:314;m:213}", |
| hdr: 314, msg: 213, |
| }, |
| } |
| const serviceName = "service" |
| for _, tc := range testCases { |
| c := serviceName + "/*" + tc.in |
| t.Logf("testing fillMethodLoggerWithConfigString(%q)", c) |
| l := newEmptyLogger() |
| if err := l.fillMethodLoggerWithConfigString(c); err != nil { |
| t.Errorf("returned err %v, want nil", err) |
| continue |
| } |
| ml, ok := l.services[serviceName] |
| if !ok { |
| t.Errorf("l.service[%q] is not set", serviceName) |
| continue |
| } |
| if hdr := ml.hdr; hdr != tc.hdr { |
| t.Errorf("header length = %v, want %v", hdr, tc.hdr) |
| |
| } |
| if msg := ml.msg; msg != tc.msg { |
| t.Errorf("message length = %v, want %v", msg, tc.msg) |
| } |
| } |
| } |
| |
| func TestFillMethodLoggerWithConfigStringPerMethod(t *testing.T) { |
| testCases := []struct { |
| in string |
| hdr, msg uint64 |
| }{ |
| { |
| in: "", |
| hdr: maxUInt, msg: maxUInt, |
| }, |
| { |
| in: "{h}", |
| hdr: maxUInt, msg: 0, |
| }, |
| { |
| in: "{h:314}", |
| hdr: 314, msg: 0, |
| }, |
| { |
| in: "{m}", |
| hdr: 0, msg: maxUInt, |
| }, |
| { |
| in: "{m:213}", |
| hdr: 0, msg: 213, |
| }, |
| { |
| in: "{h;m}", |
| hdr: maxUInt, msg: maxUInt, |
| }, |
| { |
| in: "{h:314;m}", |
| hdr: 314, msg: maxUInt, |
| }, |
| { |
| in: "{h;m:213}", |
| hdr: maxUInt, msg: 213, |
| }, |
| { |
| in: "{h:314;m:213}", |
| hdr: 314, msg: 213, |
| }, |
| } |
| const ( |
| serviceName = "service" |
| methodName = "method" |
| fullMethodName = serviceName + "/" + methodName |
| ) |
| for _, tc := range testCases { |
| c := fullMethodName + tc.in |
| t.Logf("testing fillMethodLoggerWithConfigString(%q)", c) |
| l := newEmptyLogger() |
| if err := l.fillMethodLoggerWithConfigString(c); err != nil { |
| t.Errorf("returned err %v, want nil", err) |
| continue |
| } |
| ml, ok := l.methods[fullMethodName] |
| if !ok { |
| t.Errorf("l.methods[%q] is not set", fullMethodName) |
| continue |
| } |
| if hdr := ml.hdr; hdr != tc.hdr { |
| t.Errorf("header length = %v, want %v", hdr, tc.hdr) |
| |
| } |
| if msg := ml.msg; msg != tc.msg { |
| t.Errorf("message length = %v, want %v", msg, tc.msg) |
| } |
| } |
| } |
| |
| func TestFillMethodLoggerWithConfigStringInvalid(t *testing.T) { |
| testCases := []string{ |
| "", |
| "{}", |
| "p.s/m{}", |
| "p.s/m{a}", |
| "p.s/m*", |
| "p.s/**", |
| "*/m", |
| |
| "-p.s/*", |
| "-p.s/m{h}", |
| } |
| l := &logger{} |
| for _, tc := range testCases { |
| if err := l.fillMethodLoggerWithConfigString(tc); err == nil { |
| t.Errorf("fillMethodLoggerWithConfigString(%q) returned nil error, want non-nil", tc) |
| } |
| } |
| } |