1
0

test_postgres.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. # -*- coding: utf-8 -*-
  2. # Import python libs
  3. from __future__ import absolute_import, unicode_literals, print_function
  4. # Import Salt Testing libs
  5. from tests.support.mixins import LoaderModuleMockMixin
  6. from tests.support.unit import TestCase
  7. from tests.support.mock import Mock, MagicMock, patch
  8. # Import salt libs
  9. import salt.modules.postgres as postgresmod
  10. import salt.states.postgres_database as postgres_database
  11. import salt.states.postgres_user as postgres_user
  12. import salt.states.postgres_group as postgres_group
  13. import salt.states.postgres_extension as postgres_extension
  14. import salt.states.postgres_schema as postgres_schema
  15. class PostgresUserTestCase(TestCase, LoaderModuleMockMixin):
  16. def setup_loader_modules(self):
  17. patcher = patch('salt.utils.path.which', Mock(return_value='/usr/bin/pgsql'))
  18. patcher.start()
  19. self.addCleanup(patcher.stop)
  20. self.salt_stub = {
  21. 'config.option': Mock(),
  22. 'cmd.run_all': Mock(),
  23. 'file.chown': Mock(),
  24. 'file.remove': Mock(),
  25. }
  26. self.addCleanup(delattr, self, 'salt_stub')
  27. return {
  28. postgres_database: {},
  29. postgres_group: {},
  30. postgres_extension: {},
  31. postgres_schema: {},
  32. postgres_user: {
  33. '__grains__': {'os_family': 'Linux'},
  34. '__salt__': self.salt_stub,
  35. '__opts__': {'test': False},
  36. }
  37. }
  38. def test_present__creation(self):
  39. # test=True
  40. with patch.dict(postgres_user.__salt__, {'postgres.role_get': Mock(return_value=None),
  41. 'postgres.user_create': MagicMock()}):
  42. with patch.dict(postgres_user.__opts__, {'test': True}):
  43. ret = postgres_user.present('foo')
  44. self.assertEqual(
  45. ret,
  46. {'comment': 'User foo is set to be created',
  47. 'changes': {}, 'name': 'foo', 'result': None}
  48. )
  49. self.assertEqual(self.salt_stub['postgres.user_create'].call_count, 0)
  50. # test=False
  51. ret = postgres_user.present('foo')
  52. self.assertEqual(
  53. ret,
  54. {'comment': 'The user foo has been created',
  55. 'changes': {'foo': 'Present'}, 'name': 'foo', 'result': True}
  56. )
  57. self.salt_stub['postgres.user_create'].assert_called_once_with(username='foo',
  58. superuser=None,
  59. encrypted=True,
  60. runas=None,
  61. inherit=None,
  62. rolepassword=None,
  63. port=None,
  64. replication=None,
  65. host=None,
  66. createroles=None,
  67. user=None,
  68. groups=None,
  69. maintenance_db=None,
  70. login=None,
  71. password=None,
  72. valid_until=None,
  73. createdb=None)
  74. def test_present__update(self):
  75. # test=True
  76. with patch.dict(postgres_user.__salt__, {'postgres.role_get': Mock(return_value={
  77. 'can create databases': False,
  78. 'can create roles': False,
  79. 'can login': False,
  80. 'can update system catalogs': False,
  81. 'connections': None,
  82. 'defaults variables': {},
  83. 'expiry time': None,
  84. 'inherits privileges': True,
  85. 'replication': False,
  86. 'superuser': False,
  87. }),
  88. 'postgres.user_update': MagicMock()}):
  89. with patch.dict(postgres_user.__opts__, {'test': True}):
  90. ret = postgres_user.present('foo', login=True, replication=False)
  91. self.assertEqual(
  92. ret,
  93. {'comment': 'User foo is set to be updated',
  94. 'changes': {'foo': {'login': True}}, 'name': 'foo', 'result': None}
  95. )
  96. self.assertEqual(self.salt_stub['postgres.user_update'].call_count, 0)
  97. # test=False
  98. ret = postgres_user.present('foo', login=True, replication=False)
  99. self.assertEqual(
  100. ret,
  101. {'comment': 'The user foo has been updated',
  102. 'changes': {'foo': {'login': True}}, 'name': 'foo', 'result': True}
  103. )
  104. self.salt_stub['postgres.user_update'].assert_called_once_with(username='foo',
  105. superuser=None,
  106. encrypted=True,
  107. runas=None,
  108. inherit=None,
  109. rolepassword=None,
  110. port=None,
  111. replication=False,
  112. host=None,
  113. createroles=None,
  114. user=None,
  115. groups=None,
  116. maintenance_db=None,
  117. login=True,
  118. password=None,
  119. valid_until=None,
  120. createdb=None)
  121. def test_present__no_update(self):
  122. # test=True
  123. with patch.dict(postgres_user.__salt__, {'postgres.role_get': Mock(return_value={
  124. 'can create databases': False,
  125. 'can create roles': False,
  126. 'can login': False,
  127. 'can update system catalogs': False,
  128. 'connections': None,
  129. 'defaults variables': {},
  130. 'expiry time': None,
  131. 'inherits privileges': True,
  132. 'replication': False,
  133. 'superuser': False,
  134. }),
  135. 'postgres.user_update': MagicMock()}):
  136. with patch.dict(postgres_user.__opts__, {'test': True}):
  137. ret = postgres_user.present('foo', login=False, replication=False)
  138. self.assertEqual(
  139. ret,
  140. {'comment': 'User foo is already present',
  141. 'changes': {}, 'name': 'foo', 'result': True}
  142. )
  143. self.assertEqual(self.salt_stub['postgres.user_update'].call_count, 0)
  144. # test=False
  145. ret = postgres_user.present('foo', login=False, replication=False)
  146. self.assertEqual(
  147. ret,
  148. {'comment': 'User foo is already present',
  149. 'changes': {}, 'name': 'foo', 'result': True}
  150. )
  151. self.assertEqual(self.salt_stub['postgres.user_update'].call_count, 0)
  152. class PostgresGroupTestCase(TestCase, LoaderModuleMockMixin):
  153. def setup_loader_modules(self):
  154. patcher = patch('salt.utils.path.which', Mock(return_value='/usr/bin/pgsql'))
  155. patcher.start()
  156. self.addCleanup(patcher.stop)
  157. self.salt_stub = {
  158. 'config.option': Mock(),
  159. 'cmd.run_all': Mock(),
  160. 'file.chown': Mock(),
  161. 'file.remove': Mock(),
  162. }
  163. self.addCleanup(delattr, self, 'salt_stub')
  164. return {
  165. postgres_database: {},
  166. postgres_user: {},
  167. postgres_extension: {},
  168. postgres_schema: {},
  169. postgres_group: {
  170. '__grains__': {'os_family': 'Linux'},
  171. '__salt__': self.salt_stub,
  172. '__opts__': {'test': False},
  173. }
  174. }
  175. def test_present__creation(self):
  176. # test=True
  177. with patch.dict(postgres_group.__salt__, {'postgres.role_get': Mock(return_value=None),
  178. 'postgres.group_create': MagicMock()}):
  179. with patch.dict(postgres_group.__opts__, {'test': True}):
  180. ret = postgres_group.present('foo')
  181. self.assertEqual(
  182. ret,
  183. {'comment': 'Group foo is set to be created',
  184. 'changes': {}, 'name': 'foo', 'result': None}
  185. )
  186. self.assertEqual(self.salt_stub['postgres.group_create'].call_count, 0)
  187. # test=False
  188. ret = postgres_group.present('foo')
  189. self.assertEqual(
  190. ret,
  191. {'comment': 'The group foo has been created',
  192. 'changes': {}, 'name': 'foo', 'result': True}
  193. )
  194. self.salt_stub['postgres.group_create'].assert_called_once_with(superuser=None,
  195. replication=None,
  196. encrypted=True,
  197. runas=None,
  198. inherit=None,
  199. rolepassword=None,
  200. port=None,
  201. groupname='foo',
  202. host=None,
  203. createroles=None,
  204. user=None,
  205. groups=None,
  206. maintenance_db=None,
  207. login=None,
  208. password=None,
  209. createdb=None)
  210. def test_present__update(self):
  211. # test=True
  212. with patch.dict(postgres_group.__salt__, {'postgres.role_get': Mock(return_value={
  213. 'can create databases': False,
  214. 'can create roles': False,
  215. 'can login': False,
  216. 'can update system catalogs': False,
  217. 'connections': None,
  218. 'defaults variables': {},
  219. 'expiry time': None,
  220. 'inherits privileges': True,
  221. 'replication': False,
  222. 'superuser': False,
  223. }),
  224. 'postgres.group_update': MagicMock()}):
  225. with patch.dict(postgres_group.__opts__, {'test': True}):
  226. ret = postgres_group.present('foo', login=True, replication=False)
  227. self.assertEqual(
  228. ret,
  229. {'comment': 'Group foo is set to be updated',
  230. 'changes': {'foo': {'login': True}}, 'name': 'foo', 'result': None}
  231. )
  232. self.assertEqual(self.salt_stub['postgres.group_update'].call_count, 0)
  233. # test=False
  234. ret = postgres_group.present('foo', login=True, replication=False)
  235. self.assertEqual(
  236. ret,
  237. {'comment': 'The group foo has been updated',
  238. 'changes': {'foo': {'login': True}}, 'name': 'foo', 'result': True}
  239. )
  240. self.salt_stub['postgres.group_update'].assert_called_once_with(superuser=None,
  241. replication=False,
  242. encrypted=True,
  243. runas=None,
  244. inherit=None,
  245. rolepassword=None,
  246. port=None,
  247. groupname='foo',
  248. host=None,
  249. createroles=None,
  250. user=None,
  251. groups=None,
  252. maintenance_db=None,
  253. login=True,
  254. password=None,
  255. createdb=None)
  256. def test_present__no_update(self):
  257. # test=True
  258. with patch.dict(postgres_group.__salt__, {'postgres.role_get': Mock(return_value={
  259. 'can create databases': False,
  260. 'can create roles': False,
  261. 'can login': False,
  262. 'can update system catalogs': False,
  263. 'connections': None,
  264. 'defaults variables': {},
  265. 'expiry time': None,
  266. 'inherits privileges': True,
  267. 'replication': False,
  268. 'superuser': False,
  269. }),
  270. 'postgres.group_update': MagicMock()}):
  271. with patch.dict(postgres_group.__opts__, {'test': True}):
  272. ret = postgres_group.present('foo', login=False, replication=False)
  273. self.assertEqual(
  274. ret,
  275. {'comment': 'Group foo is already present',
  276. 'changes': {}, 'name': 'foo', 'result': True}
  277. )
  278. self.assertEqual(self.salt_stub['postgres.group_update'].call_count, 0)
  279. # test=False
  280. ret = postgres_group.present('foo', login=False, replication=False)
  281. self.assertEqual(
  282. ret,
  283. {'comment': 'Group foo is already present',
  284. 'changes': {}, 'name': 'foo', 'result': True}
  285. )
  286. self.assertEqual(self.salt_stub['postgres.group_update'].call_count, 0)
  287. class PostgresExtensionTestCase(TestCase, LoaderModuleMockMixin):
  288. def setup_loader_modules(self):
  289. patcher = patch('salt.utils.path.which', Mock(return_value='/usr/bin/pgsql'))
  290. patcher.start()
  291. self.addCleanup(patcher.stop)
  292. self.salt_stub = {
  293. 'config.option': Mock(),
  294. 'cmd.run_all': Mock(),
  295. 'file.chown': Mock(),
  296. 'file.remove': Mock(),
  297. }
  298. self.addCleanup(delattr, self, 'salt_stub')
  299. return {
  300. postgres_database: {},
  301. postgres_user: {},
  302. postgres_group: {},
  303. postgres_schema: {},
  304. postgres_extension: {
  305. '__grains__': {'os_family': 'Linux'},
  306. '__salt__': self.salt_stub,
  307. '__opts__': {'test': False},
  308. }
  309. }
  310. def test_present_failed(self):
  311. '''
  312. scenario of creating upgrading extensions with possible schema and
  313. version specifications
  314. '''
  315. with patch.dict(postgres_extension.__salt__, {
  316. 'postgres.create_metadata': Mock(side_effect=[
  317. [postgresmod._EXTENSION_NOT_INSTALLED],
  318. [postgresmod._EXTENSION_TO_MOVE, postgresmod._EXTENSION_INSTALLED],
  319. ]),
  320. 'postgres.create_extension': Mock(side_effect=[
  321. False, False,
  322. ])}):
  323. ret = postgres_extension.present('foo')
  324. self.assertEqual(
  325. ret,
  326. {'comment': 'Failed to install extension foo',
  327. 'changes': {}, 'name': 'foo', 'result': False},
  328. )
  329. ret = postgres_extension.present('foo')
  330. self.assertEqual(
  331. ret,
  332. {'comment': 'Failed to upgrade extension foo',
  333. 'changes': {}, 'name': 'foo', 'result': False}
  334. )
  335. def test_present(self):
  336. '''
  337. scenario of creating upgrading extensions with possible schema and
  338. version specifications
  339. '''
  340. with patch.dict(postgres_extension.__salt__, {
  341. 'postgres.create_metadata': Mock(side_effect=[
  342. [postgresmod._EXTENSION_NOT_INSTALLED],
  343. [postgresmod._EXTENSION_INSTALLED],
  344. [postgresmod._EXTENSION_TO_MOVE, postgresmod._EXTENSION_INSTALLED],
  345. ]),
  346. 'postgres.create_extension': Mock(side_effect=[
  347. True, True, True,
  348. ])}):
  349. ret = postgres_extension.present('foo')
  350. self.assertEqual(
  351. ret,
  352. {'comment': 'The extension foo has been installed',
  353. 'changes': {'foo': 'Installed'}, 'name': 'foo', 'result': True}
  354. )
  355. ret = postgres_extension.present('foo')
  356. self.assertEqual(
  357. ret,
  358. {'comment': 'Extension foo is already present',
  359. 'changes': {}, 'name': 'foo', 'result': True}
  360. )
  361. ret = postgres_extension.present('foo')
  362. self.assertEqual(
  363. ret,
  364. {'comment': 'The extension foo has been upgraded',
  365. 'changes': {'foo': 'Upgraded'}, 'name': 'foo', 'result': True}
  366. )
  367. def test_presenttest(self):
  368. '''
  369. scenario of creating upgrading extensions with possible schema and
  370. version specifications
  371. '''
  372. with patch.dict(postgres_extension.__salt__, {
  373. 'postgres.create_metadata': Mock(side_effect=[
  374. [postgresmod._EXTENSION_NOT_INSTALLED],
  375. [postgresmod._EXTENSION_INSTALLED],
  376. [postgresmod._EXTENSION_TO_MOVE, postgresmod._EXTENSION_INSTALLED],
  377. ]),
  378. 'postgres.create_extension': Mock(side_effect=[
  379. True, True, True,
  380. ])}):
  381. with patch.dict(postgres_extension.__opts__, {'test': True}):
  382. ret = postgres_extension.present('foo')
  383. self.assertEqual(
  384. ret,
  385. {'comment': 'Extension foo is set to be installed',
  386. 'changes': {}, 'name': 'foo', 'result': None}
  387. )
  388. ret = postgres_extension.present('foo')
  389. self.assertEqual(
  390. ret,
  391. {'comment': "Extension foo is already present",
  392. 'changes': {}, 'name': 'foo', 'result': True}
  393. )
  394. ret = postgres_extension.present('foo')
  395. self.assertEqual(
  396. ret,
  397. {'comment': "Extension foo is set to be upgraded",
  398. 'changes': {}, 'name': 'foo', 'result': None}
  399. )
  400. def test_absent(self):
  401. '''
  402. scenario of creating upgrading extensions with possible schema and
  403. version specifications
  404. '''
  405. with patch.dict(postgres_extension.__salt__, {
  406. 'postgres.is_installed_extension': Mock(side_effect=[
  407. True, False,
  408. ]),
  409. 'postgres.drop_extension': Mock(side_effect=[
  410. True, True,
  411. ])}):
  412. ret = postgres_extension.absent('foo')
  413. self.assertEqual(
  414. ret,
  415. {'comment': 'Extension foo has been removed',
  416. 'changes': {'foo': 'Absent'}, 'name': 'foo', 'result': True}
  417. )
  418. ret = postgres_extension.absent('foo')
  419. self.assertEqual(
  420. ret,
  421. {'comment': (
  422. 'Extension foo is not present, '
  423. 'so it cannot be removed'),
  424. 'changes': {}, 'name': 'foo', 'result': True}
  425. )
  426. def test_absent_failed(self):
  427. '''
  428. scenario of creating upgrading extensions with possible schema and
  429. version specifications
  430. '''
  431. with patch.dict(postgres_extension.__opts__, {'test': False}):
  432. with patch.dict(postgres_extension.__salt__, {
  433. 'postgres.is_installed_extension': Mock(side_effect=[
  434. True, True,
  435. ]),
  436. 'postgres.drop_extension': Mock(side_effect=[
  437. False, False,
  438. ])}):
  439. ret = postgres_extension.absent('foo')
  440. self.assertEqual(
  441. ret,
  442. {'comment': 'Extension foo failed to be removed',
  443. 'changes': {}, 'name': 'foo', 'result': False}
  444. )
  445. def test_absent_failedtest(self):
  446. with patch.dict(postgres_extension.__salt__, {
  447. 'postgres.is_installed_extension': Mock(side_effect=[
  448. True, True,
  449. ]),
  450. 'postgres.drop_extension': Mock(side_effect=[
  451. False, False,
  452. ])}):
  453. with patch.dict(postgres_extension.__opts__, {'test': True}):
  454. ret = postgres_extension.absent('foo')
  455. self.assertEqual(
  456. ret,
  457. {'comment': 'Extension foo is set to be removed',
  458. 'changes': {}, 'name': 'foo', 'result': None}
  459. )
  460. class PostgresSchemaTestCase(TestCase, LoaderModuleMockMixin):
  461. def setup_loader_modules(self):
  462. patcher = patch('salt.utils.path.which', Mock(return_value='/usr/bin/pgsql'))
  463. patcher.start()
  464. self.addCleanup(patcher.stop)
  465. self.salt_stub = {
  466. 'config.option': Mock(),
  467. 'cmd.run_all': Mock(),
  468. 'file.chown': Mock(),
  469. 'file.remove': Mock(),
  470. }
  471. self.addCleanup(delattr, self, 'salt_stub')
  472. return {
  473. postgres_database: {},
  474. postgres_user: {},
  475. postgres_extension: {},
  476. postgres_group: {},
  477. postgres_schema: {
  478. '__grains__': {'os_family': 'Linux'},
  479. '__salt__': self.salt_stub,
  480. '__opts__': {'test': False},
  481. }
  482. }
  483. def test_present_creation(self):
  484. with patch.dict(postgres_schema.__salt__, {'postgres.schema_get': Mock(return_value=None),
  485. 'postgres.schema_create': MagicMock()}):
  486. ret = postgres_schema.present('dbname', 'foo')
  487. self.assertEqual(
  488. ret,
  489. {'comment': 'Schema foo has been created in database dbname',
  490. 'changes': {'foo': 'Present'},
  491. 'dbname': 'dbname',
  492. 'name': 'foo',
  493. 'result': True}
  494. )
  495. self.assertEqual(self.salt_stub['postgres.schema_create'].call_count, 1)
  496. def test_present_nocreation(self):
  497. with patch.dict(postgres_schema.__salt__, {
  498. 'postgres.schema_get': Mock(return_value={'foo':
  499. {'acl': '',
  500. 'owner': 'postgres'}
  501. }),
  502. 'postgres.schema_create': MagicMock()}):
  503. ret = postgres_schema.present('dbname', 'foo')
  504. self.assertEqual(
  505. ret,
  506. {'comment': 'Schema foo already exists in database dbname',
  507. 'changes': {},
  508. 'dbname': 'dbname',
  509. 'name': 'foo',
  510. 'result': True}
  511. )
  512. self.assertEqual(self.salt_stub['postgres.schema_create'].call_count, 0)
  513. def test_absent_remove(self):
  514. with patch.dict(postgres_schema.__salt__, {'postgres.schema_exists': Mock(return_value=True),
  515. 'postgres.schema_remove': MagicMock()}):
  516. ret = postgres_schema.absent('dbname', 'foo')
  517. self.assertEqual(
  518. ret,
  519. {'comment': 'Schema foo has been removed from database dbname',
  520. 'changes': {'foo': 'Absent'},
  521. 'dbname': 'dbname',
  522. 'name': 'foo',
  523. 'result': True}
  524. )
  525. self.assertEqual(self.salt_stub['postgres.schema_remove'].call_count, 1)
  526. def test_absent_noremove(self):
  527. with patch.dict(postgres_schema.__salt__, {'postgres.schema_exists': Mock(return_value=False),
  528. 'postgres.schema_remove': MagicMock()}):
  529. ret = postgres_schema.absent('dbname', 'foo')
  530. self.assertEqual(
  531. ret,
  532. {'comment': 'Schema foo is not present in database dbname,'
  533. ' so it cannot be removed',
  534. 'changes': {},
  535. 'dbname': 'dbname',
  536. 'name': 'foo',
  537. 'result': True}
  538. )
  539. self.assertEqual(self.salt_stub['postgres.schema_remove'].call_count, 0)