gitlab-org--gitlab-foss/workhorse/internal/builds/register_test.go

108 lines
3.3 KiB
Go

package builds
import (
"bytes"
"errors"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/redis"
)
const upstreamResponseCode = 999
func echoRequest(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(upstreamResponseCode)
io.Copy(rw, req.Body)
}
var echoRequestFunc = http.HandlerFunc(echoRequest)
func expectHandlerWithWatcher(t *testing.T, watchHandler WatchKeyHandler, data string, contentType string, expectedHttpStatus int, msgAndArgs ...interface{}) {
h := RegisterHandler(echoRequestFunc, watchHandler, time.Second)
rw := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/", bytes.NewBufferString(data))
req.Header.Set("Content-Type", contentType)
h.ServeHTTP(rw, req)
require.Equal(t, expectedHttpStatus, rw.Code, msgAndArgs...)
}
func expectHandler(t *testing.T, data string, contentType string, expectedHttpStatus int, msgAndArgs ...interface{}) {
expectHandlerWithWatcher(t, nil, data, contentType, expectedHttpStatus, msgAndArgs...)
}
func TestRegisterHandlerLargeBody(t *testing.T) {
data := strings.Repeat(".", maxRegisterBodySize+5)
expectHandler(t, data, "application/json", http.StatusRequestEntityTooLarge,
"rejects body with entity too large")
}
func TestRegisterHandlerInvalidRunnerRequest(t *testing.T) {
expectHandler(t, "invalid content", "text/plain", upstreamResponseCode,
"proxies request to upstream")
}
func TestRegisterHandlerInvalidJsonPayload(t *testing.T) {
expectHandler(t, `{[`, "application/json", upstreamResponseCode,
"fails on parsing body and proxies request to upstream")
}
func TestRegisterHandlerMissingData(t *testing.T) {
testCases := []string{
`{"token":"token"}`,
`{"last_update":"data"}`,
}
for _, testCase := range testCases {
expectHandler(t, testCase, "application/json", upstreamResponseCode,
"fails on argument validation and proxies request to upstream")
}
}
func expectWatcherToBeExecuted(t *testing.T, watchKeyStatus redis.WatchKeyStatus, watchKeyError error,
httpStatus int, msgAndArgs ...interface{}) {
executed := false
watchKeyHandler := func(key, value string, timeout time.Duration) (redis.WatchKeyStatus, error) {
executed = true
return watchKeyStatus, watchKeyError
}
parsableData := `{"token":"token","last_update":"last_update"}`
expectHandlerWithWatcher(t, watchKeyHandler, parsableData, "application/json", httpStatus, msgAndArgs...)
require.True(t, executed, msgAndArgs...)
}
func TestRegisterHandlerWatcherError(t *testing.T) {
expectWatcherToBeExecuted(t, redis.WatchKeyStatusNoChange, errors.New("redis connection"),
upstreamResponseCode, "proxies data to upstream")
}
func TestRegisterHandlerWatcherAlreadyChanged(t *testing.T) {
expectWatcherToBeExecuted(t, redis.WatchKeyStatusAlreadyChanged, nil,
upstreamResponseCode, "proxies data to upstream")
}
func TestRegisterHandlerWatcherSeenChange(t *testing.T) {
expectWatcherToBeExecuted(t, redis.WatchKeyStatusSeenChange, nil,
http.StatusNoContent)
}
func TestRegisterHandlerWatcherTimeout(t *testing.T) {
expectWatcherToBeExecuted(t, redis.WatchKeyStatusTimeout, nil,
http.StatusNoContent)
}
func TestRegisterHandlerWatcherNoChange(t *testing.T) {
expectWatcherToBeExecuted(t, redis.WatchKeyStatusNoChange, nil,
http.StatusNoContent)
}