install_spec.rb 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. require 'spec_helper_system'
  2. describe 'install:' do
  3. after :all do
  4. # Cleanup after tests have ran
  5. puppet_apply("class { 'postgresql::server': ensure => absent }") do |r|
  6. r.exit_code.should_not == 1
  7. end
  8. end
  9. it 'test postgresql::server' do
  10. pp = <<-EOS
  11. class { 'postgresql::server': }
  12. EOS
  13. puppet_apply(pp) do |r|
  14. r.exit_code.should_not == 1
  15. end
  16. puppet_apply(pp) do |r|
  17. r.exit_code.should be_zero
  18. end
  19. end
  20. describe 'postgresql::db' do
  21. it 'should idempotently create a db that we can connect to' do
  22. begin
  23. pp = <<-EOS
  24. $db = 'postgresql_test_db'
  25. include postgresql::server
  26. postgresql::db { $db:
  27. user => $db,
  28. password => $db,
  29. }
  30. EOS
  31. puppet_apply(pp) do |r|
  32. r.exit_code.should_not == 1
  33. end
  34. puppet_apply(pp) do |r|
  35. r.exit_code.should == 0
  36. end
  37. psql('--command="select datname from pg_database" postgresql_test_db') do |r|
  38. r.stdout.should =~ /postgresql_test_db/
  39. r.stderr.should be_empty
  40. r.exit_code.should == 0
  41. end
  42. ensure
  43. psql('--command="drop database postgresql_test_db" postgres')
  44. end
  45. end
  46. it 'should take a locale parameter' do
  47. pending('no support for locale parameter with centos 5', :if => (node.facts['osfamily'] == 'RedHat' and node.facts['lsbmajdistrelease'] == '5'))
  48. begin
  49. pp = <<-EOS
  50. class { 'postgresql::server': }
  51. if($::operatingsystem == 'Debian') {
  52. # Need to make sure the correct locale is installed first
  53. file { '/etc/locale.gen':
  54. content => "en_US ISO-8859-1\nen_NG UTF-8\n",
  55. }~>
  56. exec { '/usr/sbin/locale-gen':
  57. logoutput => true,
  58. refreshonly => true,
  59. }
  60. }
  61. postgresql::db { 'test1':
  62. user => 'test1',
  63. password => 'test1',
  64. charset => 'UTF8',
  65. locale => 'en_NG',
  66. }
  67. EOS
  68. puppet_apply(pp) do |r|
  69. r.exit_code.should_not == 1
  70. end
  71. puppet_apply(pp) do |r|
  72. r.exit_code.should == 0
  73. end
  74. psql('-c "show lc_ctype" test1') do |r|
  75. r.stdout.should =~ /en_NG/
  76. end
  77. psql('-c "show lc_collate" test1') do |r|
  78. r.stdout.should =~ /en_NG/
  79. end
  80. ensure
  81. psql('--command="drop database test1" postgres')
  82. end
  83. end
  84. end
  85. describe 'postgresql::psql' do
  86. it 'should work but emit a deprecation warning' do
  87. pp = <<-EOS
  88. include postgresql::server
  89. postgresql::psql { 'foobar':
  90. db => 'postgres',
  91. user => 'postgres',
  92. command => 'select * from pg_database limit 1',
  93. unless => 'select 1 where 1=1',
  94. require => Class['postgresql::server'],
  95. }
  96. EOS
  97. puppet_apply(pp) do |r|
  98. r.exit_code.should_not == 1
  99. r.stdout.should =~ /postgresql::psql is deprecated/
  100. end
  101. puppet_apply(pp) do |r|
  102. r.exit_code.should == 2
  103. r.stdout.should =~ /postgresql::psql is deprecated/
  104. end
  105. end
  106. end
  107. describe 'postgresql_psql' do
  108. it 'should run some SQL when the unless query returns no rows' do
  109. pp = <<-EOS
  110. include postgresql::server
  111. postgresql_psql { 'foobar':
  112. db => 'postgres',
  113. psql_user => 'postgres',
  114. command => 'select 1',
  115. unless => 'select 1 where 1=2',
  116. require => Class['postgresql::server'],
  117. }
  118. EOS
  119. puppet_apply(pp) do |r|
  120. r.exit_code.should_not == 1
  121. end
  122. puppet_apply(pp) do |r|
  123. r.exit_code.should == 2
  124. end
  125. end
  126. it 'should not run SQL when the unless query returns rows' do
  127. pp = <<-EOS
  128. include postgresql::server
  129. postgresql_psql { 'foobar':
  130. db => 'postgres',
  131. psql_user => 'postgres',
  132. command => 'select * from pg_database limit 1',
  133. unless => 'select 1 where 1=1',
  134. require => Class['postgresql::server'],
  135. }
  136. EOS
  137. puppet_apply(pp) do |r|
  138. r.exit_code.should_not == 1
  139. end
  140. puppet_apply(pp) do |r|
  141. r.exit_code.should be_zero
  142. end
  143. end
  144. end
  145. describe 'postgresql::user' do
  146. it 'should idempotently create a user who can log in' do
  147. pp = <<-EOS
  148. $user = "postgresql_test_user"
  149. $password = "postgresql_test_password"
  150. include postgresql::server
  151. # Since we are not testing pg_hba or any of that, make a local user for ident auth
  152. user { $user:
  153. ensure => present,
  154. }
  155. postgresql::database_user { $user:
  156. password_hash => postgresql_password($user, $password),
  157. require => [ Class['postgresql::server'],
  158. User[$user] ],
  159. }
  160. EOS
  161. puppet_apply(pp) do |r|
  162. r.exit_code.should_not == 1
  163. end
  164. puppet_apply(pp) do |r|
  165. r.exit_code.should be_zero
  166. end
  167. # Check that the user can log in
  168. psql('--command="select datname from pg_database" postgres', 'postgresql_test_user') do |r|
  169. r.stdout.should =~ /template1/
  170. r.stderr.should be_empty
  171. r.exit_code.should == 0
  172. end
  173. end
  174. end
  175. describe 'postgresql::grant' do
  176. it 'should grant access so a user can create in a database' do
  177. begin
  178. pp = <<-EOS
  179. $db = 'postgres'
  180. $user = 'psql_grant_tester'
  181. $password = 'psql_grant_pw'
  182. include postgresql::server
  183. # Since we are not testing pg_hba or any of that, make a local user for ident auth
  184. user { $user:
  185. ensure => present,
  186. }
  187. postgresql::database_user { $user:
  188. password_hash => postgresql_password($user, $password),
  189. require => [ Class['postgresql::server'],
  190. User[$user] ],
  191. }
  192. postgresql::database { $db:
  193. require => Class['postgresql::server'],
  194. }
  195. postgresql::database_grant { 'grant create test':
  196. privilege => 'CREATE',
  197. db => $db,
  198. role => $user,
  199. require => [ Postgresql::Database[$db],
  200. Postgresql::Database_user[$user] ],
  201. }
  202. EOS
  203. puppet_apply(pp) do |r|
  204. r.exit_code.should_not == 1
  205. end
  206. puppet_apply(pp) do |r|
  207. r.exit_code.should be_zero
  208. end
  209. # Check that the user can create a table in the database
  210. psql('--command="create table foo (foo int)" postgres', 'psql_grant_tester') do |r|
  211. r.stdout.should =~ /CREATE TABLE/
  212. r.stderr.should be_empty
  213. r.exit_code.should == 0
  214. end
  215. ensure
  216. psql('--command="drop table foo" postgres', 'psql_grant_tester')
  217. end
  218. end
  219. end
  220. describe 'postgresql::validate_db_connections' do
  221. it 'should run puppet with no changes declared if database connectivity works' do
  222. pp = <<-EOS
  223. $db = 'foo'
  224. include postgresql::server
  225. postgresql::db { $db:
  226. user => $db,
  227. password => $db,
  228. }
  229. EOS
  230. puppet_apply(pp) do |r|
  231. r.exit_code.should_not == 1
  232. end
  233. puppet_apply(pp) do |r|
  234. r.exit_code.should be_zero
  235. end
  236. pp = <<-EOS
  237. postgresql::validate_db_connection { 'foo':
  238. database_host => 'localhost',
  239. database_name => 'foo',
  240. database_username => 'foo',
  241. database_password => 'foo',
  242. }
  243. EOS
  244. puppet_apply(pp) do |r|
  245. r.exit_code.should be_zero
  246. end
  247. end
  248. it 'should fail catalogue if database connectivity fails' do
  249. pp = <<-EOS
  250. postgresql::validate_db_connection { 'foobarbaz':
  251. database_host => 'localhost',
  252. database_name => 'foobarbaz',
  253. database_username => 'foobarbaz',
  254. database_password => 'foobarbaz',
  255. }
  256. EOS
  257. puppet_apply(pp) do |r|
  258. r.exit_code.should == 4
  259. end
  260. end
  261. end
  262. describe 'postgresql::tablespace' do
  263. it 'should idempotently create tablespaces and databases that are using them' do
  264. pp = <<-EOS
  265. include postgresql::server
  266. file { '/tmp/pg_tablespaces':
  267. ensure => 'directory',
  268. owner => 'postgres',
  269. group => 'postgres',
  270. mode => '0700',
  271. }~>
  272. # This works around rubies that lack Selinux support, I'm looking at you RHEL5
  273. exec { "chcon -u system_u -r object_r -t postgresql_db_t /tmp/pg_tablespaces":
  274. refreshonly => true,
  275. path => "/bin:/usr/bin",
  276. onlyif => "which chcon",
  277. before => File["/tmp/pg_tablespaces/space1", "/tmp/pg_tablespaces/space2"]
  278. }
  279. postgresql::tablespace{ 'tablespace1':
  280. location => '/tmp/pg_tablespaces/space1',
  281. require => [Class['postgresql::server'], File['/tmp/pg_tablespaces']],
  282. }
  283. postgresql::database{ 'tablespacedb1':
  284. charset => 'utf8',
  285. tablespace => 'tablespace1',
  286. require => Postgresql::Tablespace['tablespace1'],
  287. }
  288. postgresql::db{ 'tablespacedb2':
  289. user => 'dbuser2',
  290. password => 'dbuser2',
  291. tablespace => 'tablespace1',
  292. require => Postgresql::Tablespace['tablespace1'],
  293. }
  294. postgresql::database_user{ 'spcuser':
  295. password_hash => postgresql_password('spcuser', 'spcuser'),
  296. require => Class['postgresql::server'],
  297. }
  298. postgresql::tablespace{ 'tablespace2':
  299. location => '/tmp/pg_tablespaces/space2',
  300. owner => 'spcuser',
  301. require => [Postgresql::Database_user['spcuser'], File['/tmp/pg_tablespaces']],
  302. }
  303. postgresql::database{ 'tablespacedb3':
  304. charset => 'utf8',
  305. tablespace => 'tablespace2',
  306. require => Postgresql::Tablespace['tablespace2'],
  307. }
  308. EOS
  309. puppet_apply(pp) do |r|
  310. r.exit_code.should_not == 1
  311. end
  312. puppet_apply(pp) do |r|
  313. r.exit_code.should == 0
  314. end
  315. # Check that databases use correct tablespaces
  316. psql('--command="select ts.spcname from pg_database db, pg_tablespace ts where db.dattablespace = ts.oid and db.datname = \'"\'tablespacedb1\'"\'"') do |r|
  317. r.stdout.should =~ /tablespace1/
  318. r.stderr.should be_empty
  319. r.exit_code.should == 0
  320. end
  321. psql('--command="select ts.spcname from pg_database db, pg_tablespace ts where db.dattablespace = ts.oid and db.datname = \'"\'tablespacedb3\'"\'"') do |r|
  322. r.stdout.should =~ /tablespace2/
  323. r.stderr.should be_empty
  324. r.exit_code.should == 0
  325. end
  326. end
  327. end
  328. describe 'postgresql::pg_hba_rule' do
  329. it 'should create a ruleset in pg_hba.conf' do
  330. pp = <<-EOS
  331. include postgresql::server
  332. postgresql::pg_hba_rule { "allow application network to access app database":
  333. type => "host",
  334. database => "app",
  335. user => "app",
  336. address => "200.1.2.0/24",
  337. auth_method => md5,
  338. }
  339. EOS
  340. puppet_apply(pp) do |r|
  341. r.exit_code.should_not == 1
  342. end
  343. puppet_apply(pp) do |r|
  344. r.exit_code.should be_zero
  345. end
  346. shell("grep '200.1.2.0/24' /etc/postgresql/*/*/pg_hba.conf || grep '200.1.2.0/24' /var/lib/pgsql/data/pg_hba.conf") do |r|
  347. r.exit_code.should be_zero
  348. end
  349. end
  350. it 'should create a ruleset in pg_hba.conf that denies db access to db test1' do
  351. pp = <<-EOS
  352. include postgresql::server
  353. postgresql::db { "test1":
  354. user => "test1",
  355. password => "test1",
  356. grant => "all",
  357. }
  358. postgresql::pg_hba_rule { "allow anyone to have access to db test1":
  359. type => "local",
  360. database => "test1",
  361. user => "test1",
  362. auth_method => reject,
  363. order => '001',
  364. }
  365. user { "test1":
  366. shell => "/bin/bash",
  367. managehome => true,
  368. }
  369. EOS
  370. puppet_apply(pp) do |r|
  371. r.exit_code.should_not == 1
  372. end
  373. shell('su - test1 -c \'psql -U test1 -c "\q" test1\'') do |r|
  374. r.exit_code.should == 2
  375. end
  376. end
  377. end
  378. describe 'postgresql.conf include' do
  379. it "should support an 'include' directive at the end of postgresql.conf" do
  380. pending('no support for include directive with centos 5/postgresql 8.1', :if => (node.facts['osfamily'] == 'RedHat' and node.facts['lsbmajdistrelease'] == '5'))
  381. pp = <<-EOS
  382. class pg_test {
  383. class { 'postgresql::server': }
  384. $pg_conf_include_file = "${postgresql::params::confdir}/postgresql_puppet_extras.conf"
  385. file { $pg_conf_include_file :
  386. content => 'max_connections = 123',
  387. notify => Service['postgresqld'],
  388. }
  389. }
  390. class { 'pg_test': }
  391. EOS
  392. puppet_apply(pp) do |r|
  393. r.exit_code.should_not == 1
  394. end
  395. puppet_apply(pp) do |r|
  396. r.exit_code.should be_zero
  397. end
  398. psql('--command="show max_connections" -t') do |r|
  399. r.stdout.should =~ /123/
  400. r.stderr.should be_empty
  401. r.exit_code.should be_zero
  402. end
  403. pp = <<-EOS
  404. class cleanup {
  405. require postgresql::params
  406. $pg_conf_include_file = "${postgresql::params::confdir}/postgresql_puppet_extras.conf"
  407. file { $pg_conf_include_file :
  408. ensure => absent
  409. }
  410. }
  411. class { 'cleanup': }
  412. EOS
  413. puppet_apply(pp)
  414. end
  415. end
  416. end