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 }