github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/lightning/mydump/reader_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 mydump_test
    15  
    16  import (
    17  	"context"
    18  	"errors"
    19  	"os"
    20  	"path/filepath"
    21  
    22  	mockstorage "github.com/pingcap/br/pkg/mock/storage"
    23  
    24  	"github.com/golang/mock/gomock"
    25  	. "github.com/pingcap/check"
    26  
    27  	. "github.com/pingcap/br/pkg/lightning/mydump"
    28  	"github.com/pingcap/br/pkg/storage"
    29  )
    30  
    31  var _ = Suite(&testMydumpReaderSuite{})
    32  
    33  type testMydumpReaderSuite struct{}
    34  
    35  func (s *testMydumpReaderSuite) SetUpSuite(c *C)    {}
    36  func (s *testMydumpReaderSuite) TearDownSuite(c *C) {}
    37  
    38  func (s *testMydumpReaderSuite) TestExportStatementNoTrailingNewLine(c *C) {
    39  	dir := c.MkDir()
    40  	file, err := os.Create(filepath.Join(dir, "tidb_lightning_test_reader"))
    41  	c.Assert(err, IsNil)
    42  	defer os.Remove(file.Name())
    43  
    44  	store, err := storage.NewLocalStorage(dir)
    45  	c.Assert(err, IsNil)
    46  
    47  	_, err = file.Write([]byte("CREATE DATABASE whatever;"))
    48  	c.Assert(err, IsNil)
    49  	stat, err := file.Stat()
    50  	c.Assert(err, IsNil)
    51  	err = file.Close()
    52  	c.Assert(err, IsNil)
    53  
    54  	f := FileInfo{FileMeta: SourceFileMeta{Path: stat.Name(), FileSize: stat.Size()}}
    55  	data, err := ExportStatement(context.TODO(), store, f, "auto")
    56  	c.Assert(err, IsNil)
    57  	c.Assert(data, DeepEquals, []byte("CREATE DATABASE whatever;"))
    58  }
    59  
    60  func (s *testMydumpReaderSuite) TestExportStatementWithComment(c *C) {
    61  	s.exportStatmentShouldBe(c, `
    62  		/* whatever blabla
    63  			multiple lines comment
    64  			multiple lines comment
    65  			multiple lines comment
    66  			multiple lines comment
    67  			multiple lines comment
    68  		 */;
    69  		CREATE DATABASE whatever;
    70  `, "CREATE DATABASE whatever;")
    71  }
    72  
    73  func (s *testMydumpReaderSuite) TestExportStatementWithCommentNoTrailingNewLine(c *C) {
    74  	s.exportStatmentShouldBe(c, `
    75  		/* whatever blabla
    76  			multiple lines comment
    77  			multiple lines comment
    78  			multiple lines comment
    79  			multiple lines comment
    80  			multiple lines comment
    81  		 */;
    82  		CREATE DATABASE whatever;`, "CREATE DATABASE whatever;")
    83  }
    84  
    85  func (s *testMydumpReaderSuite) exportStatmentShouldBe(c *C, stmt string, expected string) {
    86  	dir := c.MkDir()
    87  	file, err := os.Create(filepath.Join(dir, "tidb_lightning_test_reader"))
    88  	c.Assert(err, IsNil)
    89  	defer os.Remove(file.Name())
    90  
    91  	_, err = file.Write([]byte(stmt))
    92  	c.Assert(err, IsNil)
    93  	stat, err := file.Stat()
    94  	c.Assert(err, IsNil)
    95  	err = file.Close()
    96  	c.Assert(err, IsNil)
    97  
    98  	store, err := storage.NewLocalStorage(dir)
    99  	c.Assert(err, IsNil)
   100  	f := FileInfo{FileMeta: SourceFileMeta{Path: stat.Name(), FileSize: stat.Size()}}
   101  	data, err := ExportStatement(context.TODO(), store, f, "auto")
   102  	c.Assert(err, IsNil)
   103  	c.Assert(data, DeepEquals, []byte(expected))
   104  }
   105  
   106  func (s *testMydumpReaderSuite) TestExportStatementGBK(c *C) {
   107  	dir := c.MkDir()
   108  	file, err := os.Create(filepath.Join(dir, "tidb_lightning_test_reader"))
   109  	c.Assert(err, IsNil)
   110  	defer os.Remove(file.Name())
   111  
   112  	_, err = file.Write([]byte("CREATE TABLE a (b int(11) COMMENT '"))
   113  	c.Assert(err, IsNil)
   114  	// "D7 DC B0 B8 C0 FD" is the GBK encoding of "总案例".
   115  	_, err = file.Write([]byte{0xD7, 0xDC, 0xB0, 0xB8, 0xC0, 0xFD})
   116  	c.Assert(err, IsNil)
   117  	_, err = file.Write([]byte("');\n"))
   118  	c.Assert(err, IsNil)
   119  	stat, err := file.Stat()
   120  	c.Assert(err, IsNil)
   121  	err = file.Close()
   122  	c.Assert(err, IsNil)
   123  
   124  	store, err := storage.NewLocalStorage(dir)
   125  	c.Assert(err, IsNil)
   126  	f := FileInfo{FileMeta: SourceFileMeta{Path: stat.Name(), FileSize: stat.Size()}}
   127  	data, err := ExportStatement(context.TODO(), store, f, "auto")
   128  	c.Assert(err, IsNil)
   129  	c.Assert(data, DeepEquals, []byte("CREATE TABLE a (b int(11) COMMENT '总案例');"))
   130  }
   131  
   132  func (s *testMydumpReaderSuite) TestExportStatementGibberishError(c *C) {
   133  	dir := c.MkDir()
   134  	file, err := os.Create(filepath.Join(dir, "tidb_lightning_test_reader"))
   135  	c.Assert(err, IsNil)
   136  	defer os.Remove(file.Name())
   137  
   138  	_, err = file.Write([]byte("\x9e\x02\xdc\xfbZ/=n\xf3\xf2N8\xc1\xf2\xe9\xaa\xd0\x85\xc5}\x97\x07\xae6\x97\x99\x9c\x08\xcb\xe8;"))
   139  	c.Assert(err, IsNil)
   140  	stat, err := file.Stat()
   141  	c.Assert(err, IsNil)
   142  	err = file.Close()
   143  	c.Assert(err, IsNil)
   144  
   145  	store, err := storage.NewLocalStorage(dir)
   146  	c.Assert(err, IsNil)
   147  
   148  	f := FileInfo{FileMeta: SourceFileMeta{Path: stat.Name(), FileSize: stat.Size()}}
   149  	data, err := ExportStatement(context.TODO(), store, f, "auto")
   150  	c.Assert(data, HasLen, 0)
   151  	c.Assert(err, ErrorMatches, `failed to decode \w* as auto: invalid schema encoding`)
   152  }
   153  
   154  type AlwaysErrorReadSeekCloser struct{}
   155  
   156  func (AlwaysErrorReadSeekCloser) Read([]byte) (int, error) {
   157  	return 0, errors.New("read error")
   158  }
   159  
   160  func (AlwaysErrorReadSeekCloser) Seek(int64, int) (int64, error) {
   161  	return 0, errors.New("seek error")
   162  }
   163  
   164  func (AlwaysErrorReadSeekCloser) Close() error {
   165  	return nil
   166  }
   167  
   168  func (s *testMydumpReaderSuite) TestExportStatementHandleNonEOFError(c *C) {
   169  	controller := gomock.NewController(c)
   170  	defer controller.Finish()
   171  
   172  	ctx := context.TODO()
   173  
   174  	mockStorage := mockstorage.NewMockExternalStorage(controller)
   175  	mockStorage.EXPECT().
   176  		Open(ctx, "no-perm-file").
   177  		Return(AlwaysErrorReadSeekCloser{}, nil)
   178  
   179  	f := FileInfo{FileMeta: SourceFileMeta{Path: "no-perm-file", FileSize: 1}}
   180  	_, err := ExportStatement(ctx, mockStorage, f, "auto")
   181  	c.Assert(err, ErrorMatches, "read error")
   182  }