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

     1  package spanner
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/Elate-DevOps/migrate/v4"
     9  
    10  	dt "github.com/Elate-DevOps/migrate/v4/database/testing"
    11  	_ "github.com/Elate-DevOps/migrate/v4/source/file"
    12  
    13  	"cloud.google.com/go/spanner/spannertest"
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  // withSpannerEmulator is not thread-safe and cannot be used with parallel tests since it sets the emulator
    19  func withSpannerEmulator(t *testing.T, testFunc func(t *testing.T)) {
    20  	t.Helper()
    21  	srv, err := spannertest.NewServer("localhost:0")
    22  	if err != nil {
    23  		t.Fatal("Failed to create Spanner emulator:", err)
    24  	}
    25  	// This is not thread-safe
    26  	if err := os.Setenv("SPANNER_EMULATOR_HOST", srv.Addr); err != nil {
    27  		t.Fatal("Failed to set SPANNER_EMULATOR_HOST env var:", err)
    28  	}
    29  	defer srv.Close()
    30  	testFunc(t)
    31  }
    32  
    33  const db = "projects/abc/instances/def/databases/testdb"
    34  
    35  func Test(t *testing.T) {
    36  	withSpannerEmulator(t, func(t *testing.T) {
    37  		uri := fmt.Sprintf("spanner://%s", db)
    38  		s := &Spanner{}
    39  		d, err := s.Open(uri)
    40  		if err != nil {
    41  			t.Fatal(err)
    42  		}
    43  		dt.Test(t, d, []byte("CREATE TABLE test (id BOOL) PRIMARY KEY (id)"))
    44  	})
    45  }
    46  
    47  func TestMigrate(t *testing.T) {
    48  	withSpannerEmulator(t, func(t *testing.T) {
    49  		s := &Spanner{}
    50  		uri := fmt.Sprintf("spanner://%s", db)
    51  		d, err := s.Open(uri)
    52  		if err != nil {
    53  			t.Fatal(err)
    54  		}
    55  		m, err := migrate.NewWithDatabaseInstance("file://./examples/migrations", uri, d)
    56  		if err != nil {
    57  			t.Fatal(err)
    58  		}
    59  		dt.TestMigrate(t, m)
    60  	})
    61  }
    62  
    63  func TestCleanStatements(t *testing.T) {
    64  	testCases := []struct {
    65  		name           string
    66  		multiStatement string
    67  		expected       []string
    68  	}{
    69  		{
    70  			name:           "no statement",
    71  			multiStatement: "",
    72  			expected:       []string{},
    73  		},
    74  		{
    75  			name:           "single statement, single line, no semicolon, no comment",
    76  			multiStatement: "CREATE TABLE table_name (id STRING(255) NOT NULL) PRIMARY KEY (id)",
    77  			expected:       []string{"CREATE TABLE table_name (\n  id STRING(255) NOT NULL,\n) PRIMARY KEY(id)"},
    78  		},
    79  		{
    80  			name: "single statement, multi line, no semicolon, no comment",
    81  			multiStatement: `CREATE TABLE table_name (
    82  			id STRING(255) NOT NULL,
    83  		) PRIMARY KEY (id)`,
    84  			expected: []string{"CREATE TABLE table_name (\n  id STRING(255) NOT NULL,\n) PRIMARY KEY(id)"},
    85  		},
    86  		{
    87  			name:           "single statement, single line, with semicolon, no comment",
    88  			multiStatement: "CREATE TABLE table_name (id STRING(255) NOT NULL) PRIMARY KEY (id);",
    89  			expected:       []string{"CREATE TABLE table_name (\n  id STRING(255) NOT NULL,\n) PRIMARY KEY(id)"},
    90  		},
    91  		{
    92  			name: "single statement, multi line, with semicolon, no comment",
    93  			multiStatement: `CREATE TABLE table_name (
    94  			id STRING(255) NOT NULL,
    95  		) PRIMARY KEY (id);`,
    96  			expected: []string{"CREATE TABLE table_name (\n  id STRING(255) NOT NULL,\n) PRIMARY KEY(id)"},
    97  		},
    98  		{
    99  			name: "multi statement, with trailing semicolon. no comment",
   100  			// From https://github.com/mattes/migrate/pull/281
   101  			multiStatement: `CREATE TABLE table_name (
   102  			id STRING(255) NOT NULL,
   103  		) PRIMARY KEY(id);
   104  
   105  		CREATE INDEX table_name_id_idx ON table_name (id);`,
   106  			expected: []string{`CREATE TABLE table_name (
   107    id STRING(255) NOT NULL,
   108  ) PRIMARY KEY(id)`, "CREATE INDEX table_name_id_idx ON table_name(id)"},
   109  		},
   110  		{
   111  			name: "multi statement, no trailing semicolon, no comment",
   112  			// From https://github.com/mattes/migrate/pull/281
   113  			multiStatement: `CREATE TABLE table_name (
   114  			id STRING(255) NOT NULL,
   115  		) PRIMARY KEY(id);
   116  
   117  		CREATE INDEX table_name_id_idx ON table_name (id)`,
   118  			expected: []string{`CREATE TABLE table_name (
   119    id STRING(255) NOT NULL,
   120  ) PRIMARY KEY(id)`, "CREATE INDEX table_name_id_idx ON table_name(id)"},
   121  		},
   122  		{
   123  			name: "multi statement, no trailing semicolon, standalone comment",
   124  			// From https://github.com/mattes/migrate/pull/281
   125  			multiStatement: `CREATE TABLE table_name (
   126  			-- standalone comment
   127  			id STRING(255) NOT NULL,
   128  		) PRIMARY KEY(id);
   129  
   130  		CREATE INDEX table_name_id_idx ON table_name (id)`,
   131  			expected: []string{`CREATE TABLE table_name (
   132    id STRING(255) NOT NULL,
   133  ) PRIMARY KEY(id)`, "CREATE INDEX table_name_id_idx ON table_name(id)"},
   134  		},
   135  		{
   136  			name: "multi statement, no trailing semicolon, inline comment",
   137  			// From https://github.com/mattes/migrate/pull/281
   138  			multiStatement: `CREATE TABLE table_name (
   139  			id STRING(255) NOT NULL, -- inline comment
   140  		) PRIMARY KEY(id);
   141  
   142  		CREATE INDEX table_name_id_idx ON table_name (id)`,
   143  			expected: []string{`CREATE TABLE table_name (
   144    id STRING(255) NOT NULL,
   145  ) PRIMARY KEY(id)`, "CREATE INDEX table_name_id_idx ON table_name(id)"},
   146  		},
   147  		{
   148  			name: "alter table with SET OPTIONS",
   149  			multiStatement: `ALTER TABLE users ALTER COLUMN created
   150  			SET OPTIONS (allow_commit_timestamp=true);`,
   151  			expected: []string{"ALTER TABLE users ALTER COLUMN created SET OPTIONS (allow_commit_timestamp = true)"},
   152  		},
   153  		{
   154  			name: "column with NUMERIC type",
   155  			multiStatement: `CREATE TABLE table_name (
   156  				id STRING(255) NOT NULL,
   157  				sum NUMERIC,
   158  			) PRIMARY KEY (id)`,
   159  			expected: []string{"CREATE TABLE table_name (\n  id STRING(255) NOT NULL,\n  sum NUMERIC,\n) PRIMARY KEY(id)"},
   160  		},
   161  	}
   162  
   163  	for _, tc := range testCases {
   164  		t.Run(tc.name, func(t *testing.T) {
   165  			stmts, err := cleanStatements([]byte(tc.multiStatement))
   166  			require.NoError(t, err, "Error cleaning statements")
   167  			assert.Equal(t, tc.expected, stmts)
   168  		})
   169  	}
   170  }