Python library for working with the PD Buddy Sink Serial Console Configuration Interface
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

__init__.py 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. """Unit tests for the top-level pdbuddy classes"""
  2. import unittest
  3. import pdbuddy
  4. class SinkTestCase(unittest.TestCase):
  5. def setUp(self):
  6. # Get devices
  7. pdbs_devices = list(pdbuddy.Sink.get_devices())
  8. # If there are no devices, skip the test
  9. if len(pdbs_devices) == 0:
  10. self.skipTest("No PD Buddy Sink devices found")
  11. # Open the first device
  12. self.pdbs = pdbuddy.Sink(pdbs_devices[0])
  13. self.obj_valid = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  14. flags=pdbuddy.SinkFlags.NONE, v=15000, i=3000)
  15. self.obj_valid_gb = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  16. flags=pdbuddy.SinkFlags.GIVEBACK, v=15000, i=3000)
  17. self.obj_huge_v = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  18. flags=pdbuddy.SinkFlags.NONE, v=65536, i=1000)
  19. self.obj_big_v = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  20. flags=pdbuddy.SinkFlags.NONE, v=20001, i=1000)
  21. self.obj_neg_v = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  22. flags=pdbuddy.SinkFlags.NONE, v=-1, i=1000)
  23. self.obj_huge_i = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  24. flags=pdbuddy.SinkFlags.NONE, v=5000, i=65536)
  25. self.obj_big_i = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  26. flags=pdbuddy.SinkFlags.NONE, v=5000, i=5001)
  27. self.obj_neg_i = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  28. flags=pdbuddy.SinkFlags.NONE, v=5000, i=-1)
  29. def tearDown(self):
  30. # Close the connection to the PD Buddy Sink
  31. self.pdbs.close()
  32. def test_identify(self):
  33. self.pdbs.identify()
  34. def test_help(self):
  35. help_text = self.pdbs.help()
  36. self.assertTrue(len(help_text) > 0)
  37. self.assertTrue(len(help_text[0]) > 0)
  38. def test_license(self):
  39. license_text = self.pdbs.license()
  40. self.assertTrue(len(license_text) > 0)
  41. self.assertTrue(len(license_text[0]) > 0)
  42. def test_set_tmpcfg_valid(self):
  43. self.pdbs.set_tmpcfg(self.obj_valid)
  44. self.assertEqual(self.pdbs.get_tmpcfg(), self.obj_valid)
  45. def test_set_tmpcfg_valid_gb(self):
  46. self.pdbs.set_tmpcfg(self.obj_valid_gb)
  47. self.assertEqual(self.pdbs.get_tmpcfg(), self.obj_valid_gb)
  48. def test_set_tmpcfg_huge_v(self):
  49. with self.assertRaises(ValueError):
  50. self.pdbs.set_tmpcfg(self.obj_huge_v)
  51. def test_set_tmpcfg_big_v(self):
  52. with self.assertRaises(ValueError):
  53. self.pdbs.set_tmpcfg(self.obj_big_v)
  54. def test_set_tmpcfg_neg_v(self):
  55. with self.assertRaises(ValueError):
  56. self.pdbs.set_tmpcfg(self.obj_neg_v)
  57. def test_set_tmpcfg_huge_i(self):
  58. with self.assertRaises(ValueError):
  59. self.pdbs.set_tmpcfg(self.obj_huge_i)
  60. def test_set_tmpcfg_big_i(self):
  61. with self.assertRaises(ValueError):
  62. self.pdbs.set_tmpcfg(self.obj_big_i)
  63. def test_set_tmpcfg_neg_i(self):
  64. with self.assertRaises(ValueError):
  65. self.pdbs.set_tmpcfg(self.obj_neg_i)
  66. def test_write(self):
  67. self.test_set_tmpcfg_valid()
  68. self.pdbs.write()
  69. self.assertEqual(self.pdbs.get_cfg(), self.obj_valid)
  70. def test_get_cfg_index(self):
  71. self.assertIsInstance(self.pdbs.get_cfg(0), pdbuddy.SinkConfig)
  72. def test_get_cfg_index_bad(self):
  73. with self.assertRaises(IndexError):
  74. self.pdbs.get_cfg(-1)
  75. def test_load(self):
  76. # Write obj_valid to flash
  77. self.test_write()
  78. # Write obj_valid_gb to tmpcfg
  79. self.test_set_tmpcfg_valid_gb()
  80. self.assertNotEqual(self.pdbs.get_cfg(), self.pdbs.get_tmpcfg())
  81. # Load flash to tmpcfg
  82. self.pdbs.load()
  83. self.assertEqual(self.pdbs.get_cfg(), self.pdbs.get_tmpcfg())
  84. def test_erase(self):
  85. self.pdbs.erase()
  86. with self.assertRaises(KeyError):
  87. self.pdbs.load()
  88. def test_context_manager(self):
  89. self.pdbs.close()
  90. with pdbuddy.Sink(list(pdbuddy.Sink.get_devices())[0]) as pdbs:
  91. # Test something with the conext manager. For example, this is
  92. # essentially test_get_cfg_index.
  93. self.assertIsInstance(pdbs.get_cfg(0), pdbuddy.SinkConfig)
  94. def test_output(self):
  95. try:
  96. self.pdbs.output = False
  97. self.assertFalse(self.pdbs.output)
  98. self.pdbs.output = True
  99. self.assertTrue(self.pdbs.output)
  100. except KeyError:
  101. self.skipTest("Command output not supported")
  102. except ValueError:
  103. self.skipTest("Unknown value returned by PD Buddy Sink")
  104. def test_get_source_cap(self):
  105. self.assertIsInstance(self.pdbs.get_source_cap(), list)
  106. def test_send_command_invalid(self):
  107. with self.assertRaises(KeyError):
  108. self.pdbs.send_command("foo bar")
  109. class SinkConfigTestCase(unittest.TestCase):
  110. def setUp(self):
  111. self.obj_none = pdbuddy.SinkConfig(status=None, flags=None, v=None,
  112. i=None)
  113. self.obj_empty = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.EMPTY,
  114. flags=None, v=None, i=None)
  115. self.obj_valid = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  116. flags=pdbuddy.SinkFlags.NONE, v=15000, i=3000)
  117. self.obj_invalid = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.INVALID,
  118. flags=pdbuddy.SinkFlags.NONE, v=15000, i=3000)
  119. self.obj_valid_gb = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  120. flags=pdbuddy.SinkFlags.GIVEBACK, v=15000, i=3000)
  121. self.obj_valid_5v = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  122. flags=pdbuddy.SinkFlags.NONE, v=5000, i=3000)
  123. self.obj_valid_1a = pdbuddy.SinkConfig(status=pdbuddy.SinkStatus.VALID,
  124. flags=pdbuddy.SinkFlags.NONE, v=15000, i=1000)
  125. def test_str_none(self):
  126. self.assertEqual(str(self.obj_none), "No configuration")
  127. def test_str_empty(self):
  128. self.assertEqual(str(self.obj_empty), "status: empty")
  129. def test_str_valid(self):
  130. self.assertEqual(str(self.obj_valid),
  131. "status: valid\nflags: (none)\nv: 15.00 V\ni: 3.00 A")
  132. def test_str_invalid(self):
  133. self.assertEqual(str(self.obj_invalid),
  134. "status: invalid\nflags: (none)\nv: 15.00 V\ni: 3.00 A")
  135. def test_str_valid_gb(self):
  136. self.assertEqual(str(self.obj_valid_gb),
  137. "status: valid\nflags: GiveBack\nv: 15.00 V\ni: 3.00 A")
  138. def test_str_valid_5v(self):
  139. self.assertEqual(str(self.obj_valid_5v),
  140. "status: valid\nflags: (none)\nv: 5.00 V\ni: 3.00 A")
  141. def test_str_valid_1a(self):
  142. self.assertEqual(str(self.obj_valid_1a),
  143. "status: valid\nflags: (none)\nv: 15.00 V\ni: 1.00 A")
  144. def test_from_text_none(self):
  145. ft_none = pdbuddy.SinkConfig.from_text([])
  146. self.assertEqual(ft_none, self.obj_none)
  147. def test_from_text_empty(self):
  148. ft_empty = pdbuddy.SinkConfig.from_text([b"status: empty"])
  149. self.assertEqual(ft_empty, self.obj_empty)
  150. def test_from_text_valid(self):
  151. ft_valid = pdbuddy.SinkConfig.from_text([b"status: valid",
  152. b"flags: (none)",
  153. b"v: 15.00 V",
  154. b"i: 3.00 A"])
  155. self.assertEqual(ft_valid, self.obj_valid)
  156. def test_from_text_invalid(self):
  157. ft_invalid = pdbuddy.SinkConfig.from_text([b"status: invalid",
  158. b"flags: (none)",
  159. b"v: 15.00 V",
  160. b"i: 3.00 A"])
  161. self.assertEqual(ft_invalid, self.obj_invalid)
  162. def test_from_text_valid_gb(self):
  163. ft_valid_gb = pdbuddy.SinkConfig.from_text([b"status: valid",
  164. b"flags: GiveBack",
  165. b"v: 15.00 V",
  166. b"i: 3.00 A"])
  167. self.assertEqual(ft_valid_gb, self.obj_valid_gb)
  168. def test_from_text_valid_5v(self):
  169. ft_valid_5v = pdbuddy.SinkConfig.from_text([b"status: valid",
  170. b"flags: (none)",
  171. b"v: 5.00 V",
  172. b"i: 3.00 A"])
  173. self.assertEqual(ft_valid_5v, self.obj_valid_5v)
  174. def test_from_text_valid_1a(self):
  175. ft_valid_1a = pdbuddy.SinkConfig.from_text([b"status: valid",
  176. b"flags: (none)",
  177. b"v: 15.00 V",
  178. b"i: 1.00 A"])
  179. self.assertEqual(ft_valid_1a, self.obj_valid_1a)
  180. def test_from_text_invalid_index(self):
  181. with self.assertRaises(IndexError):
  182. pdbuddy.SinkConfig.from_text([b"Invalid index"])
  183. def test_from_text_no_configuration(self):
  184. ft_no_config = pdbuddy.SinkConfig.from_text([b"No configuration"])
  185. self.assertEqual(ft_no_config, self.obj_none)
  186. def test_from_text_valid_extra(self):
  187. ft_valid = pdbuddy.SinkConfig.from_text([b"status: valid",
  188. b"flags: (none)",
  189. b"This is an extra line, which shouldn't hurt anything.",
  190. b"v: 15.00 V",
  191. b"i: 3.00 A"])
  192. self.assertEqual(ft_valid, self.obj_valid)
  193. class UnknownPDOTestCase(unittest.TestCase):
  194. def setUp(self):
  195. self.obj_zero = pdbuddy.UnknownPDO(value=0x00000000)
  196. self.obj_notzero = pdbuddy.UnknownPDO(value=0xFFFFFFFF)
  197. def test_str_zero(self):
  198. self.assertEqual(str(self.obj_zero), "00000000")
  199. def test_str_notzero(self):
  200. self.assertEqual(str(self.obj_notzero), "FFFFFFFF")
  201. class SrcFixedPDOTestCase(unittest.TestCase):
  202. def setUp(self):
  203. self.obj_everything = pdbuddy.SrcFixedPDO(True, True, True, True, True,
  204. 3, 20000, 5000)
  205. self.obj_minimal = pdbuddy.SrcFixedPDO(False, False, False, False,
  206. False, 0, 5000, 1500)
  207. def test_str_everything(self):
  208. self.assertEqual(str(self.obj_everything),
  209. "fixed\n\tdual_role_pwr: 1\n\tusb_suspend: 1\n"
  210. "\tunconstrained_pwr: 1\n\tusb_comms: 1\n\tdual_role_data: 1\n"
  211. "\tpeak_i: 3\n\tv: 20.00 V\n\ti: 5.00 A")
  212. def test_str_minimal(self):
  213. self.assertEqual(str(self.obj_minimal),
  214. "fixed\n\tv: 5.00 V\n\ti: 1.50 A")
  215. class TypeCVirtualPDOTestCase(unittest.TestCase):
  216. def setUp(self):
  217. self.obj_1p5a = pdbuddy.TypeCVirtualPDO(1500)
  218. def test_str_1p5a(self):
  219. self.assertEqual(str(self.obj_1p5a), "typec_virtual\n\ti: 1.50 A")
  220. class ReadPDOTestCase(unittest.TestCase):
  221. def setUp(self):
  222. self.src_fixed_everything = pdbuddy.SrcFixedPDO(True, True, True, True,
  223. True, 3, 20000, 5000)
  224. self.src_fixed_minimal = pdbuddy.SrcFixedPDO(False, False, False,
  225. False, False, 0, 5000, 1500)
  226. self.unknown_zero = pdbuddy.UnknownPDO(value=0x00000000)
  227. self.unknown_notzero = pdbuddy.UnknownPDO(value=0xFFFFFFFF)
  228. self.typec_virtual = pdbuddy.TypeCVirtualPDO(1500)
  229. def test_read_src_fixed_everything(self):
  230. rp_src_fixed_everything = pdbuddy.read_pdo([b"PDO 1: fixed",
  231. b"\tdual_role_pwr: 1",
  232. b"\tusb_suspend: 1",
  233. b"\tunconstrained_pwr: 1",
  234. b"\tusb_comms: 1",
  235. b"\tdual_role_data: 1",
  236. b"\tpeak_i: 3",
  237. b"\tv: 20.00 V",
  238. b"\ti: 5.00 A"])
  239. self.assertEqual(self.src_fixed_everything, rp_src_fixed_everything)
  240. def test_read_src_fixed_minimal(self):
  241. rp_src_fixed_minimal = pdbuddy.read_pdo([b"PDO 1: fixed",
  242. b"\tv: 5.00 V",
  243. b"\ti: 1.50 A"])
  244. self.assertEqual(self.src_fixed_minimal, rp_src_fixed_minimal)
  245. def test_read_src_fixed_minimal_no_index(self):
  246. rp_src_fixed_minimal = pdbuddy.read_pdo([b"fixed",
  247. b"\tv: 5.00 V",
  248. b"\ti: 1.50 A"])
  249. self.assertEqual(self.src_fixed_minimal, rp_src_fixed_minimal)
  250. def test_read_unknown_zero(self):
  251. rp_unknown_zero = pdbuddy.read_pdo([b"PDO 1: 00000000"])
  252. self.assertEqual(self.unknown_zero, rp_unknown_zero)
  253. def test_read_unknown_notzero(self):
  254. rp_unknown_notzero = pdbuddy.read_pdo([b"PDO 1: FFFFFFFF"])
  255. self.assertEqual(self.unknown_notzero, rp_unknown_notzero)
  256. def test_read_typec_virtual(self):
  257. rp_typec_virtual = pdbuddy.read_pdo([b"PDO 5: typec_virtual",
  258. b"\ti: 1.50 A"])
  259. self.assertEqual(self.typec_virtual, rp_typec_virtual)
  260. def test_read_none(self):
  261. none_pdo = pdbuddy.read_pdo([b"No Source_Capabilities"])
  262. self.assertEqual(none_pdo, None)
  263. class ReadPDOListTestCase(unittest.TestCase):
  264. def setUp(self):
  265. self.src_fixed_everything = pdbuddy.SrcFixedPDO(True, True, True, True,
  266. True, 3, 20000, 5000)
  267. self.src_fixed_minimal = pdbuddy.SrcFixedPDO(False, False, False,
  268. False, False, 0, 5000, 1500)
  269. self.unknown_zero = pdbuddy.UnknownPDO(value=0x00000000)
  270. self.unknown_notzero = pdbuddy.UnknownPDO(value=0xFFFFFFFF)
  271. self.typec_virtual = pdbuddy.TypeCVirtualPDO(1500)
  272. def test_read_pdo_list(self):
  273. # It's not a legal list for USB Power Delivery, but it works fine for
  274. # testing this code
  275. text = [b"PDO 1: fixed",
  276. b"\tdual_role_pwr: 1",
  277. b"\tusb_suspend: 1",
  278. b"\tunconstrained_pwr: 1",
  279. b"\tusb_comms: 1",
  280. b"\tdual_role_data: 1",
  281. b"\tpeak_i: 3",
  282. b"\tv: 20.00 V",
  283. b"\ti: 5.00 A",
  284. b"PDO 2: fixed",
  285. b"\tv: 5.00 V",
  286. b"\ti: 1.50 A",
  287. b"PDO 3: 00000000",
  288. b"PDO 4: FFFFFFFF",
  289. b"PDO 5: typec_virtual",
  290. b"\ti: 1.50 A"]
  291. pdo_list = pdbuddy.read_pdo_list(text)
  292. self.assertEqual(pdo_list[0], self.src_fixed_everything)
  293. self.assertEqual(pdo_list[1], self.src_fixed_minimal)
  294. self.assertEqual(pdo_list[2], self.unknown_zero)
  295. self.assertEqual(pdo_list[3], self.unknown_notzero)
  296. self.assertEqual(pdo_list[4], self.typec_virtual)
  297. class PDOListCalculationsTestCase(unittest.TestCase):
  298. def setUp(self):
  299. self.src_fixed_5v_1p5a = pdbuddy.SrcFixedPDO(False, False, True,
  300. False, False, 0, 5000, 1500)
  301. self.src_fixed_5v_3a = pdbuddy.SrcFixedPDO(False, False, True, False,
  302. False, 0, 5000, 3000)
  303. self.src_fixed_9v_1p6a = pdbuddy.SrcFixedPDO(False, False, False,
  304. False, False, 0, 9000, 1600)
  305. self.src_fixed_9v_3a = pdbuddy.SrcFixedPDO(False, False, False, False,
  306. False, 0, 9000, 3000)
  307. self.src_fixed_10v_1p5a = pdbuddy.SrcFixedPDO(False, False, False,
  308. False, False, 0, 10000, 1500)
  309. self.src_fixed_12v_5a = pdbuddy.SrcFixedPDO(False, False, False, False,
  310. False, 0, 12000, 5000)
  311. self.src_fixed_15v_1p8a = pdbuddy.SrcFixedPDO(False, False, False,
  312. False, False, 0, 15000, 1800)
  313. self.src_fixed_15v_3a = pdbuddy.SrcFixedPDO(False, False, False, False,
  314. False, 0, 15000, 3000)
  315. self.src_fixed_20v_2p25a = pdbuddy.SrcFixedPDO(False, False, False,
  316. False, False, 0, 20000, 2250)
  317. self.src_fixed_20v_5a = pdbuddy.SrcFixedPDO(False, False, False, False,
  318. False, 0, 20000, 5000)
  319. self.typec_virtual_1p5a = pdbuddy.TypeCVirtualPDO(1500)
  320. def test_calculate_pdp_typec_virtual(self):
  321. self.assertEqual(pdbuddy.calculate_pdp([self.typec_virtual_1p5a]), 7.5)
  322. def test_calculate_pdp_15w(self):
  323. self.assertEqual(pdbuddy.calculate_pdp([self.src_fixed_5v_3a]), 15)
  324. self.assertEqual(pdbuddy.calculate_pdp([self.src_fixed_5v_3a,
  325. self.src_fixed_9v_1p6a]), 15)
  326. def test_calculate_pdp_27w(self):
  327. self.assertEqual(pdbuddy.calculate_pdp([self.src_fixed_5v_3a,
  328. self.src_fixed_9v_3a]), 27)
  329. self.assertEqual(pdbuddy.calculate_pdp([self.src_fixed_5v_3a,
  330. self.src_fixed_9v_3a, self.src_fixed_15v_1p8a]), 27)
  331. def test_calculate_pdp_45w(self):
  332. self.assertEqual(pdbuddy.calculate_pdp([self.src_fixed_5v_3a,
  333. self.src_fixed_9v_3a, self.src_fixed_15v_3a]), 45)
  334. self.assertEqual(pdbuddy.calculate_pdp([self.src_fixed_5v_3a,
  335. self.src_fixed_9v_3a, self.src_fixed_15v_3a,
  336. self.src_fixed_20v_2p25a]), 45)
  337. def test_calculate_pdp_100w(self):
  338. self.assertEqual(pdbuddy.calculate_pdp([self.src_fixed_5v_3a,
  339. self.src_fixed_9v_3a, self.src_fixed_15v_3a,
  340. self.src_fixed_20v_5a]), 100)
  341. self.assertEqual(pdbuddy.calculate_pdp([self.src_fixed_5v_1p5a,
  342. self.src_fixed_12v_5a, self.src_fixed_20v_5a]), 100)
  343. def test_follows_power_rules_true(self):
  344. # <= 15 W
  345. self.assertTrue(pdbuddy.follows_power_rules([]))
  346. self.assertTrue(pdbuddy.follows_power_rules([self.typec_virtual_1p5a]))
  347. self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_1p5a]))
  348. self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_3a]))
  349. self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  350. self.src_fixed_9v_1p6a]))
  351. # <= 27 W
  352. self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  353. self.src_fixed_9v_3a]))
  354. self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  355. self.src_fixed_9v_3a, self.src_fixed_15v_1p8a]))
  356. # <= 45 W
  357. self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  358. self.src_fixed_9v_3a, self.src_fixed_15v_3a]))
  359. self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  360. self.src_fixed_9v_3a, self.src_fixed_15v_3a,
  361. self.src_fixed_20v_2p25a]))
  362. # <= 100 W
  363. self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  364. self.src_fixed_9v_3a, self.src_fixed_15v_3a,
  365. self.src_fixed_20v_5a]))
  366. self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  367. self.src_fixed_9v_3a, self.src_fixed_10v_1p5a,
  368. self.src_fixed_12v_5a, self.src_fixed_15v_3a,
  369. self.src_fixed_20v_5a]))
  370. def test_follows_power_rules_false(self):
  371. # <= 15 W
  372. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_10v_1p5a]))
  373. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_5v_1p5a,
  374. self.src_fixed_10v_1p5a]))
  375. # <= 27 W
  376. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_9v_3a]))
  377. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_5v_1p5a,
  378. self.src_fixed_9v_3a]))
  379. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  380. self.src_fixed_9v_1p6a, self.src_fixed_15v_1p8a]))
  381. # <= 45 W
  382. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_20v_2p25a]))
  383. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_5v_1p5a,
  384. self.src_fixed_9v_3a, self.src_fixed_15v_3a]))
  385. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  386. self.src_fixed_9v_1p6a, self.src_fixed_15v_3a]))
  387. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  388. self.src_fixed_9v_3a, self.src_fixed_15v_1p8a,
  389. self.src_fixed_20v_2p25a]))
  390. # <= 100 W
  391. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_20v_5a]))
  392. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_5v_1p5a,
  393. self.src_fixed_9v_3a, self.src_fixed_15v_3a,
  394. self.src_fixed_20v_5a]))
  395. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  396. self.src_fixed_9v_1p6a, self.src_fixed_15v_3a,
  397. self.src_fixed_20v_5a]))
  398. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  399. self.src_fixed_9v_3a, self.src_fixed_15v_1p8a,
  400. self.src_fixed_20v_5a]))
  401. self.assertFalse(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,
  402. self.src_fixed_9v_3a, self.src_fixed_12v_5a,
  403. self.src_fixed_15v_3a, self.src_fixed_20v_2p25a]))