Source: main (252c1cf) Excluded: live tenant exports, generated artifacts, and dev-only tooling.
158 lines
6.1 KiB
Python
158 lines
6.1 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
|
|
SCRIPT_PATH = Path(__file__).resolve().parents[1] / "scripts" / "validate_backup_outputs.py"
|
|
|
|
|
|
def run_validator(*args: str) -> subprocess.CompletedProcess[str]:
|
|
cmd = [sys.executable, str(SCRIPT_PATH), *args]
|
|
return subprocess.run(cmd, check=False, text=True, capture_output=True)
|
|
|
|
|
|
class ValidateBackupOutputsTests(unittest.TestCase):
|
|
def test_intune_validation_passes_with_required_outputs(self) -> None:
|
|
with tempfile.TemporaryDirectory() as td:
|
|
base = Path(td)
|
|
root = base / "tenant-state" / "intune"
|
|
reports = base / "tenant-state" / "reports" / "intune"
|
|
(root / "Device Configurations").mkdir(parents=True, exist_ok=True)
|
|
reports.mkdir(parents=True, exist_ok=True)
|
|
|
|
(root / "Device Configurations" / "policy__id.json").write_text(
|
|
json.dumps({"id": "id-1", "displayName": "Policy"}) + "\n",
|
|
encoding="utf-8",
|
|
)
|
|
(reports / "policy-assignments.md").write_text("# report\n", encoding="utf-8")
|
|
(reports / "policy-assignments.csv").write_text("a,b\n", encoding="utf-8")
|
|
(reports / "object-inventory-all.csv").write_text("a,b\n", encoding="utf-8")
|
|
|
|
result = run_validator(
|
|
"--workload",
|
|
"intune",
|
|
"--mode",
|
|
"light",
|
|
"--root",
|
|
str(root),
|
|
"--reports-root",
|
|
str(reports),
|
|
)
|
|
self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr)
|
|
|
|
def test_intune_validation_fails_when_assignment_csv_missing(self) -> None:
|
|
with tempfile.TemporaryDirectory() as td:
|
|
base = Path(td)
|
|
root = base / "tenant-state" / "intune"
|
|
reports = base / "tenant-state" / "reports" / "intune"
|
|
(root / "Device Configurations").mkdir(parents=True, exist_ok=True)
|
|
reports.mkdir(parents=True, exist_ok=True)
|
|
|
|
(root / "Device Configurations" / "policy__id.json").write_text("{}", encoding="utf-8")
|
|
(reports / "policy-assignments.md").write_text("# report\n", encoding="utf-8")
|
|
(reports / "object-inventory-all.csv").write_text("a,b\n", encoding="utf-8")
|
|
|
|
result = run_validator(
|
|
"--workload",
|
|
"intune",
|
|
"--mode",
|
|
"full",
|
|
"--root",
|
|
str(root),
|
|
"--reports-root",
|
|
str(reports),
|
|
)
|
|
self.assertNotEqual(result.returncode, 0)
|
|
self.assertIn("Missing Intune assignment CSV report", result.stdout)
|
|
|
|
def test_entra_light_validation_allows_non_effective_enterprise_apps(self) -> None:
|
|
with tempfile.TemporaryDirectory() as td:
|
|
base = Path(td)
|
|
root = base / "tenant-state" / "entra"
|
|
reports = base / "tenant-state" / "reports" / "entra"
|
|
(root / "Named Locations").mkdir(parents=True, exist_ok=True)
|
|
reports.mkdir(parents=True, exist_ok=True)
|
|
|
|
(root / "Named Locations" / "Named Locations.md").write_text("# named\n", encoding="utf-8")
|
|
(reports / "object-inventory-all.csv").write_text("a,b\n", encoding="utf-8")
|
|
|
|
result = run_validator(
|
|
"--workload",
|
|
"entra",
|
|
"--mode",
|
|
"light",
|
|
"--root",
|
|
str(root),
|
|
"--reports-root",
|
|
str(reports),
|
|
"--include-named-locations",
|
|
"true",
|
|
"--include-enterprise-applications",
|
|
"true",
|
|
"--include-enterprise-applications-effective",
|
|
"false",
|
|
)
|
|
self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr)
|
|
|
|
def test_entra_light_validation_allows_non_effective_app_registrations(self) -> None:
|
|
with tempfile.TemporaryDirectory() as td:
|
|
base = Path(td)
|
|
root = base / "tenant-state" / "entra"
|
|
reports = base / "tenant-state" / "reports" / "entra"
|
|
(root / "Named Locations").mkdir(parents=True, exist_ok=True)
|
|
reports.mkdir(parents=True, exist_ok=True)
|
|
|
|
(root / "Named Locations" / "Named Locations.md").write_text("# named\n", encoding="utf-8")
|
|
(reports / "object-inventory-all.csv").write_text("a,b\n", encoding="utf-8")
|
|
|
|
result = run_validator(
|
|
"--workload",
|
|
"entra",
|
|
"--mode",
|
|
"light",
|
|
"--root",
|
|
str(root),
|
|
"--reports-root",
|
|
str(reports),
|
|
"--include-named-locations",
|
|
"true",
|
|
"--include-app-registrations",
|
|
"true",
|
|
"--include-app-registrations-effective",
|
|
"false",
|
|
)
|
|
self.assertEqual(result.returncode, 0, msg=result.stdout + result.stderr)
|
|
|
|
def test_entra_validation_fails_when_required_index_missing(self) -> None:
|
|
with tempfile.TemporaryDirectory() as td:
|
|
base = Path(td)
|
|
root = base / "tenant-state" / "entra"
|
|
reports = base / "tenant-state" / "reports" / "entra"
|
|
root.mkdir(parents=True, exist_ok=True)
|
|
reports.mkdir(parents=True, exist_ok=True)
|
|
(reports / "object-inventory-all.csv").write_text("a,b\n", encoding="utf-8")
|
|
|
|
result = run_validator(
|
|
"--workload",
|
|
"entra",
|
|
"--mode",
|
|
"full",
|
|
"--root",
|
|
str(root),
|
|
"--reports-root",
|
|
str(reports),
|
|
"--include-named-locations",
|
|
"true",
|
|
)
|
|
self.assertNotEqual(result.returncode, 0)
|
|
self.assertIn("Missing Entra export index for 'Named Locations'", result.stdout)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|