istio.io/istio@v0.0.0-20240520182934-d79c90f27776/operator/pkg/name/name_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 name
    16  
    17  import (
    18  	"reflect"
    19  	"testing"
    20  
    21  	"sigs.k8s.io/yaml"
    22  
    23  	"istio.io/api/operator/v1alpha1"
    24  	"istio.io/istio/operator/pkg/tpath"
    25  	"istio.io/istio/operator/pkg/util"
    26  )
    27  
    28  func TestGetFromTreePath(t *testing.T) {
    29  	type args struct {
    30  		inputTree string
    31  		path      util.Path
    32  	}
    33  
    34  	tests := []struct {
    35  		name    string
    36  		args    args
    37  		want    string
    38  		found   bool
    39  		wantErr bool
    40  	}{
    41  		{
    42  			name: "found string node",
    43  			args: args{
    44  				inputTree: `
    45  k1: v1
    46  `,
    47  				path: util.Path{"k1"},
    48  			},
    49  			want: `
    50  v1
    51  `,
    52  			found:   true,
    53  			wantErr: false,
    54  		},
    55  		{
    56  			name: "found tree node",
    57  			args: args{
    58  				inputTree: `
    59  k1:
    60   k2: v2
    61  `,
    62  				path: util.Path{"k1"},
    63  			},
    64  			want: `
    65  k2: v2
    66  `,
    67  			found:   true,
    68  			wantErr: false,
    69  		},
    70  		{
    71  			name: "path is longer than tree depth, string node",
    72  			args: args{
    73  				inputTree: `
    74  k1:
    75    k2: v1
    76  `,
    77  				path: util.Path{"k1", "k2", "k3"},
    78  			},
    79  			want:    "",
    80  			found:   false,
    81  			wantErr: false,
    82  		},
    83  		{
    84  			name: "path not in map array tree",
    85  			args: args{
    86  				inputTree: `
    87  a:
    88    b:
    89    - name: n1
    90      value: v1
    91    - name: n2
    92      list:
    93      - v21
    94      - v22
    95  `,
    96  				path: util.Path{"a", "b", "unknown"},
    97  			},
    98  			want:    ``,
    99  			found:   false,
   100  			wantErr: false,
   101  		},
   102  	}
   103  	for _, tt := range tests {
   104  		t.Run(tt.name, func(t *testing.T) {
   105  			tree := make(map[string]any)
   106  			if err := yaml.Unmarshal([]byte(tt.args.inputTree), &tree); err != nil {
   107  				t.Fatal(err)
   108  			}
   109  			got, found, err := tpath.Find(tree, tt.args.path)
   110  			if (err != nil) != tt.wantErr {
   111  				t.Errorf("Find() error = %v, wantErr %v", err, tt.wantErr)
   112  				return
   113  			}
   114  
   115  			var wantTree any
   116  			if err := yaml.Unmarshal([]byte(tt.want), &wantTree); err != nil {
   117  				t.Fatal(err)
   118  			}
   119  
   120  			if !reflect.DeepEqual(got, wantTree) {
   121  				t.Errorf("Find() got = %v, want %v", got, tt.want)
   122  			}
   123  			if found != tt.found {
   124  				t.Errorf("Find() found = %v, want %v", found, tt.found)
   125  			}
   126  		})
   127  	}
   128  }
   129  
   130  func TestManifestMap_Consolidated(t *testing.T) {
   131  	tests := []struct {
   132  		name string
   133  		mm   ManifestMap
   134  		want map[string]string
   135  	}{
   136  		{
   137  			name: "consolidate output from manifest map",
   138  			mm: ManifestMap{
   139  				"key1": []string{"value1", "value2"},
   140  				"key2": []string{},
   141  			},
   142  			want: map[string]string{
   143  				"key1": "value1\n---\nvalue2\n---\n",
   144  				"key2": "",
   145  			},
   146  		},
   147  	}
   148  	for _, tt := range tests {
   149  		t.Run(tt.name, func(t *testing.T) {
   150  			if got := tt.mm.Consolidated(); !reflect.DeepEqual(got, tt.want) {
   151  				t.Errorf("ManifestMap.Consolidated() = %v, want %v", got, tt.want)
   152  			}
   153  		})
   154  	}
   155  }
   156  
   157  func TestMergeManifestSlices(t *testing.T) {
   158  	tests := []struct {
   159  		name      string
   160  		manifests []string
   161  		want      string
   162  	}{
   163  		{
   164  			name:      "merge manifest slices",
   165  			manifests: []string{"key1", "key2", "key3"},
   166  			want:      "key1\n---\nkey2\n---\nkey3",
   167  		},
   168  	}
   169  	for _, tt := range tests {
   170  		t.Run(tt.name, func(t *testing.T) {
   171  			if got := MergeManifestSlices(tt.manifests); got != tt.want {
   172  				t.Errorf("MergeManifestSlices() = %v, want %v", got, tt.want)
   173  			}
   174  		})
   175  	}
   176  }
   177  
   178  func TestManifestMap_String(t *testing.T) {
   179  	tests := []struct {
   180  		name  string
   181  		mm    ManifestMap
   182  		want1 string
   183  		want2 string
   184  	}{
   185  		{
   186  			name: "consolidate from manifest map",
   187  			mm: ManifestMap{
   188  				"key1": []string{"value1", "value2"},
   189  				"key2": []string{"value2", "value3"},
   190  			},
   191  			want1: "value1\n---\nvalue2\n---\nvalue2\n---\nvalue3\n---\n",
   192  			want2: "value2\n---\nvalue3\n---\nvalue1\n---\nvalue2\n---\n",
   193  		},
   194  	}
   195  	for _, tt := range tests {
   196  		t.Run(tt.name, func(t *testing.T) {
   197  			got := tt.mm.String()
   198  			if got != tt.want1 && got != tt.want2 {
   199  				t.Errorf("ManifestMap.String() = %v, want %v or %v", got, tt.want1, tt.want2)
   200  			}
   201  		})
   202  	}
   203  }
   204  
   205  func TestComponentName_IsGateway(t *testing.T) {
   206  	tests := []struct {
   207  		name string
   208  		cn   ComponentName
   209  		want bool
   210  	}{
   211  		{
   212  			name: "ComponentName is IngressGateways",
   213  			cn:   IngressComponentName,
   214  			want: true,
   215  		},
   216  		{
   217  			name: "ComponentName is EgressGateways",
   218  			cn:   EgressComponentName,
   219  			want: true,
   220  		},
   221  		{
   222  			name: "ComponentName is others",
   223  			cn:   CNIComponentName,
   224  			want: false,
   225  		},
   226  	}
   227  	for _, tt := range tests {
   228  		t.Run(tt.name, func(t *testing.T) {
   229  			if got := tt.cn.IsGateway(); got != tt.want {
   230  				t.Errorf("ComponentName.IsGateway() = %v, want %v", got, tt.want)
   231  			}
   232  		})
   233  	}
   234  }
   235  
   236  func TestTitleCase(t *testing.T) {
   237  	tests := []struct {
   238  		name string
   239  		n    ComponentName
   240  		want ComponentName
   241  	}{
   242  		{
   243  			name: "to upper title",
   244  			n:    "ingressGateways",
   245  			want: "IngressGateways",
   246  		},
   247  	}
   248  	for _, tt := range tests {
   249  		t.Run(tt.name, func(t *testing.T) {
   250  			if got := TitleCase(tt.n); got != tt.want {
   251  				t.Errorf("TitleCase() = %v, want %v", got, tt.want)
   252  			}
   253  		})
   254  	}
   255  }
   256  
   257  func TestUserFacingComponentName(t *testing.T) {
   258  	tests := []struct {
   259  		name string
   260  		n    ComponentName
   261  		want string
   262  	}{
   263  		{
   264  			name: "ComponentName is unknown",
   265  			n:    "foo",
   266  			want: "Unknown",
   267  		},
   268  		{
   269  			name: "ComponentName is  istio core",
   270  			n:    IstioBaseComponentName,
   271  			want: "Istio core",
   272  		},
   273  	}
   274  	for _, tt := range tests {
   275  		t.Run(tt.name, func(t *testing.T) {
   276  			if got := UserFacingComponentName(tt.n); got != tt.want {
   277  				t.Errorf("UserFacingComponentName() = %v, want %v", got, tt.want)
   278  			}
   279  		})
   280  	}
   281  }
   282  
   283  func TestNamespace(t *testing.T) {
   284  	type args struct {
   285  		componentName    ComponentName
   286  		controlPlaneSpec *v1alpha1.IstioOperatorSpec
   287  	}
   288  	tests := []struct {
   289  		name    string
   290  		args    args
   291  		want    string
   292  		wantErr bool
   293  	}{
   294  		{
   295  			name: "DefaultNamespace and componentNamespace are unset",
   296  			args: args{
   297  				componentName: CNIComponentName,
   298  				controlPlaneSpec: &v1alpha1.IstioOperatorSpec{
   299  					Hub: "docker.io",
   300  				},
   301  			},
   302  			want:    "",
   303  			wantErr: false,
   304  		},
   305  		{
   306  			name: "DefaultNamespace is set and componentNamespace in empty",
   307  			args: args{
   308  				componentName: CNIComponentName,
   309  				controlPlaneSpec: &v1alpha1.IstioOperatorSpec{
   310  					Hub:       "docker.io",
   311  					Namespace: "istio-system",
   312  					Components: &v1alpha1.IstioComponentSetSpec{
   313  						Cni: &v1alpha1.ComponentSpec{
   314  							Namespace: "",
   315  						},
   316  					},
   317  				},
   318  			},
   319  			want:    "istio-system",
   320  			wantErr: false,
   321  		},
   322  		{
   323  			name: "DefaultNamespace is set and componentNamespace is unset",
   324  			args: args{
   325  				componentName: CNIComponentName,
   326  				controlPlaneSpec: &v1alpha1.IstioOperatorSpec{
   327  					Hub:       "docker.io",
   328  					Namespace: "istio-system",
   329  					Components: &v1alpha1.IstioComponentSetSpec{
   330  						Cni: &v1alpha1.ComponentSpec{},
   331  					},
   332  				},
   333  			},
   334  			want:    "istio-system",
   335  			wantErr: false,
   336  		},
   337  		{
   338  			name: "DefaultNamespace and componentNamespace are set and not empty",
   339  			args: args{
   340  				componentName: CNIComponentName,
   341  				controlPlaneSpec: &v1alpha1.IstioOperatorSpec{
   342  					Hub:       "docker.io",
   343  					Namespace: "istio-system",
   344  					Components: &v1alpha1.IstioComponentSetSpec{
   345  						Cni: &v1alpha1.ComponentSpec{
   346  							Namespace: "istio-test",
   347  						},
   348  					},
   349  				},
   350  			},
   351  			want:    "istio-test",
   352  			wantErr: false,
   353  		},
   354  	}
   355  	for _, tt := range tests {
   356  		t.Run(tt.name, func(t *testing.T) {
   357  			got, err := Namespace(tt.args.componentName, tt.args.controlPlaneSpec)
   358  			if (err != nil) != tt.wantErr {
   359  				t.Errorf("Namespace() error = %v, wantErr %v", err, tt.wantErr)
   360  				return
   361  			}
   362  			if got != tt.want {
   363  				t.Errorf("Namespace() = %v, want %v", got, tt.want)
   364  			}
   365  		})
   366  	}
   367  }