Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add curl_command as serverspec extension #89

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,4 +246,25 @@ describe 'my example' do
end
```

For this `examples/my_example.pp' must exist and contain valid Puppet code. It then uses the idempotent resource shared example.
For this `examples/my_example.pp` must exist and contain valid Puppet code. It then uses the idempotent resource shared example.

## Serverspec extensions

Some [Serverspec](https://serverspec.org/) extensions are shipped and enabled by default. These make it easier to write tests but were not accepted by Serverspec upstream.

### `curl_command`

Often you want to test some service that exposes things over HTTP.
Instead of using [`command("curl …")`](https://serverspec.org/resource_types.html#command) you can use `curl_command(…)` which behaves like a Serverspec `command` but adds matchers for the HTTP response code and the response body.

```ruby
describe curl_command("http://localhost:8080/api/ping") do
its(:response_code) { is_expected.to eq(200) }
its(:exit_status) { is_expected.to eq 0 }
end

describe curl_command('http://localhost:8080/api/status', headers: { 'Accept' => 'application/json' }) do
its(:response_code) { is_expected.to eq(200) }
its(:body_as_json) { is_expected.to eq({'status': 'ok'}) }
end
```
3 changes: 3 additions & 0 deletions examples/defaults_serverspec/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source 'https://rubygems.org'

gem 'voxpupuli-acceptance', path: '../..'
1 change: 1 addition & 0 deletions examples/defaults_serverspec/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require 'voxpupuli/acceptance/rake'
8 changes: 8 additions & 0 deletions examples/defaults_serverspec/manifests/init.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class defaults_serverspec {
package {'nginx':
ensure => present
}
service {'nginx':
ensure => running
}
}
14 changes: 14 additions & 0 deletions examples/defaults_serverspec/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "voxpupuliacceptancetests-defaults_serverspec",
"version": "0.0.1",
"author": "Vox Pupuli",
"license": "Apache-2.0",
"summary": "The voxpupuli-acceptance test suite defaults_serverspec",
"description": "test the serverspec extensions shipped in voxpupuli-acceptance",
"source": "https://github.com/voxpupuli/voxpupuli-acceptance",
"project_page": "https://github.com/voxpupuli/voxpupuli-acceptance",
"issues_url": "https://github.com/voxpupuli/voxpupuli-acceptance/issues",
"dependencies": [],
"requirements": [],
"operatingsystem_support": []
}
12 changes: 12 additions & 0 deletions examples/defaults_serverspec/spec/acceptance/basic_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'spec_helper_acceptance'

describe 'Basic integration test' do
it_behaves_like 'an idempotent resource' do
let(:manifest) { 'include defaults_serverspec' }
end

describe curl_command('http://localhost') do
its(:response_code) { is_expected.to eq(200) }
its(:exit_status) { is_expected.to eq 0 }
end
end
4 changes: 4 additions & 0 deletions examples/defaults_serverspec/spec/spec_helper_acceptance.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require 'voxpupuli/acceptance/spec_helper_acceptance'
require 'voxpupuli/acceptance/serverspec_extensions'

configure_beaker
2 changes: 1 addition & 1 deletion examples/new_example
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ RAKEFILE

cat > $EXAMPLE/metadata.json <<METADATA
{
"name": "voxpupuli_acceptance_tests-${EXAMPLE}",
"name": "voxpupuliacceptancetests-${EXAMPLE}",
"version": "0.0.1",
"author": "Vox Pupuli",
"license": "Apache-2.0",
Expand Down
12 changes: 12 additions & 0 deletions lib/voxpupuli/acceptance/serverspec_extensions.rb
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be added to spec_helper_acceptance.rb, or should people need to explicitly opt-in to it with

require 'voxpupuli/acceptance/serverspec_extensions'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makese sense to load it by default? It's not expensive and makes the usage easier.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only worry is that it modifies serverspec without the user opting in for that.
But I would also lean towards "enable"

@ekohl?

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'serverspec'
require_relative 'serverspec_extensions/curl_command'

module Serverspec
module Helper
module Type
def curl_command(*args)
Voxpupuli::Acceptance::ServerspecExtensions::CurlCommand.new(*args)
end
end
end
end
evgeni marked this conversation as resolved.
Show resolved Hide resolved
58 changes: 58 additions & 0 deletions lib/voxpupuli/acceptance/serverspec_extensions/curl_command.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# written by https://github.com/ekohl
# https://github.com/mizzy/serverspec/pull/611 was rejected so adding it here.

require 'serverspec'

module Voxpupuli
module Acceptance
module ServerspecExtensions
class CurlCommand < Serverspec::Type::Command
def response_code
m = %r{Response-Code: (?<code>\d+)}.match(stderr)
return 0 unless m

m[:code].to_i
end

def body
command_result.stdout
end

def body_as_json
MultiJson.load(body)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: serverspec itself now depends on multi_json so this should be acceptable.

end

private

def curl_command
# curl supports %{stderr} to --write-out since 7.63.0
# so the following doesn't work on EL8, which has curl 7.61.1
command = "curl --silent --write-out '%{stderr}Response-Code: %{response_code}\\n' '#{@name}'"
ekohl marked this conversation as resolved.
Show resolved Hide resolved

@options.each do |option, value|
case option
when :cacert, :cert, :key
command += " --#{option} '#{value}'"
when :headers
value.each do |header, header_value|
command += if header_value
" --header '#{header}: #{header_value}'"
else
" --header '#{header};'"
end
end
else
raise "Unknown option #{option} (value: #{value})"
end
end

command
end

def command_result
@command_result ||= @runner.run_command(curl_command)
end
end
end
end
end
Loading