spl2-testing-framework 1.8.5__tar.gz → 1.8.7__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 (36) hide show
  1. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/PKG-INFO +3 -1
  2. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/README.md +2 -0
  3. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/pyproject.toml +1 -1
  4. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/conftest.py +22 -1
  5. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/results.py +10 -0
  6. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/spl2test_runner.py +6 -4
  7. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/test_discovery.py +15 -0
  8. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/LICENSE +0 -0
  9. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/__init__.py +0 -0
  10. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/launch_remotely_spl2.py +0 -0
  11. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/logger_manager.py +0 -0
  12. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/pytest.ini.sample +0 -0
  13. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/single_spl2_file_runner.py +0 -0
  14. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/spl2_test_config.json +0 -0
  15. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/spl2_utils/assertions.spl2 +0 -0
  16. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/spl2_utils/logs_to_metrics.spl2 +0 -0
  17. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/splunk_setup.py +0 -0
  18. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/test_runner.py +0 -0
  19. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/__init__.py +0 -0
  20. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/create_diff_sheet.py +0 -0
  21. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/jobs/__init__.py +0 -0
  22. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/jobs/cli_job.py +0 -0
  23. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/jobs/cloud_job.py +0 -0
  24. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/jobs/job.py +0 -0
  25. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/jobs/splunk_job.py +0 -0
  26. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/jobs/test_cloud_job.py +0 -0
  27. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/performance.py +0 -0
  28. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/search_clients/__init__.py +0 -0
  29. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/search_clients/cli_search_client.py +0 -0
  30. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/search_clients/cloud_search_client.py +0 -0
  31. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/search_clients/search_client.py +0 -0
  32. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/search_clients/splunk_search_client.py +0 -0
  33. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/splunk_integration/__init__.py +0 -0
  34. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/splunk_integration/splunk_handler.py +0 -0
  35. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/spl2_testing_framework/tools/test_types.py +0 -0
  36. {spl2_testing_framework-1.8.5 → spl2_testing_framework-1.8.7}/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.8.5
3
+ Version: 1.8.7
4
4
  Summary: SPL2 Testing Framework
5
5
  Home-page: https://github.com/splunk/spl2-testing-framework
6
6
  Keywords: SPL2 testing framework
@@ -135,6 +135,7 @@ Additionally, the following options are supported:
135
135
  * `--code_dir` - directory where SPL2 code modules (`.spl2`) are located. Defaults to the current working directory. Falls back to `--test_dir` if the module is not found. See [Separate code and test directories](#separate-code-and-test-directories) for details.
136
136
  * `--ignore_empty_strings` - to ignore empty strings in the results
137
137
  * `--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)
138
+ * `--keep_tag_fields` - by default, fields whose name starts with `tag::` (e.g. `tag::metric_name`) are stripped from **both** the actual and expected rows before the destination compare. Pass `--keep_tag_fields` to disable this behaviour and include `tag::` fields in the comparison.
138
139
  * `--create_comparison_sheet` - to create a comparison sheet in `comparison_box_test` folder using actual and expected outputs (works only when running box tests)
139
140
  * `--cli_bench` - when running tests with CLI, this option enables benchmarking mode by adding `-b` and `-n` flags to the spl2-processor-cli command. The value specifies the number of events to test (e.g., `--cli_bench=1000` will add `-b -n 1000` to the CLI command). **In bench mode, all tests always succeed and CLI output is printed to logs** - this is useful for performance testing and benchmarking. This is only applicable when using `--type cli`.
140
141
  * `--lookups_root_dir` - root directory passed to `spl2-processor-cli` as `--lookupsRootDir` for resolving lookup `transforms.conf`. Defaults to `.` (current working directory). For a standard TA layout use `--lookups_root_dir=package/default`. Only applicable when using `--type cli`.
@@ -142,6 +143,7 @@ Additionally, the following options are supported:
142
143
  * `--reduction_stats` - when set, **box tests** record a reduction rate per run: input `_raw` vs output `_raw` (after pairing input/output events). Rates are grouped by **pipeline** (the `.spl2` code module stem) and **sourcetype** (from the input event if set, else the output event, else `UNKNOWN`). Off by default.
143
144
  * `--reduction_stats_file` - path to a JSON file written at the **end of the pytest session** with collected rates (default `reduction_stats.json`). Only used when `--reduction_stats` is set.
144
145
  * `--reduction_stats_full` - when set together with `--reduction_stats`, each pipeline’s JSON payload also includes a pandas **`describe()`** summary (count, mean, std, min, quartiles, max) per sourcetype column. Only used when `--reduction_stats` is set.
146
+ * `--include_placeholder_tests` - include tests whose source contains unresolved `##name##` placeholders. By default such tests are skipped with a warning.
145
147
 
146
148
  * Note: The `pytest.ini.sample` file allows you to define command parameters. Just update the configurations, rename the
147
149
  file by removing the `.sample` extension, and execute the command.
@@ -102,6 +102,7 @@ Additionally, the following options are supported:
102
102
  * `--code_dir` - directory where SPL2 code modules (`.spl2`) are located. Defaults to the current working directory. Falls back to `--test_dir` if the module is not found. See [Separate code and test directories](#separate-code-and-test-directories) for details.
103
103
  * `--ignore_empty_strings` - to ignore empty strings in the results
104
104
  * `--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)
105
+ * `--keep_tag_fields` - by default, fields whose name starts with `tag::` (e.g. `tag::metric_name`) are stripped from **both** the actual and expected rows before the destination compare. Pass `--keep_tag_fields` to disable this behaviour and include `tag::` fields in the comparison.
105
106
  * `--create_comparison_sheet` - to create a comparison sheet in `comparison_box_test` folder using actual and expected outputs (works only when running box tests)
106
107
  * `--cli_bench` - when running tests with CLI, this option enables benchmarking mode by adding `-b` and `-n` flags to the spl2-processor-cli command. The value specifies the number of events to test (e.g., `--cli_bench=1000` will add `-b -n 1000` to the CLI command). **In bench mode, all tests always succeed and CLI output is printed to logs** - this is useful for performance testing and benchmarking. This is only applicable when using `--type cli`.
107
108
  * `--lookups_root_dir` - root directory passed to `spl2-processor-cli` as `--lookupsRootDir` for resolving lookup `transforms.conf`. Defaults to `.` (current working directory). For a standard TA layout use `--lookups_root_dir=package/default`. Only applicable when using `--type cli`.
@@ -109,6 +110,7 @@ Additionally, the following options are supported:
109
110
  * `--reduction_stats` - when set, **box tests** record a reduction rate per run: input `_raw` vs output `_raw` (after pairing input/output events). Rates are grouped by **pipeline** (the `.spl2` code module stem) and **sourcetype** (from the input event if set, else the output event, else `UNKNOWN`). Off by default.
110
111
  * `--reduction_stats_file` - path to a JSON file written at the **end of the pytest session** with collected rates (default `reduction_stats.json`). Only used when `--reduction_stats` is set.
111
112
  * `--reduction_stats_full` - when set together with `--reduction_stats`, each pipeline’s JSON payload also includes a pandas **`describe()`** summary (count, mean, std, min, quartiles, max) per sourcetype column. Only used when `--reduction_stats` is set.
113
+ * `--include_placeholder_tests` - include tests whose source contains unresolved `##name##` placeholders. By default such tests are skipped with a warning.
112
114
 
113
115
  * Note: The `pytest.ini.sample` file allows you to define command parameters. Just update the configurations, rename the
114
116
  file by removing the `.sample` extension, and execute the command.
@@ -15,7 +15,7 @@
15
15
 
16
16
  [tool.poetry]
17
17
  name = "spl2-testing-framework"
18
- version = "1.8.5"
18
+ version = "1.8.7"
19
19
  description = "SPL2 Testing Framework"
20
20
  authors = ["mgazda-splunk <mgazda@splunk.com>"]
21
21
  readme = "README.md"
@@ -52,6 +52,7 @@ SINGLE_SPL2_FILE = "single_spl2_file"
52
52
 
53
53
  IGNORE_EMPTY_STRINGS = "ignore_empty_strings"
54
54
  IGNORE_ADDITIONAL_FIELDS_IN_ACTUAL = "ignore_additional_fields_in_actual"
55
+ KEEP_TAG_FIELDS = "keep_tag_fields"
55
56
  CREATE_COMPARISON_SHEET = "create_comparison_sheet"
56
57
  CHECK_SPLUNK_RESULTS = "check_splunk_results"
57
58
  PERFORMANCE_CHECK = "performance_check"
@@ -62,6 +63,7 @@ LIMIT_TESTS = "limit_tests"
62
63
  CLI_BENCH = "cli_bench"
63
64
  LOOKUPS_ROOT_DIR = "lookups_root_dir"
64
65
  REDUCTION_STATS = "reduction_stats"
66
+ INCLUDE_PLACEHOLDER_TESTS = "include_placeholder_tests"
65
67
 
66
68
  setup_logging()
67
69
 
@@ -87,6 +89,12 @@ def pytest_addoption(parser):
87
89
  parser.addoption(f"--{CREATE_COMPARISON_SHEET}", action="store_true", default=False)
88
90
  parser.addoption(f"--{IGNORE_EMPTY_STRINGS}", action="store_true")
89
91
  parser.addoption(f"--{IGNORE_ADDITIONAL_FIELDS_IN_ACTUAL}", action="store_true")
92
+ parser.addoption(
93
+ f"--{KEEP_TAG_FIELDS}",
94
+ action="store_true",
95
+ default=False,
96
+ help="Do not strip tag:: fields from destination compare. By default, fields whose name starts with 'tag::' are excluded from the comparison.",
97
+ )
90
98
  parser.addoption(f"--{LIMIT_TESTS}", action="store", type=int, default=None)
91
99
  parser.addoption(f"--{CLI_BENCH}", action="store", type=int, default=None)
92
100
  parser.addoption(
@@ -114,6 +122,12 @@ def pytest_addoption(parser):
114
122
  default=False,
115
123
  help="Include full dataframe stats (count, mean, std, min, 25%%, 50%%, 75%%, max) in the saved file. Used only when --reduction_stats is set.",
116
124
  )
125
+ parser.addoption(
126
+ f"--{INCLUDE_PLACEHOLDER_TESTS}",
127
+ action="store_true",
128
+ default=False,
129
+ help="Include tests whose source contains unresolved ##name## placeholders. By default such tests are skipped with a warning.",
130
+ )
117
131
 
118
132
 
119
133
  def pytest_generate_tests(metafunc):
@@ -123,12 +137,17 @@ def pytest_generate_tests(metafunc):
123
137
  code_dir = metafunc.config.getoption(CODE_DIR)
124
138
  performance_check = metafunc.config.getoption(PERFORMANCE_CHECK)
125
139
  limit_tests = metafunc.config.getoption(LIMIT_TESTS)
140
+ include_placeholder_tests = metafunc.config.getoption(INCLUDE_PLACEHOLDER_TESTS)
126
141
  _set_results_options(metafunc)
127
142
 
128
143
  if BOX_TEST in metafunc.fixturenames:
129
144
  _LOGGER.info("Collecting Box Tests")
130
145
  module_tests = BoxTestDiscovery(
131
- test_dir, performance_check, limit_tests, code_dir=code_dir
146
+ test_dir,
147
+ performance_check,
148
+ limit_tests,
149
+ code_dir=code_dir,
150
+ include_placeholder_tests=include_placeholder_tests,
132
151
  )
133
152
  module_tests.discover_tests()
134
153
  metafunc.parametrize(
@@ -433,3 +452,5 @@ def _set_results_options(metafunc):
433
452
  IGNORE_ADDITIONAL_FIELDS_IN_ACTUAL
434
453
  )
435
454
  Results._ignore_additional_fields_in_actual = ignore_fields_in_actual
455
+ keep_tag_fields = metafunc.config.getoption(KEEP_TAG_FIELDS)
456
+ Results._ignore_tag_fields = not keep_tag_fields
@@ -26,6 +26,7 @@ _WHOLE_FLOAT_STR_RE = re.compile(r"^(-?\d+)\.0+$")
26
26
  class Results(UserDict):
27
27
  _ignore_empty_strings = False
28
28
  _ignore_additional_fields_in_actual = False
29
+ _ignore_tag_fields = True
29
30
  """Class responsible for parsing and storing results from Splunk, IP and CLI.
30
31
  It's necessary to parse nested jsons and other python types to strings in order to compare them
31
32
  """
@@ -201,6 +202,15 @@ class Results(UserDict):
201
202
  self._remove_extra_fields(self.data, expected.data)
202
203
  return self
203
204
 
205
+ @staticmethod
206
+ def is_ignored_in_destination_compare(key: str) -> bool:
207
+ """Return True if ``key`` should be dropped from destination comparison regardless of
208
+ the per-test ``ignore_fields_in_destination_compare`` list. Currently this covers
209
+ ``tag::*`` fields, which are stripped by default and only kept when
210
+ ``--keep_tag_fields`` is passed.
211
+ """
212
+ return Results._ignore_tag_fields and key.startswith("tag::")
213
+
204
214
  def __lt__(self, other):
205
215
  if "_raw" in self.data:
206
216
  s = self.data.get("_raw")
@@ -220,7 +220,7 @@ class SPL2TestRunner:
220
220
 
221
221
  if self.create_comparison_sheet:
222
222
  self.comp_obj.create_comparison_sheet(output_result, box_test)
223
- if ignore_keys:
223
+ if ignore_keys or Results.is_ignored_in_destination_compare("tag::"):
224
224
  stripped_actual = [
225
225
  Results(
226
226
  self._strip_ignored_fields_for_destination_compare(
@@ -285,9 +285,11 @@ class SPL2TestRunner:
285
285
  def _strip_ignored_fields_for_destination_compare(
286
286
  row: dict, ignore_keys: frozenset
287
287
  ) -> dict:
288
- if not ignore_keys:
289
- return row
290
- return {k: v for k, v in row.items() if k not in ignore_keys}
288
+ return {
289
+ k: v
290
+ for k, v in row.items()
291
+ if k not in ignore_keys and not Results.is_ignored_in_destination_compare(k)
292
+ }
291
293
 
292
294
  def _splunk_process_event(self, box_test: BoxTest, event):
293
295
  try:
@@ -50,11 +50,13 @@ class TestDiscovery(abc.ABC):
50
50
  performance_check: str,
51
51
  limit_tests: Optional[int] = None,
52
52
  code_dir: Optional[str] = None,
53
+ include_placeholder_tests: bool = False,
53
54
  ):
54
55
  self.path = pathlib.Path(path)
55
56
  self.code_dir = pathlib.Path(code_dir) if code_dir else self.path
56
57
  self._performance_check = performance_check
57
58
  self.limit_tests = limit_tests
59
+ self.include_placeholder_tests = include_placeholder_tests
58
60
  self.tests = TestSuite()
59
61
 
60
62
  @property
@@ -181,6 +183,7 @@ class BoxTestDiscovery(TestDiscovery):
181
183
 
182
184
  _IGNORE_FIELDS_IN_DESTINATION_COMPARE_KEY = "ignore_fields_in_destination_compare"
183
185
  _VALID_SKIP_ON_VALUES = frozenset({"standard", "splunk_ta", "splunk_cim"})
186
+ _PLACEHOLDER_PATTERN = re.compile(r"##\w+##")
184
187
 
185
188
  @classmethod
186
189
  def _parse_skip_on(cls, test_block: dict) -> frozenset:
@@ -268,6 +271,18 @@ class BoxTestDiscovery(TestDiscovery):
268
271
  test_block = entry["test"]
269
272
  name = entry["filename"].replace(".spl2", "")
270
273
  test_input = test_block["source"]
274
+ if (
275
+ isinstance(test_input, str)
276
+ and self._PLACEHOLDER_PATTERN.search(test_input)
277
+ and not self.include_placeholder_tests
278
+ ):
279
+ _LOGGER.warning(
280
+ "Skipping test '%s' in '%s': source contains unresolved placeholder(s) (##name##). "
281
+ "Use --include_placeholder_tests to force-include these tests.",
282
+ name,
283
+ module_path,
284
+ )
285
+ continue
271
286
  code_module_path = self._resolve_code_module(entry["filename"])
272
287
  output = [
273
288
  Results(x)