acts_as_executor 1.0.0.beta2 → 1.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/acts_as_executor.gemspec +8 -1
- data/lib/acts_as_executor.rb +18 -31
- data/lib/acts_as_executor/common/future_task.rb +2 -2
- data/lib/acts_as_executor/common/instance_support_methods.rb +15 -0
- data/lib/acts_as_executor/executor/factory.rb +18 -22
- data/lib/acts_as_executor/executor/model/class_methods.rb +33 -0
- data/lib/acts_as_executor/executor/model/instance_methods.rb +87 -0
- data/lib/acts_as_executor/executor/model/instance_support_methods.rb +36 -0
- data/lib/acts_as_executor/task/clazz.rb +26 -0
- data/lib/acts_as_executor/task/model/class_methods.rb +13 -0
- data/lib/acts_as_executor/task/model/instance_methods.rb +64 -0
- data/lib/acts_as_executor/task/model/instance_support_methods.rb +32 -0
- data/lib/acts_as_executor/validators/class_exists_validator.rb +1 -1
- data/lib/acts_as_executor/validators/class_includes_validator.rb +10 -0
- data/lib/acts_as_executor/version.rb +1 -1
- data/lib/generators/{executor_generator.rb → acts_as_executor_generator.rb} +1 -5
- data/lib/generators/templates/migration/create_executors.rb +2 -2
- data/spec/acts_as_executor_spec.rb +22 -0
- data/spec/common/future_task_spec.rb +21 -0
- data/spec/common/instance_support_methods_spec.rb +25 -0
- data/spec/common/units_spec.rb +19 -0
- data/spec/executor/factory_spec.rb +31 -0
- data/spec/executor/model/class_methods_spec.rb +49 -0
- data/spec/executor/model/instance_methods_spec.rb +150 -0
- data/spec/executor/model/instance_support_methods_spec.rb +70 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/blueprints.rb +20 -0
- data/spec/support/classes.rb +55 -0
- data/spec/support/custom_matchers.rb +26 -0
- data/spec/support/database_connection.rb +4 -0
- data/spec/task/clazz_spec.rb +42 -0
- data/spec/task/model/class_methods_spec.rb +13 -0
- data/spec/task/model/instance_methods_spec.rb +80 -0
- data/spec/task/model/instance_support_methods_spec.rb +56 -0
- data/spec/task/schedules_spec.rb +11 -0
- data/spec/validators/class_exists_validator_spec.rb +21 -0
- data/spec/validators/class_includes_validator_spec.rb +21 -0
- metadata +88 -21
- data/README.rdoc +0 -67
- data/lib/acts_as_executor/executor/kinds.rb +0 -16
- data/lib/acts_as_executor/executor/model/actions.rb +0 -65
- data/lib/acts_as_executor/executor/model/associations.rb +0 -11
- data/lib/acts_as_executor/executor/model/attributes.rb +0 -16
- data/lib/acts_as_executor/executor/model/base.rb +0 -24
- data/lib/acts_as_executor/executor/model/helpers.rb +0 -25
- data/lib/acts_as_executor/executor/model/validations.rb +0 -13
- data/lib/acts_as_executor/task/model/actions.rb +0 -34
- data/lib/acts_as_executor/task/model/associations.rb +0 -11
- data/lib/acts_as_executor/task/model/attributes.rb +0 -16
- data/lib/acts_as_executor/task/model/base.rb +0 -15
- data/lib/acts_as_executor/task/model/helpers.rb +0 -14
- data/lib/acts_as_executor/task/model/validations.rb +0 -16
- data/lib/generators/templates/initializer/acts_as_executor.rb +0 -4
@@ -0,0 +1,10 @@
|
|
1
|
+
class ClassIncludesValidator < ActiveModel::EachValidator
|
2
|
+
def validate_each record, attribute, value
|
3
|
+
begin
|
4
|
+
throw TypeError unless Object.const_get(value).new.kind_of? options[:includes]
|
5
|
+
rescue NameError
|
6
|
+
rescue TypeError
|
7
|
+
record.errors[attribute] << "does not include " + options[:includes].to_s
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -1,12 +1,8 @@
|
|
1
|
-
class
|
1
|
+
class ActsAsExecutorGenerator < Rails::Generators::NamedBase
|
2
2
|
include Rails::Generators::Migration
|
3
3
|
|
4
4
|
source_root File.expand_path("../templates", __FILE__)
|
5
5
|
|
6
|
-
def initializer
|
7
|
-
template File.join("initializer", "acts_as_executor.rb"), File.join("config", "initializers", "acts_as_executor.rb")
|
8
|
-
end
|
9
|
-
|
10
6
|
def models
|
11
7
|
template File.join("models", "executor.rb"), File.join("app", "models", file_name + ".rb")
|
12
8
|
template File.join("models", "executor_task.rb"), File.join("app", "models", file_name + "_task.rb")
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActsAsExecutor do
|
4
|
+
it { ActsAsExecutor::VERSION.should == "1.0.0.rc1" }
|
5
|
+
|
6
|
+
describe "#rails_initialized?" do
|
7
|
+
context "when rails initialized" do
|
8
|
+
it "should return true" do
|
9
|
+
$0 = "rails"
|
10
|
+
|
11
|
+
ActsAsExecutor.rails_initialized?.should be_true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
context "when rails not initialized" do
|
15
|
+
it "should return false" do
|
16
|
+
$0 = "rake"
|
17
|
+
|
18
|
+
ActsAsExecutor.rails_initialized?.should be_false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActsAsExecutor::Common::FutureTask do
|
4
|
+
before(:each) { @model = ActsAsExecutor::Common::FutureTask.new Clazz.make, nil }
|
5
|
+
|
6
|
+
it { @model.should be_a Java::java.util.concurrent.FutureTask }
|
7
|
+
|
8
|
+
describe "#done" do
|
9
|
+
context "when done handler exists" do
|
10
|
+
it "should invoke handler" do
|
11
|
+
handler = double "Handler"
|
12
|
+
handler.stub :done_handler
|
13
|
+
@model.done_handler = handler.method :done_handler
|
14
|
+
|
15
|
+
handler.should_receive :done_handler
|
16
|
+
|
17
|
+
@model.done
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActsAsExecutor::Common::InstanceSupportMethods do
|
4
|
+
before(:each) { @model = InstanceSupportMethods.make }
|
5
|
+
|
6
|
+
it { @model.should_not allow_public_access_for_methods :log_statement, :log_message }
|
7
|
+
|
8
|
+
describe "#log_statement" do
|
9
|
+
it "should return a string" do
|
10
|
+
@model.send(:log_statement, "name", "statement").should == log_statement("name", "statement")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#log_message" do
|
15
|
+
it "should return a string" do
|
16
|
+
@model.send(:log_message, "name", "doing", 1.to_s, "clazz", "message").should == log_message("name", "doing", 1.to_s, "clazz", "message")
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when message is a hash" do
|
20
|
+
it "should return a string" do
|
21
|
+
@model.send(:log_message, "name", "doing", 1.to_s, "clazz", {:attribute_one => "attribute_one_value", :attribute_two => "attribute_two_value"}).should == log_message("name", "doing", 1.to_s, "clazz", {:attribute_one => "attribute_one_value", :attribute_two => "attribute_two_value"})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActsAsExecutor::Common::Units do
|
4
|
+
it { ActsAsExecutor::Common::Units::NANOSECONDS.should == "nanoseconds" }
|
5
|
+
it { ActsAsExecutor::Common::Units::MICROSECONDS.should == "microseconds" }
|
6
|
+
it { ActsAsExecutor::Common::Units::MILLISECONDS.should == "milliseconds" }
|
7
|
+
it { ActsAsExecutor::Common::Units::SECONDS.should == "seconds" }
|
8
|
+
it { ActsAsExecutor::Common::Units::MINUTES.should == "minutes" }
|
9
|
+
it { ActsAsExecutor::Common::Units::HOURS.should == "hours" }
|
10
|
+
it { ActsAsExecutor::Common::Units::DAYS.should == "days" }
|
11
|
+
it { ActsAsExecutor::Common::Units::ALL.should include ActsAsExecutor::Common::Units::NANOSECONDS,
|
12
|
+
ActsAsExecutor::Common::Units::MICROSECONDS,
|
13
|
+
ActsAsExecutor::Common::Units::MILLISECONDS,
|
14
|
+
ActsAsExecutor::Common::Units::SECONDS,
|
15
|
+
ActsAsExecutor::Common::Units::MINUTES,
|
16
|
+
ActsAsExecutor::Common::Units::HOURS,
|
17
|
+
ActsAsExecutor::Common::Units::DAYS
|
18
|
+
}
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActsAsExecutor::Executor::Factory do
|
4
|
+
describe "#create" do
|
5
|
+
it "should return a scheduled executor" do
|
6
|
+
executor = ActsAsExecutor::Executor::Factory.create 5, true
|
7
|
+
|
8
|
+
executor.should be_a Java::java.util.concurrent.ScheduledExecutorService
|
9
|
+
executor.core_pool_size.should == 5
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should return a single scheduled executor" do
|
13
|
+
ActsAsExecutor::Executor::Factory.create(1, true).should be_a Java::java.util.concurrent.ScheduledExecutorService
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return a cached executor" do
|
17
|
+
ActsAsExecutor::Executor::Factory.create(nil, nil).should be_a Java::java.util.concurrent.ExecutorService
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return a fixed executor" do
|
21
|
+
executor = ActsAsExecutor::Executor::Factory.create 5, nil
|
22
|
+
|
23
|
+
executor.should be_a Java::java.util.concurrent.ExecutorService
|
24
|
+
executor.core_pool_size.should == 5
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return a single executor" do
|
28
|
+
ActsAsExecutor::Executor::Factory.create(1, nil).should be_a Java::java.util.concurrent.ExecutorService
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActsAsExecutor::Executor::Model::ClassMethods do
|
4
|
+
subject { ActiveRecord::Base }
|
5
|
+
it { should be_a ActsAsExecutor::Executor::Model::ClassMethods }
|
6
|
+
|
7
|
+
describe "#acts_as_executor" do
|
8
|
+
subject { Executor }
|
9
|
+
it { should include ActsAsExecutor::Common::InstanceSupportMethods }
|
10
|
+
it { should include ActsAsExecutor::Executor::Model::InstanceMethods }
|
11
|
+
it { should include ActsAsExecutor::Executor::Model::InstanceSupportMethods }
|
12
|
+
|
13
|
+
context "when arguments exist" do
|
14
|
+
before :all do
|
15
|
+
@log = Logger.new
|
16
|
+
|
17
|
+
ExecutorWithoutActsAsExecutor.acts_as_executor :log => @log
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should set log" do
|
21
|
+
Rails.should_not_receive(:logger)
|
22
|
+
ExecutorWithoutActsAsExecutor.log.should == @log
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#log" do
|
28
|
+
after(:each) { Executor.log = Logger.new }
|
29
|
+
|
30
|
+
it "should return log" do
|
31
|
+
log = Logger.new
|
32
|
+
Executor.log = log
|
33
|
+
|
34
|
+
Rails.should_not_receive(:logger)
|
35
|
+
Executor.log.should == log
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when log has not been set" do
|
39
|
+
it "should return Rails.logger" do
|
40
|
+
log = Logger.new
|
41
|
+
|
42
|
+
Executor.log = nil
|
43
|
+
|
44
|
+
Rails.should_receive(:logger).at_most(:twice).and_return log
|
45
|
+
Executor.log.should == Rails.logger
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActsAsExecutor::Executor::Model::InstanceMethods do
|
4
|
+
before(:each) { @model = Executor.make }
|
5
|
+
|
6
|
+
it { @model.should_not allow_public_access_for_methods :startup, :execute, :shutdown, :forced_shutdown }
|
7
|
+
|
8
|
+
describe "#startup" do
|
9
|
+
it "should create executor" do
|
10
|
+
@model.send(:executor).should be_nil
|
11
|
+
|
12
|
+
@model.send(:log).should_receive(:debug).with log_statement(@model.name, "startup triggered")
|
13
|
+
@model.send(:log).should_receive(:info).with log_statement(@model.name, "started")
|
14
|
+
|
15
|
+
@model.send :startup
|
16
|
+
|
17
|
+
@model.send(:executor).should_not be_nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#execute" do
|
22
|
+
before(:each) { @clazz = Clazz.make }
|
23
|
+
after(:each) { @model.send(:executor).shutdown }
|
24
|
+
|
25
|
+
it "should execute a task" do
|
26
|
+
@model.send :startup
|
27
|
+
|
28
|
+
@model.send(:log).should_receive(:debug).with log_message(@model.name, "preparing", 1.to_s, @clazz.class.name, "for execution (one time)")
|
29
|
+
@model.send(:log).should_receive(:info).with log_message(@model.name, "enqueued", 1.to_s, @clazz.class.name)
|
30
|
+
|
31
|
+
future = @model.send :execute, @clazz, 1.to_s
|
32
|
+
future.get
|
33
|
+
|
34
|
+
future.is_done.should be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should execute a one shot task" do
|
38
|
+
@model = Executor.make :max_tasks => 1, :schedulable => true
|
39
|
+
@model.send :startup
|
40
|
+
|
41
|
+
@model.send(:log).should_receive(:debug).with log_message(@model.name, "preparing", 1.to_s, @clazz.class.name, "for execution (one shot)")
|
42
|
+
@model.send(:log).should_receive(:info).with log_message(@model.name, "enqueued", 1.to_s, @clazz.class.name)
|
43
|
+
|
44
|
+
future = @model.send :execute, @clazz, 1.to_s, ActsAsExecutor::Task::Schedules::ONE_SHOT, 0, nil, ActsAsExecutor::Common::Units::SECONDS
|
45
|
+
future.get
|
46
|
+
|
47
|
+
future.is_done.should be_true
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should execute a fixed delay task" do
|
51
|
+
@model = Executor.make :max_tasks => 1, :schedulable => true
|
52
|
+
@model.send :startup
|
53
|
+
|
54
|
+
@model.send(:log).should_receive(:debug).with log_message(@model.name, "preparing", 1.to_s, @clazz.class.name, "for execution (fixed delay)")
|
55
|
+
@model.send(:log).should_receive(:info).with log_message(@model.name, "enqueued", 1.to_s, @clazz.class.name)
|
56
|
+
|
57
|
+
future = @model.send :execute, @clazz, 1.to_s, ActsAsExecutor::Task::Schedules::FIXED_DELAY, 0, 2, ActsAsExecutor::Common::Units::SECONDS
|
58
|
+
|
59
|
+
future.should_not be_nil
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should execute a fixed rate task" do
|
63
|
+
@model = Executor.make :max_tasks => 1, :schedulable => true
|
64
|
+
@model.send :startup
|
65
|
+
|
66
|
+
@model.send(:log).should_receive(:debug).with log_message(@model.name, "preparing", 1.to_s, @clazz.class.name, "for execution (fixed rate)")
|
67
|
+
@model.send(:log).should_receive(:info).with log_message(@model.name, "enqueued", 1.to_s, @clazz.class.name)
|
68
|
+
|
69
|
+
future = @model.send :execute, @clazz, 1.to_s, ActsAsExecutor::Task::Schedules::FIXED_RATE, 0, 2, ActsAsExecutor::Common::Units::SECONDS
|
70
|
+
|
71
|
+
future.should_not be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when rejected execution exception is thrown" do
|
75
|
+
it "should log exception" do
|
76
|
+
@model.send :startup
|
77
|
+
|
78
|
+
@model.send(:log).should_receive(:debug).with log_message(@model.name, "preparing", 1.to_s, @clazz.class.name, "for execution (one time)")
|
79
|
+
@model.send(:executor).should_receive(:execute).and_raise Java::java.util.concurrent.RejectedExecutionException.new
|
80
|
+
@model.send(:log).should_receive(:warn).with log_message(@model.name, "preparing", 1.to_s, @clazz.class.name, "encountered a rejected execution exception")
|
81
|
+
|
82
|
+
@model.send :execute, @clazz, 1.to_s
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when any other exception is thrown" do
|
87
|
+
it "should log exception" do
|
88
|
+
@model = Executor.make :max_tasks => 1, :schedulable => true
|
89
|
+
@model.send :startup
|
90
|
+
|
91
|
+
@model.send(:log).should_receive(:debug).with log_message(@model.name, "preparing", 1.to_s, @clazz.class.name, "for execution (one time)")
|
92
|
+
@model.send(:log).should_receive(:error).with log_message(@model.name, "preparing", 1.to_s, @clazz.class.name, "encountered an unexpected exception. java.lang.IllegalArgumentException: No enum const class java.util.concurrent.TimeUnit.RANDOM")
|
93
|
+
|
94
|
+
@model.send :execute, @clazz, 1.to_s, nil, nil, nil, "random"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#shutdown" do
|
100
|
+
before(:each) { @model.send :startup }
|
101
|
+
|
102
|
+
it "should shutdown executor" do
|
103
|
+
@model.send(:log).should_receive(:debug).with log_statement(@model.name, "shutdown triggered")
|
104
|
+
@model.send(:executor).should_receive :shutdown
|
105
|
+
@model.send(:log).should_receive(:info).with log_statement(@model.name, "shutdown")
|
106
|
+
|
107
|
+
@model.send :shutdown
|
108
|
+
|
109
|
+
@model.send(:executor).should be_nil
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when security exception is thrown" do
|
113
|
+
it "should force shutdown executor" do
|
114
|
+
@model.send(:log).should_receive(:debug).with log_statement(@model.name, "shutdown triggered")
|
115
|
+
@model.send(:executor).should_receive(:shutdown).and_raise Java::java.lang.SecurityException.new
|
116
|
+
@model.send(:log).should_receive(:warn).with log_statement(@model.name, "shutdown encountered a security exception")
|
117
|
+
@model.should_receive :forced_shutdown
|
118
|
+
|
119
|
+
@model.send :shutdown
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "#forced_shutdown" do
|
125
|
+
before(:each) { @model.send :startup }
|
126
|
+
|
127
|
+
it "should shutdown executor" do
|
128
|
+
@model.send(:log).should_receive(:debug).with log_statement(@model.name, "forced shutdown triggered")
|
129
|
+
@model.send(:executor).should_receive :shutdown_now
|
130
|
+
@model.send(:log).should_receive(:info).with log_statement(@model.name, "forced shutdown")
|
131
|
+
|
132
|
+
@model.send :forced_shutdown
|
133
|
+
|
134
|
+
@model.send(:executor).should be_nil
|
135
|
+
end
|
136
|
+
|
137
|
+
context "when security exception is thrown" do
|
138
|
+
it "should log exception" do
|
139
|
+
@model.send(:log).should_receive(:debug).with log_statement(@model.name, "forced shutdown triggered")
|
140
|
+
@model.send(:executor).should_receive(:shutdown_now).and_raise Java::java.lang.SecurityException.new
|
141
|
+
@model.send(:log).should_receive(:error).with log_statement(@model.name, "forced shutdown encountered a security exception")
|
142
|
+
@model.send(:log).should_receive(:fatal).with log_statement(@model.name, "forced shutdown failure")
|
143
|
+
|
144
|
+
@model.send :forced_shutdown
|
145
|
+
|
146
|
+
@model.send(:executor).should be_nil
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActsAsExecutor::Executor::Model::InstanceSupportMethods do
|
4
|
+
before(:each) { @model = Executor.make }
|
5
|
+
|
6
|
+
it { @model.should_not allow_public_access_for_methods :executor, :executor=, :startupable?, :shutdownable?, :log }
|
7
|
+
|
8
|
+
describe "#executor" do
|
9
|
+
it "should return executor" do
|
10
|
+
executor = double "Executor"
|
11
|
+
@model.send :executor=, executor
|
12
|
+
|
13
|
+
@model.send(:executor).should == executor
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when id has not been set" do
|
17
|
+
it "should raise an argument error" do
|
18
|
+
@model.id = nil
|
19
|
+
|
20
|
+
expect { @model.send :executor=, true }.to raise_error ArgumentError, "cannot reference executor against nil id"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#startupable?" do
|
26
|
+
context "when rails initialized" do
|
27
|
+
before(:each) { ActsAsExecutor.should_receive(:rails_initialized?).at_most(:once).and_return true }
|
28
|
+
|
29
|
+
context "when executor has not been set" do
|
30
|
+
it "should return true" do
|
31
|
+
@model.should be_startupable
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when executor has been set" do
|
36
|
+
it "should return false" do
|
37
|
+
@model.send :startup
|
38
|
+
|
39
|
+
@model.should_not be_startupable
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#shutdownable?" do
|
46
|
+
context "when rails initialized" do
|
47
|
+
before(:each) { ActsAsExecutor.should_receive(:rails_initialized?).at_most(:once).and_return true }
|
48
|
+
|
49
|
+
context "when executor has been set" do
|
50
|
+
it "should return true" do
|
51
|
+
@model.send :startup
|
52
|
+
|
53
|
+
@model.should be_shutdownable
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when executor has not been set" do
|
58
|
+
it "should return false" do
|
59
|
+
@model.should_not be_shutdownable
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#log" do
|
66
|
+
it "should return class log" do
|
67
|
+
@model.send(:log).should == Executor.log
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|