test_config_cli.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. # coding=utf-8
  2. """
  3. Unit tests for ddns.config.cli module
  4. @author: GitHub Copilot
  5. """
  6. from __init__ import unittest
  7. import sys
  8. import io
  9. from ddns.config.cli import load_config, str_bool, log_level # noqa: E402
  10. class TestCliConfig(unittest.TestCase):
  11. def setUp(self):
  12. encode = sys.stdout.encoding
  13. if encode is not None and encode.lower() != "utf-8" and hasattr(sys.stdout, "buffer"):
  14. # 兼容windows 和部分ASCII编码的老旧系统
  15. sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
  16. sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8")
  17. self.original_argv = sys.argv[:]
  18. def tearDown(self):
  19. sys.argv = self.original_argv
  20. def test_str_bool_function(self):
  21. """Test str_bool function with various inputs"""
  22. # Test boolean inputs
  23. self.assertTrue(str_bool(True))
  24. self.assertFalse(str_bool(False))
  25. self.assertFalse(str_bool(None))
  26. # Test string inputs that should be True
  27. for value in ["yes", "true", "t", "y", "1", "YES", "TRUE", "T", "Y"]:
  28. self.assertTrue(str_bool(value), "Value '{}' should be True".format(value))
  29. # Test string inputs that should be False
  30. for value in ["no", "false", "f", "n", "0", "NO", "FALSE", "F", "N"]:
  31. self.assertFalse(str_bool(value), "Value '{}' should be False".format(value))
  32. # Test string inputs that should remain unchanged
  33. self.assertEqual(str_bool("maybe"), "maybe")
  34. self.assertEqual(str_bool("auto"), "auto")
  35. self.assertEqual(str_bool(""), "")
  36. self.assertEqual(str_bool("off"), "off")
  37. self.assertEqual(str_bool("on"), "on")
  38. # Test non-string inputs
  39. self.assertTrue(str_bool(1))
  40. self.assertFalse(str_bool(0))
  41. self.assertTrue(str_bool([1, 2, 3]))
  42. self.assertFalse(str_bool([]))
  43. self.assertTrue(str_bool(1.0))
  44. self.assertFalse(str_bool(0.0))
  45. # Test edge cases
  46. self.assertEqual(str_bool(" true "), " true ")
  47. self.assertTrue(str_bool("True"))
  48. self.assertEqual(str_bool("path/to/file"), "path/to/file")
  49. self.assertEqual(str_bool("中文"), "中文")
  50. def test_log_level_function(self):
  51. """Test log_level function with various inputs"""
  52. self.assertEqual(log_level("DEBUG"), 10)
  53. self.assertEqual(log_level("INFO"), 20)
  54. self.assertEqual(log_level("WARNING"), 30)
  55. self.assertEqual(log_level("ERROR"), 40)
  56. self.assertEqual(log_level("CRITICAL"), 50)
  57. self.assertEqual(log_level("debug"), 10)
  58. self.assertEqual(log_level("critical"), 50)
  59. self.assertEqual(log_level("NOTSET"), 0)
  60. def test_load_config_basic_args(self):
  61. """Test load_config with basic command line arguments"""
  62. sys.argv = ["ddns", "--dns", "cloudflare", "--id", "[email protected]", "--token", "secret123", "--debug"]
  63. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  64. self.assertEqual(config["dns"], "cloudflare")
  65. self.assertEqual(config["id"], "[email protected]")
  66. self.assertEqual(config["token"], "secret123")
  67. self.assertTrue(config["debug"])
  68. def test_load_config_with_arrays(self):
  69. """Test load_config with array arguments"""
  70. sys.argv = ["ddns", "--ipv4", "example.com", "test.com", "--proxy", "http://proxy1.com", "http://proxy2.com"]
  71. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  72. self.assertEqual(config["ipv4"], ["example.com", "test.com"])
  73. self.assertEqual(config["proxy"], ["http://proxy1.com", "http://proxy2.com"])
  74. def test_load_config_ssl_comprehensive(self):
  75. """Test comprehensive SSL configuration options"""
  76. # Test --ssl without value (should default to True)
  77. sys.argv = ["ddns", "--ssl"]
  78. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  79. self.assertTrue(config["ssl"])
  80. # Test --ssl with boolean-like values
  81. ssl_bool_cases = [
  82. ("true", True),
  83. ("false", False),
  84. ("yes", True),
  85. ("no", False),
  86. ("1", True),
  87. ("0", False),
  88. ("TRUE", True),
  89. ("FALSE", False),
  90. ("Y", True),
  91. ("N", False),
  92. ]
  93. for ssl_value, expected in ssl_bool_cases:
  94. sys.argv = ["ddns", "--ssl", ssl_value]
  95. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  96. self.assertEqual(config["ssl"], expected, "SSL value '{}' should be {}".format(ssl_value, expected))
  97. # Test --ssl with special values (auto, file paths)
  98. ssl_special_cases = [
  99. ("auto", "auto"),
  100. ("/path/to/cert.pem", "/path/to/cert.pem"),
  101. ("./cert.crt", "./cert.crt"),
  102. ("C:\\certs\\cert.pem", "C:\\certs\\cert.pem"),
  103. ("", ""),
  104. ("custom_value", "custom_value"),
  105. ]
  106. for ssl_value, expected in ssl_special_cases:
  107. sys.argv = ["ddns", "--ssl", ssl_value]
  108. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  109. self.assertEqual(config["ssl"], expected, "SSL value '{}' should be {}".format(ssl_value, expected))
  110. # Test --no-ssl flag
  111. sys.argv = ["ddns", "--no-ssl"]
  112. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  113. self.assertFalse(config["ssl"])
  114. # Test --no-ssl overrides --ssl
  115. sys.argv = ["ddns", "--ssl", "true", "--no-ssl"]
  116. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  117. self.assertFalse(config["ssl"])
  118. def test_load_config_log_settings(self):
  119. sys.argv = [
  120. "ddns",
  121. "--log-level",
  122. "DEBUG",
  123. "--log-file",
  124. "/var/log/ddns.log",
  125. "--log-format",
  126. "%(asctime)s %(message)s",
  127. ]
  128. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  129. self.assertEqual(config["log_level"], 10)
  130. self.assertEqual(config["log_file"], "/var/log/ddns.log")
  131. self.assertEqual(config["log_format"], "%(asctime)s %(message)s")
  132. sys.argv = ["ddns", "--log_level", "INFO", "--log_file", "/tmp/ddns.log", "--log_datefmt", "%Y-%m-%d %H:%M:%S"]
  133. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  134. self.assertEqual(config["log_level"], 20)
  135. self.assertEqual(config["log_file"], "/tmp/ddns.log")
  136. self.assertEqual(config["log_datefmt"], "%Y-%m-%d %H:%M:%S")
  137. def test_load_config_system_exit_flags(self):
  138. sys.argv = ["ddns", "--version"]
  139. with self.assertRaises(SystemExit):
  140. load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  141. sys.argv = ["ddns", "--help"]
  142. with self.assertRaises(SystemExit):
  143. load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  144. def test_new_config_action_simple(self):
  145. """Test NewConfigAction behavior in a simple way"""
  146. from ddns.config.cli import NewConfigAction
  147. # Create an action and test its basic properties
  148. action = NewConfigAction(["--new-config"], "new_config", nargs="?")
  149. # Test that the action has the right configuration
  150. self.assertEqual(action.option_strings, ["--new-config"])
  151. self.assertEqual(action.dest, "new_config")
  152. self.assertEqual(action.nargs, "?")
  153. def test_load_config_other_flags(self):
  154. sys.argv = ["ddns", "--ttl", "300", "--line", "unicom"]
  155. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  156. self.assertEqual(config["ttl"], 300)
  157. self.assertEqual(config["line"], "unicom")
  158. sys.argv = ["ddns", "--config", "/path/to/config.json"]
  159. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  160. self.assertEqual(config["config"], ["/path/to/config.json"])
  161. def test_load_config_index_rules(self):
  162. sys.argv = [
  163. "ddns",
  164. "--index4",
  165. "url:http://ip.example.com",
  166. "interface:eth0",
  167. "--index6",
  168. "url:http://ipv6.example.com",
  169. ]
  170. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  171. self.assertEqual(config["index4"], ["url:http://ip.example.com", "interface:eth0"])
  172. self.assertEqual(config["index6"], ["url:http://ipv6.example.com"])
  173. def test_load_config_dns_providers(self):
  174. # 测试CLI中实际支持的DNS providers
  175. cli_supported_providers = [
  176. "51dns",
  177. "alidns",
  178. "aliesa",
  179. "callback",
  180. "cloudflare",
  181. "debug",
  182. "dnscom",
  183. "dnspod_com",
  184. "dnspod",
  185. "he",
  186. "huaweidns",
  187. "noip",
  188. "tencentcloud",
  189. ]
  190. for provider in cli_supported_providers:
  191. sys.argv = ["ddns", "--dns", provider]
  192. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  193. self.assertEqual(config["dns"], provider)
  194. def test_load_config_debug_mode(self):
  195. sys.argv = ["ddns", "--debug"]
  196. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  197. self.assertTrue(config["debug"])
  198. self.assertEqual(config["log_level"], 10)
  199. self.assertFalse(config["cache"])
  200. def test_load_config_minimal_setup(self):
  201. sys.argv = ["ddns"]
  202. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  203. self.assertNotIn("dns", config)
  204. self.assertNotIn("id", config)
  205. self.assertNotIn("token", config)
  206. self.assertFalse(config.get("debug", False))
  207. def test_extend_action_functionality(self):
  208. sys.argv = ["ddns", "--ipv4", "example.com", "test.com", "--ipv4", "another.com"]
  209. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  210. self.assertEqual(config["ipv4"], ["example.com", "test.com", "another.com"])
  211. sys.argv = ["ddns", "--proxy", "proxy1.com", "--proxy", "proxy2.com", "proxy3.com", "--proxy", "proxy4.com"]
  212. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  213. self.assertEqual(config["proxy"], ["proxy1.com", "proxy2.com", "proxy3.com", "proxy4.com"])
  214. sys.argv = ["ddns", "--ipv4", "--ipv6", "--proxy"]
  215. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  216. self.assertEqual(config["ipv4"], [])
  217. self.assertEqual(config["ipv6"], [])
  218. self.assertEqual(config["proxy"], [])
  219. def test_load_config_combined_flags(self):
  220. sys.argv = [
  221. "ddns",
  222. "--dns",
  223. "cloudflare",
  224. "--id",
  225. "[email protected]",
  226. "--token",
  227. "secret123",
  228. "--ipv4",
  229. "example.com",
  230. "test.com",
  231. "--ipv6",
  232. "ipv6.example.com",
  233. "--ttl",
  234. "600",
  235. "--line",
  236. "default",
  237. "--cache",
  238. "true",
  239. "--ssl",
  240. "auto",
  241. "--proxy",
  242. "http://proxy.example.com:8080",
  243. "--log-level",
  244. "INFO",
  245. "--log-file",
  246. "/var/log/ddns.log",
  247. ]
  248. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  249. self.assertEqual(config["dns"], "cloudflare")
  250. self.assertEqual(config["id"], "[email protected]")
  251. self.assertEqual(config["token"], "secret123")
  252. self.assertEqual(config["ipv4"], ["example.com", "test.com"])
  253. self.assertEqual(config["ipv6"], ["ipv6.example.com"])
  254. self.assertEqual(config["ttl"], 600)
  255. self.assertEqual(config["line"], "default")
  256. self.assertTrue(config["cache"])
  257. self.assertEqual(config["ssl"], "auto")
  258. self.assertEqual(config["proxy"], ["http://proxy.example.com:8080"])
  259. self.assertEqual(config["log_level"], 20)
  260. self.assertEqual(config["log_file"], "/var/log/ddns.log")
  261. def test_load_config_invalid_inputs(self):
  262. sys.argv = ["ddns", "--dns", "invalid_provider"]
  263. with self.assertRaises(SystemExit):
  264. load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  265. sys.argv = ["ddns", "--ttl", "invalid_ttl"]
  266. with self.assertRaises(SystemExit):
  267. load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  268. sys.argv = ["ddns", "--log-level", "INVALID"]
  269. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  270. self.assertEqual(config["log_level"], "Level INVALID")
  271. def test_load_config_value_types(self):
  272. # Test cache with different value types
  273. test_cases = [
  274. ("true", True),
  275. ("false", False),
  276. ("1", True),
  277. ("0", False),
  278. ("yes", True),
  279. ("no", False),
  280. ("/path/to/cache", "/path/to/cache"),
  281. ]
  282. for cache_value, expected in test_cases:
  283. sys.argv = ["ddns", "--cache", cache_value]
  284. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  285. self.assertEqual(config["cache"], expected)
  286. def test_load_config_special_characters(self):
  287. sys.argv = [
  288. "ddns",
  289. "--id",
  290. "[email protected]",
  291. "--token",
  292. "secret!@#$%^&*()",
  293. "--ipv4",
  294. "sub-domain.example.com",
  295. "--line",
  296. "移动",
  297. ]
  298. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  299. self.assertEqual(config["id"], "[email protected]")
  300. self.assertEqual(config["token"], "secret!@#$%^&*()")
  301. self.assertEqual(config["ipv4"], ["sub-domain.example.com"])
  302. self.assertEqual(config["line"], "移动")
  303. def test_load_config_cache_with_different_values(self):
  304. """Test load_config cache parameter with different value types"""
  305. test_cases = [
  306. ("true", True),
  307. ("false", False),
  308. ("1", True),
  309. ("0", False),
  310. ("yes", True),
  311. ("no", False),
  312. ("/path/to/cache", "/path/to/cache"),
  313. ("auto", "auto"),
  314. ]
  315. for cache_value, expected in test_cases:
  316. sys.argv = ["ddns", "--cache", cache_value]
  317. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  318. self.assertEqual(config["cache"], expected, "Cache value '{}' should be {}".format(cache_value, expected))
  319. def test_load_config_empty_values(self):
  320. """Test load_config with empty string values"""
  321. sys.argv = ["ddns", "--id", "", "--token", "", "--line", "", "--ssl", "", "--cache", ""]
  322. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  323. self.assertEqual(config["id"], "")
  324. self.assertEqual(config["token"], "")
  325. self.assertEqual(config["ssl"], "")
  326. self.assertEqual(config["cache"], "")
  327. # Test argument precedence
  328. sys.argv = ["ddns", "--dns", "cloudflare", "--dns", "alidns", "--ttl", "300", "--ttl", "600"]
  329. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  330. self.assertEqual(config["dns"], "alidns")
  331. self.assertEqual(config["ttl"], 600)
  332. def test_load_config_paths_and_numeric(self):
  333. # Test various path formats
  334. sys.argv = [
  335. "ddns",
  336. "--config",
  337. "/absolute/path/config.json",
  338. "--log-file",
  339. "./relative/path/ddns.log",
  340. "--ssl",
  341. "~/.ssl/cert.pem",
  342. ]
  343. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  344. self.assertEqual(config["config"], ["/absolute/path/config.json"])
  345. self.assertEqual(config["log_file"], "./relative/path/ddns.log")
  346. self.assertEqual(config["ssl"], "~/.ssl/cert.pem")
  347. # Test multiple configs
  348. sys.argv = ["ddns", "--config", "/path/to/config1.json", "--config", "/path/to/config2.json"]
  349. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  350. self.assertEqual(config["config"], ["/path/to/config1.json", "/path/to/config2.json"])
  351. # Test numeric strings
  352. sys.argv = ["ddns", "--id", "123456", "--token", "987654321", "--line", "100"]
  353. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  354. self.assertEqual(config["id"], "123456")
  355. self.assertEqual(config["token"], "987654321")
  356. self.assertEqual(config["line"], "100")
  357. def test_extend_action_class(self):
  358. from ddns.config.cli import ExtendAction
  359. from argparse import Namespace, ArgumentParser
  360. parser = ArgumentParser()
  361. action = ExtendAction(option_strings=["--test"], dest="test")
  362. namespace = Namespace()
  363. # Test with single value
  364. action(parser, namespace, "value1", "--test")
  365. self.assertEqual(namespace.test, ["value1"])
  366. # Test with additional single value
  367. action(parser, namespace, "value2", "--test")
  368. self.assertEqual(namespace.test, ["value1", "value2"])
  369. # Test with list value
  370. action(parser, namespace, ["value3", "value4"], "--test")
  371. self.assertEqual(namespace.test, ["value1", "value2", "value3", "value4"])
  372. # Test with empty list
  373. namespace2 = Namespace()
  374. action(parser, namespace2, [], "--test")
  375. self.assertEqual(namespace2.test, [])
  376. action(parser, namespace2, "value1", "--test")
  377. self.assertEqual(namespace2.test, ["value1"])
  378. def test_comprehensive_scenario(self):
  379. sys.argv = [
  380. "ddns",
  381. "--dns",
  382. "cloudflare",
  383. "--id",
  384. "[email protected]",
  385. "--token",
  386. "cf_token_123456789",
  387. "--ipv4",
  388. "home.example.com",
  389. "work.example.com",
  390. "--ipv6",
  391. "home-ipv6.example.com",
  392. "--index4",
  393. "url:http://ip.example.com",
  394. "interface:eth0",
  395. "--index6",
  396. "url:http://ipv6.example.com",
  397. "--ttl",
  398. "300",
  399. "--line",
  400. "default",
  401. "--proxy",
  402. "http://proxy.corp.com:8080",
  403. "--cache",
  404. "/var/cache/ddns",
  405. "--ssl",
  406. "true",
  407. "--log-level",
  408. "INFO",
  409. "--log-file",
  410. "/var/log/ddns.log",
  411. "--log-format",
  412. "%(asctime)s [%(levelname)s] %(message)s",
  413. "--log-datefmt",
  414. "%Y-%m-%d %H:%M:%S",
  415. ]
  416. config = load_config("DDNS Client", "Dynamic DNS updater", "2.0.0", "2025-07-06")
  417. self.assertEqual(config["dns"], "cloudflare")
  418. self.assertEqual(config["id"], "[email protected]")
  419. self.assertEqual(config["token"], "cf_token_123456789")
  420. self.assertEqual(config["ipv4"], ["home.example.com", "work.example.com"])
  421. self.assertEqual(config["ipv6"], ["home-ipv6.example.com"])
  422. self.assertEqual(config["index4"], ["url:http://ip.example.com", "interface:eth0"])
  423. self.assertEqual(config["index6"], ["url:http://ipv6.example.com"])
  424. self.assertEqual(config["ttl"], 300)
  425. self.assertEqual(config["line"], "default")
  426. self.assertEqual(config["proxy"], ["http://proxy.corp.com:8080"])
  427. self.assertEqual(config["cache"], "/var/cache/ddns")
  428. self.assertEqual(config["ssl"], True)
  429. self.assertEqual(config["log_level"], 20)
  430. self.assertEqual(config["log_file"], "/var/log/ddns.log")
  431. self.assertEqual(config["log_format"], "%(asctime)s [%(levelname)s] %(message)s")
  432. self.assertEqual(config["log_datefmt"], "%Y-%m-%d %H:%M:%S")
  433. self.assertFalse(config["debug"])
  434. self.assertNotIn("new_config", config)
  435. def test_load_config_endpoint_parameter(self):
  436. # 测试endpoint参数,这在当前测试中缺失
  437. sys.argv = ["ddns", "--endpoint", "https://api.example.com/v1"]
  438. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  439. self.assertEqual(config["endpoint"], "https://api.example.com/v1")
  440. def test_load_config_hidden_parameters(self):
  441. # 测试隐藏的日志参数变体(带点号和横线的)
  442. sys.argv = ["ddns", "--log.file", "/test/log.txt", "--log.level", "ERROR"]
  443. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  444. self.assertEqual(config["log_file"], "/test/log.txt")
  445. self.assertEqual(config["log_level"], 40) # ERROR level
  446. sys.argv = ["ddns", "--log-file", "/test2/log.txt", "--log-level", "WARNING"]
  447. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  448. self.assertEqual(config["log_file"], "/test2/log.txt")
  449. self.assertEqual(config["log_level"], 30) # WARNING level
  450. sys.argv = ["ddns", "--log.format", "custom format", "--log.datefmt", "%Y-%m-%d"]
  451. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  452. self.assertEqual(config["log_format"], "custom format")
  453. self.assertEqual(config["log_datefmt"], "%Y-%m-%d")
  454. sys.argv = ["ddns", "--log-format", "custom format2", "--log-datefmt", "%H:%M:%S"]
  455. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  456. self.assertEqual(config["log_format"], "custom format2")
  457. self.assertEqual(config["log_datefmt"], "%H:%M:%S")
  458. def test_log_level_with_integers(self):
  459. # 测试log_level函数处理整数输入
  460. self.assertEqual(log_level(10), "DEBUG")
  461. self.assertEqual(log_level(20), "INFO")
  462. self.assertEqual(log_level(50), "CRITICAL")
  463. def test_load_config_cache_none_in_debug(self):
  464. # 测试debug模式下cache为None时的行为
  465. sys.argv = ["ddns", "--debug", "--cache", "true"]
  466. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  467. self.assertTrue(config["debug"])
  468. self.assertEqual(config["log_level"], 10) # DEBUG
  469. self.assertTrue(config["cache"]) # 明确设置的cache应该保持
  470. # 测试debug模式下没有设置cache时
  471. sys.argv = ["ddns", "--debug"]
  472. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  473. self.assertTrue(config["debug"])
  474. self.assertEqual(config["log_level"], 10) # DEBUG
  475. self.assertFalse(config["cache"]) # debug模式下默认禁用cache
  476. if __name__ == "__main__":
  477. unittest.main()