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

register_test.go « builds « internal « workhorse - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d5cbebd500bf6bcb8d8a3ab2c0c50fd537028e96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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)
}

func TestReadRequestBody(t *testing.T) {
	data := []byte("123456")
	rw := httptest.NewRecorder()
	req, _ := http.NewRequest("POST", "/test", bytes.NewBuffer(data))

	result, err := readRequestBody(rw, req, 1000)
	require.NoError(t, err)
	require.Equal(t, data, result)
}

func TestReadRequestBodyLimit(t *testing.T) {
	data := []byte("123456")
	rw := httptest.NewRecorder()
	req, _ := http.NewRequest("POST", "/test", bytes.NewBuffer(data))

	_, err := readRequestBody(rw, req, 2)
	require.Error(t, err)
}

func TestApplicationJson(t *testing.T) {
	req, _ := http.NewRequest("POST", "/test", nil)
	req.Header.Set("Content-Type", "application/json")

	require.True(t, isApplicationJson(req), "expected to match 'application/json' as 'application/json'")

	req.Header.Set("Content-Type", "application/json; charset=utf-8")
	require.True(t, isApplicationJson(req), "expected to match 'application/json; charset=utf-8' as 'application/json'")

	req.Header.Set("Content-Type", "text/plain")
	require.False(t, isApplicationJson(req), "expected not to match 'text/plain' as 'application/json'")
}

func TestCloneRequestWithBody(t *testing.T) {
	input := []byte("test")
	newInput := []byte("new body")
	req, _ := http.NewRequest("POST", "/test", bytes.NewBuffer(input))
	newReq := cloneRequestWithNewBody(req, newInput)

	require.NotEqual(t, req, newReq)
	require.NotEqual(t, req.Body, newReq.Body)
	require.NotEqual(t, len(newInput), newReq.ContentLength)

	var buffer bytes.Buffer
	io.Copy(&buffer, newReq.Body)
	require.Equal(t, newInput, buffer.Bytes())
}