github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/internal/binarylog/env_config_test.go (about)

     1  /*
     2   *
     3   * Copyright 2018 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package binarylog
    20  
    21  import (
    22  	"fmt"
    23  	"testing"
    24  )
    25  
    26  // This tests that when multiple configs are specified, all methods loggers will
    27  // be set correctly. Correctness of each logger is covered by other unit tests.
    28  func (s) TestNewLoggerFromConfigString(t *testing.T) {
    29  	const (
    30  		s1     = "s1"
    31  		m1     = "m1"
    32  		m2     = "m2"
    33  		fullM1 = s1 + "/" + m1
    34  		fullM2 = s1 + "/" + m2
    35  	)
    36  	c := fmt.Sprintf("*{h:1;m:2},%s{h},%s{m},%s{h;m}", s1+"/*", fullM1, fullM2)
    37  	l := NewLoggerFromConfigString(c).(*logger)
    38  
    39  	if l.all.hdr != 1 || l.all.msg != 2 {
    40  		t.Errorf("l.all = %#v, want headerLen: 1, messageLen: 2", l.all)
    41  	}
    42  
    43  	if ml, ok := l.services[s1]; ok {
    44  		if ml.hdr != maxUInt || ml.msg != 0 {
    45  			t.Errorf("want maxUInt header, 0 message, got header: %v, message: %v", ml.hdr, ml.msg)
    46  		}
    47  	} else {
    48  		t.Errorf("service/* is not set")
    49  	}
    50  
    51  	if ml, ok := l.methods[fullM1]; ok {
    52  		if ml.hdr != 0 || ml.msg != maxUInt {
    53  			t.Errorf("want 0 header, maxUInt message, got header: %v, message: %v", ml.hdr, ml.msg)
    54  		}
    55  	} else {
    56  		t.Errorf("service/method{h} is not set")
    57  	}
    58  
    59  	if ml, ok := l.methods[fullM2]; ok {
    60  		if ml.hdr != maxUInt || ml.msg != maxUInt {
    61  			t.Errorf("want maxUInt header, maxUInt message, got header: %v, message: %v", ml.hdr, ml.msg)
    62  		}
    63  	} else {
    64  		t.Errorf("service/method{h;m} is not set")
    65  	}
    66  }
    67  
    68  func (s) TestNewLoggerFromConfigStringInvalid(t *testing.T) {
    69  	testCases := []string{
    70  		"",
    71  		"*{}",
    72  		"s/m,*{}",
    73  		"s/m,s/m{a}",
    74  
    75  		// Duplicate rules.
    76  		"s/m,-s/m",
    77  		"-s/m,s/m",
    78  		"s/m,s/m",
    79  		"s/m,s/m{h:1;m:1}",
    80  		"s/m{h:1;m:1},s/m",
    81  		"-s/m,-s/m",
    82  		"s/*,s/*{h:1;m:1}",
    83  		"*,*{h:1;m:1}",
    84  	}
    85  	for _, tc := range testCases {
    86  		l := NewLoggerFromConfigString(tc)
    87  		if l != nil {
    88  			t.Errorf("With config %q, want logger %v, got %v", tc, nil, l)
    89  		}
    90  	}
    91  }
    92  
    93  func (s) TestParseMethodConfigAndSuffix(t *testing.T) {
    94  	testCases := []struct {
    95  		in, service, method, suffix string
    96  	}{
    97  		{
    98  			in:      "p.s/m",
    99  			service: "p.s", method: "m", suffix: "",
   100  		},
   101  		{
   102  			in:      "p.s/m{h,m}",
   103  			service: "p.s", method: "m", suffix: "{h,m}",
   104  		},
   105  		{
   106  			in:      "p.s/*",
   107  			service: "p.s", method: "*", suffix: "",
   108  		},
   109  		{
   110  			in:      "p.s/*{h,m}",
   111  			service: "p.s", method: "*", suffix: "{h,m}",
   112  		},
   113  
   114  		// invalid suffix will be detected by another function.
   115  		{
   116  			in:      "p.s/m{invalidsuffix}",
   117  			service: "p.s", method: "m", suffix: "{invalidsuffix}",
   118  		},
   119  		{
   120  			in:      "p.s/*{invalidsuffix}",
   121  			service: "p.s", method: "*", suffix: "{invalidsuffix}",
   122  		},
   123  		{
   124  			in:      "s/m*",
   125  			service: "s", method: "m", suffix: "*",
   126  		},
   127  		{
   128  			in:      "s/*m",
   129  			service: "s", method: "*", suffix: "m",
   130  		},
   131  		{
   132  			in:      "s/**",
   133  			service: "s", method: "*", suffix: "*",
   134  		},
   135  	}
   136  	for _, tc := range testCases {
   137  		t.Logf("testing parseMethodConfigAndSuffix(%q)", tc.in)
   138  		s, m, suffix, err := parseMethodConfigAndSuffix(tc.in)
   139  		if err != nil {
   140  			t.Errorf("returned error %v, want nil", err)
   141  			continue
   142  		}
   143  		if s != tc.service {
   144  			t.Errorf("service = %q, want %q", s, tc.service)
   145  		}
   146  		if m != tc.method {
   147  			t.Errorf("method = %q, want %q", m, tc.method)
   148  		}
   149  		if suffix != tc.suffix {
   150  			t.Errorf("suffix = %q, want %q", suffix, tc.suffix)
   151  		}
   152  	}
   153  }
   154  
   155  func (s) TestParseMethodConfigAndSuffixInvalid(t *testing.T) {
   156  	testCases := []string{
   157  		"*/m",
   158  		"*/m{}",
   159  	}
   160  	for _, tc := range testCases {
   161  		s, m, suffix, err := parseMethodConfigAndSuffix(tc)
   162  		if err == nil {
   163  			t.Errorf("Parsing %q got nil error with %q, %q, %q, want non-nil error", tc, s, m, suffix)
   164  		}
   165  	}
   166  }
   167  
   168  func (s) TestParseHeaderMessageLengthConfig(t *testing.T) {
   169  	testCases := []struct {
   170  		in       string
   171  		hdr, msg uint64
   172  	}{
   173  		{
   174  			in:  "",
   175  			hdr: maxUInt, msg: maxUInt,
   176  		},
   177  		{
   178  			in:  "{h}",
   179  			hdr: maxUInt, msg: 0,
   180  		},
   181  		{
   182  			in:  "{h:314}",
   183  			hdr: 314, msg: 0,
   184  		},
   185  		{
   186  			in:  "{m}",
   187  			hdr: 0, msg: maxUInt,
   188  		},
   189  		{
   190  			in:  "{m:213}",
   191  			hdr: 0, msg: 213,
   192  		},
   193  		{
   194  			in:  "{h;m}",
   195  			hdr: maxUInt, msg: maxUInt,
   196  		},
   197  		{
   198  			in:  "{h:314;m}",
   199  			hdr: 314, msg: maxUInt,
   200  		},
   201  		{
   202  			in:  "{h;m:213}",
   203  			hdr: maxUInt, msg: 213,
   204  		},
   205  		{
   206  			in:  "{h:314;m:213}",
   207  			hdr: 314, msg: 213,
   208  		},
   209  	}
   210  	for _, tc := range testCases {
   211  		t.Logf("testing parseHeaderMessageLengthConfig(%q)", tc.in)
   212  		hdr, msg, err := parseHeaderMessageLengthConfig(tc.in)
   213  		if err != nil {
   214  			t.Errorf("returned error %v, want nil", err)
   215  			continue
   216  		}
   217  		if hdr != tc.hdr {
   218  			t.Errorf("header length = %v, want %v", hdr, tc.hdr)
   219  		}
   220  		if msg != tc.msg {
   221  			t.Errorf("message length = %v, want %v", msg, tc.msg)
   222  		}
   223  	}
   224  }
   225  func (s) TestParseHeaderMessageLengthConfigInvalid(t *testing.T) {
   226  	testCases := []string{
   227  		"{}",
   228  		"{h;a}",
   229  		"{h;m;b}",
   230  	}
   231  	for _, tc := range testCases {
   232  		_, _, err := parseHeaderMessageLengthConfig(tc)
   233  		if err == nil {
   234  			t.Errorf("Parsing %q got nil error, want non-nil error", tc)
   235  		}
   236  	}
   237  }
   238  
   239  func (s) TestFillMethodLoggerWithConfigStringBlacklist(t *testing.T) {
   240  	testCases := []string{
   241  		"p.s/m",
   242  		"service/method",
   243  	}
   244  	for _, tc := range testCases {
   245  		c := "-" + tc
   246  		t.Logf("testing fillMethodLoggerWithConfigString(%q)", c)
   247  		l := newEmptyLogger()
   248  		if err := l.fillMethodLoggerWithConfigString(c); err != nil {
   249  			t.Errorf("returned err %v, want nil", err)
   250  			continue
   251  		}
   252  		_, ok := l.blacklist[tc]
   253  		if !ok {
   254  			t.Errorf("blacklist[%q] is not set", tc)
   255  		}
   256  	}
   257  }
   258  
   259  func (s) TestFillMethodLoggerWithConfigStringGlobal(t *testing.T) {
   260  	testCases := []struct {
   261  		in       string
   262  		hdr, msg uint64
   263  	}{
   264  		{
   265  			in:  "",
   266  			hdr: maxUInt, msg: maxUInt,
   267  		},
   268  		{
   269  			in:  "{h}",
   270  			hdr: maxUInt, msg: 0,
   271  		},
   272  		{
   273  			in:  "{h:314}",
   274  			hdr: 314, msg: 0,
   275  		},
   276  		{
   277  			in:  "{m}",
   278  			hdr: 0, msg: maxUInt,
   279  		},
   280  		{
   281  			in:  "{m:213}",
   282  			hdr: 0, msg: 213,
   283  		},
   284  		{
   285  			in:  "{h;m}",
   286  			hdr: maxUInt, msg: maxUInt,
   287  		},
   288  		{
   289  			in:  "{h:314;m}",
   290  			hdr: 314, msg: maxUInt,
   291  		},
   292  		{
   293  			in:  "{h;m:213}",
   294  			hdr: maxUInt, msg: 213,
   295  		},
   296  		{
   297  			in:  "{h:314;m:213}",
   298  			hdr: 314, msg: 213,
   299  		},
   300  	}
   301  	for _, tc := range testCases {
   302  		c := "*" + tc.in
   303  		t.Logf("testing fillMethodLoggerWithConfigString(%q)", c)
   304  		l := newEmptyLogger()
   305  		if err := l.fillMethodLoggerWithConfigString(c); err != nil {
   306  			t.Errorf("returned err %v, want nil", err)
   307  			continue
   308  		}
   309  		if l.all == nil {
   310  			t.Errorf("l.all is not set")
   311  			continue
   312  		}
   313  		if hdr := l.all.hdr; hdr != tc.hdr {
   314  			t.Errorf("header length = %v, want %v", hdr, tc.hdr)
   315  
   316  		}
   317  		if msg := l.all.msg; msg != tc.msg {
   318  			t.Errorf("message length = %v, want %v", msg, tc.msg)
   319  		}
   320  	}
   321  }
   322  
   323  func (s) TestFillMethodLoggerWithConfigStringPerService(t *testing.T) {
   324  	testCases := []struct {
   325  		in       string
   326  		hdr, msg uint64
   327  	}{
   328  		{
   329  			in:  "",
   330  			hdr: maxUInt, msg: maxUInt,
   331  		},
   332  		{
   333  			in:  "{h}",
   334  			hdr: maxUInt, msg: 0,
   335  		},
   336  		{
   337  			in:  "{h:314}",
   338  			hdr: 314, msg: 0,
   339  		},
   340  		{
   341  			in:  "{m}",
   342  			hdr: 0, msg: maxUInt,
   343  		},
   344  		{
   345  			in:  "{m:213}",
   346  			hdr: 0, msg: 213,
   347  		},
   348  		{
   349  			in:  "{h;m}",
   350  			hdr: maxUInt, msg: maxUInt,
   351  		},
   352  		{
   353  			in:  "{h:314;m}",
   354  			hdr: 314, msg: maxUInt,
   355  		},
   356  		{
   357  			in:  "{h;m:213}",
   358  			hdr: maxUInt, msg: 213,
   359  		},
   360  		{
   361  			in:  "{h:314;m:213}",
   362  			hdr: 314, msg: 213,
   363  		},
   364  	}
   365  	const serviceName = "service"
   366  	for _, tc := range testCases {
   367  		c := serviceName + "/*" + tc.in
   368  		t.Logf("testing fillMethodLoggerWithConfigString(%q)", c)
   369  		l := newEmptyLogger()
   370  		if err := l.fillMethodLoggerWithConfigString(c); err != nil {
   371  			t.Errorf("returned err %v, want nil", err)
   372  			continue
   373  		}
   374  		ml, ok := l.services[serviceName]
   375  		if !ok {
   376  			t.Errorf("l.service[%q] is not set", serviceName)
   377  			continue
   378  		}
   379  		if hdr := ml.hdr; hdr != tc.hdr {
   380  			t.Errorf("header length = %v, want %v", hdr, tc.hdr)
   381  
   382  		}
   383  		if msg := ml.msg; msg != tc.msg {
   384  			t.Errorf("message length = %v, want %v", msg, tc.msg)
   385  		}
   386  	}
   387  }
   388  
   389  func (s) TestFillMethodLoggerWithConfigStringPerMethod(t *testing.T) {
   390  	testCases := []struct {
   391  		in       string
   392  		hdr, msg uint64
   393  	}{
   394  		{
   395  			in:  "",
   396  			hdr: maxUInt, msg: maxUInt,
   397  		},
   398  		{
   399  			in:  "{h}",
   400  			hdr: maxUInt, msg: 0,
   401  		},
   402  		{
   403  			in:  "{h:314}",
   404  			hdr: 314, msg: 0,
   405  		},
   406  		{
   407  			in:  "{m}",
   408  			hdr: 0, msg: maxUInt,
   409  		},
   410  		{
   411  			in:  "{m:213}",
   412  			hdr: 0, msg: 213,
   413  		},
   414  		{
   415  			in:  "{h;m}",
   416  			hdr: maxUInt, msg: maxUInt,
   417  		},
   418  		{
   419  			in:  "{h:314;m}",
   420  			hdr: 314, msg: maxUInt,
   421  		},
   422  		{
   423  			in:  "{h;m:213}",
   424  			hdr: maxUInt, msg: 213,
   425  		},
   426  		{
   427  			in:  "{h:314;m:213}",
   428  			hdr: 314, msg: 213,
   429  		},
   430  	}
   431  	const (
   432  		serviceName    = "service"
   433  		methodName     = "method"
   434  		fullMethodName = serviceName + "/" + methodName
   435  	)
   436  	for _, tc := range testCases {
   437  		c := fullMethodName + tc.in
   438  		t.Logf("testing fillMethodLoggerWithConfigString(%q)", c)
   439  		l := newEmptyLogger()
   440  		if err := l.fillMethodLoggerWithConfigString(c); err != nil {
   441  			t.Errorf("returned err %v, want nil", err)
   442  			continue
   443  		}
   444  		ml, ok := l.methods[fullMethodName]
   445  		if !ok {
   446  			t.Errorf("l.methods[%q] is not set", fullMethodName)
   447  			continue
   448  		}
   449  		if hdr := ml.hdr; hdr != tc.hdr {
   450  			t.Errorf("header length = %v, want %v", hdr, tc.hdr)
   451  
   452  		}
   453  		if msg := ml.msg; msg != tc.msg {
   454  			t.Errorf("message length = %v, want %v", msg, tc.msg)
   455  		}
   456  	}
   457  }
   458  
   459  func (s) TestFillMethodLoggerWithConfigStringInvalid(t *testing.T) {
   460  	testCases := []string{
   461  		"",
   462  		"{}",
   463  		"p.s/m{}",
   464  		"p.s/m{a}",
   465  		"p.s/m*",
   466  		"p.s/**",
   467  		"*/m",
   468  
   469  		"-p.s/*",
   470  		"-p.s/m{h}",
   471  	}
   472  	l := &logger{}
   473  	for _, tc := range testCases {
   474  		if err := l.fillMethodLoggerWithConfigString(tc); err == nil {
   475  			t.Errorf("fillMethodLoggerWithConfigString(%q) returned nil error, want non-nil", tc)
   476  		}
   477  	}
   478  }