mirror of
https://github.com/inspec/inspec
synced 2024-11-26 22:50:36 +00:00
Add an http test method
Signed-off-by: Guilhem Lettron <g.lettron@criteo.com>
This commit is contained in:
parent
185d1185fd
commit
51ca98c468
7 changed files with 206 additions and 0 deletions
1
Gemfile
1
Gemfile
|
@ -20,6 +20,7 @@ group :test do
|
||||||
gem 'mocha', '~> 1.1'
|
gem 'mocha', '~> 1.1'
|
||||||
gem 'ruby-progressbar', '~> 1.8'
|
gem 'ruby-progressbar', '~> 1.8'
|
||||||
gem 'nokogiri', '~> 1.6'
|
gem 'nokogiri', '~> 1.6'
|
||||||
|
gem 'webmock', '~> 2.3.2'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :integration do
|
group :integration do
|
||||||
|
|
94
docs/resources/http.md.erb
Normal file
94
docs/resources/http.md.erb
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
---
|
||||||
|
title: About the http Resource
|
||||||
|
---
|
||||||
|
|
||||||
|
# http
|
||||||
|
|
||||||
|
Use the `http` InSpec audit resource to test an http endpoint.
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
An `http` resource block declares the configuration settings to be tested:
|
||||||
|
|
||||||
|
describe http('url', auth: {user: 'user', pass: 'test'}, params: {params}, method: 'method', headers: {headers}, body: body) do
|
||||||
|
its('status') { should eq number }
|
||||||
|
its('body') { should eq 'body' }
|
||||||
|
its('header') { should eq 'header' }
|
||||||
|
end
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
* `('url')` is the url to test
|
||||||
|
* `{user: 'user', pass: 'test'}` may be specified for basic auth request
|
||||||
|
* `{params}` may be specified for http request parameters
|
||||||
|
* `'method'` may be specified for http request method (default to 'GET')
|
||||||
|
* `{headers}` may be specified for http request headers
|
||||||
|
* `body` may be specified for http request body
|
||||||
|
|
||||||
|
## Matchers
|
||||||
|
|
||||||
|
This InSpec audit resource has the following matchers:
|
||||||
|
|
||||||
|
### be
|
||||||
|
|
||||||
|
<%= partial "/shared/matcher_be" %>
|
||||||
|
|
||||||
|
### body
|
||||||
|
|
||||||
|
The `body` matcher tests body content of http response:
|
||||||
|
|
||||||
|
its('body') { should eq 'hello\n' }
|
||||||
|
|
||||||
|
### cmp
|
||||||
|
|
||||||
|
<%= partial "/shared/matcher_cmp" %>
|
||||||
|
|
||||||
|
### eq
|
||||||
|
|
||||||
|
<%= partial "/shared/matcher_eq" %>
|
||||||
|
|
||||||
|
### header
|
||||||
|
|
||||||
|
The `header` matcher tests arbitrary header for the http response:
|
||||||
|
|
||||||
|
its('header') { should eq 'value' }
|
||||||
|
|
||||||
|
### include
|
||||||
|
|
||||||
|
<%= partial "/shared/matcher_include" %>
|
||||||
|
|
||||||
|
### match
|
||||||
|
|
||||||
|
<%= partial "/shared/matcher_match" %>
|
||||||
|
|
||||||
|
### status
|
||||||
|
|
||||||
|
The `status` matcher tests status of the http response:
|
||||||
|
|
||||||
|
its('status') { should eq 200 }
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
The following examples show how to use this InSpec audit resource.
|
||||||
|
|
||||||
|
### Simple http test
|
||||||
|
|
||||||
|
For example, a service is listening on default http port can be tested like this:
|
||||||
|
|
||||||
|
describe http('http://localhost') do
|
||||||
|
its('status') { should cmp 200 }
|
||||||
|
end
|
||||||
|
|
||||||
|
### Complex http test
|
||||||
|
|
||||||
|
describe http('http://localhost:8080/ping',
|
||||||
|
auth: {user: 'user', pass: 'test'},
|
||||||
|
params: {format: 'html'},
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type' => 'application/json'},
|
||||||
|
data: '{"data":{"a":"1","b":"five"}}') do
|
||||||
|
its('status') { should cmp 200 }
|
||||||
|
its('body') { should cmp 'pong' }
|
||||||
|
its('Content-Type') { should cmp 'text/html' }
|
||||||
|
end
|
||||||
|
|
|
@ -38,4 +38,5 @@ Gem::Specification.new do |spec|
|
||||||
spec.add_dependency 'sslshake', '~> 1'
|
spec.add_dependency 'sslshake', '~> 1'
|
||||||
spec.add_dependency 'parallel', '~> 1.9'
|
spec.add_dependency 'parallel', '~> 1.9'
|
||||||
spec.add_dependency 'rspec_junit_formatter', '~> 0.2.3'
|
spec.add_dependency 'rspec_junit_formatter', '~> 0.2.3'
|
||||||
|
spec.add_dependency 'http', '~> 2.1.0'
|
||||||
end
|
end
|
||||||
|
|
|
@ -86,6 +86,7 @@ require 'resources/gem'
|
||||||
require 'resources/groups'
|
require 'resources/groups'
|
||||||
require 'resources/grub_conf'
|
require 'resources/grub_conf'
|
||||||
require 'resources/host'
|
require 'resources/host'
|
||||||
|
require 'resources/http'
|
||||||
require 'resources/iis_site'
|
require 'resources/iis_site'
|
||||||
require 'resources/inetd_conf'
|
require 'resources/inetd_conf'
|
||||||
require 'resources/interface'
|
require 'resources/interface'
|
||||||
|
|
54
lib/resources/http.rb
Normal file
54
lib/resources/http.rb
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
# copyright: 2017, Criteo
|
||||||
|
# author: Guilhem Lettron
|
||||||
|
# license: Apache v2
|
||||||
|
|
||||||
|
require 'http'
|
||||||
|
|
||||||
|
module Inspec::Resources
|
||||||
|
class Http < Inspec.resource(1)
|
||||||
|
name 'http'
|
||||||
|
desc 'Use the http InSpec audit resource to test http call.'
|
||||||
|
example "
|
||||||
|
describe http('http://localhost:8080/ping', auth: {user: 'user', pass: 'test'}, params: {format: 'html'}) do
|
||||||
|
its('status') { should cmp 200 }
|
||||||
|
its('body') { should cmp 'pong' }
|
||||||
|
its('Content-Type') { should cmp 'text/html' }
|
||||||
|
end
|
||||||
|
"
|
||||||
|
|
||||||
|
# rubocop:disable ParameterLists
|
||||||
|
def initialize(url, method: 'GET', params: nil, auth: {}, headers: {}, data: nil)
|
||||||
|
@url = url
|
||||||
|
@method = method
|
||||||
|
@params = params
|
||||||
|
@auth = auth
|
||||||
|
@headers = headers
|
||||||
|
@data = data
|
||||||
|
end
|
||||||
|
|
||||||
|
def status
|
||||||
|
response.status
|
||||||
|
end
|
||||||
|
|
||||||
|
def body
|
||||||
|
response.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def method_missing(name)
|
||||||
|
response.headers[name.to_s]
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"http #{@method} on #{@url}: #{response}"
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def response
|
||||||
|
http = HTTP.headers(@headers)
|
||||||
|
http = http.basic_auth(@auth) unless @auth.empty?
|
||||||
|
@response ||= http.request(@method, @url, { body: @data, params: @params })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,6 +11,7 @@ end
|
||||||
|
|
||||||
require 'minitest/autorun'
|
require 'minitest/autorun'
|
||||||
require 'minitest/spec'
|
require 'minitest/spec'
|
||||||
|
require 'webmock/minitest'
|
||||||
require 'mocha/setup'
|
require 'mocha/setup'
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require 'pathname'
|
require 'pathname'
|
||||||
|
|
54
test/unit/resources/http_test.rb
Normal file
54
test/unit/resources/http_test.rb
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
# author: Guilhem Lettron
|
||||||
|
|
||||||
|
require 'helper'
|
||||||
|
require 'inspec/resource'
|
||||||
|
|
||||||
|
describe 'Inspec::Resources::Http' do
|
||||||
|
it 'verify simple http' do
|
||||||
|
stub_request(:get, "www.example.com").to_return(status: 200, body: 'pong')
|
||||||
|
|
||||||
|
resource = load_resource('http', 'http://www.example.com')
|
||||||
|
_(resource.status).must_equal 200
|
||||||
|
_(resource.body).must_equal 'pong'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'verify http with basic auth' do
|
||||||
|
stub_request(:get, "www.example.com").with(basic_auth: ['user', 'pass']).to_return(status: 200, body: 'auth ok')
|
||||||
|
|
||||||
|
resource = load_resource('http', 'http://www.example.com', auth: { user: 'user',pass: 'pass'})
|
||||||
|
_(resource.status).must_equal 200
|
||||||
|
_(resource.body).must_equal 'auth ok'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'verify http post with data' do
|
||||||
|
stub_request(:post, "www.example.com").with(body: {data: {a: '1', b: 'five'}}).to_return(status: 200, body: 'post ok')
|
||||||
|
|
||||||
|
resource = load_resource('http', 'http://www.example.com',
|
||||||
|
method: 'POST',
|
||||||
|
data: '{"data":{"a":"1","b":"five"}}',
|
||||||
|
headers: {'content-type' => 'application/json'})
|
||||||
|
_(resource.status).must_equal 200
|
||||||
|
_(resource.body).must_equal 'post ok'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'verify http headers' do
|
||||||
|
stub_request(:post, "www.example.com").with(headers: {'content-type' => 'application/json'}).to_return(status: 200, body: 'headers ok', headers: {'mock' => 'ok'})
|
||||||
|
|
||||||
|
resource = load_resource('http', 'http://www.example.com',
|
||||||
|
method: 'POST',
|
||||||
|
data: '{"data":{"a":"1","b":"five"}}',
|
||||||
|
headers: {'content-type' => 'application/json'})
|
||||||
|
_(resource.status).must_equal 200
|
||||||
|
_(resource.body).must_equal 'headers ok'
|
||||||
|
_(resource.mock).must_equal 'ok'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'verify http with params' do
|
||||||
|
stub_request(:get, "www.example.com").with(query: {a: 'b'}).to_return(status: 200, body: 'params ok')
|
||||||
|
|
||||||
|
resource = load_resource('http', 'http://www.example.com', params: {a: 'b'})
|
||||||
|
_(resource.status).must_equal 200
|
||||||
|
_(resource.body).must_equal 'params ok'
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue