github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/doltdb/feature_version_test.go (about) 1 // Copyright 2020 Dolthub, 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package doltdb_test 16 17 import ( 18 "context" 19 "testing" 20 21 "github.com/stretchr/testify/assert" 22 "github.com/stretchr/testify/require" 23 24 "github.com/dolthub/dolt/go/cmd/dolt/cli" 25 "github.com/dolthub/dolt/go/cmd/dolt/commands" 26 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" 27 "github.com/dolthub/dolt/go/libraries/doltcore/dtestutils" 28 "github.com/dolthub/dolt/go/libraries/doltcore/env" 29 ) 30 31 const ( 32 newVersion doltdb.FeatureVersion = 1 << 19 33 oldVersion doltdb.FeatureVersion = 1 << 13 34 ) 35 36 // |doltdb.FeatureVersion| is manipulated during these integration tests. 37 // Save a copy here to assert that it was correctly restored. 38 var DoltFeatureVersionCopy = doltdb.DoltFeatureVersion 39 40 type fvTest struct { 41 name string 42 setup []fvCommand 43 expVer doltdb.FeatureVersion 44 45 // for error path testing 46 errCmds []fvCommand 47 } 48 49 type args []string 50 51 type fvCommand struct { 52 user fvUser 53 cmd cli.Command 54 args args 55 } 56 57 func (cmd fvCommand) exec(ctx context.Context, dEnv *env.DoltEnv) int { 58 // execute the command using |cmd.user|'s Feature Version 59 doltdb.DoltFeatureVersion = cmd.user.vers 60 defer func() { doltdb.DoltFeatureVersion = DoltFeatureVersionCopy }() 61 62 return cmd.cmd.Exec(ctx, cmd.cmd.Name(), cmd.args, dEnv) 63 } 64 65 type fvUser struct { 66 vers doltdb.FeatureVersion 67 } 68 69 var NewClient = fvUser{vers: newVersion} 70 var OldClient = fvUser{vers: oldVersion} 71 72 func TestFeatureVersion(t *testing.T) { 73 74 tests := []fvTest{ 75 { 76 name: "smoke test", 77 setup: []fvCommand{ 78 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 79 }, 80 expVer: oldVersion, 81 }, 82 { 83 name: "CREATE TABLE statements write feature version", 84 setup: []fvCommand{ 85 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 86 {NewClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE quiz (pk int PRIMARY KEY);"}}, 87 }, 88 expVer: newVersion, 89 }, 90 { 91 name: "DROP TABLE statements write feature version", 92 setup: []fvCommand{ 93 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 94 {NewClient, commands.SqlCmd{}, args{"-q", "DROP TABLE test;"}}, 95 }, 96 expVer: newVersion, 97 }, 98 { 99 name: "schema changes write feature version", 100 setup: []fvCommand{ 101 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 102 {NewClient, commands.SqlCmd{}, args{"-q", "ALTER TABLE test ADD COLUMN c0 int;"}}, 103 }, 104 expVer: newVersion, 105 }, 106 { 107 name: "INSERT statements write feature version", 108 setup: []fvCommand{ 109 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 110 {NewClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (0);"}}, 111 }, 112 expVer: newVersion, 113 }, 114 { 115 name: "UPDATE statements write feature version", 116 setup: []fvCommand{ 117 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 118 {OldClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (0);"}}, 119 {NewClient, commands.SqlCmd{}, args{"-q", "UPDATE test SET pk = 1;"}}, 120 }, 121 expVer: newVersion, 122 }, 123 { 124 name: "DELETE statements write feature version", 125 setup: []fvCommand{ 126 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 127 {OldClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (0);"}}, 128 {NewClient, commands.SqlCmd{}, args{"-q", "DELETE FROM test WHERE pk = 0;"}}, 129 }, 130 expVer: newVersion, 131 }, 132 { 133 name: "new client writes to table, locking out old client", 134 setup: []fvCommand{ 135 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 136 {OldClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (0);"}}, 137 {NewClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (1);"}}, 138 }, 139 errCmds: []fvCommand{ 140 // old client can't write 141 {OldClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (2);"}}, 142 // old client can't read 143 {OldClient, commands.SqlCmd{}, args{"-q", "SELECT * FROM test;"}}, 144 }, 145 expVer: newVersion, 146 }, 147 } 148 149 ctx := context.Background() 150 for _, test := range tests { 151 t.Run(test.name, func(t *testing.T) { 152 153 doltdb.DoltFeatureVersion = oldVersion 154 dEnv := dtestutils.CreateTestEnv() 155 doltdb.DoltFeatureVersion = DoltFeatureVersionCopy 156 157 for _, cmd := range test.setup { 158 code := cmd.exec(ctx, dEnv) 159 require.Equal(t, 0, code) 160 } 161 for _, cmd := range test.errCmds { 162 code := cmd.exec(ctx, dEnv) 163 require.NotEqual(t, 0, code) 164 } 165 166 // execute assertions with newVersion to avoid OutOfDate errors 167 doltdb.DoltFeatureVersion = newVersion 168 defer func() { doltdb.DoltFeatureVersion = DoltFeatureVersionCopy }() 169 170 assertFeatureVersion := func(r *doltdb.RootValue) { 171 act, ok, err := r.GetFeatureVersion(ctx) 172 require.NoError(t, err) 173 require.True(t, ok) 174 assert.Equal(t, test.expVer, act) 175 } 176 177 working, err := dEnv.WorkingRoot(ctx) 178 require.NoError(t, err) 179 assertFeatureVersion(working) 180 }) 181 182 // ensure |doltdb.DoltFeatureVersion| was restored 183 assert.Equal(t, DoltFeatureVersionCopy, doltdb.DoltFeatureVersion) 184 } 185 }