From b03eb5332739a7c4ae29e86aa96adbc006862859 Mon Sep 17 00:00:00 2001 From: lucasgomide Date: Wed, 10 May 2017 19:21:43 -0300 Subject: [PATCH] Adding Rollbar hook readme: describing rollbar hook options --- README.md | 6 ++- hook/hook.go | 2 + hook/rollbar.go | 47 +++++++++++++++++++++++ hook/rollbar_test.go | 89 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 hook/rollbar.go create mode 100644 hook/rollbar_test.go diff --git a/README.md b/README.md index f8550b6..5c6b755 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,11 @@ Here is all avaliables hook's configurations and your descriptions. Remember tha - **host** Tell to snith your sentry host (e.g http://sentry.io or http://sentry.self.hosted) - **organization_slug** The organization slug is a unique ID used to identify your organization. (You'll find it at your sentry's configuration, probably) - **project_slug** The Project Slug is a unique ID used to identify your project (You'll find it at your project config) - - **auth_token** The Auth Token to use the Sentry Web API. You can find [here](https://docs.sentry.io/api/auth/#auth-tokens) + - **auth_token** The Auth Token to use the Sentry Web API. You can find more [here](https://docs.sentry.io/api/auth/#auth-tokens) + - **env** The application's environment variable (e.g development, production) + +- Rollbar + - **access_token** The access token with `post_server_item` scope. You can find more [here](https://rollbar.com/docs/api/#authentication) - **env** The application's environment variable (e.g development, production) ## Example diff --git a/hook/hook.go b/hook/hook.go index e5246e5..1b1feb1 100644 --- a/hook/hook.go +++ b/hook/hook.go @@ -24,6 +24,8 @@ func Execute(h types.Hook, t types.Tsuru) { h = &Slack{} case "Sentry": h = &Sentry{} + case "Rollbar": + h = &Rollbar{} default: continue } diff --git a/hook/rollbar.go b/hook/rollbar.go new file mode 100644 index 0000000..e3d9cb5 --- /dev/null +++ b/hook/rollbar.go @@ -0,0 +1,47 @@ +package hook + +import ( + "bytes" + "errors" + "github.com/lucasgomide/snitch/types" + "net/http" +) + +type Rollbar struct { + AccessToken string + Env string +} + +func (r Rollbar) CallHook(deploys []types.Deploy) error { + data := []byte( + `{ + "access_token": "` + r.AccessToken + `", + "environment": "` + r.Env + `", + "revision": "` + deploys[0].Commit + `", + "local_username": "` + deploys[0].User + `" + } + `) + + resp, err := http.Post("https://api.rollbar.com/api/1/deploy/", "application/json", bytes.NewReader(data)) + + if err != nil { + return err + } + + if resp.StatusCode != 200 { + return errors.New("Rollbar - response status code isn't 200") + } + return nil +} + +func (r Rollbar) ValidatesFields() error { + if r.AccessToken == "" { + return errors.New("Field access_token into Rollbar hook is required") + } + + if r.Env == "" { + return errors.New("Field env into Rollbar hook is required") + } + + return nil +} diff --git a/hook/rollbar_test.go b/hook/rollbar_test.go new file mode 100644 index 0000000..7095ac8 --- /dev/null +++ b/hook/rollbar_test.go @@ -0,0 +1,89 @@ +package hook + +import ( + "github.com/lucasgomide/snitch/types" + "gopkg.in/jarcoal/httpmock.v1" + "strings" + "testing" +) + +func TestCreateDeploySuccessfulOnRollbar(t *testing.T) { + r := Rollbar{"abc", "development"} + + var ( + deploys []types.Deploy + urlRollbarApi = "https://api.rollbar.com/api/1/deploy/" + ) + + deploys = append(deploys, types.Deploy{"", "", "sha1", "user@g.com", ""}) + + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterResponder("POST", urlRollbarApi, + httpmock.NewStringResponder(200, `ok`)) + + if err := r.CallHook(deploys); err != nil { + t.Error(err) + } +} + +func TestReturnsErrorWhenCreateDeployFailsOnRollbar(t *testing.T) { + r := Rollbar{"abc", "development"} + var deploys []types.Deploy + deploys = append(deploys, types.Deploy{"", "", "sha1", "user@g.com", ""}) + + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterNoResponder(nil) + + if err := r.CallHook(deploys); err == nil { + t.Error("Expected returns error, got no error") + } else if !strings.Contains(err.Error(), "no responder") { + t.Error("Expected that the returns contain: no responder, got", err.Error()) + } +} + +func TestReturnsErrorWhenRequestToCreateDeployIsnt200OnRollbar(t *testing.T) { + r := Rollbar{"abc123", "development"} + var ( + deploys []types.Deploy + urlRollbarApi = "https://api.rollbar.com/api/1/deploy/" + ) + deploys = append(deploys, types.Deploy{"", "", "sha1", "user@g.com", ""}) + + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterResponder("POST", urlRollbarApi, + httpmock.NewStringResponder(501, `error`)) + expected := "Rollbar - response status code isn't 200" + if err := r.CallHook(deploys); err == nil { + t.Error("Expected returns error, got no error") + } else if !strings.Contains(err.Error(), expected) { + t.Errorf("Expected that the returns contain: %s, got %s", expected, err.Error()) + } +} + +func TestValidateFieldsOnRollbar(t *testing.T) { + r := Rollbar{} + var err error + if err = r.ValidatesFields(); err == nil { + t.Error("Expected returns error, got nil error") + } else if err.Error() != "Field access_token into Rollbar hook is required" { + t.Error("Expected error Field access_token into Rollbar hook is required, got", err.Error()) + } + + r.AccessToken = "abc123" + if err = r.ValidatesFields(); err == nil { + t.Error("Expected returns error, got nil error") + } else if err.Error() != "Field env into Rollbar hook is required" { + t.Error("Expected error Field env into Rollbar hook is required, got", err.Error()) + } + + r.Env = "dev" + if err = r.ValidatesFields(); err != nil { + t.Error("Expected returns no error, got", err.Error()) + } +}