test_useradd.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. # -*- coding: utf-8 -*-
  2. """
  3. :codeauthor: Jayesh Kariya <jayeshk@saltstack.com>
  4. """
  5. # Import Python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import pytest
  8. # Import Salt Libs
  9. import salt.modules.useradd as useradd
  10. from salt.exceptions import CommandExecutionError
  11. # Import Salt Testing Libs
  12. from tests.support.mixins import LoaderModuleMockMixin
  13. from tests.support.mock import MagicMock, patch
  14. from tests.support.unit import TestCase, skipIf
  15. try:
  16. import pwd
  17. HAS_PWD = True
  18. except ImportError:
  19. HAS_PWD = False
  20. class UserAddTestCase(TestCase, LoaderModuleMockMixin):
  21. """
  22. Test cases for salt.modules.useradd
  23. """
  24. def setup_loader_modules(self):
  25. return {useradd: {}}
  26. @classmethod
  27. def setUpClass(cls):
  28. cls.mock_pwall = {
  29. "gid": 0,
  30. "groups": ["root"],
  31. "home": "/root",
  32. "name": "root",
  33. "passwd": "x",
  34. "shell": "/bin/bash",
  35. "uid": 0,
  36. "fullname": "root",
  37. "roomnumber": "",
  38. "workphone": "",
  39. "homephone": "",
  40. "other": "",
  41. }
  42. @classmethod
  43. def tearDownClass(cls):
  44. del cls.mock_pwall
  45. # 'add' function tests: 1
  46. def test_add(self):
  47. """
  48. Test for adding a user
  49. """
  50. with patch.dict(useradd.__grains__, {"kernel": "OpenBSD"}):
  51. mock_primary = MagicMock(return_value="Salt")
  52. with patch.dict(useradd.__salt__, {"file.gid_to_group": mock_primary}):
  53. mock = MagicMock(return_value={"retcode": 0})
  54. with patch.dict(useradd.__salt__, {"cmd.run_all": mock}):
  55. self.assertTrue(useradd.add("Salt"))
  56. mock = MagicMock(return_value={"retcode": 1})
  57. with patch.dict(useradd.__salt__, {"cmd.run_all": mock}):
  58. self.assertFalse(useradd.add("Salt"))
  59. # 'getent' function tests: 2
  60. @skipIf(HAS_PWD is False, "The pwd module is not available")
  61. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  62. def test_getent(self):
  63. """
  64. Test if user.getent already have a value
  65. """
  66. with patch("salt.modules.useradd.__context__", MagicMock(return_value="Salt")):
  67. self.assertTrue(useradd.getent())
  68. @skipIf(HAS_PWD is False, "The pwd module is not available")
  69. def test_getent_user(self):
  70. """
  71. Tests the return information on all users
  72. """
  73. with patch("pwd.getpwall", MagicMock(return_value=[""])):
  74. ret = [
  75. {
  76. "gid": 0,
  77. "groups": ["root"],
  78. "home": "/root",
  79. "name": "root",
  80. "passwd": "x",
  81. "shell": "/bin/bash",
  82. "uid": 0,
  83. "fullname": "root",
  84. "roomnumber": "",
  85. "workphone": "",
  86. "homephone": "",
  87. "other": "",
  88. }
  89. ]
  90. with patch(
  91. "salt.modules.useradd._format_info",
  92. MagicMock(return_value=self.mock_pwall),
  93. ):
  94. self.assertEqual(useradd.getent(), ret)
  95. # 'chuid' function tests: 1
  96. def test_chuid(self):
  97. """
  98. Test if the uid of a user change
  99. """
  100. mock = MagicMock(return_value={"uid": 11})
  101. with patch.object(useradd, "info", mock):
  102. self.assertTrue(useradd.chuid("name", 11))
  103. mock_run = MagicMock(return_value=None)
  104. with patch.dict(useradd.__salt__, {"cmd.run": mock_run}):
  105. mock = MagicMock(side_effect=[{"uid": 11}, {"uid": 11}])
  106. with patch.object(useradd, "info", mock):
  107. self.assertFalse(useradd.chuid("name", 22))
  108. with patch.dict(useradd.__salt__, {"cmd.run": mock_run}):
  109. mock = MagicMock(side_effect=[{"uid": 11}, {"uid": 22}])
  110. with patch.object(useradd, "info", mock):
  111. self.assertTrue(useradd.chuid("name", 11))
  112. # 'chgid' function tests: 1
  113. def test_chgid(self):
  114. """
  115. Test the default group of the user
  116. """
  117. mock = MagicMock(return_value={"gid": 11})
  118. with patch.object(useradd, "info", mock):
  119. self.assertTrue(useradd.chgid("name", 11))
  120. mock_run = MagicMock(return_value=None)
  121. with patch.dict(useradd.__salt__, {"cmd.run": mock_run}):
  122. mock = MagicMock(side_effect=[{"gid": 22}, {"gid": 22}])
  123. with patch.object(useradd, "info", mock):
  124. self.assertFalse(useradd.chgid("name", 11))
  125. with patch.dict(useradd.__salt__, {"cmd.run": mock_run}):
  126. mock = MagicMock(side_effect=[{"gid": 11}, {"gid": 22}])
  127. with patch.object(useradd, "info", mock):
  128. self.assertTrue(useradd.chgid("name", 11))
  129. # 'chshell' function tests: 1
  130. def test_chshell(self):
  131. """
  132. Test the default shell of user
  133. """
  134. mock = MagicMock(return_value={"shell": "/bin/bash"})
  135. with patch.object(useradd, "info", mock):
  136. self.assertTrue(useradd.chshell("name", "/bin/bash"))
  137. mock_run = MagicMock(return_value=None)
  138. with patch.dict(useradd.__salt__, {"cmd.run": mock_run}):
  139. mock = MagicMock(
  140. side_effect=[{"shell": "/bin/bash"}, {"shell": "/bin/bash"}]
  141. )
  142. with patch.object(useradd, "info", mock):
  143. self.assertFalse(useradd.chshell("name", "/usr/bash"))
  144. with patch.dict(useradd.__salt__, {"cmd.run": mock_run}):
  145. mock = MagicMock(
  146. side_effect=[{"shell": "/bin/bash"}, {"shell": "/usr/bash"}]
  147. )
  148. with patch.object(useradd, "info", mock):
  149. self.assertTrue(useradd.chshell("name", "/bin/bash"))
  150. # 'chhome' function tests: 1
  151. def test_chhome(self):
  152. """
  153. Test if home directory given is same as previous home directory
  154. """
  155. mock = MagicMock(return_value={"home": "/root"})
  156. with patch.object(useradd, "info", mock):
  157. self.assertTrue(useradd.chhome("name", "/root"))
  158. mock = MagicMock(return_value=None)
  159. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  160. mock = MagicMock(side_effect=[{"home": "/root"}, {"home": "/root"}])
  161. with patch.object(useradd, "info", mock):
  162. self.assertFalse(useradd.chhome("name", "/user"))
  163. mock = MagicMock(return_value=None)
  164. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  165. mock = MagicMock(side_effect=[{"home": "/root"}, {"home": "/root"}])
  166. with patch.object(useradd, "info", mock):
  167. self.assertTrue(useradd.chhome("name", "/root"))
  168. # 'chgroups' function tests: 1
  169. def test_chgroups(self):
  170. """
  171. Test if user groups changed
  172. """
  173. mock = MagicMock(return_value=["wheel", "root"])
  174. with patch.object(useradd, "list_groups", mock):
  175. self.assertTrue(useradd.chgroups("foo", "wheel,root"))
  176. mock = MagicMock(return_value=["wheel", "root"])
  177. with patch.object(useradd, "list_groups", mock):
  178. with patch.dict(useradd.__grains__, {"kernel": "OpenBSD"}):
  179. mock_runall = MagicMock(return_value={"retcode": False, "stderr": ""})
  180. with patch.dict(useradd.__salt__, {"cmd.run_all": mock_runall}):
  181. self.assertTrue(useradd.chgroups("foo", "wheel,test,root"))
  182. mock_runall = MagicMock(return_value={"retcode": True, "stderr": ""})
  183. with patch.dict(useradd.__salt__, {"cmd.run_all": mock_runall}):
  184. self.assertFalse(useradd.chgroups("foo", "wheel,test,root"))
  185. # 'chfullname' function tests: 1
  186. def test_chfullname(self):
  187. """
  188. Test if the user's Full Name is changed
  189. """
  190. mock = MagicMock(return_value=False)
  191. with patch.object(useradd, "_get_gecos", mock):
  192. self.assertFalse(useradd.chfullname("Salt", "SaltStack"))
  193. mock = MagicMock(return_value={"fullname": "SaltStack"})
  194. with patch.object(useradd, "_get_gecos", mock):
  195. self.assertTrue(useradd.chfullname("Salt", "SaltStack"))
  196. mock = MagicMock(return_value={"fullname": "SaltStack"})
  197. with patch.object(useradd, "_get_gecos", mock):
  198. mock = MagicMock(return_value=None)
  199. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  200. mock = MagicMock(return_value={"fullname": "SaltStack2"})
  201. with patch.object(useradd, "info", mock):
  202. self.assertFalse(useradd.chfullname("Salt", "SaltStack1"))
  203. mock = MagicMock(return_value={"fullname": "SaltStack2"})
  204. with patch.object(useradd, "_get_gecos", mock):
  205. mock = MagicMock(return_value=None)
  206. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  207. mock = MagicMock(return_value={"fullname": "SaltStack2"})
  208. with patch.object(useradd, "info", mock):
  209. self.assertFalse(useradd.chfullname("Salt", "SaltStack1"))
  210. # 'chroomnumber' function tests: 1
  211. def test_chroomnumber(self):
  212. """
  213. Test if the user's Room Number is changed
  214. """
  215. mock = MagicMock(return_value=False)
  216. with patch.object(useradd, "_get_gecos", mock):
  217. self.assertFalse(useradd.chroomnumber("salt", 1))
  218. mock = MagicMock(return_value={"roomnumber": "1"})
  219. with patch.object(useradd, "_get_gecos", mock):
  220. self.assertTrue(useradd.chroomnumber("salt", 1))
  221. mock = MagicMock(return_value={"roomnumber": "2"})
  222. with patch.object(useradd, "_get_gecos", mock):
  223. mock = MagicMock(return_value=None)
  224. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  225. mock = MagicMock(return_value={"roomnumber": "3"})
  226. with patch.object(useradd, "info", mock):
  227. self.assertFalse(useradd.chroomnumber("salt", 1))
  228. mock = MagicMock(return_value={"roomnumber": "3"})
  229. with patch.object(useradd, "_get_gecos", mock):
  230. mock = MagicMock(return_value=None)
  231. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  232. mock = MagicMock(return_value={"roomnumber": "3"})
  233. with patch.object(useradd, "info", mock):
  234. self.assertFalse(useradd.chroomnumber("salt", 1))
  235. # 'chworkphone' function tests: 1
  236. def test_chworkphone(self):
  237. """
  238. Test if the user's Work Phone is changed
  239. """
  240. mock = MagicMock(return_value=False)
  241. with patch.object(useradd, "_get_gecos", mock):
  242. self.assertFalse(useradd.chworkphone("salt", 1))
  243. mock = MagicMock(return_value={"workphone": "1"})
  244. with patch.object(useradd, "_get_gecos", mock):
  245. self.assertTrue(useradd.chworkphone("salt", 1))
  246. mock = MagicMock(return_value={"workphone": "2"})
  247. with patch.object(useradd, "_get_gecos", mock):
  248. mock = MagicMock(return_value=None)
  249. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  250. mock = MagicMock(return_value={"workphone": "3"})
  251. with patch.object(useradd, "info", mock):
  252. self.assertFalse(useradd.chworkphone("salt", 1))
  253. mock = MagicMock(return_value={"workphone": "3"})
  254. with patch.object(useradd, "_get_gecos", mock):
  255. mock = MagicMock(return_value=None)
  256. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  257. mock = MagicMock(return_value={"workphone": "3"})
  258. with patch.object(useradd, "info", mock):
  259. self.assertFalse(useradd.chworkphone("salt", 1))
  260. # 'chhomephone' function tests: 1
  261. def test_chhomephone(self):
  262. """
  263. Test if the user's Home Phone is changed
  264. """
  265. mock = MagicMock(return_value=False)
  266. with patch.object(useradd, "_get_gecos", mock):
  267. self.assertFalse(useradd.chhomephone("salt", 1))
  268. mock = MagicMock(return_value={"homephone": "1"})
  269. with patch.object(useradd, "_get_gecos", mock):
  270. self.assertTrue(useradd.chhomephone("salt", 1))
  271. mock = MagicMock(return_value={"homephone": "2"})
  272. with patch.object(useradd, "_get_gecos", mock):
  273. mock = MagicMock(return_value=None)
  274. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  275. mock = MagicMock(return_value={"homephone": "3"})
  276. with patch.object(useradd, "info", mock):
  277. self.assertFalse(useradd.chhomephone("salt", 1))
  278. mock = MagicMock(return_value={"homephone": "3"})
  279. with patch.object(useradd, "_get_gecos", mock):
  280. mock = MagicMock(return_value=None)
  281. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  282. mock = MagicMock(return_value={"homephone": "3"})
  283. with patch.object(useradd, "info", mock):
  284. self.assertFalse(useradd.chhomephone("salt", 1))
  285. # 'chother' function tests: 1
  286. def test_chother(self):
  287. """
  288. Test if the user's other GECOS attribute is changed
  289. """
  290. mock = MagicMock(return_value=False)
  291. with patch.object(useradd, "_get_gecos", mock):
  292. self.assertFalse(useradd.chother("salt", 1))
  293. mock = MagicMock(return_value={"other": "foobar"})
  294. with patch.object(useradd, "_get_gecos", mock):
  295. self.assertTrue(useradd.chother("salt", "foobar"))
  296. mock = MagicMock(return_value={"other": "foobar2"})
  297. with patch.object(useradd, "_get_gecos", mock):
  298. mock = MagicMock(return_value=None)
  299. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  300. mock = MagicMock(return_value={"other": "foobar3"})
  301. with patch.object(useradd, "info", mock):
  302. self.assertFalse(useradd.chother("salt", "foobar"))
  303. mock = MagicMock(return_value={"other": "foobar3"})
  304. with patch.object(useradd, "_get_gecos", mock):
  305. mock = MagicMock(return_value=None)
  306. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  307. mock = MagicMock(return_value={"other": "foobar3"})
  308. with patch.object(useradd, "info", mock):
  309. self.assertFalse(useradd.chother("salt", "foobar"))
  310. # 'info' function tests: 1
  311. @skipIf(HAS_PWD is False, "The pwd module is not available")
  312. def test_info(self):
  313. """
  314. Test the user information
  315. """
  316. self.assertEqual(useradd.info("username-that-doesnt-exist"), {})
  317. mock = MagicMock(
  318. return_value=pwd.struct_passwd(
  319. (
  320. "_TEST_GROUP",
  321. "*",
  322. 83,
  323. 83,
  324. "AMaViS Daemon",
  325. "/var/virusmails",
  326. "/usr/bin/false",
  327. )
  328. )
  329. )
  330. with patch.object(pwd, "getpwnam", mock):
  331. self.assertEqual(
  332. useradd.info("username-that-doesnt-exist")["name"], "_TEST_GROUP"
  333. )
  334. # 'list_groups' function tests: 1
  335. def test_list_groups(self):
  336. """
  337. Test if it return a list of groups the named user belongs to
  338. """
  339. with patch("salt.utils.user.get_group_list", MagicMock(return_value="Salt")):
  340. self.assertEqual(useradd.list_groups("name"), "Salt")
  341. # 'list_users' function tests: 1
  342. @skipIf(HAS_PWD is False, "The pwd module is not available")
  343. def test_list_users(self):
  344. """
  345. Test if it returns a list of all users
  346. """
  347. self.assertTrue(useradd.list_users())
  348. # 'list_users' function tests: 1
  349. def test_rename(self):
  350. """
  351. Test if the username for a named user changed
  352. """
  353. mock = MagicMock(return_value=False)
  354. with patch.object(useradd, "info", mock):
  355. self.assertRaises(CommandExecutionError, useradd.rename, "salt", 1)
  356. mock = MagicMock(return_value=True)
  357. with patch.object(useradd, "info", mock):
  358. self.assertRaises(CommandExecutionError, useradd.rename, "salt", 1)
  359. mock = MagicMock(return_value=None)
  360. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  361. mock = MagicMock(side_effect=[False, {"name": ""}, {"name": "salt"}])
  362. with patch.object(useradd, "info", mock):
  363. self.assertTrue(useradd.rename("name", "salt"))
  364. mock = MagicMock(return_value=None)
  365. with patch.dict(useradd.__salt__, {"cmd.run": mock}):
  366. mock = MagicMock(side_effect=[False, {"name": ""}, {"name": ""}])
  367. with patch.object(useradd, "info", mock):
  368. self.assertFalse(useradd.rename("salt", "salt"))
  369. def test_build_gecos_field(self):
  370. """
  371. Test if gecos fields are built correctly (removing trailing commas)
  372. """
  373. test_gecos = {
  374. "fullname": "Testing",
  375. "roomnumber": 1234,
  376. "workphone": 22222,
  377. "homephone": 99999,
  378. }
  379. expected_gecos_fields = "Testing,1234,22222,99999"
  380. self.assertEqual(useradd._build_gecos(test_gecos), expected_gecos_fields)
  381. test_gecos.pop("roomnumber")
  382. test_gecos.pop("workphone")
  383. expected_gecos_fields = "Testing,,,99999"
  384. self.assertEqual(useradd._build_gecos(test_gecos), expected_gecos_fields)
  385. test_gecos.pop("homephone")
  386. expected_gecos_fields = "Testing"
  387. self.assertEqual(useradd._build_gecos(test_gecos), expected_gecos_fields)