101 lines
3.3 KiB
Python
101 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Tests for RCA generator module."""
|
|
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
from tools.rca_generator import RCAGenerator
|
|
|
|
|
|
class TestRCAGenerator(unittest.TestCase):
|
|
"""Test RCA generation."""
|
|
|
|
def setUp(self):
|
|
self.tmp_dir = tempfile.mkdtemp()
|
|
self.gen = RCAGenerator(rca_dir=self.tmp_dir)
|
|
|
|
def tearDown(self):
|
|
import shutil
|
|
shutil.rmtree(self.tmp_dir, ignore_errors=True)
|
|
|
|
def test_generate_basic(self):
|
|
content, path = self.gen.generate(title="Test Failure")
|
|
self.assertTrue(path.exists())
|
|
self.assertIn("Test Failure", content)
|
|
self.assertIn("RCA-1", content)
|
|
|
|
def test_generate_with_all_fields(self):
|
|
content, path = self.gen.generate(
|
|
title="Token Expired",
|
|
severity="P1",
|
|
duration="2 hours",
|
|
affected="Gitea integration",
|
|
root_cause="Token rotation not automated",
|
|
impact="All API writes failed",
|
|
resolution="Manual token refresh",
|
|
timeline=[
|
|
{"time": "10:00", "event": "First 401 detected"},
|
|
{"time": "12:00", "event": "Token refreshed"},
|
|
],
|
|
five_whys=[
|
|
"API returned 401",
|
|
"Token was expired",
|
|
"No auto-refresh",
|
|
],
|
|
action_items=[
|
|
{"priority": "P1", "action": "Implement auto-refresh", "owner": "Ezra"},
|
|
],
|
|
lessons=["Always automate token rotation"],
|
|
prevention=["Add token expiry monitoring"],
|
|
status="Resolved",
|
|
)
|
|
self.assertIn("P1", content)
|
|
self.assertIn("Token Expired", content)
|
|
self.assertIn("2 hours", content)
|
|
self.assertIn("401", content)
|
|
self.assertIn("Resolved", content)
|
|
|
|
def test_number_auto_increment(self):
|
|
_, path1 = self.gen.generate(title="First")
|
|
_, path2 = self.gen.generate(title="Second")
|
|
self.assertIn("RCA-1", path1.name)
|
|
self.assertIn("RCA-2", path2.name)
|
|
|
|
def test_explicit_number(self):
|
|
_, path = self.gen.generate(title="Custom", number=99)
|
|
self.assertIn("RCA-99", path.name)
|
|
|
|
def test_severity_levels(self):
|
|
for sev in ["P0", "P1", "P2", "P3"]:
|
|
content, _ = self.gen.generate(title=f"Test {sev}", severity=sev, number=100 + int(sev[1]))
|
|
self.assertIn(sev, content)
|
|
|
|
def test_list_rcas(self):
|
|
self.gen.generate(title="First Issue")
|
|
self.gen.generate(title="Second Issue")
|
|
rcas = self.gen.list_rcas()
|
|
self.assertEqual(len(rcas), 2)
|
|
self.assertTrue(all("file" in r for r in rcas))
|
|
|
|
def test_list_rcas_empty(self):
|
|
rcas = self.gen.list_rcas()
|
|
self.assertEqual(len(rcas), 0)
|
|
|
|
def test_filename_sanitization(self):
|
|
_, path = self.gen.generate(title="Bad/Title With Spaces & Symbols!")
|
|
# Should be safe filename
|
|
self.assertNotIn("/", path.stem.split("-", 2)[-1])
|
|
|
|
def test_defaults(self):
|
|
content, _ = self.gen.generate(title="Minimal")
|
|
self.assertIn("Under investigation", content)
|
|
self.assertIn("TBD", content)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|