1515)
1616from sentry .snuba .subscriptions import create_snuba_subscription
1717from sentry .workflow_engine .models import Condition , DataPacket
18- from sentry .workflow_engine .types import DetectorPriorityLevel
18+ from sentry .workflow_engine .types import ConditionError , DetectorPriorityLevel
1919from tests .sentry .workflow_engine .handlers .condition .test_base import ConditionTestCase
2020
2121
@@ -30,6 +30,8 @@ def setUp(self) -> None:
3030 (self .workflow , self .detector , self .detector_workflow , self .workflow_triggers ) = (
3131 self .create_detector_and_workflow ()
3232 )
33+ self .detector .update (config = {"detection_type" : "dynamic" , "comparison_delta" : None })
34+ self .detector .save ()
3335
3436 packet = AnomalyDetectionUpdate (
3537 subscription_id = str (self .subscription .id ),
@@ -64,12 +66,7 @@ def setUp(self) -> None:
6466 condition_result = DetectorPriorityLevel .HIGH ,
6567 condition_group = self .workflow_triggers ,
6668 )
67-
68- @mock .patch (
69- "sentry.seer.anomaly_detection.get_anomaly_data.SEER_ANOMALY_DETECTION_CONNECTION_POOL.urlopen"
70- )
71- def test_passes (self , mock_seer_request : mock .MagicMock ) -> None :
72- seer_return_value : DetectAnomaliesResponse = {
69+ self .high_confidence_seer_response : DetectAnomaliesResponse = {
7370 "success" : True ,
7471 "timeseries" : [
7572 {
@@ -82,6 +79,12 @@ def test_passes(self, mock_seer_request: mock.MagicMock) -> None:
8279 }
8380 ],
8481 }
82+
83+ @mock .patch (
84+ "sentry.seer.anomaly_detection.get_anomaly_data.SEER_ANOMALY_DETECTION_CONNECTION_POOL.urlopen"
85+ )
86+ def test_passes (self , mock_seer_request : mock .MagicMock ) -> None :
87+ seer_return_value = self .high_confidence_seer_response
8588 mock_seer_request .return_value = HTTPResponse (orjson .dumps (seer_return_value ), status = 200 )
8689 assert (
8790 self .dc .evaluate_value (self .data_packet .packet .values )
@@ -110,6 +113,43 @@ def test_passes_medium(self, mock_seer_request: mock.MagicMock) -> None:
110113 self .dc .evaluate_value (self .data_packet .packet .values ) == DetectorPriorityLevel .OK .value
111114 )
112115
116+ @mock .patch (
117+ "sentry.seer.anomaly_detection.get_anomaly_data.SEER_ANOMALY_DETECTION_CONNECTION_POOL.urlopen"
118+ )
119+ @mock .patch ("sentry.seer.anomaly_detection.get_anomaly_data.logger" )
120+ def test_seer_call_nan_aggregation_value (
121+ self , mock_logger : mock .MagicMock , mock_seer_request : mock .MagicMock
122+ ) -> None :
123+ seer_return_value = self .high_confidence_seer_response
124+ mock_seer_request .return_value = HTTPResponse (orjson .dumps (seer_return_value ), status = 200 )
125+
126+ packet = AnomalyDetectionUpdate (
127+ subscription_id = str (self .subscription .id ),
128+ values = {
129+ "value" : float ("nan" ),
130+ "source_id" : str (self .subscription .id ),
131+ "subscription_id" : str (self .subscription .id ),
132+ "timestamp" : datetime .now (UTC ),
133+ },
134+ timestamp = datetime .now (UTC ),
135+ entity = "test-entity" ,
136+ )
137+ data_packet = DataPacket [AnomalyDetectionUpdate ](
138+ source_id = str (packet .subscription_id ),
139+ packet = packet ,
140+ )
141+
142+ assert self .dc .evaluate_value (data_packet .packet .values ) == ConditionError (
143+ msg = "Error during Seer data evaluation process."
144+ )
145+ mock_logger .error .assert_called_with (
146+ "Invalid aggregation value" ,
147+ extra = {
148+ "source_id" : self .subscription .id ,
149+ "source_type" : DataSourceType .SNUBA_QUERY_SUBSCRIPTION ,
150+ },
151+ )
152+
113153 @mock .patch (
114154 "sentry.seer.anomaly_detection.get_anomaly_data.SEER_ANOMALY_DETECTION_CONNECTION_POOL.urlopen"
115155 )
0 commit comments