pdqtest 0.6.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75a6265aa171ae4d88a6e97d754c6018edfe7d3a
4
- data.tar.gz: b1ae71344008ff1fdaabf2df6b332c0dc8766c27
3
+ metadata.gz: 81c318fbee9b279339ea33b3eadb67d6a24d522e
4
+ data.tar.gz: fe53d0ad29c10016b86f2113b719fe7b7105fd36
5
5
  SHA512:
6
- metadata.gz: '019cde9a45ac72c3f48e1d06779fcdf9d56971215cb434fe2a9cc78dd02a4bb2a699bad97fcb82cdc45e117bd6076975abf222ffa51edc04e5238a600eb3d3df'
7
- data.tar.gz: 382c6283d6c0c2801d21634fe3a2709978cd35f7a715fd0d9834bf289b2dfffed77138673162e32f1ae0042335168e5409e25aad79365c937adba584d5b1e3f2
6
+ metadata.gz: ba76837160b19db3801709f6c0303e904d40f8ce1704bae50a0cbacf604a2095ba82a488ad65bc468122eb8583b4292c01a614221783b687cce474114750a2d4
7
+ data.tar.gz: 9a261e76ea262d5051b71afd1778f46a67667bbb0664175ca468ecb09496ac902b55e9e28eafd9734ffc83d61362f029efea09e16e0a85e42d32b98bf7c5a1e9
data/.gitignore CHANGED
@@ -3,7 +3,6 @@
3
3
  /Gemfile.lock
4
4
  /_yardoc/
5
5
  /coverage/
6
- /doc/
7
6
  /pkg/
8
7
  /spec/reports/
9
8
  /tmp/
data/README.md CHANGED
@@ -10,257 +10,19 @@ PDQTest - Puppet Docker Quick-test - is the quickest and easiest way to test you
10
10
 
11
11
  And can generate code to retrofit testing to a new or existing module, along with skeleton RSpec and acceptance tests to get you started.
12
12
 
13
- PDQTest runs linting, syntax and RSpec tests within the machine it is running from and then loads a docker container to perform acceptance testing.
14
-
15
- ## Installation
16
-
17
- To install PDQTest on your system:
18
-
19
- ### System Ruby
20
- ```shell
21
- gem install pdqtest
22
- ```
23
-
24
- ### Bundler, add this line to your application's Gemfile:
25
- ```ruby
26
- gem 'pdqtest
27
- ```
28
- * It's advisable to specify a version number to ensure repeatable builds
29
-
30
- ### Puppet modules
31
- To add PDQTests to a new or existing puppet module, run the command:
32
- ```
33
- pdqtest init
34
- ```
35
-
36
- This will install PDQTest into the `Gemfile` and will generate an example set of acceptance tests
37
-
38
- ## Running tests
39
-
40
- ### PDQTest preparation
41
- PDQTest needs to download a Docker image before running tests:
42
-
43
- ```
44
- bundle exec pdqtest setup
45
- ```
46
-
47
- This image is updated periodically, the above command will download the appropriate image for the version of `pdqtest` being used.
48
-
49
- ### Module dependencies/.fixtures.yml
50
- There is no need to maintain a `.fixtures.yml` file and the presence of this file when using `pdqtest` is an error.
51
-
52
- #### Public modules (PuppetForge)
53
- Dependencies on public forge modules must be specified in your module's `metadata.json` file.
54
-
55
- #### Private modules (from git)
56
- If you need to download modules from git, then you must populate the `fixtures` section of `fixtures.yml`, eg:
57
-
58
- ```
59
- repositories:
60
- corporatestuff:
61
- repo: 'https://nonpublicgit.megacorp.com/corporatestuff.git'
62
- ref: 'mybranch'
63
- ```
64
-
65
- ##### Notes:
66
- * The filename is `fixtures.yml` NOT `.fixtures.yml`. The leading dot had to be removed to avoid `puppetlabs_spec_helper` also detecting the file and trying to use it.
67
- * The file format of `.fixtures.yml` and `fixtures.yml` for specifing git repositories is identical
68
- * Only the repositories section of the file will be processed as we do not use `puppetlabs_spec_helper` to do this for us.
69
-
70
- ## Merging additional facts
71
- PDQTest includes built-in [factsets](https://github.com/declarativesystems/puppet_factset) covering many common operating systems, however, sometimes additional facts are needed throughout a module to mock an external fact or custom fact from a different module that is expected to be some known value. In this case, creating the directory:
72
-
73
- ```
74
- spec/merge_facts
75
- ```
76
-
77
- Inside the module being tested will result in all JSON files contained being merged into all OS specific factsets used for testing as generated by `pdqtest generate_rspec`. To put it simply, drop `.json` file(s) in this directory to add them to every factset.
78
-
79
- These facts will be made automatically avaialable to facter when running acceptance testing
80
-
81
- ### All tests
82
- If you just want to run all tests:
83
-
84
- ```shell
85
- bundle exec pdqtest all
86
- ```
87
-
88
- ### RSpec tests
89
- ```shell
90
- bundle exec pdqtest rspec
91
- ```
92
-
93
- ### Debugging failed builds
94
- PDQTest makes it easy to debug failed builds:
95
-
96
- ```shell
97
- pdqtest shell
98
- ```
99
-
100
- * Open a shell inside the docker container that would be used to run tests
101
- * Your code is available at `/testcase`
102
-
103
- ```shell
104
- pdqtest --keep-container all
105
- ```
106
- * Run all tests, report pass/fail status
107
- * Keep the container Running
108
- * After testing, the container used to run tests will be left running and a message will be printed showing how to enter the container used for testing. Your code is avaiable at `/testcase`
109
-
110
- ## About acceptance tests
111
- * Acceptance tests run within a Docker container managed by PDQTest
112
- * The Docker container breaks all the rules of Docker and runs a full version of Systemd to allow complete testing of Puppet code in the most portable way (basically treat docker as a high speed VM)... This is deliberate - PDQTest exists to get results, not be a perfect Docker app.
113
- * The test container uses a minimal version of Centos 7, there's no option to change this at present
114
- * The container will only be started if at least one example file is present and contains the correct magic marker
115
- * You can get a shell on the docker container if needed:
116
- * A representitive system, identical to that which will be used to run the tests `pdqtest shell`
117
- * The actual container that was just used on a test run `pdqtest --keep-container all` and run the command indicated on exit
118
-
119
- ### Test workflow
120
- 1. Scan for all example files under `/examples`. Files must end in `.pp` and contain the magic marker `#@PDQTest` to be processed
121
- 2. If example files are present, start the docker container
122
- 3. For each example file:
123
- * Check for a file at `/spec/acceptance/EXAMPLE_NAME__setup.sh`, If it exists, run it inside the container. This is a useful place to install preqrequisites, edit files, install mock services, clean up after other tests, etc.
124
- * Check for a file at `/spec/acceptance/EXAMPLE_NAME__before.bats`, If it exists run BATS against it. This is normally used to check the system state is clean or that any test prerequisites have been setup correctly
125
- * Run `puppet apply` on the example file twice
126
- * Check for a file at `/spec/acceptance/EXAMPLE_NAME.bats`, If it exists run BATS against it. This is normally used to check the state of the system after running puppet. You can do things like check services are running, check files edited correctly, or basically anything that you can write in bash!
127
- 4. Destroy the container unless we were asked to keep it with `--keep-container`
128
-
129
- Note: `EXAMPLE_NAME` is the example filename minus the directory and `.pp`, eg the `EXAMPLE_NAME` for `examples/foo.pp` would just be `foo`.
130
-
131
- ### Example files
132
- * Found inside `/examples`
133
- * Regular puppet code
134
- * Will be executed _twice_ (to check for idempotency) with `puppet apply`
135
- * _MUST_ contain the magic marker `#@PDQTest` on a line at the top of the file to indicate that this test should be processed by PDQTest
136
- * Basically the same as a regular puppet [smoke test](https://docs.puppet.com/puppet/latest/tests_smoke.html#module-smoke-testing) but run automatically and with system state tests
137
-
138
- ### BATS tests
139
- If you've never seen a BATS test before and have previously been writing server spec code, you'll probably kick youself when you see how simple they are. Here's an example:
140
-
141
- ```BASH
142
- # Tests are really easy! just the exit status of running a command...
143
- @test "addition using bc" {
144
- result="$(ls /)"
145
- [ "$?" -eq 0 ]
146
- }
147
- ```
148
-
149
- Tests are all written in BASH and the testcase passes if the stanza returns zero. This means that basically any Linux/Unix sysadmin is now empowered to write Testcases and do TDD - score!
150
-
151
- Since our tests are written in BASH, there are of course all the usual bash quirks such as failing on incorrect spacing, bizzare variable quoting etc, but given the simplicity gained its a worthwhile tradeoff.
152
-
153
- Consider the following (real) test:
154
-
155
- ```BASH
156
- @test "ClientAliveCountMax" {
157
- grep "ClientAliveCountMax 1" /etc/ssh/sshd_config
158
- }
159
- ```
160
-
161
- Here, we have done exactly what it looks like we have done - checked for the value of a particular setting in a text file. Since our tests our plain old BASH, it means we can do things like test daemons are running with `systemctl`, test ports are open with `netstat` and do complete system tests `wget` and `curl`. Cool!
162
-
163
- #### Worked Example
164
- Lets say you have two examples, `foo.pp` and `init.pp`. In this case, the full range of files to create for acceptance testing would look like this:
165
- ```
166
- mycoolmodule
167
- ├── examples
168
- │   ├── foo.pp
169
- │   └── init.pp
170
- ├── ...
171
- └── spec
172
- ├── acceptance
173
- │   ├── foo__before.bats
174
- │   ├── foo__setup.sh
175
- │   ├── foo.bats
176
- │   ├── init__before.bats
177
- │   ├── init__setup.sh
178
- │   └── init.bats
179
- ├── ...
180
- ```
181
-
182
- * You can put any puppet code you like (includeing an empty file...) in each of the files under `/examples` and it will executed with `puppet apply`
183
- * If you need to test multiple different things (eg different parameters for a new type and provider), you need to create different testcase for each distinct thing to test. See below for help generating these
184
- * You can skip setup or BATS testing before and/or after running `puppet apply` if desired by deleting the appropriate files
185
- * If you delete all of the files under `spec/acceptance` for a given example, then PDQTest will just check that puppet runs idempotently for your example
186
- * To disable tests temporarily for a specific example, remove the magic marker `#@PDQTest` from the desired example
187
- * Nested examples (subdirectories) are not supported at this time
188
-
189
- ## Real world example
190
- See https://github.com/GeoffWilliams/puppet-filemagic for a project with lots of acceptance tests.
191
-
192
- ## Test Generation
193
- Creating a bunch of files manually is an error prone and tedious operation so PDQTest can generate files and boilerplate code for you so that your up and running in the quickest time possible.
194
-
195
- ### Skeleton
196
- * `pdqtest init` will generate a basic set of tests to get you started (tests init.pp)
197
-
198
- ### RSpec tests
199
- The skeleton tests created by `pdqtest init` only cover the `init.pp` file which is useful but your likely going to need to support more classes as your modules grow. PDQTest can generate basic RSpec testcases for each new puppet class that exists in the manifests directory for you:
200
-
201
- ```shell
202
- pdqtest generate_rspec
203
- ```
204
-
205
- * For every `.pp` file containing a puppet class under `/manifests`, RSpec will be generated to:
206
- * Check the catalogue compiles
207
- * Check the catalogue contains an instance of the class
208
- * This gives developers an easy place to start writing additional RSpec tests for specific behaviour
209
- * Its safe to run this command whenever you add a new class, it won't overwrite any existing RSpec testcases
210
-
211
- ### Acceptance tests
212
-
213
- #### Generate boilerplate files for each example found (including those without a magic marker)
214
-
215
- ```shell
216
- pdqtest generate_acceptance
217
- ```
218
-
219
- #### Generate boilerplate files for one specific example
220
-
221
- ```shell
222
- pdqtest generate_acceptance examples/mynewthing.pp
223
- ```
224
- * Note: will also create examples/mynewthing.pp if you haven't created it yet
225
-
226
- ## Caching
227
- PDQTest will attempt to cache:
228
- * Puppet modules (via librarian-puppet) in `~/.pdqtest/cache/modules`
229
- * The yum cache in `~/.pdqtest/cache/yum`
230
-
231
- Note that since the yum cache is writen to via a docker volume from the container your running tests in, the files in this directory will be root owned. If you need to clear your cache for whatever reason, delete the `~/.pdqtest/cache` directory (you will likely need sudo) and PDQtest will recreate it next time it runs.
232
-
233
- ## Development
234
-
235
- PRs welcome :) Please ensure suitable tests cover any new functionality and that all tests are passing before and after your development work:
236
-
237
- ```shell
238
- bundle exec rake spec
239
- ```
240
-
241
- ## Who should use PDQTest?
242
- You should use pdqtest if you find it increases your productivity and enriches your life
243
-
244
- ## Troubleshooting
245
- * If you can't find the `pdqtest` command and your using `rbenv` be sure to run `rbenv rehash` after installing the gem to create the necessary symlinks
246
- * Don't forget to run `pdqtest setup` before your first `pdqtest` run to download/update the Docker image
247
- * If you need to access private git repositories, make sure to use `fixtures.yml` not `.fixtures.yml`
248
- * If you need a private key to access private repositories, set this up for your regular git command/ssh and `pdqtest` will reuse the settings
249
- * Be sure to annotate the examples you wish to acceptance test with the magic marker comment `#@PDQTest`
250
- * Sometimes you might get an error: `Could not resolve the dependencies.` when executing tests. This message is from librarian puppet and usually indicates a conflict between the `metadata.json` files somewhere in the set of modules you are attempting to use. Running the command `librarian-puppet install --path spec/fixtures/ --destructive --verbose` should give you enough information to resolve the error
251
- * Be sure to run `make` or `bundle exec pdqtest all` to download dependencies when running acceptance tests. Previous versions (re)downloaded modules as required from inside docker but this step has been replaced with a simple symlink.
252
-
253
- ## Support
254
- This software is not supported by Puppet, Inc. Use at your own risk.
255
-
256
- ## Contributing
257
- Bug reports and pull requests are welcome on GitHub at https://github.com/declarativesystems/pdqtest.
258
-
259
- ## Upgrade notes
260
- * Previous versions of PDQTest mounted code at `/cut` (Code Under Test), this will still work for a few versions but the preferred mountpoint is now the more obvious `/testcase`
261
-
262
- ### Running tests
263
- * PDQTest includes a comprehensive tests for core library functions. Please ensure tests pass before and after any PRs
264
- * Run all tests `bundle exec rake spec`
265
- * Run specific test file `bundle exec rspec ./spec/SPEC/FILE/TO/RUN.rb`
266
- * Run specific test case `bundle exec rspec ./spec/SPEC/FILE/TO/RUN.rb:99` (where 99 is the line number of the test)
13
+ PDQTest runs linting, syntax and RSpec tests within the machine it is running from and then loads a docker container to perform acceptance testing, sharing the puppet module and cached dependencies from your host.
14
+
15
+ ## PDQTest Manual
16
+ 1. [Installation](doc/installation.md)
17
+ 2. [Enabling testing](doc/enableing_testing.md)
18
+ 3. [Running tests](doc/running_tests.md)
19
+ 4. [Test generation](doc/test_generation.md)
20
+ 5. [Puppet module dependencies](doc/puppet_module_dependencies.md)
21
+ 6. [Puppet facts](doc/puppet_facts.md)
22
+ 7. [Hiera](doc/hiera.md)
23
+ 8. [Caching](doc/caching.md)
24
+ 9. [Upgrading](doc/upgrading.md)
25
+ 10. [Examples](doc/examples.md)
26
+ 11. [Tips and tricks](doc/tips_and_tricks.md)
27
+ 12. [Troubleshooting](doc/troubleshooting.md)
28
+ 13. [Development](doc/development.md)
@@ -0,0 +1,87 @@
1
+ # Acceptance tests
2
+ * Acceptance tests run within a Docker container managed by PDQTest
3
+ * The Docker container breaks all the rules of Docker and runs a full version of Systemd to allow complete testing of Puppet code in the most portable way (basically treat docker as a high speed VM)... This is deliberate - PDQTest exists to get results, not be a perfect Docker app.
4
+ * The test container uses a minimal version of Centos 7, there's no option to change this at present
5
+ * The container will only be started if at least one example file is present **and contains the correct magic marker**
6
+ * You can get a shell on the docker container if needed, see [Debugging failed builds](#debugging-failed-builds)
7
+
8
+ ### Test workflow
9
+ 1. Scan for all example files under `/examples`. Files must end in `.pp` and contain the magic marker `#@PDQTest` to be processed
10
+ 2. If example files are present, start the docker container
11
+ 3. For each example file:
12
+ * Check for a file at `/spec/acceptance/EXAMPLE_NAME__setup.sh`, If it exists, run it inside the container. This is a useful place to install preqrequisites, edit files, install mock services, clean up after other tests, etc.
13
+ * Check for a file at `/spec/acceptance/EXAMPLE_NAME__before.bats`, If it exists run BATS against it. This is normally used to check the system state is clean or that any test prerequisites have been setup correctly
14
+ * Run `puppet apply` on the example file twice
15
+ * Check for a file at `/spec/acceptance/EXAMPLE_NAME.bats`, If it exists run BATS against it. This is normally used to check the state of the system after running puppet. You can do things like check services are running, check files edited correctly, or basically anything that you can write in bash!
16
+ 4. Destroy the container unless we were asked to keep it with `--keep-container`
17
+
18
+ Note: `EXAMPLE_NAME` is the example filename minus the directory and `.pp`, eg the `EXAMPLE_NAME` for `examples/foo.pp` would just be `foo`.
19
+
20
+ ### Example files
21
+ * Found inside `/examples`
22
+ * Regular puppet code
23
+ * Will be executed _twice_ (to check for idempotency) with `puppet apply`
24
+ * _MUST_ contain the magic marker `#@PDQTest` on a line at the top of the file to indicate that this test should be processed by PDQTest
25
+ * Basically the same as a regular puppet [smoke test](https://docs.puppet.com/puppet/latest/tests_smoke.html#module-smoke-testing) but run automatically and with system state tests
26
+
27
+ ### BATS tests
28
+ If you've never seen a BATS test before and have previously been writing server spec code, you'll probably kick youself when you see how simple they are. Here's an example:
29
+
30
+ ```BASH
31
+ # Tests are really easy! just the exit status of running a command...
32
+ @test "addition using bc" {
33
+ result="$(ls /)"
34
+ [ "$?" -eq 0 ]
35
+ }
36
+ ```
37
+
38
+ Tests are all written in BASH and the testcase passes if the stanza returns zero. This means that basically any Linux/Unix sysadmin is now empowered to write Testcases and do TDD - score!
39
+
40
+ Since our tests are written in BASH, there are of course all the usual bash quirks such as failing on incorrect spacing, bizzare variable quoting etc, but given the simplicity gained its a worthwhile tradeoff.
41
+
42
+ Consider the following (real) test:
43
+
44
+ ```BASH
45
+ @test "ClientAliveCountMax" {
46
+ grep "ClientAliveCountMax 1" /etc/ssh/sshd_config
47
+ }
48
+ ```
49
+
50
+ Here, we have done exactly what it looks like we have done - checked for the value of a particular setting in a text file. Since our tests our plain old BASH, it means we can do things like test daemons are running with `systemctl`, test ports are open with `netstat` and do complete system tests `wget` and `curl`. Cool!
51
+
52
+ #### Worked Example
53
+ Lets say you have two examples, `foo.pp` and `init.pp`. In this case, the full range of files to create for acceptance testing would look like this:
54
+ ```
55
+ mycoolmodule
56
+ ├── examples
57
+ │   ├── foo.pp
58
+ │   └── init.pp
59
+ ├── ...
60
+ └── spec
61
+ ├── acceptance
62
+ │   ├── foo__before.bats
63
+ │   ├── foo__setup.sh
64
+ │   ├── foo.bats
65
+ │   ├── init__before.bats
66
+ │   ├── init__setup.sh
67
+ │   └── init.bats
68
+ ├── ...
69
+ ```
70
+
71
+ ### Debugging failed builds
72
+ PDQTest makes it easy to debug failed builds:
73
+
74
+ ```shell
75
+ pdqtest shell
76
+ ```
77
+
78
+ * Opens a shell inside the docker container that would be used to run tests
79
+ * Your code is available at `/testcase`
80
+
81
+ ```shell
82
+ pdqtest --keep-container all
83
+ ```
84
+ * Runs all tests, report pass/fail status
85
+ * Keeps the container Running
86
+ * After testing, the container used to run tests will be left running and a message will be printed showing how to enter the container used for testing. Your code is avaiable at `/testcase`
87
+ * User is responsible for cleaning up the containers created in this mode
data/doc/caching.md ADDED
@@ -0,0 +1,6 @@
1
+ # Caching
2
+ PDQTest will attempt to cache:
3
+ * Puppet modules (via librarian-puppet) in `~/.pdqtest/cache/modules`
4
+ * The yum cache in `~/.pdqtest/cache/yum`
5
+
6
+ Note that since the yum cache is writen to via a docker volume from the container your running tests in, the files in this directory will be root owned. If you need to clear your cache for whatever reason, delete the `~/.pdqtest/cache` directory (you will likely need `sudo`) and PDQtest will recreate it next time it runs.
@@ -0,0 +1,15 @@
1
+ # Development
2
+
3
+ PRs welcome :) Please ensure suitable tests cover any new functionality and that all tests are passing before and after your development work.
4
+
5
+ ## Support
6
+ Interested in commercial support of PDQTest? Please email sales@declarativesystems.com to discuss your needs.
7
+
8
+ ## Contributing
9
+ Bug reports and pull requests are welcome on GitHub at https://github.com/declarativesystems/pdqtest.
10
+
11
+ ### Running tests
12
+ * PDQTest includes a comprehensive tests for core library functions. Please ensure tests pass before and after any PRs
13
+ * Run all tests `bundle exec rake spec`
14
+ * Run specific test file `bundle exec rspec ./spec/SPEC/FILE/TO/RUN.rb`
15
+ * Run specific test case `bundle exec rspec ./spec/SPEC/FILE/TO/RUN.rb:99` (where 99 is the line number of the test)
@@ -0,0 +1,11 @@
1
+ # Enabling testing
2
+ To add PDQTest to a new or existing puppet module, run the commands:
3
+
4
+ ```shell
5
+ pdqtest init
6
+ bundle install
7
+ ```
8
+
9
+ From the top level directory of your puppet module. This will install PDQTest into the `Gemfile` (for bundler), and generate an example set of acceptance tests. The `bundle install` step will need development libraries installed if you haven't already obtained them.
10
+
11
+ Note: Your puppet module *must* have a valid `metatadata.json` file. Create one before running `pdqtest init` if you don't already have one. If your creating a puppet module from scratch, try `puppet module generate` to create a complete module skeleton that includes a valid version of this file.
data/doc/examples.md ADDED
@@ -0,0 +1,10 @@
1
+ # Examples
2
+
3
+ Here are some projects that use PDQTest:
4
+ * https://github.com/geoffwilliams/puppet-motd
5
+ * https://github.com/declarativesystems/download_and_do
6
+ * https://github.com/GeoffWilliams/puppet-filemagic
7
+ * https://github.com/declarativesystems/ssh
8
+ * https://github.com/declarativesystems/puppet-chown_r/tree/master/spec/acceptance
9
+
10
+ Do you use PDQTest on your own projects? If you have a good public example let me know!
data/doc/hiera.md ADDED
@@ -0,0 +1,43 @@
1
+ # Hiera
2
+ Under normal circumstances, only a `profile` module would be consuming Hiera data directly using the `hiera()` function, and its suggested by many that these too fall back to automatic data binding parameters rather then use the `hiera()` function directly. In this case it makes more sense to use the excellent [Onceover](https://github.com/dylanratcliffe/onceover) tool to perform end-to-end testing of your Hiera data, puppet control repository and roles/profile modules.
3
+
4
+ That said, there may be occasions where you need to mock hiera data:
5
+ * You have implemented Roles and Profiles as a namespace inside a team module (for multi-tennanting)
6
+ * You have a module that performs `hiera()` lookups directly
7
+ * You intend to drive your module by adding data to hiera and including a class to make something happen
8
+ * Your class fails to compile due to missing hiera data
9
+ * You have a separate git repository for your `profile` module and want to be able to test it
10
+
11
+ ## Alternative method
12
+ In some cases where it may be easiest to directly inject strings in lieu of setting up a fake hiera:
13
+
14
+ ### RSpec Tests
15
+ ```ruby
16
+ let :params do
17
+ {
18
+ :data_from_hiera => "faked by",
19
+ :more_data => "hardcoding inline",
20
+ }
21
+ end
22
+ ```
23
+
24
+ ### Acceptance tests
25
+ ```puppet
26
+ class { "foo":
27
+ data_from_hiera => "faked by",
28
+ more_data => "hardcoding inline",
29
+ }
30
+ ```
31
+
32
+ Note that you would need to duplicate your hard-coded mock data between the rspec tests and any acceptance tests.
33
+
34
+ In the more complex cases it may instead be desireable to mock the hiera data in order to enable Puppet's regular lookup systems to work.
35
+
36
+ ## Mocking hiera
37
+ PDQTest supports full mocking of Hiera for both RSpec and acceptance tests and support for this is enabled automatically when `pdqtest init` is run by versions of PDQTest >= 0.5.0.
38
+
39
+ A basic one-level hierachy is created for you:
40
+ * Hiera configuration file at `spec/fixtures/hiera.yaml`
41
+ * Single hiera data file at `spec/fixtures/hieradata/test.yaml`
42
+
43
+ Any required hiera data can be added to `test.yaml` and will immediately show up when lookups are made.
@@ -0,0 +1,15 @@
1
+ # Installation
2
+ PDQTest only runs on Linux/MAC systems. If you are using Windows, the easiest way for you to run PDQTest is to install virtualisation software and then use [Vagrant](http://vagrantup.com/) to create a VM that shares a filesystem with your main Windows desktop. This will allow you to edit your puppet code as you please and have it instantly show up inside of a Linux VM where you can run PDQTest and Docker.
3
+
4
+ 1. Install Ruby - you will need a fairly new version of Ruby as Puppet requires this. [RVM](https://rvm.io/) or [RBENV](https://github.com/rbenv/rbenv) are easy ways of obtaining an up-to-date version. Ruby 2.3 works prefectly. You may need development libraries, eg `yum groupinstall 'Development Tools'` with these systems. Once you have obtained a modern Ruby, follow any additional setup steps to activate the environment and then check it really worked by running `ruby --version` before proceeding. Note that `pdqtest` should not be run as `root`.
5
+ 2. Make sure `git` is installed - `yum install git`
6
+ 3. Install the gem version of puppet - `gem install puppet`
7
+ 4. Install PDQTest - `gem install pdqtest`
8
+ 5. Install bundler (the only sane way to manage Ruby dependencies) - `gem install bundler`
9
+ 6. Install [Docker CE](www.docker.com)
10
+ 7. Start the `docker` daemon and make sure the user your running as is in the `docker` group. You will need to log out and back in again after doing this
11
+ 8. Install the [PDQTest Docker image](https://hub.docker.com/r/geoffwilliams/pdqtest-centos/) by typing `pdqtest setup`
12
+
13
+ You have now installed PDQTest. Steps 6-8 are only required if running acceptance testing but are highly recommended.
14
+
15
+ Note: Do *NOT* run PDQTest on a managed Puppet node, you may damage the agent.
@@ -0,0 +1,10 @@
1
+ # Puppet facts
2
+ PDQTest includes built-in [factsets](https://github.com/declarativesystems/puppet_factset) covering many common operating systems, however, sometimes additional facts are needed throughout a module to mock an external fact or custom fact from a different module that is expected to be some known value. In this case, creating the directory:
3
+
4
+ ```
5
+ spec/merge_facts
6
+ ```
7
+
8
+ Inside the module being tested will result in all JSON files contained being merged into all OS specific factsets used for testing as generated by `pdqtest generate_rspec`.
9
+
10
+ To put it simply, drop `.json` file(s) in this directory to add them to every factset. These facts will be made automatically avaialable to facter when running acceptance testing
@@ -0,0 +1,26 @@
1
+ # Puppet module dependencies
2
+ To test your puppet code, PDQTest needs to configured to obtain any modules the code being tested depends on.
3
+
4
+ ## Specifying dependencies
5
+
6
+ ### Public modules (PuppetForge)
7
+ Dependencies on public forge modules must be specified in your module's `metadata.json` file.
8
+
9
+ ### Private modules (from git)
10
+ If you need to download modules from git, then you must populate the `fixtures` section of `fixtures.yml`, eg:
11
+
12
+ ```
13
+ repositories:
14
+ corporatestuff:
15
+ repo: 'https://nonpublicgit.megacorp.com/corporatestuff.git'
16
+ ref: 'mybranch'
17
+ ```
18
+
19
+
20
+ ## .fixtures.yml
21
+ There is no need to maintain a `.fixtures.yml` file and the presence of this file when using `pdqtest` is an error.
22
+
23
+ ## Notes:
24
+ * The filename is for private modules is `fixtures.yml` NOT `.fixtures.yml`. The leading dot had to be removed to avoid `puppetlabs_spec_helper` also detecting the file and trying to use it.
25
+ * The file format of `.fixtures.yml` and `fixtures.yml` for specifing git repositories is identical
26
+ * Only the repositories section of the file will be processed as we do not use `puppetlabs_spec_helper` to do this for us.
@@ -0,0 +1,38 @@
1
+ # Running tests
2
+ If you just want to run all tests:
3
+
4
+ ```shell
5
+ make
6
+ ```
7
+
8
+ Alternatively, you can choose to run individul test phases directly:
9
+
10
+ ## All tests (excludes documentation)
11
+
12
+ ```shell
13
+ bundle exec pdqtest all
14
+ ```
15
+
16
+ ### Syntax
17
+
18
+ ```shell
19
+ bundle exec pdqtest syntax
20
+ ```
21
+
22
+ ### Lint
23
+
24
+ ```shell
25
+ bundle exec pdqtest lint
26
+ ```
27
+
28
+ ### RSpec
29
+
30
+ ```shell
31
+ bundle exec pdqtest rspec
32
+ ```
33
+
34
+ ### Acceptance
35
+
36
+ ```shell
37
+ bundle exec pdqtest acceptance
38
+ ```
@@ -0,0 +1,34 @@
1
+ # Test Generation
2
+ Creating a bunch of files manually is an error prone and tedious operation so PDQTest can generate files and boilerplate code for you so that your up and running in the quickest time possible.
3
+
4
+
5
+ ## RSpec tests
6
+ The skeleton tests created by `pdqtest init` only cover the `init.pp` file which is useful but your likely going to need to support more classes as your modules grow. PDQTest can generate basic RSpec testcases for each new puppet **class** that exists in the manifests directory for you:
7
+
8
+ ```shell
9
+ bundle exec pdqtest generate_rspec
10
+ ```
11
+
12
+ * For every `.pp` file containing a puppet class under `/manifests`, RSpec will be generated to:
13
+ * Check the catalogue compiles
14
+ * Check the catalogue contains an instance of the class
15
+
16
+ This gives developers an easy place to start writing additional RSpec tests for specific behaviour
17
+
18
+ Its safe to run this command whenever you add a new class, it won't overwrite any existing RSpec testcases
19
+
20
+ ## Acceptance tests
21
+
22
+ Generate boilerplate files for each example found (including those without a magic marker):
23
+
24
+ ```shell
25
+ pdqtest generate_acceptance
26
+ ```
27
+
28
+ Generate boilerplate files for one specific example:
29
+
30
+ ```shell
31
+ pdqtest generate_acceptance examples/mynewthing.pp
32
+ ```
33
+
34
+ Note: This will also create examples/mynewthing.pp if you haven't created it yet
@@ -0,0 +1,13 @@
1
+ # Tips and tricks
2
+ * You can put any puppet code you like (including an empty file...) in each of the files under `/examples` and it will executed with `puppet apply`
3
+ * If you need to test multiple different things (eg different parameters for a new type and provider), you need to create a different (acceptance) testcase for each distinct thing to test
4
+ * PDQTest will only execute the BATS tests and setup scripts that are present, you can delete some or all of these files if some steps aren't required.
5
+ * If no files are present under `spec/acceptance` for a given example, then PDQTest will just check that puppet runs idempotently for your example
6
+ * To disable tests temporarily for a specific example, remove the magic marker `#@PDQTest` from the desired example
7
+ * Nested examples (subdirectories) are not supported at this time
8
+ * Since the all of the `*__setup.sh` scripts are run in the container as root before executing tests, they can be used to mock _almost anything_ in the test system:
9
+ * Replace system binaries to fake network operations
10
+ * Add system binaries to simulate other operating systems such as AIX, Solaris, etc
11
+ * Create/copy files, directories, etc.
12
+ * Install OS packages
13
+ * Install python scripts to mock database servers using SQLite... :wink:
@@ -0,0 +1,8 @@
1
+ # Troubleshooting
2
+ * If you can't find the `pdqtest` command and your using `rbenv` be sure to run `rbenv rehash` after installing the gem to create the necessary symlinks
3
+ * Don't forget to run `pdqtest setup` before your first `pdqtest` run to download/update the Docker image
4
+ * If you need to access private git repositories, make sure to use `fixtures.yml` not `.fixtures.yml`
5
+ * If you need a private key to access private repositories, set this up for your regular git command/ssh and `pdqtest` will reuse the settings
6
+ * Be sure to annotate the examples you wish to acceptance test with the magic marker comment `#@PDQTest`
7
+ * Sometimes you might get an error: `Could not resolve the dependencies.` when executing tests. This message is from librarian puppet and usually indicates a conflict between the `metadata.json` files somewhere in the set of modules you are attempting to use or the presence of a `Puppetfile` in a directory above the module your testing. Running the command `librarian-puppet install --path spec/fixtures/ --destructive --verbose` should give you enough information to resolve the error
8
+ * Be sure to run `make` or `bundle exec pdqtest all` to download dependencies when running acceptance tests. Previous versions (re)downloaded modules as required from inside docker but this step has been replaced with a simple symlink to reduce the amount of downloading so the modules must already be present.
data/doc/upgrading.md ADDED
@@ -0,0 +1,28 @@
1
+ # Upgrading
2
+ To upgrade the current version of PDQTest on your system:
3
+
4
+ ```
5
+ gem update pdqtest
6
+ ```
7
+
8
+ Each project you want to use the newer version of PDQTest on should then have it's `Gemfile` updated to reference the latest version. Don't worry, this is easy:
9
+
10
+ ```shell
11
+ cd /my/cool/project/to/upgrade
12
+ pdqtest upgrade
13
+ bundle install
14
+ ```
15
+
16
+ Note that since we're using bundler, you only have to upgrade the modules you want to upgrade. Existing modules can continue to run any previous version via `make` just fine.
17
+
18
+ ## Docker image
19
+ The docker image will be updated as and when required. Run:
20
+
21
+ ```shell
22
+ pdqtest setup
23
+ ```
24
+
25
+ To obtain the latest version.
26
+
27
+ ## `/cut`
28
+ Previous versions of PDQTest mounted code at `/cut` (Code Under Test), this will still work for a few versions but the preferred mountpoint is now the more obvious `/testcase`
data/exe/pdqtest CHANGED
@@ -1,4 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ ruby_have = Gem::Version.new(RUBY_VERSION)
4
+ ruby_need = Gem::Version.new('2.2.0')
5
+
6
+ if (ruby_have <=> ruby_need) == -1
7
+ raise "Please upgrade Ruby to at least #{ruby_need.version}"
8
+ end
9
+
10
+
2
11
  require 'pdqtest'
3
12
  require 'pdqtest/emoji'
4
13
  require 'pdqtest/instance'
@@ -8,6 +17,7 @@ require 'pdqtest/skeleton'
8
17
  require 'pdqtest/lint'
9
18
  require 'pdqtest/syntax'
10
19
  require 'pdqtest/core'
20
+ require 'pdqtest/upgrade'
11
21
  require 'escort'
12
22
 
13
23
  # display help if nothing specified
@@ -163,4 +173,12 @@ Escort::App.create do |app|
163
173
  end
164
174
  end
165
175
 
176
+
177
+ app.command :upgrade do |command|
178
+ command.summary "Upgrade"
179
+ command.description "Upgrade the current module to use this version of PDQTest"
180
+ command.action do |options, arguments|
181
+ PDQTest::Upgrade.upgrade
182
+ end
183
+ end
166
184
  end
@@ -3,6 +3,7 @@ require 'digest'
3
3
  require 'pdqtest/puppet'
4
4
  require 'pdqtest/version'
5
5
  require 'pdqtest/util'
6
+ require 'pdqtest/upgrade'
6
7
 
7
8
  module PDQTest
8
9
  module Skeleton
@@ -14,7 +15,6 @@ module PDQTest
14
15
  SKELETON_DIR = 'skeleton'
15
16
  EXAMPLES_DIR = 'examples'
16
17
  GEMFILE = 'Gemfile'
17
- GEMFILE_LINE = "gem 'pdqtest', '#{PDQTest::VERSION}'"
18
18
  HIERA_DIR = File.join(SPEC_DIR, 'fixtures', 'hieradata')
19
19
  HIERA_YAML = 'hiera.yaml'
20
20
  HIERA_TEST = 'test.yaml'
@@ -54,20 +54,10 @@ module PDQTest
54
54
  end
55
55
 
56
56
  def self.install_gemfile
57
- insert_gem = false
58
- if File.exists?(GEMFILE)
59
- if ! File.readlines(GEMFILE).grep(/pdqtest/).any?
60
- insert_gem = true
61
- end
62
- else
63
- install_skeleton(GEMFILE, GEMFILE)
64
- insert_gem = true
65
- end
66
- if insert_gem
67
- open(GEMFILE, 'a') { |f|
68
- f.puts GEMFILE_LINE
69
- }
70
- end
57
+ install_skeleton(GEMFILE, GEMFILE)
58
+
59
+ # upgrade the gemfile to *this* version of pdqtest + puppet-strings
60
+ Upgrade.upgrade()
71
61
  end
72
62
 
73
63
  def self.init
@@ -81,6 +71,7 @@ module PDQTest
81
71
  FileUtils.mkdir_p(ACCEPTANCE_DIR)
82
72
  FileUtils.mkdir_p(CLASSES_DIR)
83
73
  FileUtils.mkdir_p(EXAMPLES_DIR)
74
+ FileUtils.mkdir_p(HIERA_DIR)
84
75
 
85
76
 
86
77
  # skeleton files if required
@@ -1,4 +1,11 @@
1
- require 'puppet-syntax/tasks/puppet-syntax'
1
+ # Ask user to install puppet gem if missing. It's not in the bundle to avoid
2
+ # the issue of accidentally installing the puppet gem on a managed node.
3
+ # Fixes #21
4
+ begin
5
+ require 'puppet-syntax/tasks/puppet-syntax'
6
+ rescue LoadError
7
+ raise "Please install the puppet gem: `gem install puppet`"
8
+ end
2
9
  require 'pdqtest'
3
10
  require 'pdqtest/emoji'
4
11
  module PDQTest
@@ -0,0 +1,63 @@
1
+ module PDQTest
2
+ module Upgrade
3
+ GEMFILE = 'Gemfile'
4
+ GEM_REGEXP = /gem ('|")([-\w]+)('|").*$/
5
+ GEM_ATTRIB_REGEXP = /^\s*:\w+/
6
+
7
+ GEMS = {
8
+ 'pdqtest' => {
9
+ 'line' => "gem 'pdqtest', '#{PDQTest::VERSION}'",
10
+ 'added' => false,
11
+ },
12
+ 'puppet-strings' => {
13
+ 'line' => "gem 'puppet-strings', :git => 'https://github.com/puppetlabs/puppet-strings'",
14
+ 'added' => false,
15
+ },
16
+ }
17
+
18
+
19
+ # upgrade a module to the latest version of PDQTest
20
+ def self.upgrade()
21
+ t_file = File.open("#{GEMFILE}.tmp","w")
22
+ updating_gem = false
23
+ File.open(GEMFILE, 'r') do |f|
24
+ f.each_line{ |line|
25
+ if line =~ GEM_REGEXP
26
+ # a gem stanza
27
+ processing_gem = $2
28
+ if GEMS.keys.include?(processing_gem)
29
+ # fixup one of our monitored gems as needed, mark
30
+ # this as being a gem that is being updated so
31
+ # that we can kill any multi-line attributes
32
+ t_file.puts GEMS[processing_gem]['line']
33
+ updating_gem = true
34
+ GEMS[processing_gem]['added'] = true
35
+ else
36
+ # a gem we don't care about - write it out as-is
37
+ t_file.puts line
38
+ updating_gem = false
39
+ end
40
+ elsif updating_gem and line =~ GEM_ATTRIB_REGEXP
41
+ # do nothing - remove the multi-line attributes
42
+ else
43
+ # anything else... (esp comments)
44
+ t_file.puts line
45
+ end
46
+ }
47
+ end
48
+
49
+ # the code above will only UPGRADE existing gem lines, but if this is our
50
+ # first run, there will be nothing to upgrade, so loop through the GEMS
51
+ # for any that are not already added and append them
52
+ GEMS.each { |name, opts|
53
+ if ! opts['added']
54
+ t_file.puts opts['line']
55
+ end
56
+ }
57
+
58
+ t_file.close
59
+ FileUtils.mv(t_file.path, GEMFILE)
60
+ end
61
+
62
+ end
63
+ end
@@ -1,3 +1,3 @@
1
1
  module PDQTest
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.1"
3
3
  end
data/pdqtest.gemspec CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "bundler", ">= 1.14.3"
26
26
  spec.add_development_dependency "rake", "12.0.0"
27
27
  spec.add_development_dependency "rspec", "3.5.0"
28
- spec.add_development_dependency "simplecov", "0.12.0"
28
+ spec.add_development_dependency "coveralls"
29
29
  spec.add_development_dependency "fakefs", "0.10.2"
30
30
  spec.add_development_dependency "puppet", "4.8.2"
31
31
 
data/res/skeleton/Gemfile CHANGED
@@ -7,7 +7,3 @@ gem 'puppet', '4.9.0'
7
7
  gem 'facter', '2.4.6'
8
8
  gem 'rubocop', '0.47.1'
9
9
  gem 'rspec-puppet-facts', '1.7.0'
10
-
11
- # Workaround for PDOC-160 (until gem published)
12
- gem 'puppet-strings',
13
- :git => 'https://github.com/puppetlabs/puppet-strings',
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdqtest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoff Williams
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-29 00:00:00.000000000 Z
11
+ date: 2017-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,19 +53,19 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 3.5.0
55
55
  - !ruby/object:Gem::Dependency
56
- name: simplecov
56
+ name: coveralls
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 0.12.0
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 0.12.0
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: fakefs
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -223,6 +223,20 @@ files:
223
223
  - Rakefile
224
224
  - bin/console
225
225
  - bin/setup
226
+ - doc/acceptance_tests.md
227
+ - doc/caching.md
228
+ - doc/development.md
229
+ - doc/enabling_testing.md
230
+ - doc/examples.md
231
+ - doc/hiera.md
232
+ - doc/installation.md
233
+ - doc/puppet_facts.md
234
+ - doc/puppet_module_dependencies.md
235
+ - doc/running_tests.md
236
+ - doc/test_generation.md
237
+ - doc/tips_and_tricks.md
238
+ - doc/troubleshooting.md
239
+ - doc/upgrading.md
226
240
  - docker_images/centos/Dockerfile
227
241
  - docker_images/centos/Makefile
228
242
  - exe/pdqtest
@@ -236,6 +250,7 @@ files:
236
250
  - lib/pdqtest/rspec.rb
237
251
  - lib/pdqtest/skeleton.rb
238
252
  - lib/pdqtest/syntax.rb
253
+ - lib/pdqtest/upgrade.rb
239
254
  - lib/pdqtest/util.rb
240
255
  - lib/pdqtest/version.rb
241
256
  - pdqtest.gemspec