Skip to content

Commit

Permalink
feat(core/gitlbal): add gitlab support
Browse files Browse the repository at this point in the history
  • Loading branch information
jsdidierlaurent committed Jun 1, 2020
1 parent aa32fd3 commit f0cb13f
Show file tree
Hide file tree
Showing 45 changed files with 3,104 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#MO_MONITORABLE_GITHUB_TOKEN=
#MO_MONITORABLE_GITHUB_COUNTCACHEEXPIRATION=30000

# Gitlab
#MO_MONITORABLE_GITLAB_URL=https://gitlab.com/
#MO_MONITORABLE_GITLAB_TIMEOUT=5000
#MO_MONITORABLE_GITLAB_TOKEN=

# HTTP
#MO_MONITORABLE_HTTP_TIMEOUT=2000
#MO_MONITORABLE_HTTP_SSLVERIFY=true
Expand Down
4 changes: 4 additions & 0 deletions faker-configs/faker-build-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
{ "type": "GITHUB-CHECKS", "params": { "owner": "monitoror", "repository": "monitoror", "ref": "master", "status": "ACTION_REQUIRED" } },
{ "type": "GITHUB-CHECKS", "params": { "owner": "monitoror", "repository": "monitoror", "ref": "master", "status": "RUNNING" } },
{ "type": "GITHUB-PULLREQUEST", "label": "-", "params": { "owner": "monitoror", "repository": "monitoror", "id": 1337, "mergeRequestTitle": "Feature branch which adds a super new thing", "branch": "fork:feature-branch", "status": "SUCCESS" } },
{ "type": "GITLAB-PIPELINE", "params": { "projectId": 10, "ref": "master" } },
{ "type": "GITLAB-PIPELINE", "params": { "projectId": 10, "ref": "master", "status": "ACTION_REQUIRED" } },
{ "type": "GITLAB-PIPELINE", "params": { "projectId": 10, "ref": "master", "status": "RUNNING" } },
{ "type": "GITLAB-MERGEREQUEST", "label": "-", "params": { "projectId": 10, "id": 1337, "mergeRequestTitle": "Feature branch which adds a super new thing", "branch": "fork:feature-branch", "status": "SUCCESS" } },
{
"type": "GROUP",
"label": "Merge requests in group",
Expand Down
1 change: 1 addition & 0 deletions faker-configs/faker-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
]},
{ "type": "PINGDOM-CHECK", "params": { "id": 1000 } },
{ "type": "GITHUB-COUNT", "label": "Monitoror open issues", "params": { "query": "is:open is:issue repo:monitoror/monitoror", "valueValues": ["10"] } },
{ "type": "GITLAB-ISSUES", "label": "Monitoror open issues", "params": { "valueValues": ["10"] } },
{ "type": "HTTP-STATUS", "params": { "url": "http:https://monitoror.test" } },
{ "type": "HTTP-STATUS", "params": { "url": "http:https://monitoror.test", "status": "SUCCESS"} },
{ "type": "HTTP-FORMATTED", "params": { "format": "JSON", "url": "http:https://monitoror.test", "key": ".key", "status": "SUCCESS", "valueValues": ["1337", "1337"] } }
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ require (
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator v9.31.0+incompatible
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-querystring v1.0.0 // indirect
github.com/joho/godotenv v1.3.0
github.com/jsdidierlaurent/azure-devops-go-api/azuredevops v0.0.0-20191016103718-deea5b1446b8
github.com/jsdidierlaurent/echo-middleware v1.0.3
Expand All @@ -32,9 +31,10 @@ require (
github.com/spf13/cobra v1.0.0
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.4.0
github.com/xanzy/go-gitlab v0.31.0
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 // indirect
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
gopkg.in/yaml.v2 v2.2.2
Expand Down
16 changes: 16 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-retryablehttp v0.6.4 h1:BbgctKO892xEyOXnGiaAwIoSq1QZ/SS4AhjoAh9DnfY=
github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
Expand Down Expand Up @@ -195,6 +201,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4/go.mod h1:50wTf68f99/Zt14pr046Tgt3Lp2vLyFZKzbFXTOabXw=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/xanzy/go-gitlab v0.31.0 h1:+nHztQuCXGSMluKe5Q9IRaPdz6tO8O0gMkQ0vqGpiBk=
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
Expand All @@ -210,7 +218,9 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49N
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
Expand All @@ -221,6 +231,8 @@ golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8ou
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288 h1:JIqe8uIcRBHXDQVvZtHwp80ai3Lw3IJAeJEs55Dc1W0=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -242,13 +254,17 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
Expand Down
62 changes: 62 additions & 0 deletions monitorables/gitlab/api/delivery/http/handlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package http

import (
"net/http"

"github.com/monitoror/monitoror/internal/pkg/monitorable/delivery"
"github.com/monitoror/monitoror/monitorables/gitlab/api"
"github.com/monitoror/monitoror/monitorables/gitlab/api/models"

"github.com/labstack/echo/v4"
)

type GitlabDelivery struct {
gitlabUsecase api.Usecase
}

func NewGitlabDelivery(p api.Usecase) *GitlabDelivery {
return &GitlabDelivery{p}
}

func (gd *GitlabDelivery) GetIssues(c echo.Context) error {
// Bind / check Params
params := &models.IssuesParams{}
_ = delivery.BindAndValidateParams(c, params)

tile, err := gd.gitlabUsecase.Issues(params)
if err != nil {
return err
}

return c.JSON(http.StatusOK, tile)
}

func (gd *GitlabDelivery) GetPipeline(c echo.Context) error {
// Bind / check Params
params := &models.PipelineParams{}
if err := delivery.BindAndValidateParams(c, params); err != nil {
return err
}

tile, err := gd.gitlabUsecase.Pipeline(params)
if err != nil {
return err
}

return c.JSON(http.StatusOK, tile)
}

func (gd *GitlabDelivery) GetMergeRequest(c echo.Context) error {
// Bind / check Params
params := &models.MergeRequestParams{}
if err := delivery.BindAndValidateParams(c, params); err != nil {
return err
}

tile, err := gd.gitlabUsecase.MergeRequest(params)
if err != nil {
return err
}

return c.JSON(http.StatusOK, tile)
}
203 changes: 203 additions & 0 deletions monitorables/gitlab/api/delivery/http/handlers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
package http

import (
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"strings"
"testing"

coreModels "github.com/monitoror/monitoror/models"
"github.com/monitoror/monitoror/monitorables/gitlab/api"
"github.com/monitoror/monitoror/monitorables/gitlab/api/mocks"
"github.com/monitoror/monitoror/monitorables/gitlab/api/models"

"github.com/AlekSi/pointer"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
. "github.com/stretchr/testify/mock"
)

func initEcho() (ctx echo.Context, res *httptest.ResponseRecorder) {
e := echo.New()
req := httptest.NewRequest(echo.GET, "/test", nil)
res = httptest.NewRecorder()
ctx = e.NewContext(req, res)

return
}

func TestDelivery_GetIssues_Success(t *testing.T) {
// Init
ctx, res := initEcho()

ctx.QueryParams().Set("projectId", "10")
ctx.QueryParams().Set("query", "test")

tile := coreModels.NewTile(api.GitlabIssuesTileType)
tile.Status = coreModels.SuccessStatus

mockUsecase := new(mocks.Usecase)
mockUsecase.On("Issues", &models.IssuesParams{ProjectID: pointer.ToInt(10)}).Return(tile, nil)
handler := NewGitlabDelivery(mockUsecase)

// Expected
json, err := json.Marshal(tile)
assert.NoError(t, err, "unable to marshal tile")

// Test
if assert.NoError(t, handler.GetIssues(ctx)) {
assert.Equal(t, http.StatusOK, res.Code)
assert.Equal(t, string(json), strings.TrimSpace(res.Body.String()))
mockUsecase.AssertNumberOfCalls(t, "Issues", 1)
mockUsecase.AssertExpectations(t)
}
}

func TestDelivery_GetIssues_Error(t *testing.T) {
// Init
ctx, res := initEcho()

ctx.QueryParams().Set("query", "test")

mockUsecase := new(mocks.Usecase)
mockUsecase.On("Issues", Anything).Return(nil, errors.New("build error"))
handler := NewGitlabDelivery(mockUsecase)

// Test
err := handler.GetIssues(ctx)
if assert.Error(t, err) {
assert.Equal(t, http.StatusOK, res.Code)
mockUsecase.AssertNumberOfCalls(t, "Issues", 1)
mockUsecase.AssertExpectations(t)
}
}

func TestDelivery_GetPipeline_Success(t *testing.T) {
// Init
ctx, res := initEcho()

ctx.QueryParams().Set("projectId", "10")
ctx.QueryParams().Set("ref", "master")

tile := coreModels.NewTile(api.GitlabPipelineTileType)
tile.Status = coreModels.SuccessStatus

mockUsecase := new(mocks.Usecase)
mockUsecase.On("Pipeline", &models.PipelineParams{ProjectID: pointer.ToInt(10), Ref: "master"}).Return(tile, nil)
handler := NewGitlabDelivery(mockUsecase)

// Expected
json, err := json.Marshal(tile)
assert.NoError(t, err, "unable to marshal tile")

// Test
if assert.NoError(t, handler.GetPipeline(ctx)) {
assert.Equal(t, http.StatusOK, res.Code)
assert.Equal(t, string(json), strings.TrimSpace(res.Body.String()))
mockUsecase.AssertNumberOfCalls(t, "Pipeline", 1)
mockUsecase.AssertExpectations(t)
}
}

func TestDelivery_GetChecks_MissingParams(t *testing.T) {
// Init
ctx, res := initEcho()

mockUsecase := new(mocks.Usecase)
handler := NewGitlabDelivery(mockUsecase)

// Test
err := handler.GetPipeline(ctx)
if assert.Error(t, err) {
assert.Equal(t, http.StatusOK, res.Code)
assert.IsType(t, &coreModels.MonitororError{}, err)
mockUsecase.AssertNumberOfCalls(t, "Pipeline", 0)
mockUsecase.AssertExpectations(t)
}
}

func TestDelivery_GetChecks_Error(t *testing.T) {
// Init
ctx, res := initEcho()

ctx.QueryParams().Set("projectId", "10")
ctx.QueryParams().Set("ref", "master")

mockUsecase := new(mocks.Usecase)
mockUsecase.On("Pipeline", Anything).Return(nil, errors.New("build error"))
handler := NewGitlabDelivery(mockUsecase)

// Test
err := handler.GetPipeline(ctx)
if assert.Error(t, err) {
assert.Equal(t, http.StatusOK, res.Code)
mockUsecase.AssertNumberOfCalls(t, "Pipeline", 1)
mockUsecase.AssertExpectations(t)
}
}

func TestDelivery_GetMergeRequest_Success(t *testing.T) {
// Init
ctx, res := initEcho()

ctx.QueryParams().Set("projectId", "10")
ctx.QueryParams().Set("id", "10")

tile := coreModels.NewTile(api.GitlabMergeRequestTileType)
tile.Status = coreModels.SuccessStatus

mockUsecase := new(mocks.Usecase)
mockUsecase.On("MergeRequest", &models.MergeRequestParams{ProjectID: pointer.ToInt(10), ID: pointer.ToInt(10)}).Return(tile, nil)
handler := NewGitlabDelivery(mockUsecase)

// Expected
json, err := json.Marshal(tile)
assert.NoError(t, err, "unable to marshal tile")

// Test
if assert.NoError(t, handler.GetMergeRequest(ctx)) {
assert.Equal(t, http.StatusOK, res.Code)
assert.Equal(t, string(json), strings.TrimSpace(res.Body.String()))
mockUsecase.AssertNumberOfCalls(t, "MergeRequest", 1)
mockUsecase.AssertExpectations(t)
}
}

func TestDelivery_GetMergeRequest_MissingParams(t *testing.T) {
// Init
ctx, res := initEcho()

mockUsecase := new(mocks.Usecase)
handler := NewGitlabDelivery(mockUsecase)

// Test
err := handler.GetMergeRequest(ctx)
if assert.Error(t, err) {
assert.Equal(t, http.StatusOK, res.Code)
assert.IsType(t, &coreModels.MonitororError{}, err)
mockUsecase.AssertNumberOfCalls(t, "MergeRequest", 0)
mockUsecase.AssertExpectations(t)
}
}

func TestDelivery_GetMergeRequest_Error(t *testing.T) {
// Init
ctx, res := initEcho()

ctx.QueryParams().Set("projectId", "10")
ctx.QueryParams().Set("id", "10")

mockUsecase := new(mocks.Usecase)
mockUsecase.On("MergeRequest", Anything).Return(nil, errors.New("build error"))
handler := NewGitlabDelivery(mockUsecase)

// Test
err := handler.GetMergeRequest(ctx)
if assert.Error(t, err) {
assert.Equal(t, http.StatusOK, res.Code)
mockUsecase.AssertNumberOfCalls(t, "MergeRequest", 1)
mockUsecase.AssertExpectations(t)
}
}
Loading

0 comments on commit f0cb13f

Please sign in to comment.