Skip to content

Commit 9b2f590

Browse files
committed
roachtest/mixedversion: sync workload binary versions with the cluster version
The current workload binary is no longer backwards compatible for certain workloads. Previously, the workload binary would just use whatever default binary was staged on the workload node. Currently, there's a quick fix that installs the current system version's binary on the workload node when a workload cmd is being executed. This change bakes that behavior into the test framework itself, so we can remove the binary staging from the Workload hook. Workload nodes are staged with all versioned binaries in the upgrade plan so all workload commands can use a versioned binary that matches the current state of the cluster. Resolves #147374 Epic: None Release note: None
1 parent 8504d75 commit 9b2f590

28 files changed

+346
-145
lines changed

pkg/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,7 @@ GO_TARGETS = [
12661266
"//pkg/cmd/roachprod/grafana:grafana",
12671267
"//pkg/cmd/roachprod:roachprod",
12681268
"//pkg/cmd/roachprod:roachprod_lib",
1269+
"//pkg/cmd/roachtest/cluster/mock:mockcluster",
12691270
"//pkg/cmd/roachtest/cluster:cluster",
12701271
"//pkg/cmd/roachtest/clusterstats:clusterstats",
12711272
"//pkg/cmd/roachtest/clusterstats:clusterstats_test",
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library", "gomock")
2+
3+
gomock(
4+
name = "mock_cluster",
5+
testonly = True,
6+
out = "mock_cluster_generated.go",
7+
interfaces = ["Cluster"],
8+
library = "//pkg/cmd/roachtest/cluster",
9+
package = "mockcluster",
10+
self_package = "github.com/cockroachdb/cockroach/pkg/cmd/roachtest/cluster/mock",
11+
visibility = [
12+
"//pkg/cmd/roachtest/clusterstats:__pkg__",
13+
"//pkg/cmd/roachtest/roachtestutil/mixedversion:__pkg__",
14+
"//pkg/gen:__pkg__",
15+
],
16+
)
17+
18+
go_library(
19+
name = "mockcluster",
20+
srcs = ["mock_cluster_generated.go"],
21+
importpath = "github.com/cockroachdb/cockroach/pkg/cmd/roachtest/cluster/mock",
22+
visibility = [
23+
"//pkg/cmd/roachtest/clusterstats:__pkg__",
24+
"//pkg/cmd/roachtest/roachtestutil/mixedversion:__pkg__",
25+
"//pkg/gen:__pkg__",
26+
],
27+
deps = [
28+
"//pkg/cmd/roachprod/grafana",
29+
"//pkg/cmd/roachtest/cluster",
30+
"//pkg/cmd/roachtest/option",
31+
"//pkg/cmd/roachtest/spec",
32+
"//pkg/roachprod",
33+
"//pkg/roachprod/failureinjection/failures",
34+
"//pkg/roachprod/install",
35+
"//pkg/roachprod/logger",
36+
"//pkg/roachprod/prometheus",
37+
"//pkg/roachprod/vm",
38+
"@com_github_golang_mock//gomock",
39+
],
40+
)

pkg/cmd/roachtest/clusterstats/mock_cluster_generated_test.go renamed to pkg/cmd/roachtest/cluster/mock/mock_cluster_generated.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cmd/roachtest/clusterstats/BUILD.bazel

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ go_library(
1515
"//pkg/cmd/roachprod-microbench/util",
1616
# Required for generated mocks
1717
"//pkg/cmd/roachprod/grafana", #keep
18-
"//pkg/cmd/roachtest/cluster",
1918
"//pkg/cmd/roachtest/option",
2019
"//pkg/cmd/roachtest/test",
2120
# Required for generated mocks
@@ -36,6 +35,7 @@ go_library(
3635
"@com_github_prometheus_client_golang//api/prometheus/v1:prometheus",
3736
"@com_github_prometheus_common//model",
3837
"//pkg/cmd/roachtest/roachtestutil",
38+
"//pkg/cmd/roachtest/cluster",
3939
],
4040
)
4141

@@ -45,15 +45,15 @@ go_test(
4545
"exporter_test.go",
4646
"streamer_test.go",
4747
":mock_client", # keep
48-
":mock_cluster", # keep
4948
":mock_test", # keep
5049
],
5150
embed = [":clusterstats"],
5251
embedsrcs = ["openmetrics_expected.txt"],
5352
deps = [
5453
"//pkg/cmd/roachtest/cluster",
54+
"//pkg/cmd/roachtest/cluster/mock:mockcluster", #keep
5555
"//pkg/cmd/roachtest/registry",
56-
# Required for generated mocks
56+
"//pkg/cmd/roachtest/roachtestutil",
5757
"//pkg/cmd/roachtest/roachtestutil/task", #keep
5858
"//pkg/cmd/roachtest/spec",
5959
"//pkg/cmd/roachtest/test",
@@ -64,7 +64,6 @@ go_test(
6464
"@com_github_prometheus_client_golang//api/prometheus/v1:prometheus",
6565
"@com_github_prometheus_common//model",
6666
"@com_github_stretchr_testify//require",
67-
"//pkg/cmd/roachtest/roachtestutil",
6867
],
6968
)
7069

@@ -91,15 +90,3 @@ gomock(
9190
"//pkg/gen:__pkg__",
9291
],
9392
)
94-
95-
gomock(
96-
name = "mock_cluster",
97-
out = "mock_cluster_generated_test.go",
98-
interfaces = ["Cluster"],
99-
library = "//pkg/cmd/roachtest/cluster",
100-
package = "clusterstats",
101-
visibility = [
102-
":__pkg__",
103-
"//pkg/gen:__pkg__",
104-
],
105-
)

pkg/cmd/roachtest/clusterstats/exporter_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"time"
1818

1919
"github.com/cockroachdb/cockroach/pkg/cmd/roachtest/cluster"
20+
mockcluster "github.com/cockroachdb/cockroach/pkg/cmd/roachtest/cluster/mock"
2021
"github.com/cockroachdb/cockroach/pkg/cmd/roachtest/registry"
2122
"github.com/cockroachdb/cockroach/pkg/cmd/roachtest/roachtestutil"
2223
"github.com/cockroachdb/cockroach/pkg/cmd/roachtest/spec"
@@ -328,7 +329,7 @@ func TestExport(t *testing.T) {
328329
makePromQueryRange(barStat.Query, []string{"1", "2", "3"}, 5, barTS, false),
329330
})
330331
mockTest := getMockTest(t, ctrl, true, statsFileDest)
331-
mockCluster := NewMockCluster(ctrl)
332+
mockCluster := mockcluster.NewMockCluster(ctrl)
332333
mockTest.EXPECT().Name().Return("mock_name")
333334
mockTest.EXPECT().GetRunId().Return("mock_id").AnyTimes()
334335
mockCluster.EXPECT().Cloud().Times(1).Return(spec.GCE)
@@ -376,7 +377,7 @@ func TestExport(t *testing.T) {
376377
makePromQueryRange(barStat.Query, []string{"1", "2", "3"}, 5, barTS, false),
377378
})
378379
mockTest := getMockTest(t, ctrl, false, statsFileDest)
379-
mockCluster := NewMockCluster(ctrl)
380+
mockCluster := mockcluster.NewMockCluster(ctrl)
380381
statsWriter = func(ctx context.Context, tt test.Test, c cluster.Cluster, buffer *bytes.Buffer, dest string) error {
381382
require.Equal(t, mockTest, tt)
382383
require.Equal(t, mockCluster, c)

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ func UploadWorkload(
228228
default:
229229
minWorkloadBinaryVersion = MustParseVersion("v22.2.0")
230230
}
231-
232231
// If we are uploading the `current` version, skip version checking,
233232
// as the binary used is the one passed via command line flags.
234233
if !v.IsCurrent() && !v.AtLeast(minWorkloadBinaryVersion) {
@@ -239,9 +238,15 @@ func UploadWorkload(
239238
return path, err == nil, err
240239
}
241240

242-
// uploadBinaryVersion uploads the specified binary associated with
243-
// the given version to the given nodes. It returns the path of the
244-
// uploaded binaries on the nodes.
241+
// uploadBinaryVersion attempts to upload the specified binary associated with
242+
// the given version to the given nodes. If the destination binary path already
243+
// exists, assume the binary has already been uploaded previously. Returns the
244+
// path of the uploaded binaries on the nodes.
245+
//
246+
// If cockroach is the target binary and if --versions-binary-override option
247+
// is set and if version v is contained in the override map, use that version's
248+
// value, which is a local binary path as the source binary to upload instead
249+
// of using roachprod to stage.
245250
func uploadBinaryVersion(
246251
ctx context.Context,
247252
t test.Test,
@@ -256,6 +261,8 @@ func uploadBinaryVersion(
256261
var isOverridden bool
257262
switch binary {
258263
case "cockroach":
264+
// If the --versions-binary-override option is set and version v is in the
265+
// argument map, then use that version's value as the path to the binary
259266
defaultBinary, isOverridden = t.VersionsBinaryOverride()[v.String()]
260267
if isOverridden {
261268
l.Printf("using cockroach binary override for version %s: %s", v, defaultBinary)
@@ -305,7 +312,6 @@ func uploadBinaryVersion(
305312
return "", err
306313
}
307314
}
308-
309315
return dstBinary, nil
310316
}
311317

pkg/cmd/roachtest/roachtestutil/commandbuilder.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ type Command struct {
1919
Arguments []string
2020
Flags map[string]*string
2121
UseEquals bool
22+
// EnvVars e.g. COCKROACH_RANDOM_SEED=%d ./workload ...
23+
EnvVars map[string]*string
2224
}
2325

2426
// NewCommand builds a command. The format parameter can take
@@ -35,6 +37,7 @@ func NewCommand(format string, args ...interface{}) *Command {
3537
Binary: parts[0],
3638
Arguments: parts[1:],
3739
Flags: make(map[string]*string),
40+
EnvVars: make(map[string]*string),
3841
}
3942
}
4043

@@ -94,11 +97,17 @@ func (c *Command) ITEFlag(condition bool, name string, trueVal, falseVal interfa
9497
return c.Flag(name, falseVal)
9598
}
9699

100+
func (c *Command) EnvVar(name string, val interface{}) *Command {
101+
c.EnvVars[name] = stringP(fmt.Sprint(val))
102+
return c
103+
}
104+
97105
// String returns a canonical string representation of the command
98106
// which can be passed to `cluster.Run`.
99107
func (c *Command) String() string {
100108
flags := make([]string, 0, len(c.Flags))
101109
names := make([]string, 0, len(c.Flags))
110+
envVars := make([]string, 0, len(c.EnvVars))
102111
for name := range c.Flags {
103112
names = append(names, name)
104113
}
@@ -124,10 +133,13 @@ func (c *Command) String() string {
124133
flags = append(flags, strings.Join(parts, flagJoinSymbol))
125134
}
126135

127-
cmd := append(
128-
[]string{c.Binary},
129-
append(c.Arguments, flags...)...,
130-
)
136+
for name, val := range c.EnvVars {
137+
envVars = append(envVars, fmt.Sprintf("%s=%s", name, *val))
138+
}
139+
140+
cmd := append(envVars,
141+
append([]string{c.Binary},
142+
append(c.Arguments, flags...)...)...)
131143

132144
return strings.Join(cmd, " ")
133145
}

pkg/cmd/roachtest/roachtestutil/commandbuilder_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,27 @@ func TestCommand(t *testing.T) {
6060
c.Option("x")
6161
require.True(t, c.HasFlag("c"))
6262
require.Equal(t, "./cockroach workload run bank {pgurl:1} -c 10 -n 8 -x", c.String())
63+
64+
c = clone(baseCommand)
65+
c.EnvVar("COCKROACH_RANDOM_SEED", 12345)
66+
require.Equal(t, "COCKROACH_RANDOM_SEED=12345 ./cockroach workload run bank {pgurl:1}", c.String())
6367
}
6468

6569
func clone(cmd *Command) *Command {
6670
flags := make(map[string]*string)
6771
for k, v := range cmd.Flags {
6872
flags[k] = v
6973
}
74+
envVars := make(map[string]*string)
75+
for k, v := range cmd.EnvVars {
76+
envVars[k] = v
77+
}
7078

7179
return &Command{
7280
Binary: cmd.Binary,
7381
Arguments: append([]string{}, cmd.Arguments...),
7482
Flags: flags,
7583
UseEquals: cmd.UseEquals,
84+
EnvVars: envVars,
7685
}
7786
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,14 @@ mixedversion.DisableMutators(mixedversion.PreserveDowngradeOptionRandomizerMutat
389389

390390
Use this option to disable specific [mutators](#mutators) that are incompatible with the test.
391391

392+
``` go
393+
mixedversion.WithWorkloadNodes(c.WorkloadNode())
394+
```
395+
Certain workloads i.e. bank are no longer backwards compatible as of 25.3. Therefore a new best practice for using
396+
using workload during your test is to execute a workload command on a binary that matches the cluster version. Using
397+
this option tells the framework to handle staging all the binaries you need for your test on the workload node(s)
398+
during test setup.
399+
392400
### Deployment Modes
393401

394402
By default, each run of a `mixedversion` test happens in one of 3 possible _deployment modes_: `system-only`, `shared-process`, and `separate-process`. In the latter two options, the framework will create a test tenant, and tests should exercise the feature they are testing by invoking it on the tenant.

pkg/cmd/roachtest/roachtestutil/mixedversion/helper.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,14 @@ func (h *Helper) IsSkipVersionUpgrade() bool {
355355
return numReleases > 1
356356
}
357357

358+
// VersionedCockroachPath returns the correct binary path to use when
359+
// executing workload commands in user-defined hooks that will match the
360+
// current cluster's version e.g., v25.3.1/cockroach
361+
func (h *Helper) VersionedCockroachPath(rt test.Test) string {
362+
return clusterupgrade.BinaryPathForVersion(
363+
rt, h.System.FromVersion, "cockroach")
364+
}
365+
358366
// logSQL standardizes the logging when a SQL statement or query is
359367
// run using one of the Helper methods. It includes the node used as
360368
// gateway, along with the version currently running on it, for ease

0 commit comments

Comments
 (0)