diff --git a/cli/pkg/migrate/apply.go b/cli/pkg/migrate/apply.go index 7fe1c3c5635..2421a832664 100644 --- a/cli/pkg/migrate/apply.go +++ b/cli/pkg/migrate/apply.go @@ -3,6 +3,7 @@ package migrate import ( "github.com/hasura/graphql-engine/cli/v2" "github.com/hasura/graphql-engine/cli/v2/commands" + "github.com/hasura/graphql-engine/cli/v2/internal/errors" ) type projectMigrationsApplier struct { @@ -48,13 +49,14 @@ func ApplyVersion(version string, direction MigrationDirection) ProjectMigration } func (p *projectMigrationsApplier) apply(opts ...ProjectMigrationApplierOption) ([]ApplyResult, error) { + var op errors.Op = "migrate.projectMigrationsApplier.apply" for _, opt := range opts { opt(p) } var results []ApplyResult resultChan, err := p.opts.Apply() if err != nil { - return nil, err + return nil, errors.E(op, err) } for v := range resultChan { results = append(results, ApplyResult(v)) diff --git a/cli/pkg/migrate/project_migrate.go b/cli/pkg/migrate/project_migrate.go index c6e91440c1a..9153441af21 100644 --- a/cli/pkg/migrate/project_migrate.go +++ b/cli/pkg/migrate/project_migrate.go @@ -5,6 +5,7 @@ import ( "io" "github.com/hasura/graphql-engine/cli/v2/commands" + "github.com/hasura/graphql-engine/cli/v2/internal/errors" "github.com/hasura/graphql-engine/cli/v2" "github.com/spf13/viper" @@ -15,29 +16,45 @@ type ProjectMigrate struct { } func (p *ProjectMigrate) status(opts ...ProjectMigrationStatusOption) ([]databaseMigration, error) { + var op errors.Op = "migrate.ProjectMigrate.status" lister := newProjectMigrationsStatus(p.ec) if len(opts) == 0 { opts = append(opts, StatusAllDatabases()) } - return lister.Status(opts...) + dms, err := lister.Status(opts...) + if err != nil { + return nil, errors.E(op, err) + } + return dms, nil } func (p *ProjectMigrate) StatusJSON(opts ...ProjectMigrationStatusOption) (io.Reader, error) { + var op errors.Op = "migrate.ProjectMigrate.StatusJSON" lister := newProjectMigrationsStatus(p.ec) if len(opts) == 0 { opts = append(opts, StatusAllDatabases()) } - return lister.StatusJSON(opts...) + r, err := lister.StatusJSON(opts...) + if err != nil { + return nil, errors.E(op, err) + } + return r, nil } type ApplyResult commands.MigrateApplyResult func (p *ProjectMigrate) Apply(opts ...ProjectMigrationApplierOption) ([]ApplyResult, error) { + var op errors.Op = "migrate.ProjectMigrate.Apply" applier := newProjectMigrationsApplier(p.ec) - return applier.apply(opts...) + r, err := applier.apply(opts...) + if err != nil { + return nil, errors.E(op, err) + } + return r, nil } func NewProjectMigrate(projectDirectory string, opts ...ProjectMigrateOption) (*ProjectMigrate, error) { + var op errors.Op = "migrate.NewProjectMigrate" p := &ProjectMigrate{} ec := cli.NewExecutionContext() ec.ExecutionDirectory = projectDirectory @@ -47,17 +64,17 @@ func NewProjectMigrate(projectDirectory string, opts ...ProjectMigrateOption) (* ec.Stderr = io.Discard ec.Stdout = io.Discard if err := ec.Prepare(); err != nil { - return nil, err + return nil, errors.E(op, err) } p.ec = ec for _, opt := range opts { opt(p) } if err := ec.Validate(); err != nil { - return nil, err + return nil, errors.E(op, err) } if ec.Config.Version <= cli.V1 { - return nil, fmt.Errorf("config %v is not supported", ec.Config.Version) + return nil, errors.E(op, fmt.Errorf("config %v is not supported", ec.Config.Version)) } return p, nil } diff --git a/cli/pkg/migrate/project_migrate_test.go b/cli/pkg/migrate/project_migrate_test.go index a10f0972a5e..116d5dcbfaf 100644 --- a/cli/pkg/migrate/project_migrate_test.go +++ b/cli/pkg/migrate/project_migrate_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/hasura/graphql-engine/cli/v2/internal/errors" "github.com/hasura/graphql-engine/cli/v2/internal/testutil" ) @@ -34,11 +35,12 @@ func TestProjectMigrate_ApplyConfig_v3(t *testing.T) { opts []ProjectMigrationApplierOption } tests := []struct { - name string - fields fields - args args - want []ApplyResult - wantErr bool + name string + fields fields + args args + want []ApplyResult + wantErr bool + assertErr require.ErrorAssertionFunc }{ { "can apply migrations in config v3 project", @@ -62,6 +64,7 @@ func TestProjectMigrate_ApplyConfig_v3(t *testing.T) { }, }, false, + require.NoError, }, { "can apply a version in config v3 project", @@ -80,6 +83,7 @@ func TestProjectMigrate_ApplyConfig_v3(t *testing.T) { }, }, false, + require.NoError, }, { "can apply a version in config v3 project", @@ -98,6 +102,7 @@ func TestProjectMigrate_ApplyConfig_v3(t *testing.T) { }, }, false, + require.NoError, }, } for _, tt := range tests { @@ -105,12 +110,12 @@ func TestProjectMigrate_ApplyConfig_v3(t *testing.T) { p, err := NewProjectMigrate(tt.fields.projectDirectory, WithAdminSecret(testutil.TestAdminSecret), WithEndpoint(tt.fields.endpointString)) require.NoError(t, err) got, err := p.Apply(tt.args.opts...) + tt.assertErr(t, err) if tt.wantErr { - require.Error(t, err) - } else { - require.NoError(t, err) - require.Equal(t, tt.want, got) + return } + require.NoError(t, err) + require.Equal(t, tt.want, got) }) } } @@ -128,11 +133,12 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) { opts []ProjectMigrationApplierOption } tests := []struct { - name string - fields fields - args args - want []ApplyResult - wantErr bool + name string + fields fields + args args + want []ApplyResult + wantErr bool + assertErr require.ErrorAssertionFunc }{ { "can apply migrations in config v2 project", @@ -150,6 +156,7 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) { }, }, false, + require.NoError, }, { "can apply down migration on a version in config v2 project", @@ -167,6 +174,7 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) { }, }, false, + require.NoError, }, { "throws error when trying to do a down migration which is not applied", @@ -184,6 +192,7 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) { }, }, false, + require.NoError, }, { "can apply up migrations of a version on a config v2 project", @@ -201,6 +210,7 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) { }, }, false, + require.NoError, }, } for _, tt := range tests { @@ -208,20 +218,19 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) { p, err := NewProjectMigrate(tt.fields.projectDirectory, WithAdminSecret(testutil.TestAdminSecret), WithEndpoint(tt.fields.endpointString)) require.NoError(t, err) got, err := p.Apply(tt.args.opts...) + tt.assertErr(t, err) if tt.wantErr { - require.Error(t, err) - } else { - require.NoError(t, err) - for idx, want := range tt.want { - if idx >= len(got) { - t.Errorf("expected to got to have equal number of elements: want %v got %v", len(tt.want), len(got)) - } - if len(want.Message) > 0 { - assert.Equal(t, want.Message, got[idx].Message) - } - if want.Error != nil { - assert.Equal(t, want.Error.Error(), got[idx].Error.Error()) - } + return + } + for idx, want := range tt.want { + if idx >= len(got) { + t.Errorf("expected to got to have equal number of elements: want %v got %v", len(tt.want), len(got)) + } + if len(want.Message) > 0 { + assert.Equal(t, want.Message, got[idx].Message) + } + if want.Error != nil { + assert.Equal(t, want.Error.Error(), got[idx].Error.Error()) } } }) @@ -241,12 +250,13 @@ func TestProjectMigrate_Status_ConfigV2(t *testing.T) { opts []ProjectMigrationStatusOption } tests := []struct { - name string - fields fields - args args - want string - wantErr bool - before func(t *testing.T, p *ProjectMigrate) + name string + fields fields + args args + want string + wantErr bool + assertErr require.ErrorAssertionFunc + before func(t *testing.T, p *ProjectMigrate) }{ { "can get status of migrations", @@ -296,6 +306,7 @@ func TestProjectMigrate_Status_ConfigV2(t *testing.T) { } ]`, false, + require.NoError, func(t *testing.T, p *ProjectMigrate) {}, }, { @@ -346,6 +357,7 @@ func TestProjectMigrate_Status_ConfigV2(t *testing.T) { } ]`, false, + require.NoError, func(t *testing.T, p *ProjectMigrate) { _, err := p.Apply(ApplyOnAllDatabases()) assert.NoError(t, err) @@ -360,8 +372,9 @@ func TestProjectMigrate_Status_ConfigV2(t *testing.T) { require.NoError(t, err) tt.before(t, applier) got, err := p.status(tt.args.opts...) + tt.assertErr(t, err) if tt.wantErr { - require.Error(t, err) + return } require.NoError(t, err) gotJSON, err := json.Marshal(got) @@ -403,6 +416,7 @@ func TestProjectMigrate_Status_ConfigV3(t *testing.T) { args args want string wantErr bool + assertErr require.ErrorAssertionFunc testSetup func() (hgeEndpoint string, teardown func()) before func(t *testing.T, p *ProjectMigrate) }{ @@ -486,6 +500,7 @@ func TestProjectMigrate_Status_ConfigV3(t *testing.T) { } ]`, false, + require.NoError, func() (string, func()) { return hgeEndpoint, func() {} }, func(t *testing.T, p *ProjectMigrate) {}, }, @@ -570,6 +585,7 @@ func TestProjectMigrate_Status_ConfigV3(t *testing.T) { } ]`, false, + require.NoError, func() (string, func()) { return hgeEndpoint, func() {} }, func(t *testing.T, p *ProjectMigrate) { _, err := p.Apply(ApplyOnAllDatabases()) @@ -587,6 +603,11 @@ func TestProjectMigrate_Status_ConfigV3(t *testing.T) { }, ``, true, + func(tt require.TestingT, err error, i ...interface{}) { + require.IsType(t, &errors.Error{}, err) + e := err.(*errors.Error) + require.Equal(t, errors.Op("migrate.ProjectMigrate.status"), e.Op) + }, func() (string, func()) { port, teardown := testutil.StartHasuraWithMetadataDatabase(t, testutil.HasuraDockerImage) return fmt.Sprintf("http://%s:%s", testutil.Hostname, port), teardown @@ -607,19 +628,19 @@ func TestProjectMigrate_Status_ConfigV3(t *testing.T) { require.NoError(t, err) tt.before(t, applier) got, err := p.status(tt.args.opts...) + tt.assertErr(t, err) if tt.wantErr { - require.Error(t, err) - } else { - gotJSON, err := json.Marshal(got) - require.NoError(t, err) - require.JSONEq(t, tt.want, string(gotJSON)) - - statusJson, err := p.StatusJSON(tt.args.opts...) - require.NoError(t, err) - statusJsonb, err := ioutil.ReadAll(statusJson) - require.NoError(t, err) - require.JSONEq(t, tt.want, string(statusJsonb)) + return } + gotJSON, err := json.Marshal(got) + require.NoError(t, err) + require.JSONEq(t, tt.want, string(gotJSON)) + + statusJson, err := p.StatusJSON(tt.args.opts...) + require.NoError(t, err) + statusJsonb, err := ioutil.ReadAll(statusJson) + require.NoError(t, err) + require.JSONEq(t, tt.want, string(statusJsonb)) }) } } @@ -643,9 +664,11 @@ func TestProjectMigrate_SkipExecution_Configv3(t *testing.T) { opts []ProjectMigrationApplierOption } tests := []struct { - name string - args args - want string + name string + args args + want string + wantErr bool + assertErr require.ErrorAssertionFunc }{ { "mark migration as unapplied", @@ -692,6 +715,8 @@ func TestProjectMigrate_SkipExecution_Configv3(t *testing.T) { } ] `, + false, + require.NoError, }, { "mark migration as applied", @@ -738,6 +763,8 @@ func TestProjectMigrate_SkipExecution_Configv3(t *testing.T) { } ] `, + false, + require.NoError, }, } @@ -749,7 +776,10 @@ func TestProjectMigrate_SkipExecution_Configv3(t *testing.T) { require.NoError(t, err) status, err := p.StatusJSON() - assert.NoError(t, err) + tt.assertErr(t, err) + if tt.wantErr { + return + } statusJsonb, err := ioutil.ReadAll(status) assert.NoError(t, err) @@ -772,9 +802,11 @@ func TestProjectMigrate_SkipExecution_Configv2(t *testing.T) { opts []ProjectMigrationApplierOption } tests := []struct { - name string - args args - want string + name string + args args + want string + wantErr bool + assertErr require.ErrorAssertionFunc }{ { "mark migration as unapplied", @@ -821,6 +853,8 @@ func TestProjectMigrate_SkipExecution_Configv2(t *testing.T) { } ] `, + false, + require.NoError, }, { "mark migration as applied", @@ -867,6 +901,8 @@ func TestProjectMigrate_SkipExecution_Configv2(t *testing.T) { } ] `, + false, + require.NoError, }, } @@ -878,7 +914,10 @@ func TestProjectMigrate_SkipExecution_Configv2(t *testing.T) { require.NoError(t, err) status, err := p1.StatusJSON() - assert.NoError(t, err) + tt.assertErr(t, err) + if tt.wantErr { + return + } statusJsonb, err := ioutil.ReadAll(status) assert.NoError(t, err) diff --git a/cli/pkg/migrate/status.go b/cli/pkg/migrate/status.go index 08b54f56e05..d8ad2a5ac16 100644 --- a/cli/pkg/migrate/status.go +++ b/cli/pkg/migrate/status.go @@ -8,6 +8,7 @@ import ( "github.com/hasura/graphql-engine/cli/v2" "github.com/hasura/graphql-engine/cli/v2/commands" + "github.com/hasura/graphql-engine/cli/v2/internal/errors" "github.com/hasura/graphql-engine/cli/v2/internal/metadatautil" "github.com/hasura/graphql-engine/cli/v2/migrate" ) @@ -23,6 +24,7 @@ type projectMigrationsStatus struct { } func (p *projectMigrationsStatus) Status(opts ...ProjectMigrationStatusOption) ([]databaseMigration, error) { + var op errors.Op = "migrate.projectMigrationsStatus.Status" var migrateStatus []databaseMigration for _, opt := range opts { opt(p) @@ -31,7 +33,7 @@ func (p *projectMigrationsStatus) Status(opts ...ProjectMigrationStatusOption) ( metadataOps := cli.GetCommonMetadataOps(p.ec) sources, err := metadatautil.GetSourcesAndKindStrict(metadataOps.ExportMetadata) if err != nil { - return nil, err + return nil, errors.E(op, err) } for _, source := range sources { opts := commands.MigrateStatusOptions{ @@ -43,7 +45,7 @@ func (p *projectMigrationsStatus) Status(opts ...ProjectMigrationStatusOption) ( } status, err := opts.RunOnSource() if err != nil { - return nil, err + return nil, errors.E(op, err) } migrateStatus = append( migrateStatus, @@ -58,13 +60,14 @@ func (p *projectMigrationsStatus) Status(opts ...ProjectMigrationStatusOption) ( } func (p *projectMigrationsStatus) StatusJSON(opts ...ProjectMigrationStatusOption) (io.Reader, error) { + var op errors.Op = "migrate.projectMigrationsStatus.StatusJSON" d, err := p.Status(opts...) b := new(bytes.Buffer) if err != nil { - return nil, err + return nil, errors.E(op, err) } if err := json.NewEncoder(b).Encode(d); err != nil { - return nil, fmt.Errorf("error encoding migration status as json: %w", err) + return nil, errors.E(op, fmt.Errorf("error encoding migration status as json: %w", err)) } return b, nil }