...

Source file src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/maplist_test.go

Documentation: k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel

     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 cel
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	"k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
    24  )
    25  
    26  func TestMapList(t *testing.T) {
    27  	for _, tc := range []struct {
    28  		name          string
    29  		sts           schema.Structural
    30  		items         []interface{}
    31  		warmUpQueries []interface{}
    32  		query         interface{}
    33  		expected      interface{}
    34  	}{
    35  		{
    36  			name: "default list type",
    37  			sts: schema.Structural{
    38  				Generic: schema.Generic{
    39  					Type: "array",
    40  				},
    41  			},
    42  			query:    map[string]interface{}{},
    43  			expected: nil,
    44  		},
    45  		{
    46  			name: "non list type",
    47  			sts: schema.Structural{
    48  				Generic: schema.Generic{
    49  					Type: "map",
    50  				},
    51  			},
    52  			query:    map[string]interface{}{},
    53  			expected: nil,
    54  		},
    55  		{
    56  			name: "non-map list type",
    57  			sts: schema.Structural{
    58  				Generic: schema.Generic{
    59  					Type: "array",
    60  				},
    61  				Extensions: schema.Extensions{
    62  					XListType: &listTypeSet,
    63  				},
    64  			},
    65  			query:    map[string]interface{}{},
    66  			expected: nil,
    67  		},
    68  		{
    69  			name: "no keys",
    70  			sts: schema.Structural{
    71  				Generic: schema.Generic{
    72  					Type: "array",
    73  				},
    74  				Extensions: schema.Extensions{
    75  					XListType: &listTypeMap,
    76  				},
    77  			},
    78  			query:    map[string]interface{}{},
    79  			expected: nil,
    80  		},
    81  		{
    82  			name: "single key",
    83  			sts: schema.Structural{
    84  				Generic: schema.Generic{
    85  					Type: "array",
    86  				},
    87  				Extensions: schema.Extensions{
    88  					XListType:    &listTypeMap,
    89  					XListMapKeys: []string{"k"},
    90  				},
    91  			},
    92  			items: []interface{}{
    93  				map[string]interface{}{
    94  					"k":  "a",
    95  					"v1": "a",
    96  				},
    97  				map[string]interface{}{
    98  					"k":  "b",
    99  					"v1": "b",
   100  				},
   101  			},
   102  			query: map[string]interface{}{
   103  				"k":  "b",
   104  				"v1": "B",
   105  			},
   106  			expected: map[string]interface{}{
   107  				"k":  "b",
   108  				"v1": "b",
   109  			},
   110  		},
   111  		{
   112  			name: "single key ignoring non-map query",
   113  			sts: schema.Structural{
   114  				Generic: schema.Generic{
   115  					Type: "array",
   116  				},
   117  				Extensions: schema.Extensions{
   118  					XListType:    &listTypeMap,
   119  					XListMapKeys: []string{"k"},
   120  				},
   121  			},
   122  			items: []interface{}{
   123  				map[string]interface{}{
   124  					"k":  "a",
   125  					"v1": "a",
   126  				},
   127  			},
   128  			query:    42,
   129  			expected: nil,
   130  		},
   131  		{
   132  			name: "single key ignoring unkeyable query",
   133  			sts: schema.Structural{
   134  				Generic: schema.Generic{
   135  					Type: "array",
   136  				},
   137  				Extensions: schema.Extensions{
   138  					XListType:    &listTypeMap,
   139  					XListMapKeys: []string{"k"},
   140  				},
   141  			},
   142  			items: []interface{}{
   143  				map[string]interface{}{
   144  					"k":  "a",
   145  					"v1": "a",
   146  				},
   147  			},
   148  			query: map[string]interface{}{
   149  				"k": map[string]interface{}{
   150  					"keys": "must",
   151  					"be":   "scalars",
   152  				},
   153  				"v1": "A",
   154  			},
   155  			expected: nil,
   156  		},
   157  		{
   158  			name: "ignores item of invalid type",
   159  			sts: schema.Structural{
   160  				Generic: schema.Generic{
   161  					Type: "array",
   162  				},
   163  				Extensions: schema.Extensions{
   164  					XListType:    &listTypeMap,
   165  					XListMapKeys: []string{"k"},
   166  				},
   167  			},
   168  			items: []interface{}{
   169  				map[string]interface{}{
   170  					"k":  "a",
   171  					"v1": "a",
   172  				},
   173  				5,
   174  			},
   175  			query: map[string]interface{}{
   176  				"k":  "a",
   177  				"v1": "A",
   178  			},
   179  			expected: map[string]interface{}{
   180  				"k":  "a",
   181  				"v1": "a",
   182  			},
   183  		},
   184  		{
   185  			name: "keep first entry when duplicated keys are encountered",
   186  			sts: schema.Structural{
   187  				Generic: schema.Generic{
   188  					Type: "array",
   189  				},
   190  				Extensions: schema.Extensions{
   191  					XListType:    &listTypeMap,
   192  					XListMapKeys: []string{"k"},
   193  				},
   194  			},
   195  			items: []interface{}{
   196  				map[string]interface{}{
   197  					"k":  "a",
   198  					"v1": "a",
   199  				},
   200  				map[string]interface{}{
   201  					"k":  "a",
   202  					"v1": "b",
   203  				},
   204  			},
   205  			query: map[string]interface{}{
   206  				"k":  "a",
   207  				"v1": "A",
   208  			},
   209  			expected: map[string]interface{}{
   210  				"k":  "a",
   211  				"v1": "a",
   212  			},
   213  		},
   214  		{
   215  			name: "keep first entry when duplicated multi-keys are encountered",
   216  			sts: schema.Structural{
   217  				Generic: schema.Generic{
   218  					Type: "array",
   219  				},
   220  				Extensions: schema.Extensions{
   221  					XListType:    &listTypeMap,
   222  					XListMapKeys: []string{"k1", "k2"},
   223  				},
   224  			},
   225  			items: []interface{}{
   226  				map[string]interface{}{
   227  					"k1": "a",
   228  					"k2": "b",
   229  					"v1": "a",
   230  				},
   231  				map[string]interface{}{
   232  					"k1": "a",
   233  					"k2": "b",
   234  					"v1": "b",
   235  				},
   236  				map[string]interface{}{
   237  					"k1": "x",
   238  					"k2": "y",
   239  					"v1": "z",
   240  				},
   241  			},
   242  			warmUpQueries: []interface{}{
   243  				map[string]interface{}{
   244  					"k1": "x",
   245  					"k2": "y",
   246  				},
   247  			},
   248  			query: map[string]interface{}{
   249  				"k1": "a",
   250  				"k2": "b",
   251  			},
   252  			expected: map[string]interface{}{
   253  				"k1": "a",
   254  				"k2": "b",
   255  				"v1": "a",
   256  			},
   257  		},
   258  		{
   259  			name: "multiple keys with defaults ignores item with nil value for key",
   260  			sts: schema.Structural{
   261  				Generic: schema.Generic{
   262  					Type: "array",
   263  				},
   264  				Extensions: schema.Extensions{
   265  					XListType:    &listTypeMap,
   266  					XListMapKeys: []string{"kb", "kf", "ki", "ks"},
   267  				},
   268  				Properties: map[string]schema.Structural{
   269  					"kb": {
   270  						Generic: schema.Generic{
   271  							Default: schema.JSON{Object: true},
   272  						},
   273  					},
   274  					"kf": {
   275  						Generic: schema.Generic{
   276  							Default: schema.JSON{Object: float64(2.0)},
   277  						},
   278  					},
   279  					"ki": {
   280  						Generic: schema.Generic{
   281  							Default: schema.JSON{Object: int64(42)},
   282  						},
   283  					},
   284  					"ks": {
   285  						Generic: schema.Generic{
   286  							Default: schema.JSON{Object: "hello"},
   287  						},
   288  					},
   289  				},
   290  			},
   291  			items: []interface{}{
   292  				map[string]interface{}{
   293  					"kb": nil,
   294  					"kf": float64(2.0),
   295  					"ki": int64(42),
   296  					"ks": "hello",
   297  					"v1": "a",
   298  				},
   299  				map[string]interface{}{
   300  					"kb": false,
   301  					"kf": float64(2.0),
   302  					"ki": int64(42),
   303  					"ks": "hello",
   304  					"v1": "b",
   305  				},
   306  			},
   307  			query: map[string]interface{}{
   308  				"kb": false,
   309  				"kf": float64(2.0),
   310  				"ki": int64(42),
   311  				"ks": "hello",
   312  				"v1": "B",
   313  			},
   314  			expected: map[string]interface{}{
   315  				"kb": false,
   316  				"kf": float64(2.0),
   317  				"ki": int64(42),
   318  				"ks": "hello",
   319  				"v1": "b",
   320  			},
   321  		},
   322  	} {
   323  		t.Run(tc.name, func(t *testing.T) {
   324  			mapList := makeMapList(&tc.sts, tc.items)
   325  			for _, warmUp := range tc.warmUpQueries {
   326  				mapList.Get(warmUp)
   327  			}
   328  			actual := mapList.Get(tc.query)
   329  			if !reflect.DeepEqual(tc.expected, actual) {
   330  				t.Errorf("got: %v, expected %v", actual, tc.expected)
   331  			}
   332  		})
   333  	}
   334  }
   335  

View as plain text