github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/tests/mq_protocol_tests/README.md (about) 1 # Integration Framework 2 3 ## Introduction 4 The **Integration Framework** is designed to provide a flexible way for contributors to write integration tests for new 5 sinks or MQ protocols. The core of the framework is stored in `{ticdc_root}/tests/mq_protocol_tests/framework`, and test 6 cases should be stored in `{ticdc_root}/tests/mq_protocol_tests/cases`. Currently, although the Framework is still under 7 active development, it is capable of helping test Avro support and it is the only officially supported way for 8 developers to run integration tests with Kafka connect. 9 10 ## Quick Start 11 To create a test case, you need to: 12 - create a struct that implements the `Task` interface, 13 - and ask the Environment to run the task in the `main` function in `integration.go`. 14 Note that the second step will be automated soon. 15 16 ```go 17 // Task represents a single test case 18 type Task interface { 19 Name() string 20 GetCDCProfile() *CDCProfile 21 Prepare(taskContext *TaskContext) error 22 Run(taskContext *TaskContext) error 23 } 24 ``` 25 For the time being, if you would like to write a test case for Avro and Canal, it is recommended to write a base case which define the common operations of test, and write construct function, pass `canal.SingleTableTask` or `canal.SingleTableTask` as parameters, which execute the necessary setup steps, including creating the Kafka Connect sink and creating the changefeed with appropriate configurations. 26 27 28 Example: 29 ```go 30 // cases/base_mycase.go 31 type MyCase struct { 32 framework.Task 33 } 34 35 func NewMyCase(task framework) *MyCase{ 36 return &MyCase{ 37 Task: task, 38 } 39 } 40 41 func (c *MyCase) Name() string { 42 return "My Case" 43 } 44 45 func (c *MyCase) Run(ctx *framework.TaskContext) error { 46 _, err := ctx.Upstream.ExecContext(ctx.Ctx, "create table test (id int primary key, value int)") 47 if err != nil { 48 return err 49 } 50 51 // Get a handle of an existing table 52 table := ctx.SQLHelper().GetTable("test") 53 // Create an SQL request, send it to the upstream, wait for completion and check the correctness of replication 54 err = table.Insert(map[string]interface{}{ 55 "id": 0, 56 "value": 0, 57 }).Send().Wait().Check() 58 if err != nil { 59 return errors.AddStack(err) 60 } 61 62 // To wait on a batch of SQL requests, create a slice of Awaitables 63 reqs := make([]framework.Awaitable, 0) 64 for i := 1; i < 1000; i++ { 65 // Only send, do not wait 66 req := table.Insert(map[string]interface{}{ 67 "id": i, 68 "value": i, 69 }).Send() 70 reqs = append(reqs, req) 71 } 72 73 // Wait on SQL requests in batch and check the correctness 74 return framework.All(ctx.SQLHelper(), reqs).Wait().Check() 75 } 76 77 78 // main.go 79 func main() { 80 task := &canal.SingleTableTask{TableName: "test"} 81 testCases := []framework.Task{ 82 tests.NewMyCase(task), 83 } 84 task := &avro.SingleTableTask{TableName: "test"} 85 testCases := []framework.Task{ 86 tests.NewMyCase(task), 87 } 88 //run 89 } 90 ```