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  }