@@ -14,13 +14,16 @@ import (
14
14
15
15
"github.com/cockroachdb/cockroach/pkg/cmd/roachtest/cluster"
16
16
"github.com/cockroachdb/cockroach/pkg/cmd/roachtest/option"
17
+ "github.com/cockroachdb/cockroach/pkg/cmd/roachtest/registry"
18
+ "github.com/cockroachdb/cockroach/pkg/cmd/roachtest/roachtestutil"
17
19
"github.com/cockroachdb/cockroach/pkg/cmd/roachtest/roachtestutil/clusterupgrade"
18
20
"github.com/cockroachdb/cockroach/pkg/cmd/roachtest/roachtestutil/mixedversion"
19
21
"github.com/cockroachdb/cockroach/pkg/cmd/roachtest/test"
20
22
"github.com/cockroachdb/cockroach/pkg/roachprod/install"
21
23
"github.com/cockroachdb/cockroach/pkg/roachprod/logger"
22
24
"github.com/cockroachdb/cockroach/pkg/storage"
23
25
"github.com/cockroachdb/cockroach/pkg/testutils/release"
26
+ "github.com/cockroachdb/cockroach/pkg/ts/tspb"
24
27
"github.com/cockroachdb/cockroach/pkg/util/timeutil"
25
28
"github.com/cockroachdb/cockroach/pkg/util/version"
26
29
)
@@ -108,6 +111,7 @@ func runVersionUpgrade(ctx context.Context, t test.Test, c cluster.Cluster) {
108
111
}
109
112
110
113
mvt := mixedversion .NewTest (testCtx , t , t .L (), c , c .All (), opts ... )
114
+
111
115
mvt .InMixedVersion (
112
116
"maybe run backup" ,
113
117
func (ctx context.Context , l * logger.Logger , rng * rand.Rand , h * mixedversion.Helper ) error {
@@ -287,3 +291,92 @@ for i in 1 2 3 4; do
287
291
done
288
292
` )
289
293
}
294
+
295
+ // This is a regression test for a race detailed in
296
+ // https://github.com/cockroachdb/cockroach/issues/138342, where it became
297
+ // possible for an HTTP request to cause a fatal error if the sql server
298
+ // did not initialize the cluster version in time.
299
+ func registerHTTPRestart (r registry.Registry ) {
300
+ r .Add (registry.TestSpec {
301
+ Name : "http-register-routes/mixed-version" ,
302
+ Owner : registry .OwnerObservability ,
303
+ Cluster : r .MakeClusterSpec (4 ),
304
+ CompatibleClouds : registry .AllClouds ,
305
+ Suites : registry .Suites (registry .MixedVersion , registry .Nightly ),
306
+ Randomized : true ,
307
+ Run : runHTTPRestart ,
308
+ Timeout : 1 * time .Hour ,
309
+ })
310
+ }
311
+
312
+ func runHTTPRestart (ctx context.Context , t test.Test , c cluster.Cluster ) {
313
+ mvt := mixedversion .NewTest (ctx , t , t .L (), c ,
314
+ c .CRDBNodes (),
315
+ mixedversion .AlwaysUseLatestPredecessors ,
316
+ )
317
+
318
+ // Any http request requiring auth will do.
319
+ httpReq := tspb.TimeSeriesQueryRequest {
320
+ StartNanos : timeutil .Now ().UnixNano () - 10 * time .Second .Nanoseconds (),
321
+ EndNanos : timeutil .Now ().UnixNano (),
322
+ // Ask for 10s intervals.
323
+ SampleNanos : (10 * time .Second ).Nanoseconds (),
324
+ Queries : []tspb.Query {{
325
+ Name : "cr.node.sql.service.latency-p90" ,
326
+ SourceAggregator : tspb .TimeSeriesQueryAggregator_MAX .Enum (),
327
+ }},
328
+ }
329
+
330
+ httpCall := func (ctx context.Context , node int , l * logger.Logger , useSystemTenant bool ) {
331
+ logEvery := roachtestutil .Every (1 * time .Second )
332
+ var clientOpts []func (opts * roachtestutil.RoachtestHTTPOptions )
333
+ var urlOpts []option.OptionFunc
334
+ if useSystemTenant {
335
+ clientOpts = append (clientOpts , roachtestutil .VirtualCluster (install .SystemInterfaceName ))
336
+ urlOpts = append (urlOpts , option .VirtualClusterName (install .SystemInterfaceName ))
337
+ }
338
+ client := roachtestutil .DefaultHTTPClient (c , l , clientOpts ... )
339
+ adminUrls , err := c .ExternalAdminUIAddr (ctx , l , c .Node (node ), urlOpts ... )
340
+ if err != nil {
341
+ t .Fatal (err )
342
+ }
343
+ url := "https://" + adminUrls [0 ] + "/ts/query"
344
+ l .Printf ("Sending requests to %s" , url )
345
+
346
+ var response tspb.TimeSeriesQueryResponse
347
+ // Eventually we should see a successful request.
348
+ reqSuccess := false
349
+ for {
350
+ select {
351
+ case <- ctx .Done ():
352
+ if ! reqSuccess {
353
+ t .Fatalf ("n%d: No successful http requests made." , node )
354
+ }
355
+ return
356
+ default :
357
+ }
358
+ if err := client .PostProtobuf (ctx , url , & httpReq , & response ); err != nil {
359
+ if logEvery .ShouldLog () {
360
+ l .Printf ("n%d: Error posting protobuf: %s" , node , err )
361
+ }
362
+ continue
363
+ }
364
+ reqSuccess = true
365
+ }
366
+ }
367
+
368
+ for _ , n := range c .CRDBNodes () {
369
+ mvt .BackgroundFunc ("HTTP requests to system tenant" , func (ctx context.Context , l * logger.Logger , rng * rand.Rand , h * mixedversion.Helper ) error {
370
+ httpCall (ctx , n , l , true /* useSystemTenant */ )
371
+ return nil
372
+ })
373
+ mvt .BackgroundFunc ("HTTP requests to secondary tenant" , func (ctx context.Context , l * logger.Logger , rng * rand.Rand , h * mixedversion.Helper ) error {
374
+ if h .DeploymentMode () == mixedversion .SystemOnlyDeployment {
375
+ return nil
376
+ }
377
+ httpCall (ctx , n , l , false /* useSystemTenant */ )
378
+ return nil
379
+ })
380
+ }
381
+ mvt .Run ()
382
+ }
0 commit comments