istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/test/framework/components/cluster/clusterboot/factory_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 clusterboot
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/google/go-cmp/cmp"
    21  	"github.com/google/go-cmp/cmp/cmpopts"
    22  
    23  	"istio.io/istio/pkg/test/framework/components/cluster"
    24  	"istio.io/istio/pkg/test/framework/config"
    25  )
    26  
    27  func TestBuild(t *testing.T) {
    28  	tests := []struct {
    29  		config  cluster.Config
    30  		cluster cluster.FakeCluster
    31  	}{
    32  		{
    33  			config: cluster.Config{Kind: cluster.Fake, Name: "auto-fill-primary", Network: "network-0"},
    34  			cluster: cluster.FakeCluster{
    35  				Topology: cluster.Topology{
    36  					ClusterName: "auto-fill-primary",
    37  					ClusterKind: cluster.Fake,
    38  					// The primary and config clusters should match the cluster name when not specified
    39  					PrimaryClusterName: "auto-fill-primary",
    40  					ConfigClusterName:  "auto-fill-primary",
    41  					Network:            "network-0",
    42  					ConfigMetadata:     config.Map{},
    43  				},
    44  			},
    45  		},
    46  		{
    47  			config: cluster.Config{Kind: cluster.Fake, Name: "auto-fill-remote", PrimaryClusterName: "auto-fill-primary"},
    48  			cluster: cluster.FakeCluster{
    49  				Topology: cluster.Topology{
    50  					ClusterName:        "auto-fill-remote",
    51  					ClusterKind:        cluster.Fake,
    52  					PrimaryClusterName: "auto-fill-primary",
    53  					// The config cluster should match the primary cluster when not specified
    54  					ConfigClusterName: "auto-fill-primary",
    55  					Index:             1,
    56  					ConfigMetadata:    config.Map{},
    57  				},
    58  			},
    59  		},
    60  		{
    61  			config: cluster.Config{Kind: cluster.Fake, Name: "external-istiod", ConfigClusterName: "remote-config"},
    62  			cluster: cluster.FakeCluster{
    63  				Topology: cluster.Topology{
    64  					ClusterName:        "external-istiod",
    65  					ClusterKind:        cluster.Fake,
    66  					PrimaryClusterName: "external-istiod",
    67  					ConfigClusterName:  "remote-config",
    68  					Index:              2,
    69  					ConfigMetadata:     config.Map{},
    70  				},
    71  			},
    72  		},
    73  		{
    74  			config: cluster.Config{
    75  				Name:               "remote-config",
    76  				Kind:               cluster.Fake,
    77  				PrimaryClusterName: "external-istiod",
    78  				ConfigClusterName:  "remote-config",
    79  			},
    80  			cluster: cluster.FakeCluster{
    81  				Topology: cluster.Topology{
    82  					ClusterName: "remote-config",
    83  					ClusterKind: cluster.Fake,
    84  					// Explicitly specified in config, should be copied exactly
    85  					PrimaryClusterName: "external-istiod",
    86  					ConfigClusterName:  "remote-config",
    87  					Index:              3,
    88  					ConfigMetadata:     config.Map{},
    89  				},
    90  			},
    91  		},
    92  	}
    93  	var clusters cluster.Clusters
    94  	t.Run("build", func(t *testing.T) {
    95  		factory := NewFactory()
    96  		for _, tc := range tests {
    97  			factory = factory.With(tc.config)
    98  		}
    99  		var err error
   100  		clusters, err = factory.Build()
   101  		if err != nil {
   102  			t.Fatal(err)
   103  		}
   104  		if len(clusters) != len(tests) {
   105  			t.Errorf("expected %d clusters but built %d", len(tests), len(clusters))
   106  		}
   107  	})
   108  	for _, tc := range tests {
   109  		t.Run("built "+tc.config.Name, func(t *testing.T) {
   110  			built := *clusters.GetByName(tc.config.Name).(*cluster.FakeCluster)
   111  			// don't compare these
   112  			built.AllClusters = nil
   113  			built.Version = nil
   114  			built.CLIClient = nil
   115  			if diff := cmp.Diff(built, tc.cluster, cmpopts.IgnoreUnexported(cluster.FakeCluster{})); diff != "" {
   116  				t.Fatal(diff)
   117  			}
   118  		})
   119  	}
   120  }
   121  
   122  func TestValidation(t *testing.T) {
   123  	tests := map[string][]cluster.Config{
   124  		"empty kind": {
   125  			{Name: "no-kind"},
   126  		},
   127  		"empty name": {
   128  			{Kind: cluster.Fake},
   129  		},
   130  		"duplicate name": {
   131  			{Kind: cluster.Fake, Name: "dupe"},
   132  			{Kind: cluster.Fake, Name: "dupe"},
   133  		},
   134  		"non-existent primary": {
   135  			{Kind: cluster.Fake, Name: "no-primary", PrimaryClusterName: "does-not-exist"},
   136  		},
   137  		"non-existent config": {
   138  			{Kind: cluster.Fake, Name: "no-primary", ConfigClusterName: "does-not-exist"},
   139  		},
   140  		"vm without kube primary": {
   141  			{Kind: cluster.StaticVM, Name: "vm", Meta: config.Map{"deployments": []any{
   142  				config.Map{
   143  					"service": "vm", "namespace": "echo", "instances": []config.Map{{"ip": "1.2.3.4"}},
   144  				},
   145  			}}},
   146  		},
   147  	}
   148  
   149  	for name, tc := range tests {
   150  		t.Run(name, func(t *testing.T) {
   151  			_, err := NewFactory().With(tc...).Build()
   152  			if err == nil {
   153  				t.Fatal("expected err but got nil")
   154  			}
   155  		})
   156  	}
   157  }