github.com/bdollma-te/migrate/v4@v4.17.0-clickv2/database/yugabytedb/yugabytedb_test.go (about)

     1  package yugabytedb
     2  
     3  // error codes https://github.com/lib/pq/blob/master/error.go
     4  
     5  import (
     6  	"context"
     7  	"database/sql"
     8  	"fmt"
     9  	"log"
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/bdollma-te/migrate/v4"
    15  	"github.com/dhui/dktest"
    16  
    17  	_ "github.com/lib/pq"
    18  
    19  	dt "github.com/bdollma-te/migrate/v4/database/testing"
    20  	"github.com/bdollma-te/migrate/v4/dktesting"
    21  
    22  	_ "github.com/bdollma-te/migrate/v4/source/file"
    23  )
    24  
    25  const defaultPort = 5433
    26  
    27  var (
    28  	opts = dktest.Options{
    29  		Cmd:          []string{"bin/yugabyted", "start", "--daemon=false"},
    30  		PortRequired: true,
    31  		ReadyFunc:    isReady,
    32  		Timeout:      time.Duration(60) * time.Second,
    33  	}
    34  	// Released versions: https://docs.yugabyte.com/preview/releases/release-notes/
    35  	specs = []dktesting.ContainerSpec{
    36  		{ImageName: "yugabytedb/yugabyte:2.14.10.4-b1", Options: opts},
    37  		{ImageName: "yugabytedb/yugabyte:2.20.0.2-b1", Options: opts},
    38  	}
    39  )
    40  
    41  func isReady(ctx context.Context, c dktest.ContainerInfo) bool {
    42  	ip, port, err := c.Port(defaultPort)
    43  	if err != nil {
    44  		log.Println("port error:", err)
    45  		return false
    46  	}
    47  
    48  	db, err := sql.Open("postgres", fmt.Sprintf("postgres://yugabyte:yugabyte@%v:%v?sslmode=disable", ip, port))
    49  	if err != nil {
    50  		log.Println("open error:", err)
    51  		return false
    52  	}
    53  	if err := db.PingContext(ctx); err != nil {
    54  		log.Println("ping error:", err)
    55  		return false
    56  	}
    57  	if err := db.Close(); err != nil {
    58  		log.Println("close error:", err)
    59  	}
    60  	return true
    61  }
    62  
    63  func createDB(t *testing.T, c dktest.ContainerInfo) {
    64  	ip, port, err := c.Port(defaultPort)
    65  	if err != nil {
    66  		t.Fatal(err)
    67  	}
    68  
    69  	db, err := sql.Open("postgres", fmt.Sprintf("postgres://yugabyte:yugabyte@%v:%v?sslmode=disable", ip, port))
    70  	if err != nil {
    71  		t.Fatal(err)
    72  	}
    73  	if err = db.Ping(); err != nil {
    74  		t.Fatal(err)
    75  	}
    76  	defer func() {
    77  		if err := db.Close(); err != nil {
    78  			t.Error(err)
    79  		}
    80  	}()
    81  
    82  	if _, err = db.Exec("CREATE DATABASE migrate"); err != nil {
    83  		t.Fatal(err)
    84  	}
    85  }
    86  
    87  func getConnectionString(ip, port string, options ...string) string {
    88  	options = append(options, "sslmode=disable")
    89  
    90  	return fmt.Sprintf("yugabyte://yugabyte:yugabyte@%v:%v/migrate?%s", ip, port, strings.Join(options, "&"))
    91  }
    92  
    93  func Test(t *testing.T) {
    94  	dktesting.ParallelTest(t, specs, func(t *testing.T, ci dktest.ContainerInfo) {
    95  		createDB(t, ci)
    96  
    97  		ip, port, err := ci.Port(defaultPort)
    98  		if err != nil {
    99  			t.Fatal(err)
   100  		}
   101  
   102  		addr := getConnectionString(ip, port)
   103  		c := &YugabyteDB{}
   104  		d, err := c.Open(addr)
   105  		if err != nil {
   106  			t.Fatal(err)
   107  		}
   108  		dt.Test(t, d, []byte("SELECT 1"))
   109  	})
   110  }
   111  
   112  func TestMigrate(t *testing.T) {
   113  	dktesting.ParallelTest(t, specs, func(t *testing.T, ci dktest.ContainerInfo) {
   114  		createDB(t, ci)
   115  
   116  		ip, port, err := ci.Port(defaultPort)
   117  		if err != nil {
   118  			t.Fatal(err)
   119  		}
   120  
   121  		addr := getConnectionString(ip, port)
   122  		c := &YugabyteDB{}
   123  		d, err := c.Open(addr)
   124  		if err != nil {
   125  			t.Fatal(err)
   126  		}
   127  
   128  		m, err := migrate.NewWithDatabaseInstance("file://./examples/migrations", "migrate", d)
   129  		if err != nil {
   130  			t.Fatal(err)
   131  		}
   132  		dt.TestMigrate(t, m)
   133  	})
   134  }
   135  
   136  func TestMultiStatement(t *testing.T) {
   137  	dktesting.ParallelTest(t, specs, func(t *testing.T, ci dktest.ContainerInfo) {
   138  		createDB(t, ci)
   139  
   140  		ip, port, err := ci.Port(defaultPort)
   141  		if err != nil {
   142  			t.Fatal(err)
   143  		}
   144  
   145  		addr := getConnectionString(ip, port)
   146  		c := &YugabyteDB{}
   147  		d, err := c.Open(addr)
   148  		if err != nil {
   149  			t.Fatal(err)
   150  		}
   151  		if err := d.Run(strings.NewReader("CREATE TABLE foo (foo text); CREATE TABLE bar (bar text);")); err != nil {
   152  			t.Fatalf("expected err to be nil, got %v", err)
   153  		}
   154  
   155  		// make sure second table exists
   156  		var exists bool
   157  		if err := d.(*YugabyteDB).db.QueryRow("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'bar' AND table_schema = (SELECT current_schema()))").Scan(&exists); err != nil {
   158  			t.Fatal(err)
   159  		}
   160  		if !exists {
   161  			t.Fatal("expected table bar to exist")
   162  		}
   163  	})
   164  }
   165  
   166  func TestFilterCustomQuery(t *testing.T) {
   167  	dktesting.ParallelTest(t, specs, func(t *testing.T, ci dktest.ContainerInfo) {
   168  		createDB(t, ci)
   169  
   170  		ip, port, err := ci.Port(defaultPort)
   171  		if err != nil {
   172  			t.Fatal(err)
   173  		}
   174  
   175  		addr := getConnectionString(ip, port, "x-custom=foobar")
   176  		c := &YugabyteDB{}
   177  		d, err := c.Open(addr)
   178  		if err != nil {
   179  			t.Fatal(err)
   180  		}
   181  		dt.Test(t, d, []byte("SELECT 1"))
   182  	})
   183  }