Skip to content

Commit f5f94a1

Browse files
authored
REP-5894 Fall back to isMaster if hello fails. (#103)
Some migrations are from source clusters old enough to lack the `hello` command. This changeset teaches migration-verifier to fall back to `isMaster` if the `hello` command fails.
1 parent 7780de3 commit f5f94a1

File tree

6 files changed

+50
-21
lines changed

6 files changed

+50
-21
lines changed

.github/workflows/all.yml

+11
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,23 @@ on:
55
tags-ignore:
66
- '*'
77
pull_request:
8+
workflow_dispatch:
89

910
jobs:
1011
basics:
1112
strategy:
1213
fail-fast: false
1314
matrix:
15+
include:
16+
17+
# Testing fallback when `hello` isn’t implemented
18+
# (but appendOplogNote is).
19+
- mongodb_versions: [ '4.2.5', '6.0' ]
20+
topology:
21+
name: replset
22+
srcConnStr: mongodb://localhost:27020,localhost:27021,localhost:27022
23+
dstConnStr: mongodb://localhost:27030,localhost:27031,localhost:27032
24+
1425

1526
# versions are: source, destination
1627
mongodb_versions:

internal/util/clusterinfo.go

+22-15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package util
33
import (
44
"context"
55

6+
"github.com/10gen/migration-verifier/internal/logger"
67
"github.com/10gen/migration-verifier/mbson"
78
"github.com/pkg/errors"
89
"github.com/samber/lo"
@@ -22,15 +23,22 @@ const (
2223
TopologyReplset ClusterTopology = "replset"
2324
)
2425

25-
func GetClusterInfo(ctx context.Context, client *mongo.Client) (ClusterInfo, error) {
26+
func GetClusterInfo(ctx context.Context, logger *logger.Logger, client *mongo.Client) (ClusterInfo, error) {
2627
va, err := getVersionArray(ctx, client)
2728
if err != nil {
2829
return ClusterInfo{}, errors.Wrap(err, "failed to fetch version array")
2930
}
3031

31-
topology, err := getTopology(ctx, client)
32+
topology, err := getTopology(ctx, "hello", client)
3233
if err != nil {
33-
return ClusterInfo{}, errors.Wrap(err, "failed to determine topology")
34+
logger.Info().
35+
Err(err).
36+
Msgf("Failed to learn topology via %#q; falling back to %#q.", "hello", "isMaster")
37+
38+
topology, err = getTopology(ctx, "isMaster", client)
39+
if err != nil {
40+
return ClusterInfo{}, errors.Wrapf(err, "failed to learn topology via %#q", "isMaster")
41+
}
3442
}
3543

3644
return ClusterInfo{
@@ -56,23 +64,22 @@ func getVersionArray(ctx context.Context, client *mongo.Client) ([]int, error) {
5664
return va, nil
5765
}
5866

59-
func getTopology(ctx context.Context, client *mongo.Client) (ClusterTopology, error) {
67+
func getTopology(ctx context.Context, cmdName string, client *mongo.Client) (ClusterTopology, error) {
68+
6069
resp := client.Database("admin").RunCommand(
6170
ctx,
62-
bson.D{{"hello", 1}},
71+
bson.D{{cmdName, 1}},
6372
)
6473

65-
hello := struct {
66-
Msg string
67-
}{}
74+
raw, err := resp.Raw()
75+
if err != nil {
76+
return "", errors.Wrapf(err, "failed learn topology via %#q", cmdName)
77+
}
6878

69-
if err := resp.Decode(&hello); err != nil {
70-
return "", errors.Wrapf(
71-
err,
72-
"failed to decode %#q response",
73-
"hello",
74-
)
79+
hasMsg, err := mbson.RawContains(raw, "msg")
80+
if err != nil {
81+
return "", errors.Wrapf(err, "failed to check for %#q in %#q response (%v)", "msg", cmdName, raw)
7582
}
7683

77-
return lo.Ternary(hello.Msg == "isdbgrid", TopologySharded, TopologyReplset), nil
84+
return lo.Ternary(hasMsg, TopologySharded, TopologyReplset), nil
7885
}

internal/verifier/change_stream_test.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,11 @@ func (suite *IntegrationTestSuite) testInsertsBeforeWritesOff(docsCount int) {
687687

688688
func (suite *IntegrationTestSuite) TestCreateForbidden() {
689689
ctx := suite.Context()
690-
buildInfo, err := util.GetClusterInfo(ctx, suite.srcMongoClient)
690+
buildInfo, err := util.GetClusterInfo(
691+
ctx,
692+
logger.NewDefaultLogger(),
693+
suite.srcMongoClient,
694+
)
691695
suite.Require().NoError(err)
692696

693697
if buildInfo.VersionArray[0] < 6 {
@@ -724,7 +728,11 @@ func (suite *IntegrationTestSuite) TestCreateForbidden() {
724728

725729
func (suite *IntegrationTestSuite) TestTolerateDestinationCollMod() {
726730
ctx := suite.Context()
727-
buildInfo, err := util.GetClusterInfo(ctx, suite.dstMongoClient)
731+
buildInfo, err := util.GetClusterInfo(
732+
ctx,
733+
logger.NewDefaultLogger(),
734+
suite.dstMongoClient,
735+
)
728736
suite.Require().NoError(err)
729737

730738
if buildInfo.VersionArray[0] < 6 {

internal/verifier/integration_test_suite.go

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"time"
77

88
"github.com/10gen/migration-verifier/contextplus"
9+
"github.com/10gen/migration-verifier/internal/logger"
910
"github.com/10gen/migration-verifier/internal/util"
1011
mapset "github.com/deckarep/golang-set/v2"
1112
"github.com/pkg/errors"
@@ -142,6 +143,7 @@ func (suite *IntegrationTestSuite) TearDownTest() {
142143
func (suite *IntegrationTestSuite) GetTopology(client *mongo.Client) util.ClusterTopology {
143144
clusterInfo, err := util.GetClusterInfo(
144145
suite.Context(),
146+
logger.NewDefaultLogger(),
145147
client,
146148
)
147149
suite.Require().NoError(err, "should fetch src cluster info")

internal/verifier/metadata_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package verifier
33
import (
44
"fmt"
55

6+
"github.com/10gen/migration-verifier/internal/logger"
67
"github.com/10gen/migration-verifier/internal/util"
78
"github.com/10gen/migration-verifier/mslices"
89
"github.com/samber/lo"
@@ -13,10 +14,10 @@ import (
1314

1415
func (suite *IntegrationTestSuite) TestShardingMismatch() {
1516
ctx := suite.Context()
16-
srcInfo, err := util.GetClusterInfo(ctx, suite.srcMongoClient)
17+
srcInfo, err := util.GetClusterInfo(ctx, logger.NewDefaultLogger(), suite.srcMongoClient)
1718
suite.Require().NoError(err, "should fetch src cluster info")
1819

19-
dstInfo, err := util.GetClusterInfo(ctx, suite.dstMongoClient)
20+
dstInfo, err := util.GetClusterInfo(ctx, logger.NewDefaultLogger(), suite.dstMongoClient)
2021
suite.Require().NoError(err, "should fetch dst cluster info")
2122

2223
dbname := suite.DBNameForTest()

internal/verifier/uri.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func (verifier *Verifier) SetSrcURI(ctx context.Context, uri string) error {
1717
return errors.Wrapf(err, "failed to connect to source %#q", uri)
1818
}
1919

20-
clusterInfo, err := util.GetClusterInfo(ctx, verifier.srcClient)
20+
clusterInfo, err := util.GetClusterInfo(ctx, verifier.logger, verifier.srcClient)
2121
if err != nil {
2222
return errors.Wrap(err, "failed to read source cluster info")
2323
}
@@ -50,7 +50,7 @@ func (verifier *Verifier) SetDstURI(ctx context.Context, uri string) error {
5050
return errors.Wrapf(err, "failed to connect to destination %#q", uri)
5151
}
5252

53-
clusterInfo, err := util.GetClusterInfo(ctx, verifier.dstClient)
53+
clusterInfo, err := util.GetClusterInfo(ctx, verifier.logger, verifier.dstClient)
5454
if err != nil {
5555
return errors.Wrap(err, "failed to read destination build info")
5656
}

0 commit comments

Comments
 (0)