1
0
mirror of https://github.com/go-micro/go-micro.git synced 2024-12-18 08:26:38 +02:00

feat(CI): add linting and pretty test output (#2562)

This commit is contained in:
David Brouwer 2022-09-30 02:08:42 +02:00 committed by GitHub
parent 1db36357d5
commit 47e6a8d725
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 348 additions and 59 deletions

View File

@ -1,28 +0,0 @@
name: PR Sanity Check
on: pull_request
jobs:
prtest:
name: PR sanity check
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.17
uses: actions/setup-go@v1
with:
go-version: 1.17
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Get dependencies
run: |
go get -v -t -d ./...
- name: Run tests
id: tests
env:
IN_TRAVIS_CI: yes
run: go test -v ./...

65
.github/workflows/tests.yaml vendored Normal file
View File

@ -0,0 +1,65 @@
name: Run Tests
on:
push:
branches:
- '**'
pull_request:
types:
- opened
- reopened
branches:
- '**'
jobs:
golangci:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: 1.19
check-latest: true
cache: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
unittests:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19
check-latest: true
cache: true
- name: Get dependencies
run: |
go install github.com/kyoh86/richgo@latest
go get -v -t -d ./...
- name: Run tests
id: tests
run: richgo test -v -race -cover ./...
env:
IN_TRAVIS_CI: yes
RICHGO_FORCE_COLOR: 1
summary:
name: Summary Report
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19
check-latest: true
cache: true
- name: Get dependencies
run: |
go install github.com/mfridman/tparse@latest
go get -v -t -d ./...
- name: Run tests
id: tests
run: go test -v -race -cover -json ./... | tparse -notests -format=markdown >> $GITHUB_STEP_SUMMARY
env:
IN_TRAVIS_CI: yes

View File

@ -1,29 +0,0 @@
name: Run tests
on: [push]
jobs:
test:
name: Test repo
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.17
uses: actions/setup-go@v1
with:
go-version: 1.17
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Get dependencies
run: |
go get -v -t -d ./...
- name: Run tests
id: tests
env:
IN_TRAVIS_CI: yes
run: go test -v ./...

231
.golangci.yaml Normal file
View File

@ -0,0 +1,231 @@
# This file contains all available configuration options
# with their default values.
# options for analysis running
run:
# go: '1.18'
# default concurrency is a available CPU number
# concurrency: 4
# timeout for analysis, e.g. 30s, 5m, default is 1m
deadline: 10m
# exit code when at least one issue was found, default is 1
issues-exit-code: 1
# include test files or not, default is true
tests: true
# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
skip-files: []
# - .*\\.pb\\.go$
allow-parallel-runners: true
# list of build tags, all linters use it. Default is empty list.
build-tags: []
# output configuration options
output:
# Format: colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions
#
# Multiple can be specified by separating them by comma, output can be provided
# for each of them by separating format name and path by colon symbol.
# Output path can be either `stdout`, `stderr` or path to the file to write to.
# Example: "checkstyle:report.json,colored-line-number"
#
# Default: colored-line-number
format: colored-line-number
# Print lines of code with issue.
# Default: true
print-issued-lines: true
# Print linter name in the end of issue text.
# Default: true
print-linter-name: true
# Make issues output unique by line.
# Default: true
uniq-by-line: true
# Add a prefix to the output file references.
# Default is no prefix.
path-prefix: ""
# Sort results by: filepath, line and column.
sort-results: true
# all available settings of specific linters
linters-settings:
varnamelen:
# The longest distance, in source lines, that is being considered a "small scope".
# Variables used in at most this many lines will be ignored.
# Default: 5
max-distance: 16
ignore-names:
- err
- id
- ch
- wg
- mu
ignore-decls:
- c echo.Context
- t testing.T
- f *foo.Bar
- e error
- i int
- const C
- T any
- m map[string]int
errcheck:
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
# default is false: such cases aren't reported by default.
check-type-assertions: true
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
# default is false: such cases aren't reported by default.
check-blank: true
govet:
# report about shadowed variables
check-shadowing: true
gofmt:
# simplify code: gofmt with `-s` option, true by default
simplify: true
gocyclo:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 15
maligned:
# print struct with more effective memory layout or not, false by default
suggest-new: true
dupl:
# tokens count to trigger issue, 150 by default
threshold: 100
goconst:
# minimal length of string constant, 3 by default
min-len: 3
# minimal occurrences count to trigger, 3 by default
min-occurrences: 3
depguard:
list-type: blacklist
# Packages listed here will reported as error if imported
packages:
- github.com/golang/protobuf/proto
misspell:
# Correct spellings using locale preferences for US or UK.
# Default is to use a neutral variety of English.
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
locale: US
lll:
# max line length, lines longer will be reported. Default is 120.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
line-length: 120
# tab width in spaces. Default to 1.
tab-width: 1
unused:
# treat code as a program (not a library) and report unused exported identifiers; default is false.
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
unparam:
# call graph construction algorithm (cha, rta). In general, use cha for libraries,
# and rta for programs with main packages. Default is cha.
algo: cha
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
nakedret:
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
max-func-lines: 60
nolintlint:
allow-unused: false
allow-leading-space: false
allow-no-explanation: []
require-explanation: false
require-specific: true
prealloc:
# XXX: we don't recommend using this linter before doing performance profiling.
# For most programs usage of prealloc will be a premature optimization.
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
# True by default.
simple: true
range-loops: true # Report preallocation suggestions on range loops, true by default
for-loops: false # Report preallocation suggestions on for loops, false by default
cyclop:
# the maximal code complexity to report
max-complexity: 20
gomoddirectives:
replace-local: true
retract-allow-no-explanation: false
exclude-forbidden: true
linters:
enable-all: true
disable-all: false
fast: false
disable:
- golint
- varcheck
- ifshort
- structcheck
- deadcode
# - nosnakecase
- interfacer
- maligned
- scopelint
- exhaustivestruct
- testpackage
- promlinter
- nonamedreturns
- makezero
- gofumpt
# Can be considered to be enabled
- gochecknoinits
- gochecknoglobals # RIP
- dogsled
- wrapcheck
- paralleltest
- ireturn
- gomnd
- goerr113
- exhaustruct
- containedctx
- godox
issues:
# List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all
# excluded by default patterns execute `golangci-lint run --help`
# exclude:
# - package comment should be of the form "Package services ..." # revive
# - ^ST1000 # ST1000: at least one file in a package should have a package comment (stylecheck)
# exclude-rules:
# - path: internal/app/machined/pkg/system/services
# linters:
# - dupl
# Independently from option `exclude` we use default exclude patterns,
# it can be disabled by this option. To list all
# excluded by default patterns execute `golangci-lint run --help`.
# Default value for this option is true.
exclude-use-default: false
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-issues-per-linter: 0
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0
# Show only new issues: if there are unstaged changes or untracked files,
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
# It's a super-useful option for integration of golangci-lint into existing
# large codebase. It's not practical to fix all existing issues at the moment
# of integration: much better don't allow issues in new code.
# Default is false.
new: false

29
.richstyle.yaml Normal file
View File

@ -0,0 +1,29 @@
labelType: long
coverThreshold: 70
buildStyle:
bold: true
foreground: yellow
startStyle:
foreground: lightBlack
passStyle:
foreground: green
failStyle:
bold: true
foreground: "#821515"
skipStyle:
foreground: lightBlack
passPackageStyle:
foreground: green
hide: true
failPackageStyle:
bold: true
foreground: "#821515"
coveredStyle:
foreground: green
uncoveredStyle:
bold: true
foreground: yellow
fileStyle:
foreground: cyan
lineStyle:
foreground: magenta

View File

@ -10,6 +10,8 @@ import (
func TestStore(t *testing.T) { func TestStore(t *testing.T) {
store := NewStore() store := NewStore()
t.Parallel()
testData := []Event{ testData := []Event{
{ID: uuid.New().String(), Topic: "foo"}, {ID: uuid.New().String(), Topic: "foo"},
{ID: uuid.New().String(), Topic: "foo"}, {ID: uuid.New().String(), Topic: "foo"},
@ -18,6 +20,7 @@ func TestStore(t *testing.T) {
// write the records to the store // write the records to the store
t.Run("Write", func(t *testing.T) { t.Run("Write", func(t *testing.T) {
t.Parallel()
for _, event := range testData { for _, event := range testData {
err := store.Write(&event) err := store.Write(&event)
assert.Nilf(t, err, "Writing an event should not return an error") assert.Nilf(t, err, "Writing an event should not return an error")
@ -26,6 +29,7 @@ func TestStore(t *testing.T) {
// should not be able to read events from a blank topic // should not be able to read events from a blank topic
t.Run("ReadMissingTopic", func(t *testing.T) { t.Run("ReadMissingTopic", func(t *testing.T) {
t.Parallel()
evs, err := store.Read("") evs, err := store.Read("")
assert.Equal(t, err, ErrMissingTopic, "Reading a blank topic should return an error") assert.Equal(t, err, ErrMissingTopic, "Reading a blank topic should return an error")
assert.Nil(t, evs, "No events should be returned") assert.Nil(t, evs, "No events should be returned")
@ -33,6 +37,7 @@ func TestStore(t *testing.T) {
// should only get the events from the topic requested // should only get the events from the topic requested
t.Run("ReadTopic", func(t *testing.T) { t.Run("ReadTopic", func(t *testing.T) {
t.Parallel()
evs, err := store.Read("foo") evs, err := store.Read("foo")
assert.Nilf(t, err, "No error should be returned") assert.Nilf(t, err, "No error should be returned")
assert.Len(t, evs, 2, "Only the events for this topic should be returned") assert.Len(t, evs, 2, "Only the events for this topic should be returned")
@ -40,6 +45,7 @@ func TestStore(t *testing.T) {
// limits should be honoured // limits should be honoured
t.Run("ReadTopicLimit", func(t *testing.T) { t.Run("ReadTopicLimit", func(t *testing.T) {
t.Parallel()
evs, err := store.Read("foo", ReadLimit(1)) evs, err := store.Read("foo", ReadLimit(1))
assert.Nilf(t, err, "No error should be returned") assert.Nilf(t, err, "No error should be returned")
assert.Len(t, evs, 1, "The result should include no more than the read limit") assert.Len(t, evs, 1, "The result should include no more than the read limit")

View File

@ -21,6 +21,8 @@ type testCase struct {
func TestStream(t *testing.T) { func TestStream(t *testing.T) {
tcs := []testCase{} tcs := []testCase{}
t.Parallel()
stream, err := NewStream() stream, err := NewStream()
assert.Nilf(t, err, "NewStream should not return an error") assert.Nilf(t, err, "NewStream should not return an error")
assert.NotNilf(t, stream, "NewStream should return a stream object") assert.NotNilf(t, stream, "NewStream should return a stream object")
@ -28,6 +30,7 @@ func TestStream(t *testing.T) {
for _, tc := range tcs { for _, tc := range tcs {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel()
runTestStream(t, tc.str) runTestStream(t, tc.str)
}) })
} }
@ -35,8 +38,11 @@ func TestStream(t *testing.T) {
} }
func runTestStream(t *testing.T, stream Stream) { func runTestStream(t *testing.T, stream Stream) {
t.Parallel()
// TestMissingTopic will test the topic validation on publish // TestMissingTopic will test the topic validation on publish
t.Run("TestMissingTopic", func(t *testing.T) { t.Run("TestMissingTopic", func(t *testing.T) {
t.Parallel()
err := stream.Publish("", nil) err := stream.Publish("", nil)
assert.Equalf(t, err, ErrMissingTopic, "Publishing to a blank topic should return an error") assert.Equalf(t, err, ErrMissingTopic, "Publishing to a blank topic should return an error")
}) })
@ -44,6 +50,7 @@ func runTestStream(t *testing.T, stream Stream) {
// TestConsumeTopic will publish a message to the test topic. The subscriber will subscribe to the // TestConsumeTopic will publish a message to the test topic. The subscriber will subscribe to the
// same test topic. // same test topic.
t.Run("TestConsumeTopic", func(t *testing.T) { t.Run("TestConsumeTopic", func(t *testing.T) {
t.Parallel()
payload := &testPayload{Message: "HelloWorld"} payload := &testPayload{Message: "HelloWorld"}
metadata := map[string]string{"foo": "bar"} metadata := map[string]string{"foo": "bar"}
@ -85,6 +92,8 @@ func runTestStream(t *testing.T, stream Stream) {
// the message from the firehose topic with different queues. The second subscriber will be registered // the message from the firehose topic with different queues. The second subscriber will be registered
// after the message is published to test durability. // after the message is published to test durability.
t.Run("TestConsumeGroup", func(t *testing.T) { t.Run("TestConsumeGroup", func(t *testing.T) {
t.Parallel()
topic := uuid.New().String() topic := uuid.New().String()
payload := &testPayload{Message: "HelloWorld"} payload := &testPayload{Message: "HelloWorld"}
metadata := map[string]string{"foo": "bar"} metadata := map[string]string{"foo": "bar"}
@ -150,6 +159,8 @@ func runTestStream(t *testing.T, stream Stream) {
}) })
t.Run("AckingNacking", func(t *testing.T) { t.Run("AckingNacking", func(t *testing.T) {
t.Parallel()
ch, err := stream.Consume("foobarAck", WithAutoAck(false, 5*time.Second)) ch, err := stream.Consume("foobarAck", WithAutoAck(false, 5*time.Second))
assert.NoError(t, err, "Unexpected error subscribing") assert.NoError(t, err, "Unexpected error subscribing")
assert.NoError(t, stream.Publish("foobarAck", map[string]string{"foo": "message 1"})) assert.NoError(t, stream.Publish("foobarAck", map[string]string{"foo": "message 1"}))
@ -171,6 +182,8 @@ func runTestStream(t *testing.T, stream Stream) {
}) })
t.Run("Retries", func(t *testing.T) { t.Run("Retries", func(t *testing.T) {
t.Parallel()
ch, err := stream.Consume("foobarRetries", WithAutoAck(false, 5*time.Second), WithRetryLimit(1)) ch, err := stream.Consume("foobarRetries", WithAutoAck(false, 5*time.Second), WithRetryLimit(1))
assert.NoError(t, err, "Unexpected error subscribing") assert.NoError(t, err, "Unexpected error subscribing")
assert.NoError(t, stream.Publish("foobarRetries", map[string]string{"foo": "message 1"})) assert.NoError(t, stream.Publish("foobarRetries", map[string]string{"foo": "message 1"}))
@ -186,10 +199,11 @@ func runTestStream(t *testing.T, stream Stream) {
t.Fatalf("Unexpected event received") t.Fatalf("Unexpected event received")
case <-time.After(7 * time.Second): case <-time.After(7 * time.Second):
} }
}) })
t.Run("InfiniteRetries", func(t *testing.T) { t.Run("InfiniteRetries", func(t *testing.T) {
t.Parallel()
ch, err := stream.Consume("foobarRetriesInf", WithAutoAck(false, 2*time.Second)) ch, err := stream.Consume("foobarRetriesInf", WithAutoAck(false, 2*time.Second))
assert.NoError(t, err, "Unexpected error subscribing") assert.NoError(t, err, "Unexpected error subscribing")
assert.NoError(t, stream.Publish("foobarRetriesInf", map[string]string{"foo": "message 1"})) assert.NoError(t, stream.Publish("foobarRetriesInf", map[string]string{"foo": "message 1"}))
@ -212,10 +226,11 @@ func runTestStream(t *testing.T, stream Stream) {
break break
} }
} }
}) })
t.Run("twoSubs", func(t *testing.T) { t.Run("twoSubs", func(t *testing.T) {
t.Parallel()
ch1, err := stream.Consume("foobarTwoSubs1", WithAutoAck(false, 5*time.Second)) ch1, err := stream.Consume("foobarTwoSubs1", WithAutoAck(false, 5*time.Second))
assert.NoError(t, err, "Unexpected error subscribing to topic 1") assert.NoError(t, err, "Unexpected error subscribing to topic 1")
ch2, err := stream.Consume("foobarTwoSubs2", WithAutoAck(false, 5*time.Second)) ch2, err := stream.Consume("foobarTwoSubs2", WithAutoAck(false, 5*time.Second))