and-son 0.3.0 → 0.3.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.
- 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
|