http_event_logger 0.1.0.rc1

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.
@@ -0,0 +1,151 @@
1
+ describe HttpEventLogger do
2
+
3
+ let(:host) { "localhost" }
4
+ let(:port) { 9292 }
5
+ let(:path) { "/index.html" }
6
+ let(:data) { "foo=bar&bar=foo" }
7
+
8
+ DRIVERS = [
9
+ HttpEventLogger::Test::Driver::Ethon,
10
+ HttpEventLogger::Test::Driver::Excon,
11
+ HttpEventLogger::Test::Driver::Faraday,
12
+ HttpEventLogger::Test::Driver::HTTParty,
13
+ HttpEventLogger::Test::Driver::HTTPClient,
14
+ HttpEventLogger::Test::Driver::NetHTTP,
15
+ HttpEventLogger::Test::Driver::OpenUri,
16
+ HttpEventLogger::Test::Driver::Patron,
17
+ HttpEventLogger::Test::Driver::Typhoeus
18
+ ].freeze
19
+
20
+ DRIVERS.each do |driver_class|
21
+
22
+ connection_event_supported = !driver_class.is_libcurl?
23
+
24
+ context "when #{driver_class.library_name} is in use" do
25
+
26
+ let(:driver_class) { driver_class }
27
+ let(:connection_event_supported) { connection_event_supported }
28
+ let(:expected_response_type) { driver_class.expected_response_type }
29
+ let(:driver) { driver_class.new(host, port, path) }
30
+
31
+ context "and the defaults are configured" do
32
+
33
+ it "logs GET requests" do
34
+ res = driver.send_get_request
35
+
36
+ expect(log).to include_message("Connected") if connection_event_supported
37
+
38
+ expect(log).to include_message("Sent - GET http://#{host}:#{port}#{path}")
39
+ expect(log).to include_message("Sent - Headers:")
40
+ expect(log).to_not include_message("Sent - Body:")
41
+
42
+ expect(log).to include_message("Benchmark:")
43
+ expect(log).to include_message("Received - Status: 200")
44
+ expect(log).to include_message("Received - Headers:")
45
+ expect(log).to include_message("Received - Body:#{driver_class.expected_response_body}")
46
+
47
+ expect(res).to be_a(expected_response_type) if expected_response_type
48
+ end if driver_class.method_defined?(:send_get_request)
49
+
50
+ it "logs POST requests" do
51
+ res = driver.send_post_request
52
+
53
+ expect(log).to include_message("Connected") if connection_event_supported
54
+
55
+ expect(log).to include_message("Sent - POST http://#{host}:#{port}#{path}")
56
+ expect(log).to include_message("Sent - Headers:")
57
+ expect(log).to include_message("Sent - Body: #{data}")
58
+
59
+ expect(log).to include_message("Benchmark:")
60
+ expect(log).to include_message("Received - Status: 200")
61
+ expect(log).to include_message("Received - Headers:")
62
+ expect(log).to include_message("Received - Body:#{driver_class.expected_response_body}")
63
+
64
+ expect(res).to be_a(expected_response_type) if expected_response_type
65
+ end if driver_class.method_defined?(:send_post_request)
66
+
67
+ end
68
+
69
+ context "and the default logger is configured with a custom log level" do
70
+
71
+ before(:example) { configure(HttpEventLogger::Logger.new(logger: @logger, severity: ::Logger::Severity::INFO)) }
72
+
73
+ it "logs at the configured level" do
74
+ driver.send_get_request
75
+
76
+ expect(log).to include("INFO")
77
+ end
78
+
79
+ end
80
+
81
+ context "and the default logger is configured with a uri blacklist pattern" do
82
+
83
+ before(:example) do
84
+ configure(HttpEventLogger::Logger.new(logger: @logger, blacklist_pattern: blacklist_pattern))
85
+ end
86
+
87
+ context "and a request is made matching the pattern" do
88
+
89
+ let(:blacklist_pattern) { /localhost/ }
90
+
91
+ it "should not log anything" do
92
+ driver.send_get_request
93
+
94
+ expect(log).to be_empty
95
+ end
96
+
97
+ end
98
+
99
+ context "and a request is made that does not match the pattern" do
100
+
101
+ let(:blacklist_pattern) { /does_not_match/ }
102
+
103
+ it "logs all events" do
104
+ driver.send_get_request
105
+
106
+ expect(log).to include_message("Sent")
107
+ expect(log).to include_message("Benchmark")
108
+ expect(log).to include_message("Received")
109
+ end
110
+
111
+ end
112
+
113
+ end
114
+
115
+ context "and a custom logger is configured" do
116
+
117
+ before(:example) { configure(HttpEventLogger::Test::CustomLogger.new(@logger)) }
118
+
119
+ it "logs connection events" do
120
+ driver.send_get_request
121
+
122
+ expect(log).to include("Custom - Connected: #{host}:#{port}")
123
+ end if connection_event_supported
124
+
125
+ it "logs request events" do
126
+ driver.send_get_request
127
+
128
+ expect(log).to include("Custom - Sent: Request Event")
129
+ end
130
+
131
+ it "logs repsonse events" do
132
+ driver.send_get_request
133
+
134
+ expect(log).to include("Custom - Received: Response Event")
135
+ end
136
+
137
+ end
138
+
139
+ end
140
+
141
+ end
142
+
143
+ def include_message(message)
144
+ include("[#{host}:#{port}] #{message}")
145
+ end
146
+
147
+ def configure(logger)
148
+ HttpEventLogger.configuration.logger = logger
149
+ end
150
+
151
+ end
@@ -0,0 +1,36 @@
1
+ require 'bundler'
2
+ Bundler.require(:development)
3
+
4
+ SimpleCov.start do
5
+ coverage_dir "tmp/coverage"
6
+
7
+ add_filter "/spec/"
8
+
9
+ refuse_coverage_drop
10
+ end if ENV["coverage"]
11
+
12
+ require 'stringio'
13
+
14
+ require_relative '../lib/http_event_logger'
15
+
16
+ require_relative 'support/driver/base'
17
+ Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |file| require file }
18
+
19
+ # Server for test endpoints
20
+ @server_thread = Thread.new { Rack::Handler::Thin.run(HttpEventLogger::Test::Server.new, Port: 9292) }
21
+ sleep(1) # Wait for server
22
+
23
+ RSpec.configure do |config|
24
+
25
+ config.before(:example) do
26
+ @log = StringIO.new
27
+ @logger = ::Logger.new(@log)
28
+
29
+ HttpEventLogger.configure { |config| config.logger = HttpEventLogger::Logger.new(logger: @logger) }
30
+ end
31
+
32
+ def log
33
+ @log.string
34
+ end
35
+
36
+ end
@@ -0,0 +1,25 @@
1
+ module HttpEventLogger
2
+ module Test
3
+
4
+ class CustomLogger < HttpEventLogger::Logger
5
+
6
+ def initialize(logger)
7
+ super(logger: logger)
8
+ end
9
+
10
+ def connected(connection)
11
+ log "Custom - Connected: #{connection.uri}"
12
+ end
13
+
14
+ def sent(request)
15
+ log "Custom - Sent: Request Event"
16
+ end
17
+
18
+ def received(response)
19
+ log "Custom - Received: Response Event"
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,48 @@
1
+ module HttpEventLogger
2
+ module Test
3
+ module Driver
4
+
5
+ class Base
6
+
7
+ class << self
8
+
9
+ def library_name
10
+ self.name.demodulize
11
+ end
12
+
13
+ def is_libcurl?
14
+ false
15
+ end
16
+
17
+ def expected_response_type
18
+ nil
19
+ end
20
+
21
+ def expected_response_body
22
+ "\n<html>"
23
+ end
24
+
25
+ end
26
+
27
+ def initialize(host, port, path, protocol="http")
28
+ @host = host
29
+ @port = port
30
+ @path = path
31
+ @protocol = protocol
32
+ @headers = { "accept" => "*/*", "foo" => "bar" }
33
+ @data = "foo=bar&bar=foo"
34
+ @params = { "foo" => 'bar', "bar" => "foo" }
35
+ end
36
+
37
+ def uri
38
+ "#{@protocol}://#{@host}:#{@port}#{@path}"
39
+ end
40
+
41
+ def send_post_form_request
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,29 @@
1
+ require 'ethon'
2
+
3
+ module HttpEventLogger
4
+ module Test
5
+ module Driver
6
+
7
+ class Ethon < HttpEventLogger::Test::Driver::Base
8
+
9
+ def self.is_libcurl?
10
+ true
11
+ end
12
+
13
+ def send_get_request
14
+ easy = ::Ethon::Easy.new
15
+ easy.http_request(uri, :get, { headers: @headers })
16
+ easy.perform
17
+ end
18
+
19
+ def send_post_request
20
+ easy = ::Ethon::Easy.new
21
+ easy.http_request(uri, :post, { headers: @headers, body: @data })
22
+ easy.perform
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ require 'excon'
2
+
3
+ module HttpEventLogger
4
+ module Test
5
+ module Driver
6
+
7
+ class Excon < HttpEventLogger::Test::Driver::Base
8
+
9
+ def send_get_request
10
+ ::Excon.get(uri, headers: @headers )
11
+ end
12
+
13
+ def send_post_request
14
+ ::Excon.post(uri, body: @data, headers: @headers)
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,36 @@
1
+ require 'faraday'
2
+
3
+ module HttpEventLogger
4
+ module Test
5
+ module Driver
6
+
7
+ class Faraday < HttpEventLogger::Test::Driver::Base
8
+
9
+ def send_get_request
10
+ connection.get do |req|
11
+ req.url(uri)
12
+ req.headers = @headers
13
+ end
14
+ end
15
+
16
+ def send_post_request
17
+ connection.post do |req|
18
+ req.url(uri)
19
+ req.headers = @headers
20
+ req.body = @data
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def connection
27
+ ::Faraday.new(url: "#{@protocol}://#{@host}:#{@port}") do |faraday|
28
+ faraday.adapter(::Faraday.default_adapter) # Uses Net::HTTP
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ require 'httparty'
2
+
3
+ module HttpEventLogger
4
+ module Test
5
+ module Driver
6
+
7
+ class HTTParty < HttpEventLogger::Test::Driver::Base
8
+
9
+ def send_get_request
10
+ ::HTTParty.get(uri, headers: @headers)
11
+ end
12
+
13
+ def send_post_request
14
+ ::HTTParty.post(uri, body: @data, headers: @headers)
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ require 'httpclient'
2
+
3
+ module HttpEventLogger
4
+ module Test
5
+ module Driver
6
+
7
+ class HTTPClient < HttpEventLogger::Test::Driver::Base
8
+
9
+ def self.expected_response_type
10
+ HTTP::Message
11
+ end
12
+
13
+ def send_get_request
14
+ ::HTTPClient.get(uri, header: @headers)
15
+ end
16
+
17
+ def send_post_request
18
+ ::HTTPClient.post(uri, body: @data, header: @headers)
19
+ end
20
+
21
+ def send_post_form_request(params)
22
+ ::HTTPClient.post_content(uri, params, @headers)
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ module HttpEventLogger
2
+ module Test
3
+ module Driver
4
+
5
+ class NetHTTP < HttpEventLogger::Test::Driver::Base
6
+
7
+ def send_get_request
8
+ Net::HTTP.get_response(@host, "#{@path}?#{@data}", @port)
9
+ end
10
+
11
+ def send_post_request
12
+ http = Net::HTTP.new(@host, @port)
13
+ http.post(@path, @data)
14
+ end
15
+
16
+ def send_post_form_request
17
+ Net::HTTP.post_form(uri, @params)
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ module HttpEventLogger
2
+ module Test
3
+ module Driver
4
+
5
+ class OpenUri < HttpEventLogger::Test::Driver::Base
6
+
7
+ def self.expected_response_body
8
+ "[not available]"
9
+ end
10
+
11
+ def send_get_request
12
+ open(uri)
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ require 'patron'
2
+
3
+ module HttpEventLogger
4
+ module Test
5
+ module Driver
6
+
7
+ class Patron < HttpEventLogger::Test::Driver::Base
8
+
9
+ def self.is_libcurl?
10
+ true
11
+ end
12
+
13
+ def send_get_request
14
+ session = ::Patron::Session.new
15
+ session.get(uri, @headers)
16
+ end
17
+
18
+ def send_post_request
19
+ session = ::Patron::Session.new
20
+ session.post(uri, @data, @headers)
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ require 'typhoeus'
2
+
3
+ module HttpEventLogger
4
+ module Test
5
+ module Driver
6
+
7
+ class Typhoeus < HttpEventLogger::Test::Driver::Base
8
+
9
+ class << self
10
+
11
+ def is_libcurl?
12
+ true
13
+ end
14
+
15
+ # Note: Last supported Typhoeus version is 0.5.3
16
+ def expected_response_body
17
+ ""
18
+ end
19
+
20
+ end
21
+
22
+ def send_get_request
23
+ ::Typhoeus.get(uri, headers: @headers)
24
+ end
25
+
26
+ def send_post_request
27
+ ::Typhoeus.post(uri, body: @data, headers: @headers)
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <head>
3
+ <title>Test Page</title>
4
+ </head>
5
+ <body>
6
+ <h1>This is the test page.</h1>
7
+ </body>
8
+ </html>
@@ -0,0 +1,28 @@
1
+ require 'rack'
2
+
3
+ module HttpEventLogger
4
+ module Test
5
+
6
+ class Server
7
+
8
+ def call(env)
9
+ @root = File.expand_path(File.dirname(__FILE__))
10
+ path = Rack::Utils.unescape(env["PATH_INFO"])
11
+ path += "index.html" if path == "/"
12
+ file = @root + "#{path}"
13
+
14
+ params = Rack::Utils.parse_nested_query(env["QUERY_STRING"])
15
+
16
+ if params["redirect"]
17
+ [ 301, { "Location" => "/index.html" }, "" ]
18
+ elsif File.exists?(file)
19
+ [ 200, { "Content-Type" => "text/html" }, File.read(file) ]
20
+ else
21
+ [ 404, { "Content-Type" => "text/plain" }, "file not found" ]
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end