github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/checker/utils_test.go (about)

     1  // Copyright 2021 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 checker
    15  
    16  import (
    17  	"testing"
    18  
    19  	"github.com/pingcap/errors"
    20  	"github.com/pingcap/tidb/pkg/parser"
    21  	"github.com/pingcap/tidb/pkg/parser/ast"
    22  	"github.com/pingcap/tiflow/dm/pkg/terror"
    23  	"github.com/stretchr/testify/require"
    24  )
    25  
    26  func TestVersionComparison(t *testing.T) {
    27  	// test normal cases
    28  	cases := []struct {
    29  		rawVersion     string
    30  		ge, gt, lt, le bool
    31  	}{
    32  		{"0.0.0", false, false, true, true},
    33  		{"5.5.0", false, false, true, true},
    34  		{"5.6.0", true, false, true, true},
    35  		{"5.7.0", true, true, true, true},
    36  		{"5.8.0", true, true, true, true}, // although it does not exist
    37  		{"8.0.1", true, true, true, true},
    38  		{"8.1.0", true, true, false, true},
    39  		{"255.255.255", true, true, false, false}, // max version
    40  	}
    41  
    42  	var (
    43  		version MySQLVersion
    44  		err     error
    45  	)
    46  	for _, cs := range cases {
    47  		version, err = toMySQLVersion(cs.rawVersion)
    48  		require.NoError(t, err)
    49  		require.Equal(t, cs.ge, version.Ge(SupportedVersion["mysql"].Min))
    50  		require.Equal(t, cs.gt, version.Gt(SupportedVersion["mysql"].Min))
    51  		require.Equal(t, cs.lt, version.Lt(SupportedVersion["mysql"].Max))
    52  		require.Equal(t, cs.le, version.Le(SupportedVersion["mysql"].Max))
    53  	}
    54  }
    55  
    56  func TestToVersion(t *testing.T) {
    57  	// test normal cases
    58  	cases := []struct {
    59  		rawVersion      string
    60  		expectedVersion MySQLVersion
    61  		hasError        bool
    62  	}{
    63  		{"", MinVersion, true},
    64  		{"1.2.3.4", MinVersion, true},
    65  		{"1.x.3", MySQLVersion{1, 0, 0}, true},
    66  		{"5.7.18-log", MySQLVersion{5, 7, 18}, false},
    67  		{"5.5.50-MariaDB-1~wheezy", MySQLVersion{5, 5, 50}, false},
    68  		{"5.7.19-17-log", MySQLVersion{5, 7, 19}, false},
    69  		{"5.7.18-log", MySQLVersion{5, 7, 18}, false},
    70  		{"5.7.16-log", MySQLVersion{5, 7, 16}, false},
    71  	}
    72  
    73  	for _, cs := range cases {
    74  		version, err := toMySQLVersion(cs.rawVersion)
    75  		require.Equal(t, cs.expectedVersion, version)
    76  		if cs.hasError {
    77  			require.Error(t, err)
    78  		} else {
    79  			require.NoError(t, err)
    80  		}
    81  	}
    82  }
    83  
    84  func TestGetColumnsAndIgnorable(t *testing.T) {
    85  	cases := []struct {
    86  		sql      string
    87  		expected map[string]bool
    88  	}{
    89  		{
    90  			"CREATE TABLE `t` (\n" +
    91  				"  `c` int(11) NOT NULL,\n" +
    92  				"  `c2` int(11) NOT NULL,\n" +
    93  				"  `c3` int(11) DEFAULT '1',\n" +
    94  				"  `c4` int(11) NOT NULL DEFAULT '2',\n" +
    95  				"  PRIMARY KEY (`c`) /*T![clustered_index] CLUSTERED */\n" +
    96  				") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
    97  			map[string]bool{"c": false, "c2": false, "c3": true, "c4": true},
    98  		},
    99  		{
   100  			" CREATE TABLE `t2` (\n" +
   101  				"  `c` int(11) NOT NULL AUTO_INCREMENT,\n" +
   102  				"  `c2` int(11) DEFAULT NULL,\n" +
   103  				"  `c3` int(11) GENERATED ALWAYS AS (`c2` + 1) VIRTUAL,\n" +
   104  				"  PRIMARY KEY (`c`) /*T![clustered_index] CLUSTERED */\n" +
   105  				") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
   106  			map[string]bool{"c": true, "c2": true, "c3": true},
   107  		},
   108  		// TODO: in this case, c2 should NOT be ignored when inserting
   109  		{
   110  			"CREATE TABLE `t3` (\n" +
   111  				"  `c` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,\n" +
   112  				"  `c2` int(11) DEFAULT NULL,\n" +
   113  				"  `c3` int(11) GENERATED ALWAYS AS (`c2` + 1) VIRTUAL NOT NULL,\n" +
   114  				"  `c4` int(11) DEFAULT NULL,\n" +
   115  				"  PRIMARY KEY (`c`) /*T![clustered_index] CLUSTERED */\n" +
   116  				") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![auto_rand_base] AUTO_RANDOM_BASE=30001 */",
   117  			map[string]bool{"c": true, "c2": true, "c3": true, "c4": true},
   118  		},
   119  	}
   120  
   121  	p := parser.New()
   122  	for _, c := range cases {
   123  		stmt, err := p.ParseOneStmt(c.sql, "", "")
   124  		require.NoError(t, err)
   125  		columns := getColumnsAndIgnorable(stmt.(*ast.CreateTableStmt))
   126  		require.Equal(t, c.expected, columns)
   127  	}
   128  }
   129  
   130  func TestMarkCheckError(t *testing.T) {
   131  	res := &Result{}
   132  	markCheckError(res, terror.ErrNoMasterStatus.Generate())
   133  	require.Equal(t, terror.ErrNoMasterStatus.Workaround(), res.Instruction)
   134  	res = &Result{}
   135  	markCheckError(res, errors.New("other err"))
   136  	require.Zero(t, len(res.Instruction))
   137  }