test_adb.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. # coding: utf-8
  2. # Python libs
  3. from __future__ import absolute_import
  4. # Salt libs
  5. import salt.beacons.adb as adb
  6. from tests.support.mixins import LoaderModuleMockMixin
  7. from tests.support.mock import Mock, patch
  8. # Salt testing libs
  9. from tests.support.unit import TestCase
  10. class ADBBeaconTestCase(TestCase, LoaderModuleMockMixin):
  11. """
  12. Test case for salt.beacons.adb
  13. """
  14. def setup_loader_modules(self):
  15. return {adb: {"last_state": {}, "last_state_extra": {"no_devices": False}}}
  16. def test_no_adb_command(self):
  17. with patch("salt.utils.path.which") as mock:
  18. mock.return_value = None
  19. ret = adb.__virtual__()
  20. mock.assert_called_once_with("adb")
  21. self.assertFalse(ret)
  22. def test_with_adb_command(self):
  23. with patch("salt.utils.path.which") as mock:
  24. mock.return_value = "/usr/bin/adb"
  25. ret = adb.__virtual__()
  26. mock.assert_called_once_with("adb")
  27. self.assertEqual(ret, "adb")
  28. def test_non_list_config(self):
  29. config = {}
  30. ret = adb.validate(config)
  31. self.assertEqual(ret, (False, "Configuration for adb beacon must be a list."))
  32. def test_empty_config(self):
  33. config = [{}]
  34. ret = adb.validate(config)
  35. self.assertEqual(
  36. ret, (False, "Configuration for adb beacon must include a states array.")
  37. )
  38. def test_invalid_states(self):
  39. config = [{"states": ["Random", "Failings"]}]
  40. ret = adb.validate(config)
  41. self.assertEqual(
  42. ret,
  43. (
  44. False,
  45. "Need a one of the following"
  46. " adb states: offline, bootloader,"
  47. " device, host, recovery, no"
  48. " permissions, sideload,"
  49. " unauthorized, unknown, missing",
  50. ),
  51. )
  52. def test_device_state(self):
  53. config = [{"states": ["device"]}]
  54. mock = Mock(return_value="List of devices attached\nHTC\tdevice",)
  55. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  56. ret = adb.validate(config)
  57. self.assertEqual(ret, (True, "Valid beacon configuration"))
  58. ret = adb.beacon(config)
  59. self.assertEqual(
  60. ret, [{"device": "HTC", "state": "device", "tag": "device"}]
  61. )
  62. def test_device_state_change(self):
  63. config = [{"states": ["offline"]}]
  64. out = [
  65. "List of devices attached\nHTC\tdevice",
  66. "List of devices attached\nHTC\toffline",
  67. ]
  68. mock = Mock(side_effect=out)
  69. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  70. ret = adb.validate(config)
  71. self.assertEqual(ret, (True, "Valid beacon configuration"))
  72. ret = adb.beacon(config)
  73. self.assertEqual(ret, [])
  74. ret = adb.beacon(config)
  75. self.assertEqual(
  76. ret, [{"device": "HTC", "state": "offline", "tag": "offline"}]
  77. )
  78. def test_multiple_devices(self):
  79. config = [{"states": ["offline", "device"]}]
  80. out = [
  81. "List of devices attached\nHTC\tdevice",
  82. "List of devices attached\nHTC\toffline\nNexus\tdevice",
  83. ]
  84. mock = Mock(side_effect=out)
  85. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  86. ret = adb.validate(config)
  87. self.assertEqual(ret, (True, "Valid beacon configuration"))
  88. ret = adb.beacon(config)
  89. self.assertEqual(
  90. ret, [{"device": "HTC", "state": "device", "tag": "device"}]
  91. )
  92. ret = adb.beacon(config)
  93. self.assertEqual(
  94. ret,
  95. [
  96. {"device": "HTC", "state": "offline", "tag": "offline"},
  97. {"device": "Nexus", "state": "device", "tag": "device"},
  98. ],
  99. )
  100. def test_no_devices_with_different_states(self):
  101. config = [{"states": ["offline"], "no_devices_event": True}]
  102. mock = Mock(return_value="List of devices attached\nHTC\tdevice")
  103. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  104. ret = adb.validate(config)
  105. self.assertEqual(ret, (True, "Valid beacon configuration"))
  106. ret = adb.beacon(config)
  107. self.assertEqual(ret, [])
  108. def test_no_devices_no_repeat(self):
  109. config = [{"states": ["offline", "device"], "no_devices_event": True}]
  110. out = [
  111. "List of devices attached\nHTC\tdevice",
  112. "List of devices attached",
  113. "List of devices attached",
  114. ]
  115. mock = Mock(side_effect=out)
  116. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  117. ret = adb.validate(config)
  118. self.assertEqual(ret, (True, "Valid beacon configuration"))
  119. ret = adb.beacon(config)
  120. self.assertEqual(
  121. ret, [{"device": "HTC", "state": "device", "tag": "device"}]
  122. )
  123. ret = adb.beacon(config)
  124. self.assertEqual(ret, [{"tag": "no_devices"}])
  125. ret = adb.beacon(config)
  126. self.assertEqual(ret, [])
  127. def test_no_devices(self):
  128. config = [{"states": ["offline", "device"], "no_devices_event": True}]
  129. out = ["List of devices attached", "List of devices attached"]
  130. mock = Mock(side_effect=out)
  131. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  132. ret = adb.validate(config)
  133. self.assertEqual(ret, (True, "Valid beacon configuration"))
  134. ret = adb.beacon(config)
  135. self.assertEqual(ret, [{"tag": "no_devices"}])
  136. ret = adb.beacon(config)
  137. self.assertEqual(ret, [])
  138. def test_device_missing(self):
  139. config = [{"states": ["device", "missing"]}]
  140. out = [
  141. "List of devices attached\nHTC\tdevice",
  142. "List of devices attached",
  143. "List of devices attached\nHTC\tdevice",
  144. "List of devices attached\nHTC\tdevice",
  145. ]
  146. mock = Mock(side_effect=out)
  147. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  148. ret = adb.validate(config)
  149. self.assertEqual(ret, (True, "Valid beacon configuration"))
  150. ret = adb.beacon(config)
  151. self.assertEqual(
  152. ret, [{"device": "HTC", "state": "device", "tag": "device"}]
  153. )
  154. ret = adb.beacon(config)
  155. self.assertEqual(
  156. ret, [{"device": "HTC", "state": "missing", "tag": "missing"}]
  157. )
  158. ret = adb.beacon(config)
  159. self.assertEqual(
  160. ret, [{"device": "HTC", "state": "device", "tag": "device"}]
  161. )
  162. ret = adb.beacon(config)
  163. self.assertEqual(ret, [])
  164. def test_with_startup(self):
  165. config = [{"states": ["device"]}]
  166. mock = Mock(
  167. return_value="* daemon started successfully *\nList of devices attached\nHTC\tdevice",
  168. )
  169. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  170. ret = adb.validate(config)
  171. self.assertEqual(ret, (True, "Valid beacon configuration"))
  172. ret = adb.beacon(config)
  173. self.assertEqual(
  174. ret, [{"device": "HTC", "state": "device", "tag": "device"}]
  175. )
  176. def test_with_user(self):
  177. config = [{"states": ["device"], "user": "fred"}]
  178. mock = Mock(
  179. return_value="* daemon started successfully *\nList of devices attached\nHTC\tdevice"
  180. )
  181. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  182. ret = adb.validate(config)
  183. self.assertEqual(ret, (True, "Valid beacon configuration"))
  184. ret = adb.beacon(config)
  185. mock.assert_called_once_with("adb devices", runas="fred")
  186. self.assertEqual(
  187. ret, [{"device": "HTC", "state": "device", "tag": "device"}]
  188. )
  189. def test_device_low_battery(self):
  190. config = [{"states": ["device"], "battery_low": 30}]
  191. out = [
  192. "List of devices attached\nHTC\tdevice",
  193. "25",
  194. ]
  195. mock = Mock(side_effect=out)
  196. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  197. ret = adb.validate(config)
  198. self.assertEqual(ret, (True, "Valid beacon configuration"))
  199. ret = adb.beacon(config)
  200. self.assertEqual(
  201. ret,
  202. [
  203. {"device": "HTC", "state": "device", "tag": "device"},
  204. {"device": "HTC", "battery_level": 25, "tag": "battery_low"},
  205. ],
  206. )
  207. def test_device_no_repeat(self):
  208. config = [{"states": ["device"], "battery_low": 30}]
  209. out = [
  210. "List of devices attached\nHTC\tdevice",
  211. "25",
  212. "List of devices attached\nHTC\tdevice",
  213. "25",
  214. ]
  215. mock = Mock(side_effect=out)
  216. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  217. ret = adb.validate(config)
  218. self.assertEqual(ret, (True, "Valid beacon configuration"))
  219. ret = adb.beacon(config)
  220. self.assertEqual(
  221. ret,
  222. [
  223. {"device": "HTC", "state": "device", "tag": "device"},
  224. {"device": "HTC", "battery_level": 25, "tag": "battery_low"},
  225. ],
  226. )
  227. ret = adb.beacon(config)
  228. self.assertEqual(ret, [])
  229. def test_device_no_repeat_capacity_increase(self):
  230. config = [{"states": ["device"], "battery_low": 75}]
  231. out = [
  232. "List of devices attached\nHTC\tdevice",
  233. "25",
  234. "List of devices attached\nHTC\tdevice",
  235. "30",
  236. ]
  237. mock = Mock(side_effect=out)
  238. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  239. ret = adb.validate(config)
  240. self.assertEqual(ret, (True, "Valid beacon configuration"))
  241. ret = adb.beacon(config)
  242. self.assertEqual(
  243. ret,
  244. [
  245. {"device": "HTC", "state": "device", "tag": "device"},
  246. {"device": "HTC", "battery_level": 25, "tag": "battery_low"},
  247. ],
  248. )
  249. ret = adb.beacon(config)
  250. self.assertEqual(ret, [])
  251. def test_device_no_repeat_with_not_found_state(self):
  252. config = [{"states": ["offline"], "battery_low": 30}]
  253. out = [
  254. "List of devices attached\nHTC\tdevice",
  255. "25",
  256. "List of devices attached\nHTC\tdevice",
  257. "25",
  258. ]
  259. mock = Mock(side_effect=out)
  260. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  261. ret = adb.validate(config)
  262. self.assertEqual(ret, (True, "Valid beacon configuration"))
  263. ret = adb.beacon(config)
  264. self.assertEqual(
  265. ret, [{"device": "HTC", "battery_level": 25, "tag": "battery_low"}]
  266. )
  267. ret = adb.beacon(config)
  268. self.assertEqual(ret, [])
  269. def test_device_battery_charged(self):
  270. config = [{"states": ["device"], "battery_low": 30}]
  271. out = [
  272. "List of devices attached\nHTC\tdevice",
  273. "100",
  274. ]
  275. mock = Mock(side_effect=out)
  276. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  277. ret = adb.validate(config)
  278. self.assertEqual(ret, (True, "Valid beacon configuration"))
  279. ret = adb.beacon(config)
  280. self.assertEqual(
  281. ret, [{"device": "HTC", "state": "device", "tag": "device"}]
  282. )
  283. def test_device_low_battery_equal(self):
  284. config = [{"states": ["device"], "battery_low": 25}]
  285. out = [
  286. "List of devices attached\nHTC\tdevice",
  287. "25",
  288. ]
  289. mock = Mock(side_effect=out)
  290. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  291. ret = adb.validate(config)
  292. self.assertEqual(ret, (True, "Valid beacon configuration"))
  293. ret = adb.beacon(config)
  294. self.assertEqual(
  295. ret,
  296. [
  297. {"device": "HTC", "state": "device", "tag": "device"},
  298. {"device": "HTC", "battery_level": 25, "tag": "battery_low"},
  299. ],
  300. )
  301. def test_device_battery_not_found(self):
  302. config = [{"states": ["device"], "battery_low": 25}]
  303. out = [
  304. "List of devices attached\nHTC\tdevice",
  305. "/system/bin/sh: cat: /sys/class/power_supply/*/capacity: No such file or directory",
  306. ]
  307. mock = Mock(side_effect=out)
  308. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  309. ret = adb.validate(config)
  310. self.assertEqual(ret, (True, "Valid beacon configuration"))
  311. ret = adb.beacon(config)
  312. self.assertEqual(
  313. ret, [{"device": "HTC", "state": "device", "tag": "device"}]
  314. )
  315. def test_device_repeat_multi(self):
  316. config = [{"states": ["offline"], "battery_low": 35}]
  317. out = [
  318. "List of devices attached\nHTC\tdevice",
  319. "25",
  320. "List of devices attached\nHTC\tdevice",
  321. "40",
  322. "List of devices attached\nHTC\tdevice",
  323. "25",
  324. "List of devices attached\nHTC\tdevice",
  325. "80",
  326. ]
  327. mock = Mock(side_effect=out)
  328. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  329. ret = adb.validate(config)
  330. self.assertEqual(ret, (True, "Valid beacon configuration"))
  331. ret = adb.beacon(config)
  332. self.assertEqual(
  333. ret, [{"device": "HTC", "battery_level": 25, "tag": "battery_low"}]
  334. )
  335. ret = adb.beacon(config)
  336. self.assertEqual(ret, [])
  337. ret = adb.beacon(config)
  338. self.assertEqual(
  339. ret, [{"device": "HTC", "battery_level": 25, "tag": "battery_low"}]
  340. )
  341. ret = adb.beacon(config)
  342. self.assertEqual(ret, [])
  343. def test_weird_batteries(self):
  344. config = [{"states": ["device"], "battery_low": 25}]
  345. out = [
  346. "List of devices attached\nHTC\tdevice",
  347. "-9000",
  348. ]
  349. mock = Mock(side_effect=out)
  350. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  351. ret = adb.validate(config)
  352. self.assertEqual(ret, (True, "Valid beacon configuration"))
  353. ret = adb.beacon(config)
  354. self.assertEqual(
  355. ret, [{"device": "HTC", "state": "device", "tag": "device"}]
  356. )
  357. def test_multiple_batteries(self):
  358. config = [{"states": ["device"], "battery_low": 30}]
  359. out = [
  360. "List of devices attached\nHTC\tdevice",
  361. "25\n40",
  362. ]
  363. mock = Mock(side_effect=out)
  364. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  365. ret = adb.validate(config)
  366. self.assertEqual(ret, (True, "Valid beacon configuration"))
  367. ret = adb.beacon(config)
  368. self.assertEqual(
  369. ret,
  370. [
  371. {"device": "HTC", "state": "device", "tag": "device"},
  372. {"device": "HTC", "battery_level": 25, "tag": "battery_low"},
  373. ],
  374. )
  375. def test_multiple_low_batteries(self):
  376. config = [{"states": ["device"], "battery_low": 30}]
  377. out = [
  378. "List of devices attached\nHTC\tdevice",
  379. "25\n14",
  380. ]
  381. mock = Mock(side_effect=out)
  382. with patch.dict(adb.__salt__, {"cmd.run": mock}):
  383. ret = adb.validate(config)
  384. self.assertEqual(ret, (True, "Valid beacon configuration"))
  385. ret = adb.beacon(config)
  386. self.assertEqual(
  387. ret,
  388. [
  389. {"device": "HTC", "state": "device", "tag": "device"},
  390. {"device": "HTC", "battery_level": 25, "tag": "battery_low"},
  391. ],
  392. )