weaviate

Форк
0
197 строк · 6.8 Кб
1
//                           _       _
2
// __      _____  __ ___   ___  __ _| |_ ___
3
// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
4
//  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
5
//   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
6
//
7
//  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
8
//
9
//  CONTACT: hello@weaviate.io
10
//
11

12
package clients
13

14
import (
15
	"context"
16
	"net/http"
17
	"net/http/httptest"
18
	"regexp"
19
	"strings"
20
	"testing"
21
	"time"
22

23
	"github.com/sirupsen/logrus"
24
	"github.com/sirupsen/logrus/hooks/test"
25
	"github.com/stretchr/testify/assert"
26
	"github.com/stretchr/testify/require"
27
)
28

29
func TestWaitForStartup(t *testing.T) {
30
	t.Run("when common server is immediately ready", func(t *testing.T) {
31
		server := httptest.NewServer(&testReadyHandler{t: t})
32
		defer server.Close()
33
		v := New(server.URL, server.URL, 0, nullLogger())
34
		err := v.WaitForStartup(context.Background(), 150*time.Millisecond)
35

36
		assert.Nil(t, err)
37
	})
38

39
	t.Run("when passage and query servers are immediately ready", func(t *testing.T) {
40
		serverPassage := httptest.NewServer(&testReadyHandler{t: t})
41
		serverQuery := httptest.NewServer(&testReadyHandler{t: t})
42
		defer serverPassage.Close()
43
		defer serverQuery.Close()
44
		v := New(serverPassage.URL, serverQuery.URL, 0, nullLogger())
45
		err := v.WaitForStartup(context.Background(), 150*time.Millisecond)
46

47
		assert.Nil(t, err)
48
	})
49

50
	t.Run("when common server is down", func(t *testing.T) {
51
		url := "http://nothing-running-at-this-url"
52
		v := New(url, url, 0, nullLogger())
53
		ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
54
		defer cancel()
55
		err := v.WaitForStartup(ctx, 50*time.Millisecond)
56

57
		require.NotNil(t, err, nullLogger())
58
		assert.Contains(t, err.Error(), "init context expired before remote was ready: send check ready request")
59
		assertContainsEither(t, err.Error(), "dial tcp", "context deadline exceeded")
60
		assert.NotContains(t, err.Error(), "[passage]")
61
		assert.NotContains(t, err.Error(), "[query]")
62
	})
63

64
	t.Run("when passage and query servers are down", func(t *testing.T) {
65
		urlPassage := "http://nothing-running-at-this-url"
66
		urlQuery := "http://nothing-running-at-this-url-either"
67
		v := New(urlPassage, urlQuery, 0, nullLogger())
68
		ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
69
		defer cancel()
70
		err := v.WaitForStartup(ctx, 50*time.Millisecond)
71

72
		require.NotNil(t, err, nullLogger())
73
		assert.Contains(t, err.Error(), "[passage] init context expired before remote was ready: send check ready request")
74
		assert.Contains(t, err.Error(), "[query] init context expired before remote was ready: send check ready request")
75
		assertContainsEither(t, err.Error(), "dial tcp", "context deadline exceeded")
76
	})
77

78
	t.Run("when common server is alive, but not ready", func(t *testing.T) {
79
		server := httptest.NewServer(&testReadyHandler{
80
			t:         t,
81
			readyTime: time.Now().Add(time.Hour),
82
		})
83
		defer server.Close()
84
		v := New(server.URL, server.URL, 0, nullLogger())
85
		ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
86
		defer cancel()
87
		err := v.WaitForStartup(ctx, 50*time.Millisecond)
88

89
		require.NotNil(t, err)
90
		assert.Contains(t, err.Error(), "init context expired before remote was ready")
91
		assertContainsEither(t, err.Error(), "not ready: status 503", "context deadline exceeded")
92
		assert.NotContains(t, err.Error(), "[passage]")
93
		assert.NotContains(t, err.Error(), "[query]")
94
	})
95

96
	t.Run("when passage and query servers are alive, but not ready", func(t *testing.T) {
97
		rt := time.Now().Add(time.Hour)
98
		serverPassage := httptest.NewServer(&testReadyHandler{
99
			t:         t,
100
			readyTime: rt,
101
		})
102
		serverQuery := httptest.NewServer(&testReadyHandler{
103
			t:         t,
104
			readyTime: rt,
105
		})
106
		defer serverPassage.Close()
107
		defer serverQuery.Close()
108
		v := New(serverPassage.URL, serverQuery.URL, 0, nullLogger())
109
		ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
110
		defer cancel()
111
		err := v.WaitForStartup(ctx, 50*time.Millisecond)
112

113
		require.NotNil(t, err)
114
		assert.Contains(t, err.Error(), "[passage] init context expired before remote was ready")
115
		assert.Contains(t, err.Error(), "[query] init context expired before remote was ready")
116
		assertContainsEither(t, err.Error(), "not ready: status 503", "context deadline exceeded")
117
	})
118

119
	t.Run("when passage and query servers are alive, but query one is not ready", func(t *testing.T) {
120
		serverPassage := httptest.NewServer(&testReadyHandler{t: t})
121
		serverQuery := httptest.NewServer(&testReadyHandler{
122
			t:         t,
123
			readyTime: time.Now().Add(1 * time.Minute),
124
		})
125
		defer serverPassage.Close()
126
		defer serverQuery.Close()
127
		v := New(serverPassage.URL, serverQuery.URL, 0, nullLogger())
128
		ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
129
		defer cancel()
130
		err := v.WaitForStartup(ctx, 50*time.Millisecond)
131

132
		require.NotNil(t, err)
133
		assert.Contains(t, err.Error(), "[query] init context expired before remote was ready")
134
		assertContainsEither(t, err.Error(), "not ready: status 503", "context deadline exceeded")
135
		assert.NotContains(t, err.Error(), "[passage]")
136
	})
137

138
	t.Run("when common server is initially not ready, but then becomes ready", func(t *testing.T) {
139
		server := httptest.NewServer(&testReadyHandler{
140
			t:         t,
141
			readyTime: time.Now().Add(100 * time.Millisecond),
142
		})
143
		v := New(server.URL, server.URL, 0, nullLogger())
144
		defer server.Close()
145
		ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
146
		defer cancel()
147
		err := v.WaitForStartup(ctx, 50*time.Millisecond)
148

149
		require.Nil(t, err)
150
	})
151

152
	t.Run("when passage and query servers are initially not ready, but then become ready", func(t *testing.T) {
153
		serverPassage := httptest.NewServer(&testReadyHandler{
154
			t:         t,
155
			readyTime: time.Now().Add(100 * time.Millisecond),
156
		})
157
		serverQuery := httptest.NewServer(&testReadyHandler{
158
			t:         t,
159
			readyTime: time.Now().Add(150 * time.Millisecond),
160
		})
161
		defer serverPassage.Close()
162
		defer serverQuery.Close()
163
		v := New(serverPassage.URL, serverQuery.URL, 0, nullLogger())
164
		ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
165
		defer cancel()
166
		err := v.WaitForStartup(ctx, 50*time.Millisecond)
167

168
		require.Nil(t, err)
169
	})
170
}
171

172
type testReadyHandler struct {
173
	t *testing.T
174
	// the test handler will report as not ready before the time has passed
175
	readyTime time.Time
176
}
177

178
func (f *testReadyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
179
	assert.Equal(f.t, "/.well-known/ready", r.URL.String())
180
	assert.Equal(f.t, http.MethodGet, r.Method)
181

182
	if time.Since(f.readyTime) < 0 {
183
		w.WriteHeader(http.StatusServiceUnavailable)
184
	} else {
185
		w.WriteHeader(http.StatusNoContent)
186
	}
187
}
188

189
func nullLogger() logrus.FieldLogger {
190
	l, _ := test.NewNullLogger()
191
	return l
192
}
193

194
func assertContainsEither(t *testing.T, str string, contains ...string) {
195
	reg := regexp.MustCompile(strings.Join(contains, "|"))
196
	assert.Regexp(t, reg, str)
197
}
198

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.