istio.io/istio@v0.0.0-20240520182934-d79c90f27776/operator/pkg/util/merge_iop_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 util
    16  
    17  import (
    18  	"os"
    19  	"path/filepath"
    20  	"testing"
    21  
    22  	"sigs.k8s.io/yaml"
    23  
    24  	meshconfig "istio.io/api/mesh/v1alpha1"
    25  	v1alpha12 "istio.io/api/operator/v1alpha1"
    26  	"istio.io/istio/operator/pkg/apis/istio/v1alpha1"
    27  	"istio.io/istio/pkg/config/mesh"
    28  	"istio.io/istio/pkg/test/env"
    29  	"istio.io/istio/pkg/util/protomarshal"
    30  )
    31  
    32  func TestOverlayIOP(t *testing.T) {
    33  	cases := []struct {
    34  		path string
    35  	}{
    36  		{
    37  			filepath.Join(env.IstioSrc, "manifests/profiles/default.yaml"),
    38  		},
    39  		{
    40  			filepath.Join(env.IstioSrc, "manifests/profiles/demo.yaml"),
    41  		},
    42  		{
    43  			filepath.Join("testdata", "overlay-iop.yaml"),
    44  		},
    45  	}
    46  
    47  	for _, tc := range cases {
    48  		t.Run(tc.path, func(t *testing.T) {
    49  			b, err := os.ReadFile(tc.path)
    50  			if err != nil {
    51  				t.Fatal(err)
    52  			}
    53  			// overlaying tree over itself exercises all paths for merging
    54  			if _, err := OverlayIOP(string(b), string(b)); err != nil {
    55  				t.Fatal(err)
    56  			}
    57  		})
    58  	}
    59  }
    60  
    61  // TestOverlayIOPExhaustiveness exhaustiveness check of `OverlayIOP`
    62  // Once some one add a new `Provider` in api, we should update `wellknownProviders` and
    63  // add to `meshConfigExtensionProvider`
    64  func TestOverlayIOPExhaustiveness(t *testing.T) {
    65  	wellknownProviders := map[string]struct{}{
    66  		"prometheus":            {},
    67  		"envoy_file_access_log": {},
    68  		"stackdriver":           {},
    69  		"envoy_otel_als":        {},
    70  		"envoy_ext_authz_http":  {},
    71  		"envoy_ext_authz_grpc":  {},
    72  		"zipkin":                {},
    73  		"lightstep":             {},
    74  		"datadog":               {},
    75  		"opencensus":            {},
    76  		"skywalking":            {},
    77  		"envoy_http_als":        {},
    78  		"envoy_tcp_als":         {},
    79  		"opentelemetry":         {},
    80  	}
    81  
    82  	unexpectedProviders := make([]string, 0)
    83  
    84  	msg := &meshconfig.MeshConfig_ExtensionProvider{}
    85  	pb := msg.ProtoReflect()
    86  	md := pb.Descriptor()
    87  
    88  	of := md.Oneofs().Get(0)
    89  	for i := 0; i < of.Fields().Len(); i++ {
    90  		o := of.Fields().Get(i)
    91  		n := string(o.Name())
    92  		if _, ok := wellknownProviders[n]; ok {
    93  			delete(wellknownProviders, n)
    94  		} else {
    95  			unexpectedProviders = append(unexpectedProviders, n)
    96  		}
    97  	}
    98  
    99  	if len(wellknownProviders) != 0 || len(unexpectedProviders) != 0 {
   100  		t.Errorf("unexpected provider not implemented in OverlayIOP, wellknownProviders: %v unexpectedProviders: %v", wellknownProviders, unexpectedProviders)
   101  		t.Fail()
   102  	}
   103  }
   104  
   105  func TestOverlayIOPDefaultMeshConfig(t *testing.T) {
   106  	// Transform default mesh config into map[string]interface{} for inclusion in IstioOperator.
   107  	m := mesh.DefaultMeshConfig()
   108  	my, err := protomarshal.ToJSONMap(m)
   109  	if err != nil {
   110  		t.Fatal(err)
   111  	}
   112  
   113  	iop := &v1alpha1.IstioOperator{
   114  		Spec: &v1alpha12.IstioOperatorSpec{
   115  			MeshConfig: MustStruct(my),
   116  		},
   117  	}
   118  
   119  	iy, err := yaml.Marshal(iop)
   120  	if err != nil {
   121  		t.Fatal(err)
   122  	}
   123  
   124  	// overlaying tree over itself exercises all paths for merging
   125  	if _, err := OverlayIOP(string(iy), string(iy)); err != nil {
   126  		t.Fatal(err)
   127  	}
   128  }
   129  
   130  func TestOverlayIOPIngressGatewayLabel(t *testing.T) {
   131  	l1, err := os.ReadFile("testdata/yaml/input/yaml_layer1.yaml")
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  	l2, err := os.ReadFile("testdata/yaml/input/yaml_layer2.yaml")
   136  	if err != nil {
   137  		t.Fatal(err)
   138  	}
   139  
   140  	if _, err := OverlayIOP(string(l1), string(l2)); err != nil {
   141  		t.Fatal(err)
   142  	}
   143  }