github.com/Elate-DevOps/migrate/v4@v4.0.12/database/clickhouse/clickhouse_test.go (about)

     1  package clickhouse_test
     2  
     3  import (
     4  	"context"
     5  	"database/sql"
     6  	sqldriver "database/sql/driver"
     7  	"fmt"
     8  	"log"
     9  	"testing"
    10  
    11  	_ "github.com/ClickHouse/clickhouse-go"
    12  	"github.com/Elate-DevOps/migrate/v4"
    13  	"github.com/Elate-DevOps/migrate/v4/database/clickhouse"
    14  	dt "github.com/Elate-DevOps/migrate/v4/database/testing"
    15  	"github.com/Elate-DevOps/migrate/v4/dktesting"
    16  	_ "github.com/Elate-DevOps/migrate/v4/source/file"
    17  	"github.com/dhui/dktest"
    18  )
    19  
    20  const defaultPort = 9000
    21  
    22  var (
    23  	tableEngines = []string{"TinyLog", "MergeTree"}
    24  	opts         = dktest.Options{
    25  		Env:          map[string]string{"CLICKHOUSE_USER": "user", "CLICKHOUSE_PASSWORD": "password", "CLICKHOUSE_DB": "db"},
    26  		PortRequired: true, ReadyFunc: isReady,
    27  	}
    28  	specs = []dktesting.ContainerSpec{
    29  		{ImageName: "yandex/clickhouse-server:21.3", Options: opts},
    30  	}
    31  )
    32  
    33  func clickhouseConnectionString(host, port, engine string) string {
    34  	if engine != "" {
    35  		return fmt.Sprintf(
    36  			"clickhouse://%v:%v?username=user&password=password&database=db&x-multi-statement=true&x-migrations-table-engine=%v&debug=false",
    37  			host, port, engine)
    38  	}
    39  
    40  	return fmt.Sprintf(
    41  		"clickhouse://%v:%v?username=user&password=password&database=db&x-multi-statement=true&debug=false",
    42  		host, port)
    43  }
    44  
    45  func isReady(ctx context.Context, c dktest.ContainerInfo) bool {
    46  	ip, port, err := c.Port(defaultPort)
    47  	if err != nil {
    48  		return false
    49  	}
    50  
    51  	db, err := sql.Open("clickhouse", clickhouseConnectionString(ip, port, ""))
    52  	if err != nil {
    53  		log.Println("open error", err)
    54  		return false
    55  	}
    56  	defer func() {
    57  		if err := db.Close(); err != nil {
    58  			log.Println("close error:", err)
    59  		}
    60  	}()
    61  
    62  	if err = db.PingContext(ctx); err != nil {
    63  		switch err {
    64  		case sqldriver.ErrBadConn:
    65  			return false
    66  		default:
    67  			fmt.Println(err)
    68  		}
    69  		return false
    70  	}
    71  
    72  	return true
    73  }
    74  
    75  func TestCases(t *testing.T) {
    76  	for _, engine := range tableEngines {
    77  		t.Run("Test_"+engine, func(t *testing.T) { testSimple(t, engine) })
    78  		t.Run("Migrate_"+engine, func(t *testing.T) { testMigrate(t, engine) })
    79  		t.Run("Version_"+engine, func(t *testing.T) { testVersion(t, engine) })
    80  		t.Run("Drop_"+engine, func(t *testing.T) { testDrop(t, engine) })
    81  	}
    82  	t.Run("WithInstanceDefaultConfigValues", func(t *testing.T) { testSimpleWithInstanceDefaultConfigValues(t) })
    83  }
    84  
    85  func testSimple(t *testing.T, engine string) {
    86  	dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) {
    87  		ip, port, err := c.Port(defaultPort)
    88  		if err != nil {
    89  			t.Fatal(err)
    90  		}
    91  
    92  		addr := clickhouseConnectionString(ip, port, engine)
    93  		p := &clickhouse.ClickHouse{}
    94  		d, err := p.Open(addr)
    95  		if err != nil {
    96  			t.Fatal(err)
    97  		}
    98  		defer func() {
    99  			if err := d.Close(); err != nil {
   100  				t.Error(err)
   101  			}
   102  		}()
   103  
   104  		dt.Test(t, d, []byte("SELECT 1"))
   105  	})
   106  }
   107  
   108  func testSimpleWithInstanceDefaultConfigValues(t *testing.T) {
   109  	dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) {
   110  		ip, port, err := c.Port(defaultPort)
   111  		if err != nil {
   112  			t.Fatal(err)
   113  		}
   114  
   115  		addr := clickhouseConnectionString(ip, port, "")
   116  		conn, err := sql.Open("clickhouse", addr)
   117  		if err != nil {
   118  			t.Fatal(err)
   119  		}
   120  		d, err := clickhouse.WithInstance(conn, &clickhouse.Config{})
   121  		if err != nil {
   122  			_ = conn.Close()
   123  			t.Fatal(err)
   124  		}
   125  		defer func() {
   126  			if err := d.Close(); err != nil {
   127  				t.Error(err)
   128  			}
   129  		}()
   130  
   131  		dt.Test(t, d, []byte("SELECT 1"))
   132  	})
   133  }
   134  
   135  func testMigrate(t *testing.T, engine string) {
   136  	dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) {
   137  		ip, port, err := c.Port(defaultPort)
   138  		if err != nil {
   139  			t.Fatal(err)
   140  		}
   141  
   142  		addr := clickhouseConnectionString(ip, port, engine)
   143  		p := &clickhouse.ClickHouse{}
   144  		d, err := p.Open(addr)
   145  		if err != nil {
   146  			t.Fatal(err)
   147  		}
   148  		defer func() {
   149  			if err := d.Close(); err != nil {
   150  				t.Error(err)
   151  			}
   152  		}()
   153  		m, err := migrate.NewWithDatabaseInstance("file://./examples/migrations", "db", d)
   154  		if err != nil {
   155  			t.Fatal(err)
   156  		}
   157  		dt.TestMigrate(t, m)
   158  	})
   159  }
   160  
   161  func testVersion(t *testing.T, engine string) {
   162  	dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) {
   163  		expectedVersion := 1
   164  
   165  		ip, port, err := c.Port(defaultPort)
   166  		if err != nil {
   167  			t.Fatal(err)
   168  		}
   169  
   170  		addr := clickhouseConnectionString(ip, port, engine)
   171  		p := &clickhouse.ClickHouse{}
   172  		d, err := p.Open(addr)
   173  		if err != nil {
   174  			t.Fatal(err)
   175  		}
   176  		defer func() {
   177  			if err := d.Close(); err != nil {
   178  				t.Error(err)
   179  			}
   180  		}()
   181  
   182  		err = d.SetVersion(expectedVersion, false)
   183  		if err != nil {
   184  			t.Fatal(err)
   185  		}
   186  
   187  		version, _, err := d.Version()
   188  		if err != nil {
   189  			t.Fatal(err)
   190  		}
   191  
   192  		if version != expectedVersion {
   193  			t.Fatal("Version mismatch")
   194  		}
   195  	})
   196  }
   197  
   198  func testDrop(t *testing.T, engine string) {
   199  	dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) {
   200  		ip, port, err := c.Port(defaultPort)
   201  		if err != nil {
   202  			t.Fatal(err)
   203  		}
   204  
   205  		addr := clickhouseConnectionString(ip, port, engine)
   206  		p := &clickhouse.ClickHouse{}
   207  		d, err := p.Open(addr)
   208  		if err != nil {
   209  			t.Fatal(err)
   210  		}
   211  		defer func() {
   212  			if err := d.Close(); err != nil {
   213  				t.Error(err)
   214  			}
   215  		}()
   216  
   217  		err = d.Drop()
   218  		if err != nil {
   219  			t.Fatal(err)
   220  		}
   221  	})
   222  }