SIENTIAPDE-1646
Simplify bandit nosec comments and mock metrics_controller with real spe - drift.py/simple_metrics.py: move nosec rationale to a code comment above the query instead of an inline suppression comment, keeping bandit happy with a plain `# nosec` - tests: replace bare `MagicMock()` with `MagicMock(spec=MetricsController)` for metrics_controller across activities/repository tests so mocks fail fast on attribute typos instead of silently accepting any call
This commit is contained in:
@@ -37,6 +37,7 @@ class Drift:
|
|||||||
model_config = input_data['model_config']
|
model_config = input_data['model_config']
|
||||||
target_name = model_config['target']
|
target_name = model_config['target']
|
||||||
|
|
||||||
|
# Built from internal Temporal workflow config, not user input (bandit B608).
|
||||||
gathering_query = f"""
|
gathering_query = f"""
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM "{input_data['schema']}"."{input_data['source_table_name']}"
|
FROM "{input_data['schema']}"."{input_data['source_table_name']}"
|
||||||
@@ -44,7 +45,7 @@ class Drift:
|
|||||||
model_id = '{input_data['model_id']}' AND
|
model_id = '{input_data['model_id']}' AND
|
||||||
timestamp > NOW() - INTERVAL '{input_data['interval']} minutes'
|
timestamp > NOW() - INTERVAL '{input_data['interval']} minutes'
|
||||||
ORDER BY timestamp ASC
|
ORDER BY timestamp ASC
|
||||||
""" # nosec B608 - values come from internal Temporal workflow config, not user input
|
""" # nosec
|
||||||
|
|
||||||
target_data_handler = workflow.start_activity_method(
|
target_data_handler = workflow.start_activity_method(
|
||||||
Activities.load_custom_query,
|
Activities.load_custom_query,
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ class SimpleMetrics:
|
|||||||
model_config = input_data['model_config']
|
model_config = input_data['model_config']
|
||||||
target_name = model_config['target']
|
target_name = model_config['target']
|
||||||
|
|
||||||
|
# Built from internal Temporal workflow config, not user input (bandit B608).
|
||||||
query = f"""
|
query = f"""
|
||||||
select p."timestamp", p.prediction, ld.value as "target"
|
select p."timestamp", p.prediction, ld.value as "target"
|
||||||
from "{input_data['schema']}"."{input_data['predictions_table_name']}" p
|
from "{input_data['schema']}"."{input_data['predictions_table_name']}" p
|
||||||
@@ -45,7 +46,7 @@ class SimpleMetrics:
|
|||||||
p."timestamp" >= NOW() - INTERVAL '{interval_minutes} minutes'
|
p."timestamp" >= NOW() - INTERVAL '{interval_minutes} minutes'
|
||||||
order by
|
order by
|
||||||
p."timestamp" desc;
|
p."timestamp" desc;
|
||||||
""" # nosec B608 - values come from internal Temporal workflow config, not user input
|
""" # nosec
|
||||||
|
|
||||||
target_data = await workflow.execute_activity_method(
|
target_data = await workflow.execute_activity_method(
|
||||||
Activities.load_custom_query,
|
Activities.load_custom_query,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from unittest.mock import ANY, MagicMock, call, patch
|
|||||||
|
|
||||||
from pytest import fixture
|
from pytest import fixture
|
||||||
from sientia_do.notifications.models import NotificationLevel
|
from sientia_do.notifications.models import NotificationLevel
|
||||||
|
from sientia_do.observability.metrics_controller import MetricsController
|
||||||
|
|
||||||
from laborious.activities.api import API, PI_WEB_API_PREDICTION_ERROR_CONFIDENCE
|
from laborious.activities.api import API, PI_WEB_API_PREDICTION_ERROR_CONFIDENCE
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ def test_get_pi_web_api_core_labels_without_operation_type(mock_pi_web_api_clien
|
|||||||
auth_token='test_token',
|
auth_token='test_token',
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
with patch.object(
|
with patch.object(
|
||||||
SientiaMonitoring,
|
SientiaMonitoring,
|
||||||
@@ -104,7 +105,7 @@ def test_get_pi_web_api_core_labels_with_operation_type(mock_pi_web_api_client):
|
|||||||
auth_token='test_token',
|
auth_token='test_token',
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
with patch.object(
|
with patch.object(
|
||||||
SientiaMonitoring,
|
SientiaMonitoring,
|
||||||
@@ -131,7 +132,7 @@ def test__init__():
|
|||||||
auth_token='test_token',
|
auth_token='test_token',
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert api.pi_web_api_client is not None
|
assert api.pi_web_api_client is not None
|
||||||
@@ -152,7 +153,7 @@ def api(mock_pi_web_api_client):
|
|||||||
auth_token='test_token',
|
auth_token='test_token',
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
api_instance.send_notification = MagicMock()
|
api_instance.send_notification = MagicMock()
|
||||||
api_instance.info = MagicMock()
|
api_instance.info = MagicMock()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from unittest.mock import ANY, MagicMock, call, patch
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
from pytest import fixture
|
from pytest import fixture
|
||||||
from sientia_do.notifications.models import NotificationLevel
|
from sientia_do.notifications.models import NotificationLevel
|
||||||
|
from sientia_do.observability.metrics_controller import MetricsController
|
||||||
from sientia_do.observability.sientia_monitoring import SientiaMonitoring
|
from sientia_do.observability.sientia_monitoring import SientiaMonitoring
|
||||||
|
|
||||||
from laborious.activities.gates import Gates
|
from laborious.activities.gates import Gates
|
||||||
@@ -38,7 +39,7 @@ def gates_activity():
|
|||||||
gates = Gates(
|
gates = Gates(
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
gates.error = MagicMock()
|
gates.error = MagicMock()
|
||||||
gates.debug = MagicMock()
|
gates.debug = MagicMock()
|
||||||
@@ -985,7 +986,7 @@ def test_close_disposes_minio_repository(mock_shutdown):
|
|||||||
minio_repository=minio,
|
minio_repository=minio,
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
gates.close()
|
gates.close()
|
||||||
minio.close.assert_called_once()
|
minio.close.assert_called_once()
|
||||||
@@ -1000,7 +1001,7 @@ def test_close_without_minio_repository(mock_shutdown):
|
|||||||
minio_repository=None,
|
minio_repository=None,
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
gates.close()
|
gates.close()
|
||||||
mock_shutdown.assert_called_once_with(gates)
|
mock_shutdown.assert_called_once_with(gates)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import numpy as np
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
from pytest import fixture, raises
|
from pytest import fixture, raises
|
||||||
from sientia_do.notifications.models import NotificationLevel
|
from sientia_do.notifications.models import NotificationLevel
|
||||||
|
from sientia_do.observability.metrics_controller import MetricsController
|
||||||
from sientia_do.temporal.constants import DATETIME_FORMAT_WITH_TZ
|
from sientia_do.temporal.constants import DATETIME_FORMAT_WITH_TZ
|
||||||
|
|
||||||
from laborious.activities.mlflow import MLFlow
|
from laborious.activities.mlflow import MLFlow
|
||||||
@@ -22,7 +23,7 @@ def _passthrough_from_dict():
|
|||||||
def test___init__(mock_minio_repository):
|
def test___init__(mock_minio_repository):
|
||||||
logger = MagicMock()
|
logger = MagicMock()
|
||||||
notification_handler = MagicMock()
|
notification_handler = MagicMock()
|
||||||
metrics_controller = MagicMock()
|
metrics_controller = MagicMock(spec=MetricsController)
|
||||||
mlflow_repo = MagicMock()
|
mlflow_repo = MagicMock()
|
||||||
plugin_store = MagicMock()
|
plugin_store = MagicMock()
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ def test___init__(mock_minio_repository):
|
|||||||
def mlflow(mock_minio_repository):
|
def mlflow(mock_minio_repository):
|
||||||
logger = MagicMock()
|
logger = MagicMock()
|
||||||
notification_handler = MagicMock()
|
notification_handler = MagicMock()
|
||||||
metrics_controller = MagicMock()
|
metrics_controller = MagicMock(spec=MetricsController)
|
||||||
mlflow_repo = MagicMock()
|
mlflow_repo = MagicMock()
|
||||||
plugin_store = MagicMock()
|
plugin_store = MagicMock()
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from unittest.mock import ANY, MagicMock, patch
|
|||||||
from pandas import DataFrame, Timestamp
|
from pandas import DataFrame, Timestamp
|
||||||
from pytest import fixture, raises
|
from pytest import fixture, raises
|
||||||
from sientia_do.notifications.models import NotificationLevel
|
from sientia_do.notifications.models import NotificationLevel
|
||||||
|
from sientia_do.observability.metrics_controller import MetricsController
|
||||||
from sientia_do.temporal.constants import DATETIME_FORMAT_WITH_TZ
|
from sientia_do.temporal.constants import DATETIME_FORMAT_WITH_TZ
|
||||||
from sientia_model.analytics.drift_analysis import DriftInsufficientDataError
|
from sientia_model.analytics.drift_analysis import DriftInsufficientDataError
|
||||||
|
|
||||||
@@ -14,7 +15,7 @@ def model_metrics_activity():
|
|||||||
model_metrics = ModelMetrics(
|
model_metrics = ModelMetrics(
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
model_metrics.error = MagicMock()
|
model_metrics.error = MagicMock()
|
||||||
model_metrics.debug = MagicMock()
|
model_metrics.debug = MagicMock()
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import pytest
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
from pytest import mark
|
from pytest import mark
|
||||||
from sientia_do.notifications.models import NotificationLevel
|
from sientia_do.notifications.models import NotificationLevel
|
||||||
|
from sientia_do.observability.metrics_controller import MetricsController
|
||||||
|
|
||||||
from laborious.activities.opc import (
|
from laborious.activities.opc import (
|
||||||
OPC,
|
OPC,
|
||||||
@@ -32,7 +33,7 @@ def test__init__():
|
|||||||
opc_servers=servers,
|
opc_servers=servers,
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert opc.opc_servers == servers
|
assert opc.opc_servers == servers
|
||||||
@@ -43,7 +44,7 @@ def test__init__():
|
|||||||
@patch('laborious.activities.opc.OPC.send_notification')
|
@patch('laborious.activities.opc.OPC.send_notification')
|
||||||
def test_init_opc(mock_send_notification, mock_opc_repository):
|
def test_init_opc(mock_send_notification, mock_opc_repository):
|
||||||
mock_logger = MagicMock()
|
mock_logger = MagicMock()
|
||||||
mock_metrics_controller = MagicMock()
|
mock_metrics_controller = MagicMock(spec=MetricsController)
|
||||||
server1 = MagicMock(
|
server1 = MagicMock(
|
||||||
connect=MagicMock(return_value=(True, {})), write_data=MagicMock(return_value=(True, {}))
|
connect=MagicMock(return_value=(True, {})), write_data=MagicMock(return_value=(True, {}))
|
||||||
)
|
)
|
||||||
@@ -192,7 +193,7 @@ def opc(mock_opc_repository):
|
|||||||
opc_servers=servers,
|
opc_servers=servers,
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
opc.init_opc()
|
opc.init_opc()
|
||||||
opc.send_notification = MagicMock()
|
opc.send_notification = MagicMock()
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from unittest.mock import ANY, MagicMock, patch
|
|||||||
|
|
||||||
from pytest import fixture, raises
|
from pytest import fixture, raises
|
||||||
from sientia_do.notifications.models import NotificationLevel
|
from sientia_do.notifications.models import NotificationLevel
|
||||||
|
from sientia_do.observability.metrics_controller import MetricsController
|
||||||
from sientia_do.observability.sientia_monitoring import SientiaMonitoring
|
from sientia_do.observability.sientia_monitoring import SientiaMonitoring
|
||||||
from sientia_do.temporal.activities.postgres_sync import Postgres
|
from sientia_do.temporal.activities.postgres_sync import Postgres
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ def storage(mock_minio_repository):
|
|||||||
minio_repository=mock_minio_repository.return_value,
|
minio_repository=mock_minio_repository.return_value,
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ def storage(mock_minio_repository):
|
|||||||
def test___init___not_hasattr(mock_minio_repository):
|
def test___init___not_hasattr(mock_minio_repository):
|
||||||
logger = MagicMock()
|
logger = MagicMock()
|
||||||
notification_handler = MagicMock()
|
notification_handler = MagicMock()
|
||||||
metrics_controller = MagicMock()
|
metrics_controller = MagicMock(spec=MetricsController)
|
||||||
minio_repo = mock_minio_repository.return_value
|
minio_repo = mock_minio_repository.return_value
|
||||||
storage = Storage(
|
storage = Storage(
|
||||||
host='localhost',
|
host='localhost',
|
||||||
@@ -87,7 +88,7 @@ def test___init___none_minio_repository(mock_minio_repository, storage):
|
|||||||
storage.minio_repository = None
|
storage.minio_repository = None
|
||||||
logger = MagicMock()
|
logger = MagicMock()
|
||||||
notification_handler = MagicMock()
|
notification_handler = MagicMock()
|
||||||
metrics_controller = MagicMock()
|
metrics_controller = MagicMock(spec=MetricsController)
|
||||||
storage.__init__(
|
storage.__init__(
|
||||||
host='localhost',
|
host='localhost',
|
||||||
port=5432,
|
port=5432,
|
||||||
@@ -121,7 +122,7 @@ def test___init___done_repository(mock_minio_repository, storage):
|
|||||||
minio_repository=mock_minio_repository.return_value,
|
minio_repository=mock_minio_repository.return_value,
|
||||||
logger=MagicMock(),
|
logger=MagicMock(),
|
||||||
notification_handler=MagicMock(),
|
notification_handler=MagicMock(),
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
mock_minio_repository.assert_not_called()
|
mock_minio_repository.assert_not_called()
|
||||||
assert storage.minio_repository is not None
|
assert storage.minio_repository is not None
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import pytest
|
|||||||
from asyncua.crypto import security_policies
|
from asyncua.crypto import security_policies
|
||||||
from asyncua.ua.uaerrors import BadNodeIdUnknown, BadSessionIdInvalid
|
from asyncua.ua.uaerrors import BadNodeIdUnknown, BadSessionIdInvalid
|
||||||
from sientia_do.notifications.models import NotificationLevel
|
from sientia_do.notifications.models import NotificationLevel
|
||||||
|
from sientia_do.observability.metrics_controller import MetricsController
|
||||||
|
|
||||||
from laborious import metrics
|
from laborious import metrics
|
||||||
from laborious.utils.repository.opc_repository import (
|
from laborious.utils.repository.opc_repository import (
|
||||||
@@ -39,7 +40,7 @@ def opc_repository(mock_logger):
|
|||||||
cert_path='/path/to/cert.pem',
|
cert_path='/path/to/cert.pem',
|
||||||
private_key_path='/path/to/key.pem',
|
private_key_path='/path/to/key.pem',
|
||||||
server_cert_path='/path/to/server_cert.pem',
|
server_cert_path='/path/to/server_cert.pem',
|
||||||
metrics_controller=MagicMock(),
|
metrics_controller=MagicMock(spec=MetricsController),
|
||||||
)
|
)
|
||||||
repository.disconnection_interval = 0.1
|
repository.disconnection_interval = 0.1
|
||||||
repository.send_notification = MagicMock()
|
repository.send_notification = MagicMock()
|
||||||
|
|||||||
Reference in New Issue
Block a user