github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/v1workermeta/api_test.go (about) 1 // Copyright 2020 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 v1workermeta 15 16 import ( 17 "io" 18 "os" 19 "path/filepath" 20 "runtime" 21 22 . "github.com/pingcap/check" 23 "github.com/pingcap/tiflow/dm/pb" 24 "github.com/pingcap/tiflow/dm/pkg/terror" 25 "github.com/pingcap/tiflow/dm/pkg/utils" 26 ) 27 28 type testAPI struct{} 29 30 var _ = Suite(&testAPI{}) 31 32 func (t *testAPI) TestAPI(c *C) { 33 // nolint:dogsled 34 _, currFile, _, _ := runtime.Caller(0) 35 srcMetaPath := filepath.Join(filepath.Dir(currFile), "v106_data_for_test") 36 srcDBPath := filepath.Join(srcMetaPath, "kv") 37 38 oldMetaPath := metaPath 39 oldDBPath := dbPath 40 defer func() { 41 metaPath = oldMetaPath 42 dbPath = oldDBPath 43 }() 44 45 metaPath = c.MkDir() 46 dbPath = filepath.Join(metaPath, "kv") 47 48 // copy test data to a temp directory. 49 copyDir(c, dbPath, srcDBPath) 50 51 // get subtasks meta. 52 meta, err := GetSubtasksMeta() 53 c.Assert(err, IsNil) 54 55 // verify tasks meta. 56 // - task_single: 57 // - no shard task, Running stage. 58 // - task_shard 59 // - shard task, Paused stage. 60 c.Assert(meta, HasLen, 2) 61 c.Assert(meta, HasKey, "task_single") 62 c.Assert(meta, HasKey, "task_shard") 63 c.Assert(meta["task_single"].Stage, Equals, pb.Stage_Running) 64 c.Assert(meta["task_shard"].Stage, Equals, pb.Stage_Paused) 65 66 taskSingleCfg, err := SubTaskConfigFromV1TOML(meta["task_single"].Task) 67 c.Assert(err, IsNil) 68 c.Assert(taskSingleCfg.IsSharding, IsFalse) 69 c.Assert(taskSingleCfg.MydumperConfig.ChunkFilesize, Equals, "64") 70 71 taskShardCfg, err := SubTaskConfigFromV1TOML(meta["task_shard"].Task) 72 c.Assert(err, IsNil) 73 c.Assert(taskShardCfg.IsSharding, IsTrue) 74 c.Assert(taskSingleCfg.MydumperConfig.ChunkFilesize, Equals, "64") 75 76 // try to get meta again, the same as before. 77 meta2, err := GetSubtasksMeta() 78 c.Assert(err, IsNil) 79 c.Assert(meta2, DeepEquals, meta) 80 81 // remove all metadata. 82 c.Assert(RemoveSubtasksMeta(), IsNil) 83 84 // verify removed. 85 c.Assert(utils.IsDirExists(metaPath), IsFalse) 86 87 // try to get meta again, nothing exists. 88 meta3, err := GetSubtasksMeta() 89 c.Assert(err, IsNil) 90 c.Assert(meta3, IsNil) 91 92 // remove empty path is invalid. 93 c.Assert(terror.ErrInvalidV1WorkerMetaPath.Equal(RemoveSubtasksMeta()), IsTrue) 94 95 // remove an invalid meta path. 96 metaPath = c.MkDir() 97 dbPath = filepath.Join(metaPath, "kv") 98 c.Assert(os.Mkdir(dbPath, 0o644), IsNil) 99 c.Assert(terror.ErrInvalidV1WorkerMetaPath.Equal(RemoveSubtasksMeta()), IsTrue) 100 } 101 102 func copyDir(c *C, dst, src string) { 103 si, err := os.Stat(src) 104 c.Assert(err, IsNil) 105 if !si.IsDir() { 106 c.Fatalf("source %s is not a directory", src) 107 } 108 109 _, err = os.Stat(dst) 110 if err != nil && !os.IsNotExist(err) { 111 c.Fatalf("fail to get stat for source %s", src) 112 } 113 if err == nil { 114 c.Fatalf("destination %s already exists", dst) 115 } 116 117 err = os.MkdirAll(dst, si.Mode()) 118 c.Assert(err, IsNil) 119 120 entries, err := os.ReadDir(src) 121 c.Assert(err, IsNil) 122 123 for _, entry := range entries { 124 srcPath := filepath.Join(src, entry.Name()) 125 dstPath := filepath.Join(dst, entry.Name()) 126 127 if entry.IsDir() { 128 copyDir(c, dstPath, srcPath) 129 } else { 130 info, err := entry.Info() 131 c.Assert(err, IsNil) 132 // Skip symlinks. 133 if info.Mode()&os.ModeSymlink != 0 { 134 continue 135 } 136 copyFile(c, dstPath, srcPath) 137 } 138 } 139 } 140 141 func copyFile(c *C, dst, src string) { 142 in, err := os.Open(src) 143 c.Assert(err, IsNil) 144 defer in.Close() 145 146 out, err := os.Create(dst) 147 c.Assert(err, IsNil) 148 defer out.Close() 149 150 _, err = io.Copy(out, in) 151 c.Assert(err, IsNil) 152 153 si, err := os.Stat(src) 154 c.Assert(err, IsNil) 155 err = os.Chmod(dst, si.Mode()) 156 c.Assert(err, IsNil) 157 }