deltafi 2.0rc1720728217472__py3-none-any.whl → 2.0rc1720817063181__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.
- deltafi/action.py +21 -123
- deltafi/actiontype.py +2 -6
- deltafi/domain.py +66 -62
- deltafi/exception.py +0 -10
- deltafi/input.py +1 -165
- deltafi/plugin.py +9 -17
- deltafi/result.py +32 -245
- deltafi/test_kit/framework.py +69 -66
- deltafi/test_kit/transform.py +41 -13
- {deltafi-2.0rc1720728217472.dist-info → deltafi-2.0rc1720817063181.dist-info}/METADATA +5 -5
- deltafi-2.0rc1720817063181.dist-info/RECORD +23 -0
- deltafi/test_kit/domain.py +0 -59
- deltafi/test_kit/enrich.py +0 -70
- deltafi/test_kit/format.py +0 -105
- deltafi/test_kit/load.py +0 -128
- deltafi/test_kit/validate.py +0 -54
- deltafi-2.0rc1720728217472.dist-info/RECORD +0 -28
- {deltafi-2.0rc1720728217472.dist-info → deltafi-2.0rc1720817063181.dist-info}/WHEEL +0 -0
deltafi/result.py
CHANGED
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
#
|
|
18
18
|
|
|
19
19
|
import abc
|
|
20
|
-
from enum import Enum
|
|
21
20
|
import uuid
|
|
22
|
-
from
|
|
21
|
+
from enum import Enum
|
|
22
|
+
from typing import NamedTuple
|
|
23
23
|
|
|
24
24
|
from deltafi.domain import Content, Context
|
|
25
25
|
from deltafi.metric import Metric
|
|
@@ -44,22 +44,8 @@ class Result:
|
|
|
44
44
|
|
|
45
45
|
def add_metric(self, metric: Metric):
|
|
46
46
|
self.metrics.append(metric)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class DomainResult(Result):
|
|
50
|
-
def __init__(self, context: Context):
|
|
51
|
-
super().__init__('domain', 'DOMAIN', context)
|
|
52
|
-
self.annotations = {}
|
|
53
|
-
|
|
54
|
-
def annotate(self, key: str, value: str):
|
|
55
|
-
self.annotations[key] = value
|
|
56
47
|
return self
|
|
57
48
|
|
|
58
|
-
def response(self):
|
|
59
|
-
return {
|
|
60
|
-
'annotations': self.annotations
|
|
61
|
-
}
|
|
62
|
-
|
|
63
49
|
|
|
64
50
|
class EgressResult(Result):
|
|
65
51
|
def __init__(self, context: Context, destination: str, bytes_egressed: int):
|
|
@@ -71,31 +57,6 @@ class EgressResult(Result):
|
|
|
71
57
|
return None
|
|
72
58
|
|
|
73
59
|
|
|
74
|
-
class EnrichResult(Result):
|
|
75
|
-
def __init__(self, context: Context):
|
|
76
|
-
super().__init__('enrich', 'ENRICH', context)
|
|
77
|
-
self.enrichments = []
|
|
78
|
-
self.annotations = {}
|
|
79
|
-
|
|
80
|
-
def enrich(self, name: str, value: str, media_type: str):
|
|
81
|
-
self.enrichments.append({
|
|
82
|
-
'name': name,
|
|
83
|
-
'value': value,
|
|
84
|
-
'mediaType': media_type
|
|
85
|
-
})
|
|
86
|
-
return self
|
|
87
|
-
|
|
88
|
-
def annotate(self, key: str, value: str):
|
|
89
|
-
self.annotations[key] = value
|
|
90
|
-
return self
|
|
91
|
-
|
|
92
|
-
def response(self):
|
|
93
|
-
return {
|
|
94
|
-
'enrichments': self.enrichments,
|
|
95
|
-
'annotations': self.annotations
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
99
60
|
class ErrorResult(Result):
|
|
100
61
|
def __init__(self, context: Context, error_cause: str, error_context: str):
|
|
101
62
|
super().__init__('error', 'ERROR', context)
|
|
@@ -116,7 +77,7 @@ class ErrorResult(Result):
|
|
|
116
77
|
|
|
117
78
|
|
|
118
79
|
class FilterResult(Result):
|
|
119
|
-
def __init__(self, context: Context, filtered_cause: str, filtered_context: str=None):
|
|
80
|
+
def __init__(self, context: Context, filtered_cause: str, filtered_context: str = None):
|
|
120
81
|
super().__init__('filter', 'FILTER', context)
|
|
121
82
|
self.filtered_cause = filtered_cause
|
|
122
83
|
self.filtered_context = filtered_context
|
|
@@ -134,87 +95,13 @@ class FilterResult(Result):
|
|
|
134
95
|
}
|
|
135
96
|
|
|
136
97
|
|
|
137
|
-
class FormatResult(Result):
|
|
138
|
-
def __init__(self, context: Context):
|
|
139
|
-
super().__init__('format', 'FORMAT', context)
|
|
140
|
-
self.content = None
|
|
141
|
-
self.delete_metadata_keys = []
|
|
142
|
-
self.metadata = {}
|
|
143
|
-
|
|
144
|
-
def set_metadata(self, metadata: dict):
|
|
145
|
-
self.metadata = metadata
|
|
146
|
-
return self
|
|
147
|
-
|
|
148
|
-
def add_metadata(self, key: str, value: str):
|
|
149
|
-
self.metadata[key] = value
|
|
150
|
-
return self
|
|
151
|
-
|
|
152
|
-
def delete_metadata_key(self, key: str):
|
|
153
|
-
self.delete_metadata_keys.append(key)
|
|
154
|
-
return self
|
|
155
|
-
|
|
156
|
-
def set_content(self, content: Content):
|
|
157
|
-
self.content = content
|
|
158
|
-
return self
|
|
159
|
-
|
|
160
|
-
def save_string_content(self, string_data: str, name: str, media_type: str):
|
|
161
|
-
segment = self.context.content_service.put_str(self.context.did, string_data)
|
|
162
|
-
self.content = Content(name=name, segments=[segment], media_type=media_type,
|
|
163
|
-
content_service=self.context.content_service)
|
|
164
|
-
return self
|
|
165
|
-
|
|
166
|
-
def save_byte_content(self, byte_data: bytes, name: str, media_type: str):
|
|
167
|
-
segment = self.context.content_service.put_bytes(self.context.did, byte_data)
|
|
168
|
-
self.content = Content(name=name, segments=[segment], media_type=media_type,
|
|
169
|
-
content_service=self.context.content_service)
|
|
170
|
-
return self
|
|
171
|
-
|
|
172
|
-
def response(self):
|
|
173
|
-
return {
|
|
174
|
-
'content': self.content.json(),
|
|
175
|
-
'metadata': self.metadata,
|
|
176
|
-
'deleteMetadataKeys': self.delete_metadata_keys
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
class ChildFormatResult:
|
|
181
|
-
def __init__(self, format_result: FormatResult = None):
|
|
182
|
-
self._did = str(uuid.uuid4())
|
|
183
|
-
self.format_result = format_result
|
|
184
|
-
|
|
185
|
-
@property
|
|
186
|
-
def did(self):
|
|
187
|
-
return self._did
|
|
188
|
-
|
|
189
|
-
def response(self):
|
|
190
|
-
res = self.format_result.response()
|
|
191
|
-
res["did"] = self._did
|
|
192
|
-
return res
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
class FormatManyResult(Result):
|
|
196
|
-
def __init__(self, context: Context):
|
|
197
|
-
super().__init__('formatMany', 'FORMAT_MANY', context)
|
|
198
|
-
self.format_results = []
|
|
199
|
-
|
|
200
|
-
def add_format_result(self, format_result):
|
|
201
|
-
if isinstance(format_result, ChildFormatResult):
|
|
202
|
-
self.format_results.append(format_result)
|
|
203
|
-
else:
|
|
204
|
-
self.format_results.append(ChildFormatResult(format_result))
|
|
205
|
-
return self
|
|
206
|
-
|
|
207
|
-
def response(self):
|
|
208
|
-
return [format_result.response() for format_result in self.format_results]
|
|
209
|
-
|
|
210
|
-
|
|
211
98
|
class IngressResultItem:
|
|
212
|
-
def __init__(self, context: Context,
|
|
99
|
+
def __init__(self, context: Context, delta_file_name: str):
|
|
213
100
|
self.context = context
|
|
214
|
-
self.filename = filename
|
|
215
101
|
self._did = str(uuid.uuid4())
|
|
216
102
|
self.content = []
|
|
217
103
|
self.metadata = {}
|
|
104
|
+
self.delta_file_name = delta_file_name
|
|
218
105
|
|
|
219
106
|
@property
|
|
220
107
|
def did(self):
|
|
@@ -253,7 +140,7 @@ class IngressResultItem:
|
|
|
253
140
|
def response(self):
|
|
254
141
|
return {
|
|
255
142
|
'did': self._did,
|
|
256
|
-
'
|
|
143
|
+
'deltaFileName': self.delta_file_name,
|
|
257
144
|
'metadata': self.metadata,
|
|
258
145
|
'content': [content.json() for content in self.content]
|
|
259
146
|
}
|
|
@@ -269,10 +156,10 @@ class IngressResult(Result):
|
|
|
269
156
|
def __init__(self, context: Context):
|
|
270
157
|
super().__init__('ingress', 'INGRESS', context)
|
|
271
158
|
self.memo = None
|
|
272
|
-
self.execute_immediate = False
|
|
273
159
|
self.ingress_result_items = []
|
|
160
|
+
self.execute_immediate = False
|
|
274
161
|
self.status = IngressStatusEnum.HEALTHY
|
|
275
|
-
self.
|
|
162
|
+
self.status_message = None
|
|
276
163
|
|
|
277
164
|
def add_item(self, ingress_result_item: IngressResultItem):
|
|
278
165
|
self.ingress_result_items.append(ingress_result_item)
|
|
@@ -284,17 +171,16 @@ class IngressResult(Result):
|
|
|
284
171
|
'executeImmediate': self.execute_immediate,
|
|
285
172
|
'ingressItems': [ingress_result_item.response() for ingress_result_item in self.ingress_result_items],
|
|
286
173
|
'status': self.status.value,
|
|
287
|
-
'statusMessage': self.
|
|
174
|
+
'statusMessage': self.status_message
|
|
288
175
|
}
|
|
289
176
|
|
|
290
177
|
|
|
291
|
-
class
|
|
178
|
+
class TransformResult(Result):
|
|
292
179
|
def __init__(self, context: Context):
|
|
293
|
-
super().__init__('
|
|
180
|
+
super().__init__('transform', 'TRANSFORM', context)
|
|
294
181
|
self.content = []
|
|
295
|
-
self.metadata = {}
|
|
296
|
-
self.domains = []
|
|
297
182
|
self.annotations = {}
|
|
183
|
+
self.metadata = {}
|
|
298
184
|
self.delete_metadata_keys = []
|
|
299
185
|
|
|
300
186
|
# content can be a single Content or a List[Content]
|
|
@@ -327,13 +213,6 @@ class LoadResult(Result):
|
|
|
327
213
|
self.metadata[key] = value
|
|
328
214
|
return self
|
|
329
215
|
|
|
330
|
-
def add_domain(self, name: str, value: str, media_type: str):
|
|
331
|
-
self.domains.append({
|
|
332
|
-
'name': name,
|
|
333
|
-
'value': value,
|
|
334
|
-
'mediaType': media_type})
|
|
335
|
-
return self
|
|
336
|
-
|
|
337
216
|
def annotate(self, key: str, value: str):
|
|
338
217
|
self.annotations[key] = value
|
|
339
218
|
return self
|
|
@@ -342,133 +221,41 @@ class LoadResult(Result):
|
|
|
342
221
|
self.delete_metadata_keys.append(key)
|
|
343
222
|
return self
|
|
344
223
|
|
|
345
|
-
def
|
|
224
|
+
def json(self):
|
|
346
225
|
return {
|
|
347
|
-
'domains': self.domains,
|
|
348
226
|
'content': [content.json() for content in self.content],
|
|
349
|
-
'metadata': self.metadata,
|
|
350
227
|
'annotations': self.annotations,
|
|
228
|
+
'metadata': self.metadata,
|
|
351
229
|
'deleteMetadataKeys': self.delete_metadata_keys
|
|
352
230
|
}
|
|
353
231
|
|
|
354
|
-
|
|
355
|
-
class ChildLoadResult:
|
|
356
|
-
def __init__(self, load_result: LoadResult = None):
|
|
357
|
-
self._did = str(uuid.uuid4())
|
|
358
|
-
self.load_result = load_result
|
|
359
|
-
|
|
360
|
-
@property
|
|
361
|
-
def did(self):
|
|
362
|
-
return self._did
|
|
363
|
-
|
|
364
|
-
def response(self):
|
|
365
|
-
res = self.load_result.response()
|
|
366
|
-
res["did"] = self._did
|
|
367
|
-
return res
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
class LoadManyResult(Result):
|
|
371
|
-
def __init__(self, context: Context):
|
|
372
|
-
super().__init__('loadMany', 'LOAD_MANY', context)
|
|
373
|
-
self.load_results = []
|
|
374
|
-
|
|
375
|
-
def add_load_result(self, load_result):
|
|
376
|
-
if isinstance(load_result, ChildLoadResult):
|
|
377
|
-
self.load_results.append(load_result)
|
|
378
|
-
else:
|
|
379
|
-
self.load_results.append(ChildLoadResult(load_result))
|
|
380
|
-
return self
|
|
381
|
-
|
|
382
232
|
def response(self):
|
|
383
|
-
return [
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
class ReinjectResult(Result):
|
|
387
|
-
class ReinjectChild:
|
|
388
|
-
def __init__(self, filename: str, flow: str, content: List[Content], metadata: Dict[str, str]):
|
|
389
|
-
self.filename = filename
|
|
390
|
-
self.flow = flow
|
|
391
|
-
self.content = content
|
|
392
|
-
self.metadata = metadata
|
|
233
|
+
return [self.json()]
|
|
393
234
|
|
|
394
|
-
def json(self):
|
|
395
|
-
return {
|
|
396
|
-
'filename': self.filename,
|
|
397
|
-
'flow': self.flow,
|
|
398
|
-
'metadata': self.metadata,
|
|
399
|
-
'content': [content.json() for content in self.content]
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
def __init__(self, context: Context):
|
|
403
|
-
super().__init__('reinject', 'REINJECT', context)
|
|
404
|
-
self.children = []
|
|
405
235
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
236
|
+
class NamedTransformResult(NamedTuple):
|
|
237
|
+
result: TransformResult
|
|
238
|
+
name: str
|
|
409
239
|
|
|
410
|
-
def
|
|
411
|
-
|
|
240
|
+
def json(self):
|
|
241
|
+
j = self.result.json()
|
|
242
|
+
if self.name is not None:
|
|
243
|
+
j['name'] = self.name
|
|
244
|
+
return j
|
|
412
245
|
|
|
413
246
|
|
|
414
|
-
class
|
|
247
|
+
class TransformResults(Result):
|
|
415
248
|
def __init__(self, context: Context):
|
|
416
249
|
super().__init__('transform', 'TRANSFORM', context)
|
|
417
|
-
self.
|
|
418
|
-
self.metadata = {}
|
|
419
|
-
self.annotations = {}
|
|
420
|
-
self.delete_metadata_keys = []
|
|
421
|
-
|
|
422
|
-
# content can be a single Content or a List[Content]
|
|
423
|
-
def add_content(self, content):
|
|
424
|
-
if content:
|
|
425
|
-
if type(content) == list:
|
|
426
|
-
self.content.extend(content)
|
|
427
|
-
else:
|
|
428
|
-
self.content.append(content)
|
|
250
|
+
self.named_results = []
|
|
429
251
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
def save_string_content(self, string_data: str, name: str, media_type: str):
|
|
433
|
-
segment = self.context.content_service.put_str(self.context.did, string_data)
|
|
434
|
-
self.content.append(
|
|
435
|
-
Content(name=name, segments=[segment], media_type=media_type, content_service=self.context.content_service))
|
|
436
|
-
return self
|
|
437
|
-
|
|
438
|
-
def save_byte_content(self, byte_data: bytes, name: str, media_type: str):
|
|
439
|
-
segment = self.context.content_service.put_bytes(self.context.did, byte_data)
|
|
440
|
-
self.content.append(
|
|
441
|
-
Content(name=name, segments=[segment], media_type=media_type, content_service=self.context.content_service))
|
|
442
|
-
return self
|
|
443
|
-
|
|
444
|
-
def set_metadata(self, metadata: dict):
|
|
445
|
-
self.metadata = metadata
|
|
446
|
-
return self
|
|
447
|
-
|
|
448
|
-
def add_metadata(self, key: str, value: str):
|
|
449
|
-
self.metadata[key] = value
|
|
450
|
-
return self
|
|
451
|
-
|
|
452
|
-
def annotate(self, key: str, value: str):
|
|
453
|
-
self.annotations[key] = value
|
|
454
|
-
return self
|
|
455
|
-
|
|
456
|
-
def delete_metadata_key(self, key: str):
|
|
457
|
-
self.delete_metadata_keys.append(key)
|
|
252
|
+
def add_result(self, result: TransformResult, name: str = None):
|
|
253
|
+
self.named_results.append(NamedTransformResult(result, name))
|
|
458
254
|
return self
|
|
459
255
|
|
|
460
256
|
def response(self):
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
class ValidateResult(Result):
|
|
470
|
-
def __init__(self, context: Context):
|
|
471
|
-
super().__init__(None, 'VALIDATE', context)
|
|
472
|
-
|
|
473
|
-
def response(self):
|
|
474
|
-
return None
|
|
257
|
+
transform_events = []
|
|
258
|
+
for named_result in self.named_results:
|
|
259
|
+
json_dict = named_result.json()
|
|
260
|
+
transform_events.append(json_dict)
|
|
261
|
+
return transform_events
|
deltafi/test_kit/framework.py
CHANGED
|
@@ -37,15 +37,20 @@ class IOContent:
|
|
|
37
37
|
The IOContent class holds the details for loading input or output
|
|
38
38
|
content into the test framework.
|
|
39
39
|
Attributes:
|
|
40
|
-
file_name (str): The name of file in test/data.
|
|
41
|
-
content_name (str): The name of the content.
|
|
42
|
-
content_type (str): The media type of the content
|
|
43
|
-
offset (int): Offset to use in Segment
|
|
44
|
-
content_bytes (str):
|
|
40
|
+
file_name (str) : The name of file in test/data.
|
|
41
|
+
content_name (str) : The name of the content.
|
|
42
|
+
content_type (str) : The media type of the content
|
|
43
|
+
offset (int) : Offset to use in Segment
|
|
44
|
+
content_bytes (str): Optional. If set to a String of length greater than zero, indicates to consumers of this
|
|
45
|
+
IOContent that they should bypass file read and use these bytes for content.
|
|
46
|
+
no_content (bool) : Optional. If 'True', then consumers should not attempt to interpret content but should
|
|
47
|
+
apply other aspects of this IOContent. When 'True', 'content_bytes' should be ignored and
|
|
48
|
+
loaded content, if any, should be interpreted as empty String or otherwise as documented by
|
|
49
|
+
the consumer.
|
|
45
50
|
"""
|
|
46
51
|
|
|
47
52
|
def __init__(self, file_name: str, content_name: str = None, content_type: str = None, offset: int = 0,
|
|
48
|
-
content_bytes: str = ""):
|
|
53
|
+
content_bytes: str = "", no_content: bool = False):
|
|
49
54
|
self.file_name = file_name
|
|
50
55
|
if content_name is None:
|
|
51
56
|
self.content_name = file_name
|
|
@@ -56,7 +61,11 @@ class IOContent:
|
|
|
56
61
|
else:
|
|
57
62
|
self.content_type = content_type
|
|
58
63
|
self.offset = offset
|
|
59
|
-
self.
|
|
64
|
+
self.no_content = no_content
|
|
65
|
+
if no_content:
|
|
66
|
+
self.content_bytes = None
|
|
67
|
+
else:
|
|
68
|
+
self.content_bytes = content_bytes
|
|
60
69
|
self.segment_uuid = uuid.uuid4()
|
|
61
70
|
|
|
62
71
|
@classmethod
|
|
@@ -79,7 +88,10 @@ class LoadedContent:
|
|
|
79
88
|
if data is not None:
|
|
80
89
|
self.data = data
|
|
81
90
|
else:
|
|
82
|
-
|
|
91
|
+
if ioc.no_content:
|
|
92
|
+
self.data = ""
|
|
93
|
+
else:
|
|
94
|
+
self.data = ioc.content_bytes
|
|
83
95
|
self.segment = Segment.from_dict(
|
|
84
96
|
{"uuid": str(ioc.segment_uuid), "offset": self.offset, "size": len(self.data), "did": did})
|
|
85
97
|
|
|
@@ -103,6 +115,10 @@ class InternalContentService:
|
|
|
103
115
|
seg_id = segments[0].uuid
|
|
104
116
|
return self.loaded_content[seg_id].data
|
|
105
117
|
|
|
118
|
+
def get_bytes(self, segments: List[Segment]):
|
|
119
|
+
seg_id = segments[0].uuid
|
|
120
|
+
return self.loaded_content[seg_id].data.encode('utf-8')
|
|
121
|
+
|
|
106
122
|
def get_output(self, seg_id: str):
|
|
107
123
|
if seg_id in self.outputs:
|
|
108
124
|
return self.outputs[seg_id]
|
|
@@ -123,8 +139,8 @@ class TestCaseBase(ABC):
|
|
|
123
139
|
- inputs: (optional) List[IOContent]: input content to action
|
|
124
140
|
- parameters: (optional) Dict: map of action input parameters
|
|
125
141
|
- in_meta: (optional) Dict: map of metadata as input to action
|
|
126
|
-
-
|
|
127
|
-
|
|
142
|
+
- join_meta: (optional): List[Dict]: When a List is provided, this enables the JOIN portion of an action.
|
|
143
|
+
When using JOIN, join_meta must match the size of inputs, though the Dict can be empty
|
|
128
144
|
- did: (optional): str: overrides random DID
|
|
129
145
|
"""
|
|
130
146
|
if "action" in data:
|
|
@@ -144,16 +160,14 @@ class TestCaseBase(ABC):
|
|
|
144
160
|
|
|
145
161
|
self.inputs = data["inputs"] if "inputs" in data else []
|
|
146
162
|
self.file_name = data["file_name"] if "file_name" in data else "filename"
|
|
147
|
-
self.outputs = data["outputs"] if "outputs" in data else []
|
|
148
163
|
self.parameters = data["parameters"] if "parameters" in data else {}
|
|
149
164
|
self.in_meta = data["in_meta"] if "in_meta" in data else {}
|
|
150
|
-
self.in_domains = data["in_domains"] if "in_domains" in data else []
|
|
151
|
-
self.in_enrichments = data["in_enrichments"] if "in_enrichments" in data else []
|
|
152
165
|
self.use_did = data["did"] if "did" in data else None
|
|
153
166
|
self.expected_result_type = None
|
|
154
167
|
self.err_or_filt_cause = None
|
|
155
168
|
self.err_or_filt_context = None
|
|
156
169
|
self.err_or_filt_annotations = None
|
|
170
|
+
self.join_meta = data["join_meta"] if "join_meta" in data else None
|
|
157
171
|
self.expected_metrics = []
|
|
158
172
|
|
|
159
173
|
def add_metric(self, metric: Metric):
|
|
@@ -164,7 +178,7 @@ class TestCaseBase(ABC):
|
|
|
164
178
|
A Sets the expected output of the action to an Error Result
|
|
165
179
|
:param cause: the expected error cause
|
|
166
180
|
:param context: the expected error context
|
|
167
|
-
:param annotations (Optional)
|
|
181
|
+
:param annotations: Dict: (Optional) the expected annotations
|
|
168
182
|
"""
|
|
169
183
|
self.expected_result_type = ErrorResult
|
|
170
184
|
self.err_or_filt_cause = cause
|
|
@@ -175,8 +189,8 @@ class TestCaseBase(ABC):
|
|
|
175
189
|
"""
|
|
176
190
|
A Sets the expected output of the action to a Filter Result
|
|
177
191
|
:param cause: the expected filter cause (message)
|
|
178
|
-
:param context (Optional)
|
|
179
|
-
:param annotations (Optional)
|
|
192
|
+
:param context: (Optional) the expected filter context
|
|
193
|
+
:param annotations: Dict: (Optional) the expected annotations
|
|
180
194
|
"""
|
|
181
195
|
self.expected_result_type = FilterResult
|
|
182
196
|
self.err_or_filt_cause = cause
|
|
@@ -193,7 +207,6 @@ class ActionTest(ABC):
|
|
|
193
207
|
"""
|
|
194
208
|
self.content_service = InternalContentService()
|
|
195
209
|
self.did = ""
|
|
196
|
-
self.expected_outputs = []
|
|
197
210
|
self.loaded_inputs = []
|
|
198
211
|
self.package_name = package_name
|
|
199
212
|
self.res_path = ""
|
|
@@ -204,7 +217,6 @@ class ActionTest(ABC):
|
|
|
204
217
|
self.did = str(uuid.uuid4())
|
|
205
218
|
else:
|
|
206
219
|
self.did = did
|
|
207
|
-
self.expected_outputs = []
|
|
208
220
|
self.loaded_inputs = []
|
|
209
221
|
self.res_path = ""
|
|
210
222
|
|
|
@@ -220,19 +232,12 @@ class ActionTest(ABC):
|
|
|
220
232
|
|
|
221
233
|
# Load inputs
|
|
222
234
|
for input_ioc in test_case.inputs:
|
|
223
|
-
if len(input_ioc.content_bytes) == 0:
|
|
235
|
+
if not input_ioc.no_content and len(input_ioc.content_bytes) == 0:
|
|
224
236
|
self.loaded_inputs.append(LoadedContent(self.did, input_ioc, self.load_file(input_ioc)))
|
|
225
237
|
else:
|
|
226
238
|
self.loaded_inputs.append(LoadedContent(self.did, input_ioc, None))
|
|
227
239
|
|
|
228
|
-
|
|
229
|
-
for output_ioc in test_case.outputs:
|
|
230
|
-
if len(output_ioc.content_bytes) == 0:
|
|
231
|
-
self.expected_outputs.append(LoadedContent(self.did, output_ioc, self.load_file(output_ioc)))
|
|
232
|
-
else:
|
|
233
|
-
self.expected_outputs.append(LoadedContent(self.did, output_ioc, None))
|
|
234
|
-
|
|
235
|
-
def make_content_list(self, test_case: TestCaseBase):
|
|
240
|
+
def make_content_list(self):
|
|
236
241
|
content_list = []
|
|
237
242
|
for loaded_input in self.loaded_inputs:
|
|
238
243
|
c = Content(name=loaded_input.name, segments=[loaded_input.segment], media_type=loaded_input.content_type,
|
|
@@ -242,34 +247,42 @@ class ActionTest(ABC):
|
|
|
242
247
|
|
|
243
248
|
return content_list
|
|
244
249
|
|
|
245
|
-
def
|
|
246
|
-
content_list = self.make_content_list(
|
|
250
|
+
def make_df_msgs(self, test_case: TestCaseBase):
|
|
251
|
+
content_list = self.make_content_list()
|
|
247
252
|
self.content_service.load(self.loaded_inputs)
|
|
248
253
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
+
delta_file_messages = []
|
|
255
|
+
|
|
256
|
+
if test_case.join_meta is None:
|
|
257
|
+
delta_file_messages.append(DeltaFileMessage(metadata=test_case.in_meta, content_list=content_list))
|
|
258
|
+
else:
|
|
259
|
+
for index, content in enumerate(content_list):
|
|
260
|
+
delta_file_messages.append(DeltaFileMessage(
|
|
261
|
+
metadata=test_case.join_meta[index],
|
|
262
|
+
content_list=[content]))
|
|
263
|
+
|
|
264
|
+
return delta_file_messages
|
|
254
265
|
|
|
255
266
|
def make_context(self, test_case: TestCaseBase):
|
|
256
267
|
action_name = INGRESS_FLOW + "." + test_case.action.__class__.__name__
|
|
268
|
+
join = {} if test_case.join_meta else None
|
|
257
269
|
return Context(
|
|
258
270
|
did=self.did,
|
|
259
|
-
|
|
271
|
+
delta_file_name=test_case.file_name,
|
|
272
|
+
data_source="DATASRC",
|
|
273
|
+
flow_name=INGRESS_FLOW,
|
|
274
|
+
flow_id="FLOWID",
|
|
260
275
|
action_name=action_name,
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
egress_flow=EGRESS_FLOW,
|
|
264
|
-
system=SYSTEM,
|
|
276
|
+
action_id="ACTIONID",
|
|
277
|
+
action_version="1.0",
|
|
265
278
|
hostname=HOSTNAME,
|
|
279
|
+
system_name=SYSTEM,
|
|
266
280
|
content_service=self.content_service,
|
|
267
|
-
|
|
268
|
-
collected_dids=None,
|
|
281
|
+
join=join,
|
|
269
282
|
logger=get_logger())
|
|
270
283
|
|
|
271
284
|
def make_event(self, test_case: TestCaseBase):
|
|
272
|
-
return Event(delta_file_messages=
|
|
285
|
+
return Event(delta_file_messages=self.make_df_msgs(test_case), context=self.make_context(test_case),
|
|
273
286
|
params=test_case.parameters, queue_name="", return_address="")
|
|
274
287
|
|
|
275
288
|
def call_action(self, test_case: TestCaseBase):
|
|
@@ -311,37 +324,27 @@ class ActionTest(ABC):
|
|
|
311
324
|
else:
|
|
312
325
|
raise ValueError(f"unknown type: {test_case.expected_result_type}")
|
|
313
326
|
|
|
314
|
-
|
|
327
|
+
@staticmethod
|
|
328
|
+
def compare_content_details(expected: LoadedContent, actual: Content):
|
|
315
329
|
assert_equal(expected.content_type, actual.media_type)
|
|
316
330
|
assert_equal(expected.name, actual.name)
|
|
317
331
|
|
|
318
|
-
def compare_one_content(self,
|
|
332
|
+
def compare_one_content(self, comparator: CompareHelper, expected: LoadedContent, actual, index):
|
|
319
333
|
self.compare_content_details(expected, actual)
|
|
320
334
|
seg_id = actual.segments[0].uuid
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
def
|
|
324
|
-
assert_equal_len(
|
|
325
|
-
for index,
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
def compare_domains(self, comparitor: CompareHelper, expected_items: List[Dict], results: List[Dict]):
|
|
329
|
-
assert_equal_len(expected_items, results)
|
|
330
|
-
for index, expected in enumerate(expected_items):
|
|
331
|
-
actual = results[index]
|
|
332
|
-
assert_equal(expected['name'], actual['name'])
|
|
333
|
-
assert_equal(expected['mediaType'], actual['mediaType'])
|
|
334
|
-
|
|
335
|
-
expected_value = expected['value']
|
|
336
|
-
if type(expected_value) == str:
|
|
337
|
-
comparitor.compare(expected_value, actual['value'], f"Domain[{index}]")
|
|
338
|
-
elif type(expected_value) == IOContent:
|
|
339
|
-
expected_data = self.load_file(expected_value)
|
|
340
|
-
comparitor.compare(expected_data, actual['value'], f"Domain[{index}]")
|
|
335
|
+
comparator.compare(expected.data, self.content_service.get_output(seg_id), f"Content[{index}]")
|
|
336
|
+
|
|
337
|
+
def compare_content_list(self, comparator: CompareHelper, expected_outputs: List[IOContent], content: List):
|
|
338
|
+
assert_equal_len(expected_outputs, content)
|
|
339
|
+
for index, expected_ioc in enumerate(expected_outputs):
|
|
340
|
+
if not expected_ioc.no_content and len(expected_ioc.content_bytes) == 0:
|
|
341
|
+
expected = LoadedContent(self.did, expected_ioc, self.load_file(expected_ioc))
|
|
341
342
|
else:
|
|
342
|
-
|
|
343
|
+
expected = LoadedContent(self.did, expected_ioc, None)
|
|
344
|
+
self.compare_one_content(comparator, expected, content[index], index)
|
|
343
345
|
|
|
344
|
-
|
|
346
|
+
@staticmethod
|
|
347
|
+
def compare_one_metric(expected: Metric, result: Metric):
|
|
345
348
|
assert expected.name == result.name
|
|
346
349
|
assert_equal_with_label(expected.value, result.value, expected.name)
|
|
347
350
|
assert_keys_and_values(expected.tags, result.tags)
|