prodder 1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ # Will this ever be useful? ...
2
+ require 'rspec/core/rake_task'
3
+ RSpec::Core::RakeTask.new(:spec)
4
+
5
+ task :extract_fixtures do
6
+ unless File.directory? 'features/support/blog.git'
7
+ Dir.chdir('features/support') { sh "tar xzf blog.git.tgz" }
8
+ end
9
+ end
10
+
11
+ require 'cucumber/rake/task'
12
+ Cucumber::Rake::Task.new :cucumber => :extract_fixtures
13
+
14
+ namespace :cuke do
15
+ Cucumber::Rake::Task.new(:wip => :extract_fixtures) do |t|
16
+ t.cucumber_opts = '--tags @wip'
17
+ end
18
+ end
19
+
20
+ task :default => [:spec, :cucumber]
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('../lib', File.dirname(__FILE__))
3
+ require 'prodder/cli'
4
+ Prodder::CLI.start
@@ -0,0 +1,69 @@
1
+ Feature: Commiting updated dumps to a project's repository
2
+
3
+ Background:
4
+ Given a prodder config in "prodder.yml" with project: blog
5
+ And a "blog" git repository
6
+ And I successfully run `prodder init -c prodder.yml`
7
+ And I successfully run `prodder dump -c prodder.yml`
8
+
9
+ Scenario: Structure, seed, quality_checks, permissions and settings files not yet tracked
10
+ When I run `prodder commit -c prodder.yml`
11
+ Then 1 commit by "prodder auto-commit" should be in the "blog" repository
12
+ And the file "db/structure.sql" should now be tracked
13
+ And the file "db/seeds.sql" should now be tracked
14
+ And the file "db/quality_checks.sql" should now be tracked
15
+ And the file "db/permissions.sql" should now be tracked
16
+ And the file "db/settings.sql" should now be tracked
17
+
18
+ Scenario: No changes to any file
19
+ When I run `prodder commit -c prodder.yml`
20
+ Then 1 commit by "prodder auto-commit" should be in the "blog" repository
21
+ When I run `prodder dump -c prodder.yml`
22
+ And I run `prodder commit -c prodder.yml`
23
+ Then 1 commit by "prodder auto-commit" should be in the "blog" repository
24
+
25
+ Scenario: Changes only to the structure
26
+ When I run `prodder commit -c prodder.yml`
27
+ Then 1 commit by "prodder auto-commit" should be in the "blog" repository
28
+ When I create a new table "linkbacks" in the "blog" database
29
+ And I run `prodder dump -c prodder.yml`
30
+ And I run `prodder commit -c prodder.yml`
31
+ And 2 commits by "prodder auto-commit" should be in the "blog" repository
32
+ And the latest commit should have changed "db/structure.sql" to contain "CREATE TABLE linkbacks"
33
+ And the latest commit should not have changed "db/seeds.sql"
34
+ And the latest commit should not have changed "db/quality_checks.sql"
35
+
36
+ Scenario: Changes only to the seed file
37
+ When I run `prodder commit -c prodder.yml`
38
+ Then 1 commit by "prodder auto-commit" should be in the "blog" repository
39
+ When I add a new author "Marley" to the "blog" database
40
+ And I run `prodder dump -c prodder.yml`
41
+ And I run `prodder commit -c prodder.yml`
42
+ Then 2 commits by "prodder auto-commit" should be in the "blog" repository
43
+ And the latest commit should have changed "db/seeds.sql" to contain "Marley"
44
+ And the latest commit should not have changed "db/structure.sql"
45
+ And the latest commit should not have changed "db/quality_checks.sql"
46
+
47
+ Scenario: Changes to both
48
+ When I run `prodder commit -c prodder.yml`
49
+ Then 1 commit by "prodder auto-commit" should be in the "blog" repository
50
+ When I create a new table "captchas" in the "blog" database
51
+ And I add a new author "Bob McBobbington" to the "blog" database
52
+ And I run `prodder dump -c prodder.yml`
53
+ And I run `prodder commit -c prodder.yml`
54
+ Then 2 commits by "prodder auto-commit" should be in the "blog" repository
55
+ And the latest commit should have changed "db/structure.sql" to contain "CREATE TABLE captchas"
56
+ And the latest commit should have changed "db/seeds.sql" to contain "Bob McBobbington"
57
+ And the latest commit should not have changed "db/quality_checks.sql"
58
+
59
+ Scenario: Changes only to permissions
60
+ When I run `prodder commit -c prodder.yml`
61
+ Then 1 commit by "prodder auto-commit" should be in the "blog" repository
62
+ When I create a new table "gotchas" in the "blog" database
63
+ When I grant all permissions on table "gotchas" in the "blog" database to "prodder"
64
+ And I run `prodder dump -c prodder.yml`
65
+ And I run `prodder commit -c prodder.yml`
66
+ And 2 commits by "prodder auto-commit" should be in the "blog" repository
67
+ And the latest commit should have changed "db/permissions.sql" to contain "GRANT ALL ON TABLE gotchas TO prodder"
68
+ And the latest commit should not have changed "db/seeds.sql"
69
+ And the latest commit should not have changed "db/quality_checks.sql"
@@ -0,0 +1,187 @@
1
+ Feature: prodder dump
2
+
3
+ Background:
4
+ Given a prodder config in "prodder.yml" with project: blog
5
+
6
+ Scenario: Happy path: dump structure.sql, listed seed tables, quality_checks.sql, permissions.sql and settings.sql
7
+ When I run `prodder dump -c prodder.yml`
8
+ Then the exit status should be 0
9
+ And the workspace file "blog/db/structure.sql" should match /CREATE TABLE posts/
10
+ And the workspace file "blog/db/structure.sql" should match /CREATE TABLE authors/
11
+ And the workspace file "blog/db/seeds.sql" should match /COPY posts/
12
+ And the workspace file "blog/db/seeds.sql" should match /COPY authors/
13
+ And the workspace file "blog/db/quality_checks.sql" should match /SET search_path/
14
+ And the workspace file "blog/db/quality_checks.sql" should match /CREATE TRIGGER /
15
+ And the workspace file "blog/db/permissions.sql" should match /GRANT /
16
+ And the workspace file "blog/db/settings.sql" should match /ALTER DATABASE /
17
+
18
+ Scenario: Include specified users, exclude other login roles from permissions dump
19
+ When I run `prodder dump -c prodder.yml`
20
+ Then the exit status should be 0
21
+ And the workspace file "blog/db/permissions.sql" should not match /exclude_this/
22
+ And the workspace file "blog/db/permissions.sql" should match /include_this/
23
+
24
+ Scenario: Roles missing ACL must be created, modified and granted if they're granted to non-login/included users
25
+ When I run `prodder dump -c prodder.yml`
26
+ Then the exit status should be 0
27
+ And the workspace file "blog/db/permissions.sql" should match /create_role_if_not_exists\('prodder__blog_prod:read_only'\);/
28
+ And the workspace file "blog/db/permissions.sql" should match /ALTER ROLE "prodder__blog_prod:read_only" WITH NOSUPERUSER/
29
+ And the workspace file "blog/db/permissions.sql" should match /GRANT "prodder__blog_prod:read_only" TO "prodder"/
30
+
31
+ Scenario: Roles are created smartly based on connected components in structure
32
+ When I run `prodder dump -c prodder.yml`
33
+ Then the exit status should be 0
34
+ And the workspace file "blog/db/permissions.sql" should not match /create_role_if_not_exists\('_92b'\);/
35
+ And the workspace file "blog/db/permissions.sql" should not match /create_role_if_not_exists\('_93b'\);/
36
+ And the workspace file "blog/db/permissions.sql" should not match /ALTER ROLE "_92b" WITH/
37
+ And the workspace file "blog/db/permissions.sql" should not match /ALTER ROLE "_93b" WITH/
38
+ And the workspace file "blog/db/permissions.sql" should not match /GRANT "_92b" TO "_93b"/
39
+
40
+ #TODO: Not sure how to test this
41
+ Scenario: All loginable (are there other kinds?) superusers are dumped
42
+ #TODO: Not sure how to test this
43
+ Scenario: Exhaustively test ACL
44
+
45
+ Scenario: Valid until option is quoted
46
+ When I run `prodder dump -c prodder.yml`
47
+ Then the exit status should be 0
48
+ And the workspace file "blog/db/permissions.sql" should match /VALID UNTIL '.*'/
49
+
50
+ Scenario: Exclude passwords from permissions dump
51
+ When I run `prodder dump -c prodder.yml`
52
+ Then the exit status should be 0
53
+ And the workspace file "blog/db/permissions.sql" should not match /PASSWORD '.*'/
54
+
55
+ Scenario: Roles are created if not existing instead of always being created
56
+ When I run `prodder dump -c prodder.yml`
57
+ Then the exit status should be 0
58
+ And the workspace file "blog/db/permissions.sql" should not match /CREATE ROLE \S*;/
59
+ And the workspace file "blog/db/permissions.sql" should match /create_role_if_not_exists\(.*\)/
60
+
61
+ Scenario: Exclude permissions dump if file missing
62
+ Given the prodder config in "prodder.yml" does not include a permissions file for the "blog" project
63
+ When I run `prodder dump -c prodder.yml`
64
+ Then the exit status should be 0
65
+ Then the workspace file "blog/db/permissions.sql" should not exist
66
+
67
+ Scenario: Exclude permissions dump if permissions object is missing
68
+ Given the prodder config in "prodder.yml" does not include permissions for the "blog" project
69
+ When I run `prodder dump -c prodder.yml`
70
+ Then the exit status should be 0
71
+ Then the workspace file "blog/db/permissions.sql" should not exist
72
+
73
+ Scenario Outline: Exhaustively test role creation and altering
74
+ When I run `prodder dump -c prodder.yml`
75
+ Then the exit status should be 0
76
+ And the workspace file "blog/db/permissions.sql" should match /<role_creation>/
77
+ And the workspace file "blog/db/permissions.sql" should match /<role_altering>/
78
+
79
+ Examples:
80
+ | role_creation | role_altering |
81
+ | prodder | ALTER ROLE "prodder" WITH NOSUPERUSER |
82
+ | prodder__blog_prod:read_only | ALTER ROLE "prodder__blog_prod:read_only" WITH NOSUPERUSER |
83
+ | include_this | ALTER ROLE "include_this" WITH NOSUPERUSER |
84
+ | _90enva | ALTER ROLE "_90enva" WITH NOSUPERUSER |
85
+ | _91b | ALTER ROLE "_91b" WITH NOSUPERUSER |
86
+ | _91qa | ALTER ROLE "_91qa" WITH NOSUPERUSER |
87
+ | _91se | ALTER ROLE "_91se" WITH NOSUPERUSER |
88
+ | _92qa | ALTER ROLE "_92qa" WITH NOSUPERUSER |
89
+ | _92se | ALTER ROLE "_92se" WITH NOSUPERUSER |
90
+ | _93se | ALTER ROLE "_93se" WITH NOSUPERUSER |
91
+ | _94se | ALTER ROLE "_94se" WITH NOSUPERUSER |
92
+ |prodder__blog_prod:permissions_test:read_only|ALTER ROLE "prodder__blog_prod:permissions_test:read_only" WITH NOSUPERUSER|
93
+ |prodder__blog_prod:permissions_test:read_only|ALTER ROLE "prodder__blog_prod:permissions_test:read_write" WITH NOSUPERUSER|
94
+
95
+ Scenario Outline: Exhaustively test memeberships
96
+ When I run `prodder dump -c prodder.yml`
97
+ Then the exit status should be 0
98
+ And the workspace file "blog/db/permissions.sql" should match /<membership>/
99
+
100
+ Examples:
101
+ | membership |
102
+ | GRANT "prodder__blog_prod:permissions_test:read_write" TO "include_this" |
103
+ | GRANT "prodder__blog_prod:read_only" TO "prodder" |
104
+ | GRANT "prodder__blog_prod:permissions_test:read_only" TO "prodder__blog_prod:read_only" |
105
+ | GRANT "_90enva" TO "_91se" |
106
+ | GRANT "_90enva" TO "_91qa" |
107
+ | GRANT "_90enva" TO "_91b" |
108
+ | GRANT "_91se" TO "_92se" |
109
+ | GRANT "_91qa" TO "_92se" |
110
+ | GRANT "_91qa" TO "_92qa" |
111
+ | GRANT "_91b" TO "_92qa" |
112
+ | GRANT "_91qa" TO "_94se" |
113
+ | GRANT "_92se" TO "_93se" |
114
+ | GRANT "_93se" TO "_94se" |
115
+
116
+ Scenario: Exclude specified tables from structure dump
117
+ Given the prodder config in "prodder.yml" excludes the table "authors" from the dump of "blog"
118
+ When I run `prodder dump -c prodder.yml`
119
+ Then the exit status should be 0
120
+ And the workspace file "blog/db/structure.sql" should not match /CREATE TABLE authors/
121
+
122
+ Scenario: Verify settings file contents
123
+ Given I add a customer parameter "c.p" with value "v" in the "blog" project's database
124
+ When I run `prodder dump -c prodder.yml`
125
+ Then the workspace file "blog/db/settings.sql" should match /ALTER DATABASE prodder__blog_prod SET c.p=v/
126
+
127
+ Scenario: Exclude specified schemas from structure dump
128
+ Given the prodder config in "prodder.yml" excludes the schema "ads" from the dump of "blog"
129
+ And I add a "ads" schema to the "blog" project's database
130
+ When I run `prodder dump -c prodder.yml`
131
+ Then the exit status should be 0
132
+ And the workspace file "blog/db/structure.sql" should not match /CREATE SCHEMA ads/
133
+
134
+ Scenario: Unspecified tables are not dumped to seeds
135
+ When I run `prodder dump -c prodder.yml`
136
+ Then the exit status should be 0
137
+ And the workspace file "blog/db/seeds.sql" should not match /COPY comments/
138
+
139
+ Scenario: Grant/revoke/ownership are not in the structure dump
140
+ When I run `prodder dump -c prodder.yml`
141
+ Then the workspace file "blog/db/structure.sql" should not match /GRANT/
142
+ And the workspace file "blog/db/structure.sql" should not match /ALTER TABLE.*OWNER TO/
143
+
144
+ Scenario: Ownership is not in the seeds dump
145
+ When I run `prodder dump -c prodder.yml`
146
+ Then the workspace file "blog/db/seeds.sql" should match /Owner: -/
147
+ And the workspace file "blog/db/seeds.sql" should not match /Owner: [^-]/
148
+
149
+ Scenario: Verify quality_checks file contents
150
+ Given I add a foreign key from table "posts" and column "author_id" to table "authors" and column "author_id" in the "blog" project's database
151
+ When I run `prodder dump -c prodder.yml`
152
+ Then the workspace file "blog/db/quality_checks.sql" should match /ADD CONSTRAINT .* FOREIGN KEY/
153
+ Given I add an index to table "posts" on column "author_id" in the "blog" project's database
154
+ When I run `prodder dump -c prodder.yml`
155
+ Then the workspace file "blog/db/quality_checks.sql" should match /CREATE INDEX /
156
+
157
+ Scenario: Maintaining quality checks directly in the structure file
158
+ Given the prodder config in "prodder.yml" does not include a quality check file for the "blog" project
159
+ And I add a foreign key from table "posts" and column "author_id" to table "authors" and column "author_id" in the "blog" project's database
160
+ When I run `prodder dump -c prodder.yml`
161
+ Then the workspace file "blog/db/quality_checks.sql" should not exist
162
+ And the workspace file "blog/db/structure.sql" should match /ADD CONSTRAINT .* FOREIGN KEY/
163
+
164
+ Scenario: Projects can use a YAML file to specify their seed tables
165
+ Given the prodder config in "prodder.yml" says to read the "blog" seed tables from "db/seeds.yml"
166
+ And the "blog" file "db/seeds.yml" contains:
167
+ """
168
+ - posts
169
+ """
170
+ When I run `prodder dump -c prodder.yml`
171
+ Then the exit status should be 0
172
+ And the workspace file "blog/db/seeds.sql" should match /COPY posts/
173
+ But the workspace file "blog/db/seeds.sql" should not match /COPY authors/
174
+
175
+ Scenario: YAML file listing seed tables does not exist
176
+ Given the prodder config in "prodder.yml" says to read the "blog" seed tables from "db/seeds.yml"
177
+ But the "blog" file "db/seeds.yml" does not exist
178
+ When I run `prodder dump -c prodder.yml`
179
+ Then the exit status should be 1
180
+ And the output should contain "No such file: blog/db/seeds.yml"
181
+
182
+ @restore-perms
183
+ Scenario: pg_dump failed
184
+ Given the "prodder" role can not read from the "blog" database's tables
185
+ When I run `prodder dump -c prodder.yml`
186
+ Then the exit status should be 1
187
+ And the output should contain "permission denied"
@@ -0,0 +1,24 @@
1
+ Feature: prodder init
2
+
3
+ Background:
4
+ Given a prodder config in "prodder.yml" with project: blog
5
+ And a "blog" git repository
6
+
7
+ Scenario: Clone a project
8
+ When I run `prodder init -c prodder.yml`
9
+ Then the exit status should be 0
10
+ And a directory named "prodder-workspace/blog" should exist
11
+ And the workspace file "blog/README" should match /Read me/
12
+
13
+ Scenario: Update pre-existing repository on re-initializing
14
+ Given I run `prodder init -c prodder.yml`
15
+ And a new commit is already in the "blog" git repository
16
+ When I run `prodder init -c prodder.yml`
17
+ Then the new commit should be in the workspace copy of the "blog" repository
18
+
19
+ Scenario: Can't clone repository (no such repo, permissions, whatever)
20
+ Given I deleted the "blog" git repository
21
+ When I run `prodder init -c prodder.yml`
22
+ Then the exit status should be 1
23
+ And the output should contain "Failed to run 'git clone ./repos/blog"
24
+ And the output should match /repository.*does not exist/
@@ -0,0 +1,46 @@
1
+ Feature: Configuration lint
2
+ In order to simplify later error handling and hopefully provide
3
+ rapid feedback on configuration issues, the config file is always
4
+ run through a linting process to ensure sanity before any other
5
+ operations are performed.
6
+
7
+ See spec/config_spec for a more detailed test of linting. This
8
+ test only ensures that the CLI reports lint failures reasonably.
9
+
10
+ Background:
11
+ Given a prodder config in "prodder.yml" with project: store
12
+ And no-op versions of these bins are available on my PATH: pg_dump, git
13
+
14
+ Scenario: One of the required project config keys is missing
15
+ But the "store/db/name" key is missing from "prodder.yml"
16
+ When I run `prodder ls -c prodder.yml`
17
+ Then the exit status should be 1
18
+ And the output should contain:
19
+ """
20
+ Missing required configuration key: store/db/name
21
+
22
+ Example configuration:
23
+ """
24
+ And the output should contain the example config contents
25
+
26
+ Scenario: pg_dump is not available
27
+ Given "pg_dump" is not available on my PATH
28
+ When I run `prodder ls -c prodder.yml`
29
+ Then the exit status should be 1
30
+ And the output should contain:
31
+ """
32
+ `pg_dump` could not be found on your $PATH.
33
+
34
+ Current PATH:
35
+ """
36
+
37
+ Scenario: git is not available
38
+ Given "git" is not available on my PATH
39
+ When I run `prodder ls -c prodder.yml`
40
+ Then the exit status should be 1
41
+ And the output should contain:
42
+ """
43
+ `git` could not be found on your $PATH.
44
+
45
+ Current PATH:
46
+ """
@@ -0,0 +1,76 @@
1
+ Feature: Basic CLI usage
2
+
3
+ Scenario: prodder help
4
+ When I run `prodder help`
5
+ Then the output should contain "Tasks:"
6
+
7
+ Scenario: No config file supplied
8
+ When I run `prodder`
9
+ Then the output should contain "required option '--config'"
10
+
11
+ Scenario: Config file not found
12
+ When I run `prodder init -c not-there.yml`
13
+ Then the output should contain exactly "Config file not found: not-there.yml\n"
14
+ And the exit status should be 1
15
+
16
+ Scenario: Malformed config file
17
+ Given a file named "broken.yml" with:
18
+ """
19
+ %this IS NOT VALID YAML
20
+ """
21
+ When I run `prodder init -c broken.yml`
22
+ Then the output should contain:
23
+ """
24
+ Invalid YAML in config file broken.yml. Current file contents:
25
+
26
+ %this IS NOT VALID YAML
27
+ """
28
+
29
+ Scenario: No database defined on project
30
+ Given a file named "prodder.yml" with:
31
+ """
32
+ blog:
33
+ structure_file: db/structure.sql
34
+ seed_file: db/seeds.sql
35
+ quality_check_file: db/quality_checks.sql
36
+ git:
37
+ origin: git@github.com:pd/blog.git
38
+ author: prodder auto-commit <pd+prodder@krh.me>
39
+ """
40
+ When I run `prodder dump blog -c prodder.yml`
41
+ Then the output should contain:
42
+ """
43
+ Missing required configuration key: blog/db
44
+
45
+ Example configuration:
46
+ blog:
47
+ structure_file: db/structure.sql
48
+ seed_file: db/seeds.sql
49
+ quality_check_file: db/quality_checks.sql
50
+ git:
51
+ origin: git@github.com:your/repo.git
52
+ author: prodder <prodder@example.com>
53
+ db:
54
+ name: database_name
55
+ host: database.server.example.com
56
+ user: username
57
+ password: password
58
+ tables:
59
+ - posts
60
+ - authors
61
+ """
62
+
63
+ Scenario: Projects named not defined in config file
64
+ Given a prodder config in "prodder.yml" with project: store
65
+ When I run `prodder init blog api -c prodder.yml`
66
+ Then the output should contain "Project not defined: blog, api"
67
+
68
+ Scenario: Listing projects
69
+ Given a prodder config in "prodder.yml" with projects: store, blog
70
+ When I run `prodder ls -c prodder.yml`
71
+ Then the output should contain exactly:
72
+ """
73
+ store
74
+ blog
75
+
76
+ """
@@ -0,0 +1,25 @@
1
+ Feature: prodder push
2
+
3
+ Background:
4
+ Given a prodder config in "prodder.yml" with project: blog
5
+ And a "blog" git repository
6
+ And I successfully run `prodder init -c prodder.yml`
7
+ And I successfully run `prodder dump -c prodder.yml`
8
+ And I successfully run `prodder commit -c prodder.yml`
9
+
10
+ Scenario: Changes are pushed upstream
11
+ When I successfully run `prodder push -c prodder.yml`
12
+ Then the exit status should be 0
13
+ Then the new commit should be in the remote repository
14
+
15
+ Scenario: Push fails due to permissions
16
+ Given the "blog" git repository does not allow pushing to it
17
+ When I run `prodder push -c prodder.yml`
18
+ Then the exit status should be 1
19
+ And the output should contain "insufficient permission"
20
+
21
+ Scenario: Push fails due to non-fast-forward
22
+ Given a new commit is already in the "blog" git repository
23
+ When I run `prodder push -c prodder.yml`
24
+ Then the exit status should be 1
25
+ And the output should contain "Refusing to push to remote"