rightscale-nanite 0.4.1.2 → 0.4.1.3
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/Rakefile +4 -3
- data/bin/nanite-agent +5 -0
- data/lib/nanite/actor.rb +12 -1
- data/lib/nanite/agent.rb +12 -7
- data/lib/nanite/amqp.rb +10 -3
- data/lib/nanite/cluster.rb +18 -14
- data/lib/nanite/config.rb +11 -2
- data/lib/nanite/dispatcher.rb +3 -2
- data/lib/nanite/local_state.rb +2 -2
- data/lib/nanite/log.rb +19 -18
- data/lib/nanite/mapper.rb +30 -10
- data/lib/nanite/mapper_proxy.rb +11 -1
- data/lib/nanite/packets.rb +8 -13
- data/lib/nanite/security/encrypted_document.rb +1 -1
- data/lib/nanite/security/secure_serializer.rb +1 -0
- data/lib/nanite/security/signature.rb +7 -1
- data/lib/nanite/state.rb +1 -1
- data/lib/nanite/util.rb +23 -16
- data/lib/nanite.rb +5 -2
- data/spec/actor_registry_spec.rb +16 -18
- data/spec/actor_spec.rb +38 -20
- data/spec/agent_spec.rb +6 -1
- data/spec/cluster_spec.rb +23 -9
- data/spec/log_spec.rb +49 -0
- data/spec/mapper_proxy_spec.rb +72 -0
- data/spec/mapper_spec.rb +70 -0
- data/spec/nanite_spec.rb +36 -0
- data/spec/packet_spec.rb +8 -6
- data/spec/spec_helper.rb +1 -4
- metadata +5 -1
data/Rakefile
CHANGED
@@ -8,9 +8,9 @@ rescue LoadError
|
|
8
8
|
require 'rake/rdoctask'
|
9
9
|
end
|
10
10
|
require 'rake/clean'
|
11
|
+
require 'lib/nanite'
|
11
12
|
|
12
13
|
GEM = "nanite"
|
13
|
-
VER = "0.4.1"
|
14
14
|
AUTHOR = "Ezra Zygmuntowicz"
|
15
15
|
EMAIL = "ezra@engineyard.com"
|
16
16
|
HOMEPAGE = "http://github.com/ezmobius/nanite"
|
@@ -19,8 +19,9 @@ SUMMARY = "self assembling fabric of ruby daemons"
|
|
19
19
|
Dir.glob('tasks/*.rake').each { |r| Rake.application.add_import r }
|
20
20
|
|
21
21
|
spec = Gem::Specification.new do |s|
|
22
|
+
|
22
23
|
s.name = GEM
|
23
|
-
s.version = ::
|
24
|
+
s.version = Nanite::VERSION
|
24
25
|
s.platform = Gem::Platform::RUBY
|
25
26
|
s.has_rdoc = true
|
26
27
|
s.extra_rdoc_files = ["README.rdoc", "LICENSE", 'TODO']
|
@@ -46,7 +47,7 @@ end
|
|
46
47
|
task :default => :spec
|
47
48
|
|
48
49
|
task :install => [:package] do
|
49
|
-
sh %{sudo gem install pkg/#{GEM}-#{
|
50
|
+
sh %{sudo gem install pkg/#{GEM}-#{Nanite::VERSION}}
|
50
51
|
end
|
51
52
|
|
52
53
|
desc "Run unit specs"
|
data/bin/nanite-agent
CHANGED
@@ -37,6 +37,11 @@ opts = OptionParser.new do |opts|
|
|
37
37
|
opts.on("--single-threaded", "Run all operations in one thread") do
|
38
38
|
options[:single_threaded] = true
|
39
39
|
end
|
40
|
+
|
41
|
+
opts.on("--threadpool COUNT", Integer, "Number of threads to run all operations in") do |tps|
|
42
|
+
options[:threadpool_size] = tps
|
43
|
+
end
|
44
|
+
|
40
45
|
end
|
41
46
|
|
42
47
|
opts.parse!
|
data/lib/nanite/actor.rb
CHANGED
@@ -35,7 +35,14 @@ module Nanite
|
|
35
35
|
|
36
36
|
def provides_for(prefix)
|
37
37
|
return [] unless @exposed
|
38
|
-
@exposed.
|
38
|
+
@exposed.select do |meth|
|
39
|
+
if instance_methods.include?(meth.to_s) or instance_methods.include?(meth.to_sym)
|
40
|
+
true
|
41
|
+
else
|
42
|
+
Nanite::Log.warn("Exposing non-existing method #{meth} in actor #{name}")
|
43
|
+
false
|
44
|
+
end
|
45
|
+
end.map {|meth| "/#{prefix}/#{meth}".squeeze('/')}
|
39
46
|
end
|
40
47
|
|
41
48
|
def on_exception(proc = nil, &blk)
|
@@ -54,6 +61,10 @@ module Nanite
|
|
54
61
|
def request(*args, &blk)
|
55
62
|
MapperProxy.instance.request(*args, &blk)
|
56
63
|
end
|
64
|
+
|
65
|
+
def push(*args)
|
66
|
+
MapperProxy.instance.push(*args)
|
67
|
+
end
|
57
68
|
end # InstanceMethods
|
58
69
|
|
59
70
|
end # Actor
|
data/lib/nanite/agent.rb
CHANGED
@@ -8,8 +8,11 @@ module Nanite
|
|
8
8
|
attr_reader :identity, :options, :serializer, :dispatcher, :registry, :amq, :tags
|
9
9
|
attr_accessor :status_proc
|
10
10
|
|
11
|
-
DEFAULT_OPTIONS = COMMON_DEFAULT_OPTIONS.merge({
|
12
|
-
:
|
11
|
+
DEFAULT_OPTIONS = COMMON_DEFAULT_OPTIONS.merge({
|
12
|
+
:user => 'nanite',
|
13
|
+
:ping_time => 15,
|
14
|
+
:default_services => []
|
15
|
+
}) unless defined?(DEFAULT_OPTIONS)
|
13
16
|
|
14
17
|
# Initializes a new agent and establishes AMQP connection.
|
15
18
|
# This must be used inside EM.run block or if EventMachine reactor
|
@@ -54,6 +57,8 @@ module Nanite
|
|
54
57
|
#
|
55
58
|
# single_threaded: Run all operations in one thread
|
56
59
|
#
|
60
|
+
# threadpool_size: Number of threads to run operations in
|
61
|
+
#
|
57
62
|
# Connection options:
|
58
63
|
#
|
59
64
|
# vhost : AMQP broker vhost that should be used
|
@@ -94,7 +99,7 @@ module Nanite
|
|
94
99
|
Log.init(@identity, log_path)
|
95
100
|
Log.level = @options[:log_level] if @options[:log_level]
|
96
101
|
@serializer = Serializer.new(@options[:format])
|
97
|
-
@status_proc = lambda { parse_uptime(`uptime`) rescue 'no status' }
|
102
|
+
@status_proc = lambda { parse_uptime(`uptime 2> /dev/null`) rescue 'no status' }
|
98
103
|
pid_file = PidFile.new(@identity, @options)
|
99
104
|
pid_file.check
|
100
105
|
if @options[:daemonize]
|
@@ -169,7 +174,7 @@ module Nanite
|
|
169
174
|
Nanite::Log.debug("RECV #{packet.to_s}")
|
170
175
|
case packet
|
171
176
|
when Advertise
|
172
|
-
Nanite::Log.info("RECV #{packet.to_s}") unless Nanite::Log.level ==
|
177
|
+
Nanite::Log.info("RECV #{packet.to_s}") unless Nanite::Log.level == :debug
|
173
178
|
advertise_services
|
174
179
|
when Request, Push
|
175
180
|
if @security && !@security.authorize(packet)
|
@@ -179,14 +184,14 @@ module Nanite
|
|
179
184
|
amq.queue(packet.reply_to, :no_declare => options[:secure]).publish(serializer.dump(r))
|
180
185
|
end
|
181
186
|
else
|
182
|
-
Nanite::Log.info("RECV #{packet.to_s([:from, :tags])}") unless Nanite::Log.level ==
|
187
|
+
Nanite::Log.info("RECV #{packet.to_s([:from, :tags])}") unless Nanite::Log.level == :debug
|
183
188
|
dispatcher.dispatch(packet)
|
184
189
|
end
|
185
190
|
when Result
|
186
|
-
Nanite::Log.info("RECV #{packet.to_s([])}") unless Nanite::Log.level ==
|
191
|
+
Nanite::Log.info("RECV #{packet.to_s([])}") unless Nanite::Log.level == :debug
|
187
192
|
@mapper_proxy.handle_result(packet)
|
188
193
|
when IntermediateMessage
|
189
|
-
Nanite::Log.info("RECV #{packet.to_s([])}") unless Nanite::Log.level ==
|
194
|
+
Nanite::Log.info("RECV #{packet.to_s([])}") unless Nanite::Log.level == :debug
|
190
195
|
@mapper_proxy.handle_intermediate_result(packet)
|
191
196
|
end
|
192
197
|
end
|
data/lib/nanite/amqp.rb
CHANGED
@@ -39,9 +39,16 @@ end
|
|
39
39
|
module Nanite
|
40
40
|
module AMQPHelper
|
41
41
|
def start_amqp(options)
|
42
|
-
connection = AMQP.connect(
|
43
|
-
:
|
42
|
+
connection = AMQP.connect({
|
43
|
+
:user => options[:user],
|
44
|
+
:pass => options[:pass],
|
45
|
+
:vhost => options[:vhost],
|
46
|
+
:host => options[:host],
|
47
|
+
:port => (options[:port] || ::AMQP::PORT).to_i,
|
48
|
+
:insist => options[:insist] || false,
|
49
|
+
:retry => options[:retry] || 5
|
50
|
+
})
|
44
51
|
MQ.new(connection)
|
45
52
|
end
|
46
53
|
end
|
47
|
-
end
|
54
|
+
end
|
data/lib/nanite/cluster.rb
CHANGED
@@ -87,22 +87,26 @@ module Nanite
|
|
87
87
|
# forward request coming from agent
|
88
88
|
def handle_request(request)
|
89
89
|
if @security.authorize_request(request)
|
90
|
-
Nanite::Log.info("RECV #{request.to_s([:from, :target, :tags])}") unless Nanite::Log.level ==
|
90
|
+
Nanite::Log.info("RECV #{request.to_s([:from, :target, :tags])}") unless Nanite::Log.level == :debug
|
91
91
|
Nanite::Log.debug("RECV #{request.to_s}")
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
92
|
+
case request
|
93
|
+
when Push
|
94
|
+
mapper.send_push(request)
|
95
|
+
else
|
96
|
+
intm_handler = lambda do |result, job|
|
97
|
+
result = IntermediateMessage.new(request.token, job.request.from, mapper.identity, nil, result)
|
98
|
+
forward_response(result, request.persistent)
|
99
|
+
end
|
97
100
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
101
|
+
result = Result.new(request.token, request.from, nil, mapper.identity)
|
102
|
+
ok = mapper.send_request(request, :intermediate_handler => intm_handler) do |res|
|
103
|
+
result.results = res
|
104
|
+
forward_response(result, request.persistent)
|
105
|
+
end
|
106
|
+
|
107
|
+
if ok == false
|
108
|
+
forward_response(result, request.persistent)
|
109
|
+
end
|
106
110
|
end
|
107
111
|
else
|
108
112
|
Nanite::Log.warn("RECV NOT AUTHORIZED #{request.to_s}")
|
data/lib/nanite/config.rb
CHANGED
@@ -1,7 +1,16 @@
|
|
1
1
|
module Nanite
|
2
2
|
|
3
|
-
COMMON_DEFAULT_OPTIONS = {
|
4
|
-
:
|
3
|
+
COMMON_DEFAULT_OPTIONS = {
|
4
|
+
:pass => 'testing',
|
5
|
+
:vhost => '/nanite',
|
6
|
+
:secure => false,
|
7
|
+
:host => '0.0.0.0',
|
8
|
+
:log_level => :info,
|
9
|
+
:format => :marshal,
|
10
|
+
:daemonize => false,
|
11
|
+
:console => false,
|
12
|
+
:root => Dir.pwd
|
13
|
+
}
|
5
14
|
|
6
15
|
module CommonConfig
|
7
16
|
def setup_mapper_options(opts, options)
|
data/lib/nanite/dispatcher.rb
CHANGED
@@ -10,6 +10,7 @@ module Nanite
|
|
10
10
|
@identity = identity
|
11
11
|
@options = options
|
12
12
|
@evmclass = EM
|
13
|
+
@evmclass.threadpool_size = (@options[:threadpool_size] || 20).to_i
|
13
14
|
end
|
14
15
|
|
15
16
|
def dispatch(deliverable)
|
@@ -37,7 +38,7 @@ module Nanite
|
|
37
38
|
r # For unit tests
|
38
39
|
end
|
39
40
|
|
40
|
-
if @options[:single_threaded]
|
41
|
+
if @options[:single_threaded] || @options[:thread_poolsize] == 1
|
41
42
|
@evmclass.next_tick { callback.call(operation.call) }
|
42
43
|
else
|
43
44
|
@evmclass.defer(operation, callback)
|
@@ -88,4 +89,4 @@ module Nanite
|
|
88
89
|
error
|
89
90
|
end
|
90
91
|
end
|
91
|
-
end
|
92
|
+
end
|
data/lib/nanite/local_state.rb
CHANGED
@@ -18,10 +18,10 @@ module Nanite
|
|
18
18
|
tags = tags.dup.flatten
|
19
19
|
nanites = select { |name, state| state[:services].include?(service) }
|
20
20
|
unless tags.empty?
|
21
|
-
nanites.select { |a| !(
|
21
|
+
nanites.select { |a, b| !(b[:tags] & tags).empty? }
|
22
22
|
else
|
23
23
|
nanites
|
24
|
-
end
|
24
|
+
end.to_a
|
25
25
|
end
|
26
26
|
|
27
27
|
private
|
data/lib/nanite/log.rb
CHANGED
@@ -6,6 +6,13 @@ module Nanite
|
|
6
6
|
class Log
|
7
7
|
|
8
8
|
@logger = nil
|
9
|
+
|
10
|
+
# Map log levels symbols to values
|
11
|
+
LEVELS = { :debug => Logger::DEBUG,
|
12
|
+
:info => Logger::INFO,
|
13
|
+
:warn => Logger::WARN,
|
14
|
+
:error => Logger::ERROR,
|
15
|
+
:fatal => Logger::FATAL }
|
9
16
|
|
10
17
|
class << self
|
11
18
|
attr_accessor :logger, :level, :file #:nodoc
|
@@ -21,31 +28,25 @@ module Nanite
|
|
21
28
|
end
|
22
29
|
@logger = Logger.new(file)
|
23
30
|
@logger.formatter = Nanite::Log::Formatter.new
|
24
|
-
level =
|
31
|
+
Log.level = :info
|
25
32
|
end
|
26
33
|
|
27
34
|
# Sets the level for the Logger by symbol or by command line argument.
|
28
35
|
# Throws an ArgumentError if you feed it a bogus log level (that is not
|
29
|
-
# one of :debug, :info, :warn, :error, :fatal or the corresponding strings)
|
36
|
+
# one of :debug, :info, :warn, :error, :fatal or the corresponding strings or a valid Logger level)
|
30
37
|
def level=(loglevel)
|
31
38
|
init() unless @logger
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
@logger.level = Logger::INFO
|
40
|
-
when :warn
|
41
|
-
@logger.level = Logger::WARN
|
42
|
-
when :error
|
43
|
-
@logger.level = Logger::ERROR
|
44
|
-
when :fatal
|
45
|
-
@logger.level = Logger::FATAL
|
46
|
-
else
|
47
|
-
raise ArgumentError, "Log level must be one of :debug, :info, :warn, :error, or :fatal"
|
39
|
+
lvl = case loglevel
|
40
|
+
when String then loglevel.intern
|
41
|
+
when Integer then LEVELS.invert[loglevel]
|
42
|
+
else loglevel
|
43
|
+
end
|
44
|
+
unless LEVELS.include?(lvl)
|
45
|
+
raise(ArgumentError, 'Log level must be one of :debug, :info, :warn, :error, or :fatal')
|
48
46
|
end
|
47
|
+
@logger.info("[setup] setting log level to #{lvl.to_s.upcase}")
|
48
|
+
@level = lvl
|
49
|
+
@logger.level = LEVELS[lvl]
|
49
50
|
end
|
50
51
|
|
51
52
|
# Passes any other method calls on directly to the underlying Logger object created with init. If
|
data/lib/nanite/mapper.rb
CHANGED
@@ -23,9 +23,15 @@ module Nanite
|
|
23
23
|
|
24
24
|
attr_reader :cluster, :identity, :job_warden, :options, :serializer, :amq
|
25
25
|
|
26
|
-
DEFAULT_OPTIONS = COMMON_DEFAULT_OPTIONS.merge({
|
27
|
-
:
|
28
|
-
:
|
26
|
+
DEFAULT_OPTIONS = COMMON_DEFAULT_OPTIONS.merge({
|
27
|
+
:user => 'mapper',
|
28
|
+
:identity => Identity.generate,
|
29
|
+
:agent_timeout => 15,
|
30
|
+
:offline_redelivery_frequency => 10,
|
31
|
+
:persistent => false,
|
32
|
+
:offline_failsafe => false,
|
33
|
+
:callbacks => {}
|
34
|
+
}) unless defined?(DEFAULT_OPTIONS)
|
29
35
|
|
30
36
|
# Initializes a new mapper and establishes
|
31
37
|
# AMQP connection. This must be used inside EM.run block or if EventMachine reactor
|
@@ -66,9 +72,15 @@ module Nanite
|
|
66
72
|
#
|
67
73
|
# persistent : true instructs the AMQP broker to save messages to persistent storage so that they aren't lost when the
|
68
74
|
# broker is restarted. Default is false. Can be overriden on a per-message basis using the request and push methods.
|
69
|
-
#
|
75
|
+
#
|
70
76
|
# secure : use Security features of rabbitmq to restrict nanites to themselves
|
71
77
|
#
|
78
|
+
# prefetch : Sets prefetch (only supported in RabbitMQ >= 1.6)
|
79
|
+
# callbacks : A set of callbacks to have code executed on specific events, supported events are :register,
|
80
|
+
# :unregister and :timeout. Parameter must be a hash with the corresponding events as keys and
|
81
|
+
# a block as value. The block will get the corresponding nanite's identity and a copy of the
|
82
|
+
# mapper
|
83
|
+
#
|
72
84
|
# Connection options:
|
73
85
|
#
|
74
86
|
# vhost : AMQP broker vhost that should be used
|
@@ -106,7 +118,7 @@ module Nanite
|
|
106
118
|
@options[:file_root] ||= File.join(@options[:root], 'files')
|
107
119
|
@options.freeze
|
108
120
|
end
|
109
|
-
|
121
|
+
|
110
122
|
def run
|
111
123
|
setup_logging
|
112
124
|
@serializer = Serializer.new(@options[:format])
|
@@ -187,7 +199,7 @@ module Nanite
|
|
187
199
|
false
|
188
200
|
end
|
189
201
|
end
|
190
|
-
|
202
|
+
|
191
203
|
# Make a nanite request which does not expect a response.
|
192
204
|
#
|
193
205
|
# ==== Parameters
|
@@ -210,6 +222,10 @@ module Nanite
|
|
210
222
|
# @api :public:
|
211
223
|
def push(type, payload = '', opts = {})
|
212
224
|
push = build_deliverable(Push, type, payload, opts)
|
225
|
+
send_push(push, opts)
|
226
|
+
end
|
227
|
+
|
228
|
+
def send_push(push, opts = {})
|
213
229
|
targets = cluster.targets_for(push)
|
214
230
|
if !targets.empty?
|
215
231
|
cluster.route(push, targets)
|
@@ -221,7 +237,7 @@ module Nanite
|
|
221
237
|
false
|
222
238
|
end
|
223
239
|
end
|
224
|
-
|
240
|
+
|
225
241
|
private
|
226
242
|
|
227
243
|
def build_deliverable(deliverable_type, type, payload, opts)
|
@@ -233,6 +249,10 @@ module Nanite
|
|
233
249
|
end
|
234
250
|
|
235
251
|
def setup_queues
|
252
|
+
if amq.respond_to?(:prefetch) && @options.has_key?(:prefetch)
|
253
|
+
amq.prefetch(@options[:prefetch])
|
254
|
+
end
|
255
|
+
|
236
256
|
setup_offline_queue
|
237
257
|
setup_message_queue
|
238
258
|
end
|
@@ -264,14 +284,14 @@ module Nanite
|
|
264
284
|
begin
|
265
285
|
msg = serializer.load(msg)
|
266
286
|
Nanite::Log.debug("RECV #{msg.to_s}")
|
267
|
-
Nanite::Log.info("RECV #{msg.to_s([:from])}") unless Nanite::Log.level ==
|
287
|
+
Nanite::Log.info("RECV #{msg.to_s([:from])}") unless Nanite::Log.level == :debug
|
268
288
|
job_warden.process(msg)
|
269
289
|
rescue Exception => e
|
270
290
|
Nanite::Log.error("RECV [result] #{e.message}")
|
271
291
|
end
|
272
292
|
end
|
273
293
|
end
|
274
|
-
|
294
|
+
|
275
295
|
def setup_logging
|
276
296
|
log_path = false
|
277
297
|
if @options[:daemonize]
|
@@ -280,7 +300,7 @@ module Nanite
|
|
280
300
|
Nanite::Log.init(@identity, log_path)
|
281
301
|
Nanite::Log.level = @options[:log_level] if @options[:log_level]
|
282
302
|
end
|
283
|
-
|
303
|
+
|
284
304
|
def setup_cluster
|
285
305
|
@cluster = Cluster.new(@amq, @options[:agent_timeout], @options[:identity], @serializer, self, @options[:redis], @options[:callbacks])
|
286
306
|
end
|
data/lib/nanite/mapper_proxy.rb
CHANGED
@@ -16,7 +16,7 @@ module Nanite
|
|
16
16
|
|
17
17
|
# Accessor for actor
|
18
18
|
def self.instance
|
19
|
-
@@instance
|
19
|
+
@@instance if defined?(@@instance)
|
20
20
|
end
|
21
21
|
|
22
22
|
def initialize(id, opts)
|
@@ -40,6 +40,16 @@ module Nanite
|
|
40
40
|
Nanite::Log.info("SEND #{request.to_s([:tags, :target])}")
|
41
41
|
amqp.fanout('request', :no_declare => options[:secure]).publish(serializer.dump(request))
|
42
42
|
end
|
43
|
+
|
44
|
+
def push(type, payload = '', opts = {})
|
45
|
+
raise "Mapper proxy not initialized" unless identity && options
|
46
|
+
push = Push.new(type, payload, opts)
|
47
|
+
push.from = identity
|
48
|
+
push.token = Identity.generate
|
49
|
+
push.persistent = opts.key?(:persistent) ? opts[:persistent] : options[:persistent]
|
50
|
+
Nanite::Log.info("SEND #{push.to_s([:tags, :target])}")
|
51
|
+
amqp.fanout('request', :no_declare => options[:secure]).publish(serializer.dump(push))
|
52
|
+
end
|
43
53
|
|
44
54
|
# Handle intermediary result
|
45
55
|
def handle_intermediate_result(res)
|
data/lib/nanite/packets.rb
CHANGED
@@ -12,7 +12,7 @@ module Nanite
|
|
12
12
|
def to_json(*a)
|
13
13
|
js = {
|
14
14
|
'json_class' => self.class.name,
|
15
|
-
'data' => instance_variables.inject({}) {|m,ivar| m[ivar.sub(/@/,'')] = instance_variable_get(ivar); m }
|
15
|
+
'data' => instance_variables.inject({}) {|m,ivar| m[ivar.to_s.sub(/@/,'')] = instance_variable_get(ivar); m }
|
16
16
|
}.to_json(*a)
|
17
17
|
js = js.chop + ",\"size\":#{js.size}}"
|
18
18
|
js
|
@@ -37,11 +37,6 @@ module Nanite
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
# Wrap given string to given maximum number of characters per line
|
41
|
-
def wrap(txt, col=120)
|
42
|
-
txt.gsub(/(.{1,#{col}})( +|$\n?)|(.{1,#{col}})/, "\\1\\3\n").chomp
|
43
|
-
end
|
44
|
-
|
45
40
|
end
|
46
41
|
|
47
42
|
# packet that means start of a file transfer
|
@@ -63,7 +58,7 @@ module Nanite
|
|
63
58
|
end
|
64
59
|
|
65
60
|
def to_s
|
66
|
-
|
61
|
+
"#{super} <#{token}> #{filename} to #{dest}"
|
67
62
|
end
|
68
63
|
end
|
69
64
|
|
@@ -85,7 +80,7 @@ module Nanite
|
|
85
80
|
end
|
86
81
|
|
87
82
|
def to_s
|
88
|
-
|
83
|
+
"#{super} <#{token}> meta #{meta}"
|
89
84
|
end
|
90
85
|
end
|
91
86
|
|
@@ -158,7 +153,7 @@ module Nanite
|
|
158
153
|
log_msg += ", reply_to #{id_to_s(reply_to)}" if reply_to && (filter.nil? || filter.include?(:reply_to))
|
159
154
|
log_msg += ", tags #{tags.inspect}" if tags && !tags.empty? && (filter.nil? || filter.include?(:tags))
|
160
155
|
log_msg += ", payload #{payload.inspect}" if filter.nil? || filter.include?(:payload)
|
161
|
-
|
156
|
+
log_msg
|
162
157
|
end
|
163
158
|
|
164
159
|
end
|
@@ -207,7 +202,7 @@ module Nanite
|
|
207
202
|
log_msg += ", target #{id_to_s(target)}" if target && (filter.nil? || filter.include?(:target))
|
208
203
|
log_msg += ", tags #{tags.inspect}" if tags && !tags.empty? && (filter.nil? || filter.include?(:tags))
|
209
204
|
log_msg += ", payload #{payload.inspect}" if filter.nil? || filter.include?(:payload)
|
210
|
-
|
205
|
+
log_msg
|
211
206
|
end
|
212
207
|
end
|
213
208
|
|
@@ -239,7 +234,7 @@ module Nanite
|
|
239
234
|
log_msg += " from #{id_to_s(from)}" if filter.nil? || filter.include?(:from)
|
240
235
|
log_msg += " to #{id_to_s(to)}" if filter.nil? || filter.include?(:to)
|
241
236
|
log_msg += " results: #{results.inspect}" if filter.nil? || filter.include?(:results)
|
242
|
-
|
237
|
+
log_msg
|
243
238
|
end
|
244
239
|
end
|
245
240
|
|
@@ -269,7 +264,7 @@ module Nanite
|
|
269
264
|
end
|
270
265
|
|
271
266
|
def to_s
|
272
|
-
|
267
|
+
"#{super} <#{token}> from #{id_to_s(from)}, key #{messagekey}"
|
273
268
|
end
|
274
269
|
end
|
275
270
|
|
@@ -300,7 +295,7 @@ module Nanite
|
|
300
295
|
log_msg = "#{super} #{id_to_s(identity)}"
|
301
296
|
log_msg += ", services: #{services.join(', ')}" if services && !services.empty?
|
302
297
|
log_msg += ", tags: #{tags.join(', ')}" if tags && !tags.empty?
|
303
|
-
|
298
|
+
log_msg
|
304
299
|
end
|
305
300
|
end
|
306
301
|
|
@@ -25,7 +25,7 @@ module Nanite
|
|
25
25
|
# Initialize from encrypted data.
|
26
26
|
def self.from_data(encrypted_data)
|
27
27
|
doc = EncryptedDocument.allocate
|
28
|
-
doc.instance_variable_set(:@pkcs7,
|
28
|
+
doc.instance_variable_set(:@pkcs7, Nanite::PKCS7.new(encrypted_data))
|
29
29
|
doc
|
30
30
|
end
|
31
31
|
|
@@ -51,6 +51,7 @@ module Nanite
|
|
51
51
|
data = JSON.load(json)
|
52
52
|
sig = Signature.from_data(data['signature'])
|
53
53
|
certs = @store.get_signer(data['id'])
|
54
|
+
raise "Could not find a cert for signer #{data['id']}" unless certs
|
54
55
|
certs = [ certs ] unless certs.respond_to?(:each)
|
55
56
|
jsn = data['data'] if certs.any? { |c| sig.match?(c) }
|
56
57
|
if jsn && @encrypt && data['encrypted']
|
@@ -1,3 +1,9 @@
|
|
1
|
+
if defined?(OpenSSL::PKCS7::PKCS7)
|
2
|
+
Nanite::PKCS7 = OpenSSL::PKCS7::PKCS7
|
3
|
+
else
|
4
|
+
Nanite::PKCS7 = OpenSSL::PKCS7
|
5
|
+
end
|
6
|
+
|
1
7
|
module Nanite
|
2
8
|
|
3
9
|
# Signature that can be validated against certificates
|
@@ -20,7 +26,7 @@ module Nanite
|
|
20
26
|
# Load signature previously serialized via 'data'
|
21
27
|
def self.from_data(data)
|
22
28
|
sig = Signature.allocate
|
23
|
-
sig.instance_variable_set(:@p7,
|
29
|
+
sig.instance_variable_set(:@p7, Nanite::PKCS7.new(data))
|
24
30
|
sig.instance_variable_set(:@store, OpenSSL::X509::Store.new)
|
25
31
|
sig
|
26
32
|
end
|
data/lib/nanite/state.rb
CHANGED
data/lib/nanite/util.rb
CHANGED
@@ -30,22 +30,29 @@ class String
|
|
30
30
|
end
|
31
31
|
|
32
32
|
class Object
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
33
|
+
unless defined? instance_exec # 1.9 and 1.8.7
|
34
|
+
module InstanceExecHelper; end
|
35
|
+
include InstanceExecHelper
|
36
|
+
|
37
|
+
# Evaluate the block with the given arguments within the context of
|
38
|
+
# this object, so self is set to the method receiver.
|
39
|
+
#
|
40
|
+
# From Mauricio's http://eigenclass.org/hiki/bounded+space+instance_exec
|
41
|
+
def instance_exec(*args, &block)
|
42
|
+
begin
|
43
|
+
old_critical, Thread.critical = Thread.critical, true
|
44
|
+
n = 0
|
45
|
+
n += 1 while respond_to?(method_name = "__instance_exec#{n}")
|
46
|
+
InstanceExecMethods.module_eval { define_method(method_name, &block) }
|
47
|
+
ensure
|
48
|
+
Thread.critical = old_critical
|
49
|
+
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
send(method_name, *args)
|
53
|
+
ensure
|
54
|
+
InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
|
55
|
+
end
|
48
56
|
end
|
49
|
-
ret
|
50
57
|
end
|
51
58
|
end
|
data/lib/nanite.rb
CHANGED
@@ -39,7 +39,7 @@ require 'nanite/security/static_certificate_store'
|
|
39
39
|
require 'nanite/serializer'
|
40
40
|
|
41
41
|
module Nanite
|
42
|
-
VERSION = '0.4.
|
42
|
+
VERSION = '0.4.1.3' unless defined?(Nanite::VERSION)
|
43
43
|
|
44
44
|
class MapperNotRunning < StandardError; end
|
45
45
|
|
@@ -65,7 +65,10 @@ module Nanite
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def ensure_mapper
|
68
|
-
|
68
|
+
@mapper ||= MapperProxy.instance
|
69
|
+
unless @mapper
|
70
|
+
raise MapperNotRunning.new('A mapper needs to be started via Nanite.start_mapper')
|
71
|
+
end
|
69
72
|
end
|
70
73
|
end
|
71
74
|
end
|
data/spec/actor_registry_spec.rb
CHANGED
@@ -2,30 +2,28 @@ require File.join(File.dirname(__FILE__), 'spec_helper')
|
|
2
2
|
|
3
3
|
describe Nanite::ActorRegistry do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
expose :import, :cancel
|
5
|
+
class ::WebDocumentImporter
|
6
|
+
include Nanite::Actor
|
7
|
+
expose :import, :cancel
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
9
|
+
def import
|
10
|
+
1
|
11
|
+
end
|
12
|
+
def cancel
|
13
|
+
0
|
16
14
|
end
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
17
|
+
module ::Actors
|
18
|
+
class ComedyActor
|
19
|
+
include Nanite::Actor
|
20
|
+
expose :fun_tricks
|
21
|
+
def fun_tricks
|
22
|
+
:rabbit_in_the_hat
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
28
|
-
|
26
|
+
|
29
27
|
before(:each) do
|
30
28
|
Nanite::Log.stub!(:info)
|
31
29
|
@registry = Nanite::ActorRegistry.new
|
data/spec/actor_spec.rb
CHANGED
@@ -1,33 +1,46 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
describe Nanite::Actor do
|
4
|
+
class ::WebDocumentImporter
|
5
|
+
include Nanite::Actor
|
6
|
+
expose :import, :cancel
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
def import
|
9
|
+
1
|
10
|
+
end
|
11
|
+
def cancel
|
12
|
+
0
|
13
|
+
end
|
14
|
+
def continue
|
15
|
+
1
|
16
|
+
end
|
15
17
|
end
|
16
|
-
end
|
17
18
|
|
18
|
-
module Actors
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
module ::Actors
|
20
|
+
class ComedyActor
|
21
|
+
include Nanite::Actor
|
22
|
+
expose :fun_tricks
|
23
|
+
def fun_tricks
|
24
|
+
:rabbit_in_the_hat
|
25
|
+
end
|
24
26
|
end
|
25
27
|
end
|
26
|
-
end
|
27
28
|
|
28
|
-
|
29
|
+
class ::Actors::InvalidActor
|
30
|
+
include Nanite::Actor
|
31
|
+
expose :non_existing
|
32
|
+
end
|
29
33
|
|
30
34
|
describe ".expose" do
|
35
|
+
before :each do
|
36
|
+
@exposed = WebDocumentImporter.instance_variable_get(:@exposed).dup
|
37
|
+
end
|
38
|
+
|
39
|
+
after :each do
|
40
|
+
WebDocumentImporter.instance_variable_set(:@exposed, @exposed)
|
41
|
+
end
|
42
|
+
|
43
|
+
|
31
44
|
it "should single expose method only once" do
|
32
45
|
3.times { WebDocumentImporter.expose(:continue) }
|
33
46
|
WebDocumentImporter.provides_for("webfiles").should == ["/webfiles/import", "/webfiles/cancel", "/webfiles/continue"]
|
@@ -45,6 +58,7 @@ describe Nanite::Actor do
|
|
45
58
|
before :each do
|
46
59
|
@provides = Actors::ComedyActor.provides_for("money")
|
47
60
|
end
|
61
|
+
|
48
62
|
it "returns an array" do
|
49
63
|
@provides.should be_kind_of(Array)
|
50
64
|
end
|
@@ -55,5 +69,9 @@ describe Nanite::Actor do
|
|
55
69
|
wdi_provides.should include("/webfiles/import")
|
56
70
|
wdi_provides.should include("/webfiles/cancel")
|
57
71
|
end
|
72
|
+
|
73
|
+
it "should not include methods not existing in the actor class" do
|
74
|
+
Actors::InvalidActor.provides_for("money").should_not include("/money/non_existing")
|
75
|
+
end
|
58
76
|
end
|
59
77
|
end
|
data/spec/agent_spec.rb
CHANGED
@@ -186,7 +186,12 @@ describe "Agent:" do
|
|
186
186
|
agent.tags.should include("sample_tag_1")
|
187
187
|
agent.tags.should include("sample_tag_2")
|
188
188
|
end
|
189
|
-
|
189
|
+
|
190
|
+
it "for threadpool_size" do
|
191
|
+
agent = Nanite::Agent.start(:threadpool_size => 5)
|
192
|
+
agent.dispatcher.evmclass.threadpool_size.should == 5
|
193
|
+
end
|
194
|
+
|
190
195
|
end
|
191
196
|
|
192
197
|
describe "Security" do
|
data/spec/cluster_spec.rb
CHANGED
@@ -94,17 +94,23 @@ describe Nanite::Cluster do
|
|
94
94
|
end # Reaper
|
95
95
|
|
96
96
|
describe "State" do
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
cluster.nanites.instance_of?(Nanite::LocalState).should == true
|
97
|
+
begin
|
98
|
+
require 'nanite/state'
|
99
|
+
rescue LoadError
|
101
100
|
end
|
101
|
+
|
102
|
+
if defined?(Redis)
|
103
|
+
it "should use a local state by default" do
|
104
|
+
cluster = Nanite::Cluster.new(@amq, 443, "the_identity", @serializer, @mapper)
|
105
|
+
cluster.nanites.instance_of?(Nanite::LocalState).should == true
|
106
|
+
end
|
102
107
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
+
it "should set up a redis state when requested" do
|
109
|
+
state = Nanite::State.new("")
|
110
|
+
Nanite::State.should_receive(:new).with("localhost:1234").and_return(state)
|
111
|
+
cluster = Nanite::Cluster.new(@amq, 443, "the_identity", @serializer, @mapper, "localhost:1234")
|
112
|
+
cluster.nanites.instance_of?(Nanite::State).should == true
|
113
|
+
end
|
108
114
|
end
|
109
115
|
end
|
110
116
|
end # Intialization
|
@@ -410,6 +416,14 @@ describe Nanite::Cluster do
|
|
410
416
|
@cluster_with_target.should_receive(:forward_response)
|
411
417
|
@cluster_with_target.__send__(:handle_request, @request_with_target)
|
412
418
|
end
|
419
|
+
|
420
|
+
describe "when getting push requests from an agent" do
|
421
|
+
it "should send the push message through the mapper" do
|
422
|
+
push = Nanite::Push.new(nil, nil)
|
423
|
+
@mapper_with_target.should_receive(:send_push).with(push)
|
424
|
+
@cluster_with_target.__send__(:handle_request, push)
|
425
|
+
end
|
426
|
+
end
|
413
427
|
end # Agent Request Handling
|
414
428
|
|
415
429
|
describe "Heartbeat" do
|
data/spec/log_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe Nanite::Log do
|
4
|
+
describe "Using log without initializing it first" do
|
5
|
+
before(:each) do
|
6
|
+
Nanite::Log.instance_variable_set(:@logger, nil)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should use standard out for logging" do
|
10
|
+
Nanite::Log.init
|
11
|
+
STDOUT.should_receive(:write) do |arg|
|
12
|
+
arg.include?("For your consideration").should == true
|
13
|
+
end
|
14
|
+
Nanite::Log.info("For your consideration")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "Initializing the log level" do
|
19
|
+
it "should default to :info" do
|
20
|
+
Nanite::Log.init
|
21
|
+
Nanite::Log.level.should == :info
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should raise an error if level is incorrect" do
|
25
|
+
lambda { Nanite::Log.level = "fool" }.should raise_error
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should succeed when using symbols" do
|
29
|
+
[ :debug, :info, :warn, :error, :fatal ].each do |level|
|
30
|
+
Nanite::Log.level = level
|
31
|
+
Nanite::Log.level.should == level
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
it "should succeed when using log levels" do
|
37
|
+
lvls = { Logger::DEBUG => :debug,
|
38
|
+
Logger::INFO => :info,
|
39
|
+
Logger::WARN => :warn,
|
40
|
+
Logger::ERROR => :error,
|
41
|
+
Logger::FATAL => :fatal }
|
42
|
+
lvls.keys.each do |level|
|
43
|
+
Nanite::Log.level = level
|
44
|
+
Nanite::Log.level.should == lvls[level]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe Nanite::MapperProxy do
|
4
|
+
describe "when fetching the instance" do
|
5
|
+
before(:each) do
|
6
|
+
if Nanite::MapperProxy.class_variables.include?('@@instance')
|
7
|
+
Nanite::MapperProxy.__send__(:remove_class_variable, :@@instance)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return nil when the instance is undefined" do
|
12
|
+
Nanite::MapperProxy.instance.should == nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return the instance if defined" do
|
16
|
+
instance = mock
|
17
|
+
Nanite::MapperProxy.class_eval do
|
18
|
+
@@instance = "instance"
|
19
|
+
end
|
20
|
+
|
21
|
+
Nanite::MapperProxy.instance.should_not == nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "when pushing a message" do
|
26
|
+
before do
|
27
|
+
AMQP.stub!(:connect)
|
28
|
+
MQ.stub!(:new)
|
29
|
+
Nanite::MapperProxy.new('mapperproxy', {})
|
30
|
+
@instance = Nanite::MapperProxy.instance
|
31
|
+
@fanout = stub(:fanout, :publish => true)
|
32
|
+
@instance.amqp.stub!(:fanout).and_return(@fanout)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should raise an error if mapper proxy is not initialized" do
|
36
|
+
lambda {
|
37
|
+
@instance.stub!(:identity).and_return nil
|
38
|
+
@instance.push('/welcome/aboard', 'iZac')
|
39
|
+
}.should raise_error("Mapper proxy not initialized")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should set correct attributes on the push message" do
|
43
|
+
@fanout.should_receive(:publish).with do |push|
|
44
|
+
push = @instance.serializer.load(push)
|
45
|
+
push.token.should_not == nil
|
46
|
+
push.persistent.should_not == true
|
47
|
+
push.from.should == 'mapperproxy'
|
48
|
+
end
|
49
|
+
|
50
|
+
@instance.push('/welcome/aboard', 'iZac')
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should mark the message as persistent when the option is specified on the parameter" do
|
54
|
+
@fanout.should_receive(:publish).with do |push|
|
55
|
+
push = @instance.serializer.load(push)
|
56
|
+
push.persistent.should == true
|
57
|
+
end
|
58
|
+
|
59
|
+
@instance.push('/welcome/aboard', 'iZac', :persistent => true)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should mark the message as persistent when the option is set globally" do
|
63
|
+
@instance.options[:persistent] = true
|
64
|
+
@fanout.should_receive(:publish).with do |push|
|
65
|
+
push = @instance.serializer.load(push)
|
66
|
+
push.persistent.should == true
|
67
|
+
end
|
68
|
+
|
69
|
+
@instance.push('/welcome/aboard', 'iZac')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/spec/mapper_spec.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe Nanite::Mapper do
|
4
|
+
include SpecHelpers
|
5
|
+
|
6
|
+
describe "Initializing" do
|
7
|
+
before(:each) do
|
8
|
+
@mapper = Nanite::Mapper.new({})
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should set the identity" do
|
12
|
+
@mapper.identity.should_not == nil
|
13
|
+
@mapper.identity.should =~ /mapper-.*/
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should set the identity to a custom identity" do
|
17
|
+
@mapper = Nanite::Mapper.new({:identity => "bob"})
|
18
|
+
@mapper.identity.should == "mapper-bob"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should set the file root" do
|
22
|
+
@mapper.options[:file_root].should == File.expand_path("#{File.dirname(__FILE__)}/../files")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "Starting" do
|
27
|
+
before(:each) do
|
28
|
+
@mapper = Nanite::Mapper.new({:log_level => :debug})
|
29
|
+
@mapper.stub!(:setup_queues)
|
30
|
+
@mapper.stub!(:start_amqp)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should initialize the logger" do
|
34
|
+
@mapper.stub!(:setup_cluster)
|
35
|
+
run_in_em do
|
36
|
+
@mapper.run
|
37
|
+
Nanite::Log.logger.level.should == Logger::DEBUG
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should set up the cluster" do
|
42
|
+
Nanite::Cluster.should_receive(:new).with(nil, 15, instance_of(String), instance_of(Nanite::Serializer), @mapper, nil, {})
|
43
|
+
run_in_em do
|
44
|
+
@mapper.run
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should set the prefetch value" do
|
49
|
+
amqp = mock("AMQP")
|
50
|
+
|
51
|
+
mapper = Nanite::Mapper.new(:prefetch => 11)
|
52
|
+
mapper.stub!(:setup_offline_queue)
|
53
|
+
mapper.stub!(:setup_message_queue)
|
54
|
+
mapper.stub!(:start_amqp)
|
55
|
+
mapper.stub!(:setup_cluster)
|
56
|
+
|
57
|
+
mapper.stub!(:start_amqp).and_return(amqp)
|
58
|
+
amqp.should_receive(:prefetch).with(11)
|
59
|
+
mapper.run
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should hand over callback options to the cluster" do
|
63
|
+
@mapper = Nanite::Mapper.new({:callbacks => {:register => lambda {|*args|}}})
|
64
|
+
@mapper.stub!(:setup_queues)
|
65
|
+
@mapper.stub!(:start_amqp)
|
66
|
+
Nanite::Cluster.should_receive(:new)
|
67
|
+
run_in_em {@mapper.run}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/spec/nanite_spec.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe Nanite do
|
4
|
+
describe "when ensuring a mapper exists" do
|
5
|
+
describe "with a configured mapper proxy" do
|
6
|
+
before(:each) do
|
7
|
+
Nanite.instance_variable_set(:@mapper, nil)
|
8
|
+
Nanite::MapperProxy.stub!(:instance).and_return(mock(:mapper_proxy))
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should not raise an error" do
|
12
|
+
lambda {
|
13
|
+
Nanite.ensure_mapper
|
14
|
+
}.should_not raise_error
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should set the mapper instance variable to the mapper proxy instance" do
|
18
|
+
Nanite.ensure_mapper
|
19
|
+
Nanite.mapper.should == Nanite::MapperProxy.instance
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "when the mapper wasn't started yet" do
|
24
|
+
before do
|
25
|
+
Nanite.instance_variable_set(:@mapper, nil)
|
26
|
+
Nanite::MapperProxy.stub!(:instance).and_return(nil)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should raise an error" do
|
30
|
+
lambda {
|
31
|
+
Nanite.ensure_mapper
|
32
|
+
}.should raise_error(Nanite::MapperNotRunning)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/spec/packet_spec.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
2
|
|
3
|
+
class TestPacket < Nanite::Packet
|
4
|
+
@@cls_attr = "ignore"
|
5
|
+
def initialize(attr1)
|
6
|
+
@attr1 = attr1
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
3
10
|
describe "Packet: Base class" do
|
11
|
+
|
4
12
|
before(:all) do
|
5
|
-
class TestPacket < Nanite::Packet
|
6
|
-
@@cls_attr = "ignore"
|
7
|
-
def initialize(attr1)
|
8
|
-
@attr1 = attr1
|
9
|
-
end
|
10
|
-
end
|
11
13
|
end
|
12
14
|
|
13
15
|
it "should be an abstract class" do
|
data/spec/spec_helper.rb
CHANGED
@@ -7,9 +7,6 @@ require 'nanite'
|
|
7
7
|
|
8
8
|
module SpecHelpers
|
9
9
|
|
10
|
-
# Initialize logger so it writes to file instead of STDOUT
|
11
|
-
Nanite::Log.init('test', File.join(File.dirname(__FILE__)))
|
12
|
-
|
13
10
|
# Create test certificate
|
14
11
|
def issue_cert
|
15
12
|
test_dn = { 'C' => 'US',
|
@@ -30,4 +27,4 @@ module SpecHelpers
|
|
30
27
|
end
|
31
28
|
end
|
32
29
|
|
33
|
-
end
|
30
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rightscale-nanite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.1.
|
4
|
+
version: 0.4.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ezra Zygmuntowicz
|
@@ -86,9 +86,11 @@ files:
|
|
86
86
|
- spec/certificate_cache_spec.rb
|
87
87
|
- spec/cached_certificate_store_proxy_spec.rb
|
88
88
|
- spec/dispatcher_spec.rb
|
89
|
+
- spec/log_spec.rb
|
89
90
|
- spec/rsa_key_pair_spec.rb
|
90
91
|
- spec/cluster_spec.rb
|
91
92
|
- spec/spec_helper.rb
|
93
|
+
- spec/mapper_spec.rb
|
92
94
|
- spec/actor_registry_spec.rb
|
93
95
|
- spec/actor_spec.rb
|
94
96
|
- spec/packet_spec.rb
|
@@ -96,9 +98,11 @@ files:
|
|
96
98
|
- spec/static_certificate_store_spec.rb
|
97
99
|
- spec/job_spec.rb
|
98
100
|
- spec/signature_spec.rb
|
101
|
+
- spec/mapper_proxy_spec.rb
|
99
102
|
- spec/secure_serializer_spec.rb
|
100
103
|
- spec/serializer_spec.rb
|
101
104
|
- spec/certificate_spec.rb
|
105
|
+
- spec/nanite_spec.rb
|
102
106
|
- spec/distinguished_name_spec.rb
|
103
107
|
has_rdoc: true
|
104
108
|
homepage: http://github.com/ezmobius/nanite
|