Files

88 lines
3.7 KiB
Python
Raw Permalink Normal View History

import unittest
from typing import Any
from netscaler_triage.parsing import parse_record
class ParsingTests(unittest.TestCase):
def test_native_correlation_fields(self) -> None:
row = self.parse(
'Sep 28 09:10:11 host bash[1]: return_code="0" trans id 12345 Context [email protected]'
)
self.assertEqual(row["fields"]["return_code"], "0")
self.assertEqual(row["fields"]["transaction_id"], "12345")
self.assertEqual(row["fields"]["context"], "[email protected]")
row = self.parse('Sep 28 09:10:11 host CMD_EXECUTED 12 - Status "Success"')
self.assertEqual(row["fields"]["command_status"], "Success")
def test_attacker_username_is_not_update(self) -> None:
row = self.parse('Sep 28 09:10:11 host aaad[42]: User "installns upgrade rebooting" failed')
self.assertEqual(row["categories"], [])
def test_proxy_source(self) -> None:
row = self.parse(
'192.0.2.40 -> 198.51.100.10 - - [01/Oct/2026:12:02:28 +0000] "GET / HTTP/1.1" 200 5'
)
self.assertEqual(row["fields"]["dest"], "198.51.100.10")
def parse(self, raw: str, **kwargs: Any) -> dict[str, Any]:
return parse_record({"raw": raw}, **kwargs)
def test_access_payload_not_update(self) -> None:
row = self.parse(
'192.0.2.40 - - [01/Oct/2026:12:02:28 +0200] [23] "GET '
'/installns?date=2020-01-01T00:00:00Z HTTP/1.1" 404 23 "-" "x"'
)
self.assertEqual(row["timestamp"], "2026-10-01T10:02:28Z")
self.assertEqual(row["fields"]["uri"], "/installns?date=2020-01-01T00:00:00Z")
self.assertEqual(row["categories"], [])
def test_missing_year_and_gmt(self) -> None:
row = self.parse(
"Sep 30 16:00:54 <local0.warn> 198.51.100.10 09/30/2026:14:00:54 GMT ns "
"0-PPE-0 : message"
)
self.assertEqual(row["timestamp"], "2026-09-30T14:00:54Z")
self.assertIsNone(self.parse("Sep 30 16:00:54 host bash[1]: installns")["timestamp"])
row = self.parse(
"Sep 30 16:00:54 host bash[1]: installns", year=2026, timezone="Europe/Berlin"
)
self.assertEqual(row["timestamp"], "2026-09-30T14:00:54Z")
self.assertEqual(row["fields"]["update_evidence"], "installer_invocation")
def test_historical_explicit_year(self) -> None:
row = self.parse(
"COLLECTOR::INFOA::Sun Sep 28 09:11:12 2025:Successfully loaded "
"configuration(NS13.1-60.20)",
year=2026,
timezone="UTC",
)
self.assertEqual(row["timestamp"], "2025-09-28T09:11:12Z")
self.assertEqual(row["fields"]["versions"], ["13.1-60.20"])
self.assertIn("version", row["categories"])
def test_dst_ambiguity(self) -> None:
self.assertIsNone(
self.parse("2026-10-25 02:30:00 message", timezone="Europe/Berlin")["timestamp"]
)
self.assertIsNone(
self.parse("2026-03-29 02:30:00 message", timezone="Europe/Berlin")["timestamp"]
)
def test_nssetup_version_transition(self) -> None:
row = self.parse(
"Sep 28 09:10:11 host nssetup[386]: ns_conf_check(): This is an upgrade "
"from NetScaler NS13.1 build 50.10 to build 60.20",
year=2026,
timezone="UTC",
)
self.assertEqual(row["fields"]["builds"], ["50.10", "60.20"])
self.assertEqual(row["fields"]["update_relation"], "explicit_upgrade_from_to")
row = self.parse(
"Sep 28 09:10:11 host nssetup[386]: This is NetScaler version NS13.1, build 60.20"
)
self.assertEqual(row["fields"]["versions"], ["13.1-60.20"])
if __name__ == "__main__":
unittest.main()