sigs.k8s.io/cluster-api@v1.7.1/internal/contract/infrastructure_cluster_test.go (about)

     1  /*
     2  Copyright 2021 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package contract
    18  
    19  import (
    20  	"testing"
    21  
    22  	. "github.com/onsi/gomega"
    23  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    24  
    25  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    26  )
    27  
    28  func TestInfrastructureCluster(t *testing.T) {
    29  	obj := &unstructured.Unstructured{Object: map[string]interface{}{}}
    30  
    31  	t.Run("Manages status.ready", func(t *testing.T) {
    32  		g := NewWithT(t)
    33  
    34  		g.Expect(InfrastructureCluster().Ready().Path()).To(Equal(Path{"status", "ready"}))
    35  
    36  		err := InfrastructureCluster().Ready().Set(obj, true)
    37  		g.Expect(err).ToNot(HaveOccurred())
    38  
    39  		got, err := InfrastructureCluster().Ready().Get(obj)
    40  		g.Expect(err).ToNot(HaveOccurred())
    41  		g.Expect(got).ToNot(BeNil())
    42  		g.Expect(*got).To(BeTrue())
    43  	})
    44  	t.Run("Manages optional status.failureReason", func(t *testing.T) {
    45  		g := NewWithT(t)
    46  
    47  		g.Expect(InfrastructureCluster().FailureReason().Path()).To(Equal(Path{"status", "failureReason"}))
    48  
    49  		err := InfrastructureCluster().FailureReason().Set(obj, "fake-reason")
    50  		g.Expect(err).ToNot(HaveOccurred())
    51  
    52  		got, err := InfrastructureCluster().FailureReason().Get(obj)
    53  		g.Expect(err).ToNot(HaveOccurred())
    54  		g.Expect(got).ToNot(BeNil())
    55  		g.Expect(*got).To(Equal("fake-reason"))
    56  	})
    57  	t.Run("Manages optional status.failureMessage", func(t *testing.T) {
    58  		g := NewWithT(t)
    59  
    60  		g.Expect(InfrastructureCluster().FailureMessage().Path()).To(Equal(Path{"status", "failureMessage"}))
    61  
    62  		err := InfrastructureCluster().FailureMessage().Set(obj, "fake-message")
    63  		g.Expect(err).ToNot(HaveOccurred())
    64  
    65  		got, err := InfrastructureCluster().FailureMessage().Get(obj)
    66  		g.Expect(err).ToNot(HaveOccurred())
    67  		g.Expect(got).ToNot(BeNil())
    68  		g.Expect(*got).To(Equal("fake-message"))
    69  	})
    70  	t.Run("Manages optional status.failureDomains", func(t *testing.T) {
    71  		g := NewWithT(t)
    72  
    73  		failureDomains := clusterv1.FailureDomains{
    74  			"domain1": clusterv1.FailureDomainSpec{
    75  				ControlPlane: true,
    76  				Attributes: map[string]string{
    77  					"key1": "value1",
    78  					"key2": "value2",
    79  				},
    80  			},
    81  			"domain2": clusterv1.FailureDomainSpec{
    82  				ControlPlane: false,
    83  				Attributes: map[string]string{
    84  					"key3": "value3",
    85  					"key4": "value4",
    86  				},
    87  			},
    88  		}
    89  		g.Expect(InfrastructureCluster().FailureDomains().Path()).To(Equal(Path{"status", "failureDomains"}))
    90  
    91  		err := InfrastructureCluster().FailureDomains().Set(obj, failureDomains)
    92  		g.Expect(err).ToNot(HaveOccurred())
    93  
    94  		got, err := InfrastructureCluster().FailureDomains().Get(obj)
    95  		g.Expect(err).ToNot(HaveOccurred())
    96  		g.Expect(got).ToNot(BeNil())
    97  		g.Expect(*got).To(BeComparableTo(failureDomains))
    98  	})
    99  }
   100  
   101  func TestInfrastructureClusterControlPlaneEndpoint(t *testing.T) {
   102  	tests := []struct {
   103  		name                  string
   104  		infrastructureCluster *unstructured.Unstructured
   105  		want                  []Path
   106  		expectErr             bool
   107  	}{
   108  		{
   109  			name: "No ignore paths when controlPlaneEndpoint is not set",
   110  			infrastructureCluster: &unstructured.Unstructured{
   111  				Object: map[string]interface{}{
   112  					"spec": map[string]interface{}{
   113  						"server": "1.2.3.4",
   114  					},
   115  				},
   116  			},
   117  			want: nil,
   118  		},
   119  		{
   120  			name: "No ignore paths when controlPlaneEndpoint is nil",
   121  			infrastructureCluster: &unstructured.Unstructured{
   122  				Object: map[string]interface{}{
   123  					"spec": map[string]interface{}{
   124  						"controlPlaneEndpoint": nil,
   125  					},
   126  				},
   127  			},
   128  			want: nil,
   129  		},
   130  		{
   131  			name: "No ignore paths when controlPlaneEndpoint is an empty object",
   132  			infrastructureCluster: &unstructured.Unstructured{
   133  				Object: map[string]interface{}{
   134  					"spec": map[string]interface{}{
   135  						"controlPlaneEndpoint": map[string]interface{}{},
   136  					},
   137  				},
   138  			},
   139  			want: nil,
   140  		},
   141  		{
   142  			name: "Don't ignore host when controlPlaneEndpoint.host is set",
   143  			infrastructureCluster: &unstructured.Unstructured{
   144  				Object: map[string]interface{}{
   145  					"spec": map[string]interface{}{
   146  						"controlPlaneEndpoint": map[string]interface{}{
   147  							"host": "example.com",
   148  						},
   149  					},
   150  				},
   151  			},
   152  			want: nil,
   153  		},
   154  		{
   155  			name: "Ignore host when controlPlaneEndpoint.host is set to its zero value",
   156  			infrastructureCluster: &unstructured.Unstructured{
   157  				Object: map[string]interface{}{
   158  					"spec": map[string]interface{}{
   159  						"controlPlaneEndpoint": map[string]interface{}{
   160  							"host": "",
   161  						},
   162  					},
   163  				},
   164  			},
   165  			want: []Path{
   166  				{"spec", "controlPlaneEndpoint", "host"},
   167  			},
   168  		},
   169  		{
   170  			name: "Don't ignore port when controlPlaneEndpoint.port is set",
   171  			infrastructureCluster: &unstructured.Unstructured{
   172  				Object: map[string]interface{}{
   173  					"spec": map[string]interface{}{
   174  						"controlPlaneEndpoint": map[string]interface{}{
   175  							"port": int64(6443),
   176  						},
   177  					},
   178  				},
   179  			},
   180  			want: nil,
   181  		},
   182  		{
   183  			name: "Ignore port when controlPlaneEndpoint.port is set to its zero value",
   184  			infrastructureCluster: &unstructured.Unstructured{
   185  				Object: map[string]interface{}{
   186  					"spec": map[string]interface{}{
   187  						"controlPlaneEndpoint": map[string]interface{}{
   188  							"port": int64(0),
   189  						},
   190  					},
   191  				},
   192  			},
   193  			want: []Path{
   194  				{"spec", "controlPlaneEndpoint", "port"},
   195  			},
   196  		},
   197  		{
   198  			name: "Ignore host and port when controlPlaneEndpoint host and port are set to their zero values",
   199  			infrastructureCluster: &unstructured.Unstructured{
   200  				Object: map[string]interface{}{
   201  					"spec": map[string]interface{}{
   202  						"controlPlaneEndpoint": map[string]interface{}{
   203  							"host": "",
   204  							"port": int64(0),
   205  						},
   206  					},
   207  				},
   208  			},
   209  			want: []Path{
   210  				{"spec", "controlPlaneEndpoint", "host"},
   211  				{"spec", "controlPlaneEndpoint", "port"},
   212  			},
   213  		},
   214  		{
   215  			name: "Ignore host when controlPlaneEndpoint host is to its zero values, even if port is set",
   216  			infrastructureCluster: &unstructured.Unstructured{
   217  				Object: map[string]interface{}{
   218  					"spec": map[string]interface{}{
   219  						"controlPlaneEndpoint": map[string]interface{}{
   220  							"host": "",
   221  							"port": int64(6443),
   222  						},
   223  					},
   224  				},
   225  			},
   226  			want: []Path{
   227  				{"spec", "controlPlaneEndpoint", "host"},
   228  			},
   229  		},
   230  		{
   231  			name: "Ignore port when controlPlaneEndpoint port is to its zero values, even if host is set",
   232  			infrastructureCluster: &unstructured.Unstructured{
   233  				Object: map[string]interface{}{
   234  					"spec": map[string]interface{}{
   235  						"controlPlaneEndpoint": map[string]interface{}{
   236  							"host": "example.com",
   237  							"port": int64(0),
   238  						},
   239  					},
   240  				},
   241  			},
   242  			want: []Path{
   243  				{"spec", "controlPlaneEndpoint", "port"},
   244  			},
   245  		},
   246  	}
   247  
   248  	for _, tt := range tests {
   249  		t.Run(tt.name, func(t *testing.T) {
   250  			g := NewWithT(t)
   251  
   252  			got, err := InfrastructureCluster().IgnorePaths(tt.infrastructureCluster)
   253  
   254  			if tt.expectErr {
   255  				g.Expect(err).To(HaveOccurred())
   256  				return
   257  			}
   258  			g.Expect(err).ToNot(HaveOccurred())
   259  			g.Expect(got).To(Equal(tt.want))
   260  		})
   261  	}
   262  }