test_config_log_file_dir.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. # coding=utf-8
  2. # type: ignore[index,operator,assignment]
  3. """
  4. Unit tests for log file directory creation issue
  5. Reproduces the issue where log_file path has non-existent parent directories
  6. @author: GitHub Copilot
  7. """
  8. from __init__ import unittest
  9. import tempfile
  10. import json
  11. import os
  12. import sys
  13. import shutil
  14. from ddns.config import load_configs
  15. class TestLogFileDirectory(unittest.TestCase):
  16. """测试日志文件目录创建问题"""
  17. def setUp(self):
  18. self.temp_dir = tempfile.mkdtemp()
  19. self.original_argv = sys.argv[:]
  20. def tearDown(self):
  21. sys.argv = self.original_argv
  22. # Clean up logging handlers
  23. import logging
  24. for handler in logging.root.handlers[:]:
  25. logging.root.removeHandler(handler)
  26. # Clean up temp directory
  27. shutil.rmtree(self.temp_dir, ignore_errors=True)
  28. def test_log_file_with_nonexistent_directory_single_config(self):
  29. """测试单个配置时,log文件所在目录不存在的情况"""
  30. # 创建一个不存在的目录路径
  31. log_dir = os.path.join(self.temp_dir, "nonexistent", "subdir")
  32. log_file = os.path.join(log_dir, "ddns.log")
  33. # 确保目录不存在
  34. self.assertFalse(os.path.exists(log_dir))
  35. config_data = {
  36. "dns": "debug",
  37. "id": "[email protected]",
  38. "token": "secret123",
  39. "ipv4": ["test.example.com"],
  40. "log": {"file": log_file, "level": "INFO"},
  41. }
  42. config_path = os.path.join(self.temp_dir, "config.json")
  43. with open(config_path, "w") as f:
  44. json.dump(config_data, f)
  45. sys.argv = ["ddns", "-c", config_path]
  46. # 加载配置,应该自动创建目录
  47. configs = load_configs("test", "1.0", "2023-01-01")
  48. # 验证目录被创建
  49. self.assertTrue(os.path.exists(log_dir), "Log directory should be created")
  50. self.assertEqual(len(configs), 1)
  51. self.assertEqual(configs[0].log_file, log_file)
  52. def test_log_file_with_nonexistent_directory_multi_provider(self):
  53. """测试多个provider配置时,log文件所在目录不存在的情况(复现issue中的问题)"""
  54. # 创建一个不存在的目录路径
  55. log_dir = os.path.join(self.temp_dir, "ddns")
  56. log_file = os.path.join(log_dir, "ddns.log")
  57. # 确保目录不存在
  58. self.assertFalse(os.path.exists(log_dir))
  59. # 模拟issue中的配置:多个provider,共享同一个log文件
  60. config_data = {
  61. "$schema": "https://ddns.newfuture.cc/schema/v4.1.json",
  62. "ssl": "auto",
  63. "cache": os.path.join(self.temp_dir, "cache"),
  64. "log": {"level": "INFO", "file": log_file},
  65. "index4": "default",
  66. "index6": "default",
  67. "providers": [
  68. {"provider": "debug", "token": "token1", "ipv6": ["test1.xyz"]},
  69. {"provider": "debug", "token": "token2", "ipv6": ["test2.org"]},
  70. ],
  71. }
  72. config_path = os.path.join(self.temp_dir, "multi_config.json")
  73. with open(config_path, "w") as f:
  74. json.dump(config_data, f)
  75. sys.argv = ["ddns", "-c", config_path]
  76. # 加载配置,应该自动创建目录
  77. configs = load_configs("test", "1.0", "2023-01-01")
  78. # 验证目录被创建
  79. self.assertTrue(os.path.exists(log_dir), "Log directory should be created")
  80. self.assertEqual(len(configs), 2)
  81. # 验证两个配置都使用同一个log文件
  82. for config in configs:
  83. self.assertEqual(config.log_file, log_file)
  84. def test_log_file_with_nested_nonexistent_directory(self):
  85. """测试log文件路径有多级不存在的目录"""
  86. # 创建多级不存在的目录路径
  87. log_file = os.path.join(self.temp_dir, "a", "b", "c", "d", "ddns.log")
  88. config_data = {"dns": "debug", "id": "[email protected]", "token": "secret123", "log": {"file": log_file}}
  89. config_path = os.path.join(self.temp_dir, "config.json")
  90. with open(config_path, "w") as f:
  91. json.dump(config_data, f)
  92. sys.argv = ["ddns", "-c", config_path]
  93. # 加载配置,应该自动创建所有父目录
  94. configs = load_configs("test", "1.0", "2023-01-01")
  95. # 验证所有父目录被创建
  96. self.assertTrue(os.path.exists(os.path.dirname(log_file)), "All parent directories should be created")
  97. self.assertEqual(configs[0].log_file, log_file)
  98. def test_log_file_with_existing_directory(self):
  99. """测试log文件所在目录已存在的情况(不应该出错)"""
  100. # 创建目录
  101. log_dir = os.path.join(self.temp_dir, "existing_dir")
  102. os.makedirs(log_dir)
  103. log_file = os.path.join(log_dir, "ddns.log")
  104. config_data = {"dns": "debug", "id": "[email protected]", "token": "secret123", "log": {"file": log_file}}
  105. config_path = os.path.join(self.temp_dir, "config.json")
  106. with open(config_path, "w") as f:
  107. json.dump(config_data, f)
  108. sys.argv = ["ddns", "-c", config_path]
  109. # 加载配置,应该正常工作
  110. configs = load_configs("test", "1.0", "2023-01-01")
  111. self.assertTrue(os.path.exists(log_dir))
  112. self.assertEqual(configs[0].log_file, log_file)
  113. if __name__ == "__main__":
  114. unittest.main()