diff --git a/.golangci.yml b/.golangci.yml index f95b3f3..c801c3c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -49,7 +49,7 @@ linters: - asciicheck - bidichk - bodyclose - # - containedctx # TODO enable + - containedctx - contextcheck - copyloopvar - decorder diff --git a/destination/destination_integration_test.go b/destination/destination_integration_test.go index fa4a2b9..05af47f 100644 --- a/destination/destination_integration_test.go +++ b/destination/destination_integration_test.go @@ -27,8 +27,6 @@ import ( ) func TestDestination_OpenSuccess(t *testing.T) { - t.Parallel() - is := is.New(t) destination := NewDestination() @@ -47,8 +45,6 @@ func TestDestination_OpenSuccess(t *testing.T) { } func TestDestination_OpenFail(t *testing.T) { - t.Parallel() - is := is.New(t) destination := NewDestination() @@ -67,8 +63,6 @@ func TestDestination_OpenFail(t *testing.T) { } func TestDestination_WriteOneMessage(t *testing.T) { - t.Parallel() - is := is.New(t) subject := "foo_destination_write_one_pubsub" @@ -117,8 +111,6 @@ func TestDestination_WriteOneMessage(t *testing.T) { } func TestDestination_WriteManyMessages(t *testing.T) { - t.Parallel() - is := is.New(t) subject := "foo_destination_write_many_pubsub" diff --git a/destination/destination_test.go b/destination/destination_test.go index b395aa5..3776c4b 100644 --- a/destination/destination_test.go +++ b/destination/destination_test.go @@ -17,47 +17,33 @@ package destination import ( "context" "testing" + + "github.com/conduitio/conduit-commons/config" ) func TestDestination_Configure(t *testing.T) { - t.Parallel() - - type args struct { - ctx context.Context - cfg map[string]string - } - tests := []struct { name string - args args + cfg config.Config wantErr bool }{ { name: "success, correct config", - args: args{ - ctx: context.Background(), - cfg: map[string]string{ - ConfigUrls: "nats://127.0.0.1:4222", - ConfigSubject: "foo", - }, + cfg: config.Config{ + ConfigUrls: "nats://127.0.0.1:4222", + ConfigSubject: "foo", }, wantErr: false, }, { - name: "fail, empty config", - args: args{ - ctx: context.Background(), - cfg: map[string]string{}, - }, + name: "fail, empty config", + cfg: config.Config{}, wantErr: true, }, { name: "fail, invalid config", - args: args{ - ctx: context.Background(), - cfg: map[string]string{ - ConfigUrls: "nats://127.0.0.1:4222", - }, + cfg: config.Config{ + ConfigUrls: "nats://127.0.0.1:4222", }, wantErr: true, }, @@ -65,10 +51,8 @@ func TestDestination_Configure(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - t.Parallel() - s := &Destination{} - if err := s.Configure(tt.args.ctx, tt.args.cfg); (err != nil) != tt.wantErr { + if err := s.Configure(context.Background(), tt.cfg); (err != nil) != tt.wantErr { t.Errorf("Source.Configure() error = %v, wantErr %v", err, tt.wantErr) } }) diff --git a/source/pubsub/iterator_test.go b/source/pubsub/iterator_test.go index 87c0b1b..1f547ea 100644 --- a/source/pubsub/iterator_test.go +++ b/source/pubsub/iterator_test.go @@ -26,8 +26,6 @@ import ( ) func TestPubSubIterator_HasNext(t *testing.T) { - t.Parallel() - type fields struct { messages chan *nats.Msg } @@ -63,8 +61,6 @@ func TestPubSubIterator_HasNext(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - t.Parallel() - i := &Iterator{ messages: tt.fields.messages, } @@ -83,8 +79,6 @@ func TestPubSubIterator_HasNext(t *testing.T) { } func TestPubSubIterator_Next(t *testing.T) { - t.Parallel() - type fields struct { messages chan *nats.Msg } @@ -139,8 +133,6 @@ func TestPubSubIterator_Next(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - t.Parallel() - i := &Iterator{ messages: tt.fields.messages, } @@ -188,8 +180,6 @@ func TestPubSubIterator_Next(t *testing.T) { } func TestPubSubIterator_messageToRecord(t *testing.T) { - t.Parallel() - type args struct { msg *nats.Msg } @@ -235,8 +225,6 @@ func TestPubSubIterator_messageToRecord(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - t.Parallel() - i := &Iterator{} got, err := i.messageToRecord(tt.args.msg) @@ -246,11 +234,8 @@ func TestPubSubIterator_messageToRecord(t *testing.T) { return } - // copy tt.want in order to avoid race conditions with t.Parallel - copyWant := tt.want - // we don't care about time - copyWant.Metadata = got.Metadata + tt.want.Metadata = got.Metadata // check if the position is a valid UUID _, err = uuid.FromBytes(got.Position) @@ -260,10 +245,10 @@ func TestPubSubIterator_messageToRecord(t *testing.T) { return } - copyWant.Position = got.Position + tt.want.Position = got.Position - if !reflect.DeepEqual(got, copyWant) { - t.Errorf("PubSubIterator.messageToRecord() = %v, want %v", got, copyWant) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("PubSubIterator.messageToRecord() = %v, want %v", got, tt.want) } }) } diff --git a/validator/validator.go b/validator/validator.go deleted file mode 100644 index 8eb29a3..0000000 --- a/validator/validator.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright © 2022 Meroxa, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validator - -import ( - "errors" - "fmt" - "reflect" - - "github.com/go-playground/validator/v10" - "go.uber.org/multierr" -) - -// keyStructTag is a tag which contains a field's key. -const keyStructTag = "key" - -// Validate validates a struct. -func Validate(data any) error { - var err error - - validate := validator.New() - - validationErr := validate.Struct(data) - if validationErr != nil { - if errors.Is(validationErr, (*validator.InvalidValidationError)(nil)) { - return fmt.Errorf("validate struct: %w", validationErr) - } - - for _, e := range validationErr.(validator.ValidationErrors) { - fieldName := getFieldKey(data, e.StructField()) - - switch e.Tag() { - case "required": - err = multierr.Append(err, requiredErr(fieldName)) - case "required_with": - err = multierr.Append(err, requiredWithErr(fieldName, e.Param())) - case "min": - err = multierr.Append(err, minErr(fieldName, e.Param())) - case "file": - err = multierr.Append(err, fileErr(fieldName)) - case "url": - err = multierr.Append(err, urlErr(fieldName)) - } - } - } - - return err -} - -// requiredErr returns the formatted required error. -func requiredErr(name string) error { - return fmt.Errorf("%q value must be set", name) -} - -// requiredWithErr returns the formatted required_with error. -func requiredWithErr(name, with string) error { - return fmt.Errorf("%q value is required if %q is provided", name, with) -} - -// minErr returns the formatted min error. -func minErr(name, val string) error { - return fmt.Errorf("%q value must be greater than or equal to %s", name, val) -} - -// fileErr returns the formatted file error. -func fileErr(name string) error { - return fmt.Errorf("%q value must be a valid file path and exists", name) -} - -// urlErr returns the formatted url error. -func urlErr(name string) error { - return fmt.Errorf("%q value must be a valid url", name) -} - -// getFieldKey returns a key ("key" tag) for the provided fieldName. If the "key" tag is not present, -// the function will return a fieldName. -func getFieldKey(data any, fieldName string) string { - // if the data is not pointer or it's nil, return a fieldName. - val := reflect.ValueOf(data) - if val.Kind() != reflect.Ptr || val.IsNil() { - return fieldName - } - - structField, ok := reflect.TypeOf(data).Elem().FieldByName(fieldName) - if !ok { - return fieldName - } - - fieldKey := structField.Tag.Get(keyStructTag) - if fieldKey == "" { - return fieldName - } - - return fieldKey -} diff --git a/validator/validator_test.go b/validator/validator_test.go deleted file mode 100644 index d269cd4..0000000 --- a/validator/validator_test.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright © 2022 Meroxa, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validator - -import "testing" - -func Test_getFieldKey(t *testing.T) { - t.Parallel() - - type args struct { - data any - fieldName string - } - tests := []struct { - name string - args args - want string - }{ - { - name: "struct with key tag", - args: args{ - data: &struct { - Name string `key:"super_name"` - }{ - Name: "void", - }, - fieldName: "Name", - }, - want: "super_name", - }, - { - name: "struct without any key tags", - args: args{ - data: &struct { - Name string - }{ - Name: "void", - }, - fieldName: "Name", - }, - want: "Name", - }, - { - name: "struct with empty key tag", - args: args{ - data: &struct { - Name string `key:""` - }{ - Name: "void", - }, - fieldName: "Name", - }, - want: "Name", - }, - { - name: "data is not a pointer, should return a field name", - args: args{ - data: struct { - Name string `key:"super_name"` - }{ - Name: "void", - }, - fieldName: "Name", - }, - want: "Name", - }, - { - name: "data is nil, should return a field name", - args: args{ - data: nil, - fieldName: "Name", - }, - want: "Name", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - - if got := getFieldKey(tt.args.data, tt.args.fieldName); got != tt.want { - t.Errorf("getFieldKey() = %v, want %v", got, tt.want) - } - }) - } -}