beaker-http 0.0.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 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: