run tests and linter on every PR

This commit is contained in:
Maria Ines Parnisari
2023-11-20 13:44:15 -08:00
parent 7b5dfadcde
commit de3e573a65
10 changed files with 92 additions and 58 deletions

39
.github/workflows/pull_request.yaml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: Pull Request
on:
merge_group:
pull_request:
branches:
- master
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: './go.mod'
check-latest: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: latest
test:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: './go.mod'
check-latest: true
- name: Unit Tests
run: make t

35
.golangci.yaml Normal file
View File

@@ -0,0 +1,35 @@
run:
timeout: 3m
modules-download-mode: readonly
linters:
enable:
- errname
- gofmt
- goimports
- stylecheck
- importas
- errcheck
- gosimple
- govet
- ineffassign
- mirror
- staticcheck
- tagalign
- testifylint
- typecheck
- unused
- unconvert
- unparam
- wastedassign
- whitespace
- exhaustive
- noctx
- promlinter
linters-settings:
govet:
enable-all: true
disable:
- shadow
- fieldalignment

View File

@@ -1,18 +1,20 @@
.PHONY: l
l: ## Lint Go source files
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest && golangci-lint run
.PHONY: t
t:
t: ## Run unit tests
go test -race -count=1 ./...
.PHONY: f
f:
f: ## Format code
go fmt ./...
.PHONY: c
c:
c: ## Measure code coverage
go test -race -covermode=atomic ./... -coverprofile=cover.out && \
# go tool cover -html=cover.out && \
go tool cover -func cover.out \
| grep -vP '[89]\d\.\d%' | grep -v '100.0%' \
|| true
rm cover.out
rm cover.out

View File

@@ -7,33 +7,6 @@ import (
"time"
)
// The cache has a generic 'control' channel that is used to send
// messages to the worker. These are the messages that can be sent to it
type getDropped struct {
res chan int
}
type getSize struct {
res chan int64
}
type setMaxSize struct {
size int64
done chan struct{}
}
type clear struct {
done chan struct{}
}
type syncWorker struct {
done chan struct{}
}
type gc struct {
done chan struct{}
}
type Cache[T any] struct {
*Configuration[T]
control
@@ -203,11 +176,6 @@ func (c *Cache[T]) Delete(key string) bool {
return false
}
func (c *Cache[T]) deleteItem(bucket *bucket[T], item *Item[T]) {
bucket.delete(item.key) //stop other GETs from getting it
c.deletables <- item
}
func (c *Cache[T]) set(key string, value T, duration time.Duration, track bool) *Item[T] {
item, existing := c.bucket(key).set(key, value, duration, track)
if existing != nil {
@@ -389,7 +357,7 @@ func (c *Cache[T]) gc() int {
}
prev := node.Prev
item := node.Value
if c.tracking == false || atomic.LoadInt32(&item.refCount) == 0 {
if !c.tracking || atomic.LoadInt32(&item.refCount) == 0 {
c.bucket(item.key).delete(item.key)
c.size -= item.size
c.list.Remove(node)

View File

@@ -124,7 +124,6 @@ func Test_CacheDeletesAFunc(t *testing.T) {
return key == "d"
}), 1)
assert.Equal(t, cache.ItemCount(), 2)
}
func Test_CacheOnDeleteCallbackCalled(t *testing.T) {

View File

@@ -37,7 +37,7 @@ func (c *Configuration[T]) MaxSize(max int64) *Configuration[T] {
// requires a write lock on the bucket). Must be a power of 2 (1, 2, 4, 8, 16, ...)
// [16]
func (c *Configuration[T]) Buckets(count uint32) *Configuration[T] {
if count == 0 || ((count&(^count+1)) == count) == false {
if count == 0 || !((count & (^count + 1)) == count) {
count = 16
}
c.buckets = int(count)

View File

@@ -32,7 +32,7 @@ func (b *layeredBucket[T]) getSecondaryBucket(primary string) *bucket[T] {
b.RLock()
bucket, exists := b.buckets[primary]
b.RUnlock()
if exists == false {
if !exists {
return nil
}
return bucket
@@ -41,7 +41,7 @@ func (b *layeredBucket[T]) getSecondaryBucket(primary string) *bucket[T] {
func (b *layeredBucket[T]) set(primary, secondary string, value T, duration time.Duration, track bool) (*Item[T], *Item[T]) {
b.Lock()
bkt, exists := b.buckets[primary]
if exists == false {
if !exists {
bkt = &bucket[T]{lookup: make(map[string]*Item[T])}
b.buckets[primary] = bkt
}
@@ -55,7 +55,7 @@ func (b *layeredBucket[T]) delete(primary, secondary string) *Item[T] {
b.RLock()
bucket, exists := b.buckets[primary]
b.RUnlock()
if exists == false {
if !exists {
return nil
}
return bucket.delete(secondary)
@@ -65,7 +65,7 @@ func (b *layeredBucket[T]) deletePrefix(primary, prefix string, deletables chan
b.RLock()
bucket, exists := b.buckets[primary]
b.RUnlock()
if exists == false {
if !exists {
return 0
}
return bucket.deletePrefix(prefix, deletables)
@@ -75,7 +75,7 @@ func (b *layeredBucket[T]) deleteFunc(primary string, matches func(key string, i
b.RLock()
bucket, exists := b.buckets[primary]
b.RUnlock()
if exists == false {
if !exists {
return 0
}
return bucket.deleteFunc(matches, deletables)
@@ -85,7 +85,7 @@ func (b *layeredBucket[T]) deleteAll(primary string, deletables chan *Item[T]) b
b.RLock()
bucket, exists := b.buckets[primary]
b.RUnlock()
if exists == false {
if !exists {
return false
}

View File

@@ -41,7 +41,7 @@ func Layered[T any](config *Configuration[T]) *LayeredCache[T] {
deletables: make(chan *Item[T], config.deleteBuffer),
promotables: make(chan *Item[T], config.promoteBuffer),
}
for i := 0; i < int(config.buckets); i++ {
for i := 0; i < config.buckets; i++ {
c.buckets[i] = &layeredBucket[T]{
buckets: make(map[string]*bucket[T]),
}
@@ -334,7 +334,7 @@ func (c *LayeredCache[T]) gc() int {
}
prev := node.Prev
item := node.Value
if c.tracking == false || atomic.LoadInt32(&item.refCount) == 0 {
if !c.tracking || atomic.LoadInt32(&item.refCount) == 0 {
c.bucket(item.group).delete(item.group, item.key)
c.size -= item.size
c.list.Remove(node)

View File

@@ -118,7 +118,6 @@ func Test_LayedCache_DeletesAFunc(t *testing.T) {
return key == "d"
}), 1)
assert.Equal(t, cache.ItemCount(), 3)
}
func Test_LayedCache_OnDeleteCallbackCalled(t *testing.T) {

View File

@@ -85,11 +85,3 @@ func assertList(t *testing.T, list *List[int], expected ...int) {
node = node.Prev
}
}
func listFromInts(ints ...int) *List[int] {
l := NewList[int]()
for i := len(ints) - 1; i >= 0; i-- {
l.Insert(ints[i])
}
return l
}