github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/relay/file_test.go (about) 1 // Copyright 2019 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package relay 15 16 import ( 17 "os" 18 "path/filepath" 19 20 . "github.com/pingcap/check" 21 "github.com/pingcap/errors" 22 "github.com/pingcap/tiflow/dm/pkg/terror" 23 "github.com/pingcap/tiflow/dm/pkg/utils" 24 ) 25 26 var _ = Suite(&testFileSuite{}) 27 28 type testFileSuite struct{} 29 30 func (t *testFileSuite) TestCollectBinlogFiles(c *C) { 31 var ( 32 valid = []string{ 33 "mysql-bin.000001", 34 "mysql-bin.000002", 35 "mysql-bin.000003", 36 "mysql-bin.000004", 37 } 38 invalid = []string{ 39 "mysql-bin.invalid01", 40 "mysql-bin.invalid02", 41 } 42 meta = []string{ 43 utils.MetaFilename, 44 utils.MetaFilename + ".tmp", 45 } 46 ) 47 48 files, err := CollectAllBinlogFiles("") 49 c.Assert(err, NotNil) 50 c.Assert(files, IsNil) 51 52 dir := c.MkDir() 53 54 // create all valid binlog files 55 for _, fn := range valid { 56 err = os.WriteFile(filepath.Join(dir, fn), nil, 0o600) 57 c.Assert(err, IsNil) 58 } 59 files, err = CollectAllBinlogFiles(dir) 60 c.Assert(err, IsNil) 61 c.Assert(files, DeepEquals, valid) 62 63 // create some invalid binlog files 64 for _, fn := range invalid { 65 err = os.WriteFile(filepath.Join(dir, fn), nil, 0o600) 66 c.Assert(err, IsNil) 67 } 68 files, err = CollectAllBinlogFiles(dir) 69 c.Assert(err, IsNil) 70 c.Assert(files, DeepEquals, valid) 71 72 // create some invalid meta files 73 for _, fn := range meta { 74 err = os.WriteFile(filepath.Join(dir, fn), nil, 0o600) 75 c.Assert(err, IsNil) 76 } 77 files, err = CollectAllBinlogFiles(dir) 78 c.Assert(err, IsNil) 79 c.Assert(files, DeepEquals, valid) 80 81 // collect newer files, none 82 files, err = CollectBinlogFilesCmp(dir, valid[len(valid)-1], FileCmpBigger) 83 c.Assert(err, IsNil) 84 c.Assert(files, DeepEquals, []string{}) 85 86 // collect newer files, some 87 files, err = CollectBinlogFilesCmp(dir, valid[0], FileCmpBigger) 88 c.Assert(err, IsNil) 89 c.Assert(files, DeepEquals, valid[1:]) 90 91 // collect newer or equal files, all 92 files, err = CollectBinlogFilesCmp(dir, valid[0], FileCmpBiggerEqual) 93 c.Assert(err, IsNil) 94 c.Assert(files, DeepEquals, valid) 95 96 // collect newer or equal files, some 97 files, err = CollectBinlogFilesCmp(dir, valid[1], FileCmpBiggerEqual) 98 c.Assert(err, IsNil) 99 c.Assert(files, DeepEquals, valid[1:]) 100 101 // collect older files, none 102 files, err = CollectBinlogFilesCmp(dir, valid[0], FileCmpLess) 103 c.Assert(err, IsNil) 104 c.Assert(files, DeepEquals, []string{}) 105 106 // collect older files, some 107 files, err = CollectBinlogFilesCmp(dir, valid[len(valid)-1], FileCmpLess) 108 c.Assert(err, IsNil) 109 c.Assert(files, DeepEquals, valid[:len(valid)-1]) 110 } 111 112 func (t *testFileSuite) TestCollectBinlogFilesCmp(c *C) { 113 var ( 114 dir string 115 baseFile string 116 cmp = FileCmpEqual 117 binlogFiles = []string{ 118 "mysql-bin.000001", 119 "mysql-bin.000002", 120 "mysql-bin.000003", 121 "mysql-bin.000004", 122 } 123 ) 124 125 // empty dir 126 files, err := CollectBinlogFilesCmp(dir, baseFile, cmp) 127 c.Assert(terror.ErrEmptyRelayDir.Equal(err), IsTrue) 128 c.Assert(files, IsNil) 129 130 // empty base filename, not found 131 dir = c.MkDir() 132 files, err = CollectBinlogFilesCmp(dir, baseFile, cmp) 133 c.Assert(errors.IsNotFound(err), IsTrue) 134 c.Assert(files, IsNil) 135 136 // base file not found 137 baseFile = utils.MetaFilename 138 files, err = CollectBinlogFilesCmp(dir, baseFile, cmp) 139 c.Assert(errors.IsNotFound(err), IsTrue) 140 c.Assert(files, IsNil) 141 142 // create a meta file 143 filename := filepath.Join(dir, utils.MetaFilename) 144 err = os.WriteFile(filename, nil, 0o600) 145 c.Assert(err, IsNil) 146 147 // invalid base filename, is a meta filename 148 files, err = CollectBinlogFilesCmp(dir, baseFile, cmp) 149 c.Assert(err, ErrorMatches, ".*invalid binlog filename.*") 150 c.Assert(files, IsNil) 151 152 // create some binlog files 153 for _, f := range binlogFiles { 154 filename = filepath.Join(dir, f) 155 err = os.WriteFile(filename, nil, 0o600) 156 c.Assert(err, IsNil) 157 } 158 159 // > base file 160 cmp = FileCmpBigger 161 var i int 162 for i, baseFile = range binlogFiles { 163 files, err = CollectBinlogFilesCmp(dir, baseFile, cmp) 164 c.Assert(err, IsNil) 165 c.Assert(files, DeepEquals, binlogFiles[i+1:]) 166 } 167 168 // >= base file 169 cmp = FileCmpBiggerEqual 170 for i, baseFile = range binlogFiles { 171 files, err = CollectBinlogFilesCmp(dir, baseFile, cmp) 172 c.Assert(err, IsNil) 173 c.Assert(files, DeepEquals, binlogFiles[i:]) 174 } 175 176 // < base file 177 cmp = FileCmpLess 178 for i, baseFile = range binlogFiles { 179 files, err = CollectBinlogFilesCmp(dir, baseFile, cmp) 180 c.Assert(err, IsNil) 181 c.Assert(files, DeepEquals, binlogFiles[:i]) 182 } 183 184 // add a basename mismatch binlog file 185 filename = filepath.Join(dir, "bin-mysql.100000") 186 err = os.WriteFile(filename, nil, 0o600) 187 c.Assert(err, IsNil) 188 189 // test again, should ignore it 190 for i, baseFile = range binlogFiles { 191 files, err = CollectBinlogFilesCmp(dir, baseFile, cmp) 192 c.Assert(err, IsNil) 193 c.Assert(files, DeepEquals, binlogFiles[:i]) 194 } 195 196 // other cmp not supported yet 197 cmps := []FileCmp{FileCmpLessEqual, FileCmpEqual} 198 for _, cmp = range cmps { 199 files, err = CollectBinlogFilesCmp(dir, baseFile, cmp) 200 c.Assert(err, ErrorMatches, ".*not supported.*") 201 c.Assert(files, IsNil) 202 } 203 } 204 205 func (t *testFileSuite) TestGetFirstBinlogName(c *C) { 206 var ( 207 baseDir = c.MkDir() 208 uuid = "b60868af-5a6f-11e9-9ea3-0242ac160006.000001" 209 subDir = filepath.Join(baseDir, uuid) 210 ) 211 212 // sub directory not exist 213 name, err := getFirstBinlogName(baseDir, uuid) 214 c.Assert(err, ErrorMatches, ".*(no such file or directory|The system cannot find the file specified).*") 215 c.Assert(name, Equals, "") 216 217 // empty directory 218 err = os.MkdirAll(subDir, 0o700) 219 c.Assert(err, IsNil) 220 name, err = getFirstBinlogName(baseDir, uuid) 221 c.Assert(err, ErrorMatches, ".*not found.*") 222 c.Assert(name, Equals, "") 223 224 // has file, but not a valid binlog file. Now the error message is binlog files not found 225 filename := "invalid.bin" 226 err = os.WriteFile(filepath.Join(subDir, filename), nil, 0o600) 227 c.Assert(err, IsNil) 228 _, err = getFirstBinlogName(baseDir, uuid) 229 c.Assert(err, ErrorMatches, ".*not found.*") 230 err = os.Remove(filepath.Join(subDir, filename)) 231 c.Assert(err, IsNil) 232 233 // has a valid binlog file 234 filename = "z-mysql-bin.000002" // z prefix, make it become not the _first_ if possible. 235 err = os.WriteFile(filepath.Join(subDir, filename), nil, 0o600) 236 c.Assert(err, IsNil) 237 name, err = getFirstBinlogName(baseDir, uuid) 238 c.Assert(err, IsNil) 239 c.Assert(name, Equals, filename) 240 241 // has one more earlier binlog file 242 filename = "z-mysql-bin.000001" 243 err = os.WriteFile(filepath.Join(subDir, filename), nil, 0o600) 244 c.Assert(err, IsNil) 245 name, err = getFirstBinlogName(baseDir, uuid) 246 c.Assert(err, IsNil) 247 c.Assert(name, Equals, filename) 248 249 // has a meta file 250 err = os.WriteFile(filepath.Join(subDir, utils.MetaFilename), nil, 0o600) 251 c.Assert(err, IsNil) 252 name, err = getFirstBinlogName(baseDir, uuid) 253 c.Assert(err, IsNil) 254 c.Assert(name, Equals, filename) 255 } 256 257 func (t *testFileSuite) TestFileSizeUpdated(c *C) { 258 var ( 259 filename = "mysql-bin.000001" 260 filePath = filepath.Join(c.MkDir(), filename) 261 data = []byte("meaningless file content") 262 latestSize = int64(len(data)) 263 ) 264 265 // file not exists 266 cmp, err := fileSizeUpdated(filePath, latestSize) 267 c.Assert(err, ErrorMatches, ".*(no such file or directory|The system cannot find the file specified).*") 268 c.Assert(cmp, Equals, 0) 269 270 // create and write the file 271 err = os.WriteFile(filePath, data, 0o600) 272 c.Assert(err, IsNil) 273 274 // equal 275 cmp, err = fileSizeUpdated(filePath, latestSize) 276 c.Assert(err, IsNil) 277 c.Assert(cmp, Equals, 0) 278 279 // less than 280 cmp, err = fileSizeUpdated(filePath, latestSize+1) 281 c.Assert(err, IsNil) 282 c.Assert(cmp, Equals, -1) 283 284 // greater than 285 cmp, err = fileSizeUpdated(filePath, latestSize-1) 286 c.Assert(err, IsNil) 287 c.Assert(cmp, Equals, 1) 288 }