gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/internal/serviceconfig/serviceconfig_test.go (about)

     1  /*
     2   *
     3   * Copyright 2020 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 serviceconfig
    20  
    21  import (
    22  	"encoding/json"
    23  	"fmt"
    24  	"testing"
    25  
    26  	"gitee.com/ks-custle/core-gm/grpc/balancer"
    27  	externalserviceconfig "gitee.com/ks-custle/core-gm/grpc/serviceconfig"
    28  	"github.com/google/go-cmp/cmp"
    29  )
    30  
    31  type testBalancerConfigType struct {
    32  	externalserviceconfig.LoadBalancingConfig `json:"-"`
    33  
    34  	Check bool `json:"check"`
    35  }
    36  
    37  var testBalancerConfig = testBalancerConfigType{Check: true}
    38  
    39  const (
    40  	testBalancerBuilderName          = "test-bb"
    41  	testBalancerBuilderNotParserName = "test-bb-not-parser"
    42  
    43  	testBalancerConfigJSON = `{"check":true}`
    44  )
    45  
    46  type testBalancerBuilder struct {
    47  	balancer.Builder
    48  }
    49  
    50  func (testBalancerBuilder) ParseConfig(js json.RawMessage) (externalserviceconfig.LoadBalancingConfig, error) {
    51  	if string(js) != testBalancerConfigJSON {
    52  		return nil, fmt.Errorf("unexpected config json")
    53  	}
    54  	return testBalancerConfig, nil
    55  }
    56  
    57  func (testBalancerBuilder) Name() string {
    58  	return testBalancerBuilderName
    59  }
    60  
    61  type testBalancerBuilderNotParser struct {
    62  	balancer.Builder
    63  }
    64  
    65  func (testBalancerBuilderNotParser) Name() string {
    66  	return testBalancerBuilderNotParserName
    67  }
    68  
    69  func init() {
    70  	balancer.Register(testBalancerBuilder{})
    71  	balancer.Register(testBalancerBuilderNotParser{})
    72  }
    73  
    74  func TestBalancerConfigUnmarshalJSON(t *testing.T) {
    75  	tests := []struct {
    76  		name    string
    77  		json    string
    78  		want    BalancerConfig
    79  		wantErr bool
    80  	}{
    81  		{
    82  			name:    "empty json",
    83  			json:    "",
    84  			wantErr: true,
    85  		},
    86  		{
    87  			// The config should be a slice of maps, but each map should have
    88  			// exactly one entry.
    89  			name:    "more than one entry for a map",
    90  			json:    `[{"balancer1":"1","balancer2":"2"}]`,
    91  			wantErr: true,
    92  		},
    93  		{
    94  			name:    "no balancer registered",
    95  			json:    `[{"balancer1":"1"},{"balancer2":"2"}]`,
    96  			wantErr: true,
    97  		},
    98  		{
    99  			name: "OK",
   100  			json: fmt.Sprintf("[{%q: %v}]", testBalancerBuilderName, testBalancerConfigJSON),
   101  			want: BalancerConfig{
   102  				Name:   testBalancerBuilderName,
   103  				Config: testBalancerConfig,
   104  			},
   105  			wantErr: false,
   106  		},
   107  		{
   108  			name: "first balancer not registered",
   109  			json: fmt.Sprintf(`[{"balancer1":"1"},{%q: %v}]`, testBalancerBuilderName, testBalancerConfigJSON),
   110  			want: BalancerConfig{
   111  				Name:   testBalancerBuilderName,
   112  				Config: testBalancerConfig,
   113  			},
   114  			wantErr: false,
   115  		},
   116  		{
   117  			name: "balancer registered but builder not parser",
   118  			json: fmt.Sprintf("[{%q: %v}]", testBalancerBuilderNotParserName, testBalancerConfigJSON),
   119  			want: BalancerConfig{
   120  				Name:   testBalancerBuilderNotParserName,
   121  				Config: nil,
   122  			},
   123  			wantErr: false,
   124  		},
   125  	}
   126  	for _, tt := range tests {
   127  		t.Run(tt.name, func(t *testing.T) {
   128  			var bc BalancerConfig
   129  			if err := bc.UnmarshalJSON([]byte(tt.json)); (err != nil) != tt.wantErr {
   130  				t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
   131  			}
   132  			if !cmp.Equal(bc, tt.want) {
   133  				t.Errorf("diff: %v", cmp.Diff(bc, tt.want))
   134  			}
   135  		})
   136  	}
   137  }
   138  
   139  func TestBalancerConfigMarshalJSON(t *testing.T) {
   140  	tests := []struct {
   141  		name     string
   142  		bc       BalancerConfig
   143  		wantJSON string
   144  	}{
   145  		{
   146  			name: "OK",
   147  			bc: BalancerConfig{
   148  				Name:   testBalancerBuilderName,
   149  				Config: testBalancerConfig,
   150  			},
   151  			wantJSON: `[{"test-bb": {"check":true}}]`,
   152  		},
   153  		{
   154  			name: "OK config is nil",
   155  			bc: BalancerConfig{
   156  				Name:   testBalancerBuilderNotParserName,
   157  				Config: nil, // nil should be marshalled to an empty config "{}".
   158  			},
   159  			wantJSON: `[{"test-bb-not-parser": {}}]`,
   160  		},
   161  	}
   162  	for _, tt := range tests {
   163  		t.Run(tt.name, func(t *testing.T) {
   164  			b, err := tt.bc.MarshalJSON()
   165  			if err != nil {
   166  				t.Fatalf("failed to marshal: %v", err)
   167  			}
   168  
   169  			if str := string(b); str != tt.wantJSON {
   170  				t.Fatalf("got str %q, want %q", str, tt.wantJSON)
   171  			}
   172  
   173  			var bc BalancerConfig
   174  			if err := bc.UnmarshalJSON(b); err != nil {
   175  				t.Errorf("failed to unmarshal: %v", err)
   176  			}
   177  			if !cmp.Equal(bc, tt.bc) {
   178  				t.Errorf("diff: %v", cmp.Diff(bc, tt.bc))
   179  			}
   180  		})
   181  	}
   182  }