Skip to content

Commit f43bfb6

Browse files
chore: modify uuid approach
1 parent edaad7f commit f43bfb6

File tree

9 files changed

+316
-168
lines changed

9 files changed

+316
-168
lines changed

pytest_splunk_addon/fields_tests/test_generator.py

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -264,27 +264,20 @@ def generate_requirements_tests(self):
264264
for field, value in requirement_fields.items()
265265
if field not in exceptions
266266
}
267-
unique_identifier = (
268-
getattr(event, "unique_identifier", None)
269-
if metadata.get("ingest_with_uuid") == "true"
270-
else None
271-
)
272-
variant_id = metadata.get("variant_id")
273-
search_selector = (
274-
{
275-
"unique_identifier": unique_identifier,
276-
"escaped_event": escaped_event,
277-
"variant_id": variant_id,
278-
}
279-
if unique_identifier is not None
280-
else {"escaped_event": escaped_event, "variant_id": variant_id}
281-
)
267+
sample_event = {
268+
"escaped_event": escaped_event,
269+
"fields": requirement_fields,
270+
"modinput_params": modinput_params,
271+
}
272+
273+
# Add unique_identifier if UUID ingestion is enabled and event has UUID
274+
if metadata.get("ingest_with_uuid") == "true":
275+
unique_identifier = getattr(event, "unique_identifier", None)
276+
if unique_identifier is not None:
277+
sample_event["unique_identifier"] = unique_identifier
278+
282279
yield pytest.param(
283-
{
284-
**search_selector,
285-
"fields": requirement_fields,
286-
"modinput_params": modinput_params,
287-
},
280+
sample_event,
288281
id=f"sample_name::{event.sample_name}::host::{event.metadata.get('host')}",
289282
)
290283

pytest_splunk_addon/fields_tests/test_templates.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -162,19 +162,20 @@ def test_requirements_fields(
162162
"""
163163

164164
# Search Query
165-
record_property(
166-
"Event_with", splunk_searchtime_fields_requirements["escaped_event"]
165+
unique_identifier = splunk_searchtime_fields_requirements.get(
166+
"unique_identifier"
167167
)
168+
escaped_event = splunk_searchtime_fields_requirements.get("escaped_event")
169+
event_identifier = (
170+
unique_identifier if unique_identifier is not None else escaped_event
171+
)
172+
173+
record_property("Event_with", event_identifier)
168174
record_property("fields", splunk_searchtime_fields_requirements["fields"])
169175
record_property(
170176
"modinput_params", splunk_searchtime_fields_requirements["modinput_params"]
171177
)
172178

173-
escaped_event = splunk_searchtime_fields_requirements.get("escaped_event")
174-
unique_identifier = splunk_searchtime_fields_requirements.get(
175-
"unique_identifier"
176-
)
177-
variant_id = splunk_searchtime_fields_requirements.get("variant_id")
178179
fields = splunk_searchtime_fields_requirements["fields"]
179180
modinput_params = splunk_searchtime_fields_requirements["modinput_params"]
180181

@@ -190,16 +191,13 @@ def test_requirements_fields(
190191
basic_search += f" {param}={param_value}"
191192

192193
if unique_identifier is not None:
193-
selector = f'fields.unique_identifier="{unique_identifier}"'
194+
selector = f'unique_identifier="{unique_identifier}"'
194195
elif escaped_event is not None:
195196
selector = escaped_event
196197
else:
197198
selector = ""
198-
variant_clause = f" variant_id={variant_id}" if variant_id is not None else ""
199199

200-
search = (
201-
f"search {index_list} {basic_search} {selector}{variant_clause} | fields *"
202-
)
200+
search = f"search {index_list} {basic_search} {selector} | fields *"
203201

204202
self.logger.info(f"Executing the search query: {search}")
205203

@@ -241,8 +239,7 @@ def test_requirements_fields(
241239
f"{format_search_query_log(search)}"
242240
)
243241

244-
if splunk_searchtime_fields_requirements.get("unique_identifier"):
245-
error_message += f"Test failed for event: {escaped_event}\n"
242+
error_message += f"Test failed for event: {event_identifier}\n"
246243

247244
assert wrong_value_fields == {}, error_message
248245

pytest_splunk_addon/sample_generation/sample_event.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ def __init__(self, event_string, metadata, sample_name, requirement_test_data=No
6868
self.time_values = list()
6969
self.metadata = metadata
7070
self.sample_name = sample_name
71-
if metadata.get("ingest_with_uuid") == "true":
72-
self.unique_identifier = str(uuid.uuid4())
71+
# UUID will be assigned post-tokenization per final event to avoid duplicates
7372
self.host_count = 0
7473
self.requirement_test_data = requirement_test_data
7574

pytest_splunk_addon/sample_generation/sample_stanza.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import os
1717
import re
1818
import copy
19+
import uuid
1920
from . import Rule
2021
from . import raise_warning
2122
from . import SampleEvent
@@ -103,6 +104,10 @@ def tokenize(self, conf_name):
103104
if each_rule:
104105
raw_event[event_counter] = each_rule.apply(raw_event[event_counter])
105106
for event in raw_event[event_counter]:
107+
# Assign UUID per finalized event to ensure uniqueness across variants
108+
if event.metadata.get("ingest_with_uuid") == "true":
109+
event.unique_identifier = str(uuid.uuid4())
110+
106111
host_value = event.metadata.get("host")
107112
host = token_value(key=host_value, value=host_value)
108113
event.update_requirement_test_field("host", "##host##", host)
@@ -267,9 +272,6 @@ def get_eventmetadata(self):
267272
self.host_count += 1
268273
event_host = self.metadata.get("host") + "_" + str(self.host_count)
269274
event_metadata = copy.deepcopy(self.metadata)
270-
# Add variant_id only when UUID ingestion is enabled
271-
if event_metadata.get("ingest_with_uuid") == "true":
272-
event_metadata.update(variant_id=self.host_count)
273275
event_metadata.update(host=event_host)
274276
LOGGER.info("event metadata: {}".format(event_metadata))
275277
return event_metadata

tests/unit/tests_standard_lib/test_fields_tests/test_test_generator.py

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,6 @@ def test_generate_field_tests(
486486
(
487487
{
488488
"escaped_event": "escaped_event",
489-
"variant_id": None,
490489
"fields": {
491490
"severity": "low",
492491
"signature_id": "405001",
@@ -502,7 +501,6 @@ def test_generate_field_tests(
502501
(
503502
{
504503
"escaped_event": "escaped_event",
505-
"variant_id": None,
506504
"fields": {
507505
"src": "192.168.0.1",
508506
"type": "event",
@@ -537,34 +535,35 @@ def test_generate_requirement_tests(tokenised_events, expected_output):
537535

538536

539537
def test_generate_requirement_tests_with_uuid(mock_uuid4):
540-
tokenised_events = [
541-
SampleEvent(
542-
event_string="escaped_event",
543-
metadata={
544-
"input_type": "modinput",
545-
"sourcetype_to_search": "dummy_sourcetype",
546-
"host": "dummy_host",
547-
"ingest_with_uuid": "true",
548-
"unique_identifier": "uuid",
549-
},
550-
sample_name="file1.xml",
551-
requirement_test_data={
552-
"cim_fields": {
553-
"severity": "low",
554-
"signature_id": "405001",
555-
"src": "192.168.0.1",
556-
"type": "event",
557-
},
538+
event = SampleEvent(
539+
event_string="escaped_event",
540+
metadata={
541+
"input_type": "modinput",
542+
"sourcetype_to_search": "dummy_sourcetype",
543+
"host": "dummy_host",
544+
"ingest_with_uuid": "true",
545+
},
546+
sample_name="file1.xml",
547+
requirement_test_data={
548+
"cim_fields": {
549+
"severity": "low",
550+
"signature_id": "405001",
551+
"src": "192.168.0.1",
552+
"type": "event",
558553
},
559-
)
560-
]
554+
},
555+
)
556+
557+
# Simulate tokenization UUID assignment
558+
event.unique_identifier = "uuid"
559+
560+
tokenised_events = [event]
561561

562562
expected_output = [
563563
(
564564
{
565565
"escaped_event": "escaped_event",
566566
"unique_identifier": "uuid",
567-
"variant_id": None,
568567
"fields": {
569568
"severity": "low",
570569
"signature_id": "405001",
@@ -668,19 +667,22 @@ def test_generate_requirement_datamodel_tests(tokenised_events, expected_output)
668667

669668

670669
def test_generate_requirement_datamodel_tests_with_uuid(mock_uuid4):
671-
tokenised_events = [
672-
SampleEvent(
673-
event_string="escaped_event",
674-
metadata={
675-
"input_type": "modinput",
676-
"sourcetype_to_search": "dummy_sourcetype",
677-
"host": "dummy_host",
678-
"ingest_with_uuid": "true",
679-
},
680-
sample_name="file1.xml",
681-
requirement_test_data={"datamodels": {"model": "Alerts"}},
682-
)
683-
]
670+
event = SampleEvent(
671+
event_string="escaped_event",
672+
metadata={
673+
"input_type": "modinput",
674+
"sourcetype_to_search": "dummy_sourcetype",
675+
"host": "dummy_host",
676+
"ingest_with_uuid": "true",
677+
},
678+
sample_name="file1.xml",
679+
requirement_test_data={"datamodels": {"model": "Alerts"}},
680+
)
681+
682+
# Simulate tokenization UUID assignment
683+
event.unique_identifier = "uuid"
684+
685+
tokenised_events = [event]
684686

685687
expected_output = [
686688
(

tests/unit/tests_standard_lib/tests_sample_generation/test_sample_event.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,23 @@ def samp_eve():
3535

3636
def test_sample_event_generates_uuid():
3737
METADATA["ingest_with_uuid"] = "true"
38-
with patch(
39-
"pytest_splunk_addon.sample_generation.sample_event.uuid.uuid4",
40-
return_value="uuid",
41-
) as mock_uuid:
42-
event = pytest_splunk_addon.sample_generation.sample_event.SampleEvent(
43-
event_string=EVENT_STRING,
44-
metadata=METADATA,
45-
sample_name=SAMPLE_NAME,
46-
)
47-
48-
mock_uuid.assert_called_once() # Ensures uuid4 was called
38+
event = pytest_splunk_addon.sample_generation.sample_event.SampleEvent(
39+
event_string=EVENT_STRING,
40+
metadata=METADATA,
41+
sample_name=SAMPLE_NAME,
42+
)
43+
44+
# UUID should not be generated during SampleEvent creation anymore
45+
assert not hasattr(
46+
event, "unique_identifier"
47+
), "UUID should not be assigned during SampleEvent creation"
48+
49+
# Simulate tokenization where UUID is assigned
50+
with patch("uuid.uuid4", return_value="uuid") as mock_uuid:
51+
if event.metadata.get("ingest_with_uuid") == "true":
52+
event.unique_identifier = str(mock_uuid())
53+
54+
mock_uuid.assert_called_once() # Ensures uuid4 was called during tokenization simulation
4955
assert hasattr(event, "unique_identifier") # The field was set
5056
assert event.unique_identifier == "uuid"
5157

0 commit comments

Comments
 (0)