github.com/atrox/migrate@v3.5.4+incompatible/migrate_test.go (about) 1 package migrate 2 3 import ( 4 "bytes" 5 "database/sql" 6 "io/ioutil" 7 "log" 8 "os" 9 "testing" 10 11 dStub "github.com/golang-migrate/migrate/database/stub" 12 "github.com/golang-migrate/migrate/source" 13 sStub "github.com/golang-migrate/migrate/source/stub" 14 ) 15 16 // sourceStubMigrations hold the following migrations: 17 // u = up migration, d = down migration, n = version 18 // | 1 | - | 3 | 4 | 5 | - | 7 | 19 // | u d | - | u | u d | d | - | u d | 20 var sourceStubMigrations *source.Migrations 21 22 func init() { 23 sourceStubMigrations = source.NewMigrations() 24 sourceStubMigrations.Append(&source.Migration{Version: 1, Direction: source.Up, Identifier: "CREATE 1"}) 25 sourceStubMigrations.Append(&source.Migration{Version: 1, Direction: source.Down, Identifier: "DROP 1"}) 26 sourceStubMigrations.Append(&source.Migration{Version: 3, Direction: source.Up, Identifier: "CREATE 3"}) 27 sourceStubMigrations.Append(&source.Migration{Version: 4, Direction: source.Up, Identifier: "CREATE 4"}) 28 sourceStubMigrations.Append(&source.Migration{Version: 4, Direction: source.Down, Identifier: "DROP 4"}) 29 sourceStubMigrations.Append(&source.Migration{Version: 5, Direction: source.Down, Identifier: "DROP 5"}) 30 sourceStubMigrations.Append(&source.Migration{Version: 7, Direction: source.Up, Identifier: "CREATE 7"}) 31 sourceStubMigrations.Append(&source.Migration{Version: 7, Direction: source.Down, Identifier: "DROP 7"}) 32 } 33 34 type DummyInstance struct{ Name string } 35 36 func TestNew(t *testing.T) { 37 m, err := New("stub://", "stub://") 38 if err != nil { 39 t.Fatal(err) 40 } 41 42 if m.sourceName != "stub" { 43 t.Errorf("expected stub, got %v", m.sourceName) 44 } 45 if m.sourceDrv == nil { 46 t.Error("expected sourceDrv not to be nil") 47 } 48 49 if m.databaseName != "stub" { 50 t.Errorf("expected stub, got %v", m.databaseName) 51 } 52 if m.databaseDrv == nil { 53 t.Error("expected databaseDrv not to be nil") 54 } 55 } 56 57 func ExampleNew() { 58 // Read migrations from /home/mattes/migrations and connect to a local postgres database. 59 m, err := New("file:///home/mattes/migrations", "postgres://mattes:secret@localhost:5432/database?sslmode=disable") 60 if err != nil { 61 log.Fatal(err) 62 } 63 64 // Migrate all the way up ... 65 if err := m.Up(); err != nil { 66 log.Fatal(err) 67 } 68 } 69 70 func TestNewWithDatabaseInstance(t *testing.T) { 71 dummyDb := &DummyInstance{"database"} 72 dbInst, err := dStub.WithInstance(dummyDb, &dStub.Config{}) 73 if err != nil { 74 t.Fatal(err) 75 } 76 77 m, err := NewWithDatabaseInstance("stub://", "stub", dbInst) 78 if err != nil { 79 t.Fatal(err) 80 } 81 82 if m.sourceName != "stub" { 83 t.Errorf("expected stub, got %v", m.sourceName) 84 } 85 if m.sourceDrv == nil { 86 t.Error("expected sourceDrv not to be nil") 87 } 88 89 if m.databaseName != "stub" { 90 t.Errorf("expected stub, got %v", m.databaseName) 91 } 92 if m.databaseDrv == nil { 93 t.Error("expected databaseDrv not to be nil") 94 } 95 } 96 97 func ExampleNewWithDatabaseInstance() { 98 // Create and use an existing database instance. 99 db, err := sql.Open("postgres", "postgres://mattes:secret@localhost:5432/database?sslmode=disable") 100 if err != nil { 101 log.Fatal(err) 102 } 103 defer db.Close() 104 105 // Create driver instance from db. 106 // Check each driver if it supports the WithInstance function. 107 // `import "github.com/golang-migrate/migrate/database/postgres"` 108 instance, err := dStub.WithInstance(db, &dStub.Config{}) 109 if err != nil { 110 log.Fatal(err) 111 } 112 113 // Read migrations from /home/mattes/migrations and connect to a local postgres database. 114 m, err := NewWithDatabaseInstance("file:///home/mattes/migrations", "postgres", instance) 115 if err != nil { 116 log.Fatal(err) 117 } 118 119 // Migrate all the way up ... 120 if err := m.Up(); err != nil { 121 log.Fatal(err) 122 } 123 } 124 125 func TestNewWithSourceInstance(t *testing.T) { 126 dummySource := &DummyInstance{"source"} 127 sInst, err := sStub.WithInstance(dummySource, &sStub.Config{}) 128 if err != nil { 129 t.Fatal(err) 130 } 131 132 m, err := NewWithSourceInstance("stub", sInst, "stub://") 133 if err != nil { 134 t.Fatal(err) 135 } 136 137 if m.sourceName != "stub" { 138 t.Errorf("expected stub, got %v", m.sourceName) 139 } 140 if m.sourceDrv == nil { 141 t.Error("expected sourceDrv not to be nil") 142 } 143 144 if m.databaseName != "stub" { 145 t.Errorf("expected stub, got %v", m.databaseName) 146 } 147 if m.databaseDrv == nil { 148 t.Error("expected databaseDrv not to be nil") 149 } 150 } 151 152 func ExampleNewWithSourceInstance() { 153 di := &DummyInstance{"think any client required for a source here"} 154 155 // Create driver instance from DummyInstance di. 156 // Check each driver if it support the WithInstance function. 157 // `import "github.com/golang-migrate/migrate/source/stub"` 158 instance, err := sStub.WithInstance(di, &sStub.Config{}) 159 if err != nil { 160 log.Fatal(err) 161 } 162 163 // Read migrations from Stub and connect to a local postgres database. 164 m, err := NewWithSourceInstance("stub", instance, "postgres://mattes:secret@localhost:5432/database?sslmode=disable") 165 if err != nil { 166 log.Fatal(err) 167 } 168 169 // Migrate all the way up ... 170 if err := m.Up(); err != nil { 171 log.Fatal(err) 172 } 173 } 174 175 func TestNewWithInstance(t *testing.T) { 176 dummyDb := &DummyInstance{"database"} 177 dbInst, err := dStub.WithInstance(dummyDb, &dStub.Config{}) 178 if err != nil { 179 t.Fatal(err) 180 } 181 182 dummySource := &DummyInstance{"source"} 183 sInst, err := sStub.WithInstance(dummySource, &sStub.Config{}) 184 if err != nil { 185 t.Fatal(err) 186 } 187 188 m, err := NewWithInstance("stub", sInst, "stub", dbInst) 189 if err != nil { 190 t.Fatal(err) 191 } 192 193 if m.sourceName != "stub" { 194 t.Errorf("expected stub, got %v", m.sourceName) 195 } 196 if m.sourceDrv == nil { 197 t.Error("expected sourceDrv not to be nil") 198 } 199 200 if m.databaseName != "stub" { 201 t.Errorf("expected stub, got %v", m.databaseName) 202 } 203 if m.databaseDrv == nil { 204 t.Error("expected databaseDrv not to be nil") 205 } 206 } 207 208 func ExampleNewWithInstance() { 209 // See NewWithDatabaseInstance and NewWithSourceInstance for an example. 210 } 211 212 func TestClose(t *testing.T) { 213 m, _ := New("stub://", "stub://") 214 sourceErr, databaseErr := m.Close() 215 if sourceErr != nil { 216 t.Error(sourceErr) 217 } 218 if databaseErr != nil { 219 t.Error(databaseErr) 220 } 221 } 222 223 func TestMigrate(t *testing.T) { 224 m, _ := New("stub://", "stub://") 225 m.sourceDrv.(*sStub.Stub).Migrations = sourceStubMigrations 226 dbDrv := m.databaseDrv.(*dStub.Stub) 227 228 tt := []struct { 229 version uint 230 expectErr error 231 expectVersion uint 232 expectSeq migrationSequence 233 }{ 234 // migrate all the way Up in single steps 235 { 236 version: 0, 237 expectErr: os.ErrNotExist, 238 }, 239 { 240 version: 1, 241 expectVersion: 1, 242 expectSeq: migrationSequence{ 243 mr("CREATE 1"), 244 }, 245 }, 246 { 247 version: 2, 248 expectErr: os.ErrNotExist, 249 expectSeq: migrationSequence{ 250 mr("CREATE 1"), 251 }, 252 }, 253 { 254 version: 3, 255 expectVersion: 3, 256 expectSeq: migrationSequence{ 257 mr("CREATE 1"), 258 mr("CREATE 3"), 259 }, 260 }, 261 { 262 version: 4, 263 expectVersion: 4, 264 expectSeq: migrationSequence{ 265 mr("CREATE 1"), 266 mr("CREATE 3"), 267 mr("CREATE 4"), 268 }, 269 }, 270 { 271 version: 5, 272 expectVersion: 5, 273 expectSeq: migrationSequence{ // 5 has no up migration 274 mr("CREATE 1"), 275 mr("CREATE 3"), 276 mr("CREATE 4"), 277 }, 278 }, 279 { 280 version: 6, 281 expectErr: os.ErrNotExist, 282 expectSeq: migrationSequence{ 283 mr("CREATE 1"), 284 mr("CREATE 3"), 285 mr("CREATE 4"), 286 }, 287 }, 288 { 289 version: 7, 290 expectVersion: 7, 291 expectSeq: migrationSequence{ 292 mr("CREATE 1"), 293 mr("CREATE 3"), 294 mr("CREATE 4"), 295 mr("CREATE 7"), 296 }, 297 }, 298 { 299 version: 8, 300 expectErr: os.ErrNotExist, 301 expectSeq: migrationSequence{ 302 mr("CREATE 1"), 303 mr("CREATE 3"), 304 mr("CREATE 4"), 305 mr("CREATE 7"), 306 }, 307 }, 308 309 // migrate all the way Down in single steps 310 { 311 version: 6, 312 expectErr: os.ErrNotExist, 313 expectSeq: migrationSequence{ 314 mr("CREATE 1"), 315 mr("CREATE 3"), 316 mr("CREATE 4"), 317 mr("CREATE 7"), 318 }, 319 }, 320 { 321 version: 5, 322 expectVersion: 5, 323 expectSeq: migrationSequence{ 324 mr("CREATE 1"), 325 mr("CREATE 3"), 326 mr("CREATE 4"), 327 mr("CREATE 7"), 328 mr("DROP 7"), 329 }, 330 }, 331 { 332 version: 4, 333 expectVersion: 4, 334 expectSeq: migrationSequence{ 335 mr("CREATE 1"), 336 mr("CREATE 3"), 337 mr("CREATE 4"), 338 mr("CREATE 7"), 339 mr("DROP 7"), 340 mr("DROP 5"), 341 }, 342 }, 343 { 344 version: 3, 345 expectVersion: 3, 346 expectSeq: migrationSequence{ 347 mr("CREATE 1"), 348 mr("CREATE 3"), 349 mr("CREATE 4"), 350 mr("CREATE 7"), 351 mr("DROP 7"), 352 mr("DROP 5"), 353 mr("DROP 4"), 354 }, 355 }, 356 { 357 version: 2, 358 expectErr: os.ErrNotExist, 359 expectSeq: migrationSequence{ 360 mr("CREATE 1"), 361 mr("CREATE 3"), 362 mr("CREATE 4"), 363 mr("CREATE 7"), 364 mr("DROP 7"), 365 mr("DROP 5"), 366 mr("DROP 4"), 367 }, 368 }, 369 { 370 version: 1, 371 expectVersion: 1, 372 expectSeq: migrationSequence{ // 3 has no down migration 373 mr("CREATE 1"), 374 mr("CREATE 3"), 375 mr("CREATE 4"), 376 mr("CREATE 7"), 377 mr("DROP 7"), 378 mr("DROP 5"), 379 mr("DROP 4"), 380 }, 381 }, 382 { 383 version: 0, 384 expectErr: os.ErrNotExist, 385 expectSeq: migrationSequence{ 386 mr("CREATE 1"), 387 mr("CREATE 3"), 388 mr("CREATE 4"), 389 mr("CREATE 7"), 390 mr("DROP 7"), 391 mr("DROP 5"), 392 mr("DROP 4"), 393 }, 394 }, 395 396 // migrate all the way Up in one step 397 { 398 version: 7, 399 expectVersion: 7, 400 expectSeq: migrationSequence{ 401 mr("CREATE 1"), 402 mr("CREATE 3"), 403 mr("CREATE 4"), 404 mr("CREATE 7"), 405 mr("DROP 7"), 406 mr("DROP 5"), 407 mr("DROP 4"), 408 mr("CREATE 3"), 409 mr("CREATE 4"), 410 mr("CREATE 7"), 411 }, 412 }, 413 414 // migrate all the way Down in one step 415 { 416 version: 1, 417 expectVersion: 1, 418 expectSeq: migrationSequence{ 419 mr("CREATE 1"), 420 mr("CREATE 3"), 421 mr("CREATE 4"), 422 mr("CREATE 7"), 423 mr("DROP 7"), 424 mr("DROP 5"), 425 mr("DROP 4"), 426 mr("CREATE 3"), 427 mr("CREATE 4"), 428 mr("CREATE 7"), 429 mr("DROP 7"), 430 mr("DROP 5"), 431 mr("DROP 4"), 432 }, 433 }, 434 435 // can't migrate the same version twice 436 { 437 version: 1, 438 expectErr: ErrNoChange, 439 expectSeq: migrationSequence{ 440 mr("CREATE 1"), 441 mr("CREATE 3"), 442 mr("CREATE 4"), 443 mr("CREATE 7"), 444 mr("DROP 7"), 445 mr("DROP 5"), 446 mr("DROP 4"), 447 mr("CREATE 3"), 448 mr("CREATE 4"), 449 mr("CREATE 7"), 450 mr("DROP 7"), 451 mr("DROP 5"), 452 mr("DROP 4"), 453 }, 454 }, 455 } 456 457 for i, v := range tt { 458 err := m.Migrate(v.version) 459 if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) || 460 (v.expectErr != os.ErrNotExist && err != v.expectErr) { 461 t.Errorf("expected err %v, got %v, in %v", v.expectErr, err, i) 462 463 } else if err == nil { 464 version, _, err := m.Version() 465 if err != nil { 466 t.Error(err) 467 } 468 if version != v.expectVersion { 469 t.Errorf("expected version %v, got %v, in %v", v.expectVersion, version, i) 470 } 471 } 472 equalDbSeq(t, i, v.expectSeq, dbDrv) 473 } 474 } 475 476 func TestMigrateDirty(t *testing.T) { 477 m, _ := New("stub://", "stub://") 478 dbDrv := m.databaseDrv.(*dStub.Stub) 479 if err := dbDrv.SetVersion(0, true); err != nil { 480 t.Fatal(err) 481 } 482 483 err := m.Migrate(1) 484 if _, ok := err.(ErrDirty); !ok { 485 t.Fatalf("expected ErrDirty, got %v", err) 486 } 487 } 488 489 func TestSteps(t *testing.T) { 490 m, _ := New("stub://", "stub://") 491 m.sourceDrv.(*sStub.Stub).Migrations = sourceStubMigrations 492 dbDrv := m.databaseDrv.(*dStub.Stub) 493 494 tt := []struct { 495 steps int 496 expectErr error 497 expectVersion int 498 expectSeq migrationSequence 499 }{ 500 // step must be != 0 501 { 502 steps: 0, 503 expectErr: ErrNoChange, 504 }, 505 506 // can't go Down if ErrNilVersion 507 { 508 steps: -1, 509 expectErr: os.ErrNotExist, 510 }, 511 512 // migrate all the way Up 513 { 514 steps: 1, 515 expectVersion: 1, 516 expectSeq: migrationSequence{ 517 mr("CREATE 1")}, 518 }, 519 { 520 steps: 1, 521 expectVersion: 3, 522 expectSeq: migrationSequence{ 523 mr("CREATE 1"), 524 mr("CREATE 3"), 525 }, 526 }, 527 { 528 steps: 1, 529 expectVersion: 4, 530 expectSeq: migrationSequence{ 531 mr("CREATE 1"), 532 mr("CREATE 3"), 533 mr("CREATE 4"), 534 }, 535 }, 536 { 537 steps: 1, 538 expectVersion: 5, 539 expectSeq: migrationSequence{ 540 mr("CREATE 1"), 541 mr("CREATE 3"), 542 mr("CREATE 4"), 543 }, 544 }, 545 { 546 steps: 1, 547 expectVersion: 7, 548 expectSeq: migrationSequence{ 549 mr("CREATE 1"), 550 mr("CREATE 3"), 551 mr("CREATE 4"), 552 mr("CREATE 7"), 553 }, 554 }, 555 { 556 steps: 1, 557 expectErr: os.ErrNotExist, 558 expectSeq: migrationSequence{ 559 mr("CREATE 1"), 560 mr("CREATE 3"), 561 mr("CREATE 4"), 562 mr("CREATE 7"), 563 }, 564 }, 565 566 // migrate all the way Down 567 { 568 steps: -1, 569 expectVersion: 5, 570 expectSeq: migrationSequence{ 571 mr("CREATE 1"), 572 mr("CREATE 3"), 573 mr("CREATE 4"), 574 mr("CREATE 7"), 575 mr("DROP 7"), 576 }, 577 }, 578 { 579 steps: -1, 580 expectVersion: 4, 581 expectSeq: migrationSequence{ 582 mr("CREATE 1"), 583 mr("CREATE 3"), 584 mr("CREATE 4"), 585 mr("CREATE 7"), 586 mr("DROP 7"), 587 mr("DROP 5"), 588 }, 589 }, 590 { 591 steps: -1, 592 expectVersion: 3, 593 expectSeq: migrationSequence{ 594 mr("CREATE 1"), 595 mr("CREATE 3"), 596 mr("CREATE 4"), 597 mr("CREATE 7"), 598 mr("DROP 7"), 599 mr("DROP 5"), 600 mr("DROP 4"), 601 }, 602 }, 603 { 604 steps: -1, 605 expectVersion: 1, 606 expectSeq: migrationSequence{ 607 mr("CREATE 1"), 608 mr("CREATE 3"), 609 mr("CREATE 4"), 610 mr("CREATE 7"), 611 mr("DROP 7"), 612 mr("DROP 5"), 613 mr("DROP 4"), 614 }, 615 }, 616 { 617 steps: -1, 618 expectVersion: -1, 619 expectSeq: migrationSequence{ 620 mr("CREATE 1"), 621 mr("CREATE 3"), 622 mr("CREATE 4"), 623 mr("CREATE 7"), 624 mr("DROP 7"), 625 mr("DROP 5"), 626 mr("DROP 4"), 627 mr("DROP 1"), 628 }, 629 }, 630 631 // migrate Up in bigger step 632 { 633 steps: 4, 634 expectVersion: 5, 635 expectSeq: migrationSequence{ 636 mr("CREATE 1"), 637 mr("CREATE 3"), 638 mr("CREATE 4"), 639 mr("CREATE 7"), 640 mr("DROP 7"), 641 mr("DROP 5"), 642 mr("DROP 4"), 643 mr("DROP 1"), 644 mr("CREATE 1"), 645 mr("CREATE 3"), 646 mr("CREATE 4"), 647 }, 648 }, 649 650 // apply one migration, then reaches out of boundary 651 { 652 steps: 2, 653 expectErr: ErrShortLimit{1}, 654 expectVersion: 7, 655 expectSeq: migrationSequence{ 656 mr("CREATE 1"), 657 mr("CREATE 3"), 658 mr("CREATE 4"), 659 mr("CREATE 7"), 660 mr("DROP 7"), 661 mr("DROP 5"), 662 mr("DROP 4"), 663 mr("DROP 1"), 664 mr("CREATE 1"), 665 mr("CREATE 3"), 666 mr("CREATE 4"), 667 mr("CREATE 7"), 668 }, 669 }, 670 671 // migrate Down in bigger step 672 { 673 steps: -4, 674 expectVersion: 1, 675 expectSeq: migrationSequence{ 676 mr("CREATE 1"), 677 mr("CREATE 3"), 678 mr("CREATE 4"), 679 mr("CREATE 7"), 680 mr("DROP 7"), 681 mr("DROP 5"), 682 mr("DROP 4"), 683 mr("DROP 1"), 684 mr("CREATE 1"), 685 mr("CREATE 3"), 686 mr("CREATE 4"), 687 mr("CREATE 7"), 688 mr("DROP 7"), 689 mr("DROP 5"), 690 mr("DROP 4"), 691 }, 692 }, 693 694 // apply one migration, then reaches out of boundary 695 { 696 steps: -2, 697 expectErr: ErrShortLimit{1}, 698 expectVersion: -1, 699 expectSeq: migrationSequence{ 700 mr("CREATE 1"), 701 mr("CREATE 3"), 702 mr("CREATE 4"), 703 mr("CREATE 7"), 704 mr("DROP 7"), 705 mr("DROP 5"), 706 mr("DROP 4"), 707 mr("DROP 1"), 708 mr("CREATE 1"), 709 mr("CREATE 3"), 710 mr("CREATE 4"), 711 mr("CREATE 7"), 712 mr("DROP 7"), 713 mr("DROP 5"), 714 mr("DROP 4"), 715 mr("DROP 1"), 716 }, 717 }, 718 } 719 720 for i, v := range tt { 721 err := m.Steps(v.steps) 722 if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) || 723 (v.expectErr != os.ErrNotExist && err != v.expectErr) { 724 t.Errorf("expected err %v, got %v, in %v", v.expectErr, err, i) 725 726 } else if err == nil { 727 version, _, err := m.Version() 728 if err != ErrNilVersion && err != nil { 729 t.Error(err) 730 } 731 if v.expectVersion == -1 && err != ErrNilVersion { 732 t.Errorf("expected ErrNilVersion, got %v, in %v", version, i) 733 734 } else if v.expectVersion >= 0 && version != uint(v.expectVersion) { 735 t.Errorf("expected version %v, got %v, in %v", v.expectVersion, version, i) 736 } 737 } 738 equalDbSeq(t, i, v.expectSeq, dbDrv) 739 } 740 } 741 742 func TestStepsDirty(t *testing.T) { 743 m, _ := New("stub://", "stub://") 744 dbDrv := m.databaseDrv.(*dStub.Stub) 745 if err := dbDrv.SetVersion(0, true); err != nil { 746 t.Fatal(err) 747 } 748 749 err := m.Steps(1) 750 if _, ok := err.(ErrDirty); !ok { 751 t.Fatalf("expected ErrDirty, got %v", err) 752 } 753 } 754 755 func TestUpAndDown(t *testing.T) { 756 m, _ := New("stub://", "stub://") 757 m.sourceDrv.(*sStub.Stub).Migrations = sourceStubMigrations 758 dbDrv := m.databaseDrv.(*dStub.Stub) 759 760 // go Up first 761 if err := m.Up(); err != nil { 762 t.Fatal(err) 763 } 764 expectedSequence := migrationSequence{ 765 mr("CREATE 1"), 766 mr("CREATE 3"), 767 mr("CREATE 4"), 768 mr("CREATE 7"), 769 } 770 equalDbSeq(t, 0, expectedSequence, dbDrv) 771 772 // go Down 773 if err := m.Down(); err != nil { 774 t.Fatal(err) 775 } 776 expectedSequence = migrationSequence{ 777 mr("CREATE 1"), 778 mr("CREATE 3"), 779 mr("CREATE 4"), 780 mr("CREATE 7"), 781 mr("DROP 7"), 782 mr("DROP 5"), 783 mr("DROP 4"), 784 mr("DROP 1"), 785 } 786 equalDbSeq(t, 1, expectedSequence, dbDrv) 787 788 // go 1 Up and then all the way Up 789 if err := m.Steps(1); err != nil { 790 t.Fatal(err) 791 } 792 expectedSequence = migrationSequence{ 793 mr("CREATE 1"), 794 mr("CREATE 3"), 795 mr("CREATE 4"), 796 mr("CREATE 7"), 797 mr("DROP 7"), 798 mr("DROP 5"), 799 mr("DROP 4"), 800 mr("DROP 1"), 801 mr("CREATE 1"), 802 } 803 equalDbSeq(t, 2, expectedSequence, dbDrv) 804 805 if err := m.Up(); err != nil { 806 t.Fatal(err) 807 } 808 expectedSequence = migrationSequence{ 809 mr("CREATE 1"), 810 mr("CREATE 3"), 811 mr("CREATE 4"), 812 mr("CREATE 7"), 813 mr("DROP 7"), 814 mr("DROP 5"), 815 mr("DROP 4"), 816 mr("DROP 1"), 817 mr("CREATE 1"), 818 mr("CREATE 3"), 819 mr("CREATE 4"), 820 mr("CREATE 7"), 821 } 822 equalDbSeq(t, 3, expectedSequence, dbDrv) 823 824 // go 1 Down and then all the way Down 825 if err := m.Steps(-1); err != nil { 826 t.Fatal(err) 827 } 828 expectedSequence = migrationSequence{ 829 mr("CREATE 1"), 830 mr("CREATE 3"), 831 mr("CREATE 4"), 832 mr("CREATE 7"), 833 mr("DROP 7"), 834 mr("DROP 5"), 835 mr("DROP 4"), 836 mr("DROP 1"), 837 mr("CREATE 1"), 838 mr("CREATE 3"), 839 mr("CREATE 4"), 840 mr("CREATE 7"), 841 mr("DROP 7"), 842 } 843 equalDbSeq(t, 1, expectedSequence, dbDrv) 844 845 if err := m.Down(); err != nil { 846 t.Fatal(err) 847 } 848 expectedSequence = migrationSequence{ 849 mr("CREATE 1"), 850 mr("CREATE 3"), 851 mr("CREATE 4"), 852 mr("CREATE 7"), 853 mr("DROP 7"), 854 mr("DROP 5"), 855 mr("DROP 4"), 856 mr("DROP 1"), 857 mr("CREATE 1"), 858 mr("CREATE 3"), 859 mr("CREATE 4"), 860 mr("CREATE 7"), 861 mr("DROP 7"), 862 mr("DROP 5"), 863 mr("DROP 4"), 864 mr("DROP 1"), 865 } 866 equalDbSeq(t, 1, expectedSequence, dbDrv) 867 } 868 869 func TestUpDirty(t *testing.T) { 870 m, _ := New("stub://", "stub://") 871 dbDrv := m.databaseDrv.(*dStub.Stub) 872 if err := dbDrv.SetVersion(0, true); err != nil { 873 t.Fatal(err) 874 } 875 876 err := m.Up() 877 if _, ok := err.(ErrDirty); !ok { 878 t.Fatalf("expected ErrDirty, got %v", err) 879 } 880 } 881 882 func TestDownDirty(t *testing.T) { 883 m, _ := New("stub://", "stub://") 884 dbDrv := m.databaseDrv.(*dStub.Stub) 885 if err := dbDrv.SetVersion(0, true); err != nil { 886 t.Fatal(err) 887 } 888 889 err := m.Down() 890 if _, ok := err.(ErrDirty); !ok { 891 t.Fatalf("expected ErrDirty, got %v", err) 892 } 893 } 894 895 func TestDrop(t *testing.T) { 896 m, _ := New("stub://", "stub://") 897 m.sourceDrv.(*sStub.Stub).Migrations = sourceStubMigrations 898 dbDrv := m.databaseDrv.(*dStub.Stub) 899 900 if err := m.Drop(); err != nil { 901 t.Fatal(err) 902 } 903 904 if dbDrv.MigrationSequence[len(dbDrv.MigrationSequence)-1] != dStub.DROP { 905 t.Fatalf("expected database to DROP, got sequence %v", dbDrv.MigrationSequence) 906 } 907 } 908 909 func TestVersion(t *testing.T) { 910 m, _ := New("stub://", "stub://") 911 dbDrv := m.databaseDrv.(*dStub.Stub) 912 913 _, _, err := m.Version() 914 if err != ErrNilVersion { 915 t.Fatalf("expected ErrNilVersion, got %v", err) 916 } 917 918 if err := dbDrv.Run(bytes.NewBufferString("1_up")); err != nil { 919 t.Fatal(err) 920 } 921 922 if err := dbDrv.SetVersion(1, false); err != nil { 923 t.Fatal(err) 924 } 925 926 v, _, err := m.Version() 927 if err != nil { 928 t.Fatal(err) 929 } 930 931 if v != 1 { 932 t.Fatalf("expected version 1, got %v", v) 933 } 934 } 935 936 func TestRun(t *testing.T) { 937 m, _ := New("stub://", "stub://") 938 939 mx, err := NewMigration(nil, "", 1, 2) 940 if err != nil { 941 t.Fatal(err) 942 } 943 944 if err := m.Run(mx); err != nil { 945 t.Fatal(err) 946 } 947 948 v, _, err := m.Version() 949 if err != nil { 950 t.Fatal(err) 951 } 952 953 if v != 2 { 954 t.Errorf("expected version 2, got %v", v) 955 } 956 } 957 958 func TestRunDirty(t *testing.T) { 959 m, _ := New("stub://", "stub://") 960 dbDrv := m.databaseDrv.(*dStub.Stub) 961 if err := dbDrv.SetVersion(0, true); err != nil { 962 t.Fatal(err) 963 } 964 965 migr, err := NewMigration(nil, "", 1, 2) 966 if err != nil { 967 t.Fatal(err) 968 } 969 970 err = m.Run(migr) 971 if _, ok := err.(ErrDirty); !ok { 972 t.Fatalf("expected ErrDirty, got %v", err) 973 } 974 } 975 976 func TestForce(t *testing.T) { 977 m, _ := New("stub://", "stub://") 978 m.sourceDrv.(*sStub.Stub).Migrations = sourceStubMigrations 979 980 if err := m.Force(7); err != nil { 981 t.Fatal(err) 982 } 983 984 v, dirty, err := m.Version() 985 if err != nil { 986 t.Fatal(err) 987 } 988 if dirty { 989 t.Errorf("expected dirty to be false") 990 } 991 if v != 7 { 992 t.Errorf("expected version to be 7") 993 } 994 } 995 996 func TestForceDirty(t *testing.T) { 997 m, _ := New("stub://", "stub://") 998 dbDrv := m.databaseDrv.(*dStub.Stub) 999 if err := dbDrv.SetVersion(0, true); err != nil { 1000 t.Fatal(err) 1001 } 1002 1003 if err := m.Force(1); err != nil { 1004 t.Fatal(err) 1005 } 1006 } 1007 1008 func TestRead(t *testing.T) { 1009 m, _ := New("stub://", "stub://") 1010 m.sourceDrv.(*sStub.Stub).Migrations = sourceStubMigrations 1011 1012 tt := []struct { 1013 from int 1014 to int 1015 expectErr error 1016 expectMigrations migrationSequence 1017 }{ 1018 {from: -1, to: -1, expectErr: ErrNoChange}, 1019 {from: -1, to: 0, expectErr: os.ErrNotExist}, 1020 {from: -1, to: 1, expectErr: nil, expectMigrations: newMigSeq(M(1))}, 1021 {from: -1, to: 2, expectErr: os.ErrNotExist}, 1022 {from: -1, to: 3, expectErr: nil, expectMigrations: newMigSeq(M(1), M(3))}, 1023 {from: -1, to: 4, expectErr: nil, expectMigrations: newMigSeq(M(1), M(3), M(4))}, 1024 {from: -1, to: 5, expectErr: nil, expectMigrations: newMigSeq(M(1), M(3), M(4), M(5))}, 1025 {from: -1, to: 6, expectErr: os.ErrNotExist}, 1026 {from: -1, to: 7, expectErr: nil, expectMigrations: newMigSeq(M(1), M(3), M(4), M(5), M(7))}, 1027 {from: -1, to: 8, expectErr: os.ErrNotExist}, 1028 1029 {from: 0, to: -1, expectErr: os.ErrNotExist}, 1030 {from: 0, to: 0, expectErr: os.ErrNotExist}, 1031 {from: 0, to: 1, expectErr: os.ErrNotExist}, 1032 {from: 0, to: 2, expectErr: os.ErrNotExist}, 1033 {from: 0, to: 3, expectErr: os.ErrNotExist}, 1034 {from: 0, to: 4, expectErr: os.ErrNotExist}, 1035 {from: 0, to: 5, expectErr: os.ErrNotExist}, 1036 {from: 0, to: 6, expectErr: os.ErrNotExist}, 1037 {from: 0, to: 7, expectErr: os.ErrNotExist}, 1038 {from: 0, to: 8, expectErr: os.ErrNotExist}, 1039 1040 {from: 1, to: -1, expectErr: nil, expectMigrations: newMigSeq(M(1, -1))}, 1041 {from: 1, to: 0, expectErr: os.ErrNotExist}, 1042 {from: 1, to: 1, expectErr: ErrNoChange}, 1043 {from: 1, to: 2, expectErr: os.ErrNotExist}, 1044 {from: 1, to: 3, expectErr: nil, expectMigrations: newMigSeq(M(3))}, 1045 {from: 1, to: 4, expectErr: nil, expectMigrations: newMigSeq(M(3), M(4))}, 1046 {from: 1, to: 5, expectErr: nil, expectMigrations: newMigSeq(M(3), M(4), M(5))}, 1047 {from: 1, to: 6, expectErr: os.ErrNotExist}, 1048 {from: 1, to: 7, expectErr: nil, expectMigrations: newMigSeq(M(3), M(4), M(5), M(7))}, 1049 {from: 1, to: 8, expectErr: os.ErrNotExist}, 1050 1051 {from: 2, to: -1, expectErr: os.ErrNotExist}, 1052 {from: 2, to: 0, expectErr: os.ErrNotExist}, 1053 {from: 2, to: 1, expectErr: os.ErrNotExist}, 1054 {from: 2, to: 2, expectErr: os.ErrNotExist}, 1055 {from: 2, to: 3, expectErr: os.ErrNotExist}, 1056 {from: 2, to: 4, expectErr: os.ErrNotExist}, 1057 {from: 2, to: 5, expectErr: os.ErrNotExist}, 1058 {from: 2, to: 6, expectErr: os.ErrNotExist}, 1059 {from: 2, to: 7, expectErr: os.ErrNotExist}, 1060 {from: 2, to: 8, expectErr: os.ErrNotExist}, 1061 1062 {from: 3, to: -1, expectErr: nil, expectMigrations: newMigSeq(M(3, 1), M(1, -1))}, 1063 {from: 3, to: 0, expectErr: os.ErrNotExist}, 1064 {from: 3, to: 1, expectErr: nil, expectMigrations: newMigSeq(M(3, 1))}, 1065 {from: 3, to: 2, expectErr: os.ErrNotExist}, 1066 {from: 3, to: 3, expectErr: ErrNoChange}, 1067 {from: 3, to: 4, expectErr: nil, expectMigrations: newMigSeq(M(4))}, 1068 {from: 3, to: 5, expectErr: nil, expectMigrations: newMigSeq(M(4), M(5))}, 1069 {from: 3, to: 6, expectErr: os.ErrNotExist}, 1070 {from: 3, to: 7, expectErr: nil, expectMigrations: newMigSeq(M(4), M(5), M(7))}, 1071 {from: 3, to: 8, expectErr: os.ErrNotExist}, 1072 1073 {from: 4, to: -1, expectErr: nil, expectMigrations: newMigSeq(M(4, 3), M(3, 1), M(1, -1))}, 1074 {from: 4, to: 0, expectErr: os.ErrNotExist}, 1075 {from: 4, to: 1, expectErr: nil, expectMigrations: newMigSeq(M(4, 3), M(3, 1))}, 1076 {from: 4, to: 2, expectErr: os.ErrNotExist}, 1077 {from: 4, to: 3, expectErr: nil, expectMigrations: newMigSeq(M(4, 3))}, 1078 {from: 4, to: 4, expectErr: ErrNoChange}, 1079 {from: 4, to: 5, expectErr: nil, expectMigrations: newMigSeq(M(5))}, 1080 {from: 4, to: 6, expectErr: os.ErrNotExist}, 1081 {from: 4, to: 7, expectErr: nil, expectMigrations: newMigSeq(M(5), M(7))}, 1082 {from: 4, to: 8, expectErr: os.ErrNotExist}, 1083 1084 {from: 5, to: -1, expectErr: nil, expectMigrations: newMigSeq(M(5, 4), M(4, 3), M(3, 1), M(1, -1))}, 1085 {from: 5, to: 0, expectErr: os.ErrNotExist}, 1086 {from: 5, to: 1, expectErr: nil, expectMigrations: newMigSeq(M(5, 4), M(4, 3), M(3, 1))}, 1087 {from: 5, to: 2, expectErr: os.ErrNotExist}, 1088 {from: 5, to: 3, expectErr: nil, expectMigrations: newMigSeq(M(5, 4), M(4, 3))}, 1089 {from: 5, to: 4, expectErr: nil, expectMigrations: newMigSeq(M(5, 4))}, 1090 {from: 5, to: 5, expectErr: ErrNoChange}, 1091 {from: 5, to: 6, expectErr: os.ErrNotExist}, 1092 {from: 5, to: 7, expectErr: nil, expectMigrations: newMigSeq(M(7))}, 1093 {from: 5, to: 8, expectErr: os.ErrNotExist}, 1094 1095 {from: 6, to: -1, expectErr: os.ErrNotExist}, 1096 {from: 6, to: 0, expectErr: os.ErrNotExist}, 1097 {from: 6, to: 1, expectErr: os.ErrNotExist}, 1098 {from: 6, to: 2, expectErr: os.ErrNotExist}, 1099 {from: 6, to: 3, expectErr: os.ErrNotExist}, 1100 {from: 6, to: 4, expectErr: os.ErrNotExist}, 1101 {from: 6, to: 5, expectErr: os.ErrNotExist}, 1102 {from: 6, to: 6, expectErr: os.ErrNotExist}, 1103 {from: 6, to: 7, expectErr: os.ErrNotExist}, 1104 {from: 6, to: 8, expectErr: os.ErrNotExist}, 1105 1106 {from: 7, to: -1, expectErr: nil, expectMigrations: newMigSeq(M(7, 5), M(5, 4), M(4, 3), M(3, 1), M(1, -1))}, 1107 {from: 7, to: 0, expectErr: os.ErrNotExist}, 1108 {from: 7, to: 1, expectErr: nil, expectMigrations: newMigSeq(M(7, 5), M(5, 4), M(4, 3), M(3, 1))}, 1109 {from: 7, to: 2, expectErr: os.ErrNotExist}, 1110 {from: 7, to: 3, expectErr: nil, expectMigrations: newMigSeq(M(7, 5), M(5, 4), M(4, 3))}, 1111 {from: 7, to: 4, expectErr: nil, expectMigrations: newMigSeq(M(7, 5), M(5, 4))}, 1112 {from: 7, to: 5, expectErr: nil, expectMigrations: newMigSeq(M(7, 5))}, 1113 {from: 7, to: 6, expectErr: os.ErrNotExist}, 1114 {from: 7, to: 7, expectErr: ErrNoChange}, 1115 {from: 7, to: 8, expectErr: os.ErrNotExist}, 1116 1117 {from: 8, to: -1, expectErr: os.ErrNotExist}, 1118 {from: 8, to: 0, expectErr: os.ErrNotExist}, 1119 {from: 8, to: 1, expectErr: os.ErrNotExist}, 1120 {from: 8, to: 2, expectErr: os.ErrNotExist}, 1121 {from: 8, to: 3, expectErr: os.ErrNotExist}, 1122 {from: 8, to: 4, expectErr: os.ErrNotExist}, 1123 {from: 8, to: 5, expectErr: os.ErrNotExist}, 1124 {from: 8, to: 6, expectErr: os.ErrNotExist}, 1125 {from: 8, to: 7, expectErr: os.ErrNotExist}, 1126 {from: 8, to: 8, expectErr: os.ErrNotExist}, 1127 } 1128 1129 for i, v := range tt { 1130 ret := make(chan interface{}) 1131 go m.read(v.from, v.to, ret) 1132 migrations, err := migrationsFromChannel(ret) 1133 1134 if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) || 1135 (v.expectErr != os.ErrNotExist && v.expectErr != err) { 1136 t.Errorf("expected %v, got %v, in %v", v.expectErr, err, i) 1137 t.Logf("%v, in %v", migrations, i) 1138 } 1139 if len(v.expectMigrations) > 0 { 1140 equalMigSeq(t, i, v.expectMigrations, migrations) 1141 } 1142 } 1143 } 1144 1145 func TestReadUp(t *testing.T) { 1146 m, _ := New("stub://", "stub://") 1147 m.sourceDrv.(*sStub.Stub).Migrations = sourceStubMigrations 1148 1149 tt := []struct { 1150 from int 1151 limit int // -1 means no limit 1152 expectErr error 1153 expectMigrations migrationSequence 1154 }{ 1155 {from: -1, limit: -1, expectErr: nil, expectMigrations: newMigSeq(M(1), M(3), M(4), M(5), M(7))}, 1156 {from: -1, limit: 0, expectErr: ErrNoChange}, 1157 {from: -1, limit: 1, expectErr: nil, expectMigrations: newMigSeq(M(1))}, 1158 {from: -1, limit: 2, expectErr: nil, expectMigrations: newMigSeq(M(1), M(3))}, 1159 1160 {from: 0, limit: -1, expectErr: os.ErrNotExist}, 1161 {from: 0, limit: 0, expectErr: os.ErrNotExist}, 1162 {from: 0, limit: 1, expectErr: os.ErrNotExist}, 1163 {from: 0, limit: 2, expectErr: os.ErrNotExist}, 1164 1165 {from: 1, limit: -1, expectErr: nil, expectMigrations: newMigSeq(M(3), M(4), M(5), M(7))}, 1166 {from: 1, limit: 0, expectErr: ErrNoChange}, 1167 {from: 1, limit: 1, expectErr: nil, expectMigrations: newMigSeq(M(3))}, 1168 {from: 1, limit: 2, expectErr: nil, expectMigrations: newMigSeq(M(3), M(4))}, 1169 1170 {from: 2, limit: -1, expectErr: os.ErrNotExist}, 1171 {from: 2, limit: 0, expectErr: os.ErrNotExist}, 1172 {from: 2, limit: 1, expectErr: os.ErrNotExist}, 1173 {from: 2, limit: 2, expectErr: os.ErrNotExist}, 1174 1175 {from: 3, limit: -1, expectErr: nil, expectMigrations: newMigSeq(M(4), M(5), M(7))}, 1176 {from: 3, limit: 0, expectErr: ErrNoChange}, 1177 {from: 3, limit: 1, expectErr: nil, expectMigrations: newMigSeq(M(4))}, 1178 {from: 3, limit: 2, expectErr: nil, expectMigrations: newMigSeq(M(4), M(5))}, 1179 1180 {from: 4, limit: -1, expectErr: nil, expectMigrations: newMigSeq(M(5), M(7))}, 1181 {from: 4, limit: 0, expectErr: ErrNoChange}, 1182 {from: 4, limit: 1, expectErr: nil, expectMigrations: newMigSeq(M(5))}, 1183 {from: 4, limit: 2, expectErr: nil, expectMigrations: newMigSeq(M(5), M(7))}, 1184 1185 {from: 5, limit: -1, expectErr: nil, expectMigrations: newMigSeq(M(7))}, 1186 {from: 5, limit: 0, expectErr: ErrNoChange}, 1187 {from: 5, limit: 1, expectErr: nil, expectMigrations: newMigSeq(M(7))}, 1188 {from: 5, limit: 2, expectErr: ErrShortLimit{1}, expectMigrations: newMigSeq(M(7))}, 1189 1190 {from: 6, limit: -1, expectErr: os.ErrNotExist}, 1191 {from: 6, limit: 0, expectErr: os.ErrNotExist}, 1192 {from: 6, limit: 1, expectErr: os.ErrNotExist}, 1193 {from: 6, limit: 2, expectErr: os.ErrNotExist}, 1194 1195 {from: 7, limit: -1, expectErr: ErrNoChange}, 1196 {from: 7, limit: 0, expectErr: ErrNoChange}, 1197 {from: 7, limit: 1, expectErr: os.ErrNotExist}, 1198 {from: 7, limit: 2, expectErr: os.ErrNotExist}, 1199 1200 {from: 8, limit: -1, expectErr: os.ErrNotExist}, 1201 {from: 8, limit: 0, expectErr: os.ErrNotExist}, 1202 {from: 8, limit: 1, expectErr: os.ErrNotExist}, 1203 {from: 8, limit: 2, expectErr: os.ErrNotExist}, 1204 } 1205 1206 for i, v := range tt { 1207 ret := make(chan interface{}) 1208 go m.readUp(v.from, v.limit, ret) 1209 migrations, err := migrationsFromChannel(ret) 1210 1211 if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) || 1212 (v.expectErr != os.ErrNotExist && v.expectErr != err) { 1213 t.Errorf("expected %v, got %v, in %v", v.expectErr, err, i) 1214 t.Logf("%v, in %v", migrations, i) 1215 } 1216 if len(v.expectMigrations) > 0 { 1217 equalMigSeq(t, i, v.expectMigrations, migrations) 1218 } 1219 } 1220 } 1221 1222 func TestReadDown(t *testing.T) { 1223 m, _ := New("stub://", "stub://") 1224 m.sourceDrv.(*sStub.Stub).Migrations = sourceStubMigrations 1225 1226 tt := []struct { 1227 from int 1228 limit int // -1 means no limit 1229 expectErr error 1230 expectMigrations migrationSequence 1231 }{ 1232 {from: -1, limit: -1, expectErr: ErrNoChange}, 1233 {from: -1, limit: 0, expectErr: ErrNoChange}, 1234 {from: -1, limit: 1, expectErr: os.ErrNotExist}, 1235 {from: -1, limit: 2, expectErr: os.ErrNotExist}, 1236 1237 {from: 0, limit: -1, expectErr: os.ErrNotExist}, 1238 {from: 0, limit: 0, expectErr: os.ErrNotExist}, 1239 {from: 0, limit: 1, expectErr: os.ErrNotExist}, 1240 {from: 0, limit: 2, expectErr: os.ErrNotExist}, 1241 1242 {from: 1, limit: -1, expectErr: nil, expectMigrations: newMigSeq(M(1, -1))}, 1243 {from: 1, limit: 0, expectErr: ErrNoChange}, 1244 {from: 1, limit: 1, expectErr: nil, expectMigrations: newMigSeq(M(1, -1))}, 1245 {from: 1, limit: 2, expectErr: ErrShortLimit{1}, expectMigrations: newMigSeq(M(1, -1))}, 1246 1247 {from: 2, limit: -1, expectErr: os.ErrNotExist}, 1248 {from: 2, limit: 0, expectErr: os.ErrNotExist}, 1249 {from: 2, limit: 1, expectErr: os.ErrNotExist}, 1250 {from: 2, limit: 2, expectErr: os.ErrNotExist}, 1251 1252 {from: 3, limit: -1, expectErr: nil, expectMigrations: newMigSeq(M(3, 1), M(1, -1))}, 1253 {from: 3, limit: 0, expectErr: ErrNoChange}, 1254 {from: 3, limit: 1, expectErr: nil, expectMigrations: newMigSeq(M(3, 1))}, 1255 {from: 3, limit: 2, expectErr: nil, expectMigrations: newMigSeq(M(3, 1), M(1, -1))}, 1256 1257 {from: 4, limit: -1, expectErr: nil, expectMigrations: newMigSeq(M(4, 3), M(3, 1), M(1, -1))}, 1258 {from: 4, limit: 0, expectErr: ErrNoChange}, 1259 {from: 4, limit: 1, expectErr: nil, expectMigrations: newMigSeq(M(4, 3))}, 1260 {from: 4, limit: 2, expectErr: nil, expectMigrations: newMigSeq(M(4, 3), M(3, 1))}, 1261 1262 {from: 5, limit: -1, expectErr: nil, expectMigrations: newMigSeq(M(5, 4), M(4, 3), M(3, 1), M(1, -1))}, 1263 {from: 5, limit: 0, expectErr: ErrNoChange}, 1264 {from: 5, limit: 1, expectErr: nil, expectMigrations: newMigSeq(M(5, 4))}, 1265 {from: 5, limit: 2, expectErr: nil, expectMigrations: newMigSeq(M(5, 4), M(4, 3))}, 1266 1267 {from: 6, limit: -1, expectErr: os.ErrNotExist}, 1268 {from: 6, limit: 0, expectErr: os.ErrNotExist}, 1269 {from: 6, limit: 1, expectErr: os.ErrNotExist}, 1270 {from: 6, limit: 2, expectErr: os.ErrNotExist}, 1271 1272 {from: 7, limit: -1, expectErr: nil, expectMigrations: newMigSeq(M(7, 5), M(5, 4), M(4, 3), M(3, 1), M(1, -1))}, 1273 {from: 7, limit: 0, expectErr: ErrNoChange}, 1274 {from: 7, limit: 1, expectErr: nil, expectMigrations: newMigSeq(M(7, 5))}, 1275 {from: 7, limit: 2, expectErr: nil, expectMigrations: newMigSeq(M(7, 5), M(5, 4))}, 1276 1277 {from: 8, limit: -1, expectErr: os.ErrNotExist}, 1278 {from: 8, limit: 0, expectErr: os.ErrNotExist}, 1279 {from: 8, limit: 1, expectErr: os.ErrNotExist}, 1280 {from: 8, limit: 2, expectErr: os.ErrNotExist}, 1281 } 1282 1283 for i, v := range tt { 1284 ret := make(chan interface{}) 1285 go m.readDown(v.from, v.limit, ret) 1286 migrations, err := migrationsFromChannel(ret) 1287 1288 if (v.expectErr == os.ErrNotExist && !os.IsNotExist(err)) || 1289 (v.expectErr != os.ErrNotExist && v.expectErr != err) { 1290 t.Errorf("expected %v, got %v, in %v", v.expectErr, err, i) 1291 t.Logf("%v, in %v", migrations, i) 1292 } 1293 if len(v.expectMigrations) > 0 { 1294 equalMigSeq(t, i, v.expectMigrations, migrations) 1295 } 1296 } 1297 } 1298 1299 func TestLock(t *testing.T) { 1300 m, _ := New("stub://", "stub://") 1301 if err := m.lock(); err != nil { 1302 t.Fatal(err) 1303 } 1304 1305 if err := m.lock(); err == nil { 1306 t.Fatal("should be locked already") 1307 } 1308 } 1309 1310 func migrationsFromChannel(ret chan interface{}) ([]*Migration, error) { 1311 slice := make([]*Migration, 0) 1312 for r := range ret { 1313 switch r.(type) { 1314 case error: 1315 return slice, r.(error) 1316 1317 case *Migration: 1318 slice = append(slice, r.(*Migration)) 1319 } 1320 } 1321 return slice, nil 1322 } 1323 1324 type migrationSequence []*Migration 1325 1326 func newMigSeq(migr ...*Migration) migrationSequence { 1327 return migr 1328 } 1329 1330 func (m *migrationSequence) add(migr ...*Migration) migrationSequence { 1331 *m = append(*m, migr...) 1332 return *m 1333 } 1334 1335 func (m *migrationSequence) bodySequence() []string { 1336 r := make([]string, 0) 1337 for _, v := range *m { 1338 if v.Body != nil { 1339 body, err := ioutil.ReadAll(v.Body) 1340 if err != nil { 1341 panic(err) // that should never happen 1342 } 1343 1344 // reset body reader 1345 // TODO: is there a better/nicer way? 1346 v.Body = ioutil.NopCloser(bytes.NewReader(body)) 1347 1348 r = append(r, string(body[:])) 1349 } else { 1350 r = append(r, "<empty>") 1351 } 1352 } 1353 return r 1354 } 1355 1356 // M is a convenience func to create a new *Migration 1357 func M(version uint, targetVersion ...int) *Migration { 1358 if len(targetVersion) > 1 { 1359 panic("only one targetVersion allowed") 1360 } 1361 ts := int(version) 1362 if len(targetVersion) == 1 { 1363 ts = targetVersion[0] 1364 } 1365 1366 m, _ := New("stub://", "stub://") 1367 m.sourceDrv.(*sStub.Stub).Migrations = sourceStubMigrations 1368 migr, err := m.newMigration(version, ts) 1369 if err != nil { 1370 panic(err) 1371 } 1372 return migr 1373 } 1374 1375 // mr is a convenience func to create a new *Migration from the raw database query 1376 func mr(value string) *Migration { 1377 return &Migration{ 1378 Body: ioutil.NopCloser(bytes.NewReader([]byte(value))), 1379 } 1380 } 1381 1382 func equalMigSeq(t *testing.T, i int, expected, got migrationSequence) { 1383 if len(expected) != len(got) { 1384 t.Errorf("expected migrations %v, got %v, in %v", expected, got, i) 1385 1386 } else { 1387 for ii := 0; ii < len(expected); ii++ { 1388 if expected[ii].Version != got[ii].Version { 1389 t.Errorf("expected version %v, got %v, in %v", expected[ii].Version, got[ii].Version, i) 1390 } 1391 1392 if expected[ii].TargetVersion != got[ii].TargetVersion { 1393 t.Errorf("expected targetVersion %v, got %v, in %v", expected[ii].TargetVersion, got[ii].TargetVersion, i) 1394 } 1395 } 1396 } 1397 } 1398 1399 func equalDbSeq(t *testing.T, i int, expected migrationSequence, got *dStub.Stub) { 1400 bs := expected.bodySequence() 1401 if !got.EqualSequence(bs) { 1402 t.Fatalf("\nexpected sequence %v,\ngot %v, in %v", bs, got.MigrationSequence, i) 1403 } 1404 }