protobuf 2.0.0.rc3 → 2.0.0.rc4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/protobuf/cli.rb +1 -2
- data/lib/protobuf/{common/exceptions.rb → exceptions.rb} +0 -0
- data/lib/protobuf/field/base_field.rb +1 -1
- data/lib/protobuf/{common/logger.rb → logger.rb} +21 -0
- data/lib/protobuf/message/decoder.rb +2 -2
- data/lib/protobuf/message/encoder.rb +6 -4
- data/lib/protobuf/rpc/buffer.rb +2 -2
- data/lib/protobuf/rpc/client.rb +18 -18
- data/lib/protobuf/rpc/connectors/base.rb +3 -8
- data/lib/protobuf/rpc/connectors/common.rb +29 -28
- data/lib/protobuf/rpc/connectors/em_client.rb +9 -9
- data/lib/protobuf/rpc/connectors/eventmachine.rb +11 -9
- data/lib/protobuf/rpc/connectors/socket.rb +13 -17
- data/lib/protobuf/rpc/connectors/zmq.rb +13 -17
- data/lib/protobuf/rpc/error.rb +3 -3
- data/lib/protobuf/rpc/server.rb +41 -93
- data/lib/protobuf/rpc/servers/evented/server.rb +7 -9
- data/lib/protobuf/rpc/servers/evented_runner.rb +0 -11
- data/lib/protobuf/rpc/servers/socket/server.rb +8 -7
- data/lib/protobuf/rpc/servers/socket/worker.rb +22 -15
- data/lib/protobuf/rpc/servers/zmq/server.rb +3 -3
- data/lib/protobuf/rpc/servers/zmq/util.rb +1 -1
- data/lib/protobuf/rpc/servers/zmq/worker.rb +6 -15
- data/lib/protobuf/rpc/service.rb +145 -228
- data/lib/protobuf/rpc/service_dispatcher.rb +114 -0
- data/lib/protobuf/rpc/stat.rb +46 -33
- data/lib/protobuf/version.rb +1 -1
- data/lib/protobuf/{common/wire_type.rb → wire_type.rb} +0 -0
- data/spec/benchmark/tasks.rb +18 -18
- data/spec/functional/evented_server_spec.rb +3 -4
- data/spec/functional/socket_server_spec.rb +3 -3
- data/spec/functional/zmq_server_spec.rb +3 -3
- data/spec/lib/protobuf/{common/logger_spec.rb → logger_spec.rb} +46 -36
- data/spec/lib/protobuf/rpc/client_spec.rb +10 -58
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +1 -39
- data/spec/lib/protobuf/rpc/connectors/common_spec.rb +3 -6
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +0 -12
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +1 -6
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +94 -0
- data/spec/lib/protobuf/rpc/service_spec.rb +132 -45
- data/spec/spec_helper.rb +4 -3
- data/spec/support/server.rb +8 -4
- metadata +41 -35
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'protobuf/logger'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Rpc
|
5
|
+
class ServiceDispatcher
|
6
|
+
|
7
|
+
include ::Protobuf::Logger::LogMethods
|
8
|
+
|
9
|
+
attr_accessor :service, :service_klass, :callable_method, :outer_request
|
10
|
+
attr_accessor :definition, :response, :error
|
11
|
+
|
12
|
+
def initialize(wrapper_request)
|
13
|
+
self.error = nil
|
14
|
+
self.outer_request = wrapper_request
|
15
|
+
|
16
|
+
init_service
|
17
|
+
init_method if service_klass.present?
|
18
|
+
register_rpc_failed if service.present?
|
19
|
+
end
|
20
|
+
|
21
|
+
# Call the given service method. If we get to this point and an error
|
22
|
+
# has already occurred, do not invoke the method and simply respond.
|
23
|
+
#
|
24
|
+
def invoke!
|
25
|
+
unless error?
|
26
|
+
callable_method.call
|
27
|
+
validate_response
|
28
|
+
end
|
29
|
+
|
30
|
+
return error || response
|
31
|
+
end
|
32
|
+
|
33
|
+
# We're successful if the error is not populated.
|
34
|
+
#
|
35
|
+
def success?
|
36
|
+
error.nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
# We're in error if the error is populated.
|
40
|
+
#
|
41
|
+
def error?
|
42
|
+
! success?
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def assign_error(error_klass, message)
|
48
|
+
self.error = error_klass.new(message)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get the method for the current request.
|
52
|
+
#
|
53
|
+
def init_method
|
54
|
+
method_name = outer_request.method_name.underscore.to_sym
|
55
|
+
if service_klass.rpc_method?(method_name)
|
56
|
+
self.service = service_klass.new(method_name, outer_request.request_proto)
|
57
|
+
self.callable_method = service.method(method_name)
|
58
|
+
self.definition = service.rpcs[method_name]
|
59
|
+
else
|
60
|
+
assign_error(MethodNotFound, "#{service.class.name}##{method_name} is not a defined rpc method.")
|
61
|
+
end
|
62
|
+
rescue NameError => e
|
63
|
+
log_exception(e)
|
64
|
+
assign_error(MethodNotFound, "#{service.class.name}##{method_name} is not implemented.")
|
65
|
+
end
|
66
|
+
|
67
|
+
# Constantize the service for this request. Initialization of the service
|
68
|
+
# happens when we verify that the method is callable for this service.
|
69
|
+
#
|
70
|
+
def init_service
|
71
|
+
self.service_klass = outer_request.service_name.constantize
|
72
|
+
rescue NameError => e
|
73
|
+
log_exception(e)
|
74
|
+
assign_error(ServiceNotFound, "Service class #{outer_request.service_name} is not defined.")
|
75
|
+
end
|
76
|
+
|
77
|
+
# Make sure we get rpc errors back.
|
78
|
+
#
|
79
|
+
def register_rpc_failed
|
80
|
+
service.on_rpc_failed(method(:rpc_failed_callback))
|
81
|
+
end
|
82
|
+
|
83
|
+
# Receive the failure message from the service. This method is registered
|
84
|
+
# as the callable to the service when an `rpc_failed` call is invoked.
|
85
|
+
#
|
86
|
+
def rpc_failed_callback(message)
|
87
|
+
assign_error(RpcFailed, (message.respond_to?(:message) ? message.message : message))
|
88
|
+
log_error { sign_message("RPC Failed: #{error.message}") }
|
89
|
+
end
|
90
|
+
|
91
|
+
# Ensure that the response candidate we've been given is of the type
|
92
|
+
# we expect so that deserialization on the client side works.
|
93
|
+
#
|
94
|
+
def validate_response
|
95
|
+
expected = definition.response_type
|
96
|
+
|
97
|
+
candidate = service.response
|
98
|
+
candidate = expected.new(candidate) if candidate.is_a?(Hash)
|
99
|
+
|
100
|
+
actual = candidate.class
|
101
|
+
log_debug { sign_message("response (should/actual): #{expected.name}/#{actual.name}") }
|
102
|
+
|
103
|
+
# Determine if the service tried to change response types on us
|
104
|
+
if expected != actual
|
105
|
+
assign_error(BadResponseProto, "Response proto changed from #{expected.name} to #{actual.name}")
|
106
|
+
else
|
107
|
+
self.response = candidate
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
data/lib/protobuf/rpc/stat.rb
CHANGED
@@ -1,69 +1,82 @@
|
|
1
1
|
require 'date'
|
2
|
-
require 'protobuf/
|
2
|
+
require 'protobuf/logger'
|
3
3
|
|
4
4
|
module Protobuf
|
5
5
|
module Rpc
|
6
6
|
class Stat
|
7
|
-
attr_accessor :
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
attr_accessor :mode, :start_time, :end_time, :request_size, :dispatcher
|
8
|
+
attr_accessor :response_size, :client, :server, :service, :method
|
9
|
+
|
10
|
+
MODES = [:SERVER, :CLIENT].freeze
|
11
|
+
|
12
|
+
def initialize(mode = :SERVER)
|
13
|
+
@mode = mode
|
14
|
+
start
|
14
15
|
end
|
15
|
-
|
16
|
-
def client=
|
16
|
+
|
17
|
+
def client=(peer)
|
17
18
|
@client = {:port => peer[0], :ip => peer[1]}
|
18
19
|
end
|
19
|
-
|
20
|
+
|
20
21
|
def client
|
21
|
-
@client ?
|
22
|
+
@client ? "#{@client[:ip]}:#{@client[:port]}" : nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def method
|
26
|
+
@method ||= @dispatcher.try(:callable_method).try(:name)
|
22
27
|
end
|
23
|
-
|
24
|
-
def server=
|
28
|
+
|
29
|
+
def server=(peer)
|
25
30
|
@server = {:port => peer[0], :ip => peer[1]}
|
26
31
|
end
|
27
|
-
|
32
|
+
|
28
33
|
def server
|
29
|
-
@server ?
|
34
|
+
@server ? "#{@server[:ip]}:#{@server[:port]}" : nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def service
|
38
|
+
@service ||= @dispatcher.try(:service).class.name
|
30
39
|
end
|
31
|
-
|
40
|
+
|
32
41
|
def sizes
|
33
|
-
|
42
|
+
"#{@request_size || 0}B/#{@response_size || 0}B"
|
34
43
|
end
|
35
|
-
|
44
|
+
|
36
45
|
def start
|
37
46
|
@start_time ||= Time.now
|
38
47
|
end
|
39
|
-
|
40
|
-
def
|
48
|
+
|
49
|
+
def stop
|
41
50
|
start if !@start_time
|
42
51
|
@end_time ||= Time.now
|
43
52
|
end
|
44
|
-
|
53
|
+
|
45
54
|
def rpc
|
46
|
-
service && method ?
|
55
|
+
service && method ? "#{service}##{method}" : nil
|
47
56
|
end
|
48
|
-
|
57
|
+
|
49
58
|
def elapsed_time
|
50
|
-
(start_time && end_time ?
|
59
|
+
(start_time && end_time ? "#{(end_time - start_time).round(4)}s" : nil)
|
51
60
|
end
|
52
|
-
|
53
|
-
def
|
54
|
-
|
61
|
+
|
62
|
+
def server?
|
63
|
+
@mode == :SERVER
|
64
|
+
end
|
65
|
+
|
66
|
+
def client?
|
67
|
+
@mode == :CLIENT
|
55
68
|
end
|
56
|
-
|
69
|
+
|
57
70
|
def to_s
|
58
71
|
[
|
59
|
-
|
72
|
+
server? ? "[SRV-#{self.class}]" : "[CLT-#{self.class}]",
|
60
73
|
rpc,
|
61
74
|
elapsed_time,
|
62
75
|
sizes,
|
63
|
-
|
64
|
-
].
|
76
|
+
server? ? server : client
|
77
|
+
].compact.join(' - ')
|
65
78
|
end
|
66
|
-
|
79
|
+
|
67
80
|
end
|
68
81
|
end
|
69
82
|
end
|
data/lib/protobuf/version.rb
CHANGED
File without changes
|
data/spec/benchmark/tasks.rb
CHANGED
@@ -4,7 +4,7 @@ require 'support/test/resource_service'
|
|
4
4
|
require 'perftools'
|
5
5
|
|
6
6
|
# Including a way to turn on debug logger for spec runs
|
7
|
-
if ENV["DEBUG"]
|
7
|
+
if ENV["DEBUG"]
|
8
8
|
puts 'debugging'
|
9
9
|
debug_log = File.expand_path('../debug_bench.log', File.dirname(__FILE__) )
|
10
10
|
Protobuf::Logger.configure(:file => debug_log, :level => ::Logger::DEBUG)
|
@@ -25,12 +25,12 @@ namespace :benchmark do
|
|
25
25
|
def em_client_em_server(number_tests, test_length, global_bench = nil)
|
26
26
|
EM.stop if EM.reactor_running?
|
27
27
|
|
28
|
-
EventMachine.fiber_run do
|
28
|
+
EventMachine.fiber_run do
|
29
29
|
StubServer.new do |server|
|
30
|
-
client = ::Test::ResourceService.client
|
30
|
+
client = ::Test::ResourceService.client
|
31
31
|
|
32
32
|
benchmark_wrapper(global_bench) do |bench|
|
33
|
-
bench.report("ES / EC") do
|
33
|
+
bench.report("ES / EC") do
|
34
34
|
(1..number_tests.to_i).each { client.find(:name => "Test Name" * test_length.to_i, :active => true) }
|
35
35
|
end
|
36
36
|
end
|
@@ -44,11 +44,11 @@ namespace :benchmark do
|
|
44
44
|
EM.stop if EM.reactor_running?
|
45
45
|
|
46
46
|
EventMachine.fiber_run do
|
47
|
-
StubServer.new(:server => Protobuf::Rpc::Socket::Server, :port => 9399) do |server|
|
48
|
-
client = ::Test::ResourceService.client(:
|
47
|
+
StubServer.new(:server => Protobuf::Rpc::Socket::Server, :port => 9399) do |server|
|
48
|
+
client = ::Test::ResourceService.client(:port => 9399)
|
49
49
|
|
50
50
|
benchmark_wrapper(global_bench) do |bench|
|
51
|
-
bench.report("SS / EC") do
|
51
|
+
bench.report("SS / EC") do
|
52
52
|
(1..number_tests.to_i).each { client.find(:name => "Test Name" * test_length.to_i, :active => true) }
|
53
53
|
end
|
54
54
|
end
|
@@ -63,11 +63,11 @@ namespace :benchmark do
|
|
63
63
|
::Protobuf::Rpc::Connector.connector_for_client(true)
|
64
64
|
EM.stop if EM.reactor_running?
|
65
65
|
|
66
|
-
StubServer.new(:server => Protobuf::Rpc::Socket::Server, :port => 9399) do |server|
|
67
|
-
client = ::Test::ResourceService.client(:
|
66
|
+
StubServer.new(:server => Protobuf::Rpc::Socket::Server, :port => 9399) do |server|
|
67
|
+
client = ::Test::ResourceService.client(:port => 9399)
|
68
68
|
|
69
69
|
benchmark_wrapper(global_bench) do |bench|
|
70
|
-
bench.report("SS / SC") do
|
70
|
+
bench.report("SS / SC") do
|
71
71
|
(1..number_tests.to_i).each { client.find(:name => "Test Name" * test_length.to_i, :active => true) }
|
72
72
|
end
|
73
73
|
end
|
@@ -81,11 +81,11 @@ namespace :benchmark do
|
|
81
81
|
em_thread = Thread.new { EM.run }
|
82
82
|
Thread.pass until EM.reactor_running?
|
83
83
|
|
84
|
-
StubServer.new(:port => 9399) do |server|
|
85
|
-
client = ::Test::ResourceService.client(:
|
84
|
+
StubServer.new(:port => 9399) do |server|
|
85
|
+
client = ::Test::ResourceService.client(:port => 9399)
|
86
86
|
|
87
87
|
benchmark_wrapper(global_bench) do |bench|
|
88
|
-
bench.report("ES / SC") do
|
88
|
+
bench.report("ES / SC") do
|
89
89
|
(1..number_tests.to_i).each { client.find(:name => "Test Name" * test_length.to_i, :active => true) }
|
90
90
|
end
|
91
91
|
end
|
@@ -98,11 +98,11 @@ namespace :benchmark do
|
|
98
98
|
def zmq_client_zmq_server(number_tests, test_length, global_bench = nil)
|
99
99
|
load "protobuf/zmq.rb"
|
100
100
|
::Protobuf::Rpc::Connector.connector_for_client(true)
|
101
|
-
StubServer.new(:port => 9399, :server => Protobuf::Rpc::Zmq::Server) do |server|
|
102
|
-
client = ::Test::ResourceService.client(:
|
101
|
+
StubServer.new(:port => 9399, :server => Protobuf::Rpc::Zmq::Server) do |server|
|
102
|
+
client = ::Test::ResourceService.client(:port => 9399)
|
103
103
|
|
104
104
|
benchmark_wrapper(global_bench) do |bench|
|
105
|
-
bench.report("ZS / ZC") do
|
105
|
+
bench.report("ZS / ZC") do
|
106
106
|
(1..number_tests.to_i).each { client.find(:name => "Test Name" * test_length.to_i, :active => true) }
|
107
107
|
end
|
108
108
|
end
|
@@ -119,7 +119,7 @@ namespace :benchmark do
|
|
119
119
|
desc "benchmark ZMQ client with ZMQ server and profile"
|
120
120
|
task :zmq_profile, [:number, :length, :profile_output] do |t, args|
|
121
121
|
args.with_defaults(:number => 1000, :length => 100, :profile_output => "/tmp/zmq_profiler_#{Time.now.to_i}")
|
122
|
-
::PerfTools::CpuProfiler.start(args[:profile_output]) do
|
122
|
+
::PerfTools::CpuProfiler.start(args[:profile_output]) do
|
123
123
|
zmq_client_zmq_server(args[:number], args[:length])
|
124
124
|
end
|
125
125
|
|
@@ -130,7 +130,7 @@ namespace :benchmark do
|
|
130
130
|
task :profile_protobuf_new, [:number, :profile_output] do |t, args|
|
131
131
|
args.with_defaults(:number => 1000, :profile_output => "/tmp/profiler_new_#{Time.now.to_i}")
|
132
132
|
create_params = { :name => "The name that we set", :date_created => Time.now.to_i, :status => 2 }
|
133
|
-
::PerfTools::CpuProfiler.start(args[:profile_output]) do
|
133
|
+
::PerfTools::CpuProfiler.start(args[:profile_output]) do
|
134
134
|
args[:number].to_i.times { Test::Resource.new(create_params) }
|
135
135
|
end
|
136
136
|
|
@@ -5,14 +5,13 @@ describe 'Functional EventMachine Client' do
|
|
5
5
|
before(:each) do
|
6
6
|
load 'protobuf/evented.rb'
|
7
7
|
::Protobuf::Rpc::Connector.connector_for_client(true)
|
8
|
-
::Test::ResourceService.configure(::Test::ResourceService::DEFAULT_LOCATION)
|
9
8
|
end
|
10
9
|
|
11
10
|
it 'runs fine when required fields are set' do
|
12
11
|
expect {
|
13
12
|
EventMachine.fiber_run do
|
14
13
|
StubServer.new do |server|
|
15
|
-
client = ::Test::ResourceService.client(:
|
14
|
+
client = ::Test::ResourceService.client(:timeout => 5)
|
16
15
|
|
17
16
|
client.find(:name => 'Test Name', :active => true) do |c|
|
18
17
|
c.on_success do |succ|
|
@@ -35,7 +34,7 @@ describe 'Functional EventMachine Client' do
|
|
35
34
|
EventMachine.fiber_run do
|
36
35
|
StubServer.new do |server|
|
37
36
|
request = ::Test::ResourceFindRequest.new(:active => true)
|
38
|
-
client = ::Test::ResourceService.client
|
37
|
+
client = ::Test::ResourceService.client
|
39
38
|
|
40
39
|
client.find(request) do |c|
|
41
40
|
c.on_success { raise "shouldn't pass"}
|
@@ -52,7 +51,7 @@ describe 'Functional EventMachine Client' do
|
|
52
51
|
EventMachine.fiber_run do
|
53
52
|
StubServer.new do |server|
|
54
53
|
request = ::Test::Resource.new(:name => 'Test Name')
|
55
|
-
client = ::Test::ResourceService.client
|
54
|
+
client = ::Test::ResourceService.client
|
56
55
|
|
57
56
|
client.find(request) do |c|
|
58
57
|
c.on_success { raise "shouldn't pass"}
|
@@ -18,7 +18,7 @@ describe 'Functional Socket Client' do
|
|
18
18
|
|
19
19
|
it 'runs fine when required fields are set' do
|
20
20
|
expect {
|
21
|
-
client = ::Test::ResourceService.client
|
21
|
+
client = ::Test::ResourceService.client
|
22
22
|
|
23
23
|
client.find(:name => 'Test Name', :active => true) do |c|
|
24
24
|
c.on_success do |succ|
|
@@ -36,7 +36,7 @@ describe 'Functional Socket Client' do
|
|
36
36
|
it 'calls the on_failure callback when a message is malformed' do
|
37
37
|
error = nil
|
38
38
|
request = ::Test::ResourceFindRequest.new(:active => true)
|
39
|
-
client = ::Test::ResourceService.client
|
39
|
+
client = ::Test::ResourceService.client
|
40
40
|
|
41
41
|
client.find(request) do |c|
|
42
42
|
c.on_success { raise "shouldn't pass"}
|
@@ -48,7 +48,7 @@ describe 'Functional Socket Client' do
|
|
48
48
|
it 'calls the on_failure callback when the request type is wrong' do
|
49
49
|
error = nil
|
50
50
|
request = ::Test::Resource.new(:name => 'Test Name')
|
51
|
-
client = ::Test::ResourceService.client
|
51
|
+
client = ::Test::ResourceService.client
|
52
52
|
|
53
53
|
client.find(request) do |c|
|
54
54
|
c.on_success { raise "shouldn't pass"}
|
@@ -18,7 +18,7 @@ describe 'Functional ZMQ Client' do
|
|
18
18
|
|
19
19
|
it 'runs fine when required fields are set' do
|
20
20
|
expect {
|
21
|
-
client = ::Test::ResourceService.client
|
21
|
+
client = ::Test::ResourceService.client
|
22
22
|
|
23
23
|
client.find(:name => 'Test Name', :active => true) do |c|
|
24
24
|
c.on_success do |succ|
|
@@ -36,7 +36,7 @@ describe 'Functional ZMQ Client' do
|
|
36
36
|
it 'calls the on_failure callback when a message is malformed' do
|
37
37
|
error = nil
|
38
38
|
request = ::Test::ResourceFindRequest.new(:active => true)
|
39
|
-
client = ::Test::ResourceService.client
|
39
|
+
client = ::Test::ResourceService.client
|
40
40
|
|
41
41
|
client.find(request) do |c|
|
42
42
|
c.on_success { raise "shouldn't pass"}
|
@@ -48,7 +48,7 @@ describe 'Functional ZMQ Client' do
|
|
48
48
|
it 'calls the on_failure callback when the request type is wrong' do
|
49
49
|
error = nil
|
50
50
|
request = ::Test::Resource.new(:name => 'Test Name')
|
51
|
-
client = ::Test::ResourceService.client
|
51
|
+
client = ::Test::ResourceService.client
|
52
52
|
|
53
53
|
client.find(request) do |c|
|
54
54
|
c.on_success { raise "shouldn't pass"}
|
@@ -1,40 +1,40 @@
|
|
1
|
-
require 'protobuf/
|
1
|
+
require 'protobuf/logger'
|
2
2
|
require 'stringio'
|
3
3
|
|
4
4
|
describe Protobuf::Logger do
|
5
|
-
|
5
|
+
|
6
6
|
subject { Protobuf::Logger }
|
7
|
-
|
7
|
+
|
8
8
|
before(:each) do
|
9
9
|
Protobuf::Logger.reset_device!
|
10
10
|
Protobuf::Logger.file = '/dev/null'
|
11
11
|
Protobuf::Logger.level = ::Logger::INFO
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
describe '.instance' do
|
15
|
-
|
15
|
+
|
16
16
|
it 'doesn\'t create a logger if the file was not set' do
|
17
17
|
subject.file = nil
|
18
18
|
subject.instance.should be_nil
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
it 'doesn\'t create a logger if the level was not set' do
|
22
22
|
subject.level = nil
|
23
23
|
subject.instance.should be_nil
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
it 'gets a new instance of the logger when file and level are set' do
|
27
27
|
subject.file.should_not be_nil
|
28
28
|
subject.level.should_not be_nil
|
29
29
|
subject.instance.should_not be_nil
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
it 'keeps the same object from multiple calls to instance' do
|
33
33
|
subject.instance === subject.instance
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
describe '.configure' do
|
39
39
|
before(:each) { subject.reset_device! }
|
40
40
|
it 'sets the file and level in one call' do
|
@@ -46,11 +46,11 @@ describe Protobuf::Logger do
|
|
46
46
|
subject.level.should == ::Logger::WARN
|
47
47
|
subject.instance.level.should == ::Logger::WARN
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
describe '.reset_device!' do
|
53
|
-
|
53
|
+
|
54
54
|
it 'resets the logger instance, file, and level' do
|
55
55
|
subject.instance.should be
|
56
56
|
subject.file.should be
|
@@ -60,11 +60,11 @@ describe Protobuf::Logger do
|
|
60
60
|
subject.file.should_not be
|
61
61
|
subject.level.should_not be
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
context 'when logging' do
|
67
|
-
|
67
|
+
|
68
68
|
it 'doesn\'t raise errors when log instance is nil' do
|
69
69
|
subject.reset_device!
|
70
70
|
subject.instance.should be_nil
|
@@ -78,44 +78,54 @@ describe Protobuf::Logger do
|
|
78
78
|
subject.log 'No errors here'
|
79
79
|
}.to_not raise_error
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
it 'logs correctly when instance is valid' do
|
83
83
|
subject.instance.should_not be_nil
|
84
84
|
subject.instance.should_receive(:info).with('Should log great')
|
85
85
|
subject.info 'Should log great'
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
describe Protobuf::Logger::LogMethods do
|
91
|
-
|
91
|
+
|
92
92
|
context 'when included in another class' do
|
93
|
-
|
93
|
+
|
94
94
|
before(:all) do
|
95
95
|
class MyTestClass
|
96
96
|
include Protobuf::Logger::LogMethods
|
97
97
|
end
|
98
98
|
end
|
99
|
-
|
99
|
+
|
100
100
|
subject { MyTestClass.new }
|
101
|
-
|
102
|
-
it
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
101
|
+
|
102
|
+
it { should respond_to(:log_debug) }
|
103
|
+
it { should respond_to(:log_info) }
|
104
|
+
it { should respond_to(:log_warn) }
|
105
|
+
it { should respond_to(:log_error) }
|
106
|
+
it { should respond_to(:log_fatal) }
|
107
|
+
it { should respond_to(:log_add) }
|
108
|
+
it { should respond_to(:log_log) }
|
109
|
+
|
110
|
+
context '#log_exception' do
|
111
|
+
it 'logs the exception message as an error and backtrace as debug' do
|
112
|
+
subject.should_receive(:log_error).twice
|
113
|
+
subject.should_receive(:log_debug)
|
114
|
+
subject.log_exception(RuntimeError.new('this is an exception'))
|
115
|
+
end
|
110
116
|
end
|
111
|
-
|
117
|
+
|
118
|
+
its(:log_signature) { should eq "[MyTestClass]" }
|
119
|
+
describe '#sign_message' do
|
120
|
+
specify { subject.sign_message("this is a test").should eq "[MyTestClass] this is a test" }
|
121
|
+
specify { subject.class.sign_message("this is a test").should eq "[MyTestClass] this is a test" }
|
122
|
+
end
|
123
|
+
|
112
124
|
it 'passes all embedded log calls to Logger instance' do
|
113
|
-
Protobuf::Logger.instance.should_receive(:debug).with('log this')
|
125
|
+
Protobuf::Logger.instance.should_receive(:debug).with('[MyTestClass] log this')
|
114
126
|
subject.log_debug('log this')
|
115
127
|
end
|
116
|
-
|
128
|
+
|
117
129
|
end
|
118
|
-
|
119
130
|
end
|
120
|
-
|
121
131
|
end
|