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.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/ext/spikard_rb/Cargo.toml +1 -1
  3. data/lib/spikard/grpc.rb +5 -5
  4. data/lib/spikard/version.rb +1 -1
  5. data/vendor/crates/spikard-bindings-shared/Cargo.toml +1 -1
  6. data/vendor/crates/spikard-bindings-shared/src/grpc_metadata.rs +3 -3
  7. data/vendor/crates/spikard-core/Cargo.toml +1 -1
  8. data/vendor/crates/spikard-core/src/metadata.rs +3 -14
  9. data/vendor/crates/spikard-http/Cargo.toml +1 -1
  10. data/vendor/crates/spikard-http/src/grpc/mod.rs +1 -1
  11. data/vendor/crates/spikard-http/src/grpc/service.rs +11 -11
  12. data/vendor/crates/spikard-http/src/grpc/streaming.rs +5 -1
  13. data/vendor/crates/spikard-http/src/server/grpc_routing.rs +59 -20
  14. data/vendor/crates/spikard-http/src/server/routing_factory.rs +179 -201
  15. data/vendor/crates/spikard-http/tests/common/grpc_helpers.rs +49 -60
  16. data/vendor/crates/spikard-http/tests/common/handlers.rs +5 -5
  17. data/vendor/crates/spikard-http/tests/common/mod.rs +7 -8
  18. data/vendor/crates/spikard-http/tests/common/test_builders.rs +14 -19
  19. data/vendor/crates/spikard-http/tests/grpc_error_handling_test.rs +68 -69
  20. data/vendor/crates/spikard-http/tests/grpc_integration_test.rs +1 -3
  21. data/vendor/crates/spikard-http/tests/grpc_metadata_test.rs +98 -84
  22. data/vendor/crates/spikard-http/tests/grpc_server_integration.rs +76 -57
  23. data/vendor/crates/spikard-rb/Cargo.toml +1 -1
  24. data/vendor/crates/spikard-rb/src/grpc/handler.rs +30 -25
  25. data/vendor/crates/spikard-rb/src/lib.rs +1 -2
  26. data/vendor/crates/spikard-rb-macros/Cargo.toml +1 -1
  27. 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(&self, request: spikard_http::grpc::GrpcRequestData)
27
- -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
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(&self, request: spikard_http::grpc::GrpcRequestData)
76
- -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
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
- .map(|v| v.to_str().unwrap_or("").starts_with("Bearer "))
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
- &server,
109
- "api.AuthService",
110
- "Authenticate",
111
- Bytes::from("{}"),
112
- metadata,
113
- )
114
- .await
115
- .expect("Failed to authenticate");
116
-
117
- assert_grpc_response(response, serde_json::json!({
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(&self, request: spikard_http::grpc::GrpcRequestData)
131
- -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
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": "{}"}}"#, 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(&self, request: spikard_http::grpc::GrpcRequestData)
180
- -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
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(response, serde_json::json!({
230
- "request_id": "req-12345",
231
- "trace_id": "trace-67890"
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(&self, request: spikard_http::grpc::GrpcRequestData)
243
- -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
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": "{}"}}"#, special_header);
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(response, serde_json::json!({
283
- "received": "value-with_underscore.and.dots"
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(&self, _request: spikard_http::grpc::GrpcRequestData)
322
- -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
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(&self, request: spikard_http::grpc::GrpcRequestData)
380
- -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
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(&self, request: spikard_http::grpc::GrpcRequestData)
427
- -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
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": {}}}"#, 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(&self, request: spikard_http::grpc::GrpcRequestData)
476
- -> std::pin::Pin<Box<dyn std::future::Future<Output = spikard_http::grpc::GrpcHandlerResult> + Send>>
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": "{}"}}"#, 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
- &server,
507
- "test.UuidService",
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(response, serde_json::json!({
516
- "uuid": "550e8400-e29b-41d4-a716-446655440000"
517
- }));
526
+ assert_grpc_response(
527
+ &response,
528
+ &serde_json::json!({
529
+ "uuid": "550e8400-e29b-41d4-a716-446655440000"
530
+ }),
531
+ );
518
532
  }