busser-rspec 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/publish.yml +22 -0
- data/.gitignore +0 -1
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +1 -4
- data/CHANGELOG.md +7 -0
- data/CONTRIBUTING.md +104 -0
- data/Gemfile +10 -4
- data/README.md +115 -33
- data/Rakefile +27 -2
- data/features/support/env.rb +0 -7
- data/lib/busser/rspec/version.rb +2 -1
- data/lib/busser/runner_plugin/rspec.rb +72 -6
- data/spec/busser/runner_plugin/rspec_spec.rb +87 -0
- data/spec/spec_helper.rb +2 -0
- metadata +4 -2
- data/.tailor +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 217c8f2f4bb8a712f4d69e22c3567334306c9d0e44cdc418c47630ee84660ffe
|
|
4
|
+
data.tar.gz: cf85c2e7e49b49c74273c9d2f11ee208d3eadead985ff3f9f021a7e35ace6b53
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 677c89b4864b780207555fcfe5b176e172e50c2a77ecdfd8ce8f5723fb0988250c3e9e03bacf3781f3a5486eed4050e8a5a1415288f4f1396eb4bcc239d5bc1c
|
|
7
|
+
data.tar.gz: a1ed580c340581807850947ee6ce8f391483dd809aa98efb86c7960af31318e468244c63f671948e85540fe98fcf70190dfb966fe5080e3d4d453d3153db64d0
|
|
@@ -43,3 +43,25 @@ jobs:
|
|
|
43
43
|
uses: actionshub/publish-gem-to-rubygems@f9126f7a2d36a4fd31a13e78fde5fbdcc4b7b251 # v2.0.6
|
|
44
44
|
with:
|
|
45
45
|
token: ${{ secrets.RUBYGEMS_API_KEY }}
|
|
46
|
+
|
|
47
|
+
# actionshub/publish-gem-to-rubygems logs a rejected push and still exits
|
|
48
|
+
# 0, so a release that never reached RubyGems shows up as a green job.
|
|
49
|
+
# Ask RubyGems directly instead of trusting the step. The v2 endpoint is
|
|
50
|
+
# 404 until the exact version is indexed, so -f turns "not there" into a
|
|
51
|
+
# non-zero exit rather than a substring match on `gem list` output.
|
|
52
|
+
- name: Verify the release reached RubyGems
|
|
53
|
+
if: ${{ steps.release.outputs.release_created }}
|
|
54
|
+
env:
|
|
55
|
+
VERSION: ${{ steps.release.outputs.version }}
|
|
56
|
+
run: |
|
|
57
|
+
set -euo pipefail
|
|
58
|
+
name="$(basename "$(ls ./*.gemspec)" .gemspec)"
|
|
59
|
+
for _ in $(seq 1 12); do
|
|
60
|
+
if curl -fsS -o /dev/null "https://rubygems.org/api/v2/rubygems/${name}/versions/${VERSION}.json"; then
|
|
61
|
+
echo "${name} ${VERSION} is on RubyGems"
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
sleep 15
|
|
65
|
+
done
|
|
66
|
+
echo "::error::${name} ${VERSION} never reached RubyGems. A permissions failure in the push step above does not fail that step -- read its log."
|
|
67
|
+
exit 1
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
* Additional windows fixes for recent Omnibus Chef
|
|
4
4
|
* Documentation (`README`) updates
|
|
5
5
|
|
|
6
|
+
## [0.8.1](https://github.com/test-kitchen/busser-rspec/compare/v0.8.0...v0.8.1) (2026-08-28)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* quote paths before handing them to a shell ([#30](https://github.com/test-kitchen/busser-rspec/issues/30)) ([9410c75](https://github.com/test-kitchen/busser-rspec/commit/9410c755924525ab436e27beb017b7f43a8453bc))
|
|
12
|
+
|
|
6
13
|
## [0.8.0](https://github.com/test-kitchen/busser-rspec/compare/v0.7.6...v0.8.0) (2026-08-28)
|
|
7
14
|
|
|
8
15
|
|
data/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Contributing to busser-rspec
|
|
2
|
+
|
|
3
|
+
Thanks for taking the time to contribute. This document covers how to get the
|
|
4
|
+
project running locally, how to check your work before opening a pull request,
|
|
5
|
+
and the commit convention releases depend on.
|
|
6
|
+
|
|
7
|
+
## Getting set up
|
|
8
|
+
|
|
9
|
+
This plugin requires **Ruby 3.2 or newer**. Clone the repository and install the
|
|
10
|
+
development dependencies:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
git clone https://github.com/test-kitchen/busser-rspec.git
|
|
14
|
+
cd busser-rspec
|
|
15
|
+
bundle install
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Running the tests
|
|
19
|
+
|
|
20
|
+
`rake` runs the whole suite:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bundle exec rake test
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The tests are [cucumber](https://cucumber.io) features in `features/`. They
|
|
27
|
+
drive the real `busser` executable through
|
|
28
|
+
[aruba](https://github.com/cucumber/aruba) rather than calling the plugin's
|
|
29
|
+
classes, so they cover it end to end: install the plugin into a throwaway
|
|
30
|
+
Busser root, write a suite, run it, and check what came out. The step
|
|
31
|
+
definitions they use are published by busser itself, in `lib/busser/cucumber.rb`.
|
|
32
|
+
|
|
33
|
+
### How the feature sandbox works
|
|
34
|
+
|
|
35
|
+
Features that install the plugin sandbox `GEM_HOME` into a temporary directory
|
|
36
|
+
and strip bundler out of the environment, so a run never installs a gem into
|
|
37
|
+
your bundle. Two details matter if you add or change one:
|
|
38
|
+
|
|
39
|
+
* **Do not reintroduce bundler variables.** RubyGems re-requires
|
|
40
|
+
`bundler/setup` whenever `BUNDLER_SETUP` is present, and bundler then resets
|
|
41
|
+
`Gem.dir` to the bundle. Plugins install into `vendor/bundle` instead of the
|
|
42
|
+
sandbox, and the assertions that look in `GEM_HOME` fail. The
|
|
43
|
+
`a non bundler environment` step exists to clear this.
|
|
44
|
+
* **The plugin is installed from the working tree.** With bundler out of the
|
|
45
|
+
way, `busser plugin install` would fetch the last release from RubyGems and
|
|
46
|
+
run *its* postinstall — so the suite would pass on code that is not in your
|
|
47
|
+
branch. The `this plugin is installed from the working tree` step builds the
|
|
48
|
+
gem from the gemspec and installs it into the sandbox first, which is what
|
|
49
|
+
makes the features test your change.
|
|
50
|
+
|
|
51
|
+
## Linting
|
|
52
|
+
|
|
53
|
+
CI runs three linters, all of which you can run locally:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
bundle exec cookstyle --chefstyle # Ruby
|
|
57
|
+
yamllint --strict . # YAML
|
|
58
|
+
markdownlint-cli2 "**/*.md" "!**/CHANGELOG*.md"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Commit messages
|
|
62
|
+
|
|
63
|
+
This project uses [Conventional Commits](https://www.conventionalcommits.org).
|
|
64
|
+
Releases are automated, and the commit subject on `main` is what decides the
|
|
65
|
+
next version number and what appears in the changelog.
|
|
66
|
+
|
|
67
|
+
Pull requests are **squash merged, so the pull request title becomes that
|
|
68
|
+
subject**. A CI check enforces the format on the title; the individual commits
|
|
69
|
+
on your branch are not checked.
|
|
70
|
+
|
|
71
|
+
| Prefix | Effect on the next release |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| `fix:` | Patch version bump |
|
|
74
|
+
| `feat:` | Minor version bump |
|
|
75
|
+
| `feat!:`, or a `BREAKING CHANGE:` footer | Minor bump, until this gem reaches 1.0 |
|
|
76
|
+
| `chore:`, `docs:`, `ci:`, `test:`, `refactor:` | No release |
|
|
77
|
+
|
|
78
|
+
For example:
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
fix: install the plugin into GEM_HOME rather than the bundle
|
|
82
|
+
feat: support a Gemfile alongside the suite
|
|
83
|
+
ci: pin the shared workflow to a release
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Opening a pull request
|
|
87
|
+
|
|
88
|
+
1. Fork the repository and create a branch for your change.
|
|
89
|
+
2. Add or update tests. A bug fix should come with a test that fails without it.
|
|
90
|
+
3. Run `bundle exec rake test` and the linters above.
|
|
91
|
+
4. Open a pull request with a Conventional Commits title.
|
|
92
|
+
|
|
93
|
+
## Releases
|
|
94
|
+
|
|
95
|
+
Releases are handled by
|
|
96
|
+
[release-please](https://github.com/googleapis/release-please). It watches
|
|
97
|
+
commits landing on `main` and keeps a release pull request open with the next
|
|
98
|
+
version number and the accumulated changelog. Merging that pull request tags the
|
|
99
|
+
release and publishes the gem to RubyGems and GitHub Packages.
|
|
100
|
+
|
|
101
|
+
Maintainers do not bump `lib/busser/rspec/version.rb` or edit
|
|
102
|
+
`CHANGELOG.md` by hand; release-please owns both files. This gem is still pre-1.0, so
|
|
103
|
+
`bump-minor-pre-major` is set and a breaking change takes the minor rather than
|
|
104
|
+
graduating it to 1.0.
|
data/Gemfile
CHANGED
|
@@ -3,13 +3,19 @@ source "https://rubygems.org"
|
|
|
3
3
|
gemspec
|
|
4
4
|
|
|
5
5
|
group :cookstyle do
|
|
6
|
-
gem "cookstyle", ">= 9.0
|
|
6
|
+
gem "cookstyle", ">= 9.0"
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
group :test do
|
|
10
|
-
gem "aruba", ">= 2.
|
|
11
|
-
gem "base64" # cucumber needs it; not a default gem on Ruby 4.0
|
|
10
|
+
gem "aruba", ">= 2.4"
|
|
11
|
+
gem "base64", ">= 0.3" # cucumber needs it; not a default gem on Ruby 4.0
|
|
12
12
|
gem "cucumber", ">= 11.1"
|
|
13
|
-
gem "
|
|
13
|
+
gem "minitest", ">= 6.0"
|
|
14
|
+
gem "mocha", ">= 2.7"
|
|
15
|
+
gem "rake", ">= 13.4"
|
|
14
16
|
gem "rspec", ">= 3.13"
|
|
15
17
|
end
|
|
18
|
+
|
|
19
|
+
group :development do
|
|
20
|
+
gem "yard", ">= 0.9.37"
|
|
21
|
+
end
|
data/README.md
CHANGED
|
@@ -1,67 +1,149 @@
|
|
|
1
|
-
#
|
|
1
|
+
# busser-rspec
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/busser-rspec)
|
|
4
4
|
|
|
5
|
-
A Busser runner plugin
|
|
5
|
+
A [Busser](https://github.com/test-kitchen/busser) runner plugin that runs
|
|
6
|
+
[RSpec](https://rspec.info) examples as integration tests.
|
|
7
|
+
|
|
8
|
+
Busser installs RSpec on the machine under test during postinstall, then runs
|
|
9
|
+
the suite's `rspec` directory against it. Because the examples run on the
|
|
10
|
+
machine itself rather than over SSH, they can assert on local files, services
|
|
11
|
+
and commands directly.
|
|
6
12
|
|
|
7
13
|
## Status
|
|
8
14
|
|
|
9
|
-
This software project is no longer under active development as it has no active
|
|
15
|
+
This software project is no longer under active development as it has no active
|
|
16
|
+
maintainers. The software may continue to work for some or all use cases, but
|
|
17
|
+
issues filed in GitHub will most likely not be triaged. If a new maintainer is
|
|
18
|
+
interested in working on this project please come chat with us in #test-kitchen
|
|
19
|
+
on Chef Community Slack.
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
10
22
|
|
|
11
|
-
|
|
23
|
+
Ruby 3.2 or newer, and busser 0.9.0 or newer. The plugin installs RSpec 3.13 or
|
|
24
|
+
newer on the machine under test.
|
|
12
25
|
|
|
13
|
-
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
Busser installs the plugin for you when Test Kitchen runs the suite, so there is
|
|
29
|
+
usually nothing to do. To install it by hand:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
busser plugin install busser-rspec
|
|
33
|
+
```
|
|
14
34
|
|
|
15
35
|
## Usage
|
|
16
36
|
|
|
17
|
-
|
|
37
|
+
Put your specs in the `rspec` directory of a suite:
|
|
18
38
|
|
|
19
39
|
```text
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
`--
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
40
|
+
test
|
|
41
|
+
`-- integration
|
|
42
|
+
`-- default # suite name
|
|
43
|
+
`-- rspec
|
|
44
|
+
|-- Gemfile # optional
|
|
45
|
+
|-- setup-recipe.rb # optional
|
|
46
|
+
|-- spec_helper.rb
|
|
47
|
+
`-- default_spec.rb
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The suite directory is passed to RSpec as the spec path, and both it and its
|
|
51
|
+
`lib` subdirectory are added to the load path — so `require "spec_helper"` works
|
|
52
|
+
from any spec without a relative path.
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
describe "foobar::default" do
|
|
56
|
+
it "creates foobar.txt" do
|
|
57
|
+
expect(File).to exist("/usr/local/foobar.txt")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Extra gems
|
|
63
|
+
|
|
64
|
+
If a `Gemfile` is present in the suite directory, it is `bundle install`ed
|
|
65
|
+
before the run. Remember to include RSpec itself:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
source "https://rubygems.org"
|
|
69
|
+
|
|
70
|
+
gem "rspec"
|
|
27
71
|
```
|
|
28
72
|
|
|
29
|
-
|
|
73
|
+
The install is attempted with `--local` first and falls back to the network, so
|
|
74
|
+
gems already present on the machine do not cost a download.
|
|
75
|
+
|
|
76
|
+
### Chef setup
|
|
30
77
|
|
|
31
|
-
|
|
78
|
+
If a `setup-recipe.rb` is present in the suite directory, it is applied with
|
|
79
|
+
`chef-apply` before the specs run. This requires `/opt/chef/bin/chef-apply` on
|
|
80
|
+
the machine; the run fails with a clear error if the file is there and Chef is
|
|
81
|
+
not.
|
|
32
82
|
|
|
33
|
-
###
|
|
83
|
+
### Changing the formatter
|
|
34
84
|
|
|
35
|
-
|
|
85
|
+
`rspec -f` is not available here, since Busser invokes the runner itself. Set
|
|
86
|
+
the formatter from your specs instead:
|
|
36
87
|
|
|
37
88
|
```ruby
|
|
38
89
|
RSpec.configure do |config|
|
|
39
|
-
#
|
|
90
|
+
# the same as `rspec -f documentation`
|
|
40
91
|
config.add_formatter "documentation"
|
|
92
|
+
end
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Using it with Test Kitchen
|
|
96
|
+
|
|
97
|
+
This is how most people run it, and it needs no Busser commands of your own.
|
|
98
|
+
Select the verifier in `kitchen.yml`:
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
verifier:
|
|
102
|
+
name: busser
|
|
103
|
+
|
|
104
|
+
suites:
|
|
105
|
+
- name: default
|
|
41
106
|
```
|
|
42
107
|
|
|
43
|
-
|
|
108
|
+
Then put your tests in a `rspec` directory inside the suite:
|
|
44
109
|
|
|
45
|
-
|
|
46
|
-
|
|
110
|
+
```text
|
|
111
|
+
test/integration/default/rspec/default_spec.rb
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`kitchen verify` installs Busser and this plugin on the instance and runs them.
|
|
115
|
+
The directory name is what selects this plugin -- there is nothing else to
|
|
116
|
+
configure.
|
|
117
|
+
|
|
118
|
+
## When nothing runs
|
|
47
119
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
120
|
+
If the suite files do not match what this plugin looks for, the run prints one
|
|
121
|
+
line and **exits `0`**:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
-----> Running rspec test suite
|
|
125
|
+
```
|
|
51
126
|
|
|
52
|
-
|
|
53
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
54
|
-
3. Commit your changes (`git commit -am 'Added some feature'`)
|
|
55
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
|
56
|
-
5. Create new Pull Request
|
|
127
|
+
No tests ran, and nothing said so. Work through these in order:
|
|
57
128
|
|
|
58
|
-
|
|
129
|
+
1. **Is the directory named `rspec`?** That name alone selects this plugin.
|
|
130
|
+
`rspecs/`, `tests/` or anything else is not picked up.
|
|
131
|
+
2. **Do the filenames match?** RSpec takes `*_spec.rb` -- `smoke.rb` is
|
|
132
|
+
*not* picked up.
|
|
133
|
+
3. **Is the plugin installed?** `busser plugin list` shows what is available.
|
|
134
|
+
4. **Is `BUSSER_ROOT` what you think?** `busser suite path` prints where suites
|
|
135
|
+
are actually being looked for.
|
|
59
136
|
|
|
60
|
-
|
|
137
|
+
## Contributing
|
|
61
138
|
|
|
62
|
-
|
|
139
|
+
Bug reports and pull requests are welcome. See
|
|
140
|
+
[CONTRIBUTING.md](CONTRIBUTING.md) for how to set up the project, run the test
|
|
141
|
+
suite, and format your commits.
|
|
63
142
|
|
|
64
143
|
## License
|
|
65
144
|
|
|
66
|
-
Apache 2.0
|
|
145
|
+
Apache License 2.0. See [LICENSE](LICENSE).
|
|
67
146
|
|
|
147
|
+
Originally created by [Adam Jacob](https://github.com/adamhjk), based on
|
|
148
|
+
[Daisuke Higuchi](https://github.com/cl-lab-k)'s
|
|
149
|
+
[busser-serverspec](https://github.com/test-kitchen/busser-serverspec).
|
data/Rakefile
CHANGED
|
@@ -1,11 +1,36 @@
|
|
|
1
1
|
require "bundler/gem_tasks"
|
|
2
|
+
require "rake/testtask"
|
|
3
|
+
Rake::TestTask.new(:unit) do |t|
|
|
4
|
+
t.libs.push "lib"
|
|
5
|
+
t.test_files = FileList["spec/**/*_spec.rb"]
|
|
6
|
+
t.verbose = true
|
|
7
|
+
end
|
|
8
|
+
|
|
2
9
|
require "cucumber/rake/task"
|
|
3
10
|
|
|
4
11
|
Cucumber::Rake::Task.new(:features) do |t|
|
|
5
|
-
t.cucumber_opts = ["features", "
|
|
12
|
+
t.cucumber_opts = ["features", "--format progress", "--fail-fast"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# yard lives in the :development group, which CI omits when it runs the tests.
|
|
16
|
+
# Requiring it unconditionally would make `rake test` fail there, so the real
|
|
17
|
+
# task is only defined when yard is installed and a stub explains its absence
|
|
18
|
+
# otherwise. Nothing in CI gates on documentation.
|
|
19
|
+
begin
|
|
20
|
+
require "yard"
|
|
21
|
+
|
|
22
|
+
YARD::Rake::YardocTask.new(:doc) do |t|
|
|
23
|
+
t.files = ["lib/**/*.rb"]
|
|
24
|
+
t.options = ["--output-dir", "doc", "--markup", "markdown"]
|
|
25
|
+
end
|
|
26
|
+
rescue LoadError
|
|
27
|
+
desc "Generate YARD documentation (install the development group first)"
|
|
28
|
+
task :doc do
|
|
29
|
+
abort "yard is not available. Run `bundle install --with development` first."
|
|
30
|
+
end
|
|
6
31
|
end
|
|
7
32
|
|
|
8
33
|
desc "Run all test suites"
|
|
9
|
-
task test:
|
|
34
|
+
task test: %i{unit features}
|
|
10
35
|
|
|
11
36
|
task default: [:test]
|
data/features/support/env.rb
CHANGED
|
@@ -11,13 +11,6 @@ Aruba.configure do |config|
|
|
|
11
11
|
config.exit_timeout = 120
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
After do |s|
|
|
15
|
-
# Tell Cucumber to quit after this scenario is done - if it failed.
|
|
16
|
-
# This is useful to inspect the 'tmp/aruba' directory before any other
|
|
17
|
-
# steps are executed and clear it out.
|
|
18
|
-
Cucumber.wants_to_quit = true if s.failed?
|
|
19
|
-
end
|
|
20
|
-
|
|
21
14
|
# The sandboxed features shell out to `busser plugin install <this plugin>`, and
|
|
22
15
|
# two things have to hold for that to exercise this checkout:
|
|
23
16
|
#
|
data/lib/busser/rspec/version.rb
CHANGED
|
@@ -17,17 +17,85 @@
|
|
|
17
17
|
|
|
18
18
|
require "busser/runner_plugin"
|
|
19
19
|
require "rubygems" unless defined?(Gem)
|
|
20
|
+
require "rbconfig" unless defined?(RbConfig)
|
|
21
|
+
require "shellwords" unless defined?(Shellwords)
|
|
20
22
|
|
|
21
23
|
# A Busser runner plugin for Rspec.
|
|
22
24
|
#
|
|
23
25
|
# @author Adam Jacob <adam@opscode.com>
|
|
24
26
|
#
|
|
25
27
|
class Busser::RunnerPlugin::Rspec < Busser::RunnerPlugin::Base
|
|
28
|
+
|
|
29
|
+
# Builds the command that runs the suite.
|
|
30
|
+
#
|
|
31
|
+
# The suite directory goes on the load path twice -- itself and its lib
|
|
32
|
+
# subdirectory -- so `require "spec_helper"` works from any spec without a
|
|
33
|
+
# relative path.
|
|
34
|
+
#
|
|
35
|
+
# Every path is quoted. BUSSER_ROOT is user supplied, and an unquoted path
|
|
36
|
+
# containing a space would be split by the shell into arguments RSpec would
|
|
37
|
+
# then treat as extra spec paths.
|
|
38
|
+
#
|
|
39
|
+
# @param runner [String] path to the runner script
|
|
40
|
+
# @param suite [String, Pathname] the suite directory holding the specs
|
|
41
|
+
# @return [String] the command to run
|
|
42
|
+
def self.runner_command(runner, suite)
|
|
43
|
+
suite = suite.to_s
|
|
44
|
+
[
|
|
45
|
+
Shellwords.escape(runner),
|
|
46
|
+
"-I", Shellwords.escape(suite),
|
|
47
|
+
"-I", Shellwords.escape(File.join(suite, "lib")),
|
|
48
|
+
Shellwords.escape(suite)
|
|
49
|
+
].join(" ")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Installs RSpec and bundler onto the machine under test. Runs once, when
|
|
53
|
+
# Busser installs this plugin.
|
|
54
|
+
# Builds the chef-apply command for a suite's setup recipe.
|
|
55
|
+
#
|
|
56
|
+
# @param setup_file [String, Pathname] path to the setup recipe
|
|
57
|
+
# @return [String] the command to run
|
|
58
|
+
def self.chef_apply_command(setup_file)
|
|
59
|
+
"/opt/chef/bin/chef-apply #{Shellwords.escape(setup_file.to_s)}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Builds the bundle install command for a suite's own Gemfile.
|
|
63
|
+
#
|
|
64
|
+
# bundler is invoked through the Ruby running Busser rather than whatever
|
|
65
|
+
# `bundle` is on PATH, since on a machine with several Rubies those differ and
|
|
66
|
+
# the suite's gems would land where the runner cannot see them.
|
|
67
|
+
#
|
|
68
|
+
# The --local attempt is a speed optimisation: it finishes immediately when
|
|
69
|
+
# the gems are already present and fails when it would need the network, so
|
|
70
|
+
# the second attempt is the fallback.
|
|
71
|
+
#
|
|
72
|
+
# @param gemfile [String, Pathname] path to the suite's Gemfile
|
|
73
|
+
# @return [String] the command to run
|
|
74
|
+
def self.bundle_install_command(gemfile)
|
|
75
|
+
bundle = [
|
|
76
|
+
Shellwords.escape(File.join(RbConfig::CONFIG["bindir"], "ruby")),
|
|
77
|
+
Shellwords.escape(File.join(Gem.bindir, "bundle")),
|
|
78
|
+
"install", "--gemfile", Shellwords.escape(gemfile.to_s)
|
|
79
|
+
].join(" ")
|
|
80
|
+
|
|
81
|
+
"#{bundle} --local || #{bundle}"
|
|
82
|
+
end
|
|
83
|
+
|
|
26
84
|
postinstall do
|
|
27
85
|
install_gem("rspec", ">= 3.13")
|
|
28
86
|
install_gem("bundler")
|
|
29
87
|
end
|
|
30
88
|
|
|
89
|
+
# Runs the suite's specs.
|
|
90
|
+
#
|
|
91
|
+
# If the suite ships a Gemfile its gems are installed first, and if it ships a
|
|
92
|
+
# setup-recipe.rb that recipe is applied with chef-apply to put the machine
|
|
93
|
+
# into a known state.
|
|
94
|
+
#
|
|
95
|
+
# @raise [RuntimeError] if a setup recipe is present but chef-apply is not
|
|
96
|
+
# installed, since running the specs against an unprepared machine would
|
|
97
|
+
# produce misleading failures
|
|
98
|
+
# @return [void]
|
|
31
99
|
def test
|
|
32
100
|
rspec_path = suite_path("rspec").to_s
|
|
33
101
|
|
|
@@ -43,21 +111,19 @@ class Busser::RunnerPlugin::Rspec < Busser::RunnerPlugin::Base
|
|
|
43
111
|
# to the internet-enabled version. It's a speed optimization.
|
|
44
112
|
banner("Bundle Installing..")
|
|
45
113
|
ENV["PATH"] = [ENV["PATH"], Gem.bindir, RbConfig::CONFIG["bindir"]].join(File::PATH_SEPARATOR)
|
|
46
|
-
|
|
47
|
-
"#{File.join(Gem.bindir, "bundle")} install --gemfile #{gemfile_path}"
|
|
48
|
-
run("#{bundle_exec} --local || #{bundle_exec}")
|
|
114
|
+
run(self.class.bundle_install_command(gemfile_path))
|
|
49
115
|
end
|
|
50
116
|
|
|
51
117
|
if File.exist?(setup_file)
|
|
52
118
|
unless File.exist?("/opt/chef/bin/chef-apply")
|
|
53
|
-
raise "You have a chef setup file at #{setup_file}, but /opt/chef/bin/chef-apply does not
|
|
119
|
+
raise "You have a chef setup file at #{setup_file}, but /opt/chef/bin/chef-apply does not exist"
|
|
54
120
|
end
|
|
55
121
|
|
|
56
|
-
run(
|
|
122
|
+
run(self.class.chef_apply_command(setup_file))
|
|
57
123
|
end
|
|
58
124
|
|
|
59
125
|
runner = File.expand_path(File.join(File.dirname(__FILE__), "..", "rspec", "runner.rb"))
|
|
60
|
-
run_ruby_script!(
|
|
126
|
+
run_ruby_script!(self.class.runner_command(runner, rspec_path))
|
|
61
127
|
end
|
|
62
128
|
end
|
|
63
129
|
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require_relative "../../spec_helper"
|
|
2
|
+
|
|
3
|
+
require "rbconfig"
|
|
4
|
+
require "shellwords"
|
|
5
|
+
require "busser/runner_plugin/rspec"
|
|
6
|
+
|
|
7
|
+
describe Busser::RunnerPlugin::Rspec do
|
|
8
|
+
describe ".runner_command" do
|
|
9
|
+
let(:cmd) do
|
|
10
|
+
Busser::RunnerPlugin::Rspec.runner_command("/gems/busser-rspec/lib/busser/rspec/runner.rb",
|
|
11
|
+
"/opt/busser/suites/rspec")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "runs the runner script against the suite" do
|
|
15
|
+
_(Shellwords.split(cmd)).must_equal [
|
|
16
|
+
"/gems/busser-rspec/lib/busser/rspec/runner.rb",
|
|
17
|
+
"-I", "/opt/busser/suites/rspec",
|
|
18
|
+
"-I", "/opt/busser/suites/rspec/lib",
|
|
19
|
+
"/opt/busser/suites/rspec"
|
|
20
|
+
]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Documented behaviour: spec_helper.rb is required without a relative path,
|
|
24
|
+
# which only works while the suite is on the load path.
|
|
25
|
+
it "puts the suite and its lib directory on the load path" do
|
|
26
|
+
_(Shellwords.split(cmd).each_cons(2).select { |flag, _| flag == "-I" }.map(&:last))
|
|
27
|
+
.must_equal ["/opt/busser/suites/rspec", "/opt/busser/suites/rspec/lib"]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "quotes a suite path containing spaces" do
|
|
31
|
+
cmd = Busser::RunnerPlugin::Rspec.runner_command("/a/runner.rb", "/tmp/my tests/rspec")
|
|
32
|
+
|
|
33
|
+
_(Shellwords.split(cmd)).must_equal [
|
|
34
|
+
"/a/runner.rb",
|
|
35
|
+
"-I", "/tmp/my tests/rspec",
|
|
36
|
+
"-I", "/tmp/my tests/rspec/lib",
|
|
37
|
+
"/tmp/my tests/rspec"
|
|
38
|
+
]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "accepts a Pathname suite" do
|
|
42
|
+
cmd = Busser::RunnerPlugin::Rspec.runner_command("/a/runner.rb", Pathname.new("/b/rspec"))
|
|
43
|
+
_(Shellwords.split(cmd).last).must_equal "/b/rspec"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe ".chef_apply_command" do
|
|
48
|
+
it "applies the setup recipe with chef-apply" do
|
|
49
|
+
cmd = Busser::RunnerPlugin::Rspec.chef_apply_command("/suite/setup-recipe.rb")
|
|
50
|
+
|
|
51
|
+
_(Shellwords.split(cmd))
|
|
52
|
+
.must_equal ["/opt/chef/bin/chef-apply", "/suite/setup-recipe.rb"]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "quotes a path containing spaces" do
|
|
56
|
+
cmd = Busser::RunnerPlugin::Rspec.chef_apply_command("/tmp/my tests/setup-recipe.rb")
|
|
57
|
+
|
|
58
|
+
_(Shellwords.split(cmd).last).must_equal "/tmp/my tests/setup-recipe.rb"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
describe ".bundle_install_command" do
|
|
63
|
+
let(:cmd) { Busser::RunnerPlugin::Rspec.bundle_install_command("/suite/Gemfile") }
|
|
64
|
+
|
|
65
|
+
it "invokes bundler through the running Ruby rather than PATH" do
|
|
66
|
+
first, second = Shellwords.split(cmd).first(2)
|
|
67
|
+
|
|
68
|
+
_(first).must_equal File.join(RbConfig::CONFIG["bindir"], "ruby")
|
|
69
|
+
_(second).must_equal File.join(Gem.bindir, "bundle")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "names the suite's Gemfile explicitly" do
|
|
73
|
+
_(Shellwords.split(cmd)).must_include "/suite/Gemfile"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "falls back from the local attempt to a networked one" do
|
|
77
|
+
_(cmd).must_include "--local || "
|
|
78
|
+
_(cmd.scan("--gemfile").length).must_equal 2
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "quotes a Gemfile path containing spaces" do
|
|
82
|
+
cmd = Busser::RunnerPlugin::Rspec.bundle_install_command("/tmp/my tests/Gemfile")
|
|
83
|
+
|
|
84
|
+
_(Shellwords.split(cmd.split(" || ").first)).must_include "/tmp/my tests/Gemfile"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: busser-rspec
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adam Jacob
|
|
@@ -38,9 +38,9 @@ files:
|
|
|
38
38
|
- ".markdownlint.yaml"
|
|
39
39
|
- ".release-please-manifest.json"
|
|
40
40
|
- ".rubocop.yml"
|
|
41
|
-
- ".tailor"
|
|
42
41
|
- ".yamllint"
|
|
43
42
|
- CHANGELOG.md
|
|
43
|
+
- CONTRIBUTING.md
|
|
44
44
|
- Gemfile
|
|
45
45
|
- LICENSE
|
|
46
46
|
- README.md
|
|
@@ -55,6 +55,8 @@ files:
|
|
|
55
55
|
- lib/busser/runner_plugin/rspec.rb
|
|
56
56
|
- release-please-config.json
|
|
57
57
|
- renovate.json
|
|
58
|
+
- spec/busser/runner_plugin/rspec_spec.rb
|
|
59
|
+
- spec/spec_helper.rb
|
|
58
60
|
homepage: https://github.com/test-kitchen/busser-rspec
|
|
59
61
|
licenses:
|
|
60
62
|
- Apache-2.0
|
data/.tailor
DELETED