1
18
19 package serviceconfig
20
21 import (
22 "encoding/json"
23 "fmt"
24 "testing"
25
26 "github.com/google/go-cmp/cmp"
27 "google.golang.org/grpc/balancer"
28 externalserviceconfig "google.golang.org/grpc/serviceconfig"
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
88
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,
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 }
183
View as plain text