...

Source file src/sigs.k8s.io/kustomize/kyaml/resid/gvk_test.go

Documentation: sigs.k8s.io/kustomize/kyaml/resid

     1  // Copyright 2018 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package resid
     5  
     6  import (
     7  	"fmt"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  var equalsTests = []struct {
    14  	x1 Gvk
    15  	x2 Gvk
    16  }{
    17  	{Gvk{Group: "a", Version: "b", Kind: "c"},
    18  		Gvk{Group: "a", Version: "b", Kind: "c"}},
    19  	{Gvk{Version: "b", Kind: "c"},
    20  		Gvk{Version: "b", Kind: "c"}},
    21  	{Gvk{Kind: "c"},
    22  		Gvk{Kind: "c"}},
    23  }
    24  
    25  func TestEquals(t *testing.T) {
    26  	for _, hey := range equalsTests {
    27  		if !hey.x1.Equals(hey.x2) {
    28  			t.Fatalf("%v should equal %v", hey.x1, hey.x2)
    29  		}
    30  	}
    31  }
    32  
    33  var lessThanTests = []struct {
    34  	x1 Gvk
    35  	x2 Gvk
    36  }{
    37  	{Gvk{Group: "a", Version: "b", Kind: "CustomResourceDefinition"},
    38  		Gvk{Group: "a", Version: "b", Kind: "RoleBinding"}},
    39  	{Gvk{Group: "a", Version: "b", Kind: "Namespace"},
    40  		Gvk{Group: "a", Version: "b", Kind: "ClusterRole"}},
    41  	{Gvk{Group: "a", Version: "b", Kind: "a"},
    42  		Gvk{Group: "a", Version: "b", Kind: "b"}},
    43  	{Gvk{Group: "a", Version: "b", Kind: "Namespace"},
    44  		Gvk{Group: "a", Version: "c", Kind: "Namespace"}},
    45  	{Gvk{Group: "a", Version: "c", Kind: "Namespace"},
    46  		Gvk{Group: "b", Version: "c", Kind: "Namespace"}},
    47  	{Gvk{Group: "b", Version: "c", Kind: "Namespace"},
    48  		Gvk{Group: "a", Version: "c", Kind: "ClusterRole"}},
    49  	{Gvk{Group: "a", Version: "c", Kind: "Namespace"},
    50  		Gvk{Group: "a", Version: "b", Kind: "ClusterRole"}},
    51  	{Gvk{Group: "a", Version: "d", Kind: "Namespace"},
    52  		Gvk{Group: "b", Version: "c", Kind: "Namespace"}},
    53  	{Gvk{Group: "a", Version: "b", Kind: orderFirst[len(orderFirst)-1]},
    54  		Gvk{Group: "a", Version: "b", Kind: orderLast[0]}},
    55  	{Gvk{Group: "a", Version: "b", Kind: orderFirst[len(orderFirst)-1]},
    56  		Gvk{Group: "a", Version: "b", Kind: "CustomKindX"}},
    57  	{Gvk{Group: "a", Version: "b", Kind: "CustomKindX"},
    58  		Gvk{Group: "a", Version: "b", Kind: orderLast[0]}},
    59  	{Gvk{Group: "a", Version: "b", Kind: "CustomKindA"},
    60  		Gvk{Group: "a", Version: "b", Kind: "CustomKindB"}},
    61  	{Gvk{Group: "a", Version: "b", Kind: "CustomKindX"},
    62  		Gvk{Group: "a", Version: "b", Kind: "MutatingWebhookConfiguration"}},
    63  	{Gvk{Group: "a", Version: "b", Kind: "MutatingWebhookConfiguration"},
    64  		Gvk{Group: "a", Version: "b", Kind: "ValidatingWebhookConfiguration"}},
    65  	{Gvk{Group: "a", Version: "b", Kind: "CustomKindX"},
    66  		Gvk{Group: "a", Version: "b", Kind: "ValidatingWebhookConfiguration"}},
    67  	{Gvk{Group: "a", Version: "b", Kind: "APIService"},
    68  		Gvk{Group: "a", Version: "b", Kind: "ValidatingWebhookConfiguration"}},
    69  	{Gvk{Group: "a", Version: "b", Kind: "Service"},
    70  		Gvk{Group: "a", Version: "b", Kind: "APIService"}},
    71  	{Gvk{Group: "a", Version: "b", Kind: "Endpoints"},
    72  		Gvk{Group: "a", Version: "b", Kind: "Service"}},
    73  }
    74  
    75  func TestIsLessThan1(t *testing.T) {
    76  	for _, hey := range lessThanTests {
    77  		if !hey.x1.IsLessThan(hey.x2) {
    78  			t.Fatalf("%v should be less than %v", hey.x1, hey.x2)
    79  		}
    80  		if hey.x2.IsLessThan(hey.x1) {
    81  			t.Fatalf("%v should not be less than %v", hey.x2, hey.x1)
    82  		}
    83  	}
    84  }
    85  
    86  var stringTests = []struct {
    87  	x Gvk
    88  	s string
    89  	r string
    90  }{
    91  	{Gvk{}, "[noKind].[noVer].[noGrp]", ""},
    92  	{Gvk{Kind: "k"}, "k.[noVer].[noGrp]", "k"},
    93  	{Gvk{Version: "v"}, "[noKind].v.[noGrp]", "v"},
    94  	{Gvk{Version: "v", Kind: "k"}, "k.v.[noGrp]", "v_k"},
    95  	{Gvk{Group: "g"}, "[noKind].[noVer].g", "g"},
    96  	{Gvk{Group: "g", Kind: "k"}, "k.[noVer].g", "g_k"},
    97  	{Gvk{Group: "g", Version: "v"}, "[noKind].v.g", "g_v"},
    98  	{Gvk{Group: "g", Version: "v", Kind: "k"}, "k.v.g", "g_v_k"},
    99  	{Gvk{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRole", isClusterScoped: true},
   100  		"ClusterRole.v1.rbac.authorization.k8s.io", "rbac.authorization.k8s.io_v1_ClusterRole"},
   101  }
   102  
   103  func TestString(t *testing.T) {
   104  	for _, hey := range stringTests {
   105  		assert.Equal(t, hey.s, hey.x.String())
   106  	}
   107  }
   108  
   109  func TestGvkFromString(t *testing.T) {
   110  	for _, hey := range stringTests {
   111  		assert.Equal(t, hey.x, GvkFromString(hey.s))
   112  	}
   113  }
   114  
   115  func TestApiVersion(t *testing.T) {
   116  	for _, hey := range []struct {
   117  		x   Gvk
   118  		exp string
   119  	}{
   120  		{Gvk{}, ""},
   121  		{Gvk{Kind: "k"}, ""},
   122  		{Gvk{Version: "v"}, "v"},
   123  		{Gvk{Version: "v", Kind: "k"}, "v"},
   124  		{Gvk{Group: "g"}, "g/"},
   125  		{Gvk{Group: "g", Kind: "k"}, "g/"},
   126  		{Gvk{Group: "g", Version: "v"}, "g/v"},
   127  		{Gvk{Group: "g", Version: "v", Kind: "k"}, "g/v"},
   128  	} {
   129  		assert.Equal(t, hey.exp, hey.x.ApiVersion())
   130  	}
   131  }
   132  
   133  func BenchmarkApiVersion(b *testing.B) {
   134  	for i, bench := range []Gvk{
   135  		{Kind: "k"},
   136  		{Version: "v", Kind: "k"},
   137  		{Group: "g", Kind: "k"},
   138  		{Group: "g", Version: "v"},
   139  		{Group: "g", Version: "v", Kind: "k"},
   140  		{Group: "bitnami.com", Version: "v1alpha1", Kind: "SealedSecret"},
   141  	} {
   142  		b.Run(fmt.Sprintf("%d", i), func(b *testing.B) {
   143  			for i := 0; i < b.N; i++ {
   144  				_ = bench.ApiVersion()
   145  			}
   146  		})
   147  	}
   148  }
   149  
   150  func TestStringWoEmptyField(t *testing.T) {
   151  	for _, hey := range stringTests {
   152  		assert.Equal(t, hey.r, hey.x.StringWoEmptyField())
   153  	}
   154  }
   155  
   156  func TestParseGroupVersion(t *testing.T) {
   157  	tests := []struct {
   158  		input string
   159  		g     string
   160  		v     string
   161  	}{
   162  		{input: "", g: "", v: ""},
   163  		{input: "v1", g: "", v: "v1"},
   164  		{input: "apps/v1", g: "apps", v: "v1"},
   165  		{input: "/v1", g: "", v: "v1"},
   166  		{input: "apps/", g: "apps", v: ""},
   167  		{input: "/apps/", g: "", v: "apps/"},
   168  	}
   169  	for _, tc := range tests {
   170  		g, v := ParseGroupVersion(tc.input)
   171  		assert.Equal(t, tc.g, g, tc.input)
   172  		assert.Equal(t, tc.v, v, tc.input)
   173  	}
   174  }
   175  
   176  func TestSelectByGVK(t *testing.T) {
   177  	type testCase struct {
   178  		description string
   179  		in          Gvk
   180  		filter      *Gvk
   181  		expected    bool
   182  	}
   183  	testCases := []testCase{
   184  		{
   185  			description: "nil filter",
   186  			in:          Gvk{},
   187  			filter:      nil,
   188  			expected:    true,
   189  		},
   190  		{
   191  			description: "gvk matches",
   192  			in: Gvk{
   193  				Group:   "group1",
   194  				Version: "version1",
   195  				Kind:    "kind1",
   196  			},
   197  			filter: &Gvk{
   198  				Group:   "group1",
   199  				Version: "version1",
   200  				Kind:    "kind1",
   201  			},
   202  			expected: true,
   203  		},
   204  		{
   205  			description: "group doesn't matches",
   206  			in: Gvk{
   207  				Group:   "group1",
   208  				Version: "version1",
   209  				Kind:    "kind1",
   210  			},
   211  			filter: &Gvk{
   212  				Group:   "group2",
   213  				Version: "version1",
   214  				Kind:    "kind1",
   215  			},
   216  			expected: false,
   217  		},
   218  		{
   219  			description: "version doesn't matches",
   220  			in: Gvk{
   221  				Group:   "group1",
   222  				Version: "version1",
   223  				Kind:    "kind1",
   224  			},
   225  			filter: &Gvk{
   226  				Group:   "group1",
   227  				Version: "version2",
   228  				Kind:    "kind1",
   229  			},
   230  			expected: false,
   231  		},
   232  		{
   233  			description: "kind doesn't matches",
   234  			in: Gvk{
   235  				Group:   "group1",
   236  				Version: "version1",
   237  				Kind:    "kind1",
   238  			},
   239  			filter: &Gvk{
   240  				Group:   "group1",
   241  				Version: "version1",
   242  				Kind:    "kind2",
   243  			},
   244  			expected: false,
   245  		},
   246  		{
   247  			description: "no version in filter",
   248  			in: Gvk{
   249  				Group:   "group1",
   250  				Version: "version1",
   251  				Kind:    "kind1",
   252  			},
   253  			filter: &Gvk{
   254  				Group:   "group1",
   255  				Version: "",
   256  				Kind:    "kind1",
   257  			},
   258  			expected: true,
   259  		},
   260  		{
   261  			description: "only kind is set in filter",
   262  			in: Gvk{
   263  				Group:   "group1",
   264  				Version: "version1",
   265  				Kind:    "kind1",
   266  			},
   267  			filter: &Gvk{
   268  				Group:   "",
   269  				Version: "",
   270  				Kind:    "kind1",
   271  			},
   272  			expected: true,
   273  		},
   274  	}
   275  
   276  	for _, tc := range testCases {
   277  		filtered := tc.in.IsSelected(tc.filter)
   278  		assert.Equal(t, tc.expected, filtered, tc.description)
   279  	}
   280  }
   281  
   282  func TestIsClusterScoped(t *testing.T) {
   283  	testCases := []struct {
   284  		name            string
   285  		gvk             Gvk
   286  		isClusterScoped bool
   287  	}{
   288  		{
   289  			"deployment is namespaceable",
   290  			NewGvk("apps", "v1", "Deployment"),
   291  			false,
   292  		},
   293  		{
   294  			"clusterscoped resource",
   295  			NewGvk("", "v1", "Namespace"),
   296  			true,
   297  		},
   298  		{
   299  			"unknown resource (should default to namespaceable)",
   300  			NewGvk("example1.com", "v1", "BoatyMcBoatface"),
   301  			false,
   302  		},
   303  		{
   304  			"node is cluster scoped",
   305  			NewGvk("", "v1", "Node"),
   306  			true,
   307  		},
   308  		{
   309  			"Role is namespace scoped",
   310  			NewGvk("rbac.authorization.k8s.io", "v1", "Role"),
   311  			false,
   312  		},
   313  		{
   314  			"ClusterRole is cluster scoped",
   315  			NewGvk("rbac.authorization.k8s.io", "v1", "ClusterRole"),
   316  			true,
   317  		},
   318  		{
   319  			"ClusterRoleBinding is cluster scoped",
   320  			NewGvk("rbac.authorization.k8s.io", "v1", "ClusterRoleBinding"),
   321  			true,
   322  		},
   323  	}
   324  
   325  	for i := range testCases {
   326  		test := testCases[i]
   327  		t.Run(test.name, func(t *testing.T) {
   328  			assert.Equal(t, test.isClusterScoped, test.gvk.IsClusterScoped())
   329  		})
   330  	}
   331  }
   332  

View as plain text