forked from raystack/optimus
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add bq model resource on job validate (#259)
* feat: add bq model exist capability * feat: add unit test on BQ Model part
- Loading branch information
1 parent
02f5b76
commit 9f4e285
Showing
6 changed files
with
263 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package bigquery | ||
|
||
import ( | ||
"context" | ||
|
||
"cloud.google.com/go/bigquery" | ||
|
||
"github.com/goto/optimus/core/resource" | ||
"github.com/goto/optimus/internal/errors" | ||
) | ||
|
||
const EntityModel = "resource_model" | ||
|
||
// BqModel is BigQuery Model | ||
type BqModel interface { | ||
Metadata(ctx context.Context) (mm *bigquery.ModelMetadata, err error) | ||
} | ||
|
||
type ModelHandle struct { | ||
bqModel BqModel | ||
} | ||
|
||
func (ModelHandle) Create(_ context.Context, _ *resource.Resource) error { | ||
return errors.FailedPrecondition(EntityModel, "create is not supported") | ||
} | ||
|
||
func (ModelHandle) Update(_ context.Context, _ *resource.Resource) error { | ||
return errors.FailedPrecondition(EntityModel, "update is not supported") | ||
} | ||
|
||
func (r ModelHandle) Exists(ctx context.Context) bool { | ||
if r.bqModel == nil { | ||
return false | ||
} | ||
_, err := r.bqModel.Metadata(ctx) | ||
return err == nil | ||
} | ||
|
||
func NewModelHandle(bq BqModel) *ModelHandle { | ||
return &ModelHandle{bqModel: bq} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
package bigquery_test | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"testing" | ||
|
||
"cloud.google.com/go/bigquery" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/mock" | ||
|
||
"github.com/goto/optimus/core/resource" | ||
"github.com/goto/optimus/core/tenant" | ||
storebigquery "github.com/goto/optimus/ext/store/bigquery" | ||
) | ||
|
||
func TestModelHandle(t *testing.T) { | ||
ctx := context.Background() | ||
bqStore := resource.Bigquery | ||
tnnt, _ := tenant.NewTenant("proj", "ns") | ||
metadata := resource.Metadata{ | ||
Version: 1, | ||
Description: "resource description", | ||
Labels: map[string]string{"owner": "optimus"}, | ||
} | ||
spec := map[string]any{"description": []string{"a", "b"}} | ||
res, err := resource.NewResource("proj.dataset.view1", storebigquery.KindView, bqStore, tnnt, &metadata, spec) | ||
assert.Nil(t, err) | ||
|
||
t.Run("Create", func(t *testing.T) { | ||
t.Run("return error, not supported", func(t *testing.T) { | ||
v := NewMockBigQueryModel(t) | ||
defer v.AssertExpectations(t) | ||
handle := storebigquery.NewModelHandle(v) | ||
|
||
err := handle.Create(ctx, res) | ||
assert.EqualError(t, err, "failed precondition for entity resource_model: create is not supported") | ||
}) | ||
}) | ||
|
||
t.Run("Update", func(t *testing.T) { | ||
t.Run("return error, not supported", func(t *testing.T) { | ||
v := NewMockBigQueryModel(t) | ||
defer v.AssertExpectations(t) | ||
handle := storebigquery.NewModelHandle(v) | ||
|
||
err := handle.Update(ctx, res) | ||
assert.EqualError(t, err, "failed precondition for entity resource_model: update is not supported") | ||
}) | ||
}) | ||
|
||
t.Run("Exists", func(t *testing.T) { | ||
t.Run("return true, model exists", func(t *testing.T) { | ||
v := NewMockBigQueryModel(t) | ||
defer v.AssertExpectations(t) | ||
handle := storebigquery.NewModelHandle(v) | ||
|
||
v.On("Metadata", ctx).Return(nil, nil) | ||
|
||
actual := handle.Exists(ctx) | ||
assert.True(t, actual) | ||
}) | ||
|
||
t.Run("return false, model not exists", func(t *testing.T) { | ||
v := NewMockBigQueryModel(t) | ||
defer v.AssertExpectations(t) | ||
handle := storebigquery.NewModelHandle(v) | ||
|
||
v.On("Metadata", ctx).Return(nil, errors.New("some error")) | ||
|
||
actual := handle.Exists(ctx) | ||
assert.False(t, actual) | ||
}) | ||
|
||
t.Run("return false, connection error", func(t *testing.T) { | ||
v := NewMockBigQueryModel(t) | ||
defer v.AssertExpectations(t) | ||
handle := storebigquery.NewModelHandle(v) | ||
|
||
v.On("Metadata", ctx).Return(nil, context.DeadlineExceeded) | ||
|
||
actual := handle.Exists(ctx) | ||
assert.False(t, actual) | ||
}) | ||
|
||
t.Run("return false, BqModel is nil", func(t *testing.T) { | ||
v := NewMockBigQueryModel(t) | ||
defer v.AssertExpectations(t) | ||
handle := storebigquery.NewModelHandle(nil) | ||
|
||
actual := handle.Exists(ctx) | ||
assert.False(t, actual) | ||
}) | ||
}) | ||
} | ||
|
||
type mockBigQueryModel struct { | ||
mock.Mock | ||
} | ||
|
||
func (_m *mockBigQueryModel) Metadata(ctx context.Context) (*bigquery.ModelMetadata, error) { | ||
ret := _m.Called(ctx) | ||
|
||
if len(ret) == 0 { | ||
panic("no return value specified for Metadata") | ||
} | ||
|
||
var r0 *bigquery.ModelMetadata | ||
var r1 error | ||
if rf, ok := ret.Get(0).(func(context.Context) (*bigquery.ModelMetadata, error)); ok { | ||
return rf(ctx) | ||
} | ||
if rf, ok := ret.Get(0).(func(context.Context) *bigquery.ModelMetadata); ok { | ||
r0 = rf(ctx) | ||
} else { | ||
if ret.Get(0) != nil { | ||
r0 = ret.Get(0).(*bigquery.ModelMetadata) | ||
} | ||
} | ||
|
||
if rf, ok := ret.Get(1).(func(context.Context) error); ok { | ||
r1 = rf(ctx) | ||
} else { | ||
r1 = ret.Error(1) | ||
} | ||
|
||
return r0, r1 | ||
} | ||
|
||
func NewMockBigQueryModel(t interface { | ||
mock.TestingT | ||
Cleanup(func()) | ||
}, | ||
) *mockBigQueryModel { | ||
mock := &mockBigQueryModel{} | ||
mock.Mock.Test(t) | ||
|
||
t.Cleanup(func() { mock.AssertExpectations(t) }) | ||
|
||
return mock | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters