"""Unit tests for log parser."""
import unittest
from datetime import datetime
from attendance_app.log_parser import parse_log_line, get_log_files
import tempfile
import os
class TestParseLogLine(unittest.TestCase):
"""Test parse_log_line function."""
def test_valid_logon_entry(self):
"""Test parsing a valid logon entry."""
line = '172.29.11.116.151 - - [27/Nov/2024:14:30:15 +0900] "GET /logonoff?on:user123 HTTP/1.1" 200 -'
result = parse_log_line(line)
self.assertIsNotNone(result)
host, date, action = result
self.assertEqual(host, "GRL-01")
self.assertEqual(date, datetime(2024, 11, 27, 14, 30, 15))
self.assertEqual(action, "on:user123")
def test_valid_logoff_entry(self):
"""Test parsing a valid logoff entry."""
line = '172.29.11.117.152 - - [27/Nov/2024:17:00:30 +0900] "GET /logonoff?off:user456 HTTP/1.1" 200 -'
result = parse_log_line(line)
self.assertIsNotNone(result)
host, date, action = result
self.assertEqual(host, "ML1-02")
self.assertEqual(action, "off:user456")
def test_reject_entry(self):
"""Test parsing a reject entry."""
line = '172.29.11.118.151 - - [27/Nov/2024:15:00:00 +0900] "GET /logonoff?reject:user789:ML2-01 HTTP/1.1" 200 -'
result = parse_log_line(line)
self.assertIsNotNone(result)
host, date, action = result
self.assertEqual(action, "reject:user789:ML2-01")
def test_startup_shutdown(self):
"""Test parsing startup/shutdown entries."""
line1 = '172.29.11.119.151 - - [27/Nov/2024:09:00:00 +0900] "GET /logonoff?startup HTTP/1.1" 200 -'
result1 = parse_log_line(line1)
self.assertIsNotNone(result1)
self.assertEqual(result1[2], "startup")
line2 = '172.29.11.119.151 - - [27/Nov/2024:19:00:00 +0900] "GET /logonoff?shutdown HTTP/1.1" 200 -'
result2 = parse_log_line(line2)
self.assertIsNotNone(result2)
self.assertEqual(result2[2], "shutdown")
def test_non_logonoff_entry(self):
"""Test that non-logonoff entries return None."""
line = '172.29.11.116.151 - - [27/Nov/2024:14:30:15 +0900] "GET /index.html HTTP/1.1" 200 -'
result = parse_log_line(line)
self.assertIsNone(result)
def test_invalid_format(self):
"""Test invalid log format."""
line = "invalid log line"
result = parse_log_line(line)
self.assertIsNone(result)
def test_malformed_date(self):
"""Test malformed date in log entry."""
line = '172.29.11.116.151 - - [invalid/date] "GET /logonoff?on:user123 HTTP/1.1" 200 -'
result = parse_log_line(line)
self.assertIsNone(result)
class TestGetLogFiles(unittest.TestCase):
"""Test get_log_files function."""
def setUp(self):
"""Create temporary directory with test log files."""
self.temp_dir = tempfile.mkdtemp()
# Create test log files
self.log_files = [
"access_log",
"access_log-20241120",
"access_log-20241125",
"access_log-20241127",
"access_log-20241130",
"access_log-20241205",
"other_file.txt"
]
for filename in self.log_files:
open(os.path.join(self.temp_dir, filename), 'w').close()
def tearDown(self):
"""Clean up temporary directory."""
for filename in self.log_files:
try:
os.remove(os.path.join(self.temp_dir, filename))
except:
pass
os.rmdir(self.temp_dir)
def test_get_log_files_in_range(self):
"""Test getting log files within date range."""
start_date = datetime(2024, 11, 27)
result = get_log_files(self.temp_dir, start_date)
# Should get files from 1127 to 1204 (7 days after)
self.assertIn("access_log-20241127", result)
self.assertIn("access_log-20241130", result)
self.assertNotIn("access_log-20241125", result)
self.assertNotIn("access_log-20241205", result)
self.assertNotIn("other_file.txt", result)
def test_fallback_to_access_log(self):
"""Test fallback to access_log when no dated files match."""
start_date = datetime(2024, 10, 1)
result = get_log_files(self.temp_dir, start_date)
self.assertIn("access_log", result)
if __name__ == '__main__':
unittest.main()