beaker-http 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 126ad20369072bad14cd0f1c540ebf2c5c09c8c8
4
+ data.tar.gz: 627779ca603f73a147d893dd8fef723b48082d28
5
+ SHA512:
6
+ metadata.gz: 149ac40c2ad28e4dd28d96cd27dfa0661b94018f1735139712ed655c969c179a8e0589339d7dc13f1c3ce137949eba67e98fe304185b829e356487fd291ccb85
7
+ data.tar.gz: da4fac3b62401bbabe3400c336701e76329dc2bb700fb5f802d1be66f38bdcdc93dd41839b2919a4eb37a429b403ebac4d4fec74ce0db9c7ef1cec76c7f65272
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source ENV['GEM_SOURCE'] || "https://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # beaker-http
2
+
3
+ This library is designed to assist in test scenarios where http requests to a Beaker::Host
4
+ are required. It utilizes the Faraday library to generate requests, and the [Http](lib/beaker-http/http.rb)
5
+ class is designed to be subclassed into objects that are more targeted to specific http
6
+ services running on beaker hosts.
7
+
8
+ ## spec testing
9
+
10
+ Spec tests all live under the `spec` folder. These are the default rake task, &
11
+ so can be run with a simple `bundle exec rake`, as well as being fully specified
12
+ by running `bundle exec rake test:spec:run` or using the `test:spec` task.
13
+
14
+ ## acceptance testing
15
+
16
+ Acceptance testing will be added once the first few releases have been released.
17
+
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ namespace :test do
4
+
5
+ namespace :spec do
6
+
7
+ desc "Run spec tests"
8
+ RSpec::Core::RakeTask.new(:run) do |t|
9
+ t.rspec_opts = ['--color']
10
+ t.pattern = 'spec/'
11
+ end
12
+ end
13
+ end
14
+
15
+ task 'test:spec' => 'test:spec:run'
16
+ task :test => 'test:spec'
17
+ task :default => :test
@@ -0,0 +1,33 @@
1
+ require 'beaker-http'
2
+
3
+ test_name 'Ensure that requests can be built out to the puppetserver' do
4
+
5
+ step 'install latest released puppet agent' do
6
+ install_puppet_agent_on(hosts)
7
+ end
8
+
9
+ step 'install the latest puppet-server on the master' do
10
+ install_package(master, 'puppetserver')
11
+ on master, 'service puppetserver start'
12
+ end
13
+
14
+ step 'generate a new beaker http connection object'
15
+ http_connection = generate_new_http_connection(master)
16
+
17
+ step 'configure the connection to connect to the master port' do
18
+ http_connection.url_prefix.port = 8140
19
+ end
20
+
21
+ step 'call the environments endpoint on the puppetserver' do
22
+ response = http_connection.get('/puppet/v3/environments')
23
+ assert_equal(200, response.status)
24
+ end
25
+
26
+ step 'call the environments endpoint with the #https_request method' do
27
+ response = http_request("https://#{master.hostname}:8140/puppet/v3/environments",
28
+ :get,
29
+ http_connection.ssl['client_cert'],
30
+ http_connection.ssl['client_key'])
31
+ assert_equal(200, response.status)
32
+ end
33
+ end
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'beaker-http/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "beaker-http"
8
+ spec.version = Beaker::Http::Version::STRING
9
+ spec.authors = ["Puppet"]
10
+ spec.email = ["qe@puppet.com"]
11
+ spec.summary = %q{Puppet testing tool}
12
+ spec.description = %q{Puppet testing tool coupled with Beaker}
13
+ spec.homepage = "https://github.com/puppetlabs/beaker-http"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ #Development dependencies
21
+ spec.add_development_dependency 'bundler', '~> 1.6'
22
+ spec.add_development_dependency 'pry', '~> 0.9.12'
23
+ spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'rspec', '>= 3.0.0'
25
+
26
+ #Documentation dependencies
27
+ spec.add_development_dependency 'yard', '~> 0'
28
+ spec.add_development_dependency 'markdown', '~> 0'
29
+ spec.add_development_dependency 'activesupport', '4.2.6'
30
+
31
+ #Run time dependencies
32
+ spec.add_runtime_dependency 'json', '~> 1.8'
33
+ spec.add_runtime_dependency 'beaker', '~> 3.0'
34
+ spec.add_runtime_dependency 'faraday', '~> 0.9', '>= 0.9.1'
35
+ spec.add_runtime_dependency 'faraday_middleware', '~> 0.9'
36
+ end
@@ -0,0 +1,62 @@
1
+ module Beaker::DSL::Helpers::WebHelpers
2
+
3
+ # Generates a new http connection object, using the ever-present options hash to
4
+ # configure the connection.
5
+ #
6
+ # @param host [Beaker::Host optional] supply a SUT host object; will use puppet on host
7
+ # to configure certs, and use the options in the host object instead of the global.
8
+ # @return [Beaker::Http::Connection] an object wrapping the Faraday::Connection object.
9
+ def generate_new_http_connection(host = nil)
10
+ if host
11
+ raise ArgumentError.new "host must be Beaker::Host, not #{host.class}" if !host.is_a?(Beaker::Host)
12
+ connection = Beaker::Http::Connection.new(host.options)
13
+ connection.configure_private_key_and_cert_with_puppet(host)
14
+ connection
15
+ else
16
+ Beaker::Http::Connection.new(options)
17
+ end
18
+ end
19
+
20
+ # Make a single http request and discard the http connection object. Returns a Faraday::Response
21
+ # object that can be introspected for all response information.
22
+ #
23
+ # @param url [String] String that will be parsed into a URI object.
24
+ # @param request_method [Symbol] Represents any valid http verb.
25
+ # @param cert [OpenSSL::X509::Certificate] Certifcate for authentication.
26
+ # @param key [OpenSSL::PKey::RSA] Private Key for authentication.
27
+ # @param body [String, Hash] For requests that can send a body. Strings are sent unformatted and
28
+ # Hashes are JSON.parsed by the Faraday Middleware.
29
+ # @param [Hash] options Hash of options extra options for the request
30
+ # @option options [Boolean] :read_timeout How long to wait before closing the connection.
31
+ # @return [Faraday::Response]
32
+ def http_request(url, request_method, cert=nil, key=nil, body=nil, options={})
33
+ connection = generate_new_http_connection
34
+
35
+
36
+ connection.url_prefix = URI.parse(url)
37
+
38
+ if cert
39
+ if cert.is_a?(OpenSSL::X509::Certificate)
40
+ connection.ssl['client_cert'] = cert
41
+ else
42
+ raise TypeError, "cert must be an OpenSSL::X509::Certificate object, not #{cert.class}"
43
+ end
44
+ end
45
+
46
+ if key
47
+ if key.is_a?(OpenSSL::PKey::RSA)
48
+ connection.ssl['client_key'] = key
49
+ else
50
+ raise TypeError, "key must be an OpenSSL::PKey:RSA object, not #{key.class}"
51
+ end
52
+ end
53
+
54
+ # ewwww
55
+ connection.ssl[:verify] = false
56
+
57
+ connection.connection.options.timeout = options[:read_timeout] if options[:read_timeout]
58
+
59
+ response = connection.send(request_method) { |conn| conn.body = body }
60
+ response
61
+ end
62
+ end
@@ -0,0 +1,49 @@
1
+ module Beaker
2
+ module Http
3
+ module Helpers
4
+
5
+ # Given a Beaker::Host object, introspect the host for the CA cert and save it to
6
+ # the coordinator's filesystem.
7
+ # @param host[Beaker::Host] host to ssh into and find the CA cert
8
+ # @return [String] File path to the CA cert saved on the coordinator
9
+ def get_host_cacert(host)
10
+ cacert_on_host= host.puppet['localcacert']
11
+ # puppet may not have laid down the cacert yet, so check to make sure
12
+ # the file exists
13
+ host.execute("test -f #{cacert_on_host}")
14
+ ca_cert = host.execute("cat #{cacert_on_host}", :silent => true)
15
+ cert_dir = Dir.mktmpdir("pe_certs")
16
+ ca_cert_file = File.join(cert_dir, "cacert.pem")
17
+ File.open(ca_cert_file, "w+") do |f|
18
+ f.write(ca_cert)
19
+ end
20
+ ca_cert_file
21
+ end
22
+
23
+ # Given a Beaker::Host object, introspect the host for the private key and save it to
24
+ # the coordinator's filesystem.
25
+ # @param host[Beaker::Host] host to ssh into and find the private key
26
+ # @return [String] A String of the private key
27
+ def get_host_private_key(host)
28
+ private_key = host.puppet['hostprivkey']
29
+ # puppet may not have laid down the private_key yet, so check to make sure
30
+ # the file exists
31
+ host.execute("test -f #{private_key}")
32
+ host.execute("cat #{private_key}", :silent => true)
33
+ end
34
+
35
+ # Given a Beaker::Host object, introspect the host for the host cert and save it to
36
+ # the coordinator's filesystem.
37
+ # @param host[Beaker::Host] host to ssh into and find the host cert
38
+ # @return [String] A String of the host cert
39
+ def get_host_cert(host)
40
+ hostcert = host.puppet['hostcert']
41
+ # puppet may not have laid down the hostcert yet, so check to make sure
42
+ # the file exists
43
+ host.execute("test -f #{hostcert}")
44
+ host.execute("cat #{hostcert}", :silent => true)
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,93 @@
1
+ module Beaker
2
+ module Http
3
+
4
+ # == Beaker::Http::Connection object instantiation examples
5
+ # These examples are for using the Connection object directly. If you are trying to use
6
+ # this from within a test, consider using the
7
+ # {Beaker::DSL::Helpers::WebHelpers DSL constructors} instead.
8
+ # @see Beaker::DSL::Helpers::WebHelpers
9
+ class Connection
10
+ include Beaker::Http::Helpers
11
+ extend Forwardable
12
+
13
+ attr_reader :connection
14
+
15
+ # Beaker::Http::Connection objects can be instantiated with object that
16
+ # utilizes a object for easier setup during testing.
17
+ #
18
+ # @param [Hash] options Typically the global options provided by Beaker.
19
+ # @option options [Beaker::Logger] :logger
20
+ # @option options [Boolean] :log_http_bodies
21
+ def initialize(options)
22
+ @connection = create_default_connection(options)
23
+ end
24
+
25
+ def_delegators :connection, :get, :post, :put, :delete, :head, :patch, :url_prefix, :url_prefix=, :ssl
26
+
27
+ def create_default_connection(options)
28
+ Faraday.new do |conn|
29
+ conn.request :json
30
+
31
+ conn.response :follow_redirects
32
+ conn.response :raise_error
33
+ conn.response :json, :content_type => /\bjson$/
34
+
35
+ # We can supply a third argument, a Hash with key of :bodies set to true or false,
36
+ # to configure whether or not to log http bodies in requests and responses.
37
+ # However, to uncomplicate things, we will just use the default
38
+ # set in the middleware and not allow the http log level to be set
39
+ # independently of the beaker log level. If we find that we should allow setting
40
+ # of http bodies independent of the beaker log level, we should expose that setting
41
+ # here.
42
+ conn.response :faraday_beaker_logger, options[:logger]
43
+
44
+ conn.adapter :net_http
45
+ end
46
+ end
47
+
48
+ # If you would like to run tests that expect 400 or even 500 responses,
49
+ # apply this method to remove the <tt>:raise_error</tt> middleware.
50
+ def remove_error_checking
51
+ connection.builder.delete(Faraday::Response::RaiseError)
52
+ nil
53
+ end
54
+
55
+ def set_cacert(ca_file)
56
+ ssl['ca_file'] = ca_file
57
+ url_prefix.scheme = 'https'
58
+ end
59
+
60
+ def set_client_key(client_key)
61
+ ssl['client_key'] = client_key
62
+ end
63
+
64
+ def set_client_cert(client_cert)
65
+ ssl['client_cert'] = client_cert
66
+ end
67
+
68
+ # Use this method if you are connecting as a user to the system; it will
69
+ # provide the correct SSL context but not provide authentication.
70
+ def configure_cacert_with_puppet(host)
71
+ set_cacert(get_host_cacert(host))
72
+ connection.host = host.hostname
73
+ nil
74
+ end
75
+
76
+ # Use this method if you want to connect to the system using certificate
77
+ # based authentication. This method will provide the ssl context and use
78
+ # the private key and cert from the host provided for authentication.
79
+ def configure_private_key_and_cert_with_puppet(host)
80
+ configure_cacert_with_puppet(host)
81
+
82
+ client_key_raw = get_host_private_key(host)
83
+ client_cert_raw = get_host_cert(host)
84
+
85
+ ssl['client_key'] = OpenSSL::PKey.read(client_key_raw)
86
+ ssl['client_cert'] = OpenSSL::X509::Certificate.new(client_cert_raw)
87
+
88
+ nil
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,55 @@
1
+ module Beaker
2
+ module Http
3
+ class FaradayBeakerLogger < Faraday::Response::Middleware
4
+ extend Forwardable
5
+
6
+ DEFAULT_OPTIONS = { :bodies => true }
7
+
8
+ def initialize(app, logger, options = {} )
9
+ super(app)
10
+ @logger = logger
11
+ @options = DEFAULT_OPTIONS.merge(options)
12
+ end
13
+
14
+ def_delegators :@logger, :trace, :debug, :info, :notify, :warn
15
+
16
+ def call(env)
17
+ @start_time = Time.now
18
+ info "#{env.method.upcase}: #{env.url.to_s}"
19
+ debug "REQUEST HEADERS:\n#{dump_headers env.request_headers}"
20
+ debug "REQUEST BODY:\n#{dump_body env[:body]}" if env[:body] && log_body?(:request)
21
+ super
22
+ end
23
+
24
+ def on_complete(env)
25
+ info "RESPONSE CODE: #{env.status.to_s}"
26
+ debug "ELAPSED TIME: #{Time.now - @start_time}"
27
+ debug "RESPONSE HEADERS:\n#{dump_headers env.response_headers}"
28
+ debug "RESPONSE BODY:\n#{dump_body env[:body]}" if env[:body] && log_body?(:response)
29
+ end
30
+ private
31
+
32
+ def dump_headers(headers)
33
+ headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
34
+ end
35
+
36
+ def dump_body(body)
37
+ if body.respond_to?(:to_str)
38
+ body.to_str
39
+ else
40
+ pretty_inspect(body)
41
+ end
42
+ end
43
+
44
+ def log_body?(type)
45
+ case @options[:bodies]
46
+ when Hash then @options[:bodies][type]
47
+ else @options[:bodies]
48
+ end
49
+ end
50
+
51
+ end
52
+ end
53
+ end
54
+
55
+ Faraday::Response.register_middleware :faraday_beaker_logger => lambda { Beaker::Http::FaradayBeakerLogger }
@@ -0,0 +1,7 @@
1
+ module Beaker
2
+ module Http
3
+ module Version
4
+ STRING = '0.0.1'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+ require 'forwardable'
4
+
5
+ require 'beaker'
6
+
7
+ require 'beaker-http/helpers/puppet_helpers'
8
+ require 'beaker-http/dsl/web_helpers'
9
+ require "beaker-http/http"
10
+ require 'beaker-http/middleware/response/faraday_beaker_logger'
@@ -0,0 +1,151 @@
1
+ require 'spec_helper'
2
+
3
+ class ClassMixedWithDSLWebHelpers
4
+ include Beaker::DSL::Helpers
5
+
6
+ attr_accessor :options
7
+
8
+ def initialize
9
+ @options = { logger: Beaker::Logger.new }
10
+ end
11
+ end
12
+
13
+ describe ClassMixedWithDSLWebHelpers do
14
+
15
+ describe '#generate_new_http_connection' do
16
+
17
+ it 'raises an argument error if a non Beaker::Host is supplied' do
18
+ expect{subject.generate_new_http_connection(Object.new)}.to raise_error(ArgumentError)
19
+ end
20
+
21
+ it 'raises no errors when no argument is supplied' do
22
+ expect{subject.generate_new_http_connection}.to_not raise_error
23
+ end
24
+
25
+ context 'when passed a beaker host' do
26
+ unixhost = { roles: ['test_role'],
27
+ 'platform' => 'debian-7-x86_64' }
28
+ let(:host) { Beaker::Host.create('test.com', unixhost, {}) }
29
+ let(:mock_options) { {:logger => Beaker::Logger.new} }
30
+ let(:mock_connection) {double('connection')}
31
+
32
+ it 'configures the connection object' do
33
+ expect(mock_connection).to receive(:configure_private_key_and_cert_with_puppet).with(host)
34
+ expect(Beaker::Http::Connection).to receive(:new).with(mock_options).and_return(mock_connection)
35
+ allow(host).to receive(:options).and_return(mock_options)
36
+ expect{subject.generate_new_http_connection(host)}.to_not raise_error
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ describe '#http_request' do
43
+ let (:url) {"http://wwww.test.com"}
44
+ let (:request_method) { :get }
45
+ let (:mock_response) {double('reponse')}
46
+ let (:mock_connection) { subject.generate_new_http_connection }
47
+ let (:read_timeout) {double('read_timeout')}
48
+
49
+ it 'sends a GET request to the url with the minimum required params' do
50
+ expect(mock_connection).to receive(:get).and_return(mock_response)
51
+ expect(URI).to receive(:parse).with(url).and_call_original
52
+ expect(mock_connection).to receive(:url_prefix=).and_call_original
53
+ expect(subject).to receive(:generate_new_http_connection).and_return(mock_connection)
54
+ expect(subject.http_request(url, request_method)).to eq(mock_response)
55
+ end
56
+
57
+ context 'send a DELETE request to the url with the minimum required params' do
58
+ let (:request_method) { :delete }
59
+ it 'sends a DELETE request to the url with the minimum required params' do
60
+ expect(mock_connection).to receive(:delete).and_return(mock_response)
61
+ expect(URI).to receive(:parse).with(url).and_call_original
62
+ expect(mock_connection).to receive(:url_prefix=).and_call_original
63
+ expect(subject).to receive(:generate_new_http_connection).and_return(mock_connection)
64
+ expect(subject.http_request(url, request_method)).to eq(mock_response)
65
+ end
66
+ end
67
+
68
+ context 'when the request_method is POST' do
69
+ let (:request_method) { :post }
70
+ let (:body) {double('body')}
71
+ let (:conn) { double('conn') }
72
+
73
+ it 'sends a body along in the request' do
74
+ expect(conn).to receive(:body=).with(body)
75
+ expect(mock_connection).to receive(:post).and_yield(conn).and_return(mock_response)
76
+ expect(URI).to receive(:parse).with(url).and_call_original
77
+ expect(mock_connection).to receive(:url_prefix=).and_call_original
78
+ expect(subject).to receive(:generate_new_http_connection).and_return(mock_connection)
79
+ expect(subject.http_request(url, request_method, nil, nil, body, {})).to eq(mock_response)
80
+ end
81
+ end
82
+
83
+
84
+ context 'when the request_method is PUT' do
85
+ let (:request_method) { :put }
86
+ let (:body) {double('body')}
87
+ let (:conn) { double('conn') }
88
+
89
+ it 'sends a body along in the request' do
90
+ expect(conn).to receive(:body=).with(body)
91
+ expect(mock_connection).to receive(:put).and_yield(conn).and_return(mock_response)
92
+ expect(URI).to receive(:parse).with(url).and_call_original
93
+ expect(mock_connection).to receive(:url_prefix=).and_call_original
94
+ expect(subject).to receive(:generate_new_http_connection).and_return(mock_connection)
95
+ expect(subject.http_request(url, request_method, nil, nil, body, {})).to eq(mock_response)
96
+ end
97
+
98
+ end
99
+
100
+ it 'can set the timeout from the options hash passed in' do
101
+ expect(mock_connection).to receive(:get).and_return(mock_response)
102
+ expect(URI).to receive(:parse).with(url).and_call_original
103
+ expect(mock_connection).to receive(:url_prefix=).and_call_original
104
+ expect(subject).to receive(:generate_new_http_connection).and_return(mock_connection)
105
+ expect(subject.http_request(url, request_method, nil, nil, nil, :read_timeout => read_timeout)).to eq(mock_response)
106
+ expect(mock_connection.connection.options.timeout).to eq(read_timeout)
107
+ end
108
+
109
+ context 'with a key and cert provided' do
110
+ let (:key) {'key'}
111
+ let (:cert) {'cert'}
112
+ it 'checks to ensure they are valid types and then adds them to the request' do
113
+
114
+ expect(mock_connection).to receive(:get).and_return(mock_response)
115
+ expect(key).to receive(:is_a?).with(OpenSSL::PKey::RSA).and_return(true)
116
+ expect(cert).to receive(:is_a?).with(OpenSSL::X509::Certificate).and_return(true)
117
+ expect(URI).to receive(:parse).with(url).and_call_original
118
+ expect(mock_connection).to receive(:url_prefix=).and_call_original
119
+
120
+ expect(subject).to receive(:generate_new_http_connection).and_return(mock_connection)
121
+
122
+ expect(subject.http_request(url, request_method, cert, key)).to eq(mock_response)
123
+ expect(mock_connection.ssl['client_key']).to eq(key)
124
+ expect(mock_connection.ssl['client_cert']).to eq(cert)
125
+ end
126
+
127
+ it 'errors when an invalid key is provided' do
128
+ expect(mock_connection).to_not receive(:get)
129
+ expect(key).to receive(:is_a?).with(OpenSSL::PKey::RSA).and_call_original
130
+ expect(cert).to receive(:is_a?).with(OpenSSL::X509::Certificate).and_return(true)
131
+ expect(URI).to receive(:parse).with(url).and_call_original
132
+ expect(mock_connection).to receive(:url_prefix=).and_call_original
133
+ expect(subject).to receive(:generate_new_http_connection).and_return(mock_connection)
134
+ expect{subject.http_request(url, request_method, cert, key)}.to raise_error(TypeError)
135
+ end
136
+
137
+ it 'errors when an invalid cert is provided' do
138
+ expect(mock_connection).to_not receive(:get)
139
+ expect(key).to_not receive(:is_a?).with(OpenSSL::PKey::RSA)
140
+ expect(cert).to receive(:is_a?).with(OpenSSL::X509::Certificate).and_call_original
141
+ expect(URI).to receive(:parse).with(url).and_call_original
142
+ expect(mock_connection).to receive(:url_prefix=).and_call_original
143
+ expect(subject).to receive(:generate_new_http_connection).and_return(mock_connection)
144
+ expect{subject.http_request(url, request_method, cert, key)}.to raise_error(TypeError)
145
+ end
146
+
147
+ end
148
+
149
+ end
150
+
151
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ module Beaker
4
+ module Http
5
+ describe Connection do
6
+
7
+ let(:options) {{ :logger => Beaker::Logger.new}}
8
+
9
+ subject { Connection.new( options ) }
10
+
11
+ context 'with a beaker logger in the options passed in ' do
12
+
13
+ it 'does not raise errors' do
14
+ expect {subject}.to_not raise_error
15
+ end
16
+
17
+ it 'sets a Faraday object as the instance connection object' do
18
+ expect(subject.connection).to be_instance_of(Faraday::Connection)
19
+ end
20
+
21
+ it 'sets the middleware stack' do
22
+ expect(subject.connection.builder.handlers).to eq(HttpHelpers::DEFAULT_MIDDLEWARE_STACK)
23
+ end
24
+
25
+ it 'routes all http verbs to the connection object' do
26
+ http_verbs = [:get, :post, :put, :delete, :head, :patch]
27
+
28
+ http_verbs.each do |verb|
29
+ expect(subject.connection).to receive(verb)
30
+ subject.send(verb)
31
+ end
32
+ end
33
+
34
+ it 'routes other useful methods to the connection object' do
35
+ useful_methods = [:url_prefix, :url_prefix=, :ssl]
36
+
37
+ useful_methods.each do |method|
38
+ expect(subject.connection).to receive(method)
39
+ subject.send(method)
40
+ end
41
+ end
42
+
43
+ describe '#remove_error_checking' do
44
+ it 'removes the faraday middleware raising errors on 4xx and 5xx requests' do
45
+ subject.remove_error_checking
46
+ expect(subject.connection.builder.handlers).not_to include(Faraday::Response::RaiseError)
47
+ end
48
+ end
49
+
50
+ context 'with a beaker host passed in' do
51
+ unixhost = { roles: ['test_role'],
52
+ 'platform' => 'debian-7-x86_64' }
53
+ let(:host) { Beaker::Host.create('test.com', unixhost, {}) }
54
+
55
+ describe '#configure_cacert_with_puppet'
56
+ it 'adds a ca_cert to the connection and changes the scheme to https' do
57
+ allow(subject).to receive(:get_host_cacert).with(host).and_return('ca_file')
58
+ subject.configure_cacert_with_puppet(host)
59
+ expect(subject.connection.ssl['ca_file']).to eq('ca_file')
60
+ expect(subject.connection.scheme).to eq('https')
61
+ end
62
+
63
+ describe '#configure_private_key_and_cert_with_puppet'
64
+ it 'calls #configure_cacert_only_with_puppet and adds the host private key and cert' do
65
+ allow(subject).to receive(:configure_cacert_with_puppet)
66
+ allow(subject).to receive(:get_host_private_key).with(host).and_return('private_key')
67
+ allow(subject).to receive(:get_host_cert).with(host).and_return('host_cert')
68
+
69
+ allow(OpenSSL::PKey).to receive(:read).with('private_key').and_return('ssl_private_key')
70
+ allow(OpenSSL::X509::Certificate).to receive(:new).with('host_cert').and_return('ssl_host_cert')
71
+
72
+ subject.configure_private_key_and_cert_with_puppet(host)
73
+ expect(subject.connection.ssl['client_key']).to eq('ssl_private_key')
74
+ expect(subject.connection.ssl['client_cert']).to eq('ssl_host_cert')
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Beaker::Http::FaradayBeakerLogger do
4
+
5
+ let(:conn) { Faraday.new(:url => 'http://test.com/path') }
6
+ let (:logger) { Beaker::Logger.new }
7
+
8
+ context 'with log bodies turned off' do
9
+
10
+ before do
11
+ conn.builder.insert(0, Beaker::Http::FaradayBeakerLogger, logger, :bodies => false)
12
+ conn.adapter :test do |stub|
13
+ stub.get('/path') {[200, {}, 'success']}
14
+ end
15
+ end
16
+
17
+ it 'sends info and debug requests to the logger' do
18
+ expect(logger).to receive(:info).with('GET: http://test.com/path').once
19
+ expect(logger).to receive(:info).with(/RESPONSE CODE: 200/).once
20
+ expect(logger).to receive(:debug).with(/ELAPSED TIME:/).once
21
+ expect(logger).to receive(:debug).with(/REQUEST HEADERS:/).once
22
+ expect(logger).to receive(:debug).with(/RESPONSE HEADERS:/).once
23
+ expect(logger).to_not receive(:debug).with(/RESPONSE BODY:/)
24
+ expect(logger).to_not receive(:debug).with(/REQUEST BODY:/)
25
+ conn.get
26
+ end
27
+ end
28
+
29
+ context 'with log bodies turned on' do
30
+
31
+ before do
32
+ conn.builder.insert(0, Beaker::Http::FaradayBeakerLogger, logger, :bodies => true)
33
+ conn.adapter :test do |stub|
34
+ stub.post('/path') {[201, {}, 'success']}
35
+ end
36
+ end
37
+
38
+ it 'sends extra debug requests to the logger' do
39
+ expect(logger).to receive(:info).with('POST: http://test.com/path').once
40
+ expect(logger).to receive(:info).with(/RESPONSE CODE: 201/).once
41
+ expect(logger).to receive(:debug).with(/ELAPSED TIME:/).once
42
+ expect(logger).to receive(:debug).with(/RESPONSE BODY:\nsuccess/).once
43
+ expect(logger).to receive(:debug).with(/REQUEST BODY:\nBODY MOVIN'/).once
44
+ expect(logger).to receive(:debug).with(/REQUEST HEADERS:/).once
45
+ expect(logger).to receive(:debug).with(/RESPONSE HEADERS:/).once
46
+ conn.post() { |connection| connection.body = "BODY MOVIN'" }
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,10 @@
1
+ require 'beaker-http'
2
+
3
+ module HttpHelpers
4
+ DEFAULT_MIDDLEWARE_STACK = [FaradayMiddleware::EncodeJson,
5
+ FaradayMiddleware::FollowRedirects,
6
+ Faraday::Response::RaiseError,
7
+ FaradayMiddleware::ParseJson,
8
+ Beaker::Http::FaradayBeakerLogger,
9
+ Faraday::Adapter::NetHttp]
10
+ end
metadata ADDED
@@ -0,0 +1,223 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: beaker-http
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Puppet
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.12
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.9.12
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 3.0.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 3.0.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: markdown
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '='
102
+ - !ruby/object:Gem::Version
103
+ version: 4.2.6
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 4.2.6
111
+ - !ruby/object:Gem::Dependency
112
+ name: json
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.8'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.8'
125
+ - !ruby/object:Gem::Dependency
126
+ name: beaker
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: faraday
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.9'
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: 0.9.1
149
+ type: :runtime
150
+ prerelease: false
151
+ version_requirements: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - "~>"
154
+ - !ruby/object:Gem::Version
155
+ version: '0.9'
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: 0.9.1
159
+ - !ruby/object:Gem::Dependency
160
+ name: faraday_middleware
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '0.9'
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: '0.9'
173
+ description: Puppet testing tool coupled with Beaker
174
+ email:
175
+ - qe@puppet.com
176
+ executables: []
177
+ extensions: []
178
+ extra_rdoc_files: []
179
+ files:
180
+ - Gemfile
181
+ - README.md
182
+ - Rakefile
183
+ - acceptance/tests/puppetserver_requests.rb
184
+ - beaker-http.gemspec
185
+ - lib/beaker-http.rb
186
+ - lib/beaker-http/dsl/web_helpers.rb
187
+ - lib/beaker-http/helpers/puppet_helpers.rb
188
+ - lib/beaker-http/http.rb
189
+ - lib/beaker-http/middleware/response/faraday_beaker_logger.rb
190
+ - lib/beaker-http/version.rb
191
+ - spec/beaker-http/dsl/web_helpers_spec.rb
192
+ - spec/beaker-http/http_spec.rb
193
+ - spec/beaker-http/middleware/response/faraday_beaker_logger_spec.rb
194
+ - spec/spec_helper.rb
195
+ homepage: https://github.com/puppetlabs/beaker-http
196
+ licenses: []
197
+ metadata: {}
198
+ post_install_message:
199
+ rdoc_options: []
200
+ require_paths:
201
+ - lib
202
+ required_ruby_version: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ version: '0'
207
+ required_rubygems_version: !ruby/object:Gem::Requirement
208
+ requirements:
209
+ - - ">="
210
+ - !ruby/object:Gem::Version
211
+ version: '0'
212
+ requirements: []
213
+ rubyforge_project:
214
+ rubygems_version: 2.5.1
215
+ signing_key:
216
+ specification_version: 4
217
+ summary: Puppet testing tool
218
+ test_files:
219
+ - spec/beaker-http/dsl/web_helpers_spec.rb
220
+ - spec/beaker-http/http_spec.rb
221
+ - spec/beaker-http/middleware/response/faraday_beaker_logger_spec.rb
222
+ - spec/spec_helper.rb
223
+ has_rdoc: