|
| 1 | +from unittest.mock import patch, MagicMock |
| 2 | +from csle_common.util.export_util import ExportUtil |
| 3 | +import os |
| 4 | +import tempfile |
| 5 | +import json |
| 6 | + |
| 7 | + |
| 8 | +class TestExportUtilSuite: |
| 9 | + """ |
| 10 | + Test suite for Export Util |
| 11 | + """ |
| 12 | + |
| 13 | + def test_zipdir(self) -> None: |
| 14 | + """ |
| 15 | + Test the method that creates a zip file of a given directory |
| 16 | +
|
| 17 | + :return: None |
| 18 | + """ |
| 19 | + with tempfile.TemporaryDirectory() as tmpdir: |
| 20 | + file_path = os.path.join(tmpdir, "test.txt") |
| 21 | + with open(file_path, "w") as f: |
| 22 | + f.write("text") |
| 23 | + zip_path = os.path.join(tmpdir, "test.zip") |
| 24 | + ExportUtil.zipdir(tmpdir, zip_path) |
| 25 | + assert os.path.exists(zip_path) |
| 26 | + |
| 27 | + def test_get_dir_size_gb(self) -> None: |
| 28 | + """ |
| 29 | + Test the method that calculates the zie of a file directory in gb |
| 30 | +
|
| 31 | + :return: None |
| 32 | + """ |
| 33 | + with tempfile.TemporaryDirectory() as tmpdir: |
| 34 | + sub_dir = os.path.join(tmpdir, "subdir") |
| 35 | + os.makedirs(sub_dir) |
| 36 | + file_sizes = [150000000, 250000000, 350000000] |
| 37 | + total_size = sum(file_sizes) |
| 38 | + file_paths = [ |
| 39 | + os.path.join(tmpdir, "file1.txt"), |
| 40 | + os.path.join(tmpdir, "file2.txt"), |
| 41 | + os.path.join(tmpdir, "file3.txt"), |
| 42 | + ] |
| 43 | + for file_path, size in zip(file_paths, file_sizes): |
| 44 | + with open(file_path, "wb") as f: |
| 45 | + f.write(b"\0" * size) |
| 46 | + size_gb = ExportUtil.get_dir_size_gb(tmpdir) |
| 47 | + expected_size_gb = round(float(total_size) / 1000000000, 2) |
| 48 | + assert size_gb == expected_size_gb, f"Expected {expected_size_gb} GB but got {size_gb} GB" |
| 49 | + |
| 50 | + @patch("csle_common.metastore.metastore_facade.MetastoreFacade.list_emulation_traces_ids") |
| 51 | + @patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_emulation_trace") |
| 52 | + @patch("csle_common.util.export_util.ExportUtil.zipdir") |
| 53 | + def test_export_emulation_traces_to_disk_json( |
| 54 | + self, mock_zipdir, mock_get_emulation_trace, mock_list_emulation_traces_ids |
| 55 | + ) -> None: |
| 56 | + """ |
| 57 | + Test the method that exports emulation traces from the metastore to disk |
| 58 | +
|
| 59 | + :param mock_zipdir: mock_zipdir |
| 60 | + :param mock_get_emulation_trace: mock_get_emulation_trace |
| 61 | + :param mock_list_emulation_traces_ids: mock_list_emulation_traces_ids |
| 62 | +
|
| 63 | + :return: None |
| 64 | + """ |
| 65 | + mock_list_emulation_traces_ids.return_value = [(1,), (2,)] |
| 66 | + mock_trace = MagicMock() |
| 67 | + mock_trace.to_dict.return_value = {"trace_data": "example_data"} |
| 68 | + mock_trace.num_attributes_per_time_step.return_value = 5 |
| 69 | + mock_trace.schema.return_value.to_dict.return_value = {"schema_data": "example_schema"} |
| 70 | + mock_get_emulation_trace.return_value = mock_trace |
| 71 | + with tempfile.TemporaryDirectory() as temp_dir: |
| 72 | + zip_file_output = os.path.join(temp_dir, "output.zip") |
| 73 | + ExportUtil.export_emulation_traces_to_disk_json( |
| 74 | + num_traces_per_file=1, |
| 75 | + output_dir=temp_dir, |
| 76 | + zip_file_output=zip_file_output, |
| 77 | + max_num_traces=2, |
| 78 | + added_by="test_user", |
| 79 | + offset=0, |
| 80 | + file_start_id=1, |
| 81 | + ) |
| 82 | + assert os.path.exists(os.path.join(temp_dir, "1.json")) |
| 83 | + |
| 84 | + @patch("csle_common.util.export_util.ExportUtil.get_dir_size_gb") |
| 85 | + @patch("os.listdir") |
| 86 | + @patch("os.path.getsize") |
| 87 | + @patch("io.open") |
| 88 | + def test_extract_emulation_traces_dataset_metadata( |
| 89 | + self, mock_open, mock_getsize, mock_listdir, mock_get_dir_size_gb |
| 90 | + ) -> None: |
| 91 | + """ |
| 92 | + Test the method that extracts metadata of a traces dataset stored on disk |
| 93 | +
|
| 94 | + :param mock_open: mock_open |
| 95 | + :param mock_getsize: mock_getsize |
| 96 | + :param mock_listdir: mock_listdir |
| 97 | + :param mock_get_dir_size_gb: mock_get_dir_size_gb |
| 98 | +
|
| 99 | + :return: None |
| 100 | + """ |
| 101 | + mock_metadata = { |
| 102 | + "schema": {"schema_data": "example_schema"}, |
| 103 | + "num_traces": 5, |
| 104 | + "num_traces_per_file": 2, |
| 105 | + "num_attributes_per_time_step": 3, |
| 106 | + "file_format": "json", |
| 107 | + "added_by": "test_user", |
| 108 | + "columns": "example_columns", |
| 109 | + } |
| 110 | + mock_open.return_value.__enter__.return_value.read.return_value = json.dumps(mock_metadata) |
| 111 | + mock_listdir.return_value = ["1.json", "2.json", "metadata.json"] |
| 112 | + mock_getsize.return_value = 500000000 |
| 113 | + mock_get_dir_size_gb.return_value = 1.5 |
| 114 | + dir_path = "/dir" |
| 115 | + zip_file_path = "/dir/zipfile.zip" |
| 116 | + result = ExportUtil.extract_emulation_traces_dataset_metadata(dir_path=dir_path, zip_file_path=zip_file_path) |
| 117 | + assert result |
| 118 | + |
| 119 | + @patch("csle_common.metastore.metastore_facade.MetastoreFacade.list_emulation_traces_ids") |
| 120 | + @patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_emulation_trace") |
| 121 | + @patch("csle_common.util.export_util.ExportUtil.zipdir") |
| 122 | + def test_export_emulation_traces_to_disk_csv( |
| 123 | + self, mock_zipdir, mock_get_emulation_trace, mock_list_emulation_traces_ids |
| 124 | + ) -> None: |
| 125 | + """ |
| 126 | + Test the method that exports emulation traces from the metastore to disk |
| 127 | +
|
| 128 | + :param mock_zipdir: mock_zipdir |
| 129 | + :param mock_get_emulation_trace: mock_get_emulation_trace |
| 130 | + :param mock_list_emulation_traces_ids: mock_list_emulation_traces_id |
| 131 | +
|
| 132 | + :return: None |
| 133 | + """ |
| 134 | + mock_list_emulation_traces_ids.return_value = [(1,), (2,)] |
| 135 | + mock_trace = MagicMock() |
| 136 | + mock_trace.to_csv_record.return_value = (["value1", "value2"], ["col1", "col2"]) |
| 137 | + mock_trace.num_attributes_per_time_step.return_value = 5 |
| 138 | + mock_get_emulation_trace.return_value = mock_trace |
| 139 | + with tempfile.TemporaryDirectory() as temp_dir: |
| 140 | + zip_file_output = os.path.join(temp_dir, "output.zip") |
| 141 | + ExportUtil.export_emulation_traces_to_disk_csv( |
| 142 | + num_traces_per_file=1, |
| 143 | + output_dir=temp_dir, |
| 144 | + zip_file_output=zip_file_output, |
| 145 | + max_num_traces=2, |
| 146 | + max_time_steps=10, |
| 147 | + max_nodes=5, |
| 148 | + max_ports=3, |
| 149 | + max_vulns=2, |
| 150 | + null_value=-1, |
| 151 | + added_by="test_user", |
| 152 | + ) |
| 153 | + assert os.path.exists(os.path.join(temp_dir, "1.csv")) |
| 154 | + |
| 155 | + @patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_emulation_statistic") |
| 156 | + @patch("csle_common.util.export_util.ExportUtil.zipdir") |
| 157 | + def test_export_emulation_statistic_to_disk_json(self, mock_zipdir, mock_get_emulation_statistic) -> None: |
| 158 | + """ |
| 159 | + Test the method that exports emulation statistics from the metastore to disk |
| 160 | +
|
| 161 | + :param mock_zipdir: mock_zipdir |
| 162 | + :param mock_get_emulation_statistic: mock_get_emulation_statistic |
| 163 | +
|
| 164 | + :return: None |
| 165 | + """ |
| 166 | + mock_statistic = MagicMock() |
| 167 | + mock_statistic.num_measurements = 100 |
| 168 | + mock_statistic.num_metrics = 10 |
| 169 | + mock_statistic.metrics = ["metric1", "metric2"] |
| 170 | + mock_statistic.conditions = ["condition1", "condition2"] |
| 171 | + mock_statistic.num_conditions = 2 |
| 172 | + mock_statistic.to_dict.return_value = {"key": "value"} |
| 173 | + mock_get_emulation_statistic.return_value = mock_statistic |
| 174 | + with tempfile.TemporaryDirectory() as temp_dir: |
| 175 | + zip_file_output = os.path.join(temp_dir, "output.zip") |
| 176 | + ExportUtil.export_emulation_statistics_to_disk_json( |
| 177 | + output_dir=temp_dir, zip_file_output=zip_file_output, statistics_id=1, added_by="test_user" |
| 178 | + ) |
| 179 | + assert os.path.exists(os.path.join(temp_dir, "statistics.json")) |
| 180 | + |
| 181 | + @patch("csle_common.util.export_util.ExportUtil.get_dir_size_gb") |
| 182 | + @patch("os.listdir") |
| 183 | + @patch("os.path.getsize") |
| 184 | + @patch("io.open") |
| 185 | + def test_extract_emulation_statistics_dataset_metadata( |
| 186 | + self, mock_open, mock_getsize, mock_listdir, mock_get_dir_size_gb |
| 187 | + ) -> None: |
| 188 | + """ |
| 189 | + Test the method that extracts metadata of a traces dataset stored on disk |
| 190 | +
|
| 191 | + :param mock_open: mock_open |
| 192 | + :param mock_getsize: mock_getsize |
| 193 | + :param mock_listdir: mock_listdir |
| 194 | + :param mock_get_dir_size_gb: mock_get_dir_size_gb |
| 195 | +
|
| 196 | + :return: None |
| 197 | + """ |
| 198 | + mock_metadata = { |
| 199 | + "file_format": "json", |
| 200 | + "added_by": "test_user", |
| 201 | + "num_measurements": 100, |
| 202 | + "num_metrics": 10, |
| 203 | + "metrics": "metric1,metric2", |
| 204 | + "conditions": "condition1,condition2", |
| 205 | + "num_conditions": 2, |
| 206 | + } |
| 207 | + mock_open.return_value.__enter__.return_value.read.return_value = json.dumps(mock_metadata) |
| 208 | + mock_listdir.return_value = ["statistics.json", "metadata.json"] |
| 209 | + mock_getsize.return_value = 500000000 |
| 210 | + mock_get_dir_size_gb.return_value = 1.5 |
| 211 | + dir_path = "/dir" |
| 212 | + zip_file_path = "/dir/zipfile.zip" |
| 213 | + result = ExportUtil.extract_emulation_statistics_dataset_metadata( |
| 214 | + dir_path=dir_path, zip_file_path=zip_file_path |
| 215 | + ) |
| 216 | + assert result |
0 commit comments