spl2-testing-framework 1.8.4__tar.gz → 1.8.6__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.4 → spl2_testing_framework-1.8.6}/PKG-INFO +2 -1
  2. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/README.md +1 -0
  3. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/pyproject.toml +1 -1
  4. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/conftest.py +13 -1
  5. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/results.py +16 -3
  6. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/test_discovery.py +15 -0
  7. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/LICENSE +0 -0
  8. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/__init__.py +0 -0
  9. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/launch_remotely_spl2.py +0 -0
  10. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/logger_manager.py +0 -0
  11. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/pytest.ini.sample +0 -0
  12. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/single_spl2_file_runner.py +0 -0
  13. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/spl2_test_config.json +0 -0
  14. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/spl2_utils/assertions.spl2 +0 -0
  15. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/spl2_utils/logs_to_metrics.spl2 +0 -0
  16. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/splunk_setup.py +0 -0
  17. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/test_runner.py +0 -0
  18. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/__init__.py +0 -0
  19. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/create_diff_sheet.py +0 -0
  20. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/jobs/__init__.py +0 -0
  21. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/jobs/cli_job.py +0 -0
  22. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/jobs/cloud_job.py +0 -0
  23. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/jobs/job.py +0 -0
  24. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/jobs/splunk_job.py +0 -0
  25. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/jobs/test_cloud_job.py +0 -0
  26. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/performance.py +0 -0
  27. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/search_clients/__init__.py +0 -0
  28. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/search_clients/cli_search_client.py +0 -0
  29. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/search_clients/cloud_search_client.py +0 -0
  30. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/search_clients/search_client.py +0 -0
  31. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/search_clients/splunk_search_client.py +0 -0
  32. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/spl2test_runner.py +0 -0
  33. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/splunk_integration/__init__.py +0 -0
  34. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/splunk_integration/splunk_handler.py +0 -0
  35. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/spl2_testing_framework/tools/test_types.py +0 -0
  36. {spl2_testing_framework-1.8.4 → spl2_testing_framework-1.8.6}/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.4
3
+ Version: 1.8.6
4
4
  Summary: SPL2 Testing Framework
5
5
  Home-page: https://github.com/splunk/spl2-testing-framework
6
6
  Keywords: SPL2 testing framework
@@ -142,6 +142,7 @@ Additionally, the following options are supported:
142
142
  * `--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
143
  * `--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
144
  * `--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.
145
+ * `--include_placeholder_tests` - include tests whose source contains unresolved `##name##` placeholders. By default such tests are skipped with a warning.
145
146
 
146
147
  * Note: The `pytest.ini.sample` file allows you to define command parameters. Just update the configurations, rename the
147
148
  file by removing the `.sample` extension, and execute the command.
@@ -109,6 +109,7 @@ Additionally, the following options are supported:
109
109
  * `--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
110
  * `--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
111
  * `--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.
112
+ * `--include_placeholder_tests` - include tests whose source contains unresolved `##name##` placeholders. By default such tests are skipped with a warning.
112
113
 
113
114
  * Note: The `pytest.ini.sample` file allows you to define command parameters. Just update the configurations, rename the
114
115
  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.4"
18
+ version = "1.8.6"
19
19
  description = "SPL2 Testing Framework"
20
20
  authors = ["mgazda-splunk <mgazda@splunk.com>"]
21
21
  readme = "README.md"
@@ -62,6 +62,7 @@ LIMIT_TESTS = "limit_tests"
62
62
  CLI_BENCH = "cli_bench"
63
63
  LOOKUPS_ROOT_DIR = "lookups_root_dir"
64
64
  REDUCTION_STATS = "reduction_stats"
65
+ INCLUDE_PLACEHOLDER_TESTS = "include_placeholder_tests"
65
66
 
66
67
  setup_logging()
67
68
 
@@ -114,6 +115,12 @@ def pytest_addoption(parser):
114
115
  default=False,
115
116
  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
117
  )
118
+ parser.addoption(
119
+ f"--{INCLUDE_PLACEHOLDER_TESTS}",
120
+ action="store_true",
121
+ default=False,
122
+ help="Include tests whose source contains unresolved ##name## placeholders. By default such tests are skipped with a warning.",
123
+ )
117
124
 
118
125
 
119
126
  def pytest_generate_tests(metafunc):
@@ -123,12 +130,17 @@ def pytest_generate_tests(metafunc):
123
130
  code_dir = metafunc.config.getoption(CODE_DIR)
124
131
  performance_check = metafunc.config.getoption(PERFORMANCE_CHECK)
125
132
  limit_tests = metafunc.config.getoption(LIMIT_TESTS)
133
+ include_placeholder_tests = metafunc.config.getoption(INCLUDE_PLACEHOLDER_TESTS)
126
134
  _set_results_options(metafunc)
127
135
 
128
136
  if BOX_TEST in metafunc.fixturenames:
129
137
  _LOGGER.info("Collecting Box Tests")
130
138
  module_tests = BoxTestDiscovery(
131
- test_dir, performance_check, limit_tests, code_dir=code_dir
139
+ test_dir,
140
+ performance_check,
141
+ limit_tests,
142
+ code_dir=code_dir,
143
+ include_placeholder_tests=include_placeholder_tests,
132
144
  )
133
145
  module_tests.discover_tests()
134
146
  metafunc.parametrize(
@@ -15,10 +15,13 @@
15
15
 
16
16
  import ast
17
17
  import json
18
+ import re
18
19
  from collections import UserDict
19
20
  from datetime import datetime, timezone
20
21
  from typing import Any
21
22
 
23
+ _WHOLE_FLOAT_STR_RE = re.compile(r"^(-?\d+)\.0+$")
24
+
22
25
 
23
26
  class Results(UserDict):
24
27
  _ignore_empty_strings = False
@@ -76,10 +79,20 @@ class Results(UserDict):
76
79
  if isinstance(data, bool):
77
80
  data = str(data).lower()
78
81
  elif isinstance(data, (int, float)):
79
- data = str(data)
82
+ data = (
83
+ str(int(data))
84
+ if isinstance(data, float) and data == int(data)
85
+ else str(data)
86
+ )
80
87
 
81
- if isinstance(data, str) and data in ("True", "False"):
82
- data = data.lower()
88
+ if isinstance(data, str):
89
+ if data in ("True", "False"):
90
+ data = data.lower()
91
+ # Normalize "7.0", "7.00", "7.00000" → "7" for whole-number float strings returned by Splunk.
92
+ else:
93
+ m = _WHOLE_FLOAT_STR_RE.match(data)
94
+ if m:
95
+ data = m.group(1)
83
96
 
84
97
  return data
85
98
 
@@ -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)