github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/integration/framework/task.go (about)

     1  // Copyright 2020 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 framework
    15  
    16  import (
    17  	"context"
    18  	"database/sql"
    19  	"strings"
    20  
    21  	_ "github.com/go-sql-driver/mysql" // imported for side effects
    22  	"github.com/pingcap/log"
    23  	"go.uber.org/zap"
    24  )
    25  
    26  // Task represents a single test case
    27  type Task interface {
    28  	Name() string
    29  	GetCDCProfile() *CDCProfile
    30  	Prepare(taskContext *TaskContext) error
    31  	Run(taskContext *TaskContext) error
    32  }
    33  
    34  // TaskContext is passed to the test case to provide basic utilities for testing
    35  type TaskContext struct {
    36  	Upstream     *sql.DB
    37  	Downstream   *sql.DB
    38  	Env          Environment
    39  	WaitForReady func() error
    40  	Ctx          context.Context
    41  }
    42  
    43  // CDCProfile represents the command line arguments used to create the changefeed
    44  type CDCProfile struct {
    45  	PDUri      string
    46  	SinkURI    string
    47  	ConfigFile string
    48  	Opts       map[string]string
    49  }
    50  
    51  // CreateDB creates a database in both the upstream and the downstream
    52  func (c *TaskContext) CreateDB(name string) error {
    53  	log.Debug("Creating database in upstream", zap.String("db", name))
    54  	_, err := c.Upstream.ExecContext(c.Ctx, "create database "+name)
    55  	if err != nil {
    56  		log.Warn("Failed to create database in upstream", zap.String("db", name), zap.Error(err))
    57  		return err
    58  	}
    59  	log.Debug("Successfully created database in upstream", zap.String("db", name))
    60  
    61  	log.Debug("Creating database in downstream", zap.String("db", name))
    62  	_, err = c.Downstream.ExecContext(c.Ctx, "create database "+name)
    63  	if err != nil {
    64  		log.Warn("Failed to create database in downstream", zap.String("db", name), zap.Error(err))
    65  		return err
    66  	}
    67  	log.Debug("Successfully created database in downstream", zap.String("db", name))
    68  
    69  	return nil
    70  }
    71  
    72  // SQLHelper returns an SQLHelper
    73  func (c *TaskContext) SQLHelper() *SQLHelper {
    74  	return &SQLHelper{
    75  		upstream:   c.Upstream,
    76  		downstream: c.Downstream,
    77  		ctx:        c.Ctx,
    78  	}
    79  }
    80  
    81  // String returns the string representation of the CDCProfile
    82  func (p *CDCProfile) String() string {
    83  	builder := strings.Builder{}
    84  	builder.WriteString("cli changefeed create ")
    85  	if p.PDUri == "" {
    86  		p.PDUri = "http://127.0.0.1:2379"
    87  	}
    88  
    89  	builder.WriteString("--pd=" + p.PDUri + " ")
    90  
    91  	if p.SinkURI == "" {
    92  		log.Fatal("SinkURI cannot be empty!")
    93  	}
    94  
    95  	builder.WriteString("--sink-uri=\"" + p.SinkURI + "\" ")
    96  
    97  	if p.ConfigFile != "" {
    98  		builder.WriteString("--config=" + p.ConfigFile + " ")
    99  	}
   100  
   101  	if p.Opts == nil || len(p.Opts) == 0 {
   102  		return builder.String()
   103  	}
   104  
   105  	for k, v := range p.Opts {
   106  		builder.WriteString("--opts=\"" + k + "=" + v + "\" ")
   107  	}
   108  
   109  	builder.WriteString(" --log-level debug")
   110  	return builder.String()
   111  }