github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/binlog/reader/mock_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 reader
    15  
    16  import (
    17  	"context"
    18  	"errors"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/go-mysql-org/go-mysql/mysql"
    23  	"github.com/go-mysql-org/go-mysql/replication"
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  type testMockCase struct {
    28  	ev  *replication.BinlogEvent
    29  	err error
    30  }
    31  
    32  func TestRead(t *testing.T) {
    33  	t.Parallel()
    34  	r := NewMockReader()
    35  
    36  	// some interface methods do nothing
    37  	require.Nil(t, r.StartSyncByPos(mysql.Position{}))
    38  	require.Nil(t, r.StartSyncByGTID(nil))
    39  	require.Nil(t, r.Status())
    40  	require.Nil(t, r.Close())
    41  
    42  	// replace with special error
    43  	mockR := r.(*MockReader)
    44  	errStartByPos := errors.New("special error for start by pos")
    45  	errStartByGTID := errors.New("special error for start by GTID")
    46  	errClose := errors.New("special error for close")
    47  	mockR.ErrStartByPos = errStartByPos
    48  	mockR.ErrStartByGTID = errStartByGTID
    49  	mockR.ErrClose = errClose
    50  	require.Equal(t, errStartByPos, r.StartSyncByPos(mysql.Position{}))
    51  	require.Equal(t, errStartByGTID, r.StartSyncByGTID(nil))
    52  	require.Equal(t, errClose, r.Close())
    53  
    54  	cases := []testMockCase{
    55  		{
    56  			ev: &replication.BinlogEvent{
    57  				RawData: []byte{1},
    58  			},
    59  			err: nil,
    60  		},
    61  		{
    62  			ev: &replication.BinlogEvent{
    63  				RawData: []byte{2},
    64  			},
    65  			err: nil,
    66  		},
    67  		{
    68  			ev:  nil,
    69  			err: errors.New("1"),
    70  		},
    71  		{
    72  			ev: &replication.BinlogEvent{
    73  				RawData: []byte{3},
    74  			},
    75  			err: nil,
    76  		},
    77  		{
    78  			ev:  nil,
    79  			err: errors.New("2"),
    80  		},
    81  	}
    82  
    83  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    84  	defer cancel()
    85  
    86  	go func() {
    87  		for _, cs := range cases {
    88  			if cs.err != nil {
    89  				require.Nil(t, mockR.PushError(ctx, cs.err))
    90  			} else {
    91  				require.Nil(t, mockR.PushEvent(ctx, cs.ev))
    92  			}
    93  		}
    94  	}()
    95  
    96  	obtained := make([]testMockCase, 0, len(cases))
    97  	for {
    98  		ev, err := r.GetEvent(ctx)
    99  		if err != nil {
   100  			obtained = append(obtained, testMockCase{ev: nil, err: err})
   101  		} else {
   102  			obtained = append(obtained, testMockCase{ev: ev, err: nil})
   103  		}
   104  		require.Nil(t, ctx.Err())
   105  		if len(obtained) == len(cases) {
   106  			break
   107  		}
   108  	}
   109  
   110  	require.Equal(t, cases, obtained)
   111  
   112  	cancel() // cancel manually
   113  	require.Equal(t, ctx.Err(), mockR.PushError(ctx, cases[0].err))
   114  	require.Equal(t, ctx.Err(), mockR.PushEvent(ctx, cases[0].ev))
   115  	ev, err := r.GetEvent(ctx)
   116  	require.Nil(t, ev)
   117  	require.Equal(t, ctx.Err(), err)
   118  }