and-son 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -2
- data/lib/and-son/client.rb +26 -39
- data/lib/and-son/version.rb +1 -1
- data/test/helper.rb +7 -9
- data/test/support/fake_connection.rb +28 -0
- data/test/support/fake_server.rb +11 -0
- data/test/system/{making_requests_test.rb → making_requests_tests.rb} +17 -9
- data/test/unit/{and-son_test.rb → and-son_tests.rb} +2 -1
- data/test/unit/{client_test.rb → client_tests.rb} +46 -9
- data/test/unit/{response_test.rb → response_tests.rb} +15 -8
- data/test/unit/{stored_responses_test.rb → stored_responses_tests.rb} +1 -0
- metadata +16 -14
data/Gemfile
CHANGED
data/lib/and-son/client.rb
CHANGED
@@ -86,7 +86,16 @@ module AndSon
|
|
86
86
|
client_response ||= self.call!(name, params)
|
87
87
|
end
|
88
88
|
|
89
|
-
|
89
|
+
summary_line = SummaryLine.new({
|
90
|
+
'time' => RoundedTime.new(benchmark.real),
|
91
|
+
'status' => client_response.protocol_response.code,
|
92
|
+
'host' => "#{self.host}:#{self.port}",
|
93
|
+
'version' => self.version,
|
94
|
+
'service' => name,
|
95
|
+
'params' => params
|
96
|
+
})
|
97
|
+
self.logger_value.info("[AndSon] #{summary_line}")
|
98
|
+
|
90
99
|
if block_given?
|
91
100
|
yield client_response.protocol_response
|
92
101
|
else
|
@@ -98,6 +107,7 @@ module AndSon
|
|
98
107
|
call_params = self.params_value.merge(params)
|
99
108
|
AndSon::Connection.new(host, port).open do |connection|
|
100
109
|
connection.write(Sanford::Protocol::Request.new(version, name, call_params).to_hash)
|
110
|
+
connection.close_write
|
101
111
|
if !connection.peek(timeout_value).empty?
|
102
112
|
AndSon::Response.parse(connection.read(timeout_value))
|
103
113
|
else
|
@@ -106,44 +116,6 @@ module AndSon
|
|
106
116
|
end
|
107
117
|
end
|
108
118
|
|
109
|
-
protected
|
110
|
-
|
111
|
-
def summary_line(name, params, benchmark, client_response)
|
112
|
-
response = client_response.protocol_response
|
113
|
-
SummaryLine.new.tap do |line|
|
114
|
-
line.add 'host', "#{self.host}:#{self.port}"
|
115
|
-
line.add 'version', self.version
|
116
|
-
line.add 'service', name
|
117
|
-
line.add 'params', params
|
118
|
-
line.add 'status', response.code
|
119
|
-
line.add 'duration', self.round_time(benchmark.real)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
ROUND_PRECISION = 2
|
124
|
-
ROUND_MODIFIER = 10 ** ROUND_PRECISION
|
125
|
-
def round_time(time_in_seconds)
|
126
|
-
(time_in_seconds * 1000 * ROUND_MODIFIER).to_i / ROUND_MODIFIER.to_f
|
127
|
-
end
|
128
|
-
|
129
|
-
end
|
130
|
-
|
131
|
-
class SummaryLine
|
132
|
-
|
133
|
-
def initialize
|
134
|
-
@hash = {}
|
135
|
-
end
|
136
|
-
|
137
|
-
def add(key, value)
|
138
|
-
@hash[key] = value.inspect if value
|
139
|
-
end
|
140
|
-
|
141
|
-
def to_s
|
142
|
-
[ 'host', 'version', 'service', 'status', 'duration', 'params' ].map do |key|
|
143
|
-
"#{key}=#{@hash[key]}" if @hash[key]
|
144
|
-
end.compact.join(" ")
|
145
|
-
end
|
146
|
-
|
147
119
|
end
|
148
120
|
|
149
121
|
class ConnectionClosedError < RuntimeError
|
@@ -158,4 +130,19 @@ module AndSon
|
|
158
130
|
end
|
159
131
|
end
|
160
132
|
|
133
|
+
module SummaryLine
|
134
|
+
def self.new(line_attrs)
|
135
|
+
attr_keys = %w{time status host version service params}
|
136
|
+
attr_keys.map{ |k| "#{k}=#{line_attrs[k].inspect}" }.join(' ')
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
module RoundedTime
|
141
|
+
ROUND_PRECISION = 2
|
142
|
+
ROUND_MODIFIER = 10 ** ROUND_PRECISION
|
143
|
+
def self.new(time_in_seconds)
|
144
|
+
(time_in_seconds * 1000 * ROUND_MODIFIER).to_i / ROUND_MODIFIER.to_f
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
161
148
|
end
|
data/lib/and-son/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
|
1
|
+
# this file is automatically required when you run `assert`
|
2
|
+
# put any test helpers here
|
2
3
|
|
3
|
-
|
4
|
+
# add the root dir to the load path
|
5
|
+
$LOAD_PATH.unshift(File.expand_path("../..", __FILE__))
|
4
6
|
|
5
|
-
require
|
6
|
-
|
7
|
-
require '
|
8
|
-
|
9
|
-
if defined?(Assert)
|
10
|
-
require 'assert-mocha'
|
11
|
-
end
|
7
|
+
# require pry for debugging (`binding.pry`)
|
8
|
+
require 'pry'
|
9
|
+
require 'assert-mocha' if defined?(Assert)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class FakeConnection
|
2
|
+
attr_reader :written
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@written = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def peek(*args)
|
9
|
+
"peek_data"
|
10
|
+
end
|
11
|
+
|
12
|
+
def read(*args)
|
13
|
+
{ 'status' => [ 200 ], 'data' => {} }
|
14
|
+
end
|
15
|
+
|
16
|
+
def write(request_hash)
|
17
|
+
@written << request_hash
|
18
|
+
end
|
19
|
+
|
20
|
+
def close_write
|
21
|
+
@write_stream_closed = true
|
22
|
+
end
|
23
|
+
|
24
|
+
def write_stream_closed?
|
25
|
+
!!@write_stream_closed
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/test/support/fake_server.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
1
3
|
class FakeServer
|
2
4
|
|
3
5
|
def initialize(port, options = nil)
|
@@ -6,6 +8,7 @@ class FakeServer
|
|
6
8
|
@handlers = {}
|
7
9
|
|
8
10
|
@closing_server = !!options[:closing_server]
|
11
|
+
@slow = !!options[:slow]
|
9
12
|
end
|
10
13
|
|
11
14
|
def add_handler(version, name, &block)
|
@@ -20,6 +23,8 @@ class FakeServer
|
|
20
23
|
sleep 0.1 # ensure the connection isn't closed before a client can run
|
21
24
|
# IO.select
|
22
25
|
socket.close
|
26
|
+
elsif @slow
|
27
|
+
sleep 0.5
|
23
28
|
else
|
24
29
|
serve(socket)
|
25
30
|
end
|
@@ -35,6 +40,7 @@ class FakeServer
|
|
35
40
|
status, result = route(request)
|
36
41
|
response = Sanford::Protocol::Response.new(status, result)
|
37
42
|
connection.write(response.to_hash)
|
43
|
+
connection.close_write
|
38
44
|
end
|
39
45
|
|
40
46
|
def route(request)
|
@@ -62,6 +68,11 @@ class FakeServer
|
|
62
68
|
run_fake_server(server, &block)
|
63
69
|
end
|
64
70
|
|
71
|
+
def start_slow_server(port, &block)
|
72
|
+
server = FakeServer.new(port, :slow => true)
|
73
|
+
run_fake_server(server, &block)
|
74
|
+
end
|
75
|
+
|
65
76
|
end
|
66
77
|
|
67
78
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'assert'
|
2
|
+
require 'test/support/fake_server'
|
3
|
+
require 'and-son'
|
2
4
|
|
3
|
-
class
|
5
|
+
class MakingRequestsTests < Assert::Context
|
4
6
|
include FakeServer::Helper
|
5
7
|
|
6
8
|
desc "making a request that"
|
@@ -8,7 +10,7 @@ class MakingRequestsTest < Assert::Context
|
|
8
10
|
@fake_server = FakeServer.new(12000)
|
9
11
|
end
|
10
12
|
|
11
|
-
class
|
13
|
+
class SuccessTests < MakingRequestsTests
|
12
14
|
desc "returns a successful response"
|
13
15
|
setup do
|
14
16
|
@fake_server.add_handler('v1', 'echo'){|params| [ 200, params['message'] ] }
|
@@ -29,7 +31,7 @@ class MakingRequestsTest < Assert::Context
|
|
29
31
|
|
30
32
|
end
|
31
33
|
|
32
|
-
class
|
34
|
+
class WithStoredResponsesTests < MakingRequestsTests
|
33
35
|
desc "is stored with and-son and with testing ENV var set"
|
34
36
|
setup do
|
35
37
|
ENV['ANDSON_TEST_MODE'] = 'yes'
|
@@ -51,7 +53,7 @@ class MakingRequestsTest < Assert::Context
|
|
51
53
|
|
52
54
|
end
|
53
55
|
|
54
|
-
class
|
56
|
+
class AuthorizeTests < MakingRequestsTests
|
55
57
|
setup do
|
56
58
|
@fake_server.add_handler('v1', 'authorize_it') do |params|
|
57
59
|
if params['api_key'] == 12345
|
@@ -87,9 +89,10 @@ class MakingRequestsTest < Assert::Context
|
|
87
89
|
|
88
90
|
end
|
89
91
|
end
|
92
|
+
|
90
93
|
end
|
91
94
|
|
92
|
-
class
|
95
|
+
class Failure400Tests < MakingRequestsTests
|
93
96
|
desc "when a request fails with a 400"
|
94
97
|
setup do
|
95
98
|
@fake_server.add_handler('v1', '400'){|params| [ 400, false ] }
|
@@ -105,9 +108,10 @@ class MakingRequestsTest < Assert::Context
|
|
105
108
|
|
106
109
|
end
|
107
110
|
end
|
111
|
+
|
108
112
|
end
|
109
113
|
|
110
|
-
class
|
114
|
+
class Failure404Tests < MakingRequestsTests
|
111
115
|
desc "when a request fails with a 404"
|
112
116
|
setup do
|
113
117
|
@fake_server.add_handler('v1', '404'){|params| [ 404, false ] }
|
@@ -123,9 +127,10 @@ class MakingRequestsTest < Assert::Context
|
|
123
127
|
|
124
128
|
end
|
125
129
|
end
|
130
|
+
|
126
131
|
end
|
127
132
|
|
128
|
-
class
|
133
|
+
class Failure4xxTests < MakingRequestsTests
|
129
134
|
desc "when a request fails with a 4xx"
|
130
135
|
setup do
|
131
136
|
@fake_server.add_handler('v1', '4xx'){|params| [ 402, false ] }
|
@@ -141,9 +146,10 @@ class MakingRequestsTest < Assert::Context
|
|
141
146
|
|
142
147
|
end
|
143
148
|
end
|
149
|
+
|
144
150
|
end
|
145
151
|
|
146
|
-
class
|
152
|
+
class Failure5xxTests < MakingRequestsTests
|
147
153
|
desc "when a request fails with a 5xx"
|
148
154
|
setup do
|
149
155
|
@fake_server.add_handler('v1', '5xx'){|params| [ 500, false ] }
|
@@ -159,9 +165,10 @@ class MakingRequestsTest < Assert::Context
|
|
159
165
|
|
160
166
|
end
|
161
167
|
end
|
168
|
+
|
162
169
|
end
|
163
170
|
|
164
|
-
class
|
171
|
+
class TimeoutErrorTests < MakingRequestsTests
|
165
172
|
desc "when a request takes to long to respond"
|
166
173
|
setup do
|
167
174
|
@fake_server.add_handler('v1', 'forever') do |params|
|
@@ -180,6 +187,7 @@ class MakingRequestsTest < Assert::Context
|
|
180
187
|
|
181
188
|
end
|
182
189
|
end
|
190
|
+
|
183
191
|
end
|
184
192
|
|
185
193
|
end
|
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'assert'
|
2
|
+
require 'test/support/fake_connection'
|
3
|
+
require 'test/support/fake_server'
|
2
4
|
require 'and-son/stored_responses'
|
5
|
+
require 'and-son/client'
|
3
6
|
|
4
7
|
class AndSon::Client
|
5
8
|
|
6
|
-
class
|
9
|
+
class BaseTests < Assert::Context
|
7
10
|
include FakeServer::Helper
|
8
11
|
|
9
12
|
desc "AndSon::Client"
|
@@ -65,19 +68,56 @@ class AndSon::Client
|
|
65
68
|
subject.params('test')
|
66
69
|
end
|
67
70
|
end
|
71
|
+
should "track its stored responses" do
|
72
|
+
assert_kind_of AndSon::StoredResponses, subject.responses
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
class CallTest < BaseTests
|
78
|
+
desc "call"
|
79
|
+
setup do
|
80
|
+
@connection = AndSon::Connection.new('localhost', 12001)
|
81
|
+
@response = AndSon::Response.parse({ 'status' => [200] })
|
82
|
+
@fake_connection = FakeConnection.new
|
83
|
+
AndSon::Connection.stubs(:new).returns(@connection)
|
84
|
+
end
|
85
|
+
teardown do
|
86
|
+
AndSon::Connection.unstub(:new)
|
87
|
+
end
|
88
|
+
|
89
|
+
should "write a request to the connection" do
|
90
|
+
@connection.stubs(:open).yields(@fake_connection).returns(@response)
|
91
|
+
|
92
|
+
client = AndSon::Client.new('localhost', 12001, 'v1').call('echo', {
|
93
|
+
:message => 'test'
|
94
|
+
})
|
95
|
+
|
96
|
+
request_data = @fake_connection.written.first
|
97
|
+
assert_equal 'v1', request_data['version']
|
98
|
+
assert_equal 'echo', request_data['name']
|
99
|
+
assert_equal({ 'message' => 'test' }, request_data['params'])
|
100
|
+
end
|
101
|
+
|
102
|
+
should "close the write stream" do
|
103
|
+
@connection.stubs(:open).yields(@fake_connection).returns(@response)
|
104
|
+
|
105
|
+
client = AndSon::Client.new('localhost', 12001, 'v1').call('echo', {
|
106
|
+
:message => 'test'
|
107
|
+
})
|
108
|
+
|
109
|
+
assert @fake_connection.write_stream_closed?
|
110
|
+
end
|
68
111
|
|
69
112
|
should "raise an ArgumentError when #call is not passed a Hash for params" do
|
70
|
-
|
113
|
+
client = AndSon::Client.new('localhost', 12001, 'v1')
|
114
|
+
runner = client.timeout(0.1) # in case it actually tries to make the request
|
71
115
|
|
72
116
|
assert_raises(ArgumentError) do
|
73
117
|
runner.call('something', 'test')
|
74
118
|
end
|
75
119
|
end
|
76
120
|
|
77
|
-
should "track its stored responses" do
|
78
|
-
assert_kind_of AndSon::StoredResponses, subject.responses
|
79
|
-
end
|
80
|
-
|
81
121
|
should "raise a ConnectionClosedError when the server closes the connection" do
|
82
122
|
self.start_closing_server(12001) do
|
83
123
|
client = AndSon::Client.new('localhost', 12001, 'v1')
|
@@ -90,7 +130,4 @@ class AndSon::Client
|
|
90
130
|
|
91
131
|
end
|
92
132
|
|
93
|
-
# the `call` method is tested in the file test/system/making_requests_test.rb,
|
94
|
-
# because there is a lot of setup needed to call this method
|
95
|
-
|
96
133
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'assert'
|
2
|
+
require 'and-son/response'
|
2
3
|
|
3
4
|
class AndSon::Response
|
4
5
|
|
5
|
-
class
|
6
|
+
class BaseTests < Assert::Context
|
6
7
|
desc "AndSon::Response"
|
7
8
|
setup do
|
8
9
|
@protocol_response = Sanford::Protocol::Response.new([ 200, 'message' ], 'data')
|
@@ -10,8 +11,8 @@ class AndSon::Response
|
|
10
11
|
end
|
11
12
|
subject{ @response }
|
12
13
|
|
13
|
-
should
|
14
|
-
should
|
14
|
+
should have_imeths :data, :code_is_5xx?, :code_is_404?, :code_is_400?, :code_is_4xx?
|
15
|
+
should have_cmeths :parse
|
15
16
|
|
16
17
|
should "return the protocol response's data with #data" do
|
17
18
|
assert_equal @protocol_response.data, subject.data
|
@@ -22,9 +23,10 @@ class AndSon::Response
|
|
22
23
|
assert_equal false, subject.code_is_400?
|
23
24
|
assert_equal false, subject.code_is_4xx?
|
24
25
|
end
|
26
|
+
|
25
27
|
end
|
26
28
|
|
27
|
-
class
|
29
|
+
class FailedResponseTests < BaseTests
|
28
30
|
desc "given a failed response"
|
29
31
|
setup do
|
30
32
|
@protocol_response = Sanford::Protocol::Response.new([ 500, 'message' ])
|
@@ -40,9 +42,10 @@ class AndSon::Response
|
|
40
42
|
assert_equal @protocol_response.status.message, exception.message
|
41
43
|
assert_equal @protocol_response, exception.response
|
42
44
|
end
|
45
|
+
|
43
46
|
end
|
44
47
|
|
45
|
-
class
|
48
|
+
class Response5xxTests < BaseTests
|
46
49
|
desc "given a 5xx response"
|
47
50
|
setup do
|
48
51
|
@protocol_response = Sanford::Protocol::Response.new(500)
|
@@ -55,9 +58,10 @@ class AndSon::Response
|
|
55
58
|
assert_equal false, subject.code_is_400?
|
56
59
|
assert_equal false, subject.code_is_4xx?
|
57
60
|
end
|
61
|
+
|
58
62
|
end
|
59
63
|
|
60
|
-
class
|
64
|
+
class Response404Tests < BaseTests
|
61
65
|
desc "given a 404 response"
|
62
66
|
setup do
|
63
67
|
@protocol_response = Sanford::Protocol::Response.new(404)
|
@@ -71,9 +75,10 @@ class AndSon::Response
|
|
71
75
|
assert_equal false, subject.code_is_400?
|
72
76
|
assert_equal true, subject.code_is_4xx?
|
73
77
|
end
|
78
|
+
|
74
79
|
end
|
75
80
|
|
76
|
-
class
|
81
|
+
class Response400Tests < BaseTests
|
77
82
|
desc "given a 400 response"
|
78
83
|
setup do
|
79
84
|
@protocol_response = Sanford::Protocol::Response.new(400)
|
@@ -87,9 +92,10 @@ class AndSon::Response
|
|
87
92
|
assert_equal true, subject.code_is_400?
|
88
93
|
assert_equal true, subject.code_is_4xx?
|
89
94
|
end
|
95
|
+
|
90
96
|
end
|
91
97
|
|
92
|
-
class
|
98
|
+
class Response4xxTests < BaseTests
|
93
99
|
desc "given a 4xx response"
|
94
100
|
setup do
|
95
101
|
@protocol_response = Sanford::Protocol::Response.new(402)
|
@@ -102,6 +108,7 @@ class AndSon::Response
|
|
102
108
|
assert_equal false, subject.code_is_400?
|
103
109
|
assert_equal true, subject.code_is_4xx?
|
104
110
|
end
|
111
|
+
|
105
112
|
end
|
106
113
|
|
107
114
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: and-son
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 1
|
10
|
+
version: 0.3.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Collin Redding
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2013-03-
|
19
|
+
date: 2013-03-14 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
prerelease: false
|
@@ -87,12 +87,13 @@ files:
|
|
87
87
|
- lib/and-son/stored_responses.rb
|
88
88
|
- lib/and-son/version.rb
|
89
89
|
- test/helper.rb
|
90
|
+
- test/support/fake_connection.rb
|
90
91
|
- test/support/fake_server.rb
|
91
|
-
- test/system/
|
92
|
-
- test/unit/and-
|
93
|
-
- test/unit/
|
94
|
-
- test/unit/
|
95
|
-
- test/unit/
|
92
|
+
- test/system/making_requests_tests.rb
|
93
|
+
- test/unit/and-son_tests.rb
|
94
|
+
- test/unit/client_tests.rb
|
95
|
+
- test/unit/response_tests.rb
|
96
|
+
- test/unit/stored_responses_tests.rb
|
96
97
|
homepage: https://github.com/redding/and-son
|
97
98
|
licenses: []
|
98
99
|
|
@@ -128,9 +129,10 @@ specification_version: 3
|
|
128
129
|
summary: Simple Sanford client for Ruby.
|
129
130
|
test_files:
|
130
131
|
- test/helper.rb
|
132
|
+
- test/support/fake_connection.rb
|
131
133
|
- test/support/fake_server.rb
|
132
|
-
- test/system/
|
133
|
-
- test/unit/and-
|
134
|
-
- test/unit/
|
135
|
-
- test/unit/
|
136
|
-
- test/unit/
|
134
|
+
- test/system/making_requests_tests.rb
|
135
|
+
- test/unit/and-son_tests.rb
|
136
|
+
- test/unit/client_tests.rb
|
137
|
+
- test/unit/response_tests.rb
|
138
|
+
- test/unit/stored_responses_tests.rb
|