spikard 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/spikard_rb/Cargo.toml +1 -1
- data/lib/spikard/grpc.rb +5 -5
- data/lib/spikard/version.rb +1 -1
- data/vendor/crates/spikard-bindings-shared/Cargo.toml +1 -1
- data/vendor/crates/spikard-bindings-shared/src/grpc_metadata.rs +3 -3
- data/vendor/crates/spikard-core/Cargo.toml +1 -1
- data/vendor/crates/spikard-core/src/metadata.rs +3 -14
- data/vendor/crates/spikard-http/Cargo.toml +1 -1
- data/vendor/crates/spikard-http/src/grpc/mod.rs +1 -1
- data/vendor/crates/spikard-http/src/grpc/service.rs +11 -11
- data/vendor/crates/spikard-http/src/grpc/streaming.rs +5 -1
- data/vendor/crates/spikard-http/src/server/grpc_routing.rs +59 -20
- data/vendor/crates/spikard-http/src/server/routing_factory.rs +179 -201
- data/vendor/crates/spikard-http/tests/common/grpc_helpers.rs +49 -60
- data/vendor/crates/spikard-http/tests/common/handlers.rs +5 -5
- data/vendor/crates/spikard-http/tests/common/mod.rs +7 -8
- data/vendor/crates/spikard-http/tests/common/test_builders.rs +14 -19
- data/vendor/crates/spikard-http/tests/grpc_error_handling_test.rs +68 -69
- data/vendor/crates/spikard-http/tests/grpc_integration_test.rs +1 -3
- data/vendor/crates/spikard-http/tests/grpc_metadata_test.rs +98 -84
- data/vendor/crates/spikard-http/tests/grpc_server_integration.rs +76 -57
- data/vendor/crates/spikard-rb/Cargo.toml +1 -1
- data/vendor/crates/spikard-rb/src/grpc/handler.rs +30 -25
- data/vendor/crates/spikard-rb/src/lib.rs +1 -2
- data/vendor/crates/spikard-rb-macros/Cargo.toml +1 -1
- metadata +1 -1
|
@@ -19,12 +19,12 @@ mod common;
|
|
|
19
19
|
/// Test metadata extraction from request
|
|
20
20
|
#[tokio::test]
|
|
21
21
|
async fn test_metadata_extraction_from_request() {
|
|
22
|
-
let mut server = GrpcTestServer::new();
|
|
23
|
-
|
|
24
22
|
struct MetadataCheckHandler;
|
|
25
23
|
impl spikard_http::grpc::GrpcHandler for MetadataCheckHandler {
|
|
26
|
-
fn call(
|
|
27
|
-
|
|
24
|
+
fn call(
|
|
25
|
+
&self,
|
|
26
|
+
request: spikard_http::grpc::GrpcRequestData,
|
|
27
|
+
) -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
|
|
28
28
|
{
|
|
29
29
|
// Extract and verify metadata
|
|
30
30
|
let has_user_agent = request.metadata.get("user-agent").is_some();
|
|
@@ -48,6 +48,8 @@ async fn test_metadata_extraction_from_request() {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
let server = GrpcTestServer::new();
|
|
52
|
+
|
|
51
53
|
server.register_service(Arc::new(MetadataCheckHandler));
|
|
52
54
|
|
|
53
55
|
let metadata = create_test_metadata();
|
|
@@ -62,24 +64,23 @@ async fn test_metadata_extraction_from_request() {
|
|
|
62
64
|
.await
|
|
63
65
|
.expect("Failed to send request with metadata");
|
|
64
66
|
|
|
65
|
-
assert_grpc_response(response, serde_json::json!({"extracted": true}));
|
|
67
|
+
assert_grpc_response(&response, &serde_json::json!({"extracted": true}));
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
/// Test Bearer token authentication metadata
|
|
69
71
|
#[tokio::test]
|
|
70
72
|
async fn test_authentication_bearer_token_metadata() {
|
|
71
|
-
let mut server = GrpcTestServer::new();
|
|
72
|
-
|
|
73
73
|
struct AuthServiceHandler;
|
|
74
74
|
impl spikard_http::grpc::GrpcHandler for AuthServiceHandler {
|
|
75
|
-
fn call(
|
|
76
|
-
|
|
75
|
+
fn call(
|
|
76
|
+
&self,
|
|
77
|
+
request: spikard_http::grpc::GrpcRequestData,
|
|
78
|
+
) -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
|
|
77
79
|
{
|
|
78
80
|
let token_present = request
|
|
79
81
|
.metadata
|
|
80
82
|
.get("authorization")
|
|
81
|
-
.
|
|
82
|
-
.unwrap_or(false);
|
|
83
|
+
.is_some_and(|v| v.to_str().unwrap_or("").starts_with("Bearer "));
|
|
83
84
|
|
|
84
85
|
let response = if token_present {
|
|
85
86
|
Bytes::from(r#"{"authenticated": true, "user": "alice"}"#)
|
|
@@ -99,36 +100,35 @@ async fn test_authentication_bearer_token_metadata() {
|
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
|
|
103
|
+
let server = GrpcTestServer::new();
|
|
104
|
+
|
|
102
105
|
server.register_service(Arc::new(AuthServiceHandler));
|
|
103
106
|
|
|
104
107
|
let mut metadata = create_test_metadata();
|
|
105
108
|
add_auth_metadata(&mut metadata, "secret_token_abc123").unwrap();
|
|
106
109
|
|
|
107
|
-
let response = send_unary_request(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
"authenticated": true,
|
|
119
|
-
"user": "alice"
|
|
120
|
-
}));
|
|
110
|
+
let response = send_unary_request(&server, "api.AuthService", "Authenticate", Bytes::from("{}"), metadata)
|
|
111
|
+
.await
|
|
112
|
+
.expect("Failed to authenticate");
|
|
113
|
+
|
|
114
|
+
assert_grpc_response(
|
|
115
|
+
&response,
|
|
116
|
+
&serde_json::json!({
|
|
117
|
+
"authenticated": true,
|
|
118
|
+
"user": "alice"
|
|
119
|
+
}),
|
|
120
|
+
);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/// Test custom header metadata
|
|
124
124
|
#[tokio::test]
|
|
125
125
|
async fn test_custom_header_metadata() {
|
|
126
|
-
let mut server = GrpcTestServer::new();
|
|
127
|
-
|
|
128
126
|
struct CustomHeaderHandler;
|
|
129
127
|
impl spikard_http::grpc::GrpcHandler for CustomHeaderHandler {
|
|
130
|
-
fn call(
|
|
131
|
-
|
|
128
|
+
fn call(
|
|
129
|
+
&self,
|
|
130
|
+
request: spikard_http::grpc::GrpcRequestData,
|
|
131
|
+
) -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
|
|
132
132
|
{
|
|
133
133
|
let custom_value = request
|
|
134
134
|
.metadata
|
|
@@ -137,7 +137,7 @@ async fn test_custom_header_metadata() {
|
|
|
137
137
|
.unwrap_or("missing")
|
|
138
138
|
.to_string();
|
|
139
139
|
|
|
140
|
-
let response = format!(r#"{{"custom_value": "{}"}}"
|
|
140
|
+
let response = format!(r#"{{"custom_value": "{custom_value}"}}"#);
|
|
141
141
|
|
|
142
142
|
Box::pin(async move {
|
|
143
143
|
Ok(spikard_http::grpc::GrpcResponseData {
|
|
@@ -151,6 +151,8 @@ async fn test_custom_header_metadata() {
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
let server = GrpcTestServer::new();
|
|
155
|
+
|
|
154
156
|
server.register_service(Arc::new(CustomHeaderHandler));
|
|
155
157
|
|
|
156
158
|
let mut metadata = create_test_metadata();
|
|
@@ -166,18 +168,18 @@ async fn test_custom_header_metadata() {
|
|
|
166
168
|
.await
|
|
167
169
|
.expect("Failed to send custom header");
|
|
168
170
|
|
|
169
|
-
assert_grpc_response(response, serde_json::json!({"custom_value": "custom_value_123"}));
|
|
171
|
+
assert_grpc_response(&response, &serde_json::json!({"custom_value": "custom_value_123"}));
|
|
170
172
|
}
|
|
171
173
|
|
|
172
174
|
/// Test multiple custom headers
|
|
173
175
|
#[tokio::test]
|
|
174
176
|
async fn test_multiple_custom_headers() {
|
|
175
|
-
let mut server = GrpcTestServer::new();
|
|
176
|
-
|
|
177
177
|
struct MultiHeaderHandler;
|
|
178
178
|
impl spikard_http::grpc::GrpcHandler for MultiHeaderHandler {
|
|
179
|
-
fn call(
|
|
180
|
-
|
|
179
|
+
fn call(
|
|
180
|
+
&self,
|
|
181
|
+
request: spikard_http::grpc::GrpcRequestData,
|
|
182
|
+
) -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
|
|
181
183
|
{
|
|
182
184
|
let req_id = request
|
|
183
185
|
.metadata
|
|
@@ -193,10 +195,7 @@ async fn test_multiple_custom_headers() {
|
|
|
193
195
|
.unwrap_or("missing")
|
|
194
196
|
.to_string();
|
|
195
197
|
|
|
196
|
-
let response = format!(
|
|
197
|
-
r#"{{"request_id": "{}", "trace_id": "{}"}}"#,
|
|
198
|
-
req_id, trace_id
|
|
199
|
-
);
|
|
198
|
+
let response = format!(r#"{{"request_id": "{req_id}", "trace_id": "{trace_id}"}}"#);
|
|
200
199
|
|
|
201
200
|
Box::pin(async move {
|
|
202
201
|
Ok(spikard_http::grpc::GrpcResponseData {
|
|
@@ -210,6 +209,8 @@ async fn test_multiple_custom_headers() {
|
|
|
210
209
|
}
|
|
211
210
|
}
|
|
212
211
|
|
|
212
|
+
let server = GrpcTestServer::new();
|
|
213
|
+
|
|
213
214
|
server.register_service(Arc::new(MultiHeaderHandler));
|
|
214
215
|
|
|
215
216
|
let mut metadata = create_test_metadata();
|
|
@@ -226,21 +227,24 @@ async fn test_multiple_custom_headers() {
|
|
|
226
227
|
.await
|
|
227
228
|
.expect("Failed to send multiple headers");
|
|
228
229
|
|
|
229
|
-
assert_grpc_response(
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
230
|
+
assert_grpc_response(
|
|
231
|
+
&response,
|
|
232
|
+
&serde_json::json!({
|
|
233
|
+
"request_id": "req-12345",
|
|
234
|
+
"trace_id": "trace-67890"
|
|
235
|
+
}),
|
|
236
|
+
);
|
|
233
237
|
}
|
|
234
238
|
|
|
235
239
|
/// Test metadata with special characters in values
|
|
236
240
|
#[tokio::test]
|
|
237
241
|
async fn test_metadata_special_characters() {
|
|
238
|
-
let mut server = GrpcTestServer::new();
|
|
239
|
-
|
|
240
242
|
struct SpecialCharHandler;
|
|
241
243
|
impl spikard_http::grpc::GrpcHandler for SpecialCharHandler {
|
|
242
|
-
fn call(
|
|
243
|
-
|
|
244
|
+
fn call(
|
|
245
|
+
&self,
|
|
246
|
+
request: spikard_http::grpc::GrpcRequestData,
|
|
247
|
+
) -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
|
|
244
248
|
{
|
|
245
249
|
let special_header = request
|
|
246
250
|
.metadata
|
|
@@ -249,7 +253,7 @@ async fn test_metadata_special_characters() {
|
|
|
249
253
|
.unwrap_or("")
|
|
250
254
|
.to_string();
|
|
251
255
|
|
|
252
|
-
let response = format!(r#"{{"received": "{}"}}"
|
|
256
|
+
let response = format!(r#"{{"received": "{special_header}"}}"#);
|
|
253
257
|
|
|
254
258
|
Box::pin(async move {
|
|
255
259
|
Ok(spikard_http::grpc::GrpcResponseData {
|
|
@@ -263,6 +267,8 @@ async fn test_metadata_special_characters() {
|
|
|
263
267
|
}
|
|
264
268
|
}
|
|
265
269
|
|
|
270
|
+
let server = GrpcTestServer::new();
|
|
271
|
+
|
|
266
272
|
server.register_service(Arc::new(SpecialCharHandler));
|
|
267
273
|
|
|
268
274
|
let mut metadata = create_test_metadata();
|
|
@@ -279,12 +285,15 @@ async fn test_metadata_special_characters() {
|
|
|
279
285
|
.await
|
|
280
286
|
.expect("Failed to send special chars");
|
|
281
287
|
|
|
282
|
-
assert_grpc_response(
|
|
283
|
-
|
|
284
|
-
|
|
288
|
+
assert_grpc_response(
|
|
289
|
+
&response,
|
|
290
|
+
&serde_json::json!({
|
|
291
|
+
"received": "value-with_underscore.and.dots"
|
|
292
|
+
}),
|
|
293
|
+
);
|
|
285
294
|
}
|
|
286
295
|
|
|
287
|
-
/// Test metadata creation with HashMap
|
|
296
|
+
/// Test metadata creation with `HashMap`
|
|
288
297
|
#[test]
|
|
289
298
|
fn test_create_metadata_with_headers_map() {
|
|
290
299
|
let mut headers = HashMap::new();
|
|
@@ -314,12 +323,12 @@ fn test_default_metadata_headers() {
|
|
|
314
323
|
/// Test response metadata is preserved
|
|
315
324
|
#[tokio::test]
|
|
316
325
|
async fn test_response_metadata_preservation() {
|
|
317
|
-
let mut server = GrpcTestServer::new();
|
|
318
|
-
|
|
319
326
|
struct ResponseMetadataHandler;
|
|
320
327
|
impl spikard_http::grpc::GrpcHandler for ResponseMetadataHandler {
|
|
321
|
-
fn call(
|
|
322
|
-
|
|
328
|
+
fn call(
|
|
329
|
+
&self,
|
|
330
|
+
_request: spikard_http::grpc::GrpcRequestData,
|
|
331
|
+
) -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
|
|
323
332
|
{
|
|
324
333
|
let mut response_metadata = MetadataMap::new();
|
|
325
334
|
response_metadata.insert("x-response-header", "response-value".parse().unwrap());
|
|
@@ -336,6 +345,8 @@ async fn test_response_metadata_preservation() {
|
|
|
336
345
|
}
|
|
337
346
|
}
|
|
338
347
|
|
|
348
|
+
let server = GrpcTestServer::new();
|
|
349
|
+
|
|
339
350
|
server.register_service(Arc::new(ResponseMetadataHandler));
|
|
340
351
|
|
|
341
352
|
let response = send_unary_request(
|
|
@@ -372,12 +383,12 @@ fn test_bearer_token_format() {
|
|
|
372
383
|
/// Test metadata extraction with no headers
|
|
373
384
|
#[tokio::test]
|
|
374
385
|
async fn test_metadata_extraction_empty_metadata() {
|
|
375
|
-
let mut server = GrpcTestServer::new();
|
|
376
|
-
|
|
377
386
|
struct EmptyMetadataHandler;
|
|
378
387
|
impl spikard_http::grpc::GrpcHandler for EmptyMetadataHandler {
|
|
379
|
-
fn call(
|
|
380
|
-
|
|
388
|
+
fn call(
|
|
389
|
+
&self,
|
|
390
|
+
request: spikard_http::grpc::GrpcRequestData,
|
|
391
|
+
) -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
|
|
381
392
|
{
|
|
382
393
|
let is_empty = request.metadata.is_empty();
|
|
383
394
|
|
|
@@ -399,6 +410,8 @@ async fn test_metadata_extraction_empty_metadata() {
|
|
|
399
410
|
}
|
|
400
411
|
}
|
|
401
412
|
|
|
413
|
+
let server = GrpcTestServer::new();
|
|
414
|
+
|
|
402
415
|
server.register_service(Arc::new(EmptyMetadataHandler));
|
|
403
416
|
|
|
404
417
|
let empty_metadata = MetadataMap::new();
|
|
@@ -413,18 +426,18 @@ async fn test_metadata_extraction_empty_metadata() {
|
|
|
413
426
|
.await
|
|
414
427
|
.expect("Failed to send with empty metadata");
|
|
415
428
|
|
|
416
|
-
assert_grpc_response(response, serde_json::json!({"metadata_empty": true}));
|
|
429
|
+
assert_grpc_response(&response, &serde_json::json!({"metadata_empty": true}));
|
|
417
430
|
}
|
|
418
431
|
|
|
419
432
|
/// Test metadata header with numeric value
|
|
420
433
|
#[tokio::test]
|
|
421
434
|
async fn test_metadata_numeric_value() {
|
|
422
|
-
let mut server = GrpcTestServer::new();
|
|
423
|
-
|
|
424
435
|
struct NumericHeaderHandler;
|
|
425
436
|
impl spikard_http::grpc::GrpcHandler for NumericHeaderHandler {
|
|
426
|
-
fn call(
|
|
427
|
-
|
|
437
|
+
fn call(
|
|
438
|
+
&self,
|
|
439
|
+
request: spikard_http::grpc::GrpcRequestData,
|
|
440
|
+
) -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
|
|
428
441
|
{
|
|
429
442
|
let count = request
|
|
430
443
|
.metadata
|
|
@@ -433,7 +446,7 @@ async fn test_metadata_numeric_value() {
|
|
|
433
446
|
.unwrap_or("0")
|
|
434
447
|
.to_string();
|
|
435
448
|
|
|
436
|
-
let response = format!(r#"{{"count": {}}}"
|
|
449
|
+
let response = format!(r#"{{"count": {count}}}"#);
|
|
437
450
|
|
|
438
451
|
Box::pin(async move {
|
|
439
452
|
Ok(spikard_http::grpc::GrpcResponseData {
|
|
@@ -447,6 +460,8 @@ async fn test_metadata_numeric_value() {
|
|
|
447
460
|
}
|
|
448
461
|
}
|
|
449
462
|
|
|
463
|
+
let server = GrpcTestServer::new();
|
|
464
|
+
|
|
450
465
|
server.register_service(Arc::new(NumericHeaderHandler));
|
|
451
466
|
|
|
452
467
|
let mut metadata = create_test_metadata();
|
|
@@ -462,18 +477,18 @@ async fn test_metadata_numeric_value() {
|
|
|
462
477
|
.await
|
|
463
478
|
.expect("Failed to send numeric header");
|
|
464
479
|
|
|
465
|
-
assert_grpc_response(response, serde_json::json!({"count": 42}));
|
|
480
|
+
assert_grpc_response(&response, &serde_json::json!({"count": 42}));
|
|
466
481
|
}
|
|
467
482
|
|
|
468
483
|
/// Test metadata with UUID value
|
|
469
484
|
#[tokio::test]
|
|
470
485
|
async fn test_metadata_uuid_value() {
|
|
471
|
-
let mut server = GrpcTestServer::new();
|
|
472
|
-
|
|
473
486
|
struct UuidHeaderHandler;
|
|
474
487
|
impl spikard_http::grpc::GrpcHandler for UuidHeaderHandler {
|
|
475
|
-
fn call(
|
|
476
|
-
|
|
488
|
+
fn call(
|
|
489
|
+
&self,
|
|
490
|
+
request: spikard_http::grpc::GrpcRequestData,
|
|
491
|
+
) -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
|
|
477
492
|
{
|
|
478
493
|
let uuid = request
|
|
479
494
|
.metadata
|
|
@@ -482,7 +497,7 @@ async fn test_metadata_uuid_value() {
|
|
|
482
497
|
.unwrap_or("invalid")
|
|
483
498
|
.to_string();
|
|
484
499
|
|
|
485
|
-
let response = format!(r#"{{"uuid": "{}"}}"
|
|
500
|
+
let response = format!(r#"{{"uuid": "{uuid}"}}"#);
|
|
486
501
|
|
|
487
502
|
Box::pin(async move {
|
|
488
503
|
Ok(spikard_http::grpc::GrpcResponseData {
|
|
@@ -496,23 +511,22 @@ async fn test_metadata_uuid_value() {
|
|
|
496
511
|
}
|
|
497
512
|
}
|
|
498
513
|
|
|
514
|
+
let server = GrpcTestServer::new();
|
|
515
|
+
|
|
499
516
|
server.register_service(Arc::new(UuidHeaderHandler));
|
|
500
517
|
|
|
501
518
|
let mut metadata = create_test_metadata();
|
|
502
519
|
let uuid = "550e8400-e29b-41d4-a716-446655440000";
|
|
503
520
|
add_metadata_header(&mut metadata, "x-request-uuid", uuid).unwrap();
|
|
504
521
|
|
|
505
|
-
let response = send_unary_request(
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
"Process",
|
|
509
|
-
Bytes::from("{}"),
|
|
510
|
-
metadata,
|
|
511
|
-
)
|
|
512
|
-
.await
|
|
513
|
-
.expect("Failed to send UUID header");
|
|
522
|
+
let response = send_unary_request(&server, "test.UuidService", "Process", Bytes::from("{}"), metadata)
|
|
523
|
+
.await
|
|
524
|
+
.expect("Failed to send UUID header");
|
|
514
525
|
|
|
515
|
-
assert_grpc_response(
|
|
516
|
-
|
|
517
|
-
|
|
526
|
+
assert_grpc_response(
|
|
527
|
+
&response,
|
|
528
|
+
&serde_json::json!({
|
|
529
|
+
"uuid": "550e8400-e29b-41d4-a716-446655440000"
|
|
530
|
+
}),
|
|
531
|
+
);
|
|
518
532
|
}
|