github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/merge/schema_integration_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 merge_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 "github.com/dolthub/dolt/go/libraries/doltcore/merge" 30 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 31 "github.com/dolthub/dolt/go/libraries/doltcore/schema/typeinfo" 32 ) 33 34 type testCommand struct { 35 cmd cli.Command 36 args args 37 } 38 39 func (tc testCommand) exec(t *testing.T, ctx context.Context, dEnv *env.DoltEnv) { 40 exitCode := tc.cmd.Exec(ctx, tc.cmd.Name(), tc.args, dEnv) 41 require.Equal(t, 0, exitCode) 42 } 43 44 type args []string 45 46 func TestMergeSchemas(t *testing.T) { 47 for _, test := range mergeSchemaTests { 48 t.Run(test.name, func(t *testing.T) { 49 testMergeSchemas(t, test) 50 }) 51 } 52 for _, test := range mergeSchemaConflictTests { 53 t.Run(test.name, func(t *testing.T) { 54 testMergeSchemasWithConflicts(t, test) 55 }) 56 } 57 for _, test := range mergeForeignKeyTests { 58 t.Run(test.name, func(t *testing.T) { 59 testMergeForeignKeys(t, test) 60 }) 61 } 62 } 63 64 type mergeSchemaTest struct { 65 name string 66 setup []testCommand 67 sch schema.Schema 68 } 69 70 type mergeSchemaConflictTest struct { 71 name string 72 setup []testCommand 73 expConflict merge.SchemaConflict 74 } 75 76 type mergeForeignKeyTest struct { 77 name string 78 setup []testCommand 79 fkColl *doltdb.ForeignKeyCollection 80 expFKConflict []merge.FKConflict 81 } 82 83 var setupCommon = []testCommand{ 84 {commands.SqlCmd{}, []string{"-q", "create table test (" + 85 "pk int not null primary key," + 86 "c1 int not null," + 87 "c2 int," + 88 "c3 int);"}}, 89 {commands.SqlCmd{}, []string{"-q", "create index c1_idx on test(c1)"}}, 90 {commands.AddCmd{}, []string{"."}}, 91 {commands.CommitCmd{}, []string{"-m", "setup common"}}, 92 {commands.BranchCmd{}, []string{"other"}}, 93 } 94 95 var mergeSchemaTests = []mergeSchemaTest{ 96 { 97 name: "no changes", 98 setup: []testCommand{}, 99 sch: schemaFromColsAndIdxs( 100 colCollection( 101 newColTypeInfo("pk", uint64(3228), typeinfo.Int32Type, true, schema.NotNullConstraint{}), 102 newColTypeInfo("c1", uint64(8201), typeinfo.Int32Type, false, schema.NotNullConstraint{}), 103 newColTypeInfo("c2", uint64(8539), typeinfo.Int32Type, false), 104 newColTypeInfo("c3", uint64(4696), typeinfo.Int32Type, false)), 105 schema.NewIndex("c1_idx", []uint64{8201}, []uint64{8201, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 106 ), 107 }, 108 { 109 name: "add cols, drop cols, merge", 110 setup: []testCommand{ 111 {commands.SqlCmd{}, []string{"-q", "alter table test drop column c2;"}}, 112 {commands.SqlCmd{}, []string{"-q", "alter table test add column c8 int;"}}, 113 {commands.AddCmd{}, []string{"."}}, 114 {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 115 {commands.CheckoutCmd{}, []string{"other"}}, 116 {commands.SqlCmd{}, []string{"-q", "alter table test drop column c3;"}}, 117 {commands.SqlCmd{}, []string{"-q", "alter table test add column c9 int;"}}, 118 {commands.AddCmd{}, []string{"."}}, 119 {commands.CommitCmd{}, []string{"-m", "modified branch other"}}, 120 {commands.CheckoutCmd{}, []string{"master"}}, 121 }, 122 sch: schemaFromColsAndIdxs( 123 colCollection( 124 newColTypeInfo("pk", uint64(3228), typeinfo.Int32Type, true, schema.NotNullConstraint{}), 125 newColTypeInfo("c1", uint64(8201), typeinfo.Int32Type, false, schema.NotNullConstraint{}), 126 newColTypeInfo("c8", uint64(12393), typeinfo.Int32Type, false), 127 newColTypeInfo("c9", uint64(4508), typeinfo.Int32Type, false)), 128 schema.NewIndex("c1_idx", []uint64{8201}, []uint64{8201, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 129 ), 130 }, 131 { 132 name: "add constraint, drop constraint, merge", 133 setup: []testCommand{ 134 {commands.SqlCmd{}, []string{"-q", "alter table test modify c1 int null;"}}, 135 {commands.AddCmd{}, []string{"."}}, 136 {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 137 {commands.CheckoutCmd{}, []string{"other"}}, 138 {commands.SqlCmd{}, []string{"-q", "alter table test modify c2 int not null;"}}, 139 {commands.AddCmd{}, []string{"."}}, 140 {commands.CommitCmd{}, []string{"-m", "modified branch other"}}, 141 {commands.CheckoutCmd{}, []string{"master"}}, 142 }, 143 sch: schemaFromColsAndIdxs( 144 colCollection( 145 newColTypeInfo("pk", uint64(3228), typeinfo.Int32Type, true, schema.NotNullConstraint{}), 146 newColTypeInfo("c1", uint64(8201), typeinfo.Int32Type, false), 147 newColTypeInfo("c2", uint64(8539), typeinfo.Int32Type, false, schema.NotNullConstraint{}), 148 newColTypeInfo("c3", uint64(4696), typeinfo.Int32Type, false)), 149 schema.NewIndex("c1_idx", []uint64{8201}, []uint64{8201, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 150 ), 151 }, 152 { 153 name: "add index, drop index, merge", 154 setup: []testCommand{ 155 {commands.SqlCmd{}, []string{"-q", "create index c3_idx on test(c3);"}}, 156 {commands.AddCmd{}, []string{"."}}, 157 {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 158 {commands.CheckoutCmd{}, []string{"other"}}, 159 {commands.SqlCmd{}, []string{"-q", "alter table test drop index c1_idx;"}}, 160 {commands.AddCmd{}, []string{"."}}, 161 {commands.CommitCmd{}, []string{"-m", "modified branch other"}}, 162 {commands.CheckoutCmd{}, []string{"master"}}, 163 }, 164 sch: schemaFromColsAndIdxs( 165 colCollection( 166 newColTypeInfo("pk", uint64(3228), typeinfo.Int32Type, true, schema.NotNullConstraint{}), 167 newColTypeInfo("c1", uint64(8201), typeinfo.Int32Type, false, schema.NotNullConstraint{}), 168 newColTypeInfo("c2", uint64(8539), typeinfo.Int32Type, false), 169 newColTypeInfo("c3", uint64(4696), typeinfo.Int32Type, false)), 170 schema.NewIndex("c3_idx", []uint64{4696}, []uint64{4696, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 171 ), 172 }, 173 { 174 name: "rename columns", 175 setup: []testCommand{ 176 {commands.SqlCmd{}, []string{"-q", "alter table test rename column c3 to c33;"}}, 177 {commands.AddCmd{}, []string{"."}}, 178 {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 179 {commands.CheckoutCmd{}, []string{"other"}}, 180 {commands.SqlCmd{}, []string{"-q", "alter table test rename column c2 to c22;"}}, 181 {commands.AddCmd{}, []string{"."}}, 182 {commands.CommitCmd{}, []string{"-m", "modified branch other"}}, 183 {commands.CheckoutCmd{}, []string{"master"}}, 184 }, 185 sch: schemaFromColsAndIdxs( 186 colCollection( 187 newColTypeInfo("pk", uint64(3228), typeinfo.Int32Type, true, schema.NotNullConstraint{}), 188 newColTypeInfo("c1", uint64(8201), typeinfo.Int32Type, false, schema.NotNullConstraint{}), 189 newColTypeInfo("c22", uint64(8539), typeinfo.Int32Type, false), 190 newColTypeInfo("c33", uint64(4696), typeinfo.Int32Type, false)), 191 schema.NewIndex("c1_idx", []uint64{8201}, []uint64{8201, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 192 ), 193 }, 194 { 195 name: "rename indexes", 196 setup: []testCommand{ 197 {commands.SqlCmd{}, []string{"-q", "alter table test drop index c1_idx;"}}, 198 {commands.SqlCmd{}, []string{"-q", "create index c1_index on test(c1);"}}, 199 {commands.AddCmd{}, []string{"."}}, 200 {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 201 }, 202 sch: schemaFromColsAndIdxs( 203 colCollection( 204 newColTypeInfo("pk", uint64(3228), typeinfo.Int32Type, true, schema.NotNullConstraint{}), 205 newColTypeInfo("c1", uint64(8201), typeinfo.Int32Type, false, schema.NotNullConstraint{}), 206 newColTypeInfo("c2", uint64(8539), typeinfo.Int32Type, false), 207 newColTypeInfo("c3", uint64(4696), typeinfo.Int32Type, false)), 208 schema.NewIndex("c1_index", []uint64{8201}, []uint64{8201, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 209 ), 210 }, 211 { 212 name: "add same column on both branches, merge", 213 setup: []testCommand{ 214 {commands.SqlCmd{}, []string{"-q", "alter table test add column c4 int;"}}, 215 {commands.AddCmd{}, []string{"."}}, 216 {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 217 {commands.CheckoutCmd{}, []string{"other"}}, 218 {commands.SqlCmd{}, []string{"-q", "alter table test add column c4 int;"}}, 219 {commands.AddCmd{}, []string{"."}}, 220 {commands.CommitCmd{}, []string{"-m", "modified branch other"}}, 221 {commands.CheckoutCmd{}, []string{"master"}}, 222 }, 223 sch: schemaFromColsAndIdxs( 224 colCollection( 225 newColTypeInfo("pk", uint64(3228), typeinfo.Int32Type, true, schema.NotNullConstraint{}), 226 newColTypeInfo("c1", uint64(8201), typeinfo.Int32Type, false, schema.NotNullConstraint{}), 227 newColTypeInfo("c2", uint64(8539), typeinfo.Int32Type, false), 228 newColTypeInfo("c3", uint64(4696), typeinfo.Int32Type, false), 229 newColTypeInfo("c4", uint64(1716), typeinfo.Int32Type, false)), 230 schema.NewIndex("c1_idx", []uint64{8201}, []uint64{8201, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 231 ), 232 }, 233 { 234 name: "add same index on both branches, merge", 235 setup: []testCommand{ 236 {commands.SqlCmd{}, []string{"-q", "create index c3_idx on test(c3);"}}, 237 {commands.AddCmd{}, []string{"."}}, 238 {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 239 {commands.CheckoutCmd{}, []string{"other"}}, 240 {commands.SqlCmd{}, []string{"-q", "create index c3_idx on test(c3);"}}, 241 {commands.AddCmd{}, []string{"."}}, 242 {commands.CommitCmd{}, []string{"-m", "modified branch other"}}, 243 {commands.CheckoutCmd{}, []string{"master"}}, 244 }, 245 sch: schemaFromColsAndIdxs( 246 colCollection( 247 newColTypeInfo("pk", uint64(3228), typeinfo.Int32Type, true, schema.NotNullConstraint{}), 248 newColTypeInfo("c1", uint64(8201), typeinfo.Int32Type, false, schema.NotNullConstraint{}), 249 newColTypeInfo("c2", uint64(8539), typeinfo.Int32Type, false), 250 newColTypeInfo("c3", uint64(4696), typeinfo.Int32Type, false)), 251 schema.NewIndex("c1_idx", []uint64{8201}, []uint64{8201, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 252 schema.NewIndex("c3_idx", []uint64{4696}, []uint64{4696, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 253 ), 254 }, 255 } 256 257 var mergeSchemaConflictTests = []mergeSchemaConflictTest{ 258 { 259 name: "no conflicts", 260 expConflict: merge.SchemaConflict{ 261 TableName: "test", 262 }, 263 }, 264 { 265 name: "column name collisions", 266 setup: []testCommand{ 267 {commands.SqlCmd{}, []string{"-q", "alter table test rename column c3 to c4;"}}, 268 {commands.SqlCmd{}, []string{"-q", "alter table test add column C6 int;"}}, 269 {commands.AddCmd{}, []string{"."}}, 270 {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 271 {commands.CheckoutCmd{}, []string{"other"}}, 272 {commands.SqlCmd{}, []string{"-q", "alter table test rename column c2 to c4;"}}, 273 {commands.SqlCmd{}, []string{"-q", "alter table test add column c6 int;"}}, 274 {commands.AddCmd{}, []string{"."}}, 275 {commands.CommitCmd{}, []string{"-m", "modified branch other"}}, 276 {commands.CheckoutCmd{}, []string{"master"}}, 277 }, 278 expConflict: merge.SchemaConflict{ 279 TableName: "test", 280 ColConflicts: []merge.ColConflict{ 281 { 282 Kind: merge.NameCollision, 283 Ours: newColTypeInfo("c4", uint64(3), typeinfo.Int32Type, false), 284 Theirs: newColTypeInfo("c4", uint64(2), typeinfo.Int32Type, false), 285 }, 286 { 287 Kind: merge.NameCollision, 288 Ours: newColTypeInfo("C6", uint64(13), typeinfo.Int32Type, false), 289 Theirs: newColTypeInfo("c6", uint64(19), typeinfo.Int32Type, false), 290 }, 291 }, 292 }, 293 }, 294 { 295 name: "index name collisions", 296 setup: []testCommand{ 297 {commands.SqlCmd{}, []string{"-q", "create index both on test (c1,c2);"}}, 298 {commands.AddCmd{}, []string{"."}}, 299 {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 300 {commands.CheckoutCmd{}, []string{"other"}}, 301 {commands.SqlCmd{}, []string{"-q", "create index both on test (c2, c3);"}}, 302 {commands.AddCmd{}, []string{"."}}, 303 {commands.CommitCmd{}, []string{"-m", "modified branch other"}}, 304 {commands.CheckoutCmd{}, []string{"master"}}, 305 }, 306 expConflict: merge.SchemaConflict{ 307 TableName: "test", 308 IdxConflicts: []merge.IdxConflict{ 309 { 310 Kind: merge.NameCollision, 311 Ours: schema.NewIndex("both", []uint64{8201, 8539}, []uint64{8201, 8539, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 312 Theirs: schema.NewIndex("both", []uint64{8539, 4696}, []uint64{8539, 4696, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 313 }, 314 }, 315 }, 316 }, 317 { 318 name: "column definition collision", 319 setup: []testCommand{ 320 {commands.SqlCmd{}, []string{"-q", "alter table test add column c40 int;"}}, 321 {commands.SqlCmd{}, []string{"-q", "alter table test add column c6 bigint;"}}, 322 {commands.AddCmd{}, []string{"."}}, 323 {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 324 {commands.CheckoutCmd{}, []string{"other"}}, 325 {commands.SqlCmd{}, []string{"-q", "alter table test add column c40 int;"}}, 326 {commands.SqlCmd{}, []string{"-q", "alter table test rename column c40 to c44;"}}, 327 {commands.SqlCmd{}, []string{"-q", "alter table test add column c6 tinyint;"}}, 328 {commands.AddCmd{}, []string{"."}}, 329 {commands.CommitCmd{}, []string{"-m", "modified branch other"}}, 330 {commands.CheckoutCmd{}, []string{"master"}}, 331 }, 332 expConflict: merge.SchemaConflict{ 333 TableName: "test", 334 ColConflicts: []merge.ColConflict{ 335 { 336 Kind: merge.TagCollision, 337 Ours: newColTypeInfo("c40", uint64(679), typeinfo.Int32Type, false), 338 Theirs: newColTypeInfo("c44", uint64(679), typeinfo.Int32Type, false), 339 }, 340 { 341 Kind: merge.TagCollision, 342 Ours: newColTypeInfo("c6", uint64(10774), typeinfo.Int64Type, false), 343 Theirs: newColTypeInfo("c6", uint64(10774), typeinfo.Int8Type, false), 344 }, 345 }, 346 }, 347 }, 348 { 349 name: "index definition collision", 350 setup: []testCommand{ 351 {commands.SqlCmd{}, []string{"-q", "create index c3_idx on test(c3);"}}, 352 {commands.AddCmd{}, []string{"."}}, 353 {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 354 {commands.CheckoutCmd{}, []string{"other"}}, 355 {commands.SqlCmd{}, []string{"-q", "create index c3_index on test(c3);"}}, 356 {commands.AddCmd{}, []string{"."}}, 357 {commands.CommitCmd{}, []string{"-m", "modified branch other"}}, 358 {commands.CheckoutCmd{}, []string{"master"}}, 359 }, 360 expConflict: merge.SchemaConflict{ 361 TableName: "test", 362 IdxConflicts: []merge.IdxConflict{ 363 { 364 Kind: merge.TagCollision, 365 Ours: schema.NewIndex("c3_idx", []uint64{4696}, []uint64{4696, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 366 Theirs: schema.NewIndex("c3_index", []uint64{4696}, []uint64{4696, 3228}, nil, schema.IndexProperties{IsUserDefined: true}), 367 }, 368 }, 369 }, 370 }, 371 } 372 373 var setupForeignKeyTests = []testCommand{ 374 {commands.SqlCmd{}, []string{"-q", "create table test (" + 375 "pk int not null primary key," + 376 "t1 int not null," + 377 "t2 int," + 378 "t3 int);"}}, 379 {commands.SqlCmd{}, []string{"-q", "alter table test add index t1_idx (t1);"}}, 380 {commands.SqlCmd{}, []string{"-q", "create table quiz (" + 381 "pk int not null primary key," + 382 "q1 int not null," + 383 "q2 int not null," + 384 "index q2_idx (q2)," + 385 "constraint q1_fk foreign key (q1) references test(t1));"}}, 386 {commands.AddCmd{}, []string{"."}}, 387 {commands.CommitCmd{}, []string{"-m", "setup common"}}, 388 {commands.BranchCmd{}, []string{"other"}}, 389 } 390 391 var mergeForeignKeyTests = []mergeForeignKeyTest{ 392 { 393 name: "no changes", 394 setup: []testCommand{}, 395 fkColl: fkCollection(doltdb.ForeignKey{ 396 Name: "q1_fk", 397 TableName: "quiz", 398 TableIndex: "q1", 399 TableColumns: []uint64{13001}, 400 ReferencedTableName: "test", 401 ReferencedTableIndex: "t1_idx", 402 ReferencedTableColumns: []uint64{12111}}), 403 expFKConflict: []merge.FKConflict{}, 404 }, 405 //{ 406 // name: "add foreign key, drop foreign key, merge", 407 // setup: []testCommand{ 408 // {commands.SqlCmd{}, []string{"-q", "alter table quiz add constraint q2_fk foreign key (q2) references test(t2);"}}, 409 // {commands.AddCmd{}, []string{"."}}, 410 // {commands.CommitCmd{}, []string{"-m", "modified branch master"}}, 411 // {commands.CheckoutCmd{}, []string{"other"}}, 412 // {commands.SqlCmd{}, []string{"-q", "alter table quiz drop constraint q1_fk;"}}, 413 // {commands.AddCmd{}, []string{"."}}, 414 // {commands.CommitCmd{}, []string{"-m", "modified branch other"}}, 415 // {commands.CheckoutCmd{}, []string{"master"}}, 416 // }, 417 // fkColl: fkCollection( 418 // &doltdb.ForeignKey{ 419 // Name: "q2_fk", 420 // TableName: "quiz", 421 // TableIndex: "dolt_fk_2", 422 // TableColumns: []uint64{12}, 423 // ReferencedTableName: "test", 424 // ReferencedTableIndex: "dolt_fk_2", 425 // ReferencedTableColumns: []uint64{2}}), 426 // expFKConflict: []merge.FKConflict{}, 427 //}, 428 } 429 430 func colCollection(cols ...schema.Column) *schema.ColCollection { 431 return schema.NewColCollection(cols...) 432 } 433 434 // SchemaFromColsAndIdxs creates a Schema from a ColCollection and an IndexCollection. 435 func schemaFromColsAndIdxs(allCols *schema.ColCollection, indexes ...schema.Index) schema.Schema { 436 sch := schema.MustSchemaFromCols(allCols) 437 sch.Indexes().AddIndex(indexes...) 438 return sch 439 } 440 441 func newColTypeInfo(name string, tag uint64, typeInfo typeinfo.TypeInfo, partOfPK bool, constraints ...schema.ColConstraint) schema.Column { 442 c, err := schema.NewColumnWithTypeInfo(name, tag, typeInfo, partOfPK, "", false, "", constraints...) 443 if err != nil { 444 panic("could not create column") 445 } 446 return c 447 } 448 449 func fkCollection(fks ...doltdb.ForeignKey) *doltdb.ForeignKeyCollection { 450 fkc, err := doltdb.NewForeignKeyCollection(fks...) 451 if err != nil { 452 panic(err) 453 } 454 return fkc 455 } 456 457 func testMergeSchemas(t *testing.T, test mergeSchemaTest) { 458 dEnv := dtestutils.CreateTestEnv() 459 ctx := context.Background() 460 for _, c := range setupCommon { 461 c.exec(t, ctx, dEnv) 462 } 463 for _, c := range test.setup { 464 c.exec(t, ctx, dEnv) 465 } 466 467 // assert that we're on master 468 exitCode := commands.CheckoutCmd{}.Exec(ctx, "checkout", []string{"master"}, dEnv) 469 require.Equal(t, 0, exitCode) 470 471 // merge branches 472 exitCode = commands.MergeCmd{}.Exec(ctx, "merge", []string{"other"}, dEnv) 473 assert.Equal(t, 0, exitCode) 474 475 wr, err := dEnv.WorkingRoot(ctx) 476 assert.NoError(t, err) 477 tbl, ok, err := wr.GetTable(ctx, "test") 478 assert.True(t, ok) 479 require.NoError(t, err) 480 sch, err := tbl.GetSchema(ctx) 481 require.NoError(t, err) 482 483 assert.Equal(t, test.sch.GetAllCols(), sch.GetAllCols()) 484 assert.Equal(t, test.sch.Indexes(), sch.Indexes()) 485 } 486 487 func testMergeSchemasWithConflicts(t *testing.T, test mergeSchemaConflictTest) { 488 getSchema := func(t *testing.T, dEnv *env.DoltEnv) schema.Schema { 489 ctx := context.Background() 490 wr, err := dEnv.WorkingRoot(ctx) 491 assert.NoError(t, err) 492 tbl, ok, err := wr.GetTable(ctx, "test") 493 assert.True(t, ok) 494 require.NoError(t, err) 495 sch, err := tbl.GetSchema(ctx) 496 require.NoError(t, err) 497 return sch 498 } 499 500 dEnv := dtestutils.CreateTestEnv() 501 ctx := context.Background() 502 for _, c := range setupCommon { 503 c.exec(t, ctx, dEnv) 504 } 505 506 ancSch := getSchema(t, dEnv) 507 508 for _, c := range test.setup { 509 c.exec(t, ctx, dEnv) 510 } 511 512 // assert that we're on master 513 exitCode := commands.CheckoutCmd{}.Exec(ctx, "checkout", []string{"master"}, dEnv) 514 require.Equal(t, 0, exitCode) 515 516 masterSch := getSchema(t, dEnv) 517 518 exitCode = commands.CheckoutCmd{}.Exec(ctx, "checkout", []string{"other"}, dEnv) 519 require.Equal(t, 0, exitCode) 520 521 otherSch := getSchema(t, dEnv) 522 523 _, actConflicts, err := merge.SchemaMerge(masterSch, otherSch, ancSch, "test") 524 require.NoError(t, err) 525 assert.Equal(t, actConflicts.TableName, "test") 526 527 assert.Equal(t, test.expConflict.Count(), actConflicts.Count()) 528 529 require.Equal(t, len(test.expConflict.IdxConflicts), len(actConflicts.IdxConflicts)) 530 for i, acc := range actConflicts.IdxConflicts { 531 assert.True(t, test.expConflict.IdxConflicts[i].Ours.Equals(acc.Ours)) 532 assert.True(t, test.expConflict.IdxConflicts[i].Theirs.Equals(acc.Theirs)) 533 } 534 535 require.Equal(t, len(test.expConflict.IdxConflicts), len(actConflicts.IdxConflicts)) 536 for i, icc := range actConflicts.IdxConflicts { 537 assert.True(t, test.expConflict.IdxConflicts[i].Ours.Equals(icc.Ours)) 538 assert.True(t, test.expConflict.IdxConflicts[i].Theirs.Equals(icc.Theirs)) 539 } 540 } 541 542 func testMergeForeignKeys(t *testing.T, test mergeForeignKeyTest) { 543 dEnv := dtestutils.CreateTestEnv() 544 ctx := context.Background() 545 for _, c := range setupForeignKeyTests { 546 c.exec(t, ctx, dEnv) 547 } 548 549 ancRoot, err := dEnv.WorkingRoot(ctx) 550 require.NoError(t, err) 551 552 for _, c := range test.setup { 553 c.exec(t, ctx, dEnv) 554 } 555 556 // assert that we're on master 557 exitCode := commands.CheckoutCmd{}.Exec(ctx, "checkout", []string{"master"}, dEnv) 558 require.Equal(t, 0, exitCode) 559 560 masterRoot, err := dEnv.WorkingRoot(ctx) 561 require.NoError(t, err) 562 563 exitCode = commands.CheckoutCmd{}.Exec(ctx, "checkout", []string{"other"}, dEnv) 564 require.Equal(t, 0, exitCode) 565 566 otherRoot, err := dEnv.WorkingRoot(ctx) 567 require.NoError(t, err) 568 569 mergedRoot, _, err := merge.MergeRoots(ctx, masterRoot, otherRoot, ancRoot) 570 assert.NoError(t, err) 571 572 fkc, err := mergedRoot.GetForeignKeyCollection(ctx) 573 assert.NoError(t, err) 574 assert.Equal(t, test.fkColl.Count(), fkc.Count()) 575 576 err = test.fkColl.Iter(func(expFK doltdb.ForeignKey) (stop bool, err error) { 577 actFK, ok := fkc.GetByTags(expFK.TableColumns, expFK.ReferencedTableColumns) 578 assert.True(t, ok) 579 assert.Equal(t, expFK, actFK) 580 return false, nil 581 }) 582 assert.NoError(t, err) 583 }