github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/version/version_test.go (about) 1 // Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0. 2 3 package version 4 5 import ( 6 "context" 7 "fmt" 8 "testing" 9 10 "github.com/coreos/go-semver/semver" 11 . "github.com/pingcap/check" 12 "github.com/pingcap/kvproto/pkg/metapb" 13 pd "github.com/tikv/pd/client" 14 15 "github.com/pingcap/br/pkg/version/build" 16 ) 17 18 type checkSuite struct{} 19 20 var _ = Suite(&checkSuite{}) 21 22 func TestT(t *testing.T) { 23 TestingT(t) 24 } 25 26 type mockPDClient struct { 27 pd.Client 28 getAllStores func() []*metapb.Store 29 } 30 31 func (m *mockPDClient) GetAllStores(ctx context.Context, opts ...pd.GetStoreOption) ([]*metapb.Store, error) { 32 if m.getAllStores != nil { 33 return m.getAllStores(), nil 34 } 35 return []*metapb.Store{}, nil 36 } 37 38 func tiflash(version string) []*metapb.Store { 39 return []*metapb.Store{ 40 {Version: version, Labels: []*metapb.StoreLabel{{Key: "engine", Value: "tiflash"}}}, 41 } 42 } 43 44 func (s *checkSuite) TestCheckClusterVersion(c *C) { 45 mock := mockPDClient{ 46 Client: nil, 47 } 48 49 { 50 build.ReleaseVersion = "v4.0.5" 51 mock.getAllStores = func() []*metapb.Store { 52 return tiflash("v4.0.0-rc.1") 53 } 54 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) 55 c.Assert(err, ErrorMatches, `incompatible.*version v4.0.0-rc.1, try update it to 4.0.0.*`) 56 } 57 58 { 59 build.ReleaseVersion = "v3.0.14" 60 mock.getAllStores = func() []*metapb.Store { 61 return tiflash("v3.1.0-beta.1") 62 } 63 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) 64 c.Assert(err, ErrorMatches, `incompatible.*version v3.1.0-beta.1, try update it to 3.1.0.*`) 65 } 66 67 { 68 build.ReleaseVersion = "v3.1.1" 69 mock.getAllStores = func() []*metapb.Store { 70 return tiflash("v3.0.15") 71 } 72 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) 73 c.Assert(err, ErrorMatches, `incompatible.*version v3.0.15, try update it to 3.1.0.*`) 74 } 75 76 { 77 build.ReleaseVersion = "v3.1.0-beta.2" 78 mock.getAllStores = func() []*metapb.Store { 79 return []*metapb.Store{{Version: minTiKVVersion.String()}} 80 } 81 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) 82 c.Assert(err, IsNil) 83 } 84 85 { 86 build.ReleaseVersion = "v3.1.0-beta.2" 87 mock.getAllStores = func() []*metapb.Store { 88 // TiKV is too lower to support BR 89 return []*metapb.Store{{Version: `v2.1.0`}} 90 } 91 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) 92 c.Assert(err, ErrorMatches, ".*TiKV .* don't support BR, please upgrade cluster .*") 93 } 94 95 { 96 build.ReleaseVersion = "v3.1.0" 97 mock.getAllStores = func() []*metapb.Store { 98 // TiKV v3.1.0-beta.2 is incompatible with BR v3.1.0 99 return []*metapb.Store{{Version: minTiKVVersion.String()}} 100 } 101 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) 102 c.Assert(err, ErrorMatches, "TiKV .* mismatch, please .*") 103 } 104 105 { 106 build.ReleaseVersion = "v3.1.0" 107 mock.getAllStores = func() []*metapb.Store { 108 // TiKV v4.0.0-rc major version mismatch with BR v3.1.0 109 return []*metapb.Store{{Version: "v4.0.0-rc"}} 110 } 111 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) 112 c.Assert(err, ErrorMatches, "TiKV .* major version mismatch, please .*") 113 } 114 115 { 116 build.ReleaseVersion = "v4.0.0-rc.2" 117 mock.getAllStores = func() []*metapb.Store { 118 // TiKV v4.0.0-rc.2 is incompatible with BR v4.0.0-beta.1 119 return []*metapb.Store{{Version: "v4.0.0-beta.1"}} 120 } 121 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) 122 c.Assert(err, ErrorMatches, "TiKV .* mismatch, please .*") 123 } 124 125 { 126 build.ReleaseVersion = "v4.0.0-rc.2" 127 mock.getAllStores = func() []*metapb.Store { 128 // TiKV v4.0.0-rc.1 with BR v4.0.0-rc.2 is ok 129 return []*metapb.Store{{Version: "v4.0.0-rc.1"}} 130 } 131 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) 132 c.Assert(err, IsNil) 133 } 134 135 { 136 // Even across many patch versions, backup should be usable. 137 mock.getAllStores = func() []*metapb.Store { 138 return []*metapb.Store{{Version: "v4.0.0-rc.1"}} 139 } 140 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBackup(semver.New("4.0.12"))) 141 c.Assert(err, IsNil) 142 } 143 144 { 145 // Restore across major version isn't allowed. 146 mock.getAllStores = func() []*metapb.Store { 147 return []*metapb.Store{{Version: "v4.0.0-rc.1"}} 148 } 149 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBackup(semver.New("5.0.0-rc"))) 150 c.Assert(err, Not(IsNil)) 151 } 152 153 { 154 build.ReleaseVersion = "v4.0.0-rc.1" 155 mock.getAllStores = func() []*metapb.Store { 156 // TiKV v4.0.0-rc.2 with BR v4.0.0-rc.1 is ok 157 return []*metapb.Store{{Version: "v4.0.0-rc.2"}} 158 } 159 err := CheckClusterVersion(context.Background(), &mock, CheckVersionForBR) 160 c.Assert(err, IsNil) 161 } 162 } 163 164 func (s *checkSuite) TestCompareVersion(c *C) { 165 c.Assert(semver.New("4.0.0-rc").Compare(*semver.New("4.0.0-rc.2")), Equals, -1) 166 c.Assert(semver.New("4.0.0-beta.3").Compare(*semver.New("4.0.0-rc.2")), Equals, -1) 167 c.Assert(semver.New("4.0.0-rc.1").Compare(*semver.New("4.0.0")), Equals, -1) 168 c.Assert(semver.New("4.0.0-beta.1").Compare(*semver.New("4.0.0")), Equals, -1) 169 c.Assert(semver.New(removeVAndHash("4.0.0-rc-35-g31dae220")).Compare(*semver.New("4.0.0-rc.2")), Equals, -1) 170 c.Assert(semver.New(removeVAndHash("4.0.0-9-g30f0b014")).Compare(*semver.New("4.0.0-rc.1")), Equals, 1) 171 c.Assert(semver.New(removeVAndHash("v3.0.0-beta-211-g09beefbe0-dirty")). 172 Compare(*semver.New("3.0.0-beta")), Equals, 0) 173 c.Assert(semver.New(removeVAndHash("v3.0.5-dirty")). 174 Compare(*semver.New("3.0.5")), Equals, 0) 175 c.Assert(semver.New(removeVAndHash("v3.0.5-beta.12-dirty")). 176 Compare(*semver.New("3.0.5-beta.12")), Equals, 0) 177 c.Assert(semver.New(removeVAndHash("v2.1.0-rc.1-7-g38c939f-dirty")). 178 Compare(*semver.New("2.1.0-rc.1")), Equals, 0) 179 } 180 181 func (s *checkSuite) TestNextMajorVersion(c *C) { 182 build.ReleaseVersion = "v4.0.0-rc.1" 183 c.Assert(NextMajorVersion().String(), Equals, "5.0.0") 184 build.ReleaseVersion = "4.0.0-rc-35-g31dae220" 185 c.Assert(NextMajorVersion().String(), Equals, "5.0.0") 186 build.ReleaseVersion = "4.0.0-9-g30f0b014" 187 c.Assert(NextMajorVersion().String(), Equals, "5.0.0") 188 189 build.ReleaseVersion = "v5.0.0-rc.2" 190 c.Assert(NextMajorVersion().String(), Equals, "6.0.0") 191 build.ReleaseVersion = "v5.0.0-master" 192 c.Assert(NextMajorVersion().String(), Equals, "6.0.0") 193 } 194 195 func (s *checkSuite) TestExtractTiDBVersion(c *C) { 196 vers, err := ExtractTiDBVersion("5.7.10-TiDB-v2.1.0-rc.1-7-g38c939f") 197 c.Assert(err, IsNil) 198 c.Assert(*vers, Equals, *semver.New("2.1.0-rc.1")) 199 200 vers, err = ExtractTiDBVersion("5.7.10-TiDB-v2.0.4-1-g06a0bf5") 201 c.Assert(err, IsNil) 202 c.Assert(*vers, Equals, *semver.New("2.0.4")) 203 204 vers, err = ExtractTiDBVersion("5.7.10-TiDB-v2.0.7") 205 c.Assert(err, IsNil) 206 c.Assert(*vers, Equals, *semver.New("2.0.7")) 207 208 vers, err = ExtractTiDBVersion("8.0.12-TiDB-v3.0.5-beta.12") 209 c.Assert(err, IsNil) 210 c.Assert(*vers, Equals, *semver.New("3.0.5-beta.12")) 211 212 vers, err = ExtractTiDBVersion("5.7.25-TiDB-v3.0.0-beta-211-g09beefbe0-dirty") 213 c.Assert(err, IsNil) 214 c.Assert(*vers, Equals, *semver.New("3.0.0-beta")) 215 216 vers, err = ExtractTiDBVersion("8.0.12-TiDB-v3.0.5-dirty") 217 c.Assert(err, IsNil) 218 c.Assert(*vers, Equals, *semver.New("3.0.5")) 219 220 vers, err = ExtractTiDBVersion("8.0.12-TiDB-v3.0.5-beta.12-dirty") 221 c.Assert(err, IsNil) 222 c.Assert(*vers, Equals, *semver.New("3.0.5-beta.12")) 223 224 vers, err = ExtractTiDBVersion("5.7.10-TiDB-v2.1.0-rc.1-7-g38c939f-dirty") 225 c.Assert(err, IsNil) 226 c.Assert(*vers, Equals, *semver.New("2.1.0-rc.1")) 227 228 _, err = ExtractTiDBVersion("") 229 c.Assert(err, ErrorMatches, "not a valid TiDB version.*") 230 231 _, err = ExtractTiDBVersion("8.0.12") 232 c.Assert(err, ErrorMatches, "not a valid TiDB version.*") 233 234 _, err = ExtractTiDBVersion("not-a-valid-version") 235 c.Assert(err, NotNil) 236 } 237 238 func (s *checkSuite) TestCheckVersion(c *C) { 239 err := CheckVersion("TiNB", *semver.New("2.3.5"), *semver.New("2.1.0"), *semver.New("3.0.0")) 240 c.Assert(err, IsNil) 241 242 err = CheckVersion("TiNB", *semver.New("2.1.0"), *semver.New("2.3.5"), *semver.New("3.0.0")) 243 c.Assert(err, ErrorMatches, "TiNB version too old.*") 244 245 err = CheckVersion("TiNB", *semver.New("3.1.0"), *semver.New("2.3.5"), *semver.New("3.0.0")) 246 c.Assert(err, ErrorMatches, "TiNB version too new.*") 247 248 err = CheckVersion("TiNB", *semver.New("3.0.0-beta"), *semver.New("2.3.5"), *semver.New("3.0.0")) 249 c.Assert(err, ErrorMatches, "TiNB version too new.*") 250 } 251 252 type versionEqualsC struct{} 253 254 func (v versionEqualsC) Info() *CheckerInfo { 255 return &CheckerInfo{ 256 Name: "VersionEquals", 257 Params: []string{"source", "target"}, 258 } 259 } 260 261 func (v versionEqualsC) Check(params []interface{}, names []string) (result bool, error string) { 262 source := params[0].(*semver.Version) 263 target := params[1].(*semver.Version) 264 265 if source == nil || target == nil { 266 if target == source { 267 return true, "" 268 } 269 return false, fmt.Sprintf("one of version is nil but another is not (%s and %s)", params[0], params[1]) 270 } 271 272 if source.Equal(*target) { 273 return true, "" 274 } 275 return false, fmt.Sprintf("version not equal (%s vs %s)", source, target) 276 } 277 278 var versionEquals versionEqualsC 279 280 func (s *checkSuite) TestNormalizeBackupVersion(c *C) { 281 cases := []struct { 282 target string 283 source string 284 }{ 285 {"4.0.0", `"4.0.0\n"`}, 286 {"5.0.0-rc.x", `"5.0.0-rc.x\n"`}, 287 {"5.0.0-rc.x", `5.0.0-rc.x`}, 288 {"4.0.12", `"4.0.12"` + "\n"}, 289 {"<error-version>", ""}, 290 } 291 292 for _, testCase := range cases { 293 target, _ := semver.NewVersion(testCase.target) 294 source := NormalizeBackupVersion(testCase.source) 295 c.Assert(source, versionEquals, target) 296 } 297 }