istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/model/conversion_test.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package model_test 16 17 import ( 18 "fmt" 19 "reflect" 20 "strings" 21 "testing" 22 23 "github.com/davecgh/go-spew/spew" 24 25 meshconfig "istio.io/api/mesh/v1alpha1" 26 networking "istio.io/api/networking/v1alpha3" 27 "istio.io/istio/pilot/pkg/config/kube/crd" 28 "istio.io/istio/pkg/config/schema/collections" 29 "istio.io/istio/pkg/test/util/assert" 30 "istio.io/istio/pkg/util/protomarshal" 31 ) 32 33 func TestApplyJSON(t *testing.T) { 34 cases := []struct { 35 in string 36 want *meshconfig.MeshConfig 37 wantErr bool 38 }{ 39 { 40 in: `{"enableTracing": true}`, 41 want: &meshconfig.MeshConfig{EnableTracing: true}, 42 }, 43 { 44 in: `{"enableTracing": true, "unknownField": "unknownValue"}`, 45 want: &meshconfig.MeshConfig{EnableTracing: true}, 46 }, 47 } 48 for i, c := range cases { 49 t.Run(fmt.Sprintf("[%v]", i), func(tt *testing.T) { 50 var got meshconfig.MeshConfig 51 err := protomarshal.ApplyJSON(c.in, &got) 52 if err != nil { 53 if !c.wantErr { 54 tt.Fatalf("got unexpected error: %v", err) 55 } 56 } else { 57 if c.wantErr { 58 tt.Fatal("unexpected success, expected error") 59 } 60 assert.Equal(t, &got, c.want) 61 } 62 }) 63 } 64 } 65 66 func TestProtoSchemaConversions(t *testing.T) { 67 destinationRuleSchema := collections.DestinationRule 68 69 msg := &networking.DestinationRule{ 70 Host: "something.svc.local", 71 TrafficPolicy: &networking.TrafficPolicy{ 72 LoadBalancer: &networking.LoadBalancerSettings{ 73 LbPolicy: &networking.LoadBalancerSettings_Simple{}, 74 }, 75 }, 76 Subsets: []*networking.Subset{ 77 { 78 Name: "foo", 79 Labels: map[string]string{ 80 "test": "label", 81 }, 82 }, 83 }, 84 } 85 86 wantJSON := ` 87 { 88 "host":"something.svc.local", 89 "trafficPolicy": { 90 "loadBalancer":{"simple":"UNSPECIFIED"} 91 }, 92 "subsets": [ 93 {"name":"foo","labels":{"test":"label"}} 94 ] 95 }` 96 97 wantYAML := `host: something.svc.local 98 subsets: 99 - labels: 100 test: label 101 name: foo 102 trafficPolicy: 103 loadBalancer: 104 simple: UNSPECIFIED 105 ` 106 107 wantJSONMap := map[string]any{ 108 "host": "something.svc.local", 109 "trafficPolicy": map[string]any{ 110 "loadBalancer": map[string]any{ 111 "simple": "UNSPECIFIED", 112 }, 113 }, 114 "subsets": []any{ 115 map[string]any{ 116 "name": "foo", 117 "labels": map[string]any{ 118 "test": "label", 119 }, 120 }, 121 }, 122 } 123 124 badSchema := schemaFor("bad", "bad-name") 125 if _, err := crd.FromYAML(badSchema, wantYAML); err == nil { 126 t.Errorf("FromYAML should have failed using Schema with bad MessageName") 127 } 128 129 gotJSON, err := protomarshal.ToJSON(msg) 130 if err != nil { 131 t.Errorf("ToJSON failed: %v", err) 132 } 133 if gotJSON != strings.Join(strings.Fields(wantJSON), "") { 134 t.Errorf("ToJSON failed: got %s, want %s", gotJSON, wantJSON) 135 } 136 137 if _, err = protomarshal.ToJSON(nil); err == nil { 138 t.Error("should produce an error") 139 } 140 141 gotFromJSON, err := crd.FromJSON(destinationRuleSchema, wantJSON) 142 if err != nil { 143 t.Errorf("FromJSON failed: %v", err) 144 } 145 if !reflect.DeepEqual(gotFromJSON, msg) { 146 t.Errorf("FromYAML failed: got %+v want %+v", spew.Sdump(gotFromJSON), spew.Sdump(msg)) 147 } 148 149 gotYAML, err := protomarshal.ToYAML(msg) 150 if err != nil { 151 t.Errorf("ToYAML failed: %v", err) 152 } 153 if !reflect.DeepEqual(gotYAML, wantYAML) { 154 t.Errorf("ToYAML failed: got %+v want %+v", spew.Sdump(gotYAML), spew.Sdump(wantYAML)) 155 } 156 157 if _, err = protomarshal.ToYAML(nil); err == nil { 158 t.Error("should produce an error") 159 } 160 161 gotFromYAML, err := crd.FromYAML(destinationRuleSchema, wantYAML) 162 if err != nil { 163 t.Errorf("FromYAML failed: %v", err) 164 } 165 if !reflect.DeepEqual(gotFromYAML, msg) { 166 t.Errorf("FromYAML failed: got %+v want %+v", spew.Sdump(gotFromYAML), spew.Sdump(msg)) 167 } 168 169 if _, err = crd.FromYAML(destinationRuleSchema, ":"); err == nil { 170 t.Errorf("should produce an error") 171 } 172 173 gotJSONMap, err := protomarshal.ToJSONMap(msg) 174 if err != nil { 175 t.Errorf("ToJSONMap failed: %v", err) 176 } 177 if !reflect.DeepEqual(gotJSONMap, wantJSONMap) { 178 t.Errorf("ToJSONMap failed: \ngot %vwant %v", spew.Sdump(gotJSONMap), spew.Sdump(wantJSONMap)) 179 } 180 181 if _, err = protomarshal.ToJSONMap(nil); err == nil { 182 t.Error("should produce an error") 183 } 184 185 gotFromJSONMap, err := crd.FromJSONMap(destinationRuleSchema, wantJSONMap) 186 if err != nil { 187 t.Errorf("FromJSONMap failed: %v", err) 188 } 189 if !reflect.DeepEqual(gotFromJSONMap, msg) { 190 t.Errorf("FromJSONMap failed: got %+v want %+v", spew.Sdump(gotFromJSONMap), spew.Sdump(msg)) 191 } 192 193 if _, err = crd.FromJSONMap(destinationRuleSchema, 1); err == nil { 194 t.Error("should produce an error") 195 } 196 if _, err = crd.FromJSONMap(destinationRuleSchema, ":"); err == nil { 197 t.Errorf("should produce an error") 198 } 199 }