spl2-testing-framework 1.3.0__tar.gz → 1.4.0__tar.gz

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.
Files changed (33) hide show
  1. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/PKG-INFO +2 -1
  2. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/README.md +1 -0
  3. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/pyproject.toml +1 -1
  4. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/conftest.py +6 -0
  5. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/results.py +48 -0
  6. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/spl2test_runner.py +10 -0
  7. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/LICENSE +0 -0
  8. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/__init__.py +0 -0
  9. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/launch_remotely_spl2.py +0 -0
  10. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/logger_manager.py +0 -0
  11. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/pytest.ini.sample +0 -0
  12. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/single_spl2_file_runner.py +0 -0
  13. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/spl2_test_config.json +0 -0
  14. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/spl2_utils/assertions.spl2 +0 -0
  15. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/spl2_utils/logs_to_metrics.spl2 +0 -0
  16. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/test_runner.py +0 -0
  17. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/__init__.py +0 -0
  18. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/create_diff_sheet.py +0 -0
  19. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/jobs/__init__.py +0 -0
  20. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/jobs/cli_job.py +0 -0
  21. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/jobs/cloud_job.py +0 -0
  22. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/jobs/job.py +0 -0
  23. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/jobs/splunk_job.py +0 -0
  24. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/jobs/test_cloud_job.py +0 -0
  25. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/performance.py +0 -0
  26. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/search_clients/__init__.py +0 -0
  27. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/search_clients/cli_search_client.py +0 -0
  28. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/search_clients/cloud_search_client.py +0 -0
  29. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/search_clients/search_client.py +0 -0
  30. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/search_clients/splunk_search_client.py +0 -0
  31. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/test_discovery.py +0 -0
  32. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/test_types.py +0 -0
  33. {spl2_testing_framework-1.3.0 → spl2_testing_framework-1.4.0}/spl2_testing_framework/tools/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spl2-testing-framework
3
- Version: 1.3.0
3
+ Version: 1.4.0
4
4
  Summary: SPL2 Testing Framework
5
5
  Home-page: https://github.com/splunk/spl2-testing-framework
6
6
  Keywords: SPL2 testing framework
@@ -131,6 +131,7 @@ It is possible to pass more options to the command, which works also with pytest
131
131
  Additionally, the following options are supported:
132
132
 
133
133
  * `--ignore_empty_strings` - to ignore empty strings in the results
134
+ * `--ignore_additional_fields_in_actual` - to ignore fields present in actual results but not in expected results (useful when actual results contain extra fields that should not affect comparison)
134
135
  * `--create_comparison_sheet` - to create a comparison sheet in `comparison_box_test` folder using actual and expected outputs (works only when running box tests)
135
136
 
136
137
  Note: The `pytest.ini.sample` file allows you to define command parameters. Just update the configurations, rename the
@@ -99,6 +99,7 @@ It is possible to pass more options to the command, which works also with pytest
99
99
  Additionally, the following options are supported:
100
100
 
101
101
  * `--ignore_empty_strings` - to ignore empty strings in the results
102
+ * `--ignore_additional_fields_in_actual` - to ignore fields present in actual results but not in expected results (useful when actual results contain extra fields that should not affect comparison)
102
103
  * `--create_comparison_sheet` - to create a comparison sheet in `comparison_box_test` folder using actual and expected outputs (works only when running box tests)
103
104
 
104
105
  Note: The `pytest.ini.sample` file allows you to define command parameters. Just update the configurations, rename the
@@ -16,7 +16,7 @@
16
16
 
17
17
  [tool.poetry]
18
18
  name = "spl2-testing-framework"
19
- version = "1.3.0"
19
+ version = "1.4.0"
20
20
  description = "SPL2 Testing Framework"
21
21
  authors = ["mgazda-splunk <mgazda@splunk.com>"]
22
22
  readme = "README.md"
@@ -47,6 +47,7 @@ BOX_TEST = "box_test"
47
47
  SINGLE_SPL2_FILE = "single_spl2_file"
48
48
 
49
49
  IGNORE_EMPTY_STRINGS = "ignore_empty_strings"
50
+ IGNORE_ADDITIONAL_FIELDS_IN_ACTUAL = "ignore_additional_fields_in_actual"
50
51
  CREATE_COMPARISON_SHEET = "create_comparison_sheet"
51
52
  PERFORMANCE_CHECK = "performance_check"
52
53
  TEST_TYPE = "type"
@@ -76,6 +77,7 @@ def pytest_addoption(parser):
76
77
  parser.addoption("--sample_delimiter", action="store", default="\n")
77
78
  parser.addoption(f"--{CREATE_COMPARISON_SHEET}", action="store_true", default=False)
78
79
  parser.addoption(f"--{IGNORE_EMPTY_STRINGS}", action="store_true")
80
+ parser.addoption(f"--{IGNORE_ADDITIONAL_FIELDS_IN_ACTUAL}", action="store_true")
79
81
  parser.addoption(f"--{LIMIT_TESTS}", action="store", type=int, default=None)
80
82
 
81
83
 
@@ -249,3 +251,7 @@ def bearer_token_authentication(config):
249
251
  def _set_results_options(metafunc):
250
252
  ignore_empty_strings = metafunc.config.getoption(IGNORE_EMPTY_STRINGS)
251
253
  Results._ignore_empty_strings = ignore_empty_strings
254
+ ignore_fields_in_actual = metafunc.config.getoption(
255
+ IGNORE_ADDITIONAL_FIELDS_IN_ACTUAL
256
+ )
257
+ Results._ignore_additional_fields_in_actual = ignore_fields_in_actual
@@ -24,6 +24,7 @@ import pytest
24
24
 
25
25
  class Results(UserDict):
26
26
  _ignore_empty_strings = False
27
+ _ignore_additional_fields_in_actual = False
27
28
  """Class responsible for parsing and storing results from Splunk, IP and CLI.
28
29
  It's necessary to parse nested jsons and other python types to strings in order to compare them
29
30
  """
@@ -121,6 +122,53 @@ class Results(UserDict):
121
122
  if self._ignore_empty_strings:
122
123
  self.data = self._remove_field_by_value(self.data, "")
123
124
 
125
+ @staticmethod
126
+ def _remove_extra_fields(actual_data, expected_data):
127
+ """Remove fields from actual_data that are not present in expected_data.
128
+ This is useful when actual results may have additional fields that should be ignored in comparison.
129
+ Works recursively for nested dicts and lists.
130
+ """
131
+ if isinstance(expected_data, dict) and isinstance(actual_data, dict):
132
+ # Get the keys that are in actual but not in expected
133
+ keys_to_remove = set(actual_data.keys()) - set(expected_data.keys())
134
+ for key in keys_to_remove:
135
+ actual_data.pop(key, None)
136
+
137
+ # Recursively process nested structures
138
+ for key in actual_data.keys():
139
+ if key in expected_data:
140
+ if isinstance(actual_data[key], dict) and isinstance(
141
+ expected_data[key], dict
142
+ ):
143
+ Results._remove_extra_fields(
144
+ actual_data[key], expected_data[key]
145
+ )
146
+ elif isinstance(actual_data[key], list) and isinstance(
147
+ expected_data[key], list
148
+ ):
149
+ # For lists, we need to handle them carefully
150
+ if len(actual_data[key]) > 0 and len(expected_data[key]) > 0:
151
+ if isinstance(actual_data[key][0], dict) and isinstance(
152
+ expected_data[key][0], dict
153
+ ):
154
+ # If both are lists of dicts, process each element
155
+ for i in range(
156
+ min(len(actual_data[key]), len(expected_data[key]))
157
+ ):
158
+ Results._remove_extra_fields(
159
+ actual_data[key][i], expected_data[key][i]
160
+ )
161
+
162
+ return actual_data
163
+
164
+ def remove_fields_not_in_expected(self, expected):
165
+ """Remove fields from this Results object that are not present in the expected Results object.
166
+ This is the public method to be called when comparing results.
167
+ """
168
+ if self._ignore_additional_fields_in_actual and isinstance(expected, Results):
169
+ self.data = self._remove_extra_fields(self.data, expected.data)
170
+ return self
171
+
124
172
  def __lt__(self, other):
125
173
  if "_raw" in self.data:
126
174
  s = self.data.get("_raw")
@@ -131,6 +131,11 @@ class SPL2TestRunner:
131
131
  perf.check_performance(output_result)
132
132
 
133
133
  if box_test.output:
134
+ # Remove fields from actual results that are not in expected results if configured
135
+ for i, actual_result in enumerate(output_result):
136
+ if i < len(box_test.output):
137
+ actual_result.remove_fields_not_in_expected(box_test.output[i])
138
+
134
139
  if self.create_comparison_sheet:
135
140
  self.comp_obj.create_comparison_sheet(output_result, box_test)
136
141
  assert sorted(output_result) == sorted(box_test.output)
@@ -141,6 +146,11 @@ class SPL2TestRunner:
141
146
  _LOGGER.info(f"Output check skipped (expected empty): {box_test.name}")
142
147
 
143
148
  if box_test.metrics:
149
+ # Remove fields from actual metrics that are not in expected metrics if configured
150
+ for i, actual_metric in enumerate(metrics_result):
151
+ if i < len(box_test.metrics):
152
+ actual_metric.remove_fields_not_in_expected(box_test.metrics[i])
153
+
144
154
  assert sorted(metrics_result) == sorted(box_test.metrics)
145
155
  _LOGGER.info(f"Metric check passed: {box_test.name}")
146
156
  _LOGGER.debug("Received: \n%s", str(metrics_result))