mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-09-14 18:56:52 +00:00
107 lines
3.8 KiB
Python
107 lines
3.8 KiB
Python
import sys
|
|||
|
|
import unittest
|
||
|
|
from pathlib import Path
|
||
|
|
from queue import Queue
|
||
|
|
from unittest import mock
|
||
|
|
|
||
|
|
|
||
|
|
SCRIPTS_DIR = Path(__file__).resolve().parents[1]
|
||
|
|
if str(SCRIPTS_DIR) not in sys.path:
|
||
|
|
sys.path.insert(0, str(SCRIPTS_DIR))
|
||
|
|
|
||
|
|
import notification_events # noqa: E402
|
||
|
|
import notification_templates # noqa: E402
|
||
|
|
|
||
|
|
|
||
|
|
class ReplicationWebhookTests(unittest.TestCase):
|
||
|
|
def _process(self, payload, guest_name='fileserver'):
|
||
|
|
watcher = notification_events.ProxmoxHookWatcher(Queue())
|
||
|
|
with mock.patch.object(
|
||
|
|
watcher,
|
||
|
|
'_resolve_replication_guest_name',
|
||
|
|
return_value=guest_name,
|
||
|
|
), mock.patch.object(
|
||
|
|
notification_events,
|
||
|
|
'capture_journal_context',
|
||
|
|
return_value='',
|
||
|
|
):
|
||
|
|
result = watcher.process_webhook(payload)
|
||
|
|
return result, watcher._queue.get_nowait()
|
||
|
|
|
||
|
|
def test_structured_job_id_populates_template_fields(self):
|
||
|
|
reason = 'command zfs error: cannot open pool\nremote side unavailable'
|
||
|
|
result, event = self._process({
|
||
|
|
'title': "Replication Job: '100-0' failed",
|
||
|
|
'message': (
|
||
|
|
"Replication job '100-0' with target 'pve02' and schedule "
|
||
|
|
"'*/15' failed!\n\n"
|
||
|
|
"Last successful sync: 2026-09-02 15:00:00\n"
|
||
|
|
"Next sync try: 2026-09-02 15:30:00\n"
|
||
|
|
"Failure count: 1\n\n"
|
||
|
|
f"Error:\n{reason}"
|
||
|
|
),
|
||
|
|
'severity': 'error',
|
||
|
|
'fields': {
|
||
|
|
'type': 'replication',
|
||
|
|
'hostname': 'pve01',
|
||
|
|
'job-id': '100-0',
|
||
|
|
},
|
||
|
|
})
|
||
|
|
|
||
|
|
self.assertTrue(result['accepted'])
|
||
|
|
self.assertEqual(event.event_type, 'replication_fail')
|
||
|
|
self.assertEqual(event.entity_id, '100-0')
|
||
|
|
self.assertEqual(event.data['job_id'], '100-0')
|
||
|
|
self.assertEqual(event.data['vmid'], '100')
|
||
|
|
self.assertEqual(event.data['vmname'], 'fileserver')
|
||
|
|
self.assertEqual(event.data['target_node'], 'pve02')
|
||
|
|
self.assertEqual(event.data['reason'], reason)
|
||
|
|
|
||
|
|
rendered = notification_templates.render_template(
|
||
|
|
event.event_type,
|
||
|
|
event.data,
|
||
|
|
)
|
||
|
|
self.assertIn('fileserver (100)', rendered['title'])
|
||
|
|
self.assertIn('ID: 100', rendered['body_text'])
|
||
|
|
self.assertIn(reason, rendered['body_text'])
|
||
|
|
|
||
|
|
def test_title_and_message_are_used_when_job_id_field_is_missing(self):
|
||
|
|
_, event = self._process({
|
||
|
|
'title': "Replication Job: '212-3' failed",
|
||
|
|
'message': (
|
||
|
|
"Replication job '212-3' with target 'pve03' failed!\n\n"
|
||
|
|
"Error: storage 'replica-zfs' is not available"
|
||
|
|
),
|
||
|
|
'severity': 'error',
|
||
|
|
'fields': {'type': 'replication', 'hostname': 'pve01'},
|
||
|
|
}, guest_name='')
|
||
|
|
|
||
|
|
self.assertEqual(event.entity_id, '212-3')
|
||
|
|
self.assertEqual(event.data['vmid'], '212')
|
||
|
|
self.assertEqual(event.data['vmname'], 'VM/CT')
|
||
|
|
self.assertEqual(event.data['target_node'], 'pve03')
|
||
|
|
self.assertEqual(
|
||
|
|
event.data['reason'],
|
||
|
|
"storage 'replica-zfs' is not available",
|
||
|
|
)
|
||
|
|
|
||
|
|
def test_missing_error_block_never_renders_an_empty_reason(self):
|
||
|
|
message = "Replication job '300-0' failed unexpectedly"
|
||
|
|
_, event = self._process({
|
||
|
|
'title': "Replication Job: '300-0' failed",
|
||
|
|
'message': message,
|
||
|
|
'severity': 'error',
|
||
|
|
'fields': {'type': 'replication', 'hostname': 'pve01'},
|
||
|
|
})
|
||
|
|
|
||
|
|
self.assertEqual(event.data['reason'], message)
|
||
|
|
rendered = notification_templates.render_template(
|
||
|
|
event.event_type,
|
||
|
|
event.data,
|
||
|
|
)
|
||
|
|
self.assertIn(f'Reason: {message}', rendered['body_text'])
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
unittest.main()
|