Skip to content

Commit 5ad1ee9

Browse files
craig[bot]DarrylWongsrosenberg
committed
Merge #146857
146857: mixedversion: fix MinBootstrapVersion bugs r=srosenberg a=srosenberg Previously, `chooseUpgradePath` was buggy in how upgrades were chosen with respect to `minimumBootstrapVersion` and `minimumSupportedVersion`. Some invariants were violated, resulting in runtime panic or inability to find a plan. This change refactors `chooseUpgradePath` and adds both a regression test, as well as a property-based test to ensure the invariants, now codified in `assertValidPlan` are indeed _invariant_. Fixes: #139201 Epic: none Release note: None Co-authored-by: DarrylWong <[email protected]> Co-authored-by: Stan Rosenberg <[email protected]>
2 parents 619b556 + 8f74401 commit 5ad1ee9

24 files changed

+1936
-1199
lines changed

pkg/cmd/roachtest/roachtestutil/clusterupgrade/clusterupgrade.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ type Version struct {
5454
// tested, we print the branch name being tested if the test is
5555
// running on TeamCity, to make it clearer (instead of "<current>").
5656
func (v *Version) String() string {
57+
suffix := ""
5758
if v.IsCurrent() {
5859
if currentBranch != "" {
59-
return currentBranch
60+
suffix = fmt.Sprintf(" (%s)", currentBranch)
61+
} else {
62+
suffix = fmt.Sprintf(" (%s)", CurrentVersionString)
6063
}
61-
62-
return CurrentVersionString
6364
}
64-
65-
return v.Version.String()
65+
return v.Version.String() + suffix
6666
}
6767

6868
// IsCurrent returns whether this version corresponds to the current

pkg/cmd/roachtest/roachtestutil/mixedversion/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ go_test(
7373
"//pkg/roachprod/vm",
7474
"//pkg/testutils/datapathutils",
7575
"//pkg/testutils/release",
76+
"//pkg/testutils/skip",
7677
"//pkg/util/intsets",
7778
"//pkg/util/randutil",
7879
"//pkg/util/retry",

pkg/cmd/roachtest/roachtestutil/mixedversion/README.md

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,14 +160,7 @@ The 5th argument to the call above (`c.CRDBNodes()`) indicates to the framework
160160
mvt.OnStartup("create some tables on the previous version", createSomeTables)
161161
```
162162

163-
This is the first _user hook_ we encounter: `OnStartup`. [Hooks](#terminology) are functions that are invoked at specific points in the test and is where test logic and assertions must live. The `OnStartup` function lets the test register a hook to be executed as soon as the cluster is ready (i.e., when it is running a version greater than the test's _minimum supported version_). In addition, in multi-tenant tests, the test tenant has also been created and is ready to serve requests at this point.
164-
165-
One important point to note is that mixed-version tests start the cluster at a [_predecessor version_ (not necessarily immediate predecessor)](#high-level-overview). As such, if a feature was just introduced in the current release, it won't be available at this point.
166-
167-
**Note**: _Minimum Supported Version_ vs. _Minimum Bootstrap Version_:
168-
One common mistake is to think that the _minimum supported version_ will configure the test to never start on any version older. However, this setting only configures _user hooks_ to not be scheduled at any versions older than the _minimum supported version_. It is still possible for the test to start the cluster at a _predecessor version_ of the _minimum supported version_ and run upgrades normally without any user hooks. Even if the feature we are primarily testing was not introduced until _minimum supported version_, it can be useful to run through the exercise of loading in old data.
169-
170-
However, you may run into a scenario that requires the cluster to _start_ at a certain version. This is where _minimum bootstrap version_ comes in and enforces that the framework will not generate any plans that start the cluster on a version older. For best practices, if either option works, prefer _Minimum Supported Version_ due to the extra coverage it provides.
163+
This is the first _user hook_ we encounter: `OnStartup`. [Hooks](#terminology) are functions that are invoked at specific points in the test and is where test logic and assertions must live. The `OnStartup` function lets the test register a hook to be executed as soon as the cluster is ready (i.e., when it is running a version greater than or equal to the test's _minimum supported version_). In addition, in multi-tenant tests, the test tenant has also been created and is ready to serve requests at this point.
171164

172165
#### Testing code in mixed-version
173166

@@ -198,6 +191,43 @@ Once all hooks are registered, all that is left to do is to actually run the tes
198191

199192
### Best Practices
200193

194+
#### Mixed-version Hooks and Compatibility
195+
196+
One important point to note is that mixed-version tests start the cluster at a [_predecessor version_](#high-level-overview). As such, if a feature was introduced in the _current_ release, it will not be
197+
"available" in _all_ mixed-version states. The reason is that a new feature is typically version-gated; i.e., it's disabled until after the cluster is at the specified _minimum_ version (or above). Thus, the user
198+
hooks which are designed to run in mixed-version states, i.e., `OnStartup`, `InMixedVersion`, and `AfterUpgradeFinalized`, will not be able to exercise the new feature. The new feature is still tested in mixed-version
199+
states since some of the cluster nodes will be running on a previous release; thus, we're mostly testing backward compatibility. (Also, see [BackgroundFunc](#aside-background-functions) which can be utilized in this scenario.)
200+
201+
In reality, the above case is mitigated by the release process, wherein upon feature completion (aka "stability period"), a new release branch is created (and [`cockroach_releases.yaml`](https://github.com/cockroachdb/cockroach/blob/master/pkg/testutils/release/cockroach_releases.yaml) is updated in `master`). Any subsequent commit on that branch will yield a new version
202+
that is available for mixed-version testing. Now, the cluster would start at the _minimum_ version where the feature is available, and the mixed-version user hooks will be exercised, all throughout the stability
203+
period.
204+
205+
A test may explicitly require a _minimum supported version_ to ensure that the mixed-version user-hooks don't encounter any incompatibility. E.g.,
206+
```
207+
// We test only upgrades from 23.2 in this test because it uses
208+
// the `workload fixtures import` command, which is only supported
209+
// reliably multi-tenant mode starting from that version.
210+
// mixedversion.MinimumSupportedVersion("v23.2.0"),
211+
```
212+
Thus, `MinimumSupportedVersion` allows tests to specify that the mixed-versions hooks are run only _after_ the cluster is running at least at the specified version, or above. As a side-note, the
213+
implementation uses `minimumSupportedVersion` to divide the resulting test plan into "setup" and "test" parts, the latter of which denotes when the mixed-version user hooks are eligible to run. As another
214+
side-note, when testing skip-upgrades, e.g., `v23.2.0` to `v24.2.0`, the framework must ensure that `minimumSupportedVersion` is _not_ older than `v23.2.0`; otherwise, the mixed-version hooks
215+
won't run.
216+
217+
```go
218+
// Find which upgrades are part of setup and which upgrades will be
219+
// tested, based on the test's minimum supported version.
220+
idx := slices.IndexFunc(allUpgrades, func(upgrade *upgradePlan) bool {
221+
return upgrade.from.AtLeast(p.options.minimumSupportedVersion)
222+
})
223+
```
224+
225+
**Note**: _Minimum Supported Version_ vs. _Minimum Bootstrap Version_:
226+
One common mistake is to think that the _minimum supported version_ will configure the test to never start on any version older. However, this setting only configures _user hooks_ to not be scheduled at any versions older than the _minimum supported version_. It is still possible for the test to start the cluster at a _predecessor version_ of the _minimum supported version_ and run upgrades normally without any user hooks. Even if the feature we are primarily testing was not introduced until _minimum supported version_, it can be useful to run through the exercise of loading in old data.
227+
228+
However, you may run into a scenario that requires the cluster to _start_ at a certain version. This is where _minimum bootstrap version_ comes in and enforces that the framework will not generate any plans that start the cluster on a version older. For best practices, if either option works, prefer _Minimum Supported Version_ due to the extra coverage it provides.
229+
230+
201231
#### Embrace randomness
202232

203233
The `mixedversion` framework itself randomizes a lot of its operations: the order in which nodes are restarted with a new binary, whether to use fixtures when setting up the cluster, the deployment mode used in each test run, the timing of user functions, etc. Similarly, tests are encouraged to take advantage of randomization to get more coverage out of a single test.

0 commit comments

Comments
 (0)