k8s.io/client-go@v0.31.1/util/watchlist/watch_list_test.go (about)

     1  /*
     2  Copyright 2024 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 watchlist
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/stretchr/testify/require"
    23  
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	clientfeatures "k8s.io/client-go/features"
    26  	clientfeaturestesting "k8s.io/client-go/features/testing"
    27  	"k8s.io/utils/ptr"
    28  )
    29  
    30  // TestPrepareWatchListOptionsFromListOptions test the following cases:
    31  //
    32  // +--------------------------+-----------------+---------+-----------------+
    33  // |   ResourceVersionMatch   | ResourceVersion |  Limit  |  Continuation   |
    34  // +--------------------------+-----------------+---------+-----------------+
    35  // | unset/NotOlderThan/Exact | unset/0/100     | unset/4 | unset/FakeToken |
    36  // +--------------------------+-----------------+---------+-----------------+
    37  func TestPrepareWatchListOptionsFromListOptions(t *testing.T) {
    38  	scenarios := []struct {
    39  		name              string
    40  		listOptions       metav1.ListOptions
    41  		enableWatchListFG bool
    42  
    43  		expectToPrepareWatchListOptions bool
    44  		expectedWatchListOptions        metav1.ListOptions
    45  	}{
    46  
    47  		{
    48  			name:                            "can't enable watch list for: WatchListClient=off, RVM=unset, RV=unset, Limit=unset, Continuation=unset",
    49  			enableWatchListFG:               false,
    50  			expectToPrepareWatchListOptions: false,
    51  		},
    52  		//		+----------------------+-----------------+-------+--------------+
    53  		//		| ResourceVersionMatch | ResourceVersion | Limit | Continuation |
    54  		//		+----------------------+-----------------+-------+--------------+
    55  		//		| unset                | unset           | unset | unset        |
    56  		//		| unset                | 0               | unset | unset        |
    57  		//		| unset                | 100             | unset | unset        |
    58  		//		| unset                | 0               | 4     | unset        |
    59  		//		| unset                | 0               | unset | FakeToken    |
    60  		//		+----------------------+-----------------+-------+--------------+
    61  		{
    62  			name:                            "can enable watch list for: RVM=unset, RV=unset, Limit=unset, Continuation=unset",
    63  			enableWatchListFG:               true,
    64  			expectToPrepareWatchListOptions: true,
    65  			expectedWatchListOptions:        expectedWatchListOptionsFor(""),
    66  		},
    67  		{
    68  			name:                            "can enable watch list for: RVM=unset, RV=0, Limit=unset, Continuation=unset",
    69  			listOptions:                     metav1.ListOptions{ResourceVersion: "0"},
    70  			enableWatchListFG:               true,
    71  			expectToPrepareWatchListOptions: true,
    72  			expectedWatchListOptions:        expectedWatchListOptionsFor("0"),
    73  		},
    74  		{
    75  			name:                            "can enable watch list for: RVM=unset, RV=100, Limit=unset, Continuation=unset",
    76  			listOptions:                     metav1.ListOptions{ResourceVersion: "100"},
    77  			enableWatchListFG:               true,
    78  			expectToPrepareWatchListOptions: true,
    79  			expectedWatchListOptions:        expectedWatchListOptionsFor("100"),
    80  		},
    81  		{
    82  			name:                            "legacy: can enable watch list for: RVM=unset, RV=0, Limit=4,  Continuation=unset",
    83  			listOptions:                     metav1.ListOptions{ResourceVersion: "0", Limit: 4},
    84  			enableWatchListFG:               true,
    85  			expectToPrepareWatchListOptions: true,
    86  			expectedWatchListOptions:        expectedWatchListOptionsFor("0"),
    87  		},
    88  		{
    89  			name:                            "can't enable watch list for: RVM=unset, RV=0, Limit=unset, Continuation=FakeToken",
    90  			listOptions:                     metav1.ListOptions{ResourceVersion: "0", Continue: "FakeToken"},
    91  			enableWatchListFG:               true,
    92  			expectToPrepareWatchListOptions: false,
    93  		},
    94  		//		+----------------------+-----------------+-------+--------------+
    95  		//		| ResourceVersionMatch | ResourceVersion | Limit | Continuation |
    96  		//		+----------------------+-----------------+-------+--------------+
    97  		//		| NotOlderThan         | unset           | unset | unset        |
    98  		//		| NotOlderThan         | 0               | unset | unset        |
    99  		//		| NotOlderThan         | 100             | unset | unset        |
   100  		//		| NotOlderThan         | 0               | 4     | unset        |
   101  		//		| NotOlderThan         | 0               | unset | FakeToken    |
   102  		//		+----------------------+-----------------+-------+--------------+
   103  		{
   104  			name:                            "can't enable watch list for: RVM=NotOlderThan, RV=unset, Limit=unset, Continuation=unset",
   105  			listOptions:                     metav1.ListOptions{ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan},
   106  			enableWatchListFG:               true,
   107  			expectToPrepareWatchListOptions: false,
   108  		},
   109  		{
   110  			name:                            "can enable watch list for: RVM=NotOlderThan, RV=0, Limit=unset, Continuation=unset",
   111  			listOptions:                     metav1.ListOptions{ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan, ResourceVersion: "0"},
   112  			enableWatchListFG:               true,
   113  			expectToPrepareWatchListOptions: true,
   114  			expectedWatchListOptions:        expectedWatchListOptionsFor("0"),
   115  		},
   116  		{
   117  			name:                            "can enable watch list for: RVM=NotOlderThan, RV=100, Limit=unset, Continuation=unset",
   118  			listOptions:                     metav1.ListOptions{ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan, ResourceVersion: "100"},
   119  			enableWatchListFG:               true,
   120  			expectToPrepareWatchListOptions: true,
   121  			expectedWatchListOptions:        expectedWatchListOptionsFor("100"),
   122  		},
   123  		{
   124  			name:                            "legacy: can enable watch list for: RVM=NotOlderThan, RV=0, Limit=4, Continuation=unset",
   125  			listOptions:                     metav1.ListOptions{ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan, ResourceVersion: "0", Limit: 4},
   126  			enableWatchListFG:               true,
   127  			expectToPrepareWatchListOptions: true,
   128  			expectedWatchListOptions:        expectedWatchListOptionsFor("0"),
   129  		},
   130  		{
   131  			name:                            "can't enable watch list for: RVM=NotOlderThan, RV=0, Limit=unset, Continuation=FakeToken",
   132  			listOptions:                     metav1.ListOptions{ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan, ResourceVersion: "0", Continue: "FakeToken"},
   133  			enableWatchListFG:               true,
   134  			expectToPrepareWatchListOptions: false,
   135  		},
   136  
   137  		//		+----------------------+-----------------+-------+--------------+
   138  		//		| ResourceVersionMatch | ResourceVersion | Limit | Continuation |
   139  		//		+----------------------+-----------------+-------+--------------+
   140  		//		| Exact                | unset           | unset | unset        |
   141  		//		| Exact                | 0               | unset | unset        |
   142  		//		| Exact                | 100             | unset | unset        |
   143  		//		| Exact                | 0               | 4     | unset        |
   144  		//		| Exact                | 0               | unset | FakeToken    |
   145  		//		+----------------------+-----------------+-------+--------------+
   146  		{
   147  			name:                            "can't enable watch list for: RVM=Exact, RV=unset, Limit=unset, Continuation=unset",
   148  			listOptions:                     metav1.ListOptions{ResourceVersionMatch: metav1.ResourceVersionMatchExact},
   149  			enableWatchListFG:               true,
   150  			expectToPrepareWatchListOptions: false,
   151  		},
   152  		{
   153  			name:                            "can enable watch list for: RVM=Exact, RV=0, Limit=unset, Continuation=unset",
   154  			listOptions:                     metav1.ListOptions{ResourceVersionMatch: metav1.ResourceVersionMatchExact, ResourceVersion: "0"},
   155  			enableWatchListFG:               true,
   156  			expectToPrepareWatchListOptions: false,
   157  		},
   158  		{
   159  			name:                            "can enable watch list for: RVM=Exact, RV=100, Limit=unset, Continuation=unset",
   160  			listOptions:                     metav1.ListOptions{ResourceVersionMatch: metav1.ResourceVersionMatchExact, ResourceVersion: "100"},
   161  			enableWatchListFG:               true,
   162  			expectToPrepareWatchListOptions: false,
   163  		},
   164  		{
   165  			name:                            "can't enable watch list for: RVM=Exact, RV=0, Limit=4,  Continuation=unset",
   166  			listOptions:                     metav1.ListOptions{ResourceVersionMatch: metav1.ResourceVersionMatchExact, ResourceVersion: "0", Limit: 4},
   167  			enableWatchListFG:               true,
   168  			expectToPrepareWatchListOptions: false,
   169  		},
   170  		{
   171  			name:                            "can't enable watch list for: RVM=Exact, RV=0, Limit=unset, Continuation=FakeToken",
   172  			listOptions:                     metav1.ListOptions{ResourceVersionMatch: metav1.ResourceVersionMatchExact, ResourceVersion: "0", Continue: "FakeToken"},
   173  			enableWatchListFG:               true,
   174  			expectToPrepareWatchListOptions: false,
   175  		},
   176  	}
   177  	for _, scenario := range scenarios {
   178  		t.Run(scenario.name, func(t *testing.T) {
   179  			clientfeaturestesting.SetFeatureDuringTest(t, clientfeatures.WatchListClient, scenario.enableWatchListFG)
   180  
   181  			watchListOptions, hasWatchListOptionsPrepared, err := PrepareWatchListOptionsFromListOptions(scenario.listOptions)
   182  
   183  			require.NoError(t, err)
   184  			require.Equal(t, scenario.expectToPrepareWatchListOptions, hasWatchListOptionsPrepared)
   185  			require.Equal(t, scenario.expectedWatchListOptions, watchListOptions)
   186  		})
   187  	}
   188  }
   189  
   190  func expectedWatchListOptionsFor(rv string) metav1.ListOptions {
   191  	var watchListOptions metav1.ListOptions
   192  
   193  	watchListOptions.ResourceVersion = rv
   194  	watchListOptions.ResourceVersionMatch = metav1.ResourceVersionMatchNotOlderThan
   195  	watchListOptions.Watch = true
   196  	watchListOptions.AllowWatchBookmarks = true
   197  	watchListOptions.SendInitialEvents = ptr.To(true)
   198  
   199  	return watchListOptions
   200  }