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 }