test_config_cli.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  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 = [
  133. "ddns",
  134. "--log_level",
  135. "INFO",
  136. "--log_file",
  137. "/tmp/ddns.log",
  138. "--log_datefmt",
  139. "%Y-%m-%d %H:%M:%S",
  140. ]
  141. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  142. self.assertEqual(config["log_level"], 20)
  143. self.assertEqual(config["log_file"], "/tmp/ddns.log")
  144. self.assertEqual(config["log_datefmt"], "%Y-%m-%d %H:%M:%S")
  145. def test_load_config_system_exit_flags(self):
  146. sys.argv = ["ddns", "--version"]
  147. with self.assertRaises(SystemExit):
  148. load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  149. sys.argv = ["ddns", "--help"]
  150. with self.assertRaises(SystemExit):
  151. load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  152. def test_new_config_action_simple(self):
  153. """Test NewConfigAction behavior in a simple way"""
  154. from ddns.config.cli import NewConfigAction
  155. # Create an action and test its basic properties
  156. action = NewConfigAction(["--new-config"], "new_config", nargs="?")
  157. # Test that the action has the right configuration
  158. self.assertEqual(action.option_strings, ["--new-config"])
  159. self.assertEqual(action.dest, "new_config")
  160. self.assertEqual(action.nargs, "?")
  161. def test_load_config_other_flags(self):
  162. sys.argv = ["ddns", "--ttl", "300", "--line", "unicom"]
  163. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  164. self.assertEqual(config["ttl"], 300)
  165. self.assertEqual(config["line"], "unicom")
  166. sys.argv = ["ddns", "--config", "/path/to/config.json"]
  167. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  168. self.assertEqual(config["config"], ["/path/to/config.json"])
  169. def test_load_config_index_rules(self):
  170. sys.argv = [
  171. "ddns",
  172. "--index4",
  173. "url:http://ip.example.com",
  174. "interface:eth0",
  175. "--index6",
  176. "url:http://ipv6.example.com",
  177. ]
  178. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  179. self.assertEqual(config["index4"], ["url:http://ip.example.com", "interface:eth0"])
  180. self.assertEqual(config["index6"], ["url:http://ipv6.example.com"])
  181. def test_load_config_dns_providers(self):
  182. # 测试CLI中实际支持的DNS providers
  183. cli_supported_providers = [
  184. "51dns",
  185. "alidns",
  186. "aliesa",
  187. "callback",
  188. "cloudflare",
  189. "debug",
  190. "dnscom",
  191. "dnspod_com",
  192. "dnspod",
  193. "he",
  194. "huaweidns",
  195. "noip",
  196. "tencentcloud",
  197. ]
  198. for provider in cli_supported_providers:
  199. sys.argv = ["ddns", "--dns", provider]
  200. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  201. self.assertEqual(config["dns"], provider)
  202. def test_load_config_debug_mode(self):
  203. sys.argv = ["ddns", "--debug"]
  204. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  205. self.assertTrue(config["debug"])
  206. self.assertEqual(config["log_level"], 10)
  207. self.assertFalse(config["cache"])
  208. def test_load_config_minimal_setup(self):
  209. sys.argv = ["ddns"]
  210. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  211. self.assertNotIn("dns", config)
  212. self.assertNotIn("id", config)
  213. self.assertNotIn("token", config)
  214. self.assertFalse(config.get("debug", False))
  215. def test_extend_action_functionality(self):
  216. sys.argv = ["ddns", "--ipv4", "example.com", "test.com", "--ipv4", "another.com"]
  217. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  218. self.assertEqual(config["ipv4"], ["example.com", "test.com", "another.com"])
  219. sys.argv = ["ddns", "--proxy", "proxy1.com", "--proxy", "proxy2.com", "proxy3.com", "--proxy", "proxy4.com"]
  220. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  221. self.assertEqual(config["proxy"], ["proxy1.com", "proxy2.com", "proxy3.com", "proxy4.com"])
  222. sys.argv = ["ddns", "--ipv4", "--ipv6", "--proxy"]
  223. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  224. self.assertEqual(config["ipv4"], [])
  225. self.assertEqual(config["ipv6"], [])
  226. self.assertEqual(config["proxy"], [])
  227. def test_load_config_combined_flags(self):
  228. sys.argv = [
  229. "ddns",
  230. "--dns",
  231. "cloudflare",
  232. "--id",
  233. "[email protected]",
  234. "--token",
  235. "secret123",
  236. "--ipv4",
  237. "example.com",
  238. "test.com",
  239. "--ipv6",
  240. "ipv6.example.com",
  241. "--ttl",
  242. "600",
  243. "--line",
  244. "default",
  245. "--cache",
  246. "true",
  247. "--ssl",
  248. "auto",
  249. "--proxy",
  250. "http://proxy.example.com:8080",
  251. "--log-level",
  252. "INFO",
  253. "--log-file",
  254. "/var/log/ddns.log",
  255. ]
  256. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  257. self.assertEqual(config["dns"], "cloudflare")
  258. self.assertEqual(config["id"], "[email protected]")
  259. self.assertEqual(config["token"], "secret123")
  260. self.assertEqual(config["ipv4"], ["example.com", "test.com"])
  261. self.assertEqual(config["ipv6"], ["ipv6.example.com"])
  262. self.assertEqual(config["ttl"], 600)
  263. self.assertEqual(config["line"], "default")
  264. self.assertTrue(config["cache"])
  265. self.assertEqual(config["ssl"], "auto")
  266. self.assertEqual(config["proxy"], ["http://proxy.example.com:8080"])
  267. self.assertEqual(config["log_level"], 20)
  268. self.assertEqual(config["log_file"], "/var/log/ddns.log")
  269. def test_load_config_invalid_inputs(self):
  270. sys.argv = ["ddns", "--dns", "invalid_provider"]
  271. with self.assertRaises(SystemExit):
  272. load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  273. sys.argv = ["ddns", "--ttl", "invalid_ttl"]
  274. with self.assertRaises(SystemExit):
  275. load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  276. sys.argv = ["ddns", "--log-level", "INVALID"]
  277. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  278. self.assertEqual(config["log_level"], "Level INVALID")
  279. def test_load_config_value_types(self):
  280. # Test cache with different value types
  281. test_cases = [
  282. ("true", True),
  283. ("false", False),
  284. ("1", True),
  285. ("0", False),
  286. ("yes", True),
  287. ("no", False),
  288. ("/path/to/cache", "/path/to/cache"),
  289. ]
  290. for cache_value, expected in test_cases:
  291. sys.argv = ["ddns", "--cache", cache_value]
  292. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  293. self.assertEqual(config["cache"], expected)
  294. def test_load_config_special_characters(self):
  295. sys.argv = [
  296. "ddns",
  297. "--id",
  298. "[email protected]",
  299. "--token",
  300. "secret!@#$%^&*()",
  301. "--ipv4",
  302. "sub-domain.example.com",
  303. "--line",
  304. "移动",
  305. ]
  306. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  307. self.assertEqual(config["id"], "[email protected]")
  308. self.assertEqual(config["token"], "secret!@#$%^&*()")
  309. self.assertEqual(config["ipv4"], ["sub-domain.example.com"])
  310. self.assertEqual(config["line"], "移动")
  311. def test_load_config_cache_with_different_values(self):
  312. """Test load_config cache parameter with different value types"""
  313. test_cases = [
  314. ("true", True),
  315. ("false", False),
  316. ("1", True),
  317. ("0", False),
  318. ("yes", True),
  319. ("no", False),
  320. ("/path/to/cache", "/path/to/cache"),
  321. ("auto", "auto"),
  322. ]
  323. for cache_value, expected in test_cases:
  324. sys.argv = ["ddns", "--cache", cache_value]
  325. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  326. self.assertEqual(config["cache"], expected, "Cache value '{}' should be {}".format(cache_value, expected))
  327. def test_load_config_empty_values(self):
  328. """Test load_config with empty string values"""
  329. sys.argv = ["ddns", "--id", "", "--token", "", "--line", "", "--ssl", "", "--cache", ""]
  330. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  331. self.assertEqual(config["id"], "")
  332. self.assertEqual(config["token"], "")
  333. self.assertEqual(config["ssl"], "")
  334. self.assertEqual(config["cache"], "")
  335. # Test argument precedence
  336. sys.argv = ["ddns", "--dns", "cloudflare", "--dns", "alidns", "--ttl", "300", "--ttl", "600"]
  337. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  338. self.assertEqual(config["dns"], "alidns")
  339. self.assertEqual(config["ttl"], 600)
  340. def test_load_config_paths_and_numeric(self):
  341. # Test various path formats
  342. sys.argv = [
  343. "ddns",
  344. "--config",
  345. "/absolute/path/config.json",
  346. "--log-file",
  347. "./relative/path/ddns.log",
  348. "--ssl",
  349. "~/.ssl/cert.pem",
  350. ]
  351. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  352. self.assertEqual(config["config"], ["/absolute/path/config.json"])
  353. self.assertEqual(config["log_file"], "./relative/path/ddns.log")
  354. self.assertEqual(config["ssl"], "~/.ssl/cert.pem")
  355. # Test multiple configs
  356. sys.argv = [
  357. "ddns",
  358. "--config",
  359. "/path/to/config1.json",
  360. "--config",
  361. "/path/to/config2.json",
  362. ]
  363. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  364. self.assertEqual(config["config"], ["/path/to/config1.json", "/path/to/config2.json"])
  365. # Test numeric strings
  366. sys.argv = ["ddns", "--id", "123456", "--token", "987654321", "--line", "100"]
  367. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  368. self.assertEqual(config["id"], "123456")
  369. self.assertEqual(config["token"], "987654321")
  370. self.assertEqual(config["line"], "100")
  371. def test_extend_action_class(self):
  372. from ddns.config.cli import ExtendAction
  373. from argparse import Namespace, ArgumentParser
  374. parser = ArgumentParser()
  375. action = ExtendAction(option_strings=["--test"], dest="test")
  376. namespace = Namespace()
  377. # Test with single value
  378. action(parser, namespace, "value1", "--test")
  379. self.assertEqual(namespace.test, ["value1"])
  380. # Test with additional single value
  381. action(parser, namespace, "value2", "--test")
  382. self.assertEqual(namespace.test, ["value1", "value2"])
  383. # Test with list value
  384. action(parser, namespace, ["value3", "value4"], "--test")
  385. self.assertEqual(namespace.test, ["value1", "value2", "value3", "value4"])
  386. # Test with empty list
  387. namespace2 = Namespace()
  388. action(parser, namespace2, [], "--test")
  389. self.assertEqual(namespace2.test, [])
  390. action(parser, namespace2, "value1", "--test")
  391. self.assertEqual(namespace2.test, ["value1"])
  392. def test_comprehensive_scenario(self):
  393. sys.argv = [
  394. "ddns",
  395. "--dns",
  396. "cloudflare",
  397. "--id",
  398. "[email protected]",
  399. "--token",
  400. "cf_token_123456789",
  401. "--ipv4",
  402. "home.example.com",
  403. "work.example.com",
  404. "--ipv6",
  405. "home-ipv6.example.com",
  406. "--index4",
  407. "url:http://ip.example.com",
  408. "interface:eth0",
  409. "--index6",
  410. "url:http://ipv6.example.com",
  411. "--ttl",
  412. "300",
  413. "--line",
  414. "default",
  415. "--proxy",
  416. "http://proxy.corp.com:8080",
  417. "--cache",
  418. "/var/cache/ddns",
  419. "--ssl",
  420. "true",
  421. "--log-level",
  422. "INFO",
  423. "--log-file",
  424. "/var/log/ddns.log",
  425. "--log-format",
  426. "%(asctime)s [%(levelname)s] %(message)s",
  427. "--log-datefmt",
  428. "%Y-%m-%d %H:%M:%S",
  429. ]
  430. config = load_config("DDNS Client", "Dynamic DNS updater", "2.0.0", "2025-07-06")
  431. self.assertEqual(config["dns"], "cloudflare")
  432. self.assertEqual(config["id"], "[email protected]")
  433. self.assertEqual(config["token"], "cf_token_123456789")
  434. self.assertEqual(config["ipv4"], ["home.example.com", "work.example.com"])
  435. self.assertEqual(config["ipv6"], ["home-ipv6.example.com"])
  436. self.assertEqual(config["index4"], ["url:http://ip.example.com", "interface:eth0"])
  437. self.assertEqual(config["index6"], ["url:http://ipv6.example.com"])
  438. self.assertEqual(config["ttl"], 300)
  439. self.assertEqual(config["line"], "default")
  440. self.assertEqual(config["proxy"], ["http://proxy.corp.com:8080"])
  441. self.assertEqual(config["cache"], "/var/cache/ddns")
  442. self.assertEqual(config["ssl"], True)
  443. self.assertEqual(config["log_level"], 20)
  444. self.assertEqual(config["log_file"], "/var/log/ddns.log")
  445. self.assertEqual(config["log_format"], "%(asctime)s [%(levelname)s] %(message)s")
  446. self.assertEqual(config["log_datefmt"], "%Y-%m-%d %H:%M:%S")
  447. self.assertFalse(config["debug"])
  448. self.assertNotIn("new_config", config)
  449. def test_load_config_endpoint_parameter(self):
  450. # 测试endpoint参数,这在当前测试中缺失
  451. sys.argv = ["ddns", "--endpoint", "https://api.example.com/v1"]
  452. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  453. self.assertEqual(config["endpoint"], "https://api.example.com/v1")
  454. def test_load_config_hidden_parameters(self):
  455. # 测试隐藏的日志参数变体(带点号和横线的)
  456. sys.argv = ["ddns", "--log.file", "/test/log.txt", "--log.level", "ERROR"]
  457. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  458. self.assertEqual(config["log_file"], "/test/log.txt")
  459. self.assertEqual(config["log_level"], 40) # ERROR level
  460. sys.argv = ["ddns", "--log-file", "/test2/log.txt", "--log-level", "WARNING"]
  461. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  462. self.assertEqual(config["log_file"], "/test2/log.txt")
  463. self.assertEqual(config["log_level"], 30) # WARNING level
  464. sys.argv = ["ddns", "--log.format", "custom format", "--log.datefmt", "%Y-%m-%d"]
  465. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  466. self.assertEqual(config["log_format"], "custom format")
  467. self.assertEqual(config["log_datefmt"], "%Y-%m-%d")
  468. sys.argv = ["ddns", "--log-format", "custom format2", "--log-datefmt", "%H:%M:%S"]
  469. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  470. self.assertEqual(config["log_format"], "custom format2")
  471. self.assertEqual(config["log_datefmt"], "%H:%M:%S")
  472. def test_log_level_with_integers(self):
  473. # 测试log_level函数处理整数输入
  474. self.assertEqual(log_level(10), "DEBUG")
  475. self.assertEqual(log_level(20), "INFO")
  476. self.assertEqual(log_level(50), "CRITICAL")
  477. def test_load_config_cache_none_in_debug(self):
  478. # 测试debug模式下cache为None时的行为
  479. sys.argv = ["ddns", "--debug", "--cache", "true"]
  480. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  481. self.assertTrue(config["debug"])
  482. self.assertEqual(config["log_level"], 10) # DEBUG
  483. self.assertTrue(config["cache"]) # 明确设置的cache应该保持
  484. # 测试debug模式下没有设置cache时
  485. sys.argv = ["ddns", "--debug"]
  486. config = load_config("Test DDNS", "Test doc", "1.0.0", "2025-07-04")
  487. self.assertTrue(config["debug"])
  488. self.assertEqual(config["log_level"], 10) # DEBUG
  489. self.assertFalse(config["cache"]) # debug模式下默认禁用cache
  490. if __name__ == "__main__":
  491. unittest.main()