@@ -354,7 +354,7 @@ type (
354
354
355
355
CustomOption func (* testOptions )
356
356
357
- predecessorFunc func (* rand.Rand , * clusterupgrade.Version , * clusterupgrade.Version ) (* clusterupgrade.Version , error )
357
+ predecessorFunc func (* rand.Rand , * clusterupgrade.Version , * clusterupgrade.Version , * clusterupgrade. Version ) (* clusterupgrade.Version , error )
358
358
359
359
// Test is the main struct callers of this package interact with.
360
360
Test struct {
@@ -1048,18 +1048,18 @@ func (t *Test) chooseUpgradePath() ([]*clusterupgrade.Version, error) {
1048
1048
// function to change in case the rules around what upgrades are
1049
1049
// possible in CRDB change.
1050
1050
possiblePredecessorsFor := func (v * clusterupgrade.Version ) ([]* clusterupgrade.Version , error ) {
1051
- pred , err := t .options .predecessorFunc (t .prng , v , t .options .minimumSupportedVersion )
1051
+ pred , err := t .options .predecessorFunc (t .prng , v , t .options .minimumSupportedVersion , t . options . minimumBootstrapVersion )
1052
1052
if err != nil {
1053
1053
return nil , err
1054
1054
}
1055
1055
1056
- // If the predecessor is older than the minimum bootstrap version,
1057
- // then it is not a legal predecessor.
1058
- if isOlderThanMinimumBootstrapVersion (pred ) {
1056
+ if ! isAvailable (pred ) {
1059
1057
return nil , nil
1060
1058
}
1061
1059
1062
- if ! isAvailable (pred ) {
1060
+ // If the predecessor is older than the minimum bootstrap version,
1061
+ // then it is not a legal predecessor.
1062
+ if isOlderThanMinimumBootstrapVersion (pred ) {
1063
1063
return nil , nil
1064
1064
}
1065
1065
@@ -1069,7 +1069,7 @@ func (t *Test) chooseUpgradePath() ([]*clusterupgrade.Version, error) {
1069
1069
return []* clusterupgrade.Version {pred }, nil
1070
1070
}
1071
1071
1072
- predPred , err := t .options .predecessorFunc (t .prng , pred , t .options .minimumSupportedVersion )
1072
+ predPred , err := t .options .predecessorFunc (t .prng , pred , t .options .minimumSupportedVersion , t . options . minimumBootstrapVersion )
1073
1073
if err != nil {
1074
1074
return nil , err
1075
1075
}
@@ -1193,7 +1193,7 @@ func (t *Test) deploymentMode() DeploymentMode {
1193
1193
// always picks the latest predecessor for the given release version,
1194
1194
// ignoring the minimum supported version declared by the test.
1195
1195
func latestPredecessor (
1196
- _ * rand.Rand , v , minSupported * clusterupgrade.Version ,
1196
+ _ * rand.Rand , v , minSupported , minBootstrap * clusterupgrade.Version ,
1197
1197
) (* clusterupgrade.Version , error ) {
1198
1198
predecessor , err := release .LatestPredecessor (& v .Version )
1199
1199
if err != nil {
@@ -1207,47 +1207,100 @@ func latestPredecessor(
1207
1207
// picks a random predecessor for the given release version. If we are
1208
1208
// choosing a predecessor in the same series as the minimum supported
1209
1209
// version, special care is taken to select a random predecessor that
1210
- // is more recent that the minimum supported version.
1210
+ // is more recent that the minimum supported version. Similarly, the
1211
+ // same is done for the minimum bootstrap version. minSupported must be
1212
+ // set but minBootstrap can be nil.
1211
1213
func randomPredecessor (
1212
- rng * rand.Rand , v , minSupported * clusterupgrade.Version ,
1214
+ rng * rand.Rand , v , minSupported , minBootstrap * clusterupgrade.Version ,
1213
1215
) (* clusterupgrade.Version , error ) {
1214
1216
predecessor , err := release .RandomPredecessor (rng , & v .Version )
1215
1217
if err != nil {
1216
1218
return nil , err
1217
1219
}
1218
1220
1219
- // If the minimum supported version is from a different release
1220
- // series, we can pick any random patch release.
1221
1221
predV := clusterupgrade .MustParseVersion (predecessor )
1222
- if predV .Series () != minSupported .Series () {
1222
+ // minVersion the minimum version we make sure our selected predecessor satisfies.
1223
+ // When choosing a predecessor version, we want to make sure we can run test hooks
1224
+ // if possible on that release series.
1225
+ minVersion := minSupported
1226
+ // minBootstrapSeries is the release series of the minimum bootstrap version, is empty
1227
+ // string if one is not set.
1228
+ var minBootstrapSeries string
1229
+ if minBootstrap != nil {
1230
+ minBootstrapSeries = minBootstrap .Series ()
1231
+ }
1232
+
1233
+ // The minimum bootstrap version (mbv) is guaranteed to be older than or the same
1234
+ // version as the minimum supported version (msv). This gives us the ordering of
1235
+ // minBootstrap <= minSupported < currentVersion and the following 4 cases for what
1236
+ // minVersion should be set to:
1237
+ //
1238
+ // 1. The predecessor series is a different series than the mbv and msv series, we can
1239
+ // pick any random patch release.
1240
+ // 2. The predecessor series is the same as the msv series, validate against the msv.
1241
+ // 3. The predecessor series is the same as the mbv series, validate against the mbv.
1242
+ // 4. The predecessor series is the same as both the mbv and msv series, validate against
1243
+ // the msv since it's older.
1244
+ //
1245
+ // For example, consider a minimum bootstrap version (mbv) of v23.1.3 and a minimum
1246
+ // supported version of v24.1.5 (msv). The framework may pick an upgrade path of:
1247
+ // v23.1 -> v23.2 -> v24.1 -> 24.2. When picking a predecessor for:
1248
+ //
1249
+ // 1. v23.1: This is the same series as our mbv, so our predecessor needs to be
1250
+ // at least v23.1.3 or the plan will not be valid. In this case, minVersion is
1251
+ // set to the mbv. We can ignore the msv here since it is an older series so
1252
+ // no patch release could satisfy it.
1253
+ //
1254
+ // 2. v23.2: This isn't the same series as either the msv or mbv, so we can ignore
1255
+ // minVersion and pick any random patch release. Any patch from a series older than
1256
+ // the msb/msv will never satisfy it, while any patch from a series older always
1257
+ // satisfies it.
1258
+ //
1259
+ // 3. v24.1: This is the same series as our msv, so our predecessor needs to be
1260
+ // at least v24.1.5. We could pick a patch older than that (e.g. v24.1.4) but then
1261
+ // user hooks will not be run, and we lose out on testing coverage. In this case,
1262
+ // minVersion is set to the msv.
1263
+ //
1264
+ // 4. v24.2: This is the same as v23.2 where neither the msv and mbv are the same
1265
+ // series, so we can pick any random patch release.
1266
+ if predV .Series () != minSupported .Series () && predV .Series () != minBootstrapSeries {
1267
+ // If the predecessor version is from a different release series than both the minimum
1268
+ // supported version and minimum bootstrap version, we can pick any random patch release.
1269
+ // Case 1 above.
1223
1270
return predV , nil
1271
+ } else if predV .Series () == minSupported .Series () {
1272
+ // Case 2 and 4 above.
1273
+ minVersion = minSupported
1274
+ } else {
1275
+ // Case 3 above.
1276
+ minVersion = minBootstrap
1224
1277
}
1225
1278
1226
1279
// If the latest release of a series is a pre-release, we validate
1227
1280
// whether the minimum supported version is valid.
1228
- if predV .IsPrerelease () && ! predV .AtLeast (minSupported ) {
1281
+ if predV .IsPrerelease () && ! predV .AtLeast (minVersion ) {
1229
1282
return nil , fmt .Errorf (
1230
1283
"latest release for %s (%s) is not sufficient for minimum supported version (%s)" ,
1231
- predV .Series (), predV , minSupported .Version ,
1284
+ predV .Series (), predV , minVersion .Version ,
1232
1285
)
1233
1286
}
1234
1287
1235
- // If the patch version of `minSupported ` is 0, it means that we
1288
+ // If the patch version of `minVersion ` is 0, it means that we
1236
1289
// can choose any patch release in the predecessor series. It is
1237
1290
// also safe to return `predV` here if the `minSupported` version is
1238
1291
// a pre-release: we already validated that `predV`is at least
1239
1292
// `minSupported` in check above.
1240
- if minSupported .Patch () == 0 {
1293
+ if minVersion .Patch () == 0 {
1241
1294
return predV , nil
1242
1295
}
1243
1296
1244
- latestPred , err := latestPredecessor (rng , v , minSupported )
1297
+ latestPred , err := latestPredecessor (rng , v , minVersion , minBootstrap )
1245
1298
if err != nil {
1246
1299
return nil , err
1247
1300
}
1248
1301
1249
1302
var supportedPatchReleases []* clusterupgrade.Version
1250
- for j := minSupported .Patch (); j <= latestPred .Patch (); j ++ {
1303
+ for j := minVersion .Patch (); j <= latestPred .Patch (); j ++ {
1251
1304
supportedV := clusterupgrade .MustParseVersion (
1252
1305
fmt .Sprintf ("%s.%d" , predV .Major ().String (), j ),
1253
1306
)
@@ -1624,6 +1677,11 @@ func assertValidTest(test *Test, fatalFunc func(...interface{})) {
1624
1677
test .logger .Printf ("WARN: overriding maxUpgrades, minimum bootstrap version (%s) allows for at most %d upgrades" , minBootstrapVersion , maxUpgradesFromBootstrapVersion )
1625
1678
test .options .maxUpgrades = maxUpgradesFromBootstrapVersion
1626
1679
}
1680
+
1681
+ if msv .LessThan (minBootstrapVersion ) {
1682
+ test .logger .Printf ("WARN: overriding minSupportedVersion, cannot be older than minimum bootstrap version (%s)" , minBootstrapVersion )
1683
+ test .options .minimumSupportedVersion = minBootstrapVersion
1684
+ }
1627
1685
}
1628
1686
}
1629
1687
0 commit comments