migrate/driver/mongodb/example/mongodb_test.go

311 lines
8.7 KiB
Go

package example
import (
"testing"
"github.com/mattes/migrate/file"
"github.com/mattes/migrate/migrate/direction"
"github.com/mattes/migrate/driver"
"github.com/mattes/migrate/driver/mongodb"
"github.com/mattes/migrate/driver/mongodb/gomethods"
pipep "github.com/mattes/migrate/pipe"
"os"
"reflect"
"time"
)
type ExpectedMigrationResult struct {
Organizations []Organization
Organizations_v2 []Organization_v2
Users []User
Errors []error
}
func RunMigrationAndAssertResult(
t *testing.T,
title string,
d *mongodb.Driver,
file file.File,
expected *ExpectedMigrationResult) {
actualOrganizations := []Organization{}
actualOrganizations_v2 := []Organization_v2{}
actualUsers := []User{}
var err error
var pipe chan interface{}
var errs []error
pipe = pipep.New()
go d.Migrate(file, pipe)
errs = pipep.ReadErrors(pipe)
session := d.Session
if len(expected.Organizations) > 0 {
err = session.DB(DB_NAME).C(ORGANIZATIONS_C).Find(nil).All(&actualOrganizations)
} else {
err = session.DB(DB_NAME).C(ORGANIZATIONS_C).Find(nil).All(&actualOrganizations_v2)
}
if err != nil {
t.Fatal("Failed to query Organizations collection")
}
err = session.DB(DB_NAME).C(USERS_C).Find(nil).All(&actualUsers)
if err != nil {
t.Fatal("Failed to query Users collection")
}
if !reflect.DeepEqual(expected.Errors, errs) {
t.Fatalf("Migration '%s': FAILED\nexpected errors %v\nbut got %v", title, expected.Errors, errs)
}
if !reflect.DeepEqual(expected.Organizations, actualOrganizations) {
t.Fatalf("Migration '%s': FAILED\nexpected organizations %v\nbut got %v", title, expected.Organizations, actualOrganizations)
}
if !reflect.DeepEqual(expected.Organizations_v2, actualOrganizations_v2) {
t.Fatalf("Migration '%s': FAILED\nexpected organizations v2 %v\nbut got %v", title, expected.Organizations_v2, actualOrganizations_v2)
}
if !reflect.DeepEqual(expected.Users, actualUsers) {
t.Fatalf("Migration '%s': FAILED\nexpected users %v\nbut got %v", title, expected.Users, actualUsers)
}
// t.Logf("Migration '%s': PASSED", title)
}
func TestMigrate(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Fatalf("Test failed on panic: %v", r)
}
}()
host := os.Getenv("MONGO_PORT_27017_TCP_ADDR")
port := os.Getenv("MONGO_PORT_27017_TCP_PORT")
driverUrl := "mongodb://" + host + ":" + port
d0 := driver.GetDriver("mongodb")
d, ok := d0.(*mongodb.Driver)
if !ok {
t.Fatal("MongoDbGoMethodsDriver has not registered")
}
if err := d.Initialize(driverUrl); err != nil {
t.Fatal(err)
}
// Reset DB
d.Session.DB(DB_NAME).C(mongodb.MIGRATE_C).DropCollection()
d.Session.DB(DB_NAME).C(ORGANIZATIONS_C).DropCollection()
d.Session.DB(DB_NAME).C(USERS_C).DropCollection()
date1, _ := time.Parse(SHORT_DATE_LAYOUT, "1994-Jul-05")
date2, _ := time.Parse(SHORT_DATE_LAYOUT, "1998-Sep-04")
date3, _ := time.Parse(SHORT_DATE_LAYOUT, "2008-Apr-28")
migrations := []struct {
name string
file file.File
expectedResult ExpectedMigrationResult
}{
{
name: "v0 -> v1",
file: file.File{
Path: "/foobar",
FileName: "001_foobar.up.gm",
Version: 1,
Name: "foobar",
Direction: direction.Up,
Content: []byte(`
V001_init_organizations_up
V001_init_users_up
`),
},
expectedResult: ExpectedMigrationResult{
Organizations: []Organization{
{Id: OrganizationIds[0], Name: "Amazon", Location: "Seattle", DateFounded: date1},
{Id: OrganizationIds[1], Name: "Google", Location: "Mountain View", DateFounded: date2},
{Id: OrganizationIds[2], Name: "JFrog", Location: "Santa Clara", DateFounded: date3},
},
Organizations_v2: []Organization_v2{},
Users: []User{
{Id: UserIds[0], Name: "Alex"},
{Id: UserIds[1], Name: "Beatrice"},
{Id: UserIds[2], Name: "Cleo"},
},
Errors: []error{},
},
},
{
name: "v1 -> v2",
file: file.File{
Path: "/foobar",
FileName: "002_foobar.up.gm",
Version: 2,
Name: "foobar",
Direction: direction.Up,
Content: []byte(`
V002_organizations_rename_location_field_to_headquarters_up
V002_change_user_cleo_to_cleopatra_up
`),
},
expectedResult: ExpectedMigrationResult{
Organizations: []Organization{},
Organizations_v2: []Organization_v2{
{Id: OrganizationIds[0], Name: "Amazon", Headquarters: "Seattle", DateFounded: date1},
{Id: OrganizationIds[1], Name: "Google", Headquarters: "Mountain View", DateFounded: date2},
{Id: OrganizationIds[2], Name: "JFrog", Headquarters: "Santa Clara", DateFounded: date3},
},
Users: []User{
{Id: UserIds[0], Name: "Alex"},
{Id: UserIds[1], Name: "Beatrice"},
{Id: UserIds[2], Name: "Cleopatra"},
},
Errors: []error{},
},
},
{
name: "v2 -> v1",
file: file.File{
Path: "/foobar",
FileName: "002_foobar.down.gm",
Version: 2,
Name: "foobar",
Direction: direction.Down,
Content: []byte(`
V002_change_user_cleo_to_cleopatra_down
V002_organizations_rename_location_field_to_headquarters_down
`),
},
expectedResult: ExpectedMigrationResult{
Organizations: []Organization{
{Id: OrganizationIds[0], Name: "Amazon", Location: "Seattle", DateFounded: date1},
{Id: OrganizationIds[1], Name: "Google", Location: "Mountain View", DateFounded: date2},
{Id: OrganizationIds[2], Name: "JFrog", Location: "Santa Clara", DateFounded: date3},
},
Organizations_v2: []Organization_v2{},
Users: []User{
{Id: UserIds[0], Name: "Alex"},
{Id: UserIds[1], Name: "Beatrice"},
{Id: UserIds[2], Name: "Cleo"},
},
Errors: []error{},
},
},
{
name: "v1 -> v0",
file: file.File{
Path: "/foobar",
FileName: "001_foobar.down.gm",
Version: 1,
Name: "foobar",
Direction: direction.Down,
Content: []byte(`
V001_init_users_down
V001_init_organizations_down
`),
},
expectedResult: ExpectedMigrationResult{
Organizations: []Organization{},
Organizations_v2: []Organization_v2{},
Users: []User{},
Errors: []error{},
},
},
{
name: "v0 -> v1: missing method aborts migration",
file: file.File{
Path: "/foobar",
FileName: "001_foobar.up.gm",
Version: 1,
Name: "foobar",
Direction: direction.Up,
Content: []byte(`
V001_init_organizations_up
V001_init_users_up
v001_non_existing_method_up
`),
},
expectedResult: ExpectedMigrationResult{
Organizations: []Organization{},
Organizations_v2: []Organization_v2{},
Users: []User{},
Errors: []error{gomethods.MethodNotFoundError("v001_non_existing_method_up")},
},
},
{
name: "v0 -> v1: not exported method aborts migration",
file: file.File{
Path: "/foobar",
FileName: "001_foobar.up.gm",
Version: 1,
Name: "foobar",
Direction: direction.Up,
Content: []byte(`
V001_init_organizations_up
v001_not_exported_method_up
V001_init_users_up
`),
},
expectedResult: ExpectedMigrationResult{
Organizations: []Organization{},
Organizations_v2: []Organization_v2{},
Users: []User{},
Errors: []error{gomethods.MethodNotFoundError("v001_not_exported_method_up")},
},
},
{
name: "v0 -> v1: wrong signature method aborts migration",
file: file.File{
Path: "/foobar",
FileName: "001_foobar.up.gm",
Version: 1,
Name: "foobar",
Direction: direction.Up,
Content: []byte(`
V001_init_organizations_up
V001_method_with_wrong_signature_up
V001_init_users_up
`),
},
expectedResult: ExpectedMigrationResult{
Organizations: []Organization{},
Organizations_v2: []Organization_v2{},
Users: []User{},
Errors: []error{gomethods.WrongMethodSignatureError("V001_method_with_wrong_signature_up")},
},
},
{
name: "v1 -> v0: wrong signature method aborts migration",
file: file.File{
Path: "/foobar",
FileName: "001_foobar.down.gm",
Version: 1,
Name: "foobar",
Direction: direction.Down,
Content: []byte(`
V001_init_users_down
V001_method_with_wrong_signature_down
V001_init_organizations_down
`),
},
expectedResult: ExpectedMigrationResult{
Organizations: []Organization{},
Organizations_v2: []Organization_v2{},
Users: []User{},
Errors: []error{gomethods.WrongMethodSignatureError("V001_method_with_wrong_signature_down")},
},
},
}
for _, m := range migrations {
RunMigrationAndAssertResult(t, m.name, d, m.file, &m.expectedResult)
}
if err := d.Close(); err != nil {
t.Fatal(err)
}
}