sigs.k8s.io/cluster-api@v1.6.3/internal/util/ssa/filterintent_test.go (about)

     1  /*
     2  Copyright 2022 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 ssa
    18  
    19  import (
    20  	"testing"
    21  
    22  	. "github.com/onsi/gomega"
    23  
    24  	"sigs.k8s.io/cluster-api/internal/contract"
    25  )
    26  
    27  func Test_filterNotAllowedPaths(t *testing.T) {
    28  	tests := []struct {
    29  		name      string
    30  		ctx       *FilterIntentInput
    31  		wantValue map[string]interface{}
    32  	}{
    33  		{
    34  			name: "Filters out not allowed paths",
    35  			ctx: &FilterIntentInput{
    36  				Path: contract.Path{},
    37  				Value: map[string]interface{}{
    38  					"apiVersion": "foo.bar/v1",
    39  					"kind":       "Foo",
    40  					"metadata": map[string]interface{}{
    41  						"name":      "foo",
    42  						"namespace": "bar",
    43  						"labels": map[string]interface{}{
    44  							"foo": "123",
    45  						},
    46  						"annotations": map[string]interface{}{
    47  							"foo": "123",
    48  						},
    49  						"resourceVersion": "123",
    50  					},
    51  					"spec": map[string]interface{}{
    52  						"foo": "123",
    53  					},
    54  					"status": map[string]interface{}{
    55  						"foo": "123",
    56  					},
    57  				},
    58  				ShouldFilter: IsPathNotAllowed(
    59  					[]contract.Path{ // NOTE: we are dropping everything not in this list
    60  						{"apiVersion"},
    61  						{"kind"},
    62  						{"metadata", "name"},
    63  						{"metadata", "namespace"},
    64  						{"metadata", "labels"},
    65  						{"metadata", "annotations"},
    66  						{"spec"},
    67  					},
    68  				),
    69  			},
    70  			wantValue: map[string]interface{}{
    71  				"apiVersion": "foo.bar/v1",
    72  				"kind":       "Foo",
    73  				"metadata": map[string]interface{}{
    74  					"name":      "foo",
    75  					"namespace": "bar",
    76  					"labels": map[string]interface{}{
    77  						"foo": "123",
    78  					},
    79  					"annotations": map[string]interface{}{
    80  						"foo": "123",
    81  					},
    82  					// metadata.resourceVersion filtered out
    83  				},
    84  				"spec": map[string]interface{}{
    85  					"foo": "123",
    86  				},
    87  				// status filtered out
    88  			},
    89  		},
    90  		{
    91  			name: "Cleanup empty maps",
    92  			ctx: &FilterIntentInput{
    93  				Path: contract.Path{},
    94  				Value: map[string]interface{}{
    95  					"spec": map[string]interface{}{
    96  						"foo": "123",
    97  					},
    98  				},
    99  				ShouldFilter: IsPathNotAllowed(
   100  					[]contract.Path{}, // NOTE: we are filtering out everything not in this list (everything)
   101  				),
   102  			},
   103  			wantValue: map[string]interface{}{
   104  				// we are filtering out spec.foo and then spec given that it is an empty map
   105  			},
   106  		},
   107  	}
   108  	for _, tt := range tests {
   109  		t.Run(tt.name, func(t *testing.T) {
   110  			g := NewWithT(t)
   111  
   112  			FilterIntent(tt.ctx)
   113  
   114  			g.Expect(tt.ctx.Value).To(BeComparableTo(tt.wantValue))
   115  		})
   116  	}
   117  }
   118  
   119  func Test_filterIgnoredPaths(t *testing.T) {
   120  	tests := []struct {
   121  		name      string
   122  		ctx       *FilterIntentInput
   123  		wantValue map[string]interface{}
   124  	}{
   125  		{
   126  			name: "Filters out ignore paths",
   127  			ctx: &FilterIntentInput{
   128  				Path: contract.Path{},
   129  				Value: map[string]interface{}{
   130  					"spec": map[string]interface{}{
   131  						"foo": "bar",
   132  						"controlPlaneEndpoint": map[string]interface{}{
   133  							"host": "foo-changed",
   134  							"port": "123-changed",
   135  						},
   136  					},
   137  				},
   138  				ShouldFilter: IsPathIgnored(
   139  					[]contract.Path{
   140  						{"spec", "controlPlaneEndpoint"},
   141  					},
   142  				),
   143  			},
   144  			wantValue: map[string]interface{}{
   145  				"spec": map[string]interface{}{
   146  					"foo": "bar",
   147  					// spec.controlPlaneEndpoint filtered out
   148  				},
   149  			},
   150  		},
   151  		{
   152  			name: "Cleanup empty maps",
   153  			ctx: &FilterIntentInput{
   154  				Path: contract.Path{},
   155  				Value: map[string]interface{}{
   156  					"spec": map[string]interface{}{
   157  						"foo": "123",
   158  					},
   159  				},
   160  				ShouldFilter: IsPathIgnored(
   161  					[]contract.Path{
   162  						{"spec", "foo"},
   163  					},
   164  				),
   165  			},
   166  			wantValue: map[string]interface{}{
   167  				// we are filtering out spec.foo and then spec given that it is an empty map
   168  			},
   169  		},
   170  		{
   171  			name: "Cleanup empty nested maps",
   172  			ctx: &FilterIntentInput{
   173  				Path: contract.Path{},
   174  				Value: map[string]interface{}{
   175  					"spec": map[string]interface{}{
   176  						"bar": map[string]interface{}{
   177  							"foo": "123",
   178  						},
   179  					},
   180  				},
   181  				ShouldFilter: IsPathIgnored(
   182  					[]contract.Path{
   183  						{"spec", "bar", "foo"},
   184  					},
   185  				),
   186  			},
   187  			wantValue: map[string]interface{}{
   188  				// we are filtering out spec.bar.foo and then spec given that it is an empty map
   189  			},
   190  		},
   191  	}
   192  	for _, tt := range tests {
   193  		t.Run(tt.name, func(t *testing.T) {
   194  			g := NewWithT(t)
   195  
   196  			FilterIntent(tt.ctx)
   197  
   198  			g.Expect(tt.ctx.Value).To(BeComparableTo(tt.wantValue))
   199  		})
   200  	}
   201  }