@@ -456,4 +456,96 @@ defmodule Sentry.Test.AssertionsTest do
456456 :ets . insert ( table , { System . unique_integer ( [ :monotonic ] ) , metric } )
457457 metric
458458 end
459+
460+ describe "assert_sentry_metric/2" do
461+ setup do
462+ SentryTest . setup_sentry ( )
463+ end
464+
465+ test "finds metric by type when multiple metrics exist" do
466+ insert_metric ( type: :counter , name: "clicks" , value: 5 )
467+ insert_metric ( type: :distribution , name: "response.time" , value: 42.5 )
468+
469+ metric = assert_sentry_metric ( :counter , name: "clicks" )
470+ assert % Sentry.Metric { } = metric
471+ assert metric . type == :counter
472+ assert metric . name == "clicks"
473+ assert metric . value == 5
474+ end
475+
476+ test "uses find semantics - succeeds when target is among many" do
477+ insert_metric ( type: :counter , name: "sync.read.entities" , value: 1 )
478+ insert_metric ( type: :distribution , name: "sync.read.entities.count" , value: 10 )
479+
480+ metric = assert_sentry_metric ( :distribution , name: "sync.read.entities.count" )
481+ assert metric . value == 10
482+ end
483+
484+ test "returns unmatched metrics to inbox for subsequent assertions" do
485+ insert_metric ( type: :counter , name: "first.metric" , value: 1 )
486+ insert_metric ( type: :distribution , name: "second.metric" , value: 99.9 )
487+
488+ assert_sentry_metric ( :counter , name: "first.metric" )
489+ # Second assertion must still find the distribution metric
490+ assert_sentry_metric ( :distribution , name: "second.metric" )
491+ end
492+
493+ test "matches additional criteria beyond type" do
494+ insert_metric ( type: :counter , name: "button.clicks" , value: 1 ,
495+ attributes: % { button_id: "submit" } )
496+ insert_metric ( type: :counter , name: "button.clicks" , value: 1 ,
497+ attributes: % { button_id: "cancel" } )
498+
499+ metric = assert_sentry_metric ( :counter ,
500+ name: "button.clicks" ,
501+ attributes: % { button_id: "submit" }
502+ )
503+ assert metric . attributes [ :button_id ] == "submit"
504+ end
505+
506+ test "fails when no matching metric found" do
507+ insert_metric ( type: :counter , name: "other.metric" )
508+
509+ assert_raise ExUnit.AssertionError , ~r/ No matching Sentry metric found/ , fn ->
510+ assert_sentry_metric ( :gauge , name: "nonexistent" , timeout: 10 )
511+ end
512+ end
513+
514+ test "fails when type doesn't match" do
515+ insert_metric ( type: :counter , name: "my.metric" )
516+
517+ assert_raise ExUnit.AssertionError , ~r/ No matching Sentry metric found/ , fn ->
518+ assert_sentry_metric ( :gauge , name: "my.metric" , timeout: 10 )
519+ end
520+ end
521+
522+ test "respects :timeout option" do
523+ before = System . monotonic_time ( :millisecond )
524+
525+ assert_raise ExUnit.AssertionError , ~r/ No matching Sentry metric found/ , fn ->
526+ assert_sentry_metric ( :counter , name: "missing" , timeout: 50 )
527+ end
528+
529+ elapsed = System . monotonic_time ( :millisecond ) - before
530+ assert elapsed < 500 , "expected fast failure, waited #{ elapsed } ms"
531+ end
532+
533+ test "awaits async metrics" do
534+ table = Process . get ( :sentry_test_collector )
535+
536+ Task . start ( fn ->
537+ Process . sleep ( 30 )
538+ metric = struct! ( Sentry.Metric ,
539+ type: :counter ,
540+ name: "async.metric" ,
541+ value: 1 ,
542+ timestamp: System . system_time ( :nanosecond ) / 1_000_000_000
543+ )
544+ :ets . insert ( table , { System . unique_integer ( [ :monotonic ] ) , metric } )
545+ end )
546+
547+ metric = assert_sentry_metric ( :counter , name: "async.metric" , timeout: 500 )
548+ assert metric . name == "async.metric"
549+ end
550+ end
459551end
0 commit comments