Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: validation of detections against cms_main #303

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5ebdfc4
typing and linting fixes
cmcginley-splunk Sep 13, 2024
61e811d
Merge branch 'main' into feature/validation_against_cms_main
cmcginley-splunk Sep 16, 2024
336cd7b
initial commit; adding validation against CMS index
cmcginley-splunk Oct 8, 2024
2c87187
added logic for checking when to run cms testing
cmcginley-splunk Oct 8, 2024
386fe7a
Merge branch 'main' into feature/validation_against_cms_main
cmcginley-splunk Oct 8, 2024
27cc478
migrated logging to utils
cmcginley-splunk Oct 8, 2024
35ece19
writing out setup complete to terminal
cmcginley-splunk Oct 8, 2024
21520bc
setup functions need to be run before we can check if content version…
cmcginley-splunk Oct 8, 2024
8391a50
Merge branch 'main' into feature/validation_against_cms_main
cmcginley-splunk Oct 16, 2024
84e89c4
missing comma
cmcginley-splunk Oct 24, 2024
e87fe15
Merge branch 'main' into feature/validation_against_cms_main
cmcginley-splunk Oct 24, 2024
84a0d1b
logging the beginning of content versioning validation
cmcginley-splunk Oct 24, 2024
c849694
adjusting for some of the changes in build and ES 8.0
cmcginley-splunk Oct 29, 2024
4a5cc2f
adding error filtering
cmcginley-splunk Oct 29, 2024
1f2431f
bugfix fitlering
cmcginley-splunk Oct 30, 2024
aac149c
bumping timeout
cmcginley-splunk Oct 30, 2024
b3c6948
TODO (revert): temporarily disabling some v
cmcginley-splunk Oct 30, 2024
5fadeed
Merge branch 'main' into feature/validation_against_cms_main
pyth0n1c Nov 4, 2024
65f3c81
logging tracebacks in verbose mode
cmcginley-splunk Nov 21, 2024
614d4fd
Merge branch 'main' into feature/validation_against_cms_main
cmcginley-splunk Nov 21, 2024
4b79565
Merge branch 'feature/validation_against_cms_main' of https://github.…
cmcginley-splunk Nov 21, 2024
57fe775
Revert "TODO (revert): temporarily disabling some v"
cmcginley-splunk Nov 21, 2024
390c372
updating TODOs, updating query
cmcginley-splunk Dec 9, 2024
8362af7
annotating issues
cmcginley-splunk Dec 10, 2024
5f78f20
removing .DS_store
cmcginley-splunk Feb 3, 2025
d8899de
Merge branch 'main' into feature/validation_against_cms_main
cmcginley-splunk Feb 3, 2025
12afdd5
Merge branch 'main' into feature/validation_against_cms_main
cmcginley-splunk Feb 3, 2025
ec3a50f
formatting
cmcginley-splunk Feb 3, 2025
e8fa869
addressing some of Eric's comments
cmcginley-splunk Feb 3, 2025
e4cadcb
resolving TODOs
cmcginley-splunk Feb 3, 2025
5b9c05b
removing a stale TODO
cmcginley-splunk Feb 3, 2025
71b3d45
reordering the conditionals
cmcginley-splunk Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 64 additions & 24 deletions contentctl/actions/detection_testing/DetectionTestingManager.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
import concurrent.futures
import datetime
import signal
import traceback
from dataclasses import dataclass
from typing import List, Union
from contentctl.objects.config import test, test_servers, Container, Infrastructure

import docker
from pydantic import BaseModel

from contentctl.actions.detection_testing.infrastructures.DetectionTestingInfrastructure import (
DetectionTestingInfrastructure,
DetectionTestingManagerOutputDto,
)
from contentctl.actions.detection_testing.infrastructures.DetectionTestingInfrastructureContainer import (
DetectionTestingInfrastructureContainer,
)
from contentctl.actions.detection_testing.infrastructures.DetectionTestingInfrastructureServer import (
DetectionTestingInfrastructureServer,
)
import signal
import datetime

# from queue import Queue
from dataclasses import dataclass

# import threading
from contentctl.actions.detection_testing.infrastructures.DetectionTestingInfrastructure import (
DetectionTestingManagerOutputDto,
)
from contentctl.actions.detection_testing.views.DetectionTestingView import (
DetectionTestingView,
)
from contentctl.objects.enums import PostTestBehavior
from pydantic import BaseModel
from contentctl.objects.config import Container, Infrastructure, test, test_servers
from contentctl.objects.detection import Detection
import concurrent.futures
import docker
from contentctl.objects.enums import PostTestBehavior


@dataclass(frozen=False)
Expand Down Expand Up @@ -63,12 +60,14 @@ def sigint_handler(signum, frame):
# a newline '\r\n' which will cause that wait to stop
print("*******************************")
print(
"If testing is paused and you are debugging a detection, you MUST hit CTRL-D at the prompt to complete shutdown."
"If testing is paused and you are debugging a detection, you MUST hit CTRL-D "
"at the prompt to complete shutdown."
)
print("*******************************")

signal.signal(signal.SIGINT, sigint_handler)

# TODO (#337): futures can be hard to maintain/debug; let's consider alternatives
with (
concurrent.futures.ThreadPoolExecutor(
max_workers=len(self.input_dto.config.test_instances),
Expand All @@ -80,10 +79,19 @@ def sigint_handler(signum, frame):
max_workers=len(self.input_dto.config.test_instances),
) as view_shutdowner,
):
# Capture any errors for reporting at the end after all threads have been gathered
cmcginley-splunk marked this conversation as resolved.
Show resolved Hide resolved
errors: dict[str, list[Exception]] = {
"INSTANCE SETUP ERRORS": [],
"TESTING ERRORS": [],
"ERRORS DURING VIEW SHUTDOWN": [],
"ERRORS DURING VIEW EXECUTION": [],
}

# Start all the views
future_views = {
view_runner.submit(view.setup): view for view in self.input_dto.views
}

# Configure all the instances
future_instances_setup = {
instance_pool.submit(instance.setup): instance
Expand All @@ -96,7 +104,11 @@ def sigint_handler(signum, frame):
future.result()
except Exception as e:
self.output_dto.terminate = True
print(f"Error setting up container: {str(e)}")
# Output the traceback if we encounter errors in verbose mode
if self.input_dto.config.verbose:
tb = traceback.format_exc()
print(tb)
errors["INSTANCE SETUP ERRORS"].append(e)

# Start and wait for all tests to run
if not self.output_dto.terminate:
Expand All @@ -111,7 +123,11 @@ def sigint_handler(signum, frame):
future.result()
except Exception as e:
self.output_dto.terminate = True
print(f"Error running in container: {str(e)}")
# Output the traceback if we encounter errors in verbose mode
if self.input_dto.config.verbose:
tb = traceback.format_exc()
print(tb)
errors["TESTING ERRORS"].append(e)

self.output_dto.terminate = True

Expand All @@ -123,14 +139,34 @@ def sigint_handler(signum, frame):
try:
future.result()
except Exception as e:
print(f"Error stopping view: {str(e)}")
# Output the traceback if we encounter errors in verbose mode
if self.input_dto.config.verbose:
tb = traceback.format_exc()
print(tb)
errors["ERRORS DURING VIEW SHUTDOWN"].append(e)

# Wait for original view-related threads to complete
for future in concurrent.futures.as_completed(future_views):
try:
future.result()
except Exception as e:
print(f"Error running container: {str(e)}")
# Output the traceback if we encounter errors in verbose mode
if self.input_dto.config.verbose:
tb = traceback.format_exc()
print(tb)
errors["ERRORS DURING VIEW EXECUTION"].append(e)

# Log any errors
for error_type in errors:
if len(errors[error_type]) > 0:
print()
print(f"[{error_type}]:")
for error in errors[error_type]:
print(f"\t❌ {str(error)}")
if isinstance(error, ExceptionGroup):
for suberror in error.exceptions: # type: ignore
print(f"\t\t❌ {str(suberror)}") # type: ignore
print()

return self.output_dto

Expand All @@ -154,12 +190,15 @@ def create_DetectionTestingInfrastructureObjects(self):
)
if len(parts) != 2:
raise Exception(
f"Expected to find a name:tag in {self.input_dto.config.container_settings.full_image_path}, "
f"but instead found {parts}. Note that this path MUST include the tag, which is separated by ':'"
"Expected to find a name:tag in "
f"{self.input_dto.config.container_settings.full_image_path}, "
f"but instead found {parts}. Note that this path MUST include the "
"tag, which is separated by ':'"
)

print(
f"Getting the latest version of the container image [{self.input_dto.config.container_settings.full_image_path}]...",
"Getting the latest version of the container image "
f"[{self.input_dto.config.container_settings.full_image_path}]...",
end="",
flush=True,
)
Expand All @@ -168,7 +207,8 @@ def create_DetectionTestingInfrastructureObjects(self):
break
except Exception as e:
raise Exception(
f"Failed to pull docker container image [{self.input_dto.config.container_settings.full_image_path}]: {str(e)}"
"Failed to pull docker container image "
f"[{self.input_dto.config.container_settings.full_image_path}]: {str(e)}"
)

already_staged_container_files = False
Expand Down
Loading
Loading