@@ -13,6 +13,12 @@ const HTTP1: &[u8] = b"GET / HTTP/1.1\r\nhost: example.com\r\n\r\n";
13
13
const HTTP2 : & [ u8 ] = b"PRI * HTTP/2.0\r \n " ;
14
14
const NOT_HTTP : & [ u8 ] = b"foo\r \n bar\r \n blah\r \n " ;
15
15
16
+ const RESULTS_NOT_HTTP : & str = "results_total{result=\" not_http\" ,srv_group=\" policy.linkerd.io\" ,srv_kind=\" server\" ,srv_name=\" testsrv\" ,srv_port=\" 1000\" }" ;
17
+ const RESULTS_HTTP1 : & str = "results_total{result=\" http/1\" ,srv_group=\" policy.linkerd.io\" ,srv_kind=\" server\" ,srv_name=\" testsrv\" ,srv_port=\" 1000\" }" ;
18
+ const RESULTS_HTTP2 : & str = "results_total{result=\" http/2\" ,srv_group=\" policy.linkerd.io\" ,srv_kind=\" server\" ,srv_name=\" testsrv\" ,srv_port=\" 1000\" }" ;
19
+ const RESULTS_READ_TIMEOUT : & str = "results_total{result=\" read_timeout\" ,srv_group=\" policy.linkerd.io\" ,srv_kind=\" server\" ,srv_name=\" testsrv\" ,srv_port=\" 1000\" }" ;
20
+ const RESULTS_ERROR : & str = "results_total{result=\" error\" ,srv_group=\" policy.linkerd.io\" ,srv_kind=\" server\" ,srv_name=\" testsrv\" ,srv_port=\" 1000\" }" ;
21
+
16
22
fn authzs ( ) -> Arc < [ Authorization ] > {
17
23
Arc :: new ( [ Authorization {
18
24
authentication : Authentication :: Unauthenticated ,
@@ -41,6 +47,35 @@ fn allow(protocol: Protocol) -> AllowPolicy {
41
47
allow
42
48
}
43
49
50
+ macro_rules! assert_contains_metric {
51
+ ( $registry: expr, $metric: expr, $value: expr) => { {
52
+ let mut buf = String :: new( ) ;
53
+ prom:: encoding:: text:: encode_registry( & mut buf, $registry) . expect( "encode registry failed" ) ;
54
+ let lines = buf. split_terminator( '\n' ) . collect:: <Vec <_>>( ) ;
55
+ assert_eq!(
56
+ lines. iter( ) . find( |l| l. starts_with( $metric) ) ,
57
+ Some ( &&* format!( "{} {}" , $metric, $value) ) ,
58
+ "metric '{}' not found in:\n {:?}" ,
59
+ $metric,
60
+ buf
61
+ ) ;
62
+ } } ;
63
+ }
64
+
65
+ macro_rules! assert_not_contains_metric {
66
+ ( $registry: expr, $pattern: expr) => { {
67
+ let mut buf = String :: new( ) ;
68
+ prom:: encoding:: text:: encode_registry( & mut buf, $registry) . expect( "encode registry failed" ) ;
69
+ let lines = buf. split_terminator( '\n' ) . collect:: <Vec <_>>( ) ;
70
+ assert!(
71
+ !lines. iter( ) . any( |l| l. starts_with( $pattern) ) ,
72
+ "metric '{}' found in:\n {:?}" ,
73
+ $pattern,
74
+ buf
75
+ ) ;
76
+ } } ;
77
+ }
78
+
44
79
#[ tokio:: test( flavor = "current_thread" ) ]
45
80
async fn detect_tls_opaque ( ) {
46
81
let _trace = trace:: test:: trace_init ( ) ;
@@ -77,14 +112,21 @@ async fn detect_http_non_http() {
77
112
let ( ior, mut iow) = io:: duplex ( 100 ) ;
78
113
iow. write_all ( NOT_HTTP ) . await . unwrap ( ) ;
79
114
115
+ let mut registry = prom:: Registry :: default ( ) ;
80
116
inbound ( )
81
117
. with_stack ( new_panic ( "http stack must not be used" ) )
82
- . push_detect_http ( new_ok ( ) )
118
+ . push_detect_http ( super :: HttpDetectMetrics :: register ( & mut registry ) , new_ok ( ) )
83
119
. into_inner ( )
84
120
. new_service ( target)
85
121
. oneshot ( ior)
86
122
. await
87
123
. expect ( "should succeed" ) ;
124
+
125
+ assert_contains_metric ! ( & registry, RESULTS_NOT_HTTP , 1 ) ;
126
+ assert_contains_metric ! ( & registry, RESULTS_HTTP1 , 0 ) ;
127
+ assert_contains_metric ! ( & registry, RESULTS_HTTP2 , 0 ) ;
128
+ assert_contains_metric ! ( & registry, RESULTS_READ_TIMEOUT , 0 ) ;
129
+ assert_contains_metric ! ( & registry, RESULTS_ERROR , 0 ) ;
88
130
}
89
131
90
132
#[ tokio:: test( flavor = "current_thread" ) ]
@@ -108,14 +150,24 @@ async fn detect_http() {
108
150
let ( ior, mut iow) = io:: duplex ( 100 ) ;
109
151
iow. write_all ( HTTP1 ) . await . unwrap ( ) ;
110
152
153
+ let mut registry = prom:: Registry :: default ( ) ;
111
154
inbound ( )
112
155
. with_stack ( new_ok ( ) )
113
- . push_detect_http ( new_panic ( "tcp stack must not be used" ) )
156
+ . push_detect_http (
157
+ super :: HttpDetectMetrics :: register ( & mut registry) ,
158
+ new_panic ( "tcp stack must not be used" ) ,
159
+ )
114
160
. into_inner ( )
115
161
. new_service ( target)
116
162
. oneshot ( ior)
117
163
. await
118
164
. expect ( "should succeed" ) ;
165
+
166
+ assert_contains_metric ! ( & registry, RESULTS_NOT_HTTP , 0 ) ;
167
+ assert_contains_metric ! ( & registry, RESULTS_HTTP1 , 1 ) ;
168
+ assert_contains_metric ! ( & registry, RESULTS_HTTP2 , 0 ) ;
169
+ assert_contains_metric ! ( & registry, RESULTS_READ_TIMEOUT , 0 ) ;
170
+ assert_contains_metric ! ( & registry, RESULTS_ERROR , 0 ) ;
119
171
}
120
172
121
173
#[ tokio:: test( flavor = "current_thread" ) ]
@@ -134,14 +186,24 @@ async fn hinted_http1() {
134
186
let ( ior, mut iow) = io:: duplex ( 100 ) ;
135
187
iow. write_all ( HTTP1 ) . await . unwrap ( ) ;
136
188
189
+ let mut registry = prom:: Registry :: default ( ) ;
137
190
inbound ( )
138
191
. with_stack ( new_ok ( ) )
139
- . push_detect_http ( new_panic ( "tcp stack must not be used" ) )
192
+ . push_detect_http (
193
+ super :: HttpDetectMetrics :: register ( & mut registry) ,
194
+ new_panic ( "tcp stack must not be used" ) ,
195
+ )
140
196
. into_inner ( )
141
197
. new_service ( target)
142
198
. oneshot ( ior)
143
199
. await
144
200
. expect ( "should succeed" ) ;
201
+
202
+ assert_contains_metric ! ( & registry, RESULTS_NOT_HTTP , 0 ) ;
203
+ assert_contains_metric ! ( & registry, RESULTS_HTTP1 , 1 ) ;
204
+ assert_contains_metric ! ( & registry, RESULTS_HTTP2 , 0 ) ;
205
+ assert_contains_metric ! ( & registry, RESULTS_READ_TIMEOUT , 0 ) ;
206
+ assert_contains_metric ! ( & registry, RESULTS_ERROR , 0 ) ;
145
207
}
146
208
147
209
#[ tokio:: test( flavor = "current_thread" ) ]
@@ -160,14 +222,24 @@ async fn hinted_http1_supports_http2() {
160
222
let ( ior, mut iow) = io:: duplex ( 100 ) ;
161
223
iow. write_all ( HTTP2 ) . await . unwrap ( ) ;
162
224
225
+ let mut registry = prom:: Registry :: default ( ) ;
163
226
inbound ( )
164
227
. with_stack ( new_ok ( ) )
165
- . push_detect_http ( new_panic ( "tcp stack must not be used" ) )
228
+ . push_detect_http (
229
+ super :: HttpDetectMetrics :: register ( & mut registry) ,
230
+ new_panic ( "tcp stack must not be used" ) ,
231
+ )
166
232
. into_inner ( )
167
233
. new_service ( target)
168
234
. oneshot ( ior)
169
235
. await
170
236
. expect ( "should succeed" ) ;
237
+
238
+ assert_contains_metric ! ( & registry, RESULTS_NOT_HTTP , 0 ) ;
239
+ assert_contains_metric ! ( & registry, RESULTS_HTTP1 , 0 ) ;
240
+ assert_contains_metric ! ( & registry, RESULTS_HTTP2 , 1 ) ;
241
+ assert_contains_metric ! ( & registry, RESULTS_READ_TIMEOUT , 0 ) ;
242
+ assert_contains_metric ! ( & registry, RESULTS_ERROR , 0 ) ;
171
243
}
172
244
173
245
#[ tokio:: test( flavor = "current_thread" ) ]
@@ -185,14 +257,25 @@ async fn hinted_http2() {
185
257
186
258
let ( ior, _) = io:: duplex ( 100 ) ;
187
259
260
+ let mut registry = prom:: Registry :: default ( ) ;
188
261
inbound ( )
189
262
. with_stack ( new_ok ( ) )
190
- . push_detect_http ( new_panic ( "tcp stack must not be used" ) )
263
+ . push_detect_http (
264
+ super :: HttpDetectMetrics :: register ( & mut registry) ,
265
+ new_panic ( "tcp stack must not be used" ) ,
266
+ )
191
267
. into_inner ( )
192
268
. new_service ( target)
193
269
. oneshot ( ior)
194
270
. await
195
271
. expect ( "should succeed" ) ;
272
+
273
+ // No detection is performed when HTTP/2 is hinted, so no metrics are recorded.
274
+ assert_not_contains_metric ! ( & registry, RESULTS_NOT_HTTP ) ;
275
+ assert_not_contains_metric ! ( & registry, RESULTS_HTTP1 ) ;
276
+ assert_not_contains_metric ! ( & registry, RESULTS_HTTP2 ) ;
277
+ assert_not_contains_metric ! ( & registry, RESULTS_READ_TIMEOUT ) ;
278
+ assert_not_contains_metric ! ( & registry, RESULTS_ERROR ) ;
196
279
}
197
280
198
281
fn client_id ( ) -> tls:: ClientId {
@@ -210,7 +293,11 @@ fn orig_dst_addr() -> OrigDstAddr {
210
293
}
211
294
212
295
fn inbound ( ) -> Inbound < ( ) > {
213
- Inbound :: new ( test_util:: default_config ( ) , test_util:: runtime ( ) . 0 )
296
+ Inbound :: new (
297
+ test_util:: default_config ( ) ,
298
+ test_util:: runtime ( ) . 0 ,
299
+ & mut Default :: default ( ) ,
300
+ )
214
301
}
215
302
216
303
fn new_panic < T , I : ' static > ( msg : & ' static str ) -> svc:: ArcNewTcp < T , I > {
0 commit comments