From 543c9ddda1f47b0ae008b2c04888d851ea35da41 Mon Sep 17 00:00:00 2001 From: Derek Duncan Date: Tue, 21 Feb 2023 10:20:48 +1100 Subject: [PATCH 1/5] Add tests to http_auth_hook --- http_auth_hook_test.go | 111 +++++++++++++++++++++++++++++++++++++++++ mock_roundtripper.go | 50 +++++++++++++++++++ transport_test.go | 26 ---------- 3 files changed, 161 insertions(+), 26 deletions(-) create mode 100644 mock_roundtripper.go diff --git a/http_auth_hook_test.go b/http_auth_hook_test.go index c98df96..cb66fc3 100644 --- a/http_auth_hook_test.go +++ b/http_auth_hook_test.go @@ -1,9 +1,14 @@ package mochicloudhooks import ( + "context" + "errors" + "net/http" "testing" + gomock "github.com/golang/mock/gomock" "github.com/mochi-co/mqtt/v2" + "github.com/rs/zerolog" "github.com/stretchr/testify/require" ) @@ -46,3 +51,109 @@ func TestProvides(t *testing.T) { }) } } + +func TestInit(t *testing.T) { + authHook := new(HTTPAuthHook) + authHook.Log = &zerolog.Logger{} + + tests := []struct { + name string + config any + expectError bool + }{ + { + name: "Success - Proper config", + config: HTTPAuthHookConfig{}, + expectError: false, + }, + { + name: "Success - nil config", + config: nil, + expectError: false, + }, + { + name: "Failure - improper config", + config: "", + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + err := authHook.Init(tt.config) + if tt.expectError { + require.Error(t, err) + } + + }) + } +} + +func TestOnConnectAuthenticate(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockRT := NewMockRoundTripper(ctrl) + + tests := []struct { + name string + config any + mocks func(ctx context.Context) + + expectPass bool + }{ + { + name: "Success - Proper config", + config: HTTPAuthHookConfig{ + RoundTripper: mockRT, + }, + expectPass: true, + mocks: func(ctx context.Context) { + mockRT.EXPECT().RoundTrip(gomock.Any()).Return(&http.Response{ + StatusCode: http.StatusOK, + }, nil) + + }, + }, + { + name: "Error - HTTP error", + config: HTTPAuthHookConfig{ + RoundTripper: mockRT, + }, + expectPass: false, + mocks: func(ctx context.Context) { + mockRT.EXPECT().RoundTrip(gomock.Any()).Return(nil, errors.New("Oh Crap")) + }, + }, + { + name: "Error - Non 2xx", + config: HTTPAuthHookConfig{ + RoundTripper: mockRT, + }, + expectPass: false, + mocks: func(ctx context.Context) { + mockRT.EXPECT().RoundTrip(gomock.Any()).Return(&http.Response{ + StatusCode: http.StatusTeapot, + }, nil) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + tt.mocks(ctx) + + authHook := new(HTTPAuthHook) + authHook.Log = &zerolog.Logger{} + authHook.Init(tt.config) + + success := authHook.OnACLCheck(&mqtt.Client{}, "/topic", false) + require.Equal(t, tt.expectPass, success) + // if tt.expectError { + // require.Error(t, err) + // } + + }) + } +} diff --git a/mock_roundtripper.go b/mock_roundtripper.go new file mode 100644 index 0000000..0f362f4 --- /dev/null +++ b/mock_roundtripper.go @@ -0,0 +1,50 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: net/http (interfaces: RoundTripper) + +// Package assetattributor is a generated GoMock package. +package mochicloudhooks + +import ( + http "net/http" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockRoundTripper is a mock of RoundTripper interface +type MockRoundTripper struct { + ctrl *gomock.Controller + recorder *MockRoundTripperMockRecorder +} + +// MockRoundTripperMockRecorder is the mock recorder for MockRoundTripper +type MockRoundTripperMockRecorder struct { + mock *MockRoundTripper +} + +// NewMockRoundTripper creates a new mock instance +func NewMockRoundTripper(ctrl *gomock.Controller) *MockRoundTripper { + mock := &MockRoundTripper{ctrl: ctrl} + mock.recorder = &MockRoundTripperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockRoundTripper) EXPECT() *MockRoundTripperMockRecorder { + return m.recorder +} + +// RoundTrip mocks base method +func (m *MockRoundTripper) RoundTrip(arg0 *http.Request) (*http.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RoundTrip", arg0) + ret0, _ := ret[0].(*http.Response) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RoundTrip indicates an expected call of RoundTrip +func (mr *MockRoundTripperMockRecorder) RoundTrip(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RoundTrip", reflect.TypeOf((*MockRoundTripper)(nil).RoundTrip), arg0) +} diff --git a/transport_test.go b/transport_test.go index 45e69f6..0defa79 100644 --- a/transport_test.go +++ b/transport_test.go @@ -8,32 +8,6 @@ import ( "github.com/stretchr/testify/require" ) -// func TestNewRoundTrip(t *testing.T) { - -// ctrl := gomock.NewController(t) -// defer ctrl.Finish() - -// tests := []struct { -// name string -// expectErr bool -// }{ -// { -// name: "Success - Golden Path", -// expectErr: false, -// }, -// } - -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { - -// req, _ := http.NewRequest("GET", "http://example.com", nil) -// nt := NewTransport(http.DefaultTransport) - -// require.Nil(t, err) -// }) -// } -// } - func TestRoundTrip(t *testing.T) { ctrl := gomock.NewController(t) From 8f8b49559643b87f1b0c322e168ae6ac3074366d Mon Sep 17 00:00:00 2001 From: Derek Duncan Date: Tue, 21 Feb 2023 10:25:17 +1100 Subject: [PATCH 2/5] Add TestOnConnectAuthenticate --- go.mod | 4 +-- go.sum | 8 ++--- http_auth_hook_test.go | 69 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 031eb3a..21052aa 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,8 @@ go 1.19 require ( github.com/golang/mock v1.6.0 - github.com/mochi-co/mqtt/v2 v2.2.1 + github.com/mochi-co/mqtt/v2 v2.2.2 + github.com/rs/zerolog v1.29.0 github.com/stretchr/testify v1.8.1 ) @@ -15,7 +16,6 @@ require ( github.com/mattn/go-isatty v0.0.14 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rs/xid v1.4.0 // indirect - github.com/rs/zerolog v1.28.0 // indirect golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0b63110..00d52b7 100644 --- a/go.sum +++ b/go.sum @@ -12,15 +12,15 @@ github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZb github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mochi-co/mqtt/v2 v2.2.1 h1:8GtksYNfkAB14SjZCwWAo2TFWQMKy38LGYVdE5bzDms= -github.com/mochi-co/mqtt/v2 v2.2.1/go.mod h1:KzMgWoPd31AtOSAsQKBjEWY0klMKmNlX1dO+bv+DeAo= +github.com/mochi-co/mqtt/v2 v2.2.2 h1:s1izxNecs0Zfmpo89g1EulKcIlxFzFbR6B2tgdVWVbg= +github.com/mochi-co/mqtt/v2 v2.2.2/go.mod h1:KzMgWoPd31AtOSAsQKBjEWY0klMKmNlX1dO+bv+DeAo= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= -github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= +github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= +github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= diff --git a/http_auth_hook_test.go b/http_auth_hook_test.go index cb66fc3..3b10cf7 100644 --- a/http_auth_hook_test.go +++ b/http_auth_hook_test.go @@ -8,6 +8,7 @@ import ( gomock "github.com/golang/mock/gomock" "github.com/mochi-co/mqtt/v2" + "github.com/mochi-co/mqtt/v2/packets" "github.com/rs/zerolog" "github.com/stretchr/testify/require" ) @@ -90,7 +91,7 @@ func TestInit(t *testing.T) { } } -func TestOnConnectAuthenticate(t *testing.T) { +func TestOnACLCheck(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockRT := NewMockRoundTripper(ctrl) @@ -150,10 +151,70 @@ func TestOnConnectAuthenticate(t *testing.T) { success := authHook.OnACLCheck(&mqtt.Client{}, "/topic", false) require.Equal(t, tt.expectPass, success) - // if tt.expectError { - // require.Error(t, err) - // } + }) + } +} + +func TestOnConnectAuthenticate(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockRT := NewMockRoundTripper(ctrl) + + tests := []struct { + name string + config any + mocks func(ctx context.Context) + + expectPass bool + }{ + { + name: "Success - Proper config", + config: HTTPAuthHookConfig{ + RoundTripper: mockRT, + }, + expectPass: true, + mocks: func(ctx context.Context) { + mockRT.EXPECT().RoundTrip(gomock.Any()).Return(&http.Response{ + StatusCode: http.StatusOK, + }, nil) + }, + }, + { + name: "Error - HTTP error", + config: HTTPAuthHookConfig{ + RoundTripper: mockRT, + }, + expectPass: false, + mocks: func(ctx context.Context) { + mockRT.EXPECT().RoundTrip(gomock.Any()).Return(nil, errors.New("Oh Crap")) + }, + }, + { + name: "Error - Non 2xx", + config: HTTPAuthHookConfig{ + RoundTripper: mockRT, + }, + expectPass: false, + mocks: func(ctx context.Context) { + mockRT.EXPECT().RoundTrip(gomock.Any()).Return(&http.Response{ + StatusCode: http.StatusTeapot, + }, nil) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + tt.mocks(ctx) + + authHook := new(HTTPAuthHook) + authHook.Log = &zerolog.Logger{} + authHook.Init(tt.config) + + success := authHook.OnConnectAuthenticate(&mqtt.Client{}, packets.Packet{}) + require.Equal(t, tt.expectPass, success) }) } } From 4346ead0dfe9e0b283c5cb1ec865ea130b198c94 Mon Sep 17 00:00:00 2001 From: Derek Duncan Date: Tue, 21 Feb 2023 11:08:09 +1100 Subject: [PATCH 3/5] Update go.yml to fix missing paren --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 65c43cf..f64ab57 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -7,7 +7,7 @@ on: push: branches: [ "main", "dev" ] pull_request: - branches: [ "main", "dev ] + branches: [ "main", "dev" ] jobs: From e8ccaee5a68846ec951a99406649cfe59751b0e4 Mon Sep 17 00:00:00 2001 From: Derek Duncan Date: Tue, 21 Feb 2023 11:18:22 +1100 Subject: [PATCH 4/5] Update go.yml to test coverage --- .github/workflows/go.yml | 26 ++++++++++++++++++++++++++ .gitignore | 2 ++ 2 files changed, 28 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index f64ab57..fc6a512 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -26,3 +26,29 @@ jobs: - name: Test run: go test -v ./... + + - name: Vet + run: go vet ./... + - name: Coverage + run: go test -v -covermode=count -coverprofile=coverage.out ./... + + coverage: + runs-on: ubuntu-latest + steps: + - name: Install Go + if: success() + uses: actions/setup-go@v2 + with: + go-version: 1.19.x + - name: Checkout code + uses: actions/checkout@v2 + - name: Calc coverage + run: | + go test -v -covermode=count -coverprofile=coverage.out ./... + - name: Convert coverage.out to coverage.lcov + uses: jandelgado/gcov2lcov-action@v1.0.6 + - name: Coveralls + uses: coverallsapp/github-action@v1.1.2 + with: + github-token: ${{ secrets.github_token }} + path-to-lcov: coverage.lcov diff --git a/.gitignore b/.gitignore index 22d0d82..a5471bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ vendor + +coverage.out \ No newline at end of file From a0912a3eabb078b28cb530ab86df2224ac3737bb Mon Sep 17 00:00:00 2001 From: Derek Duncan Date: Tue, 21 Feb 2023 11:21:06 +1100 Subject: [PATCH 5/5] Update go.yml to change step --- .github/workflows/go.yml | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index fc6a512..5230deb 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -35,20 +35,13 @@ jobs: coverage: runs-on: ubuntu-latest steps: - - name: Install Go - if: success() - uses: actions/setup-go@v2 - with: - go-version: 1.19.x - - name: Checkout code - uses: actions/checkout@v2 - - name: Calc coverage - run: | - go test -v -covermode=count -coverprofile=coverage.out ./... - - name: Convert coverage.out to coverage.lcov - uses: jandelgado/gcov2lcov-action@v1.0.6 - - name: Coveralls - uses: coverallsapp/github-action@v1.1.2 - with: - github-token: ${{ secrets.github_token }} - path-to-lcov: coverage.lcov + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: 1.19 + - name: Coverage + run: go test -v -covermode=count -coverprofile=coverage.out ./... + - name: Convert coverage.out to coverage.lcov + uses: jandelgado/gcov2lcov-action@v1.0.6