Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2019-11-13 15:06:54 +0300
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2019-11-13 15:06:54 +0300
commit9452eadb1915363a08fb5e9dc0367af6107dfb08 (patch)
treeeb53789de90a5e4bb9c93db20712036656efa8b3 /internal/source/gitlab/cache/cache_test.go
parent308e11bf576ed6b94db12230e73607fdd438c1c2 (diff)
Add more concurrency tests for gitlab source cache
Diffstat (limited to 'internal/source/gitlab/cache/cache_test.go')
-rw-r--r--internal/source/gitlab/cache/cache_test.go75
1 files changed, 63 insertions, 12 deletions
diff --git a/internal/source/gitlab/cache/cache_test.go b/internal/source/gitlab/cache/cache_test.go
index d0fbd4e1..5a885279 100644
--- a/internal/source/gitlab/cache/cache_test.go
+++ b/internal/source/gitlab/cache/cache_test.go
@@ -12,33 +12,44 @@ import (
)
type client struct {
+ started uint64
resolutions uint64
+ bootup chan uint64
domain chan string
failure error
status int
}
func (c *client) Resolve(ctx context.Context, _ string) Lookup {
- atomic.AddUint64(&c.resolutions, 1)
+ var domain Domain
+
+ c.bootup <- atomic.AddUint64(&c.started, 1)
+ defer atomic.AddUint64(&c.resolutions, 1)
if c.status == 0 {
c.status = 200
}
- if c.failure != nil {
- return Lookup{Domain: Domain{}, Status: c.status, Error: c.failure}
+ if c.failure == nil {
+ domain = Domain{Name: <-c.domain}
}
- return Lookup{Domain: Domain{Name: <-c.domain}, Status: c.status, Error: nil}
+ return Lookup{Domain: domain, Status: c.status, Error: c.failure}
}
func withTestCache(config resolverConfig, block func(*Cache, *client)) {
- var resolver *client
+ var chanSize int
if config.buffered {
- resolver = &client{domain: make(chan string, 1), failure: config.failure}
+ chanSize = 1
} else {
- resolver = &client{domain: make(chan string), failure: config.failure}
+ chanSize = 0
+ }
+
+ resolver := &client{
+ domain: make(chan string, chanSize),
+ bootup: make(chan uint64, 100),
+ failure: config.failure,
}
cache := NewCache(resolver)
@@ -46,7 +57,7 @@ func withTestCache(config resolverConfig, block func(*Cache, *client)) {
block(cache, resolver)
}
-func (cache *Cache) withTestEntry(config entryConfig, block func()) {
+func (cache *Cache) withTestEntry(config entryConfig, block func(*Entry)) {
domain := "my.gitlab.com"
if len(config.domain) > 0 {
@@ -65,7 +76,7 @@ func (cache *Cache) withTestEntry(config entryConfig, block func()) {
entry.created = time.Now().Add(-time.Hour)
}
- block()
+ block(entry)
}
type resolverConfig struct {
@@ -119,7 +130,7 @@ func TestResolve(t *testing.T) {
t.Run("when item is in short cache", func(t *testing.T) {
withTestCache(resolverConfig{}, func(cache *Cache, resolver *client) {
- cache.withTestEntry(entryConfig{expired: false, retrieved: true}, func() {
+ cache.withTestEntry(entryConfig{expired: false, retrieved: true}, func(*Entry) {
lookup := cache.Resolve(context.Background(), "my.gitlab.com")
assert.Equal(t, "my.gitlab.com", lookup.Domain.Name)
@@ -128,9 +139,32 @@ func TestResolve(t *testing.T) {
})
})
+ t.Run("when a non-retrieved new item is in short cache", func(t *testing.T) {
+ withTestCache(resolverConfig{}, func(cache *Cache, resolver *client) {
+ cache.withTestEntry(entryConfig{expired: false, retrieved: false}, func(*Entry) {
+ lookup := make(chan *Lookup, 1)
+
+ go func() {
+ lookup <- cache.Resolve(context.Background(), "my.gitlab.com")
+ }()
+
+ <-resolver.bootup
+
+ assert.Equal(t, uint64(1), resolver.started)
+ assert.Equal(t, uint64(0), resolver.resolutions)
+
+ resolver.domain <- "my.gitlab.com"
+ <-lookup
+
+ assert.Equal(t, uint64(1), resolver.started)
+ assert.Equal(t, uint64(1), resolver.resolutions)
+ })
+ })
+ })
+
t.Run("when item is in long cache only", func(t *testing.T) {
withTestCache(resolverConfig{}, func(cache *Cache, resolver *client) {
- cache.withTestEntry(entryConfig{expired: true, retrieved: true}, func() {
+ cache.withTestEntry(entryConfig{expired: true, retrieved: true}, func(*Entry) {
lookup := cache.Resolve(context.Background(), "my.gitlab.com")
assert.Equal(t, "my.gitlab.com", lookup.Domain.Name)
@@ -144,7 +178,7 @@ func TestResolve(t *testing.T) {
t.Run("when item in long cache is requested multiple times", func(t *testing.T) {
withTestCache(resolverConfig{}, func(cache *Cache, resolver *client) {
- cache.withTestEntry(entryConfig{expired: true, retrieved: true}, func() {
+ cache.withTestEntry(entryConfig{expired: true, retrieved: true}, func(*Entry) {
cache.Resolve(context.Background(), "my.gitlab.com")
cache.Resolve(context.Background(), "my.gitlab.com")
cache.Resolve(context.Background(), "my.gitlab.com")
@@ -182,6 +216,7 @@ func TestResolve(t *testing.T) {
t.Run("when retrieval failed because of an internal context timeout", func(t *testing.T) {
retrievalTimeout = 0
+ defer func() { retrievalTimeout = 5 * time.Second }()
withTestCache(resolverConfig{}, func(cache *Cache, resolver *client) {
lookup := cache.Resolve(context.Background(), "my.gitlab.com")
@@ -190,4 +225,20 @@ func TestResolve(t *testing.T) {
assert.EqualError(t, lookup.Error, "context timeout")
})
})
+
+ t.Run("when cache entry is evicted from cache", func(t *testing.T) {
+ withTestCache(resolverConfig{}, func(cache *Cache, resolver *client) {
+ cache.withTestEntry(entryConfig{expired: false, retrieved: false}, func(entry *Entry) {
+ lookup := make(chan *Lookup, 1)
+ go func() { lookup <- cache.Resolve(context.Background(), "my.gitlab.com") }()
+
+ cache.store.ReplaceOrCreate(context.Background(), "my.gitlab.com")
+
+ resolver.domain <- "my.gitlab.com"
+ <-lookup
+
+ assert.EqualError(t, entry.ctx.Err(), "context canceled")
+ })
+ })
+ })
}