tts-data-utils 0.7.3__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.
- tts_data_utils/__init__.py +0 -0
- tts_data_utils/core/__init__.py +0 -0
- tts_data_utils/core/container_history.py +79 -0
- tts_data_utils/core/data_container.py +2102 -0
- tts_data_utils/core/data_item.py +487 -0
- tts_data_utils/core/diff.py +155 -0
- tts_data_utils/core/generic.py +78 -0
- tts_data_utils/core/lorem_utils.py +206 -0
- tts_data_utils/core/visual_diff.py +148 -0
- tts_data_utils/invulnerable_data_manager/__init__.py +0 -0
- tts_data_utils/invulnerable_data_manager/batch.py +176 -0
- tts_data_utils/invulnerable_data_manager/invulnerable_data_manager.py +171 -0
- tts_data_utils/invulnerable_data_manager/utilities.py +151 -0
- tts_data_utils/multimission/__init__.py +0 -0
- tts_data_utils/multimission/alarms.py +109 -0
- tts_data_utils/multimission/eha.py +253 -0
- tts_data_utils/multimission/evr.py +340 -0
- tts_data_utils/multimission/evr_gaps.py +148 -0
- tts_data_utils/multimission/expected_lad.py +161 -0
- tts_data_utils/multimission/planning_rule.py +106 -0
- tts_data_utils/multimission/taco.py +53 -0
- tts_data_utils/test/__init__.py +0 -0
- tts_data_utils/test/core/__init__.py +0 -0
- tts_data_utils/test/core/test_data_container.py +403 -0
- tts_data_utils/test/core/test_data_item.py +92 -0
- tts_data_utils/test/core/test_diff.py +173 -0
- tts_data_utils/test/core/test_files/diff/diff_dict/actual_diff.csv +5135 -0
- tts_data_utils/test/core/test_files/diff/diff_dict/expected_diff.csv +5135 -0
- tts_data_utils/test/core/test_files/diff/diff_dict/left.csv +637 -0
- tts_data_utils/test/core/test_files/diff/diff_dict/right.csv +637 -0
- tts_data_utils/test/core/test_files/diff/diff_list/actual_diff.csv +5135 -0
- tts_data_utils/test/core/test_files/diff/diff_list/expected_diff.csv +5135 -0
- tts_data_utils/test/core/test_files/diff/diff_list/left.csv +637 -0
- tts_data_utils/test/core/test_files/diff/diff_list/right.csv +637 -0
- tts_data_utils/test/core/test_files/diff/diff_list_size/actual_diff.csv +33 -0
- tts_data_utils/test/core/test_files/diff/diff_list_size/expected_diff.csv +33 -0
- tts_data_utils/test/core/test_files/diff/diff_list_size/left.csv +637 -0
- tts_data_utils/test/core/test_files/diff/diff_list_size/right.csv +637 -0
- tts_data_utils/test/core/test_files/diff/diff_simple_types/actual_diff.csv +17894 -0
- tts_data_utils/test/core/test_files/diff/diff_simple_types/expected_diff.csv +17894 -0
- tts_data_utils/test/core/test_files/diff/diff_simple_types/left.csv +637 -0
- tts_data_utils/test/core/test_files/diff/diff_simple_types/right.csv +637 -0
- tts_data_utils/test/core/test_files/diff/diff_type/actual_diff.csv +5135 -0
- tts_data_utils/test/core/test_files/diff/diff_type/expected_diff.csv +5135 -0
- tts_data_utils/test/core/test_files/diff/diff_type/left.csv +637 -0
- tts_data_utils/test/core/test_files/diff/diff_type/right.csv +637 -0
- tts_data_utils/test/core/test_files/diff/same_not_same/actual_diff.csv +5135 -0
- tts_data_utils/test/core/test_files/visdiff/adjacent_insert_delete.html +1581 -0
- tts_data_utils/test/core/test_files/visdiff/insert_and_delete.html +1581 -0
- tts_data_utils/test/core/test_files/visdiff/no_diff.html +1581 -0
- tts_data_utils/test/core/test_files/visdiff/overlapping_insert_delete.html +1541 -0
- tts_data_utils/test/core/test_files/visdiff/replace.html +1581 -0
- tts_data_utils/test/core/test_files/visdiff/replace_with_delete.html +1581 -0
- tts_data_utils/test/core/test_files/visdiff/simple_delete.html +1581 -0
- tts_data_utils/test/core/test_files/visdiff/simple_insert.html +1581 -0
- tts_data_utils/test/core/test_files/visdiff/stressing_case.html +2061 -0
- tts_data_utils/test/core/test_filters.py +319 -0
- tts_data_utils/test/core/test_generic_container.py +22 -0
- tts_data_utils/test/core/test_history.py +44 -0
- tts_data_utils/test/core/test_visdiff.py +193 -0
- tts_data_utils/test/invulnerable_data_manager/test_invulnerable_data_manager.py +150 -0
- tts_data_utils/test/multimission/__init__.py +0 -0
- tts_data_utils/test/multimission/evr/__init__.py +0 -0
- tts_data_utils/test/multimission/evr/test_evr.py +29 -0
- tts_data_utils/test/multimission/evr/test_files/actual_evr_gaps.csv +12 -0
- tts_data_utils/test/multimission/evr/test_files/evrs_with_gaps.csv +30 -0
- tts_data_utils/test/multimission/evr/test_files/expected_evr_gaps.csv +12 -0
- tts_data_utils/util.py +104 -0
- tts_data_utils-0.7.3.dist-info/METADATA +81 -0
- tts_data_utils-0.7.3.dist-info/RECORD +72 -0
- tts_data_utils-0.7.3.dist-info/WHEEL +5 -0
- tts_data_utils-0.7.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
#Standard Library Imports
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import pdb
|
|
4
|
+
|
|
5
|
+
#Installed Library Importsimport pytest
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
#Teamtool Studio Imports
|
|
10
|
+
from tts_utilities.logger import create_logger
|
|
11
|
+
from tts_utilities.test_utilities import safe_test_paths
|
|
12
|
+
from tts_html_utils.visdiff.visdiff import VisualDiff
|
|
13
|
+
from tts_html_utils.core.compiler import HtmlCompiler
|
|
14
|
+
|
|
15
|
+
#This Library Imports
|
|
16
|
+
from tts_data_utils.core.generic import GenericContainer
|
|
17
|
+
|
|
18
|
+
logger = create_logger(f'data_utils.core.filters')
|
|
19
|
+
TEST_INPUT_DIR, TEST_OUTPUT_DIR = safe_test_paths(Path(__file__).parent, 'test_files/visdiff')
|
|
20
|
+
|
|
21
|
+
def save_html(visdiff_left, visdiff_right, filepath):
|
|
22
|
+
power_table_left = visdiff_left.power_table(id='visdiff-left', style={'width': '130%', 'float': 'left'})
|
|
23
|
+
power_table_right = visdiff_right.power_table(id='visdiff-right', style={'width': '130%', 'float': 'right'})
|
|
24
|
+
compiler = HtmlCompiler('VisDiff Test')
|
|
25
|
+
compiler.add_body_component(VisualDiff(power_table_left, power_table_right))
|
|
26
|
+
file = open(filepath, 'w')
|
|
27
|
+
file.write(compiler.render())
|
|
28
|
+
file.close()
|
|
29
|
+
|
|
30
|
+
@pytest.fixture(scope="module")
|
|
31
|
+
def test_container():
|
|
32
|
+
time = [datetime.fromtimestamp(ii) for ii in range(100)]
|
|
33
|
+
col1 = [ii for ii in range(50)]*2
|
|
34
|
+
col2 = [ii for ii in range(100, 200)]
|
|
35
|
+
col3 = [str(ii) for ii in range(200, 300)]
|
|
36
|
+
col4 = [ii for ii in range(300, 400)]
|
|
37
|
+
col5 = [ii for ii in range(400, 500)]
|
|
38
|
+
raw_data = [{
|
|
39
|
+
'Time': t,
|
|
40
|
+
'Column 1': c1,
|
|
41
|
+
'Column 2': c2,
|
|
42
|
+
'Column 3': c3,
|
|
43
|
+
'Column 4': c4,
|
|
44
|
+
'Column 5': c5,
|
|
45
|
+
} for t, c1, c2, c3, c4, c5 in zip(time, col1, col2, col3, col4, col5)]
|
|
46
|
+
test_container = GenericContainer(raw_data=raw_data)
|
|
47
|
+
return test_container
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class TestVisDiff:
|
|
51
|
+
def test_no_diff(self, test_container):
|
|
52
|
+
visdiff_left, visdiff_right = test_container.visual_diff(test_container)
|
|
53
|
+
save_html(visdiff_left, visdiff_right, TEST_OUTPUT_DIR.joinpath('no_diff.html'))
|
|
54
|
+
|
|
55
|
+
assert visdiff_left['_visdiff_match'] == ['equal']*100
|
|
56
|
+
assert visdiff_left['_visdiff_index'] == [ii for ii in range(100)]
|
|
57
|
+
assert visdiff_left['_mismatched_keys'] == [[]]*100
|
|
58
|
+
|
|
59
|
+
assert visdiff_right['_visdiff_match'] == ['equal']*100
|
|
60
|
+
assert visdiff_right['_visdiff_index'] == [ii for ii in range(100)]
|
|
61
|
+
assert visdiff_right['_mismatched_keys'] == [[]]*100
|
|
62
|
+
|
|
63
|
+
def test_simple_delete(self, test_container):
|
|
64
|
+
left = test_container
|
|
65
|
+
right = test_container[:10] + test_container[20:]
|
|
66
|
+
visdiff_left, visdiff_right = left.visual_diff(right)
|
|
67
|
+
|
|
68
|
+
save_html(visdiff_left, visdiff_right, TEST_OUTPUT_DIR.joinpath('simple_delete.html'))
|
|
69
|
+
|
|
70
|
+
assert visdiff_left['_visdiff_match'] == ['equal']*10 + ['delete']*10 + ['equal']*80
|
|
71
|
+
assert visdiff_left['_visdiff_index'] == [ii for ii in range(10)] + [None]*10 + [ii for ii in range(10, 90)]
|
|
72
|
+
assert visdiff_left['_mismatched_keys'] == [[]]*100
|
|
73
|
+
|
|
74
|
+
assert visdiff_right['_visdiff_match'] == ['equal']*10 + ['empty_from_delete']*10 + ['equal']*80
|
|
75
|
+
assert visdiff_right['_visdiff_index'] == [ii for ii in range(10)] + [None]*10 + [ii for ii in range(20, 100)]
|
|
76
|
+
assert visdiff_right['_mismatched_keys'] == [[]]*100
|
|
77
|
+
|
|
78
|
+
def test_simple_insert(self, test_container):
|
|
79
|
+
left = test_container[:10] + test_container[20:]
|
|
80
|
+
right = test_container
|
|
81
|
+
visdiff_left, visdiff_right = left.visual_diff(right)
|
|
82
|
+
save_html(visdiff_left, visdiff_right, TEST_OUTPUT_DIR.joinpath('simple_insert.html'))
|
|
83
|
+
|
|
84
|
+
assert visdiff_left['_visdiff_match'] == ['equal']*10 + ['empty_from_insert']*10 + ['equal']*80
|
|
85
|
+
assert visdiff_left['_visdiff_index'] == [ii for ii in range(10)] + [None]*10 + [ii for ii in range(20,100)]
|
|
86
|
+
assert visdiff_left['_mismatched_keys'] == [[]]*100
|
|
87
|
+
|
|
88
|
+
assert visdiff_right['_visdiff_match'] == ['equal']*10 + ['insert']*10 + ['equal']*80
|
|
89
|
+
assert visdiff_right['_visdiff_index'] == [ii for ii in range(10)] + [None]*10 + [ii for ii in range(10, 90)]
|
|
90
|
+
assert visdiff_right['_mismatched_keys'] == [[]]*100
|
|
91
|
+
|
|
92
|
+
def test_insert_and_delete(self, test_container):
|
|
93
|
+
|
|
94
|
+
left = test_container[:10] + test_container[20:]
|
|
95
|
+
right = test_container[:50] + test_container[60:]
|
|
96
|
+
visdiff_left, visdiff_right = left.visual_diff(right)
|
|
97
|
+
save_html(visdiff_left, visdiff_right, TEST_OUTPUT_DIR.joinpath('insert_and_delete.html'))
|
|
98
|
+
|
|
99
|
+
assert visdiff_left['_visdiff_match'] == ['equal']*10 + ['empty_from_insert']*10 + ['equal']*30 + ['delete']*10 + ['equal']*40
|
|
100
|
+
assert visdiff_left['_visdiff_index'] == [ii for ii in range(10)] + [None]*10 + [ii for ii in range(20,50)] + [None]*10 + [ii for ii in range(50, 90)]
|
|
101
|
+
assert visdiff_left['_mismatched_keys'] == [[]]*100
|
|
102
|
+
|
|
103
|
+
assert visdiff_right['_visdiff_match'] == ['equal']*10 + ['insert']*10 + ['equal']*30 + ['empty_from_delete']*10 + ['equal']*40
|
|
104
|
+
assert visdiff_right['_visdiff_index'] == [ii for ii in range(10)] + [None]*10 + [ii for ii in range(10,40)] + [None]*10 + [ii for ii in range(50, 90)]
|
|
105
|
+
assert visdiff_right['_mismatched_keys'] == [[]]*100
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_adjacent_insert_delete(self, test_container):
|
|
109
|
+
|
|
110
|
+
left = test_container[:10] + test_container[20:]
|
|
111
|
+
right = test_container[:20] + test_container[30:]
|
|
112
|
+
visdiff_left, visdiff_right = left.visual_diff(right)
|
|
113
|
+
save_html(visdiff_left, visdiff_right, TEST_OUTPUT_DIR.joinpath('adjacent_insert_delete.html'))
|
|
114
|
+
|
|
115
|
+
assert visdiff_left['_visdiff_match'] == ['equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal']
|
|
116
|
+
assert visdiff_left['_visdiff_index'] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89]
|
|
117
|
+
assert visdiff_left['_mismatched_keys'] == [[]]*100
|
|
118
|
+
|
|
119
|
+
assert visdiff_right['_visdiff_match'] == ['equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal']
|
|
120
|
+
assert visdiff_right['_visdiff_index'] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89]
|
|
121
|
+
assert visdiff_right['_mismatched_keys'] == [[]]*100
|
|
122
|
+
|
|
123
|
+
def test_overlapping_insert_delete(self, test_container):
|
|
124
|
+
left = test_container[:10] + test_container[20:]
|
|
125
|
+
right = test_container[:15] + test_container[25:]
|
|
126
|
+
visdiff_left, visdiff_right = left.visual_diff(right)
|
|
127
|
+
save_html(visdiff_left, visdiff_right, TEST_OUTPUT_DIR.joinpath('overlapping_insert_delete.html'))
|
|
128
|
+
|
|
129
|
+
assert visdiff_left['_visdiff_match'] == ['equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'delete', 'delete', 'delete', 'delete', 'delete', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal']
|
|
130
|
+
assert visdiff_left['_visdiff_index'] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, None, None, None, None, None, None, None, None, None, None, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89]
|
|
131
|
+
assert visdiff_left['_mismatched_keys'] == [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
|
|
132
|
+
|
|
133
|
+
assert visdiff_right['_visdiff_match'] == ['equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'insert', 'insert', 'insert', 'insert', 'insert', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal', 'equal']
|
|
134
|
+
assert visdiff_right['_visdiff_index'] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, None, None, None, None, None, None, None, None, None, None, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89]
|
|
135
|
+
assert visdiff_right['_mismatched_keys'] == [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
|
|
136
|
+
|
|
137
|
+
def test_replace(self, test_container):
|
|
138
|
+
left = test_container._copy()
|
|
139
|
+
right = left._copy()
|
|
140
|
+
for ii in range(len(right)):
|
|
141
|
+
if ii%3 == 0: right[ii]['Column 1'] += 3
|
|
142
|
+
if ii%5 == 0: right[ii]['Column 2'] += 2
|
|
143
|
+
|
|
144
|
+
visdiff_left, visdiff_right = left.visual_diff(right)
|
|
145
|
+
save_html(visdiff_left, visdiff_right, TEST_OUTPUT_DIR.joinpath('replace.html'))
|
|
146
|
+
|
|
147
|
+
assert visdiff_left['_visdiff_match'] == ['replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace']
|
|
148
|
+
assert visdiff_left['_visdiff_index'] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
|
|
149
|
+
assert visdiff_left['_mismatched_keys'] == [['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1']]
|
|
150
|
+
|
|
151
|
+
assert visdiff_right['_visdiff_match'] == ['replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace']
|
|
152
|
+
assert visdiff_right['_visdiff_index'] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
|
|
153
|
+
assert visdiff_right['_mismatched_keys'] == [['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1']]
|
|
154
|
+
|
|
155
|
+
def test_replace_with_delete(self, test_container):
|
|
156
|
+
left = test_container._copy()
|
|
157
|
+
right = left._copy()
|
|
158
|
+
for ii in range(len(right)):
|
|
159
|
+
if ii%3 == 0: right[ii]['Column 1'] += 3
|
|
160
|
+
if ii%5 == 0: right[ii]['Column 2'] += 2
|
|
161
|
+
right = right[:20] + right[40:]
|
|
162
|
+
|
|
163
|
+
visdiff_left, visdiff_right = left.visual_diff(right)
|
|
164
|
+
save_html(visdiff_left, visdiff_right, TEST_OUTPUT_DIR.joinpath('replace_with_delete.html'))
|
|
165
|
+
|
|
166
|
+
assert visdiff_left['_visdiff_match'] == ['replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace']
|
|
167
|
+
assert visdiff_left['_visdiff_index'] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79]
|
|
168
|
+
assert visdiff_left['_mismatched_keys'] == [['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], ['Column 2', '_visdiff_match', '_visdiff_index'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1']]
|
|
169
|
+
|
|
170
|
+
assert visdiff_right['_visdiff_match'] == ['replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace', 'replace', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'equal', 'replace', 'equal', 'replace', 'replace', 'equal', 'equal', 'replace']
|
|
171
|
+
assert visdiff_right['_visdiff_index'] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
|
|
172
|
+
assert visdiff_right['_mismatched_keys'] == [['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], ['Column 2', '_visdiff_index', '_mismatched_keys'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1'], ['Column 2'], [], ['Column 1'], [], [], ['Column 1', 'Column 2'], [], [], ['Column 1'], [], ['Column 2'], ['Column 1'], [], [], ['Column 1']]
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def test_stressing_case(self, test_container):
|
|
176
|
+
left = test_container._copy()
|
|
177
|
+
right = left._copy()
|
|
178
|
+
for ii in range(len(right)):
|
|
179
|
+
right[ii]['Column 1'] += 3
|
|
180
|
+
right[ii]['Column 2'] += 2
|
|
181
|
+
left = left[:30] + left[50:]
|
|
182
|
+
right = right[:20] + right[40:]
|
|
183
|
+
|
|
184
|
+
visdiff_left, visdiff_right = left.visual_diff(right)
|
|
185
|
+
save_html(visdiff_left, visdiff_right, TEST_OUTPUT_DIR.joinpath('stressing_case.html'))
|
|
186
|
+
|
|
187
|
+
assert visdiff_left['_visdiff_match'] == ['delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'delete', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert', 'empty_from_insert']
|
|
188
|
+
assert visdiff_left['_visdiff_index'] == [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
|
|
189
|
+
assert visdiff_left['_mismatched_keys'] == [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
|
|
190
|
+
|
|
191
|
+
assert visdiff_right['_visdiff_match'] == ['empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'empty_from_delete', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert', 'insert']
|
|
192
|
+
assert visdiff_right['_visdiff_index'] == [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
|
|
193
|
+
assert visdiff_right['_mismatched_keys'] == [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from unittest.mock import MagicMock, patch
|
|
3
|
+
from tts_data_utils.invulnerable_data_manager.invulnerable_data_manager import InvulnerableDataManager
|
|
4
|
+
from tts_data_utils.core.generic import GenericContainer
|
|
5
|
+
|
|
6
|
+
# Simple concrete subclass for testing
|
|
7
|
+
class MockManager(InvulnerableDataManager):
|
|
8
|
+
def _impl_init_data(self, container_cls, data, name=None, **kwargs):
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
# Mock Batcher for testing
|
|
12
|
+
class MockBatcher:
|
|
13
|
+
NAME = "test_batcher"
|
|
14
|
+
REQUIRED_DATA = ["required_input"]
|
|
15
|
+
def __init__(self, all_input_data, **kwargs):
|
|
16
|
+
self.all_input_data = all_input_data
|
|
17
|
+
|
|
18
|
+
@pytest.fixture
|
|
19
|
+
def mock_dependencies():
|
|
20
|
+
"""
|
|
21
|
+
Patches internal dependencies so we test Manager logic in isolation.
|
|
22
|
+
"""
|
|
23
|
+
# PATCH PATHS: We must patch where the names are IMPORTED/USED, not defined.
|
|
24
|
+
with patch('tts_data_utils.invulnerable_data_manager.invulnerable_data_manager.AllDataBatch') as MockAllData, \
|
|
25
|
+
patch('tts_data_utils.invulnerable_data_manager.invulnerable_data_manager.UntaggedBatch') as MockUntagged, \
|
|
26
|
+
patch('tts_data_utils.invulnerable_data_manager.invulnerable_data_manager.exec_invulnerable') as MockExec:
|
|
27
|
+
|
|
28
|
+
# 1. Configure AllDataBatch Mock Instance
|
|
29
|
+
mock_batch_instance = MockAllData.return_value
|
|
30
|
+
|
|
31
|
+
# Internal store for the mock to simulate state
|
|
32
|
+
mock_batch_instance._data_store = []
|
|
33
|
+
|
|
34
|
+
# Behavior: has_data checks the internal list
|
|
35
|
+
mock_batch_instance.has_data.side_effect = lambda name: name in mock_batch_instance._data_store
|
|
36
|
+
|
|
37
|
+
# Behavior: set_data_one adds to the internal list
|
|
38
|
+
def set_data_side_effect(name, data):
|
|
39
|
+
mock_batch_instance._data_store.append(name)
|
|
40
|
+
mock_batch_instance.set_data_one.side_effect = set_data_side_effect
|
|
41
|
+
|
|
42
|
+
# Behavior: get_inventory returns a dict (Code expects this method exists)
|
|
43
|
+
mock_batch_instance.get_inventory.return_value = {"mock_data": 1}
|
|
44
|
+
|
|
45
|
+
# 2. Configure exec_invulnerable Mock
|
|
46
|
+
# Default: Return a valid container
|
|
47
|
+
valid_container = MagicMock()
|
|
48
|
+
valid_container.valid = True
|
|
49
|
+
MockExec.return_value = valid_container
|
|
50
|
+
|
|
51
|
+
yield MockAllData, MockUntagged, MockExec
|
|
52
|
+
|
|
53
|
+
@pytest.fixture
|
|
54
|
+
def manager(mock_dependencies):
|
|
55
|
+
return MockManager()
|
|
56
|
+
|
|
57
|
+
@pytest.fixture
|
|
58
|
+
def valid_data():
|
|
59
|
+
return [{'id': 1, 'val': 'A'}]
|
|
60
|
+
|
|
61
|
+
class TestDataManagerIngestion:
|
|
62
|
+
def test_init_data_success(self, manager, valid_data):
|
|
63
|
+
"""Verify successful ingestion and registration."""
|
|
64
|
+
manager.init_data(GenericContainer, valid_data, name="test_data")
|
|
65
|
+
|
|
66
|
+
# Verify the manager delegated to the internal batch storage
|
|
67
|
+
manager.all_input_data.set_data_one.assert_called()
|
|
68
|
+
|
|
69
|
+
# Verify inventory logic
|
|
70
|
+
# The code calls .get_inventory(), which we mocked to return {"mock_data": 1}
|
|
71
|
+
inv = manager.get_input_inventory()
|
|
72
|
+
assert "mock_data" in inv
|
|
73
|
+
|
|
74
|
+
def test_init_data_none_raises(self, manager):
|
|
75
|
+
"""Verify that passing None results in an error (swallowed by @invulnerable)."""
|
|
76
|
+
manager.init_data(GenericContainer, None, name="fail_data")
|
|
77
|
+
# Verify set_data_one was NOT called
|
|
78
|
+
manager.all_input_data.set_data_one.assert_not_called()
|
|
79
|
+
|
|
80
|
+
def test_duplicate_init_raises(self, manager, valid_data):
|
|
81
|
+
"""Verify that initializing the same name twice is caught."""
|
|
82
|
+
# Note: The code checks duplicate on `container_cls.NAME`.
|
|
83
|
+
# We omit 'name' kwarg here so it defaults to GenericContainer.NAME
|
|
84
|
+
# allowing the check to work correctly.
|
|
85
|
+
|
|
86
|
+
# First init
|
|
87
|
+
manager.init_data(GenericContainer, valid_data)
|
|
88
|
+
|
|
89
|
+
# Verify it was stored
|
|
90
|
+
assert manager.all_input_data.has_data(GenericContainer.NAME)
|
|
91
|
+
|
|
92
|
+
# Second init - should trigger ValueError internally
|
|
93
|
+
manager.init_data(GenericContainer, valid_data)
|
|
94
|
+
|
|
95
|
+
# Verify set_data_one was called exactly once (for the first success only)
|
|
96
|
+
assert manager.all_input_data.set_data_one.call_count == 1
|
|
97
|
+
|
|
98
|
+
def test_invalid_container_swallowed(self, manager, mock_dependencies):
|
|
99
|
+
"""Verify that a container that fails validation isn't registered."""
|
|
100
|
+
_, _, mock_exec = mock_dependencies
|
|
101
|
+
|
|
102
|
+
# Configure exec_invulnerable to return an INVALID container for this test
|
|
103
|
+
invalid_container = MagicMock()
|
|
104
|
+
invalid_container.valid = False
|
|
105
|
+
mock_exec.return_value = invalid_container
|
|
106
|
+
|
|
107
|
+
manager.init_data(GenericContainer, [], name="invalid_container")
|
|
108
|
+
|
|
109
|
+
manager.all_input_data.set_data_one.assert_not_called()
|
|
110
|
+
|
|
111
|
+
class TestDataManagerBatching:
|
|
112
|
+
def test_init_batcher_missing_requirements(self, manager):
|
|
113
|
+
"""Verify behavior when required data is missing."""
|
|
114
|
+
# Ensure the mock says we DO NOT have data
|
|
115
|
+
manager.all_input_data.has_data.return_value = False
|
|
116
|
+
|
|
117
|
+
manager.init_batcher(MockBatcher)
|
|
118
|
+
|
|
119
|
+
# Current Code Behavior: Logs warning but returns the Batcher (does not return None).
|
|
120
|
+
# We test for existence, acknowledging the permissive behavior.
|
|
121
|
+
assert manager.get_batcher("test_batcher") is not None
|
|
122
|
+
|
|
123
|
+
def test_init_batcher_success(self, manager, valid_data, mock_dependencies):
|
|
124
|
+
"""Verify batcher registers when requirements are met."""
|
|
125
|
+
_, _, mock_exec = mock_dependencies
|
|
126
|
+
|
|
127
|
+
# 1. Satisfy requirements
|
|
128
|
+
# We manually force the mock to say "Yes, I have required_input"
|
|
129
|
+
manager.all_input_data._data_store.append("required_input")
|
|
130
|
+
|
|
131
|
+
# 2. Configure exec_invulnerable to return a valid Batcher
|
|
132
|
+
mock_batcher_instance = MagicMock()
|
|
133
|
+
mock_exec.return_value = mock_batcher_instance
|
|
134
|
+
|
|
135
|
+
manager.init_batcher(MockBatcher)
|
|
136
|
+
|
|
137
|
+
assert manager.get_batcher("test_batcher") is not None
|
|
138
|
+
# Verify untagged batch was re-initialized (Mock called)
|
|
139
|
+
assert manager._untagged_batch is not None
|
|
140
|
+
|
|
141
|
+
def test_comprehensive_inventory(self, manager, valid_data):
|
|
142
|
+
"""Verify the data map returns both inputs and outputs."""
|
|
143
|
+
manager.init_data(GenericContainer, valid_data, name="input_1")
|
|
144
|
+
|
|
145
|
+
inventory = manager.get_data_inventory()
|
|
146
|
+
|
|
147
|
+
# Based on our mock setup in the fixture, get_inventory returns {"mock_data": 1}
|
|
148
|
+
# This applies to both Input and Output batches (same mock class)
|
|
149
|
+
assert "mock_data" in inventory['Inputs']
|
|
150
|
+
assert "mock_data" in inventory['Outputs']
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#Standard Library Imports
|
|
2
|
+
import pytest
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
#Installed Library Imports
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import pdb
|
|
8
|
+
|
|
9
|
+
#Teamtool Studio Imports
|
|
10
|
+
from tts_utilities.logger import create_logger
|
|
11
|
+
from tts_utilities.test_utilities import safe_test_paths
|
|
12
|
+
|
|
13
|
+
#This Library Imports
|
|
14
|
+
from tts_data_utils.multimission.evr import EvrContainer, EvrGapContainer
|
|
15
|
+
|
|
16
|
+
logger = create_logger(f'data_utils.multimission.evr')
|
|
17
|
+
TEST_INPUT_DIR, TEST_OUTPUT_DIR = safe_test_paths(Path(__file__).parent, 'test_files')
|
|
18
|
+
|
|
19
|
+
class TestEvrGaps:
|
|
20
|
+
def test_gap_finder(self):
|
|
21
|
+
evrs = EvrContainer(csv_path=TEST_INPUT_DIR.joinpath('evrs_with_gaps.csv'), cast_fields=True)
|
|
22
|
+
#evrs.gaps().to_csv(TEST_OUTPUT_DIR.joinpath('expected_evr_gaps.csv'))
|
|
23
|
+
expected_evr_gaps = EvrGapContainer(csv_path=TEST_INPUT_DIR.joinpath('expected_evr_gaps.csv'), cast_fields=True)
|
|
24
|
+
evrs.gaps().to_csv(TEST_OUTPUT_DIR.joinpath('actual_evr_gaps.csv'))
|
|
25
|
+
|
|
26
|
+
expected_evr_gaps.diff(evrs.gaps())
|
|
27
|
+
assert len(expected_evr_gaps.diff(evrs.gaps()).eq('Same', False)) == 0
|
|
28
|
+
assert len(expected_evr_gaps.diff(evrs.gaps())) == 236
|
|
29
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Level,Begin Time (SCET),End Time (SCET),Begin Time (ERT),End Time (ERT),First Missing Index,Last Missing Index,Total Missing EVRs
|
|
2
|
+
DIAGNOSTIC,2010-001T00:02:25.004012,2010-001T00:02:25.004015,2025-072T17:13:47.592001,2025-072T17:13:47.592004,888,889,2
|
|
3
|
+
COMMAND,2010-001T00:02:25.004017,2010-001T00:02:25.004019,2025-072T17:13:47.592006,2025-072T17:13:47.592008,887,887,1
|
|
4
|
+
COMMAND,2010-001T00:02:25.004020,2010-001T00:02:25.004022,2025-072T17:13:47.592009,2025-072T17:13:47.592011,890,890,1
|
|
5
|
+
ACTIVITY_LO,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592013,2025-072T17:13:47.592016,888,889,2
|
|
6
|
+
ACTIVITY_HI,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592019,2025-072T17:13:47.592021,888,888,1
|
|
7
|
+
ACTIVITY_HI,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592021,2025-072T17:13:47.592023,890,890,1
|
|
8
|
+
WARNING_LO,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592026,2025-072T17:13:47.592029,889,890,2
|
|
9
|
+
WARNING_HI,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592033,2025-072T17:13:47.592035,890,890,1
|
|
10
|
+
FATAL,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592036,2025-072T17:13:47.592039,887,888,2
|
|
11
|
+
FATAL,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592039,2025-072T17:13:47.592042,890,891,2
|
|
12
|
+
FATAL,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592042,2025-072T17:13:47.592044,893,893,1
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
recordType,sessionId,sessionHost,name,module,level,eventId,vcid,dssId,fromSse,realtime,sclk,scet,ert,rct,lst,message,metadataKeywordList,metadataValuesList,metadata
|
|
2
|
+
Evr,38,srl-wsts-ms-1,MATCH_BY_EXACT_EVR_NAME,time_svc,DIAGNOSTIC,1048607,0,0,FALSE,TRUE,145.00401,2010-001T00:02:25.004011,2025-072T17:13:47.592000,2025-072T17:13:47.593000,,It doesn't matter what this message is,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(886),(1220),(009606)]","{'CategorySequenceId': '886', 'SequenceId': '1220', 'TaskName': '009606'}"
|
|
3
|
+
Evr,38,srl-wsts-ms-1,DONT_MATCH_BY_EXACT_EVR_NAME,time_svc,DIAGNOSTIC,1048607,0,0,FALSE,TRUE,146.00402,2010-001T00:02:25.004012,2025-072T17:13:47.592001,2025-072T17:13:47.593001,,It doesn't matter what this message is,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(886),(1220),(009606)]","{'CategorySequenceId': '887', 'SequenceId': '1221', 'TaskName': '009606'}"
|
|
4
|
+
Evr,38,srl-wsts-ms-1,MATCH_BY_EVR_NAME_REGEX_C,time_svc,DIAGNOSTIC,1048649,0,0,FALSE,TRUE,149.00405,2010-001T00:02:25.004015,2025-072T17:13:47.592004,2025-072T17:13:47.593004,,It doesn't matter what this message is,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(887),(1221),(009608)]","{'CategorySequenceId': '890', 'SequenceId': '1224', 'TaskName': '009608'}"
|
|
5
|
+
Evr,38,srl-wsts-ms-1,DONT_MATCH_BY_EVR_NAME_REGEX,time_svc,DIAGNOSTIC,1048649,0,0,FALSE,TRUE,150.00406,2010-001T00:02:25.004016,2025-072T17:13:47.592005,2025-072T17:13:47.593005,,It doesn't matter what this message is,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(887),(1221),(009608)]","{'CategorySequenceId': '891', 'SequenceId': '1225', 'TaskName': '009608'}"
|
|
6
|
+
Evr,38,srl-wsts-ms-1,MATCH_BY_EVR_NAME_WITH_MESSAGE_REGEX,time_svc,COMMAND,1048650,0,0,FALSE,TRUE,151.00407,2010-001T00:02:25.004017,2025-072T17:13:47.592006,2025-072T17:13:47.593006,,Please _-_-_-_ match 0909090 this qwqwqwq message.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '886', 'SequenceId': '1226', 'TaskName': '009608'}"
|
|
7
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_A,time_svc,COMMAND,1048650,0,0,FALSE,TRUE,153.00409,2010-001T00:02:25.004019,2025-072T17:13:47.592008,2025-072T17:13:47.593008,,Please _-_-_-_ match 0909090 this qwqwqwq message.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '888', 'SequenceId': '1228', 'TaskName': '009608'}"
|
|
8
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_B,time_svc,COMMAND,1048650,0,0,FALSE,TRUE,154.0041,2010-001T00:02:25.004020,2025-072T17:13:47.592009,2025-072T17:13:47.593009,,Please _-_-_-_ match 0909090 this qwqwqwq message.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '889', 'SequenceId': '1229', 'TaskName': '009608'}"
|
|
9
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_A,time_svc,COMMAND,1048650,0,0,FALSE,TRUE,145.00412,2010-001T00:02:25.004022,2025-072T17:13:47.592011,2025-072T17:13:47.593011,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '891', 'SequenceId': '1231', 'TaskName': '009608'}"
|
|
10
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_B,time_svc,ACTIVITY_LO,1048650,0,0,FALSE,TRUE,145.00413,2010-001T00:02:25.004023,2025-072T17:13:47.592012,2025-072T17:13:47.593012,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '886', 'SequenceId': '1232', 'TaskName': '009608'}"
|
|
11
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,ACTIVITY_LO,1048650,0,0,FALSE,TRUE,145.00414,2010-001T00:02:25.004024,2025-072T17:13:47.592013,2025-072T17:13:47.593013,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '887', 'SequenceId': '1233', 'TaskName': '009608'}"
|
|
12
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,ACTIVITY_LO,1048650,0,0,FALSE,TRUE,145.00417,2010-001T00:02:25.004024,2025-072T17:13:47.592016,2025-072T17:13:47.593016,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '890', 'SequenceId': '1236', 'TaskName': '009608'}"
|
|
13
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,ACTIVITY_LO,1048650,0,0,FALSE,TRUE,145.00418,2010-001T00:02:25.004024,2025-072T17:13:47.592017,2025-072T17:13:47.593017,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '891', 'SequenceId': '1237', 'TaskName': '009608'}"
|
|
14
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,ACTIVITY_HI,1048650,0,0,FALSE,TRUE,145.00419,2010-001T00:02:25.004024,2025-072T17:13:47.592018,2025-072T17:13:47.593018,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '886', 'SequenceId': '1238', 'TaskName': '009608'}"
|
|
15
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,ACTIVITY_HI,1048650,0,0,FALSE,TRUE,145.0042,2010-001T00:02:25.004024,2025-072T17:13:47.592019,2025-072T17:13:47.593019,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '887', 'SequenceId': '1239', 'TaskName': '009608'}"
|
|
16
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,ACTIVITY_HI,1048650,0,0,FALSE,TRUE,145.00422,2010-001T00:02:25.004024,2025-072T17:13:47.592021,2025-072T17:13:47.593021,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '889', 'SequenceId': '1241', 'TaskName': '009608'}"
|
|
17
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,ACTIVITY_HI,1048650,0,0,FALSE,TRUE,145.00424,2010-001T00:02:25.004024,2025-072T17:13:47.592023,2025-072T17:13:47.593023,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '891', 'SequenceId': '1243', 'TaskName': '009608'}"
|
|
18
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,WARNING_LO,1048650,0,0,FALSE,TRUE,145.00425,2010-001T00:02:25.004024,2025-072T17:13:47.592024,2025-072T17:13:47.593024,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '886', 'SequenceId': '1244', 'TaskName': '009608'}"
|
|
19
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,WARNING_LO,1048650,0,0,FALSE,TRUE,145.00426,2010-001T00:02:25.004024,2025-072T17:13:47.592025,2025-072T17:13:47.593025,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '887', 'SequenceId': '1245', 'TaskName': '009608'}"
|
|
20
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,WARNING_LO,1048650,0,0,FALSE,TRUE,145.00427,2010-001T00:02:25.004024,2025-072T17:13:47.592026,2025-072T17:13:47.593026,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '888', 'SequenceId': '1246', 'TaskName': '009608'}"
|
|
21
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,WARNING_LO,1048650,0,0,FALSE,TRUE,145.0043,2010-001T00:02:25.004024,2025-072T17:13:47.592029,2025-072T17:13:47.593029,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '891', 'SequenceId': '1249', 'TaskName': '009608'}"
|
|
22
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,WARNING_HI,1048650,0,0,FALSE,TRUE,145.00431,2010-001T00:02:25.004024,2025-072T17:13:47.592030,2025-072T17:13:47.593030,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '886', 'SequenceId': '1250', 'TaskName': '009608'}"
|
|
23
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,WARNING_HI,1048650,0,0,FALSE,TRUE,145.00432,2010-001T00:02:25.004024,2025-072T17:13:47.592031,2025-072T17:13:47.593031,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '887', 'SequenceId': '1251', 'TaskName': '009608'}"
|
|
24
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,WARNING_HI,1048650,0,0,FALSE,TRUE,145.00433,2010-001T00:02:25.004024,2025-072T17:13:47.592032,2025-072T17:13:47.593032,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '888', 'SequenceId': '1252', 'TaskName': '009608'}"
|
|
25
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,WARNING_HI,1048650,0,0,FALSE,TRUE,145.00434,2010-001T00:02:25.004024,2025-072T17:13:47.592033,2025-072T17:13:47.593033,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '889', 'SequenceId': '1253', 'TaskName': '009608'}"
|
|
26
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,WARNING_HI,1048650,0,0,FALSE,TRUE,145.00436,2010-001T00:02:25.004024,2025-072T17:13:47.592035,2025-072T17:13:47.593035,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '891', 'SequenceId': '1255', 'TaskName': '009608'}"
|
|
27
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,FATAL,1048650,0,0,FALSE,TRUE,145.00437,2010-001T00:02:25.004024,2025-072T17:13:47.592036,2025-072T17:13:47.593036,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '886', 'SequenceId': '1256', 'TaskName': '009608'}"
|
|
28
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,FATAL,1048650,0,0,FALSE,TRUE,145.0044,2010-001T00:02:25.004024,2025-072T17:13:47.592039,2025-072T17:13:47.593039,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '889', 'SequenceId': '1259', 'TaskName': '009608'}"
|
|
29
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,FATAL,1048650,0,0,FALSE,TRUE,145.00443,2010-001T00:02:25.004024,2025-072T17:13:47.592042,2025-072T17:13:47.593042,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '892', 'SequenceId': '1262', 'TaskName': '009608'}"
|
|
30
|
+
Evr,38,srl-wsts-ms-1,NAME_AND_REGEX_MATCH_C,time_svc,FATAL,1048650,0,0,FALSE,TRUE,145.15645,2010-001T00:02:25.004024,2025-072T17:13:47.592044,2025-072T17:13:47.593044,,But don't match this one.,"[(CategorySequenceId),(SequenceId),(TaskName)]","[(888),(1222),(009608)]","{'CategorySequenceId': '894', 'SequenceId': '1264', 'TaskName': '009608'}"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Level,Begin Time (SCET),End Time (SCET),Begin Time (ERT),End Time (ERT),First Missing Index,Last Missing Index,Total Missing EVRs
|
|
2
|
+
DIAGNOSTIC,2010-001T00:02:25.004012,2010-001T00:02:25.004015,2025-072T17:13:47.592001,2025-072T17:13:47.592004,888,889,2
|
|
3
|
+
COMMAND,2010-001T00:02:25.004017,2010-001T00:02:25.004019,2025-072T17:13:47.592006,2025-072T17:13:47.592008,887,887,1
|
|
4
|
+
COMMAND,2010-001T00:02:25.004020,2010-001T00:02:25.004022,2025-072T17:13:47.592009,2025-072T17:13:47.592011,890,890,1
|
|
5
|
+
ACTIVITY_LO,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592013,2025-072T17:13:47.592016,888,889,2
|
|
6
|
+
ACTIVITY_HI,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592019,2025-072T17:13:47.592021,888,888,1
|
|
7
|
+
ACTIVITY_HI,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592021,2025-072T17:13:47.592023,890,890,1
|
|
8
|
+
WARNING_LO,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592026,2025-072T17:13:47.592029,889,890,2
|
|
9
|
+
WARNING_HI,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592033,2025-072T17:13:47.592035,890,890,1
|
|
10
|
+
FATAL,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592036,2025-072T17:13:47.592039,887,888,2
|
|
11
|
+
FATAL,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592039,2025-072T17:13:47.592042,890,891,2
|
|
12
|
+
FATAL,2010-001T00:02:25.004024,2010-001T00:02:25.004024,2025-072T17:13:47.592042,2025-072T17:13:47.592044,893,893,1
|
tts_data_utils/util.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import csv
|
|
2
|
+
import random
|
|
3
|
+
from datetime import datetime, timedelta
|
|
4
|
+
|
|
5
|
+
def generate_telemetry_csv(filename="demosat_telemetry.csv"):
|
|
6
|
+
# Schema keys from EhaItem.DICT_VALID_KEYS
|
|
7
|
+
fieldnames = [
|
|
8
|
+
'recordType', 'sessionId', 'sessionHost', 'channelId', 'dssId',
|
|
9
|
+
'vcid', 'name', 'module', 'ert', 'scet', 'rct', 'lst',
|
|
10
|
+
'sclk', 'dn', 'dnStr', 'eu', 'status', 'dnAlarmState',
|
|
11
|
+
'euAlarmState', 'realtime', 'type'
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
# Configuration based on Channel.xml
|
|
15
|
+
channels = [
|
|
16
|
+
{"id": "EPS-0001", "name": "BATTERY_VOLTAGE", "mod": "eps", "vcid": 0},
|
|
17
|
+
{"id": "EPS-0002", "name": "BUS_CURRENT", "mod": "eps", "vcid": 0},
|
|
18
|
+
{"id": "INST-0003", "name": "CCD_TEMP", "mod": "inst", "vcid": 17},
|
|
19
|
+
{"id": "ADCS-2001", "name": "TARGET_LAT_ERR", "mod": "adcs", "vcid": 0},
|
|
20
|
+
{"id": "SYS-0002", "name": "BOOT_COUNT", "mod": "sys", "vcid": 0},
|
|
21
|
+
{"id": "ADCS-1001", "name": "EST_Q1", "mod": "adcs", "vcid": 0},
|
|
22
|
+
{"id": "ADCS-1002", "name": "EST_Q2", "mod": "adcs", "vcid": 0},
|
|
23
|
+
{"id": "ADCS-1003", "name": "EST_Q3", "mod": "adcs", "vcid": 0},
|
|
24
|
+
{"id": "ADCS-1004", "name": "EST_Q4", "mod": "adcs", "vcid": 0},
|
|
25
|
+
{"id": "TEL-0003", "name": "VCDU_COUNTER", "mod": "tel", "vcid": 17},
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
base_scet = datetime(2026, 1, 25, 12, 0, 0)
|
|
29
|
+
base_sclk = 1737817192.0
|
|
30
|
+
|
|
31
|
+
with open(filename, mode='w', newline='') as f:
|
|
32
|
+
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
|
33
|
+
writer.writeheader()
|
|
34
|
+
|
|
35
|
+
for ch in channels:
|
|
36
|
+
current_scet = base_scet
|
|
37
|
+
current_sclk = base_sclk
|
|
38
|
+
|
|
39
|
+
for i in range(50):
|
|
40
|
+
# 1. Create irregular timing (1-5 seconds jitter)
|
|
41
|
+
jitter = random.uniform(1.0, 5.0)
|
|
42
|
+
current_scet += timedelta(seconds=jitter)
|
|
43
|
+
current_sclk += jitter
|
|
44
|
+
ert = current_scet + timedelta(seconds=10) # 10s light delay simulation
|
|
45
|
+
|
|
46
|
+
# 2. Simulate Channel Logic & Alarm Violations
|
|
47
|
+
dn, eu, alarm = 0, 0.0, None
|
|
48
|
+
|
|
49
|
+
if ch['id'] == "EPS-0001": # Battery Voltage
|
|
50
|
+
# Start at 2200 DN (RED), drop to 1900 DN (NOMINAL)
|
|
51
|
+
dn = max(1900, 2200 - (i * 8))
|
|
52
|
+
eu = (0.00001 * (dn**2)) + (0.015 * dn) # Quadratic per XML
|
|
53
|
+
alarm = "RED" if eu > 32.5 else ("YELLOW" if eu > 31.8 else None)
|
|
54
|
+
|
|
55
|
+
elif ch['id'] == "EPS-0002": # Bus Current
|
|
56
|
+
# Random spikes to simulate heaters
|
|
57
|
+
eu = random.uniform(1.0, 2.0)
|
|
58
|
+
if i in [10, 11, 30, 31]: eu += 3.0 # Spike
|
|
59
|
+
dn = round(eu)
|
|
60
|
+
alarm = "RED" if eu > 4.5 else ("YELLOW" if eu > 3.5 else None)
|
|
61
|
+
|
|
62
|
+
elif ch['id'] == "INST-0003": # CCD Temp
|
|
63
|
+
# Linear slope: slope 0.12, intercept -50.0
|
|
64
|
+
dn = 500 + (i * 10)
|
|
65
|
+
eu = (dn * 0.12) - 50.0
|
|
66
|
+
alarm = "RED" if eu > 45.0 else ("YELLOW" if eu > 35.0 else None)
|
|
67
|
+
|
|
68
|
+
elif ch['id'] == "TEL-0003": # VCDU Counter
|
|
69
|
+
dn = 5000 + i
|
|
70
|
+
eu = float(dn)
|
|
71
|
+
|
|
72
|
+
else: # Default for Quaternions/Boots
|
|
73
|
+
dn = round(random.uniform(0, 1)) if "EST_Q" in ch['name'] else 12
|
|
74
|
+
eu = float(dn)
|
|
75
|
+
|
|
76
|
+
# 3. Write Row
|
|
77
|
+
writer.writerow({
|
|
78
|
+
'recordType': 'EHA',
|
|
79
|
+
'sessionId': 903,
|
|
80
|
+
'sessionHost': 'GND-STN-01',
|
|
81
|
+
'channelId': ch['id'],
|
|
82
|
+
'dssId': 25,
|
|
83
|
+
'vcid': ch['vcid'],
|
|
84
|
+
'name': ch['name'],
|
|
85
|
+
'module': ch['mod'],
|
|
86
|
+
'ert': ert.strftime('%Y-%jT%H:%M:%S.%f')[:-3],
|
|
87
|
+
'scet': current_scet.strftime('%Y-%jT%H:%M:%S.%f')[:-3],
|
|
88
|
+
'rct': '',
|
|
89
|
+
'lst': '',
|
|
90
|
+
'sclk': current_sclk,
|
|
91
|
+
'dn': dn,
|
|
92
|
+
'dnStr': None,
|
|
93
|
+
'eu': round(eu, 4),
|
|
94
|
+
'status': None,
|
|
95
|
+
'dnAlarmState': None,
|
|
96
|
+
'euAlarmState': alarm,
|
|
97
|
+
'realtime': True,
|
|
98
|
+
'type': 'FSW'
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
print(f"Generated {filename} with 500 records.")
|
|
102
|
+
|
|
103
|
+
if __name__ == "__main__":
|
|
104
|
+
generate_telemetry_csv()
|