deltacat 1.1.0__py3-none-any.whl → 1.1.2__py3-none-any.whl
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.
- deltacat/__init__.py +1 -1
- deltacat/aws/clients.py +12 -2
- deltacat/aws/constants.py +5 -1
- deltacat/aws/s3u.py +8 -1
- deltacat/compute/compactor/model/compact_partition_params.py +24 -0
- deltacat/compute/compactor/model/compaction_session_audit_info.py +11 -0
- deltacat/compute/compactor_v2/compaction_session.py +44 -6
- deltacat/compute/compactor_v2/constants.py +28 -0
- deltacat/compute/compactor_v2/deletes/utils.py +3 -0
- deltacat/compute/compactor_v2/model/hash_bucket_input.py +6 -0
- deltacat/compute/compactor_v2/model/merge_input.py +6 -0
- deltacat/compute/compactor_v2/steps/hash_bucket.py +11 -3
- deltacat/compute/compactor_v2/steps/merge.py +35 -6
- deltacat/compute/compactor_v2/utils/io.py +3 -0
- deltacat/compute/compactor_v2/utils/merge.py +3 -0
- deltacat/compute/compactor_v2/utils/task_options.py +94 -8
- deltacat/io/memcached_object_store.py +20 -0
- deltacat/logs.py +29 -2
- deltacat/tests/compute/test_compact_partition_params.py +5 -0
- deltacat/tests/io/test_memcached_object_store.py +19 -0
- deltacat/tests/utils/test_metrics.py +575 -0
- deltacat/utils/metrics.py +158 -23
- deltacat/utils/resources.py +5 -3
- {deltacat-1.1.0.dist-info → deltacat-1.1.2.dist-info}/METADATA +1 -1
- {deltacat-1.1.0.dist-info → deltacat-1.1.2.dist-info}/RECORD +28 -27
- {deltacat-1.1.0.dist-info → deltacat-1.1.2.dist-info}/LICENSE +0 -0
- {deltacat-1.1.0.dist-info → deltacat-1.1.2.dist-info}/WHEEL +0 -0
- {deltacat-1.1.0.dist-info → deltacat-1.1.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,575 @@
|
|
1
|
+
import unittest
|
2
|
+
from unittest.mock import MagicMock, ANY, call
|
3
|
+
import ray
|
4
|
+
from deltacat.utils.metrics import (
|
5
|
+
metrics,
|
6
|
+
success_metric,
|
7
|
+
failure_metric,
|
8
|
+
latency_metric,
|
9
|
+
MetricsActor,
|
10
|
+
METRICS_CONFIG_ACTOR_NAME,
|
11
|
+
MetricsConfig,
|
12
|
+
MetricsTarget,
|
13
|
+
METRICS_TARGET_TO_EMITTER_DICT,
|
14
|
+
)
|
15
|
+
from deltacat.utils.performance import timed_invocation
|
16
|
+
|
17
|
+
|
18
|
+
def method_not_annotated(mock_func):
|
19
|
+
mock_func("called")
|
20
|
+
|
21
|
+
|
22
|
+
@metrics
|
23
|
+
def metrics_annotated_method(mock_func):
|
24
|
+
mock_func("called")
|
25
|
+
|
26
|
+
|
27
|
+
@metrics
|
28
|
+
def metrics_annotated_method_error(mock_func):
|
29
|
+
raise ValueError()
|
30
|
+
|
31
|
+
|
32
|
+
@metrics(prefix="test_prefix")
|
33
|
+
def metrics_with_prefix_annotated_method(mock_func):
|
34
|
+
mock_func("called")
|
35
|
+
|
36
|
+
|
37
|
+
@metrics(prefix="test_prefix")
|
38
|
+
def metrics_with_prefix_annotated_method_error(mock_func):
|
39
|
+
raise ValueError()
|
40
|
+
|
41
|
+
|
42
|
+
class TestMetricsAnnotation(unittest.TestCase):
|
43
|
+
def test_metrics_annotation_sanity(self):
|
44
|
+
mock, mock_target = MagicMock(), MagicMock()
|
45
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
46
|
+
metrics_actor = MetricsActor.options(
|
47
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
48
|
+
).remote()
|
49
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
50
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
51
|
+
|
52
|
+
# action
|
53
|
+
metrics_annotated_method(mock)
|
54
|
+
|
55
|
+
mock.assert_called_once()
|
56
|
+
self.assertEqual(2, mock_target.call_count)
|
57
|
+
mock_target.assert_has_calls(
|
58
|
+
[
|
59
|
+
call(
|
60
|
+
metrics_name="metrics_annotated_method_time",
|
61
|
+
metrics_config=ANY,
|
62
|
+
value=ANY,
|
63
|
+
),
|
64
|
+
call(
|
65
|
+
metrics_name="metrics_annotated_method_success_count",
|
66
|
+
metrics_config=ANY,
|
67
|
+
value=ANY,
|
68
|
+
),
|
69
|
+
],
|
70
|
+
any_order=True,
|
71
|
+
)
|
72
|
+
|
73
|
+
def test_metrics_annotation_when_error(self):
|
74
|
+
mock, mock_target = MagicMock(), MagicMock()
|
75
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
76
|
+
metrics_actor = MetricsActor.options(
|
77
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
78
|
+
).remote()
|
79
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
80
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
81
|
+
|
82
|
+
# action
|
83
|
+
self.assertRaises(ValueError, lambda: metrics_annotated_method_error(mock))
|
84
|
+
|
85
|
+
mock.assert_not_called()
|
86
|
+
self.assertEqual(3, mock_target.call_count)
|
87
|
+
mock_target.assert_has_calls(
|
88
|
+
[
|
89
|
+
call(
|
90
|
+
metrics_name="metrics_annotated_method_error_time",
|
91
|
+
metrics_config=ANY,
|
92
|
+
value=ANY,
|
93
|
+
),
|
94
|
+
call(
|
95
|
+
metrics_name="metrics_annotated_method_error_failure_count",
|
96
|
+
metrics_config=ANY,
|
97
|
+
value=ANY,
|
98
|
+
),
|
99
|
+
call(
|
100
|
+
metrics_name="metrics_annotated_method_error_failure_count.ValueError",
|
101
|
+
metrics_config=ANY,
|
102
|
+
value=ANY,
|
103
|
+
),
|
104
|
+
],
|
105
|
+
any_order=True,
|
106
|
+
)
|
107
|
+
|
108
|
+
def test_metrics_with_prefix_annotation_sanity(self):
|
109
|
+
mock, mock_target = MagicMock(), MagicMock()
|
110
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
111
|
+
metrics_actor = MetricsActor.options(
|
112
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
113
|
+
).remote()
|
114
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
115
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
116
|
+
|
117
|
+
# action
|
118
|
+
metrics_with_prefix_annotated_method(mock)
|
119
|
+
|
120
|
+
mock.assert_called_once()
|
121
|
+
self.assertEqual(2, mock_target.call_count)
|
122
|
+
mock_target.assert_has_calls(
|
123
|
+
[
|
124
|
+
call(metrics_name="test_prefix_time", metrics_config=ANY, value=ANY),
|
125
|
+
call(
|
126
|
+
metrics_name="test_prefix_success_count",
|
127
|
+
metrics_config=ANY,
|
128
|
+
value=ANY,
|
129
|
+
),
|
130
|
+
],
|
131
|
+
any_order=True,
|
132
|
+
)
|
133
|
+
|
134
|
+
def test_metrics_annotation_performance(self):
|
135
|
+
mock, mock_target = MagicMock(), MagicMock()
|
136
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
137
|
+
metrics_actor = MetricsActor.options(
|
138
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
139
|
+
).remote()
|
140
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
141
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
142
|
+
|
143
|
+
# action with annotation
|
144
|
+
_, actual_latency = timed_invocation(metrics_annotated_method, mock)
|
145
|
+
_, second_call_latency = timed_invocation(metrics_annotated_method, mock)
|
146
|
+
|
147
|
+
mock.assert_called()
|
148
|
+
self.assertEqual(4, mock_target.call_count)
|
149
|
+
self.assertLess(
|
150
|
+
second_call_latency,
|
151
|
+
actual_latency,
|
152
|
+
"Second call to actor must be much faster",
|
153
|
+
)
|
154
|
+
|
155
|
+
def test_metrics_with_prefix_annotation_when_error(self):
|
156
|
+
mock, mock_target = MagicMock(), MagicMock()
|
157
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
158
|
+
metrics_actor = MetricsActor.options(
|
159
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
160
|
+
).remote()
|
161
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
162
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
163
|
+
|
164
|
+
# action
|
165
|
+
self.assertRaises(
|
166
|
+
ValueError, lambda: metrics_with_prefix_annotated_method_error(mock)
|
167
|
+
)
|
168
|
+
|
169
|
+
mock.assert_not_called()
|
170
|
+
self.assertEqual(3, mock_target.call_count)
|
171
|
+
mock_target.assert_has_calls(
|
172
|
+
[
|
173
|
+
call(metrics_name="test_prefix_time", metrics_config=ANY, value=ANY),
|
174
|
+
call(
|
175
|
+
metrics_name="test_prefix_failure_count",
|
176
|
+
metrics_config=ANY,
|
177
|
+
value=ANY,
|
178
|
+
),
|
179
|
+
call(
|
180
|
+
metrics_name="test_prefix_failure_count.ValueError",
|
181
|
+
metrics_config=ANY,
|
182
|
+
value=ANY,
|
183
|
+
),
|
184
|
+
],
|
185
|
+
any_order=True,
|
186
|
+
)
|
187
|
+
|
188
|
+
def test_metrics_with_prefix_annotation_without_actor(self):
|
189
|
+
mock, mock_target = MagicMock(), MagicMock()
|
190
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
191
|
+
metrics_actor = MetricsActor.options(
|
192
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
193
|
+
).remote()
|
194
|
+
|
195
|
+
# explicitly making sure actor is killed
|
196
|
+
ray.kill(metrics_actor)
|
197
|
+
|
198
|
+
# action
|
199
|
+
self.assertRaises(
|
200
|
+
ValueError, lambda: metrics_with_prefix_annotated_method_error(mock)
|
201
|
+
)
|
202
|
+
|
203
|
+
mock.assert_not_called()
|
204
|
+
mock_target.assert_not_called()
|
205
|
+
|
206
|
+
|
207
|
+
@latency_metric
|
208
|
+
def latency_metric_annotated_method(mock_func):
|
209
|
+
mock_func("called")
|
210
|
+
|
211
|
+
|
212
|
+
@latency_metric
|
213
|
+
def latency_metric_annotated_method_error(mock_func):
|
214
|
+
raise ValueError()
|
215
|
+
|
216
|
+
|
217
|
+
@latency_metric(name="test")
|
218
|
+
def latency_metric_with_name_annotated_method(mock_func):
|
219
|
+
mock_func("called")
|
220
|
+
|
221
|
+
|
222
|
+
@latency_metric(name="test")
|
223
|
+
def latency_metric_with_name_annotated_method_error(mock_func):
|
224
|
+
raise ValueError()
|
225
|
+
|
226
|
+
|
227
|
+
class TestLatencyMetricAnnotation(unittest.TestCase):
|
228
|
+
def test_annotation_sanity(self):
|
229
|
+
mock, mock_target = MagicMock(), MagicMock()
|
230
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
231
|
+
metrics_actor = MetricsActor.options(
|
232
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
233
|
+
).remote()
|
234
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
235
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
236
|
+
|
237
|
+
# action
|
238
|
+
latency_metric_annotated_method(mock)
|
239
|
+
|
240
|
+
mock.assert_called_once()
|
241
|
+
self.assertEqual(1, mock_target.call_count)
|
242
|
+
mock_target.assert_has_calls(
|
243
|
+
[
|
244
|
+
call(
|
245
|
+
metrics_name="latency_metric_annotated_method_time",
|
246
|
+
metrics_config=ANY,
|
247
|
+
value=ANY,
|
248
|
+
)
|
249
|
+
],
|
250
|
+
any_order=True,
|
251
|
+
)
|
252
|
+
|
253
|
+
def test_annotation_when_error(self):
|
254
|
+
mock, mock_target = MagicMock(), MagicMock()
|
255
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
256
|
+
metrics_actor = MetricsActor.options(
|
257
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
258
|
+
).remote()
|
259
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
260
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
261
|
+
|
262
|
+
# action
|
263
|
+
self.assertRaises(
|
264
|
+
ValueError, lambda: latency_metric_annotated_method_error(mock)
|
265
|
+
)
|
266
|
+
|
267
|
+
mock.assert_not_called()
|
268
|
+
self.assertEqual(1, mock_target.call_count)
|
269
|
+
mock_target.assert_has_calls(
|
270
|
+
[
|
271
|
+
call(
|
272
|
+
metrics_name="latency_metric_annotated_method_error_time",
|
273
|
+
metrics_config=ANY,
|
274
|
+
value=ANY,
|
275
|
+
)
|
276
|
+
],
|
277
|
+
any_order=True,
|
278
|
+
)
|
279
|
+
|
280
|
+
def test_annotation_with_args_sanity(self):
|
281
|
+
mock, mock_target = MagicMock(), MagicMock()
|
282
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
283
|
+
metrics_actor = MetricsActor.options(
|
284
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
285
|
+
).remote()
|
286
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
287
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
288
|
+
|
289
|
+
# action
|
290
|
+
latency_metric_with_name_annotated_method(mock)
|
291
|
+
|
292
|
+
mock.assert_called_once()
|
293
|
+
self.assertEqual(1, mock_target.call_count)
|
294
|
+
mock_target.assert_has_calls(
|
295
|
+
[call(metrics_name="test", metrics_config=ANY, value=ANY)], any_order=True
|
296
|
+
)
|
297
|
+
|
298
|
+
def test_annotation_with_args_when_error(self):
|
299
|
+
mock, mock_target = MagicMock(), MagicMock()
|
300
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
301
|
+
metrics_actor = MetricsActor.options(
|
302
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
303
|
+
).remote()
|
304
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
305
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
306
|
+
|
307
|
+
# action
|
308
|
+
self.assertRaises(
|
309
|
+
ValueError, lambda: latency_metric_with_name_annotated_method_error(mock)
|
310
|
+
)
|
311
|
+
|
312
|
+
mock.assert_not_called()
|
313
|
+
self.assertEqual(1, mock_target.call_count)
|
314
|
+
mock_target.assert_has_calls(
|
315
|
+
[call(metrics_name="test", metrics_config=ANY, value=ANY)], any_order=True
|
316
|
+
)
|
317
|
+
|
318
|
+
def test_annotation_without_actor(self):
|
319
|
+
mock, mock_target = MagicMock(), MagicMock()
|
320
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
321
|
+
metrics_actor = MetricsActor.options(
|
322
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
323
|
+
).remote()
|
324
|
+
|
325
|
+
# explicitly making sure actor is killed
|
326
|
+
ray.kill(metrics_actor)
|
327
|
+
|
328
|
+
# action
|
329
|
+
self.assertRaises(
|
330
|
+
ValueError, lambda: latency_metric_with_name_annotated_method_error(mock)
|
331
|
+
)
|
332
|
+
|
333
|
+
mock.assert_not_called()
|
334
|
+
mock_target.assert_not_called()
|
335
|
+
|
336
|
+
|
337
|
+
@success_metric
|
338
|
+
def success_metric_annotated_method(mock_func):
|
339
|
+
mock_func("called")
|
340
|
+
|
341
|
+
|
342
|
+
@success_metric
|
343
|
+
def success_metric_annotated_method_error(mock_func):
|
344
|
+
raise ValueError()
|
345
|
+
|
346
|
+
|
347
|
+
@success_metric(name="test")
|
348
|
+
def success_metric_with_name_annotated_method(mock_func):
|
349
|
+
mock_func("called")
|
350
|
+
|
351
|
+
|
352
|
+
@success_metric(name="test")
|
353
|
+
def success_metric_with_name_annotated_method_error(mock_func):
|
354
|
+
raise ValueError()
|
355
|
+
|
356
|
+
|
357
|
+
class TestSuccessMetricAnnotation(unittest.TestCase):
|
358
|
+
def test_annotation_sanity(self):
|
359
|
+
mock, mock_target = MagicMock(), MagicMock()
|
360
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
361
|
+
metrics_actor = MetricsActor.options(
|
362
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
363
|
+
).remote()
|
364
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
365
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
366
|
+
|
367
|
+
# action
|
368
|
+
success_metric_annotated_method(mock)
|
369
|
+
|
370
|
+
mock.assert_called_once()
|
371
|
+
self.assertEqual(1, mock_target.call_count)
|
372
|
+
mock_target.assert_has_calls(
|
373
|
+
[
|
374
|
+
call(
|
375
|
+
metrics_name="success_metric_annotated_method_success_count",
|
376
|
+
metrics_config=ANY,
|
377
|
+
value=ANY,
|
378
|
+
)
|
379
|
+
],
|
380
|
+
any_order=True,
|
381
|
+
)
|
382
|
+
|
383
|
+
def test_annotation_when_error(self):
|
384
|
+
mock, mock_target = MagicMock(), MagicMock()
|
385
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
386
|
+
metrics_actor = MetricsActor.options(
|
387
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
388
|
+
).remote()
|
389
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
390
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
391
|
+
|
392
|
+
# action
|
393
|
+
self.assertRaises(
|
394
|
+
ValueError, lambda: success_metric_annotated_method_error(mock)
|
395
|
+
)
|
396
|
+
|
397
|
+
mock.assert_not_called()
|
398
|
+
mock_target.assert_not_called()
|
399
|
+
|
400
|
+
def test_annotation_with_args_sanity(self):
|
401
|
+
mock, mock_target = MagicMock(), MagicMock()
|
402
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
403
|
+
metrics_actor = MetricsActor.options(
|
404
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
405
|
+
).remote()
|
406
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
407
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
408
|
+
|
409
|
+
# action
|
410
|
+
success_metric_with_name_annotated_method(mock)
|
411
|
+
|
412
|
+
mock.assert_called_once()
|
413
|
+
self.assertEqual(1, mock_target.call_count)
|
414
|
+
mock_target.assert_has_calls(
|
415
|
+
[call(metrics_name="test", metrics_config=ANY, value=ANY)], any_order=True
|
416
|
+
)
|
417
|
+
|
418
|
+
def test_annotation_with_args_when_error(self):
|
419
|
+
mock, mock_target = MagicMock(), MagicMock()
|
420
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
421
|
+
metrics_actor = MetricsActor.options(
|
422
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
423
|
+
).remote()
|
424
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
425
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
426
|
+
|
427
|
+
# action
|
428
|
+
self.assertRaises(
|
429
|
+
ValueError, lambda: success_metric_with_name_annotated_method_error(mock)
|
430
|
+
)
|
431
|
+
|
432
|
+
mock.assert_not_called()
|
433
|
+
mock_target.assert_not_called()
|
434
|
+
|
435
|
+
def test_annotation_without_actor(self):
|
436
|
+
mock, mock_target = MagicMock(), MagicMock()
|
437
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
438
|
+
metrics_actor = MetricsActor.options(
|
439
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
440
|
+
).remote()
|
441
|
+
|
442
|
+
# explicitly making sure actor is killed
|
443
|
+
ray.kill(metrics_actor)
|
444
|
+
|
445
|
+
# action
|
446
|
+
success_metric_annotated_method(mock)
|
447
|
+
|
448
|
+
mock.assert_called_once()
|
449
|
+
mock_target.assert_not_called()
|
450
|
+
|
451
|
+
|
452
|
+
@failure_metric
|
453
|
+
def failure_metric_annotated_method(mock_func):
|
454
|
+
mock_func("called")
|
455
|
+
|
456
|
+
|
457
|
+
@failure_metric
|
458
|
+
def failure_metric_annotated_method_error(mock_func):
|
459
|
+
raise ValueError()
|
460
|
+
|
461
|
+
|
462
|
+
@failure_metric(name="test")
|
463
|
+
def failure_metric_with_name_annotated_method(mock_func):
|
464
|
+
mock_func("called")
|
465
|
+
|
466
|
+
|
467
|
+
@failure_metric(name="test")
|
468
|
+
def failure_metric_with_name_annotated_method_error(mock_func):
|
469
|
+
raise ValueError()
|
470
|
+
|
471
|
+
|
472
|
+
class TestFailureMetricAnnotation(unittest.TestCase):
|
473
|
+
def test_annotation_sanity(self):
|
474
|
+
mock, mock_target = MagicMock(), MagicMock()
|
475
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
476
|
+
metrics_actor = MetricsActor.options(
|
477
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
478
|
+
).remote()
|
479
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
480
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
481
|
+
|
482
|
+
# action
|
483
|
+
failure_metric_annotated_method(mock)
|
484
|
+
|
485
|
+
mock.assert_called_once()
|
486
|
+
mock_target.assert_not_called()
|
487
|
+
|
488
|
+
def test_annotation_when_error(self):
|
489
|
+
mock, mock_target = MagicMock(), MagicMock()
|
490
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
491
|
+
metrics_actor = MetricsActor.options(
|
492
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
493
|
+
).remote()
|
494
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
495
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
496
|
+
|
497
|
+
# action
|
498
|
+
self.assertRaises(
|
499
|
+
ValueError, lambda: failure_metric_annotated_method_error(mock)
|
500
|
+
)
|
501
|
+
|
502
|
+
mock.assert_not_called()
|
503
|
+
self.assertEqual(2, mock_target.call_count)
|
504
|
+
mock_target.assert_has_calls(
|
505
|
+
[
|
506
|
+
call(
|
507
|
+
metrics_name="failure_metric_annotated_method_error_failure_count.ValueError",
|
508
|
+
metrics_config=ANY,
|
509
|
+
value=ANY,
|
510
|
+
),
|
511
|
+
call(
|
512
|
+
metrics_name="failure_metric_annotated_method_error_failure_count",
|
513
|
+
metrics_config=ANY,
|
514
|
+
value=ANY,
|
515
|
+
),
|
516
|
+
],
|
517
|
+
any_order=True,
|
518
|
+
)
|
519
|
+
|
520
|
+
def test_annotation_with_args_sanity(self):
|
521
|
+
mock, mock_target = MagicMock(), MagicMock()
|
522
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
523
|
+
metrics_actor = MetricsActor.options(
|
524
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
525
|
+
).remote()
|
526
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
527
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
528
|
+
|
529
|
+
# action
|
530
|
+
failure_metric_with_name_annotated_method(mock)
|
531
|
+
|
532
|
+
mock.assert_called_once()
|
533
|
+
mock_target.assert_not_called()
|
534
|
+
|
535
|
+
def test_annotation_with_args_when_error(self):
|
536
|
+
mock, mock_target = MagicMock(), MagicMock()
|
537
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
538
|
+
metrics_actor = MetricsActor.options(
|
539
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
540
|
+
).remote()
|
541
|
+
config = MetricsConfig("us-east-1", MetricsTarget.NOOP)
|
542
|
+
ray.get(metrics_actor.set_metrics_config.remote(config))
|
543
|
+
|
544
|
+
# action
|
545
|
+
self.assertRaises(
|
546
|
+
ValueError, lambda: failure_metric_with_name_annotated_method_error(mock)
|
547
|
+
)
|
548
|
+
|
549
|
+
mock.assert_not_called()
|
550
|
+
self.assertEqual(2, mock_target.call_count)
|
551
|
+
mock_target.assert_has_calls(
|
552
|
+
[
|
553
|
+
call(metrics_name="test.ValueError", metrics_config=ANY, value=ANY),
|
554
|
+
call(metrics_name="test", metrics_config=ANY, value=ANY),
|
555
|
+
],
|
556
|
+
any_order=True,
|
557
|
+
)
|
558
|
+
|
559
|
+
def test_annotation_without_actor(self):
|
560
|
+
mock, mock_target = MagicMock(), MagicMock()
|
561
|
+
METRICS_TARGET_TO_EMITTER_DICT[MetricsTarget.NOOP] = mock_target
|
562
|
+
metrics_actor = MetricsActor.options(
|
563
|
+
name=METRICS_CONFIG_ACTOR_NAME, get_if_exists=True
|
564
|
+
).remote()
|
565
|
+
|
566
|
+
# explicitly making sure actor is killed
|
567
|
+
ray.kill(metrics_actor)
|
568
|
+
|
569
|
+
# action
|
570
|
+
self.assertRaises(
|
571
|
+
ValueError, lambda: failure_metric_with_name_annotated_method_error(mock)
|
572
|
+
)
|
573
|
+
|
574
|
+
mock.assert_not_called()
|
575
|
+
mock_target.assert_not_called()
|