Skip to content

Commit

Permalink
Added errcheck, test to makefile, added circle CI config.
Browse files Browse the repository at this point in the history
And we have first unit test! ;p

Signed-off-by: Bartek Plotka <bwplotka@gmail.com>
  • Loading branch information
bwplotka committed May 10, 2019
1 parent 88fb628 commit 5dc75ea
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 22 deletions.
25 changes: 25 additions & 0 deletions .circleci/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# NOTE: Current plan gives 1500 build minutes per month.
version: 2
jobs:
test:
docker:
# Available from https://hub.docker.com/r/circleci/golang/
- image: circleci/golang:1.12
working_directory: /go/src/github.com/free/jiralert
environment:
GO111MODULE: 'on'
GOBIN: "/tmp/bin"
steps:
- checkout
- setup_remote_docker:
version: 17.07.0-ce
- run: make

workflows:
version: 2
jiralert:
jobs:
- test:
filters:
tags:
only: /.*/
3 changes: 3 additions & 0 deletions .errcheck_excludes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(github.com/go-kit/kit/log.Logger).Log
fmt.Fprintln
fmt.Fprint
34 changes: 29 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
GO := go
STATICCHECK := ${GOBIN}/staticcheck
GOBIN ?= ${GOPATH}/bin
STATICCHECK := $(GOBIN)/staticcheck

VERSION := $(shell git describe --tags 2>/dev/null)
ifeq "$(VERSION)" ""
Expand All @@ -11,10 +12,13 @@ RELEASE_DIR := release/$(RELEASE)

PACKAGES := $(shell $(GO) list ./... | grep -v /vendor/)
STATICCHECK_IGNORE :=
DOCKER_IMAGE_NAME := jiralert

DOCKER_IMAGE_NAME := jiralert
# v1.2.0
ERRCHECK_VERSION ?= e14f8d59a22d460d56c5ee92507cd94c78fbf274
ERRCHECK ?= $(GOBIN)/errcheck-$(ERRCHECK_VERSION)

all: clean format check build
all: check-go-mod clean format check errcheck build test

clean:
@rm -rf jiralert release
Expand Down Expand Up @@ -42,13 +46,33 @@ tarball:
@rm -rf "$(RELEASE_DIR)/*"
@mkdir -p "$(RELEASE_DIR)"
@cp jiralert README.md LICENSE "$(RELEASE_DIR)"
@mkdir -p "$(RELEASE_DIR)/config"
@mkdir -p "$(RELEASE_WDIR)/config"
@cp config/* "$(RELEASE_DIR)/config"
@tar -zcvf "$(RELEASE).tar.gz" -C "$(RELEASE_DIR)"/.. "$(RELEASE)"
@rm -rf "$(RELEASE_DIR)"

.PHONY: check-go-mod
check-go-mod:
@go mod verify

# errcheck performs static analysis and returns error if any of the errors is not checked.
.PHONY: errcheck
errcheck: $(ERRCHECK)
@echo ">> errchecking the code"
$(ERRCHECK) -verbose -exclude .errcheck_excludes.txt ./cmd/... ./pkg/...

.PHONY: test
test:
@echo ">> running all tests."
@go test $(shell go list ./... | grep -v /vendor/);

$(ERRCHECK):
@go get github.com/kisielk/errcheck@$(ERRCHECK_VERSION)
@mv $(GOBIN)/errcheck $(ERRCHECK)
@go mod tidy

$(STATICCHECK):
ifeq (${GOBIN},)
ifeq ($(GOBIN),)
@echo >&2 "GOBIN environment variable is not defined, where to put installed binaries?"; exit 1
endif
@echo ">> getting staticcheck"
Expand Down
22 changes: 8 additions & 14 deletions cmd/jiralert/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,28 +86,22 @@ func pageTemplate(name string) *template.Template {
// HomeHandlerFunc is the HTTP handler for the home page (`/`).
func HomeHandlerFunc() func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
homeTemplate.Execute(w, &tdata{
if err := homeTemplate.Execute(w, &tdata{
DocsUrl: docsUrl,
})
}); err != nil {
w.WriteHeader(500)
}
}
}

// ConfigHandlerFunc is the HTTP handler for the `/config` page. It outputs the configuration marshaled in YAML format.
func ConfigHandlerFunc(config *config.Config) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
configTemplate.Execute(w, &tdata{
if err := configTemplate.Execute(w, &tdata{
DocsUrl: docsUrl,
Config: config.String(),
})
}); err != nil {
w.WriteHeader(500)
}
}
}

// HandleError is an error handler that other handlers defer to in case of error. It is important to not have written
// anything to w before calling HandleError(), or the 500 status code won't be set (and the content might be mixed up).
//func HandleError(err error, metricsPath string, w http.ResponseWriter, r *http.Request) {
// w.WriteHeader(http.StatusInternalServerError)
// errorTemplate.Execute(w, &tdata{
// DocsUrl: docsUrl,
// Err: err,
// })
//}
6 changes: 3 additions & 3 deletions cmd/jiralert/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ import (
const (
unknownReceiver = "<unknown>"
logFormatLogfmt = "logfmt"
logFormatJson = "json"
logFormatJson = "json"
)

var (
listenAddress = flag.String("listen-address", ":9097", "The address to listen on for HTTP requests.")
configFile = flag.String("config", "config/jiralert.yml", "The JIRAlert configuration file")
logLevel = flag.String("log.level", "info", "Log filtering level (debug, info, warn, error)")
logFormat = flag.String("log.format", logFormatLogfmt, "Log format to use (" + logFormatLogfmt + ", " + logFormatJson + ")")
logFormat = flag.String("log.format", logFormatLogfmt, "Log format to use ("+logFormatLogfmt+", "+logFormatJson+")")

// Version is the build version, set by make to latest git tag/hash via `-ldflags "-X main.Version=$(VERSION)"`.
Version = "<local build>"
Expand Down Expand Up @@ -62,7 +62,7 @@ func main() {

http.HandleFunc("/alert", func(w http.ResponseWriter, req *http.Request) {
level.Debug(logger).Log("msg", "handling /alert webhook request")
defer req.Body.Close()
defer func() { _ = req.Body.Close() }()

// https://godoc.org/github.com/prometheus/alertmanager/template#Data
data := alertmanager.Data{}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612 // indirect
github.com/prometheus/common v0.0.0-20171006141418-1bab55dd05db // indirect
github.com/prometheus/procfs v0.0.0-20171017214025-a6e9df898b13 // indirect
github.com/stretchr/testify v1.3.0
github.com/trivago/tgo v1.0.1
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ github.com/andygrunwald/go-jira v0.0.0-20181018203616-bbce4afa5493 h1:7bKcEt+LMT
github.com/andygrunwald/go-jira v0.0.0-20181018203616-bbce4afa5493/go.mod h1:yNYQrX3nGSrVdcVsM2mWz2pm7tTeDtYfRyVEkc3VUiY=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a h1:BtpsbiV638WQZwhA98cEZw2BsbnQJrbd0BI7tsy0W1c=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/structs v0.0.0-20171020064819-f5faa72e7309 h1:yetGKN1jYaaVt+q69KPz+V2Z64OyTw/KfTNQS90n/tU=
github.com/fatih/structs v0.0.0-20171020064819-f5faa72e7309/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
Expand All @@ -25,6 +27,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/pkg/errors v0.0.0-20181023235946-059132a15dd0 h1:R+lX9nKwNd1n7UE5SQAyoorREvRn3aLF6ZndXBoIWqY=
github.com/pkg/errors v0.0.0-20181023235946-059132a15dd0/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/prometheus/client_golang v0.0.0-20171005112915-5cec1d0429b0 h1:uEiENdm9N5Nj3ezfwdvwBGc2EHLiUgD3hUTOaMfBn5E=
github.com/prometheus/client_golang v0.0.0-20171005112915-5cec1d0429b0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612 h1:13pIdM2tpaDi4OVe24fgoIS7ZTqMt0QI+bwQsX5hq+g=
Expand All @@ -33,6 +37,9 @@ github.com/prometheus/common v0.0.0-20171006141418-1bab55dd05db h1:PmL7nSW2mvuot
github.com/prometheus/common v0.0.0-20171006141418-1bab55dd05db/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20171017214025-a6e9df898b13 h1:leRfx9kcgnSDkqAFhaaUcRqpAZgnFdwZkZcdRcea1h0=
github.com/prometheus/procfs v0.0.0-20171017214025-a6e9df898b13/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/trivago/tgo v1.0.1 h1:bxatjJIXNIpV18bucU4Uk/LaoxvxuOlp/oowRHyncLQ=
github.com/trivago/tgo v1.0.1/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
Expand Down
79 changes: 79 additions & 0 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package config

import (
"github.com/go-kit/kit/log"
"github.com/stretchr/testify/require"
"io/ioutil"
"os"
"path"
"testing"
)

const testConf = `
# Global defaults, applied to all receivers where not explicitly overridden. Optional.
defaults:
# API access fields.
api_url: https://jiralert.atlassian.net
user: jiralert
password: 'JIRAlert'
# The type of JIRA issue to create. Required.
issue_type: Bug
# Issue priority. Optional.
priority: Critical
# Go template invocation for generating the summary. Required.
summary: '{{ template "jira.summary" . }}'
# Go template invocation for generating the description. Optional.
description: '{{ template "jira.description" . }}'
# State to transition into when reopening a closed issue. Required.
reopen_state: "To Do"
# Do not reopen issues with this resolution. Optional.
wont_fix_resolution: "Won't Fix"
# Amount of time after being closed that an issue should be reopened, after which, a new issue is created.
# Optional (default: always reopen)
reopen_duration: 0h
# Receiver definitions. At least one must be defined.
receivers:
# Must match the Alertmanager receiver name. Required.
- name: 'jira-ab'
# JIRA project to create the issue in. Required.
project: AB
# Copy all Prometheus labels into separate JIRA labels. Optional (default: false).
add_group_labels: false
- name: 'jira-xy'
project: XY
# Overrides default.
issue_type: Task
# JIRA components. Optional.
components: [ 'Operations' ]
# Standard or custom field values to set on created issue. Optional.
#
# See https://developer.atlassian.com/server/jira/platform/jira-rest-api-examples/#setting-custom-field-data-for-other-field-types for further examples.
fields:
# TextField
customfield_10001: "Random text"
# SelectList
customfield_10002: { "value": "red" }
# MultiSelect
customfield_10003: [{"value": "red" }, {"value": "blue" }, {"value": "green" }]
# File containing template definitions. Required.
template: jiralert.tmpl
`

func TestLoadFile(t *testing.T) {
dir, err := ioutil.TempDir("", "test_jiralert")
require.NoError(t, err)
defer func() { require.NoError(t, os.RemoveAll(dir)) }()

require.NoError(t, ioutil.WriteFile(path.Join(dir, "config.yaml"), []byte(testConf), os.ModePerm))

_, content, err := LoadFile(path.Join(dir, "config.yaml"), log.NewNopLogger())

require.NoError(t, err)
require.Equal(t, testConf, string(content))

// TODO(bwplotka): Add proper test cases on config struct.
}

0 comments on commit 5dc75ea

Please sign in to comment.