beaker 2.48.1 → 2.49.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MWIxODZmNmI0MzNjNWYwZDVlYjk0NmQyNGNiYjJlOThmMDIxY2MzYw==
4
+ ZWI4OTU0ZmQ1MGYzNmMxMzkwOWNlM2RmZjQzY2ZhZGIyMDc3MDdiNA==
5
5
  data.tar.gz: !binary |-
6
- ZDEzZjdlYzQyMWEwZjNjY2Y1Mzk5NDRiODhkYzYwNzU3NzZiZDM3Mw==
6
+ YWZiN2EwY2Y4NDMwNjRhODZiNjZjZmU4ZTU5YzVlMzBhZTk2ZmI1Nw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NDYwYmY3M2FkMDNmMDhiZjg4ZmZlZGY4YmZkMmM4Njc1OTQxYmQ5MDQxZDkx
10
- NmU1YmQ1NjdkMjczYjExMmIzODBjZGNjNWM2NDI1ZWMwZmU2ZTliNGM3MzYz
11
- MzVkZGE0YmQ5M2U2YjhlMTliY2U0ZWQ3YmNjZTQwMDFkNzI1OTE=
9
+ ZjI3YmQwZDJlMGI2OGI1OGJhMGE5YmUzMjZmNGM2ZjViODQ4MzBhYTYzMTNm
10
+ Zjg3OGVkMThhZDdiMmMwNWMyNzM3ZTNiZTY3ZTBhOTRkYjk2MTVmMTZmMmQ2
11
+ NjFmN2Y3MjkyY2VmYzQyZGJkZGI4ZmY5ZmNhNmY3OTA0MGI1YWE=
12
12
  data.tar.gz: !binary |-
13
- ZjcwMTliODIwMjlhMTA3NTgwYTViYmY4OGUyNDhkNDM2OWNlYzllYmZmZTdk
14
- MjNkOTAyNWNiMTJhMDc3NWQ0ZGIyMjA2MDM0OTQ5ODc5ZjUxODdhNWU4YjU0
15
- N2I1MWYzYmEyYTJlMmUxOWVjMDMzMzFjMGM5NzYwYmM3NGQ4Y2Y=
13
+ YjU4YzYzMTZiMGVkNTk3ODQ0M2Q4Njk1OTQzNDJlMzkzNjNkYmE0ZTcxMWNh
14
+ YmM0OTMxYjA4NjBhOGQ4MjU2YzM2YWYzZjZiZGQ2YzI4NWExZmMxZDRiZTYx
15
+ NGFmODM4ZDJiNDA1N2NmNDJiZmUyM2NkMGY0NWYyYTM5ZTYyNTA=
@@ -11,9 +11,8 @@
11
11
 
12
12
  ## Making Changes
13
13
 
14
- * Create a topic branch from where you want to base your work.
15
- * This is the `master` branch in the case of Beaker
16
- * To quickly create a topic branch based on master use `git checkout -b my_contribution master`. Please avoid working directly on the `master` branch.
14
+ * Create a topic branch from your fork of [puppetlabs/beaker](https://github.com/puppetlabs/beaker).
15
+ * Please title the branch after the beaker ticket you intend to address, ie `BKR-1234`.
17
16
  * Make commits of logical units.
18
17
  * Check for unnecessary whitespace with `git diff --check` before committing.
19
18
  * Make sure your commit messages are in the proper format.
data/HISTORY.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # default - History
2
2
  ## Tags
3
- * [LATEST - 29 Jul, 2016 (90d15165)](#LATEST)
3
+ * [LATEST - 11 Aug, 2016 (966f74b9)](#LATEST)
4
+ * [2.48.1 - 29 Jul, 2016 (e5a52ad4)](#2.48.1)
4
5
  * [2.48.0 - 27 Jul, 2016 (47d3aa18)](#2.48.0)
5
6
  * [2.47.1 - 15 Jul, 2016 (da89c35b)](#2.47.1)
6
7
  * [2.47.0 - 13 Jul, 2016 (bf4cbcf0)](#2.47.0)
@@ -126,7 +127,182 @@
126
127
  * [pe1.2 - 6 Sep, 2011 (ba3dadd2)](#pe1.2)
127
128
 
128
129
  ## Details
129
- ### <a name = "LATEST">LATEST - 29 Jul, 2016 (90d15165)
130
+ ### <a name = "LATEST">LATEST - 11 Aug, 2016 (966f74b9)
131
+
132
+ * (GEM) update beaker version to 2.49.0 (966f74b9)
133
+
134
+ * (BKR-783) Confusing error messages when key missing from .fog file (#1216) (581ece1f)
135
+
136
+ * Merge pull request #1217 from kevpl/bkr910_epel7_url_fix (4bf3269e)
137
+
138
+
139
+ ```
140
+ Merge pull request #1217 from kevpl/bkr910_epel7_url_fix
141
+
142
+ (BKR-910) fixed EPEL URL, added tests to detect changes
143
+ ```
144
+ * Merge pull request #1210 from ferglor/BKR-892 (751e3827)
145
+
146
+
147
+ ```
148
+ Merge pull request #1210 from ferglor/BKR-892
149
+
150
+ BKR-892 Generalize how beaker determines run_in_parallel option
151
+ ```
152
+ * (BKR-910) fixed EPEL URL, added tests to detect changes (417614c8)
153
+
154
+ * Merge pull request #1197 from kevpl/docs_style_guide (95225217)
155
+
156
+
157
+ ```
158
+ Merge pull request #1197 from kevpl/docs_style_guide
159
+
160
+ (BKR-80) created style guide for beaker tests
161
+ ```
162
+ * Output informational message at debug level. (#1209) (5e8b4ced)
163
+
164
+
165
+ ```
166
+ Output informational message at debug level. (#1209)
167
+
168
+ (MAINT) Output informational message at debug level
169
+
170
+ The previous behavior output this as a warning message, causing it to
171
+ appear in red with the default configuration which is probably not
172
+ desired since this is expected in normal conditions.
173
+ ```
174
+ * Merge pull request #1203 from kurtwall/use-pretty-generate (24adf82b)
175
+
176
+
177
+ ```
178
+ Merge pull request #1203 from kurtwall/use-pretty-generate
179
+
180
+ (MAINT) Use JSON.pretty_generate to create JSON output
181
+ ```
182
+ * (MAINT) Document how to do ssh agent forwarding. (#1208) (bb17ae34)
183
+
184
+
185
+ ```
186
+ (MAINT) Document how to do ssh agent forwarding. (#1208)
187
+
188
+ * Document how to do ssh agent forwarding.
189
+
190
+ I literally spent hours understanding that the `@option` / `option` hash
191
+ was coming from the `CONFIG` section… Such a howto would have saved my
192
+ day :-)
193
+
194
+ * Clarify what a 'host machine' is.
195
+
196
+ Suggested by: @kevpl
197
+ ```
198
+ * Merge pull request #1191 from samwoods1/teardown_errors (9f540f37)
199
+
200
+
201
+ ```
202
+ Merge pull request #1191 from samwoods1/teardown_errors
203
+
204
+ (BKR-570) Errors in teardown do not obscure errors in test
205
+ ```
206
+ * Merge pull request #1211 from tvpartytonight/maint_add_PR_request_procedure (5f43a8f3)
207
+
208
+
209
+ ```
210
+ Merge pull request #1211 from tvpartytonight/maint_add_PR_request_procedure
211
+
212
+ (MAINT) Modify PR instructions
213
+ ```
214
+ * (MAINT) Modify PR instructions (5a433ecd)
215
+
216
+ * BKR-892 Generalize how beaker determines run_in_parallel option (80f3e1bb)
217
+
218
+ * Update last spec test (066094bb)
219
+
220
+ * Merge branch 'master' of https://github.com/puppetlabs/beaker into use-pretty-generate (0a33b21e)
221
+
222
+ * Merge pull request #1200 from johnduarte/bkr-894-aix-dns (ec2657eb)
223
+
224
+
225
+ ```
226
+ Merge pull request #1200 from johnduarte/bkr-894-aix-dns
227
+
228
+ (BKR-894) AIX - prefer local DNS if hosts file changed
229
+ ```
230
+ * Merge pull request #1187 from samwoods1/log_at_failure (63920f57)
231
+
232
+
233
+ ```
234
+ Merge pull request #1187 from samwoods1/log_at_failure
235
+
236
+ (BKR-890) Surface and provide more visibility into where failures occured
237
+ ```
238
+ * Merge pull request #1204 from kevpl/docs_file_archiving (e1f3bd51)
239
+
240
+
241
+ ```
242
+ Merge pull request #1204 from kevpl/docs_file_archiving
243
+
244
+ (MAINT) added archiving SUT files doc
245
+ ```
246
+ * Merge pull request #1205 from tvpartytonight/maint_fix_folder_link (e8835781)
247
+
248
+
249
+ ```
250
+ Merge pull request #1205 from tvpartytonight/maint_fix_folder_link
251
+
252
+ (MAINT) Fix link to folder from /doc README
253
+ ```
254
+ * (MAINT) Fix link to folder from /doc README (2c651e99)
255
+
256
+ * (MAINT) added archiving SUT files doc (1bcce26d)
257
+
258
+
259
+ ```
260
+ (MAINT) added archiving SUT files doc
261
+
262
+ [skip ci]
263
+ ```
264
+ * (MAINT) Use JSON.pretty_generate instead of JSON.dump to create JSON (4a98bf79)
265
+
266
+
267
+ ```
268
+ (MAINT) Use JSON.pretty_generate instead of JSON.dump to create JSON
269
+ for TK config files.
270
+
271
+ JSON.dump ruins the formatting of JSON files, which can make TK config
272
+ files difficult to read. This commit replaces .dump with .pretty_generate
273
+ to preserve config file formatting and readability.
274
+ ```
275
+ * (BKR-894) AIX - prefer local DNS if hosts file changed (d5a3363e)
276
+
277
+
278
+ ```
279
+ (BKR-894) AIX - prefer local DNS if hosts file changed
280
+
281
+ This commit adds logic to the `set_etc_hosts` method to change the
282
+ preferred DNS resolution order on AIX platforms.
283
+
284
+ By default, AIX will first use external DNS to resolve a name even
285
+ if the name has an entry in the `/etc/hosts` file. This means that
286
+ an externally resolvable hostname cannot be overridden by a local
287
+ entry in `/etc/hosts` unless the resolution order is changed. The
288
+ logic added with this commit adds the configuration to give precedence
289
+ to local DNS resolution.
290
+ ```
291
+ * (BKR-80) created style guide for beaker tests (db298c85)
292
+
293
+
294
+ ```
295
+ (BKR-80) created style guide for beaker tests
296
+
297
+ [skip ci]
298
+ ```
299
+ * (BKR-570) Errors in teardown do not obscure errors in test (19208967)
300
+
301
+ * (BKR-890) Log failure info and stack inline in log. (671c5ea7)
302
+
303
+ ### <a name = "2.48.1">2.48.1 - 29 Jul, 2016 (e5a52ad4)
304
+
305
+ * (HISTORY) update beaker history for gem release 2.48.1 (e5a52ad4)
130
306
 
131
307
  * (GEM) update beaker version to 2.48.1 (90d15165)
132
308
 
@@ -0,0 +1,34 @@
1
+ test_name 'External Resources Test' do
2
+ step 'Verify EPEL is correct' do
3
+ def epel_url_test(el_version, arch, pkg_key)
4
+ url = "#{@options[:epel_url]}/#{el_version}/#{arch}/#{@options[pkg_key]}"
5
+ curl_headers_result = default.exec(Command.new("curl -I #{url}"))
6
+ assert_match(/200 OK/, curl_headers_result.stdout, "EPEL #{el_version} should be reachable")
7
+ end
8
+
9
+ step 'arch is i386' do
10
+ @arch = 'i386'
11
+ # epel-7 does not provide packages for i386
12
+ step 'EPEL 6' do
13
+ epel_url_test(6, @arch, :epel_6_pkg)
14
+ end
15
+ step 'EPEL 5' do
16
+ epel_url_test(5, @arch, :epel_5_pkg)
17
+ end
18
+ end
19
+
20
+ step 'arch is x86_64' do
21
+ @arch = 'x86_64'
22
+ step 'EPEL 7' do
23
+ # note: interpolation gets around URL change for epel 7
24
+ epel_url_test(7, "#{@arch}/e", :epel_7_pkg)
25
+ end
26
+ step 'EPEL 6' do
27
+ epel_url_test(6, @arch, :epel_6_pkg)
28
+ end
29
+ step 'EPEL 5' do
30
+ epel_url_test(5, @arch, :epel_5_pkg)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,6 +1,6 @@
1
1
  ![Beaker Muppet Image](http://images4.wikia.nocookie.net/__cb20101015151248/muppet/images/0/05/Beaker.jpg)
2
2
 
3
- Documentation for Beaker can be found in this repository in [the docs/ folder](README.md).
3
+ Documentation for Beaker can be found in this repository in [the docs/ folder]().
4
4
 
5
5
  ## Table of Contents
6
6
 
@@ -0,0 +1,216 @@
1
+ # Beaker Style Guide
2
+
3
+ ## Scope of this guide
4
+
5
+ The purpose of this guide is to provide definitions for best practices when
6
+ writing Beaker tests, both syntactically and stylistically. This guide will
7
+ define and provide examples for preferred test layout and conventions. Common
8
+ patterns that are recommended as well as patterns that should be avoided will be
9
+ described.
10
+
11
+ No style manual can cover every possible circumstance. When a judgement call
12
+ becomes necessary, keep in mind the following general ideas:
13
+
14
+ 1. **Readability matters**. If you have to choose between two equally effective
15
+ alternatives, pick the more readable one. This is, of course, subjective, but if
16
+ you can read your own code three months from now, that's a great start. Don't be
17
+ clever over readable, unless you have a documented purpose. Use object oriented
18
+ programming when things get complex and
19
+ [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself).
20
+ 2. **Inherit upstream conventions**. Beaker is still ruby, so use the
21
+ [ruby community style guide](https://github.com/bbatsov/ruby-style-guide). When
22
+ not called out here, use the ruby style guide.
23
+
24
+ ## Test Naming
25
+
26
+ Tests should test what they say they test. Test names, both the name of the test
27
+ file and the value given to the
28
+ [`test_name`](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Structure#test_name-instance_method)
29
+ function, should provide an accurate indication about the purpose of the test.
30
+
31
+ The `test_name` function should be the first line in the Beaker test file.
32
+
33
+ **Good:**
34
+ ```ruby
35
+ # head -1 puppet/acceptance/tests/resource/file/should_default_mode.rb
36
+ test_name "file resource: set default modes" do
37
+ ```
38
+
39
+ ## Structure Methods Should Use Explicit Blocks
40
+
41
+ These methods aid in self-documenting your tests, including indention in the
42
+ logs. If you don't use explicit blocks, beaker does not know how to properly
43
+ indent your test's output.
44
+
45
+ The most common
46
+ [structure methods](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Structure)
47
+ are
48
+ [`#test_name`](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Structure#test_name-instance_method),
49
+ [`#step`](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Structure#step-instance_method),
50
+ and
51
+ [`#teardown`](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Structure#teardown-instance_method).
52
+
53
+ **Good:**
54
+ ```ruby
55
+ step 'do this thang' do
56
+ on(host, "echo 'do this thang'")
57
+ end
58
+ ```
59
+ **Bad:**
60
+ ```ruby
61
+ step 'do this thang'
62
+ on(host, "echo 'do this thang'")
63
+ ```
64
+
65
+ ## Teardowns
66
+
67
+ - Return the state of the system to the way it was prior to test execution
68
+ - Put the teardown as early in the test as possible
69
+
70
+ Teardowns must be used to return the system to the state it was in prior to the
71
+ execution or attempted execution of the test. Beaker will gather all teardowns
72
+ encountered throughout the execution path of the test. These teardowns will all
73
+ be executed when the test exits, even if the test exits early due to a failure
74
+ or error.
75
+
76
+ ### Place Teardowns Early
77
+
78
+ Teardowns can be placed anywhere in the test file or its helpers. The preferred
79
+ style is to have a teardown step near the beginning of the test file to show the
80
+ reader that the system state will be restored.
81
+
82
+ **Good:**
83
+ ```ruby
84
+ test_name 'The source attribute' do
85
+
86
+ target_file_on_nix = '/tmp/source_attr_test'
87
+ teardown do
88
+ hosts.each do |host|
89
+ on(host, "rm #{target_file_on_nix}", :accept_all_exit_codes => true) unless host['platform'] =~ /^win/
90
+ end
91
+ end
92
+ ...
93
+ end
94
+ ```
95
+
96
+ Teardowns are at the mercy of the scoping of the variables necessary to perform
97
+ the restoration of the system. This fact means that additional teardown steps
98
+ will need to be added within the scope necessary to do their job. Effort should
99
+ be taken to make the teardown steps prominent and readable so that it can be
100
+ confirmed, via the logs, that the system has been restored.
101
+
102
+ Teardown steps registered outside of tests should use
103
+ [`#step`](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Structure#step-instance_method)
104
+ to document and log what they are doing.
105
+
106
+ ## Acceptable Exit Codes
107
+
108
+ When using the Beaker
109
+ [`on`](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Helpers/HostHelpers#on-instance_method)
110
+ method, the default setting is that only an exit code of 0 (zero) will not
111
+ trigger an error. When other exit codes are acceptable, the
112
+ `:acceptable_exit_codes` key with an array of exit codes should be passed in the
113
+ options hash to `#on`. If 0 (zero) is the only acceptable exit code, then the
114
+ `:acceptable_exit_codes` symbol must not be used.
115
+
116
+ **Good:**
117
+
118
+ - Single 0 exit code allowed
119
+ ```ruby
120
+ on(host, "rm #{file_to_rm}")
121
+ ```
122
+ - Single non-0 exit code allowed
123
+ ```ruby
124
+ on(host, "rm #{file_to_rm}", :acceptable_exit_codes => 1)
125
+ ```
126
+ - Multiple exit codes allowed
127
+ ```ruby
128
+ on(host, "rm #{file_to_rm}", :acceptable_exit_codes => [0,1])
129
+ ```
130
+ - Any exit code allowed
131
+ ```ruby
132
+ on(host, "rm #{file_to_rm}", :accept_all_exit_codes => true)
133
+ ```
134
+
135
+ In the last case, when any exit code is allowed, one must follow-up with a valid
136
+ assertion test.
137
+
138
+ If an exit_code outside of 0 is expected, one must use acceptable_exit_codes so
139
+ the test will fail on the proper assertion and not error at that command. Allow
140
+ only the minimum expected set of exit codes unless coverage is provided by
141
+ subsequent assertions.
142
+
143
+ ## Test Outcomes
144
+
145
+ When to use each, and how to format the message:
146
+
147
+ ### Expecting Failure
148
+
149
+ If your tests are failing due to an "expected failure", you should wrap your
150
+ failing assertion in an
151
+ [`expect_failure`](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Structure#expect_failure-instance_method)
152
+ block with an explanatory logging message:
153
+
154
+ ```ruby
155
+ expect_failure('expected to fail due to PE-1234') do
156
+ assert_equal(400, response.code, 'bad response code from API call')
157
+ end
158
+ ```
159
+
160
+ Note that `expect_failure` will only trigger from failed assertions. It won't
161
+ take care of failed host or `on` commands. To deal with expected failure from an
162
+ `on` invocation, you'd want something more like this:
163
+
164
+ ```ruby
165
+ on(blah, 'blah', :allow_all_exit_codes => true) do |result|
166
+ expect_failure 'known issue: TIK-1234' do
167
+ assert_equal(4,result.exit_code,'did not receive expected exit code for blah')
168
+ end
169
+ end
170
+ ```
171
+
172
+ ### `fail_test`, `pass_test`, & `skip_test`
173
+
174
+ These can be used anywhere in a test to exit early. A
175
+ [`skip_test`](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Outcomes#fail_test-instance_method)
176
+ between two assertions, for instance, will run the first assertion, raise an
177
+ exception for `skip_test`, run teardown, and then exit as we expect. The same is
178
+ true for
179
+ [fail_test](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Outcomes#fail_test-instance_method).
180
+
181
+ [`pass_test`](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Outcomes#fail_test-instance_method)
182
+ is typically not required. When the end of a test is reached without causing an
183
+ error (due to bad test code execution, or an unhandled exit code or exception)
184
+ or failure (due to assertions), then it passes.
185
+
186
+ `pass_test` can be used in a situation where one knows a test has passed before
187
+ the end of a test under certain circumstances, such as during a loop that has
188
+ not yet completed.
189
+
190
+ ### Skipping Tests
191
+
192
+ Skipping tests can be used, for instance, when they are temporarily failing or
193
+ not yet complete.
194
+
195
+ **Good:**
196
+ ```ruby
197
+ skip_test 'requires puppet and mcollective service scripts from AIO agent package' if @options[:type] != 'aio'
198
+ ```
199
+ **Bad:**
200
+ ```ruby
201
+ confine :to, :platform => 'solaris:pending'
202
+ ```
203
+
204
+ ## Confining
205
+
206
+ Another way that you can skip or manipulate tests is by confining them to apply
207
+ to a subset of the SUTs available for testing. Confining is a complex topic, and
208
+ one we don't have the length to get into in the style guide. For an explanation
209
+ of confining, as well as the best practices in using it, check out our
210
+ [confine doc](../how_to/confine.md).
211
+
212
+ ## Assertions
213
+
214
+ Always include a _unique_ error message in your assertion statement. Use strict
215
+ asserts whenever possible (e.g. assert_equal, assert_match.
216
+ [More info](http://danwin.com/2013/03/ruby-minitest-cheat-sheet/)).
@@ -0,0 +1,31 @@
1
+ # How to Archive Files from the Systems Under Test (SUTs)
2
+
3
+ Oftentimes when you're dealing with beaker test development or troubleshooting
4
+ a failed acceptance test, you'll need to get information from a SUT. The
5
+ traditional way that we've advocated getting information from these machines is
6
+ to use our [preserved hosts functionality](preserve_hosts.md).
7
+
8
+ If you're preserving hosts just to SSH in and look at log files, however, this
9
+ can be a tedious exercise. Why not just bring the log files to you on the
10
+ beaker coordinator? This doc explains exactly how to do that using our
11
+ `archive_file_from` Domain-Specific Language (DSL) method
12
+ ([method rubydocs](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Helpers/HostHelpers#archive_file_from-instance_method)).
13
+
14
+ # How Do I Use This?
15
+
16
+ `archive_file_from` is a part of the beaker DSL, so it's available in all test
17
+ suites. Just call it from your tests, and it'll execute, pulling any particular
18
+ file you need off your SUTs, and dropping it on your beaker coordinator's
19
+ file system.
20
+
21
+ A common example of a post-suite step to archive files that were created during
22
+ a particular test is included in the Rubydocs, referenced above. Path details,
23
+ and details of all method arguments are documented there as well. Check it out,
24
+ and with the right use, you won't need to preserve hosts at all to debug any
25
+ test failures.
26
+
27
+ # When Did This Come Out?
28
+
29
+ `archive_file_from` was originally added to the DSL in beaker
30
+ [2.48.0](https://github.com/puppetlabs/beaker/releases/tag/2.48.0), released on
31
+ [July 27, 2016](https://github.com/puppetlabs/beaker/blob/master/HISTORY.md#2480---27-jul-2016-47d3aa18).
@@ -7,6 +7,12 @@ If you don't see a file here for a hypervisor, then it's either not yet document
7
7
  (feel free to help us out here!), or it should conform to our normal hypervisor
8
8
  assumptions.
9
9
 
10
+ # Credentials File
11
+
12
+ Beaker uses credentials from a .fog file for authentication.
13
+ By default, the file is located under the user's home directory. This helps to keep the credentials confidential.
14
+ The path of .fog file can be changed by setting the 'dot_fog' option.
15
+
10
16
  # External Hypervisors
11
17
 
12
18
  There are a number of community-supported hypervisors that have not been added to
@@ -7,6 +7,24 @@ able to quickly iterate on those tests in an already setup System Under Test
7
7
  (SUT) configuration. Beaker provides the ability to do that using its preserved
8
8
  hosts functionality.
9
9
 
10
+ ## But Is This The Right Solution?
11
+
12
+ Many people are of the opinion that if you have to login to a SUT, then you've
13
+ already failed, and that the purpose of good automation is so that you don't
14
+ ever have to do this. Beaker supports a diverse group of developers and testers,
15
+ and we try to remain flexible and support multiple approaches to these problems.
16
+
17
+ Another approach you might take to debugging failed tests, during development or
18
+ test runs in your Continuous Integration (CI) systems, is to archive any
19
+ artifacts or log files from the SUTs, so that you can read them all from the
20
+ beaker coordinator. Beaker provides a Domain-Specific Language (DSL) method to
21
+ accomodate this workflow, called `archive_file_from`. Check out the
22
+ [how-to article](archive_sut_files.md) on this method for details on it.
23
+
24
+ That being said, the preserved hosts functionality is still useful, particularly
25
+ for new development. In this case, you might not be able to necessarily tell
26
+ what files you might need from your SUTs, and exploration might be necessary.
27
+
10
28
  ## How Do I Use It?
11
29
 
12
30
  Note that where you decide to use this option will affect its precedence. You
@@ -0,0 +1,31 @@
1
+ # How to Forward ssh(1) Agent
2
+
3
+ `ssh(1)` agent forwarding can is activated in the `CONFIG` section of the hosts
4
+ file:
5
+
6
+ ~~~yaml
7
+ HOSTS:
8
+ ...
9
+ CONFIG:
10
+ forward_ssh_agent: true
11
+ ~~~
12
+
13
+ Beaker will then make the ssh agent running on the beaker coordinator available to the Systems Under Test (SUT). There is
14
+ a gotcha though: the agent socket file in the SUT is only available
15
+ to the user who signed in. If you want to access remote machine resources as
16
+ another user, you *must* change the socket permission.
17
+
18
+ A dirty hack is to `chmod -R 777 /tmp/ssh-*` before changing to another user
19
+ and relying on `$SSH_AUTH_SOCK`.
20
+
21
+ Example:
22
+
23
+ ~~~puppet
24
+ exec { '/bin/chmod -R 777 /tmp/ssh-*':
25
+ } ->
26
+ vcsrepo { '/var/www/app':
27
+ provider => 'git',
28
+ source => 'https://example.com/git/app.git',
29
+ user => 'deploy'
30
+ }
31
+ ~~~
@@ -50,7 +50,7 @@ module Beaker
50
50
  new_hash.merge!(options_hash)
51
51
  end
52
52
 
53
- file_string = JSON.dump(new_hash)
53
+ file_string = JSON.pretty_generate(new_hash)
54
54
  create_remote_file host, config_file_path, file_string
55
55
  end
56
56
 
@@ -261,10 +261,8 @@ module Beaker
261
261
  else
262
262
  # Use option specified in the method call, otherwise check whether the global
263
263
  # run_in_parallel option includes install
264
- run_in_parallel = opts[:run_in_parallel]
265
- run_in_parallel = ((@options && @options[:run_in_parallel].is_a?(Array)) ?
266
- @options[:run_in_parallel].include?('install') : false) if run_in_parallel.nil?
267
- block_on hosts, { :run_in_parallel => run_in_parallel} do |host|
264
+ run_in_parallel = run_in_parallel? opts, @options, 'install'
265
+ block_on hosts, { :run_in_parallel => run_in_parallel } do |host|
268
266
  if host['platform'] =~ /el-(5|6|7)/
269
267
  relver = $1
270
268
  install_puppet_from_rpm_on(host, opts.merge(:release => relver, :family => 'el'))
@@ -340,9 +338,7 @@ module Beaker
340
338
  opts[:puppet_collection] ||= 'pc1' #hi! i'm case sensitive! be careful!
341
339
  opts[:puppet_agent_version] ||= opts[:version] #backwards compatability with old parameter name
342
340
 
343
- run_in_parallel = opts[:run_in_parallel]
344
- run_in_parallel = ((@options && @options[:run_in_parallel].is_a?(Array)) ?
345
- @options[:run_in_parallel].include?('install') : false) if run_in_parallel.nil?
341
+ run_in_parallel = run_in_parallel? opts, @options, 'install'
346
342
  block_on hosts, { :run_in_parallel => run_in_parallel } do |host|
347
343
  add_role(host, 'aio') #we are installing agent, so we want aio role
348
344
  package_name = nil
@@ -332,6 +332,14 @@ module Beaker
332
332
  else
333
333
  host.exec(Command.new("echo '#{etc_hosts}' >> /etc/hosts"))
334
334
  end
335
+ # AIX must be configured to prefer local DNS over external
336
+ if host['platform'] =~ /aix/
337
+ aix_netsvc = '/etc/netsvc.conf'
338
+ aix_local_resolv = 'hosts = local, bind'
339
+ unless host.exec(Command.new("grep '#{aix_local_resolv}' #{aix_netsvc}"), :accept_all_exit_codes => true).exit_code == 0
340
+ host.exec(Command.new("echo '#{aix_local_resolv}' >> #{aix_netsvc}"))
341
+ end
342
+ end
335
343
  end
336
344
 
337
345
  #Make it possible to log in as root by copying the current users ssh keys to the root account
@@ -103,8 +103,8 @@ module Beaker
103
103
  #to the provided SUT for test execution to be successful.
104
104
  def configure(opts = {})
105
105
  return unless @options[:configure]
106
- block_on @hosts, { :run_in_parallel => (@options && @options[:run_in_parallel].is_a?(Array)) ?
107
- @options[:run_in_parallel].include?('configure') : false} do |host|
106
+ run_in_parallel = run_in_parallel? opts, @options, 'configure'
107
+ block_on @hosts, { :run_in_parallel => run_in_parallel} do |host|
108
108
  if host[:timesync]
109
109
  timesync(host, @options)
110
110
  end
@@ -39,6 +39,9 @@ module Beaker
39
39
 
40
40
  creds
41
41
 
42
+ rescue TypeError, Psych::SyntaxError => e
43
+ @logger.warn "#{e.class}: Credentials file (#{dot_fog}) has invalid syntax; proceeding without authentication"
44
+ creds
42
45
  rescue Errno::ENOENT
43
46
  @logger.warn "Credentials file (#{dot_fog}) not found; proceeding without authentication"
44
47
  creds
@@ -171,7 +171,7 @@ module Beaker
171
171
  :add_el_extras => false,
172
172
  :epel_url => "http://dl.fedoraproject.org/pub/epel",
173
173
  :epel_arch => "i386",
174
- :epel_7_pkg => "epel-release-7-7.noarch.rpm",
174
+ :epel_7_pkg => "epel-release-7-8.noarch.rpm",
175
175
  :epel_6_pkg => "epel-release-6-8.noarch.rpm",
176
176
  :epel_5_pkg => "epel-release-5-4.noarch.rpm",
177
177
  :consoleport => 443,
@@ -1,4 +1,4 @@
1
- [ 'repetition', 'error_handler', 'host_manager', 'timed', 'semvar' ].each do |lib|
1
+ [ 'repetition', 'error_handler', 'host_manager', 'timed', 'semvar', 'options_resolver' ].each do |lib|
2
2
  require "beaker/shared/#{lib}"
3
3
  end
4
4
  module Beaker
@@ -8,6 +8,7 @@ module Beaker
8
8
  include Beaker::Shared::Repetition
9
9
  include Beaker::Shared::Timed
10
10
  include Beaker::Shared::Semvar
11
+ include Beaker::Shared::OptionsResolver
11
12
  end
12
13
  end
13
14
  include Beaker::Shared
@@ -102,7 +102,7 @@ module Beaker
102
102
  end
103
103
  if block_hosts.is_a? Array
104
104
  if block_hosts.length > 0
105
- if opts[:run_in_parallel] == true
105
+ if run_in_parallel? opts
106
106
  # Pass caller[1] - the line that called block_on - for logging purposes.
107
107
  result = block_hosts.map.each_in_parallel(caller[1]) do |h|
108
108
  run_block_on h, &block
@@ -0,0 +1,41 @@
1
+ module Beaker
2
+ module Shared
3
+ # Methods for parsing options.
4
+ module OptionsResolver
5
+ # parses local and global options to determine if a particular mode should
6
+ # be run in parallel. typically, local_options will specify a true/false
7
+ # value, while global_options will specify an array of mode names that should
8
+ # be run in parallel. the value specified in local_options will take precedence
9
+ # over the values specified in global_options.
10
+ # @param [Hash] local_options local options for running in parallel
11
+ # @option local_options [Boolean] :run_in_parallel flag for running in parallel
12
+ # @param [Hash] global_options global options for running in parallel
13
+ # @option global_options [Array<String>] :run_in_parallel list of modes to run in parallel
14
+ # @param [String] mode the mode we want to query global_options for
15
+ # @return [Boolean] true if the specified mode is in global_options and :run_in_parallel in local_options is not false,
16
+ # or if :run_in_parallel in local_options is true, false otherwise
17
+ # @example
18
+ # run_in_parallel?({:run_in_parallel => true})
19
+ # -> will return true
20
+ #
21
+ # run_in_parallel?({:run_in_parallel => true}, {:run_in_parallel => ['install','configure']}, 'install')
22
+ # -> will return true
23
+ #
24
+ # run_in_parallel?({:run_in_parallel => false}, {:run_in_parallel => ['install','configure']}, 'install')
25
+ # -> will return false
26
+ def run_in_parallel?(local_options=nil, global_options=nil, mode=nil)
27
+ run_in_parallel = local_options[:run_in_parallel] unless local_options.nil?
28
+
29
+ if !run_in_parallel.nil? && run_in_parallel.is_a?(Array)
30
+ run_in_parallel = false
31
+ end
32
+
33
+ if run_in_parallel.nil? && global_options && global_options[:run_in_parallel].is_a?(Array)
34
+ run_in_parallel = global_options[:run_in_parallel].include?(mode)
35
+ end
36
+
37
+ run_in_parallel
38
+ end
39
+ end
40
+ end
41
+ end
@@ -102,7 +102,7 @@ module Beaker
102
102
  raise e
103
103
  ensure
104
104
  @ssh = nil
105
- @logger.warn("ssh connection to #{@hostname} has been terminated")
105
+ @logger.debug("ssh connection to #{@hostname} has been terminated")
106
106
  end
107
107
  end
108
108
 
@@ -132,8 +132,7 @@ module Beaker
132
132
  test = File.read(path)
133
133
  eval test,nil,path,1
134
134
  rescue FailTest, TEST_EXCEPTION_CLASS => e
135
- @test_status = :fail
136
- @exception = e
135
+ log_and_fail_test(e, :fail)
137
136
  rescue PendingTest
138
137
  @test_status = :pending
139
138
  rescue SkipTest
@@ -146,7 +145,7 @@ module Beaker
146
145
  begin
147
146
  teardown.call
148
147
  rescue StandardError, SignalException, TEST_EXCEPTION_CLASS => e
149
- log_and_fail_test(e)
148
+ log_and_fail_test(e, :teardown_error)
150
149
  end
151
150
  end
152
151
  @logger.info('End teardown')
@@ -166,14 +165,19 @@ module Beaker
166
165
  # individually as well.
167
166
  #
168
167
  # @param exception [Exception] exception to fail with
169
- def log_and_fail_test(exception)
168
+ # @param exception [Symbol] the test status
169
+ def log_and_fail_test(exception, status=:error)
170
170
  logger.error("#{exception.class}: #{exception.message}")
171
171
  bt = exception.backtrace
172
172
  logger.pretty_backtrace(bt).each_line do |line|
173
173
  logger.error(line)
174
174
  end
175
- @test_status = :error
176
- @exception = exception
175
+ # If the status is already a test failure or error, don't overwrite with the teardown failure.
176
+ unless status == :teardown_error && (@test_status == :error || @test_status == :fail)
177
+ status = :error if status == :teardown_error
178
+ @test_status = status
179
+ @exception = exception
180
+ end
177
181
  end
178
182
  end
179
183
  end
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '2.48.1'
3
+ STRING = '2.49.0'
4
4
  end
5
5
  end
@@ -35,7 +35,7 @@ describe ClassMixedWithDSLHelpers do
35
35
 
36
36
  shared_examples 'modify-tk-config-without-error' do
37
37
  it 'dumps to the SUT config file path' do
38
- allow( JSON ).to receive(:dump)
38
+ allow( JSON ).to receive(:pretty_generate)
39
39
  allow( subject ).to receive(:create_remote_file).with(host, config_file_path, anything())
40
40
  subject.modify_tk_config(host, config_file_path, options_hash, replace)
41
41
  end
@@ -72,7 +72,7 @@ describe ClassMixedWithDSLHelpers do
72
72
 
73
73
  describe 'given a true value to its `replace` parameter' do
74
74
  before do
75
- expect( JSON ).to receive(:dump)
75
+ expect( JSON ).to receive(:pretty_generate)
76
76
  expect( subject ).to receive(:create_remote_file).with(host, config_file_path, anything())
77
77
  end
78
78
  include_examples('modify-tk-config-without-error')
@@ -169,7 +169,7 @@ describe Beaker do
169
169
  it "can return the correct url for an el-7 host" do
170
170
  host = make_host( 'testhost', { :platform => Beaker::Platform.new('el-7-platform') } )
171
171
 
172
- expect( subject.epel_info_for( host, options )).to be === ["http://dl.fedoraproject.org/pub/epel/7", "x86_64", "epel-release-7-7.noarch.rpm"]
172
+ expect( subject.epel_info_for( host, options )).to be === ["http://dl.fedoraproject.org/pub/epel/7", "x86_64", "epel-release-7-8.noarch.rpm"]
173
173
  end
174
174
 
175
175
  it "can return the correct url for an el-6 host" do
@@ -181,6 +181,51 @@ module Beaker
181
181
  expect( vmpooler.credentials ).to be == { }
182
182
  end
183
183
 
184
+ it 'continues without credentials when there are formatting errors in the fog file' do
185
+ data = { "'default'" => { :vmpooler_token => "b2wl8prqe6ddoii70md" } }
186
+
187
+ allow_any_instance_of( Beaker::Vmpooler ).to \
188
+ receive(:read_fog_file).and_return(data)
189
+
190
+ logger = double('logger')
191
+
192
+ expect(logger).to receive(:warn).with(/is missing a :default section with a :vmpooler_token value/)
193
+ make_opts = {:logger => logger}
194
+
195
+ vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts )
196
+ expect( vmpooler.credentials ).to be == { }
197
+ end
198
+
199
+ it 'throws a TypeError and continues without credentials when there are syntax errors in the fog file' do
200
+ data = "'default'\n :vmpooler_token: z2wl8prqe0ddoii70ad"
201
+
202
+ allow( File ).to receive( :open ).and_yield( StringIO.new(data) )
203
+ logger = double('logger')
204
+
205
+ expect(logger).to receive(:warn).with(/TypeError: .* has invalid syntax/)
206
+ make_opts = {:logger => logger}
207
+
208
+ vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts )
209
+
210
+ expect( vmpooler.credentials ).to be == { }
211
+ end
212
+
213
+ it 'throws a Psych::SyntaxError and continues without credentials when there are syntax errors in the fog file' do
214
+
215
+ data = ";default;\n :vmpooler_token: z2wl8prqe0ddoii707d"
216
+
217
+ allow( File ).to receive( :open ).and_yield( StringIO.new(data) )
218
+
219
+ logger = double('logger')
220
+
221
+ expect(logger).to receive(:warn).with(/Psych::SyntaxError: .* invalid syntax/)
222
+ make_opts = {:logger => logger}
223
+
224
+ vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts )
225
+
226
+ expect( vmpooler.credentials ).to be == { }
227
+ end
228
+
184
229
  it 'stores vmpooler token when found in fog file' do
185
230
  data = { :default => { :vmpooler_token => "TOKEN" } }
186
231
 
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ module Beaker
4
+ module Shared
5
+ describe OptionsResolver do
6
+
7
+ describe 'run_in_parallel?' do
8
+
9
+ it 'returns true if :run_in_parallel in opts is true' do
10
+ expect( subject.run_in_parallel?({:run_in_parallel => true}, nil, nil) ).to be === true
11
+ end
12
+
13
+ it 'returns false if :run_in_parallel in opts is false' do
14
+ expect( subject.run_in_parallel?({:run_in_parallel => false}, nil, nil) ).to be === false
15
+ end
16
+
17
+ it 'returns false if :run_in_parallel in opts is an empty array' do
18
+ expect( subject.run_in_parallel?({:run_in_parallel => []}, nil, nil) ).to be === false
19
+ end
20
+
21
+ it 'returns false if :run_in_parallel in opts is an empty array but a mode is specified in options' do
22
+ expect( subject.run_in_parallel?({:run_in_parallel => []}, {:run_in_parallel => ['install']}, 'install') ).to be === false
23
+ end
24
+
25
+ it 'returns true if opts is nil but a matching mode is specified in options' do
26
+ expect( subject.run_in_parallel?(nil, {:run_in_parallel => ['install']}, 'install') ).to be === true
27
+ end
28
+
29
+ it 'returns false if opts is nil and a non matching mode is specified in options' do
30
+ expect( subject.run_in_parallel?(nil, {:run_in_parallel => ['configure']}, 'install') ).to be === false
31
+ end
32
+
33
+ it 'returns true if opts is nil and a matching mode and a non matching mode is specified in options' do
34
+ expect( subject.run_in_parallel?(nil, {:run_in_parallel => ['configure', 'install']}, 'install') ).to be === true
35
+ end
36
+
37
+ it 'returns false if opts is nil and no mode is specified in options' do
38
+ expect( subject.run_in_parallel?(nil, {:run_in_parallel => []}, 'install') ).to be === false
39
+ end
40
+
41
+ it 'returns false if opts is false but a matching mode is specified in options' do
42
+ expect( subject.run_in_parallel?({:run_in_parallel => false}, {:run_in_parallel => ['install']}, 'install') ).to be === false
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
@@ -49,7 +49,7 @@ module Beaker
49
49
  f.write "raise FailTest"
50
50
  end
51
51
  @path = path
52
- expect( testcase ).to_not receive( :log_and_fail_test )
52
+ expect( testcase ).to receive( :log_and_fail_test ).once.with(kind_of(Beaker::DSL::FailTest), :fail).and_call_original
53
53
  testcase.run_test
54
54
  status = testcase.instance_variable_get(:@test_status)
55
55
  expect(status).to be === :fail
@@ -105,8 +105,26 @@ module Beaker
105
105
  EOF
106
106
  end
107
107
  @path = path
108
- expect( testcase ).to receive( :log_and_fail_test ).once.with(kind_of(Minitest::Assertion))
108
+ expect( testcase ).to receive( :log_and_fail_test ).once.with(kind_of(Minitest::Assertion), :teardown_error).and_call_original
109
+ testcase.run_test
110
+ expect @test_status == :error
111
+ end
112
+
113
+ it 'does not overwrite a test failure if an assertion also happens in a teardown block' do
114
+ path = 'test.rb'
115
+ File.open(path, 'w') do |f|
116
+ f.write <<-EOF
117
+ teardown do
118
+ assert_equal(1, 2, 'Oh noes!')
119
+ end
120
+ assert_equal(true, false, 'failed test')
121
+ EOF
122
+ end
123
+ @path = path
124
+ expect( testcase ).to receive( :log_and_fail_test ).once.with(kind_of(Minitest::Assertion), :fail).and_call_original
125
+ expect( testcase ).to receive( :log_and_fail_test ).once.with(kind_of(Minitest::Assertion), :teardown_error).and_call_original
109
126
  testcase.run_test
127
+ expect @test_status == :fail
110
128
  end
111
129
  end
112
130
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.48.1
4
+ version: 2.49.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppetlabs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-29 00:00:00.000000000 Z
11
+ date: 2016-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -551,6 +551,7 @@ files:
551
551
  - acceptance/tests/base/dsl/install_utils/clone_git_repo_on_test.rb
552
552
  - acceptance/tests/base/dsl/platform_tag_confiner_test.rb
553
553
  - acceptance/tests/base/dsl/structure_test.rb
554
+ - acceptance/tests/base/external_resources_test.rb
554
555
  - acceptance/tests/base/host_prebuilt_steps/ssh_environment_test.rb
555
556
  - acceptance/tests/base/host_test.rb
556
557
  - acceptance/tests/base/packages.rb
@@ -573,10 +574,12 @@ files:
573
574
  - docs/concepts/masterless_puppet.md
574
575
  - docs/concepts/roles_what_are_they.md
575
576
  - docs/concepts/shared_options_for_executing_beaker_commands.md
577
+ - docs/concepts/style_guide.md
576
578
  - docs/concepts/test_tagging.md
577
579
  - docs/concepts/ticket_process.md
578
580
  - docs/concepts/types_puppet_4_and_the_all_in_one_agent.md
579
581
  - docs/how_to/access_the_live_test_console_with_pry.md
582
+ - docs/how_to/archive_sut_files.md
580
583
  - docs/how_to/change_terminal_output_coloring.md
581
584
  - docs/how_to/confine.md
582
585
  - docs/how_to/hosts/README.md
@@ -598,6 +601,7 @@ files:
598
601
  - docs/how_to/rake_tasks.md
599
602
  - docs/how_to/recipes.md
600
603
  - docs/how_to/run_in_parallel.md
604
+ - docs/how_to/ssh_agent_forwarding.md
601
605
  - docs/how_to/the_beaker_dsl.md
602
606
  - docs/how_to/use_user_password_authentication.md
603
607
  - docs/how_to/write_a_beaker_test_for_a_module.md
@@ -710,6 +714,7 @@ files:
710
714
  - lib/beaker/shared.rb
711
715
  - lib/beaker/shared/error_handler.rb
712
716
  - lib/beaker/shared/host_manager.rb
717
+ - lib/beaker/shared/options_resolver.rb
713
718
  - lib/beaker/shared/repetition.rb
714
719
  - lib/beaker/shared/semvar.rb
715
720
  - lib/beaker/shared/timed.rb
@@ -797,6 +802,7 @@ files:
797
802
  - spec/beaker/platform_spec.rb
798
803
  - spec/beaker/shared/error_handler_spec.rb
799
804
  - spec/beaker/shared/host_manager_spec.rb
805
+ - spec/beaker/shared/options_resolver_spec.rb
800
806
  - spec/beaker/shared/repetition_spec.rb
801
807
  - spec/beaker/shared/semvar_spec.rb
802
808
  - spec/beaker/ssh_connection_spec.rb