@@ -12,7 +12,6 @@ import (
12
12
"net"
13
13
"net/http"
14
14
"net/http/httptest"
15
- "net/url"
16
15
"strings"
17
16
"sync"
18
17
"testing"
@@ -33,6 +32,7 @@ import (
33
32
"golang.org/x/net/http2/h2c"
34
33
"google.golang.org/grpc"
35
34
"google.golang.org/grpc/credentials/insecure"
35
+ "google.golang.org/grpc/test/bufconn"
36
36
37
37
"github.com/grafana/pyroscope/pkg/frontend/frontendpb"
38
38
"github.com/grafana/pyroscope/pkg/scheduler/schedulerpb"
@@ -44,30 +44,50 @@ import (
44
44
45
45
const testMaxOutstandingPerTenant = 5
46
46
47
- func setupScheduler (t * testing.T , reg prometheus.Registerer , opts ... connect.HandlerOption ) (* Scheduler , schedulerpb.SchedulerForFrontendClient , schedulerpb.SchedulerForQuerierClient ) {
48
- cfg := Config {}
47
+ type schedulerArgs struct {
48
+ reg prometheus.Registerer
49
+ handlerOpts []connect.HandlerOption
50
+ dialOpts []grpc.DialOption
51
+ }
52
+
53
+ func setupScheduler (t * testing.T , args schedulerArgs ) (* Scheduler , schedulerpb.SchedulerForFrontendClient , schedulerpb.SchedulerForQuerierClient ) {
54
+ cfg := Config {
55
+ DialOpts : args .dialOpts ,
56
+ }
49
57
flagext .DefaultValues (& cfg )
50
58
cfg .MaxOutstandingPerTenant = testMaxOutstandingPerTenant
51
59
52
- s , err := NewScheduler (cfg , & limits {queriers : 2 }, log .NewNopLogger (), reg )
60
+ s , err := NewScheduler (cfg , & limits {queriers : 2 }, log .NewNopLogger (), args .reg )
61
+
53
62
require .NoError (t , err )
54
63
55
64
server := httptest .NewUnstartedServer (nil )
56
65
mux := mux .NewRouter ()
57
66
server .Config .Handler = h2c .NewHandler (mux , & http2.Server {})
67
+
68
+ // Use an in-memory network connection to avoid test flake from network access.
69
+ listener := bufconn .Listen (256 << 10 )
70
+ server .Listener = listener
71
+
58
72
server .Start ()
59
- u , err := url .Parse (server .URL )
60
73
require .NoError (t , err )
61
- schedulerpbconnect .RegisterSchedulerForFrontendHandler (mux , s , opts ... )
62
- schedulerpbconnect .RegisterSchedulerForQuerierHandler (mux , s , opts ... )
74
+ schedulerpbconnect .RegisterSchedulerForFrontendHandler (mux , s , args . handlerOpts ... )
75
+ schedulerpbconnect .RegisterSchedulerForQuerierHandler (mux , s , args . handlerOpts ... )
63
76
64
77
require .NoError (t , services .StartAndAwaitRunning (context .Background (), s ))
65
78
t .Cleanup (func () {
66
79
_ = services .StopAndAwaitTerminated (context .Background (), s )
67
80
server .Close ()
68
81
})
69
82
70
- c , err := grpc .Dial (u .Hostname ()+ ":" + u .Port (), grpc .WithTransportCredentials (insecure .NewCredentials ()))
83
+ c , err := grpc .NewClient (
84
+ // Target address is irrelevant as we're using an in-memory connection.
85
+ // We simply need the DNS resolution to succeed.
86
+ "localhost:3030" ,
87
+ grpc .WithContextDialer (func (context.Context , string ) (net.Conn , error ) { return listener .Dial () }),
88
+ grpc .WithTransportCredentials (insecure .NewCredentials ()),
89
+ )
90
+
71
91
require .NoError (t , err )
72
92
73
93
t .Cleanup (func () {
@@ -77,9 +97,14 @@ func setupScheduler(t *testing.T, reg prometheus.Registerer, opts ...connect.Han
77
97
return s , schedulerpb .NewSchedulerForFrontendClient (c ), schedulerpb .NewSchedulerForQuerierClient (c )
78
98
}
79
99
80
- func Test_Timeout (t * testing.T ) {
81
- s , _ , querierClient := setupScheduler (t , nil , connect .WithInterceptors (util .WithTimeout (1 * time .Second )))
100
+ func setupSchedulerWithHandlerOpts (t * testing.T , handlerOpts ... connect.HandlerOption ) (* Scheduler , schedulerpb.SchedulerForFrontendClient , schedulerpb.SchedulerForQuerierClient ) {
101
+ return setupScheduler (t , schedulerArgs {
102
+ handlerOpts : handlerOpts ,
103
+ })
104
+ }
82
105
106
+ func Test_Timeout (t * testing.T ) {
107
+ s , _ , querierClient := setupSchedulerWithHandlerOpts (t , connect .WithInterceptors (util .WithTimeout (1 * time .Second )))
83
108
ql , err := querierClient .QuerierLoop (context .Background ())
84
109
require .NoError (t , err )
85
110
require .NoError (t , ql .Send (& schedulerpb.QuerierToScheduler {QuerierID : "querier-1" }))
@@ -88,7 +113,7 @@ func Test_Timeout(t *testing.T) {
88
113
}
89
114
90
115
func TestSchedulerBasicEnqueue (t * testing.T ) {
91
- scheduler , frontendClient , querierClient := setupScheduler (t , nil )
116
+ scheduler , frontendClient , querierClient := setupScheduler (t , schedulerArgs {} )
92
117
93
118
frontendLoop := initFrontendLoop (t , frontendClient , "frontend-12345" )
94
119
frontendToScheduler (t , frontendLoop , & schedulerpb.FrontendToScheduler {
@@ -116,7 +141,7 @@ func TestSchedulerBasicEnqueue(t *testing.T) {
116
141
}
117
142
118
143
func TestSchedulerEnqueueWithCancel (t * testing.T ) {
119
- scheduler , frontendClient , querierClient := setupScheduler (t , nil )
144
+ scheduler , frontendClient , querierClient := setupScheduler (t , schedulerArgs {} )
120
145
121
146
frontendLoop := initFrontendLoop (t , frontendClient , "frontend-12345" )
122
147
frontendToScheduler (t , frontendLoop , & schedulerpb.FrontendToScheduler {
@@ -146,7 +171,7 @@ func initQuerierLoop(t *testing.T, querierClient schedulerpb.SchedulerForQuerier
146
171
}
147
172
148
173
func TestSchedulerEnqueueByMultipleFrontendsWithCancel (t * testing.T ) {
149
- scheduler , frontendClient , querierClient := setupScheduler (t , nil )
174
+ scheduler , frontendClient , querierClient := setupScheduler (t , schedulerArgs {} )
150
175
151
176
frontendLoop1 := initFrontendLoop (t , frontendClient , "frontend-1" )
152
177
frontendLoop2 := initFrontendLoop (t , frontendClient , "frontend-2" )
@@ -187,7 +212,7 @@ func TestSchedulerEnqueueByMultipleFrontendsWithCancel(t *testing.T) {
187
212
}
188
213
189
214
func TestSchedulerEnqueueWithFrontendDisconnect (t * testing.T ) {
190
- scheduler , frontendClient , querierClient := setupScheduler (t , nil )
215
+ scheduler , frontendClient , querierClient := setupScheduler (t , schedulerArgs {} )
191
216
192
217
frontendLoop := initFrontendLoop (t , frontendClient , "frontend-12345" )
193
218
frontendToScheduler (t , frontendLoop , & schedulerpb.FrontendToScheduler {
@@ -217,7 +242,7 @@ func TestSchedulerEnqueueWithFrontendDisconnect(t *testing.T) {
217
242
}
218
243
219
244
func TestCancelRequestInProgress (t * testing.T ) {
220
- scheduler , frontendClient , querierClient := setupScheduler (t , nil )
245
+ scheduler , frontendClient , querierClient := setupScheduler (t , schedulerArgs {} )
221
246
222
247
frontendLoop := initFrontendLoop (t , frontendClient , "frontend-12345" )
223
248
frontendToScheduler (t , frontendLoop , & schedulerpb.FrontendToScheduler {
@@ -249,7 +274,7 @@ func TestCancelRequestInProgress(t *testing.T) {
249
274
}
250
275
251
276
func TestTracingContext (t * testing.T ) {
252
- scheduler , frontendClient , _ := setupScheduler (t , nil )
277
+ scheduler , frontendClient , _ := setupScheduler (t , schedulerArgs {} )
253
278
254
279
frontendLoop := initFrontendLoop (t , frontendClient , "frontend-12345" )
255
280
@@ -280,7 +305,7 @@ func TestTracingContext(t *testing.T) {
280
305
}
281
306
282
307
func TestSchedulerShutdown_FrontendLoop (t * testing.T ) {
283
- scheduler , frontendClient , _ := setupScheduler (t , nil )
308
+ scheduler , frontendClient , _ := setupScheduler (t , schedulerArgs {} )
284
309
285
310
frontendLoop := initFrontendLoop (t , frontendClient , "frontend-12345" )
286
311
@@ -301,7 +326,7 @@ func TestSchedulerShutdown_FrontendLoop(t *testing.T) {
301
326
}
302
327
303
328
func TestSchedulerShutdown_QuerierLoop (t * testing.T ) {
304
- scheduler , frontendClient , querierClient := setupScheduler (t , nil )
329
+ scheduler , frontendClient , querierClient := setupScheduler (t , schedulerArgs {} )
305
330
306
331
frontendLoop := initFrontendLoop (t , frontendClient , "frontend-12345" )
307
332
frontendToScheduler (t , frontendLoop , & schedulerpb.FrontendToScheduler {
@@ -333,7 +358,7 @@ func TestSchedulerShutdown_QuerierLoop(t *testing.T) {
333
358
}
334
359
335
360
func TestSchedulerMaxOutstandingRequests (t * testing.T ) {
336
- _ , frontendClient , _ := setupScheduler (t , nil )
361
+ _ , frontendClient , _ := setupScheduler (t , schedulerArgs {} )
337
362
338
363
for i := 0 ; i < testMaxOutstandingPerTenant ; i ++ {
339
364
// coming from different frontends
@@ -365,32 +390,32 @@ func TestSchedulerMaxOutstandingRequests(t *testing.T) {
365
390
}
366
391
367
392
func TestSchedulerForwardsErrorToFrontend (t * testing.T ) {
368
- _ , frontendClient , querierClient := setupScheduler (t , nil )
393
+
394
+ l := bufconn .Listen (256 << 10 )
395
+ _ , frontendClient , querierClient := setupScheduler (t , schedulerArgs {
396
+ // Have the scheduler use the in-memory connection to call back into the frontend.
397
+ dialOpts : []grpc.DialOption {
398
+ grpc .WithContextDialer (func (context.Context , string ) (net.Conn , error ) { return l .Dial () }),
399
+ },
400
+ })
369
401
370
402
fm := & frontendMock {resp : map [uint64 ]* httpgrpc.HTTPResponse {}}
371
- frontendAddress := ""
372
403
373
404
// Setup frontend grpc server
374
405
{
375
406
frontendGrpcServer := grpc .NewServer ()
376
407
frontendpb .RegisterFrontendForQuerierServer (frontendGrpcServer , fm )
377
408
378
- l , err := net .Listen ("tcp" , "127.0.0.1:" )
379
- require .NoError (t , err )
380
-
381
- frontendAddress = l .Addr ().String ()
382
-
383
409
go func () {
384
410
_ = frontendGrpcServer .Serve (l )
385
411
}()
386
-
387
412
t .Cleanup (func () {
388
413
_ = l .Close ()
389
414
})
390
415
}
391
416
392
417
// After preparations, start frontend and querier.
393
- frontendLoop := initFrontendLoop (t , frontendClient , frontendAddress )
418
+ frontendLoop := initFrontendLoop (t , frontendClient , "irrelevant://because-we-use-in-memory-connection" )
394
419
frontendToScheduler (t , frontendLoop , & schedulerpb.FrontendToScheduler {
395
420
Type : schedulerpb .FrontendToSchedulerType_ENQUEUE ,
396
421
QueryID : 100 ,
@@ -427,7 +452,7 @@ func TestSchedulerForwardsErrorToFrontend(t *testing.T) {
427
452
func TestSchedulerMetrics (t * testing.T ) {
428
453
reg := prometheus .NewPedanticRegistry ()
429
454
430
- scheduler , frontendClient , _ := setupScheduler (t , reg )
455
+ scheduler , frontendClient , _ := setupScheduler (t , schedulerArgs { reg : reg } )
431
456
432
457
frontendLoop := initFrontendLoop (t , frontendClient , "frontend-12345" )
433
458
frontendToScheduler (t , frontendLoop , & schedulerpb.FrontendToScheduler {
0 commit comments