github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/cdcv2/metadata/sql/uuid_test.go (about) 1 // Copyright 2023 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 sql 15 16 import ( 17 "context" 18 "testing" 19 "time" 20 21 "github.com/DATA-DOG/go-sqlmock" 22 "github.com/go-sql-driver/mysql" 23 "github.com/pingcap/tiflow/pkg/errors" 24 "github.com/stretchr/testify/require" 25 ) 26 27 func TestORMUUIDGeneratorInitFail(t *testing.T) { 28 t.Parallel() 29 30 backendDB, db, mock := newMockDB(t) 31 defer backendDB.Close() 32 33 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) 34 defer cancel() 35 36 // auto migrate 37 mock.ExpectExec("CREATE TABLE `logic_epoch` (`task_id` varchar(128),`epoch` bigint(20) unsigned NOT NULL," + 38 "`created_at` datetime(3) NULL,`updated_at` datetime(3) NULL,PRIMARY KEY (`task_id`))"). 39 WillReturnResult(sqlmock.NewResult(0, 0)) 40 41 // insert first record fail 42 mock.ExpectExec("INSERT INTO `logic_epoch` (`task_id`,`epoch`,`created_at`,`updated_at`) VALUES " + 43 "(?,?,?,?) ON DUPLICATE KEY UPDATE `task_id`=`task_id`"). 44 WillReturnError(&mysql.MySQLError{Number: 1062, Message: "test error"}) 45 gen := newORMUUIDGenerator(taskCDCChangefeedUUID, db) 46 uuid, err := gen.GenChangefeedUUID(ctx) 47 require.ErrorIs(t, err, errors.ErrMetaOpFailed) 48 require.ErrorContains(t, err, "test error") 49 require.Equal(t, uint64(0), uuid) 50 51 mock.ExpectClose() 52 } 53 54 func TestORMUUIDGenerator(t *testing.T) { 55 t.Parallel() 56 57 backendDB, db, mock := newMockDB(t) 58 defer backendDB.Close() 59 60 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) 61 defer cancel() 62 63 gen := newORMUUIDGenerator(taskCDCChangefeedUUID, db) 64 65 // auto migrate 66 mock.ExpectExec("CREATE TABLE `logic_epoch` (`task_id` varchar(128),`epoch` bigint(20) unsigned NOT NULL," + 67 "`created_at` datetime(3) NULL,`updated_at` datetime(3) NULL,PRIMARY KEY (`task_id`))"). 68 WillReturnResult(sqlmock.NewResult(0, 0)) 69 70 // insert first record 71 mock.ExpectExec("INSERT INTO `logic_epoch` (`task_id`,`epoch`,`created_at`,`updated_at`) VALUES " + 72 "(?,?,?,?) ON DUPLICATE KEY UPDATE `task_id`=`task_id`"). 73 WillReturnResult(sqlmock.NewResult(1, 1)) 74 75 // case 1: update success 76 mock.ExpectBegin() 77 mock.ExpectExec("UPDATE `logic_epoch` SET `epoch`=epoch + ?,`updated_at`=? WHERE task_id = ?"). 78 WithArgs(1, sqlmock.AnyArg(), taskCDCChangefeedUUID). 79 WillReturnResult(sqlmock.NewResult(1, 1)) 80 81 // select 82 mock.ExpectQuery("SELECT `epoch` FROM `logic_epoch` WHERE task_id = ? LIMIT 1"). 83 WithArgs(taskCDCChangefeedUUID). 84 WillReturnRows(sqlmock.NewRows([]string{"epoch"}).AddRow(11)) 85 mock.ExpectCommit() 86 87 uuid, err := gen.GenChangefeedUUID(ctx) 88 require.NoError(t, err) 89 require.Equal(t, uint64(11), uuid) 90 91 // case 2: update fail 92 failedErr := errors.New("gen epoch error") 93 mock.ExpectBegin() 94 mock.ExpectExec("UPDATE `logic_epoch` SET `epoch`=epoch + ?,`updated_at`=? WHERE task_id = ?"). 95 WithArgs(1, sqlmock.AnyArg(), taskCDCChangefeedUUID). 96 WillReturnError(failedErr) 97 mock.ExpectRollback() 98 uuid, err = gen.GenChangefeedUUID(ctx) 99 require.ErrorContains(t, err, failedErr.Error()) 100 require.Equal(t, uint64(0), uuid) 101 102 mock.ExpectClose() 103 }