spl2-testing-framework 1.0.1__tar.gz → 1.1.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 (32) hide show
  1. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/PKG-INFO +5 -1
  2. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/README.md +4 -0
  3. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/pyproject.toml +1 -1
  4. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/conftest.py +20 -6
  5. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/results.py +24 -6
  6. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/search_clients/cloud_search_client.py +4 -2
  7. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/LICENSE +0 -0
  8. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/__init__.py +0 -0
  9. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/launch_remotely_spl2.py +0 -0
  10. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/logger_manager.py +0 -0
  11. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/pytest.ini.sample +0 -0
  12. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/single_spl2_file_runner.py +0 -0
  13. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/spl2_test_config.json +0 -0
  14. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/spl2_utils/assertions.spl2 +0 -0
  15. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/spl2_utils/logs_to_metrics.spl2 +0 -0
  16. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/test_runner.py +0 -0
  17. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/__init__.py +0 -0
  18. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/jobs/__init__.py +0 -0
  19. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/jobs/cli_job.py +0 -0
  20. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/jobs/cloud_job.py +0 -0
  21. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/jobs/job.py +0 -0
  22. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/jobs/splunk_job.py +0 -0
  23. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/jobs/test_cloud_job.py +0 -0
  24. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/performance.py +0 -0
  25. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/search_clients/__init__.py +0 -0
  26. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/search_clients/cli_search_client.py +0 -0
  27. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/search_clients/search_client.py +0 -0
  28. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/search_clients/splunk_search_client.py +0 -0
  29. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/spl2test_runner.py +0 -0
  30. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/test_discovery.py +0 -0
  31. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.0}/spl2_testing_framework/tools/test_types.py +0 -0
  32. {spl2_testing_framework-1.0.1 → spl2_testing_framework-1.1.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.0.1
3
+ Version: 1.1.0
4
4
  Summary: SPL2 Testing Framework
5
5
  Home-page: https://cd.splunkdev.com/data-availability/spl2-content-tools
6
6
  Keywords: SPL2 testing framework
@@ -120,6 +120,10 @@ It is possible to pass more options to the command, which works also with pytest
120
120
  * `-pdb` - to enter debugger on failure
121
121
  * ... and much more, whatever is supported by pytest
122
122
 
123
+ Additionally, the following options are supported:
124
+
125
+ * `--ignore_empty_strings` - to ignore empty strings in the results
126
+
123
127
  Note: The `pytest.ini.sample` file allows you to define command parameters. Just update the configurations, rename the
124
128
  file by removing the `.sample` extension, and execute the command.
125
129
 
@@ -96,6 +96,10 @@ It is possible to pass more options to the command, which works also with pytest
96
96
  * `-pdb` - to enter debugger on failure
97
97
  * ... and much more, whatever is supported by pytest
98
98
 
99
+ Additionally, the following options are supported:
100
+
101
+ * `--ignore_empty_strings` - to ignore empty strings in the results
102
+
99
103
  Note: The `pytest.ini.sample` file allows you to define command parameters. Just update the configurations, rename the
100
104
  file by removing the `.sample` extension, and execute the command.
101
105
 
@@ -16,7 +16,7 @@
16
16
 
17
17
  [tool.poetry]
18
18
  name = "spl2-testing-framework"
19
- version = "1.0.1"
19
+ version = "1.1.0"
20
20
  description = "SPL2 Testing Framework"
21
21
  authors = ["mgazda-splunk <mgazda@splunk.com>"]
22
22
  readme = "README.md"
@@ -19,6 +19,8 @@ import os
19
19
 
20
20
  import pytest
21
21
 
22
+ from .tools.results import Results
23
+
22
24
  pytest.register_assert_rewrite("spl2_testing_framework")
23
25
 
24
26
  from requests.auth import AuthBase, HTTPBasicAuth
@@ -44,6 +46,11 @@ UNIT_TEST = "unit_test"
44
46
  BOX_TEST = "box_test"
45
47
  SINGLE_SPL2_FILE = "single_spl2_file"
46
48
 
49
+ IGNORE_EMPTY_STRINGS = "ignore_empty_strings"
50
+ PERFORMANCE_CHECK = "performance_check"
51
+ TEST_TYPE = "type"
52
+ TEST_DIR = "test_dir"
53
+
47
54
  import logging
48
55
 
49
56
  from .logger_manager import setup_logging
@@ -54,10 +61,10 @@ _LOGGER = logging.getLogger(__name__)
54
61
 
55
62
 
56
63
  def pytest_addoption(parser):
57
- parser.addoption("--type", action="store", default="local")
58
- parser.addoption("--test_dir", action="store", default=".")
64
+ parser.addoption(f"--{TEST_TYPE}", action="store", default="local")
65
+ parser.addoption(f"--{TEST_DIR}", action="store", default=".")
59
66
  parser.addoption(
60
- "--performance_check",
67
+ f"--{PERFORMANCE_CHECK}",
61
68
  action="store",
62
69
  default="no",
63
70
  choices=["no", "time", "detailed_time"],
@@ -65,13 +72,15 @@ def pytest_addoption(parser):
65
72
  parser.addoption("--template_file", action="store", default=None)
66
73
  parser.addoption("--sample_file", action="store", default=None)
67
74
  parser.addoption("--sample_delimiter", action="store", default="\n")
75
+ parser.addoption(f"--{IGNORE_EMPTY_STRINGS}", action="store_true")
68
76
 
69
77
 
70
78
  def pytest_generate_tests(metafunc):
71
79
  """This function is used for dynamic generation of tests based on the test files in the directory specified by the
72
80
  --test_dir option"""
73
- test_dir = metafunc.config.getoption("test_dir")
74
- performance_check = metafunc.config.getoption("performance_check")
81
+ test_dir = metafunc.config.getoption(TEST_DIR)
82
+ performance_check = metafunc.config.getoption(PERFORMANCE_CHECK)
83
+ _set_results_options(metafunc)
75
84
 
76
85
  if BOX_TEST in metafunc.fixturenames:
77
86
  _LOGGER.info("Collecting Box Tests")
@@ -121,7 +130,7 @@ def spl2_test_runner(
121
130
  """This fixture is used to create a test runner object based on the test type specified by the --type option
122
131
  3 types of tests are supported: 'splunk', 'cloud', 'cli'
123
132
  """
124
- test_type = request.config.option.type.lower()
133
+ test_type = request.config.getoption(TEST_TYPE).lower()
125
134
  if test_type == "splunk":
126
135
  url = f"{config['host']}:{config['port']}"
127
136
  search_client = SplunkSearchClient(url=url, auth=basic_authentication)
@@ -215,3 +224,8 @@ def bearer_token_authentication(config):
215
224
 
216
225
  token = config.get("bearer_token", "")
217
226
  return HTTPBearerTokenAuth(token)
227
+
228
+
229
+ def _set_results_options(metafunc):
230
+ ignore_empty_strings = metafunc.config.getoption(IGNORE_EMPTY_STRINGS)
231
+ Results._ignore_empty_strings = ignore_empty_strings
@@ -17,10 +17,13 @@
17
17
  import json
18
18
  from collections import UserDict
19
19
  from datetime import datetime, timezone
20
+ from os import remove
20
21
  from typing import Any
22
+ import pytest
21
23
 
22
24
 
23
25
  class Results(UserDict):
26
+ _ignore_empty_strings = False
24
27
  """Class responsible for parsing and storing results from Splunk, IP and CLI.
25
28
  It's necessary to parse nested jsons and other python types to strings in order to compare them
26
29
  """
@@ -33,6 +36,7 @@ class Results(UserDict):
33
36
  ) # TODO -> remove
34
37
 
35
38
  self._remove_timestamps_if_necessary()
39
+ self._remove_all_empty_strings_from_dicts_if_necessary()
36
40
 
37
41
  @staticmethod
38
42
  def _cast_types(data: Any):
@@ -83,26 +87,40 @@ class Results(UserDict):
83
87
  self.data.pop("_has_time", None)
84
88
 
85
89
  @staticmethod
86
- def _remove_all_string_nulls_from_dicts(
87
- data,
88
- ): # TODO -> remove, it's just a workaround for different behaviour of splunk, IP and CLI
90
+ def _remove_field_by_value(data, value):
91
+ # TODO -> remove, it's just a workaround for different behaviour of splunk, IP and CLI
89
92
  """Because of different behaviour of Splunk, IP and CLI, we need to remove all "null" values,
90
93
  which are returned by CLI
91
94
  """
92
95
  for k, v in list(
93
96
  data.items()
94
97
  ): # list(...) is to avoid changing dict size during iteration
95
- if v == "null":
98
+ if v == value:
96
99
  del data[k]
97
100
  if isinstance(v, dict):
98
- Results._remove_all_string_nulls_from_dicts(v)
101
+ Results._remove_field_by_value(v, value)
99
102
  if isinstance(v, list):
100
103
  for item in v[:]:
101
104
  if isinstance(item, dict):
102
- Results._remove_all_string_nulls_from_dicts(item)
105
+ Results._remove_field_by_value(item, value)
103
106
 
104
107
  return data
105
108
 
109
+ def _remove_all_string_nulls_from_dicts(self, data):
110
+ # TODO -> remove, it's just a workaround for different behaviour of splunk, IP and CLI
111
+ """Because of different behaviour of Splunk, IP and CLI, we need to remove all "null" values,
112
+ which are returned by CLI
113
+ """
114
+ return self._remove_field_by_value(data, "null")
115
+
116
+ def _remove_all_empty_strings_from_dicts_if_necessary(self):
117
+ """If ignore_empty_strings is True, remove all empty strings from dicts
118
+ This is necessary because for some cases we may want to ignore empty strings in comparison
119
+ (e.g. when a field is not set, it may be returned as empty string)
120
+ """
121
+ if self._ignore_empty_strings:
122
+ self.data = self._remove_field_by_value(self.data, "")
123
+
106
124
  def __lt__(self, other):
107
125
  if "_raw" in self.data:
108
126
  s = self.data.get("_raw")
@@ -76,9 +76,11 @@ class CloudSearchClient(HTTPSSearchClient):
76
76
  if response.status_code != 200:
77
77
  if "GET_PIPELINE_NOT_FOUND" in response.text:
78
78
  continue
79
- raise Exception(response.text)
79
+ raise Exception(f"Job failed, id: {job_id}", response.text)
80
80
  if response.json()["status"] == "failed":
81
- raise Exception(f"Job failed, id: {job_id}")
81
+ raise Exception(
82
+ f"Job failed, id: {job_id}", response.status_code, response.text
83
+ )
82
84
  if response.json()["status"] == "done":
83
85
  return response
84
86
  time.sleep(1)