Commit 9e96ee75 authored by Kamil Trzcinski's avatar Kamil Trzcinski

Improve readability of tests

parent 3f90655c
...@@ -13,6 +13,12 @@ gitlab-workhorse'][brief-history-blog]. ...@@ -13,6 +13,12 @@ gitlab-workhorse'][brief-history-blog].
gitlab-workhorse [OPTIONS] gitlab-workhorse [OPTIONS]
Options: Options:
-apiLimit uint
Number of API requests allowed at single time
-apiQueueDuration duration
Maximum queueing duration of requests (default 30s)
-apiQueueLimit uint
Number of API requests allowed to be queued
-authBackend string -authBackend string
Authentication/authorization backend (default "http://localhost:8080") Authentication/authorization backend (default "http://localhost:8080")
-authSocket string -authSocket string
......
...@@ -23,7 +23,7 @@ type Queue struct { ...@@ -23,7 +23,7 @@ type Queue struct {
func NewQueue(limit, queueLimit uint) *Queue { func NewQueue(limit, queueLimit uint) *Queue {
return &Queue{ return &Queue{
busyCh: make(chan struct{}, limit), busyCh: make(chan struct{}, limit),
waitingCh: make(chan struct{}, limit+queueLimit), waitingCh: make(chan struct{}, queueLimit),
} }
} }
...@@ -41,9 +41,7 @@ func (s *Queue) Acquire(timeout time.Duration) (err error) { ...@@ -41,9 +41,7 @@ func (s *Queue) Acquire(timeout time.Duration) (err error) {
} }
defer func() { defer func() {
if err != nil { <-s.waitingCh
<-s.waitingCh
}
}() }()
// fast path: push item to current processed items (non-blocking) // fast path: push item to current processed items (non-blocking)
...@@ -71,6 +69,5 @@ func (s *Queue) Acquire(timeout time.Duration) (err error) { ...@@ -71,6 +69,5 @@ func (s *Queue) Acquire(timeout time.Duration) (err error) {
// It triggers next request to be processed if it's in queue // It triggers next request to be processed if it's in queue
func (s *Queue) Release() { func (s *Queue) Release() {
// dequeue from queue to allow next request to be processed // dequeue from queue to allow next request to be processed
<-s.waitingCh
<-s.busyCh <-s.busyCh
} }
...@@ -12,14 +12,14 @@ var httpHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) ...@@ -12,14 +12,14 @@ var httpHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request)
fmt.Fprintln(w, "OK") fmt.Fprintln(w, "OK")
}) })
func slowHttpHandler(closeCh chan struct{}) http.Handler { func pausedHttpHandler(pauseCh chan struct{}) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
<-closeCh <-pauseCh
fmt.Fprintln(w, "OK") fmt.Fprintln(w, "OK")
}) })
} }
func TestQueueRequests(t *testing.T) { func TestNormalRequestProcessing(t *testing.T) {
w := httptest.NewRecorder() w := httptest.NewRecorder()
h := QueueRequests(httpHandler, 1, 1, time.Second) h := QueueRequests(httpHandler, 1, 1, time.Second)
h.ServeHTTP(w, nil) h.ServeHTTP(w, nil)
...@@ -28,28 +28,34 @@ func TestQueueRequests(t *testing.T) { ...@@ -28,28 +28,34 @@ func TestQueueRequests(t *testing.T) {
} }
} }
// testSlowRequestProcessing creates a new queue,
// then it runs a number of requests that are going through queue,
// we return the response of first finished request,
// where status of request can be 200, 429 or 503
func testSlowRequestProcessing(count, limit, queueLimit uint, queueTimeout time.Duration) *httptest.ResponseRecorder { func testSlowRequestProcessing(count, limit, queueLimit uint, queueTimeout time.Duration) *httptest.ResponseRecorder {
closeCh := make(chan struct{}) pauseCh := make(chan struct{})
defer close(closeCh) defer close(pauseCh)
handler := QueueRequests(slowHttpHandler(closeCh), limit, queueLimit, queueTimeout) handler := QueueRequests(pausedHttpHandler(pauseCh), limit, queueLimit, queueTimeout)
respCh := make(chan *httptest.ResponseRecorder, count) respCh := make(chan *httptest.ResponseRecorder, count)
// queue requests to use up the queue // queue requests to use up the queue
for count > 0 { for i := 0; i < count; i++ {
go func() { go func() {
w := httptest.NewRecorder() w := httptest.NewRecorder()
handler.ServeHTTP(w, nil) handler.ServeHTTP(w, nil)
respCh <- w respCh <- w
}() }()
count--
} }
// dequeue first request // dequeue first request
return <-respCh return <-respCh
} }
// TestQueueingTimeout performs 2 requests
// the queue limit and length is 1,
// the second request gets timed-out
func TestQueueingTimeout(t *testing.T) { func TestQueueingTimeout(t *testing.T) {
w := testSlowRequestProcessing(2, 1, 1, time.Microsecond) w := testSlowRequestProcessing(2, 1, 1, time.Microsecond)
...@@ -58,7 +64,10 @@ func TestQueueingTimeout(t *testing.T) { ...@@ -58,7 +64,10 @@ func TestQueueingTimeout(t *testing.T) {
} }
} }
func TestQueuedRequests(t *testing.T) { // TestQueueingTooManyRequests performs 3 requests
// the queue limit and length is 1,
// so the third request has to be rejected with 429
func TestQueueingTooManyRequests(t *testing.T) {
w := testSlowRequestProcessing(3, 1, 1, time.Minute) w := testSlowRequestProcessing(3, 1, 1, time.Minute)
if w.Code != 429 { if w.Code != 429 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment