vitess.io/vitess@v0.16.2/go/vt/vtctl/reparentutil/durability_funcs_test.go (about) 1 /* 2 Copyright 2022 The Vitess 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 reparentutil 18 19 import ( 20 "fmt" 21 "testing" 22 23 "github.com/stretchr/testify/require" 24 25 topodatapb "vitess.io/vitess/go/vt/proto/topodata" 26 ) 27 28 var ( 29 primaryTablet = &topodatapb.Tablet{ 30 Alias: &topodatapb.TabletAlias{ 31 Cell: "zone-1", 32 Uid: 1, 33 }, 34 Type: topodatapb.TabletType_PRIMARY, 35 } 36 replicaTablet = &topodatapb.Tablet{ 37 Alias: &topodatapb.TabletAlias{ 38 Cell: "zone-1", 39 Uid: 2, 40 }, 41 Type: topodatapb.TabletType_REPLICA, 42 } 43 rdonlyTablet = &topodatapb.Tablet{ 44 Alias: &topodatapb.TabletAlias{ 45 Cell: "zone-1", 46 Uid: 3, 47 }, 48 Type: topodatapb.TabletType_RDONLY, 49 } 50 replicaCrossCellTablet = &topodatapb.Tablet{ 51 Alias: &topodatapb.TabletAlias{ 52 Cell: "zone-2", 53 Uid: 2, 54 }, 55 Type: topodatapb.TabletType_REPLICA, 56 } 57 rdonlyCrossCellTablet = &topodatapb.Tablet{ 58 Alias: &topodatapb.TabletAlias{ 59 Cell: "zone-2", 60 Uid: 3, 61 }, 62 Type: topodatapb.TabletType_RDONLY, 63 } 64 ) 65 66 func TestSemiSyncAckersForPrimary(t *testing.T) { 67 tests := []struct { 68 name string 69 durabilityPolicy string 70 primary *topodatapb.Tablet 71 allTablets []*topodatapb.Tablet 72 wantSemiSyncAckers []*topodatapb.Tablet 73 }{ 74 { 75 name: "no other tablets", 76 durabilityPolicy: "none", 77 primary: primaryTablet, 78 allTablets: []*topodatapb.Tablet{primaryTablet}, 79 wantSemiSyncAckers: nil, 80 }, { 81 name: "'none' durability policy", 82 durabilityPolicy: "none", 83 primary: primaryTablet, 84 allTablets: []*topodatapb.Tablet{primaryTablet, replicaTablet, rdonlyTablet, replicaCrossCellTablet, rdonlyCrossCellTablet}, 85 wantSemiSyncAckers: nil, 86 }, { 87 name: "'semi_sync' durability policy", 88 durabilityPolicy: "semi_sync", 89 primary: primaryTablet, 90 allTablets: []*topodatapb.Tablet{primaryTablet, replicaTablet, rdonlyTablet, replicaCrossCellTablet, rdonlyCrossCellTablet}, 91 wantSemiSyncAckers: []*topodatapb.Tablet{replicaTablet, replicaCrossCellTablet}, 92 }, { 93 name: "'cross_cell' durability policy", 94 durabilityPolicy: "cross_cell", 95 primary: primaryTablet, 96 allTablets: []*topodatapb.Tablet{primaryTablet, replicaTablet, rdonlyTablet, replicaCrossCellTablet, rdonlyCrossCellTablet}, 97 wantSemiSyncAckers: []*topodatapb.Tablet{replicaCrossCellTablet}, 98 }, 99 } 100 for _, tt := range tests { 101 t.Run(tt.name, func(t *testing.T) { 102 durability, err := GetDurabilityPolicy(tt.durabilityPolicy) 103 require.NoError(t, err, "error setting durability policy") 104 semiSyncAckers := SemiSyncAckersForPrimary(durability, tt.primary, tt.allTablets) 105 require.Equal(t, tt.wantSemiSyncAckers, semiSyncAckers) 106 }) 107 } 108 } 109 110 func Test_haveRevokedForTablet(t *testing.T) { 111 tests := []struct { 112 name string 113 durabilityPolicy string 114 primaryEligible *topodatapb.Tablet 115 allTablets []*topodatapb.Tablet 116 tabletsReached []*topodatapb.Tablet 117 revoked bool 118 }{ 119 { 120 name: "'none' durability policy - not revoked", 121 durabilityPolicy: "none", 122 primaryEligible: primaryTablet, 123 allTablets: []*topodatapb.Tablet{ 124 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 125 }, 126 tabletsReached: []*topodatapb.Tablet{ 127 replicaTablet, replicaCrossCellTablet, rdonlyTablet, rdonlyCrossCellTablet, 128 }, 129 revoked: false, 130 }, { 131 name: "'none' durability policy - revoked", 132 durabilityPolicy: "none", 133 primaryEligible: primaryTablet, 134 allTablets: []*topodatapb.Tablet{ 135 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 136 }, 137 tabletsReached: []*topodatapb.Tablet{ 138 primaryTablet, rdonlyTablet, rdonlyCrossCellTablet, 139 }, 140 revoked: true, 141 }, { 142 name: "'semi_sync' durability policy - revoked", 143 durabilityPolicy: "semi_sync", 144 primaryEligible: primaryTablet, 145 allTablets: []*topodatapb.Tablet{ 146 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 147 }, 148 tabletsReached: []*topodatapb.Tablet{ 149 replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, 150 }, 151 revoked: true, 152 }, { 153 name: "'semi_sync' durability policy - not revoked", 154 durabilityPolicy: "semi_sync", 155 primaryEligible: primaryTablet, 156 allTablets: []*topodatapb.Tablet{ 157 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 158 }, 159 tabletsReached: []*topodatapb.Tablet{ 160 replicaTablet, rdonlyCrossCellTablet, rdonlyTablet, 161 }, 162 revoked: false, 163 }, { 164 name: "'cross_cell' durability policy - revoked", 165 durabilityPolicy: "cross_cell", 166 primaryEligible: primaryTablet, 167 allTablets: []*topodatapb.Tablet{ 168 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 169 }, 170 tabletsReached: []*topodatapb.Tablet{ 171 replicaCrossCellTablet, 172 }, 173 revoked: true, 174 }, { 175 name: "'cross_cell' durability policy - not revoked", 176 durabilityPolicy: "cross_cell", 177 primaryEligible: primaryTablet, 178 allTablets: []*topodatapb.Tablet{ 179 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 180 }, 181 tabletsReached: []*topodatapb.Tablet{ 182 replicaTablet, rdonlyCrossCellTablet, rdonlyTablet, 183 }, 184 revoked: false, 185 }, { 186 name: "'cross_cell' durability policy - primary in list", 187 durabilityPolicy: "cross_cell", 188 primaryEligible: primaryTablet, 189 allTablets: []*topodatapb.Tablet{ 190 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 191 }, 192 tabletsReached: []*topodatapb.Tablet{ 193 primaryTablet, 194 }, 195 revoked: true, 196 }, 197 } 198 for _, tt := range tests { 199 t.Run(tt.name, func(t *testing.T) { 200 durability, err := GetDurabilityPolicy(tt.durabilityPolicy) 201 require.NoError(t, err) 202 out := haveRevokedForTablet(durability, tt.primaryEligible, tt.tabletsReached, tt.allTablets) 203 require.Equal(t, tt.revoked, out) 204 }) 205 } 206 } 207 208 func Test_haveRevoked(t *testing.T) { 209 tests := []struct { 210 name string 211 durabilityPolicy string 212 tabletsReached []*topodatapb.Tablet 213 allTablets []*topodatapb.Tablet 214 revoked bool 215 }{ 216 { 217 name: "'none' durability policy - all tablets revoked", 218 durabilityPolicy: "none", 219 tabletsReached: []*topodatapb.Tablet{ 220 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 221 }, 222 allTablets: []*topodatapb.Tablet{ 223 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 224 }, 225 revoked: true, 226 }, { 227 name: "'semi_sync' durability policy - all tablets revoked", 228 durabilityPolicy: "semi_sync", 229 tabletsReached: []*topodatapb.Tablet{ 230 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 231 }, 232 allTablets: []*topodatapb.Tablet{ 233 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 234 }, 235 revoked: true, 236 }, { 237 name: "'cross_cell' durability policy - all tablets revoked", 238 durabilityPolicy: "cross_cell", 239 tabletsReached: []*topodatapb.Tablet{ 240 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 241 }, 242 allTablets: []*topodatapb.Tablet{ 243 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 244 }, 245 revoked: true, 246 }, { 247 name: "'none' durability policy - revoked", 248 durabilityPolicy: "none", 249 tabletsReached: []*topodatapb.Tablet{ 250 primaryTablet, replicaTablet, replicaCrossCellTablet, 251 }, 252 allTablets: []*topodatapb.Tablet{ 253 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 254 }, 255 revoked: true, 256 }, { 257 name: "'semi_sync' durability policy - revoked", 258 durabilityPolicy: "semi_sync", 259 tabletsReached: []*topodatapb.Tablet{ 260 replicaTablet, replicaCrossCellTablet, rdonlyTablet, 261 }, 262 allTablets: []*topodatapb.Tablet{ 263 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 264 }, 265 revoked: true, 266 }, { 267 name: "'cross_cell' durability policy - revoked", 268 durabilityPolicy: "cross_cell", 269 tabletsReached: []*topodatapb.Tablet{ 270 replicaCrossCellTablet, 271 }, 272 allTablets: []*topodatapb.Tablet{ 273 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 274 }, 275 revoked: true, 276 }, { 277 name: "'none' durability policy - not revoked", 278 durabilityPolicy: "none", 279 tabletsReached: []*topodatapb.Tablet{ 280 primaryTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 281 }, 282 allTablets: []*topodatapb.Tablet{ 283 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 284 }, 285 revoked: false, 286 }, { 287 name: "'semi_sync' durability policy - not revoked", 288 durabilityPolicy: "semi_sync", 289 tabletsReached: []*topodatapb.Tablet{ 290 primaryTablet, rdonlyCrossCellTablet, rdonlyTablet, 291 }, 292 allTablets: []*topodatapb.Tablet{ 293 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 294 }, 295 revoked: false, 296 }, { 297 name: "'cross_cell' durability policy - not revoked", 298 durabilityPolicy: "cross_cell", 299 tabletsReached: []*topodatapb.Tablet{ 300 primaryTablet, rdonlyCrossCellTablet, rdonlyTablet, 301 }, 302 allTablets: []*topodatapb.Tablet{ 303 primaryTablet, replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 304 }, 305 revoked: false, 306 }, 307 } 308 for _, tt := range tests { 309 t.Run(tt.name, func(t *testing.T) { 310 durability, err := GetDurabilityPolicy(tt.durabilityPolicy) 311 require.NoError(t, err) 312 out := haveRevoked(durability, tt.tabletsReached, tt.allTablets) 313 require.Equal(t, tt.revoked, out) 314 }) 315 } 316 } 317 318 func Test_canEstablishForTablet(t *testing.T) { 319 tests := []struct { 320 name string 321 durabilityPolicy string 322 primaryEligible *topodatapb.Tablet 323 tabletsReached []*topodatapb.Tablet 324 canEstablish bool 325 }{ 326 { 327 name: "primary not reached", 328 durabilityPolicy: "none", 329 primaryEligible: primaryTablet, 330 tabletsReached: []*topodatapb.Tablet{ 331 replicaTablet, replicaCrossCellTablet, rdonlyCrossCellTablet, rdonlyTablet, 332 }, 333 canEstablish: false, 334 }, { 335 name: "not established", 336 durabilityPolicy: "semi_sync", 337 primaryEligible: primaryTablet, 338 tabletsReached: []*topodatapb.Tablet{ 339 primaryTablet, rdonlyCrossCellTablet, rdonlyTablet, 340 }, 341 canEstablish: false, 342 }, { 343 name: "not established", 344 durabilityPolicy: "cross_cell", 345 primaryEligible: primaryTablet, 346 tabletsReached: []*topodatapb.Tablet{ 347 primaryTablet, replicaTablet, rdonlyCrossCellTablet, rdonlyTablet, 348 }, 349 canEstablish: false, 350 }, { 351 name: "established", 352 durabilityPolicy: "none", 353 primaryEligible: primaryTablet, 354 tabletsReached: []*topodatapb.Tablet{ 355 primaryTablet, 356 }, 357 canEstablish: true, 358 }, { 359 name: "established", 360 durabilityPolicy: "semi_sync", 361 primaryEligible: primaryTablet, 362 tabletsReached: []*topodatapb.Tablet{ 363 primaryTablet, replicaTablet, 364 }, 365 canEstablish: true, 366 }, { 367 name: "established", 368 durabilityPolicy: "cross_cell", 369 primaryEligible: primaryTablet, 370 tabletsReached: []*topodatapb.Tablet{ 371 primaryTablet, replicaCrossCellTablet, 372 }, 373 canEstablish: true, 374 }, 375 } 376 for _, tt := range tests { 377 t.Run(fmt.Sprintf("'%s' durability policy - %s", tt.durabilityPolicy, tt.name), func(t *testing.T) { 378 durability, err := GetDurabilityPolicy(tt.durabilityPolicy) 379 require.NoError(t, err) 380 require.Equalf(t, tt.canEstablish, canEstablishForTablet(durability, tt.primaryEligible, tt.tabletsReached), "canEstablishForTablet(%v, %v)", tt.primaryEligible, tt.tabletsReached) 381 }) 382 } 383 }