github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/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 cliCtx, _ := commands.NewArgFreeCliContext(ctx, dEnv) 63 64 return cmd.cmd.Exec(ctx, cmd.cmd.Name(), cmd.args, dEnv, cliCtx) 65 } 66 67 type fvUser struct { 68 vers doltdb.FeatureVersion 69 } 70 71 var NewClient = fvUser{vers: newVersion} 72 var OldClient = fvUser{vers: oldVersion} 73 74 func TestFeatureVersion(t *testing.T) { 75 76 tests := []fvTest{ 77 { 78 name: "smoke test", 79 setup: []fvCommand{ 80 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 81 }, 82 expVer: oldVersion, 83 }, 84 { 85 name: "CREATE TABLE statements write feature version", 86 setup: []fvCommand{ 87 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 88 {NewClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE quiz (pk int PRIMARY KEY);"}}, 89 }, 90 expVer: newVersion, 91 }, 92 { 93 name: "DROP TABLE statements write feature version", 94 setup: []fvCommand{ 95 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 96 {NewClient, commands.SqlCmd{}, args{"-q", "DROP TABLE test;"}}, 97 }, 98 expVer: newVersion, 99 }, 100 { 101 name: "schema changes write feature version", 102 setup: []fvCommand{ 103 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 104 {NewClient, commands.SqlCmd{}, args{"-q", "ALTER TABLE test ADD COLUMN c0 int;"}}, 105 }, 106 expVer: newVersion, 107 }, 108 { 109 name: "INSERT statements write feature version", 110 setup: []fvCommand{ 111 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 112 {NewClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (0);"}}, 113 }, 114 expVer: newVersion, 115 }, 116 { 117 name: "UPDATE statements write feature version", 118 setup: []fvCommand{ 119 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 120 {OldClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (0);"}}, 121 {NewClient, commands.SqlCmd{}, args{"-q", "UPDATE test SET pk = 1;"}}, 122 }, 123 expVer: newVersion, 124 }, 125 { 126 name: "DELETE statements write feature version", 127 setup: []fvCommand{ 128 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 129 {OldClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (0);"}}, 130 {NewClient, commands.SqlCmd{}, args{"-q", "DELETE FROM test WHERE pk = 0;"}}, 131 }, 132 expVer: newVersion, 133 }, 134 { 135 name: "new client writes to table, locking out old client", 136 setup: []fvCommand{ 137 {OldClient, commands.SqlCmd{}, args{"-q", "CREATE TABLE test (pk int PRIMARY KEY);"}}, 138 {OldClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (0);"}}, 139 {NewClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (1);"}}, 140 }, 141 errCmds: []fvCommand{ 142 // old client can't write 143 {OldClient, commands.SqlCmd{}, args{"-q", "INSERT INTO test VALUES (2);"}}, 144 // old client can't read 145 {OldClient, commands.SqlCmd{}, args{"-q", "SELECT * FROM test;"}}, 146 }, 147 expVer: newVersion, 148 }, 149 } 150 151 ctx := context.Background() 152 for _, test := range tests { 153 t.Run(test.name, func(t *testing.T) { 154 155 doltdb.DoltFeatureVersion = oldVersion 156 dEnv := dtestutils.CreateTestEnv() 157 defer dEnv.DoltDB.Close() 158 doltdb.DoltFeatureVersion = DoltFeatureVersionCopy 159 160 for _, cmd := range test.setup { 161 code := cmd.exec(ctx, dEnv) 162 require.Equal(t, 0, code) 163 } 164 for _, cmd := range test.errCmds { 165 code := cmd.exec(ctx, dEnv) 166 require.NotEqual(t, 0, code) 167 } 168 169 // execute assertions with newVersion to avoid OutOfDate errors 170 doltdb.DoltFeatureVersion = newVersion 171 defer func() { doltdb.DoltFeatureVersion = DoltFeatureVersionCopy }() 172 173 assertFeatureVersion := func(r doltdb.RootValue) { 174 act, ok, err := r.GetFeatureVersion(ctx) 175 require.NoError(t, err) 176 require.True(t, ok) 177 assert.Equal(t, test.expVer, act) 178 } 179 180 working, err := dEnv.WorkingRoot(ctx) 181 require.NoError(t, err) 182 assertFeatureVersion(working) 183 }) 184 185 // ensure |doltdb.DoltFeatureVersion| was restored 186 assert.Equal(t, DoltFeatureVersionCopy, doltdb.DoltFeatureVersion) 187 } 188 }