github.com/matrixorigin/matrixone@v0.7.0/pkg/frontend/export_test.go (about)

     1  // Copyright 2022 Matrix Origin
     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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package frontend
    16  
    17  import (
    18  	"bufio"
    19  	"context"
    20  	"os"
    21  	"testing"
    22  
    23  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    24  	"github.com/matrixorigin/matrixone/pkg/container/types"
    25  	"github.com/matrixorigin/matrixone/pkg/defines"
    26  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/tree"
    27  	"github.com/prashantv/gostub"
    28  	"github.com/smartystreets/goconvey/convey"
    29  )
    30  
    31  var colName1, colName2 = "DATABASE()", "VARIABLE_VALUE"
    32  
    33  func Test_initExportFileParam(t *testing.T) {
    34  	var oq = &outputQueue{
    35  		mrs: &MysqlResultSet{},
    36  		ep: &ExportParam{
    37  			ExportParam: &tree.ExportParam{
    38  				Lines:  &tree.Lines{},
    39  				Fields: &tree.Fields{},
    40  			},
    41  		},
    42  	}
    43  	initExportFileParam(oq.ep, oq.mrs)
    44  
    45  	col1 := new(MysqlColumn)
    46  	col1.SetName(colName1)
    47  	col2 := new(MysqlColumn)
    48  	col2.SetName(colName2)
    49  	oq.mrs.AddColumn(col1)
    50  	oq.mrs.AddColumn(col2)
    51  
    52  	oq.ep.ForceQuote = append(oq.ep.ForceQuote, colName1)
    53  	oq.mrs.Name2Index[colName1] = 0
    54  	initExportFileParam(oq.ep, oq.mrs)
    55  }
    56  
    57  func Test_openNewFile(t *testing.T) {
    58  	convey.Convey("openNewFile failed", t, func() {
    59  		var oq = &outputQueue{
    60  			mrs: &MysqlResultSet{},
    61  			ep: &ExportParam{
    62  				ExportParam: &tree.ExportParam{
    63  					Lines:    &tree.Lines{},
    64  					Fields:   &tree.Fields{},
    65  					Header:   true,
    66  					FilePath: "test/export.csv",
    67  				},
    68  			},
    69  		}
    70  		stubs := gostub.StubFunc(&OpenFile, nil, moerr.NewInternalError(context.TODO(), "can not open file"))
    71  		defer stubs.Reset()
    72  		convey.So(openNewFile(context.TODO(), oq.ep, oq.mrs), convey.ShouldNotBeNil)
    73  	})
    74  
    75  	convey.Convey("openNewFile succ", t, func() {
    76  		var oq = &outputQueue{
    77  			mrs: &MysqlResultSet{},
    78  			ep: &ExportParam{
    79  				ExportParam: &tree.ExportParam{
    80  					Lines:    &tree.Lines{},
    81  					Fields:   &tree.Fields{},
    82  					Header:   true,
    83  					FilePath: "test/export.csv",
    84  				},
    85  				LineSize: 1,
    86  			},
    87  		}
    88  		col1 := new(MysqlColumn)
    89  		col1.SetName(colName1)
    90  		col2 := new(MysqlColumn)
    91  		col2.SetName(colName2)
    92  		oq.mrs.AddColumn(col1)
    93  		oq.mrs.AddColumn(col2)
    94  
    95  		var file = &os.File{}
    96  		stubs := gostub.StubFunc(&OpenFile, file, nil)
    97  		defer stubs.Reset()
    98  
    99  		stubs = gostub.StubFunc(&writeDataToCSVFile, nil)
   100  		defer stubs.Reset()
   101  
   102  		convey.So(openNewFile(context.TODO(), oq.ep, oq.mrs), convey.ShouldBeNil)
   103  	})
   104  }
   105  
   106  func Test_formatOutputString(t *testing.T) {
   107  	convey.Convey("openNewFile failed", t, func() {
   108  		var oq = &outputQueue{
   109  			mrs: &MysqlResultSet{},
   110  			ep: &ExportParam{
   111  				ExportParam: &tree.ExportParam{
   112  					Lines:    &tree.Lines{},
   113  					Fields:   &tree.Fields{},
   114  					Header:   true,
   115  					FilePath: "test/export.csv",
   116  				},
   117  				LineSize: 1,
   118  			},
   119  		}
   120  		stubs := gostub.StubFunc(&writeDataToCSVFile, moerr.NewInternalError(context.TODO(), "write err"))
   121  		defer stubs.Reset()
   122  		convey.So(formatOutputString(oq, nil, nil, '\n', true), convey.ShouldNotBeNil)
   123  
   124  		stubs = gostub.StubFunc(&writeDataToCSVFile, nil)
   125  		defer stubs.Reset()
   126  		convey.So(formatOutputString(oq, nil, nil, '\n', true), convey.ShouldBeNil)
   127  	})
   128  }
   129  
   130  func Test_writeToCSVFile(t *testing.T) {
   131  	convey.Convey("writeToCSVFile case", t, func() {
   132  		var oq = &outputQueue{
   133  			mrs: &MysqlResultSet{},
   134  			ep: &ExportParam{
   135  				ExportParam: &tree.ExportParam{
   136  					Lines:    &tree.Lines{},
   137  					Fields:   &tree.Fields{},
   138  					Header:   true,
   139  					FilePath: "test/export.csv",
   140  				},
   141  				LineSize: 1,
   142  				Writer:   &bufio.Writer{},
   143  			},
   144  		}
   145  		var output = []byte{'1', '2'}
   146  		oq.ep.MaxFileSize = 1
   147  
   148  		convey.So(writeToCSVFile(oq, output), convey.ShouldNotBeNil)
   149  
   150  		oq.ep.Rows = 1
   151  		stubs := gostub.StubFunc(&Flush, moerr.NewInternalError(context.TODO(), "Flush error"))
   152  		defer stubs.Reset()
   153  
   154  		convey.So(writeToCSVFile(oq, output), convey.ShouldNotBeNil)
   155  
   156  		stubs = gostub.StubFunc(&Flush, nil)
   157  		defer stubs.Reset()
   158  
   159  		stubs = gostub.StubFunc(&Seek, int64(0), moerr.NewInternalError(context.TODO(), "Seek error"))
   160  		defer stubs.Reset()
   161  		convey.So(writeToCSVFile(oq, output), convey.ShouldNotBeNil)
   162  
   163  		stubs = gostub.StubFunc(&Seek, int64(0), nil)
   164  		defer stubs.Reset()
   165  		stubs = gostub.StubFunc(&Read, 0, moerr.NewInternalError(context.TODO(), "Read error"))
   166  		defer stubs.Reset()
   167  		convey.So(writeToCSVFile(oq, output), convey.ShouldNotBeNil)
   168  
   169  		stubs = gostub.StubFunc(&Read, 1, nil)
   170  		defer stubs.Reset()
   171  
   172  		stubs = gostub.StubFunc(&Truncate, moerr.NewInternalError(context.TODO(), "Truncate error"))
   173  		defer stubs.Reset()
   174  		convey.So(writeToCSVFile(oq, output), convey.ShouldNotBeNil)
   175  
   176  		stubs = gostub.StubFunc(&Truncate, nil)
   177  		defer stubs.Reset()
   178  		stubs = gostub.StubFunc(&Close, moerr.NewInternalError(context.TODO(), "Close error"))
   179  		defer stubs.Reset()
   180  		convey.So(writeToCSVFile(oq, output), convey.ShouldNotBeNil)
   181  
   182  		stubs = gostub.StubFunc(&Close, nil)
   183  		defer stubs.Reset()
   184  		stubs = gostub.StubFunc(&openNewFile, moerr.NewInternalError(context.TODO(), "openNewFile error"))
   185  		defer stubs.Reset()
   186  		convey.So(writeToCSVFile(oq, output), convey.ShouldNotBeNil)
   187  
   188  		stubs = gostub.StubFunc(&openNewFile, nil)
   189  		defer stubs.Reset()
   190  		stubs = gostub.StubFunc(&writeDataToCSVFile, moerr.NewInternalError(context.TODO(), "writeDataToCSVFile error"))
   191  		defer stubs.Reset()
   192  		convey.So(writeToCSVFile(oq, output), convey.ShouldNotBeNil)
   193  
   194  		stubs = gostub.StubFunc(&writeDataToCSVFile, nil)
   195  		defer stubs.Reset()
   196  		convey.So(writeToCSVFile(oq, output), convey.ShouldBeNil)
   197  	})
   198  }
   199  
   200  func Test_writeDataToCSVFile(t *testing.T) {
   201  	convey.Convey("writeDataToCSVFile case", t, func() {
   202  		var oq = &outputQueue{
   203  			mrs: &MysqlResultSet{},
   204  			ep: &ExportParam{
   205  				ExportParam: &tree.ExportParam{
   206  					Lines:    &tree.Lines{},
   207  					Fields:   &tree.Fields{},
   208  					Header:   true,
   209  					FilePath: "test/export.csv",
   210  				},
   211  				LineSize: 1,
   212  				Writer:   &bufio.Writer{},
   213  			},
   214  		}
   215  		var output = []byte{'1', '2'}
   216  		stubs := gostub.StubFunc(&Write, 0, moerr.NewInternalError(context.TODO(), "writeDataToCSVFile error"))
   217  		defer stubs.Reset()
   218  
   219  		convey.So(writeDataToCSVFile(oq.ep, output), convey.ShouldNotBeNil)
   220  
   221  		stubs = gostub.StubFunc(&Write, len(output), nil)
   222  		defer stubs.Reset()
   223  		convey.So(writeDataToCSVFile(oq.ep, output), convey.ShouldBeNil)
   224  
   225  	})
   226  }
   227  
   228  func Test_exportDataToCSVFile(t *testing.T) {
   229  	convey.Convey("exportDataToCSVFile succ", t, func() {
   230  		var oq = &outputQueue{
   231  			mrs: &MysqlResultSet{},
   232  			ep: &ExportParam{
   233  				ExportParam: &tree.ExportParam{
   234  					Lines:    &tree.Lines{},
   235  					Fields:   &tree.Fields{},
   236  					Header:   true,
   237  					FilePath: "test/export.csv",
   238  				},
   239  				LineSize: 1,
   240  				Writer:   &bufio.Writer{},
   241  			},
   242  		}
   243  
   244  		var col = make([]MysqlColumn, 13)
   245  		col[5].flag = 0
   246  		col[6].flag = 1 << 5
   247  		var colType = []defines.MysqlType{defines.MYSQL_TYPE_YEAR, defines.MYSQL_TYPE_YEAR, defines.MYSQL_TYPE_YEAR, defines.MYSQL_TYPE_SHORT, defines.MYSQL_TYPE_DOUBLE,
   248  			defines.MYSQL_TYPE_LONGLONG, defines.MYSQL_TYPE_LONGLONG, defines.MYSQL_TYPE_VARCHAR, defines.MYSQL_TYPE_DATE, defines.MYSQL_TYPE_DATETIME,
   249  			defines.MYSQL_TYPE_BOOL, defines.MYSQL_TYPE_DECIMAL, defines.MYSQL_TYPE_JSON}
   250  		for i := 0; i < len(col); i++ {
   251  			col[i].SetColumnType(colType[i])
   252  			oq.mrs.AddColumn(&col[i])
   253  		}
   254  		var data = make([]interface{}, len(col))
   255  		data[1] = 0
   256  		data[2] = 1
   257  		data[3] = 1
   258  		data[4] = 1.0
   259  		data[5] = 1
   260  		data[6] = 1
   261  		data[7] = []byte{1}
   262  		data[8] = types.Date(1)
   263  		data[9] = "2022-02-28 23:59:59.9999"
   264  		data[10] = true
   265  		data[11] = 1.2
   266  		data[12], _ = types.ParseStringToByteJson(`{"a":1}`)
   267  
   268  		oq.mrs.AddRow(data)
   269  
   270  		oq.ep.Symbol = make([][]byte, len(col))
   271  		oq.ep.ColumnFlag = make([]bool, len(col))
   272  
   273  		stubs := gostub.StubFunc(&formatOutputString, nil)
   274  		defer stubs.Reset()
   275  
   276  		convey.So(exportDataToCSVFile(oq), convey.ShouldBeNil)
   277  	})
   278  
   279  	convey.Convey("exportDataToCSVFile fail", t, func() {
   280  		var oq = &outputQueue{
   281  			mrs: &MysqlResultSet{},
   282  			ep: &ExportParam{
   283  				ExportParam: &tree.ExportParam{
   284  					Lines:    &tree.Lines{},
   285  					Fields:   &tree.Fields{},
   286  					Header:   true,
   287  					FilePath: "test/export.csv",
   288  				},
   289  				LineSize: 1,
   290  				Writer:   &bufio.Writer{},
   291  			},
   292  		}
   293  		var col = make([]MysqlColumn, 1)
   294  		var colType = []defines.MysqlType{defines.MYSQL_TYPE_TIMESTAMP}
   295  		for i := 0; i < len(col); i++ {
   296  			col[i].SetColumnType(colType[i])
   297  			oq.mrs.AddColumn(&col[i])
   298  		}
   299  
   300  		var data = make([]interface{}, len(col))
   301  		data[0] = 1
   302  		oq.mrs.AddRow(data)
   303  		oq.ep.Symbol = make([][]byte, len(col))
   304  		oq.ep.ColumnFlag = make([]bool, len(col))
   305  
   306  		stubs := gostub.StubFunc(&formatOutputString, nil)
   307  		defer stubs.Reset()
   308  
   309  		convey.So(exportDataToCSVFile(oq), convey.ShouldBeNil)
   310  	})
   311  }