updater 0.9.4 → 0.10.0

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/spec/fooclass.rb CHANGED
@@ -1,18 +1,49 @@
1
-
2
- class Foo
3
- include DataMapper::Resource
1
+ class Foo
2
+ class << self
3
+ def index
4
+ @index ||= 0
5
+ @index += 1
6
+ end
7
+
8
+ def create(*args)
9
+ new(*args).tap {|r| r.save}
10
+ end
4
11
 
5
- property :id, Serial
6
- property :name, String
12
+ def storage
13
+ @storage ||= {}
14
+ end
15
+
16
+ def find(id)
17
+ storage[id]
18
+ end
7
19
 
8
- def bar(*args)
9
- Foo.bar(:instance,*args)
20
+ def reset
21
+ @storage = {}
10
22
  end
11
23
 
12
- def self.bar(*args)
13
-
24
+ def count
25
+ storage.length
14
26
  end
15
27
 
16
28
  end
17
-
18
- Foo.auto_migrate!
29
+ attr_reader :id
30
+ attr_accessor :name
31
+
32
+ def bar(*args)
33
+ Foo.bar(:instance,*args)
34
+ end
35
+
36
+ def self.bar(*args)
37
+
38
+ end
39
+
40
+ def initialize(hash = {})
41
+ @id = Foo.index
42
+ @name = hash[:name]
43
+ end
44
+
45
+ def save
46
+ Foo.storage[self.id] = self
47
+ end
48
+
49
+ end
@@ -0,0 +1,38 @@
1
+ require File.join( File.dirname(__FILE__), "spec_helper" )
2
+
3
+ describe Foo do
4
+ before :each do
5
+ Foo.reset
6
+ end
7
+
8
+ it "should have an unique index function" do
9
+ i1 = Foo.index
10
+ i2 = Foo.index
11
+ i1.should_not be_nil
12
+ i2.should_not be_nil
13
+ i1.should_not == i2
14
+ end
15
+
16
+ it "should instantiate a new instance with an id" do
17
+ foo = Foo.new
18
+ foo.id.should_not be_nil
19
+ end
20
+
21
+ it "should create saved instances" do
22
+ foo = Foo.create
23
+ Foo.find(foo.id).should be(foo)
24
+ end
25
+
26
+ it "should have a name I can set" do
27
+ foo = Foo.create(:name=>'bar')
28
+ foo.name.should == 'bar'
29
+ foo.name = 'baz'
30
+ foo.name.should == 'baz'
31
+ end
32
+
33
+ it "should have a count" do
34
+ Foo.count.should == 0
35
+ foo = Foo.create(:name=>'bar')
36
+ Foo.count.should == 1
37
+ end
38
+ end
@@ -34,23 +34,4 @@ describe "Fork Worker Instance" do
34
34
 
35
35
  end
36
36
 
37
- describe "#wait_for" do
38
-
39
- it "should have specs"
40
-
41
- describe "when there are pending jobs" do
42
-
43
- it "should NOT wait for a signal"
44
-
45
- it "should smoke the pipe"
46
-
47
- end
48
-
49
- it "should wake as soon as a new job signal is placed on the pipe"
50
-
51
-
52
- it "should run the heartbeat every 'timeout' seconds"
53
-
54
- end
55
-
56
37
  end
@@ -175,6 +175,7 @@ describe ForkWorker do
175
175
 
176
176
  it "should do maintance when the queue is empty" do
177
177
  ForkWorker.should_receive(:murder_lazy_workers)
178
+ ForkWorker.should_receive(:antisipate_workload)
178
179
  ForkWorker.should_receive(:maintain_worker_count)
179
180
  ForkWorker.should_receive(:master_sleep)
180
181
 
@@ -0,0 +1,7 @@
1
+ require File.join( File.dirname(__FILE__), "spec_helper" )
2
+ require 'updater/orm/mock'
3
+
4
+ describe Updater::ORM::Mock do
5
+ it_behaves_like "an orm"
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ require File.join( File.dirname(__FILE__), "spec_helper" )
2
+ require 'updater/orm/mongo'
3
+
4
+ describe Updater::ORM::Mongo do
5
+ it_behaves_like "an orm", :database=>'test'
6
+
7
+ end
@@ -2,12 +2,10 @@ require File.join( File.dirname(__FILE__), "spec_helper" )
2
2
 
3
3
  include Updater
4
4
 
5
- require File.join( File.dirname(__FILE__), "fooclass" )
6
-
7
5
  describe "named request" do
8
6
 
9
7
  before(:each) do
10
- Foo.all.destroy!
8
+ Foo.reset
11
9
  Update.clear_all
12
10
  end
13
11
 
@@ -34,7 +32,6 @@ describe "named request" do
34
32
  it "should not include locked updates" do
35
33
  u = Update.immidiate(Foo,:bar,[:named],:name=>'Now')
36
34
  u.orm.lock(Struct.new(:name).new('test_worker'))
37
- u.orm.should be_locked
38
35
  Update.for(Foo).should_not include(u)
39
36
  Update.for(Foo).should be_empty
40
37
  end
data/spec/orm_lint.rb ADDED
@@ -0,0 +1,292 @@
1
+ shared_examples_for "an orm" do |test_setup|
2
+
3
+ before :each do
4
+ @target = Foo.create
5
+ @opts = {
6
+ :time =>Updater::Update.time.now.to_i,
7
+ :target=>Foo, :finder=>'find', :finder_args=>[@target.id],
8
+ :method=>'bar', :method_args=>['baz'],
9
+ :persistant=>false
10
+ }
11
+ end
12
+
13
+ let(:instance) { described_class.create(@opts) }
14
+ let(:delayed) { described_class.create(@opts.merge(:time =>Updater::Update.time.now.to_i + 25000)) }
15
+ ["","1","2","3"].each do |c|
16
+ let("chained#{c}".to_sym) { Updater::Update.new(described_class.create(@opts.merge(:time =>nil, :persistant=>true))) }
17
+ end
18
+ %w{tom dick harry}.each do |name|
19
+ let("#{name}_job".to_sym) { Updater::Update.new(described_class.create(@opts.merge(:name=>name))) }
20
+ end
21
+
22
+ before :all do
23
+ test_setup ||= {}
24
+ test_setup[:logger] ||= Logger.new(STDOUT).tap {|l| l.level = 99}
25
+ described_class.setup(test_setup)
26
+ @old_orm = Updater::Update.orm
27
+ Updater::Update.orm = described_class
28
+ end
29
+
30
+ after :all do
31
+ Updater::Update.orm = @old_orm
32
+ end
33
+
34
+ #Class Methods
35
+ describe "class methods" do
36
+ %w{get create current current_load delayed future queue_time lock_next clear_locks
37
+ clear_all setup for logger logger=}.each do |m|
38
+ it "should have a class method: #{m}" do
39
+ described_class.should respond_to(m)
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "instance methods" do
45
+ %w{id time time= target target= finder finder= finder_args finder_args=
46
+ method method= method_args method_args= name name= persistant persistant=
47
+ save destroy lock}.each do |m|
48
+ it "should have an instance method: #{m}" do
49
+ instance.should respond_to(m)
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "constants" do
55
+ %w{FINDER ID}.each do |c|
56
+ it "should have a constant: #{c}" do
57
+ described_class.const_get(c).should be_kind_of Symbol
58
+ end
59
+ end
60
+ end
61
+
62
+
63
+
64
+ describe "clear_all" do
65
+ it "should remove all jobs" do
66
+ described_class.clear_all
67
+ (described_class.current_load + described_class.delayed).should == 0
68
+ end
69
+ end
70
+
71
+ describe "an instance" do
72
+ before :each do
73
+ described_class.clear_all
74
+ instance
75
+ end
76
+
77
+ it "should have an id" do
78
+ instance.id.should_not be_nil
79
+ end
80
+
81
+ describe "getters" do
82
+ %w{time finder finder_args method method_args target persistant}.each do |m|
83
+ specify "#{m} should be set to the correct value" do
84
+ instance.send(m.to_s).should == @opts[m.to_sym]
85
+ end
86
+ end
87
+ end
88
+
89
+ it "should be in the current list" do
90
+ described_class.current.should include(instance)
91
+ described_class.current_load.should == 1
92
+ end
93
+
94
+ it "should be retrieved with 'get'" do
95
+ described_class.get(instance.id).should == instance
96
+ end
97
+
98
+ it "should be removed with 'destroy'" do
99
+ instance.destroy
100
+ described_class.get(instance.id).should be_nil
101
+ described_class.current_load.should == 0
102
+ end
103
+
104
+ end
105
+
106
+ describe "locking" do
107
+ before :each do
108
+ @worker1 = Struct.new(:name).new('foo')
109
+ @worker2 = Struct.new(:name).new('bar')
110
+ @worker1.stub(:say)
111
+ @worker2.stub(:say)
112
+ end
113
+
114
+ it "an instance should lock" do
115
+ instance.lock(@worker1).should be_true
116
+ end
117
+
118
+ it "an instance should lock again with the same worker" do
119
+ instance.lock(@worker1).should be_true
120
+ instance.lock(@worker1).should be_true
121
+ end
122
+
123
+ it "an instance should lock if it has been locked" do
124
+ instance.lock(@worker1).should be_true
125
+ instance.lock(@worker2).should be_false
126
+ end
127
+ end
128
+
129
+ describe "lock_next" do
130
+ before :each do
131
+ described_class.clear_all
132
+ @worker1 = Struct.new(:name).new('foo')
133
+ @worker2 = Struct.new(:name).new('bar')
134
+ @worker1.stub(:say)
135
+ @worker2.stub(:say)
136
+ end
137
+
138
+ it "should return the next current instance locked to the worker" do
139
+ instance
140
+ job = described_class.lock_next(@worker1)
141
+ job.should == instance
142
+ job.lock(@worker2).should be_false
143
+ end
144
+
145
+ it "should return nil if there are no current jobs without a lock" do
146
+ described_class.lock_next(@worker1).should be_nil
147
+ delayed
148
+ described_class.lock_next(@worker1).should be_nil
149
+ instance.lock(@worker2)
150
+ described_class.lock_next(@worker1).should be_nil
151
+ end
152
+
153
+ end
154
+
155
+ describe "clear locks" do
156
+ before :each do
157
+ described_class.clear_all
158
+ @worker1 = Struct.new(:name).new('foo')
159
+ @worker2 = Struct.new(:name).new('bar')
160
+ @worker1.stub(:say)
161
+ @worker2.stub(:say)
162
+ end
163
+
164
+ it "should clear every lock held by a worker" do
165
+ instance.lock(@worker1)
166
+ described_class.clear_locks(@worker1)
167
+ instance.lock(@worker2).should be_true
168
+ end
169
+ end
170
+
171
+ describe "queue_time" do
172
+ before :each do
173
+ described_class.clear_all
174
+ end
175
+
176
+ it "should be nil if the queue is empty" do
177
+ described_class.queue_time.should be_nil
178
+ end
179
+
180
+ it "should be 0 if there is a current job" do
181
+ instance
182
+ described_class.queue_time.should == 0
183
+ end
184
+
185
+ it "should be the time to the next job" do
186
+ Timecop.freeze do
187
+ delayed
188
+ described_class.queue_time.should == 25000
189
+ end
190
+ end
191
+ end
192
+
193
+ describe "with method chaining:" do
194
+ before :each do
195
+ described_class.clear_all
196
+ end
197
+
198
+ %w{success failure ensure}.each do |mode|
199
+ describe mode do
200
+ it "should initially be empty" do
201
+ instance.send(mode).should be_empty
202
+ end
203
+ end
204
+ describe "#{mode}=" do
205
+ it "should add an Update instance" do
206
+ instance.send("#{mode}=", chained).should == chained
207
+ instance.send(mode).should_not be_empty
208
+ instance.send(mode).should include chained
209
+ end
210
+
211
+ it "should add a #{described_class.to_s} instance" do
212
+ instance.send("#{mode}=", chained.orm).should == chained.orm
213
+ instance.send(mode).should_not be_empty
214
+ instance.send(mode).map{|x| x.orm}.should include chained.orm
215
+ end
216
+
217
+ it "should add an id" do
218
+ instance.send("#{mode}=", chained.id).should == chained.id
219
+ instance.send(mode).should_not be_empty
220
+ instance.send(mode).should include chained
221
+ end
222
+
223
+ it "should add multiple items from an array" do
224
+ instance.send("#{mode}=", [chained,chained1,chained2])
225
+ instance.send(mode).length.should == 3
226
+ instance.send(mode).should == [chained,chained1,chained2]
227
+ end
228
+
229
+ specify "nested arrays should set param" do
230
+ instance.send("#{mode}=", [chained,[chained1, :foo],chained2])
231
+ puts "%s (%s:%s)" % [instance.send(mode),__FILE__,__LINE__] if instance.send(mode)[1].nil?
232
+ instance.send(mode)[1].params.should == :foo
233
+ end
234
+
235
+ it "should add multiple items from a hash" do
236
+ instance.send("#{mode}=", {chained=>:foo,chained1=>:bar,chained2=>:baz})
237
+ instance.send(mode).length.should == 3
238
+ instance.send(mode).should == [chained,chained1,chained2]
239
+ end
240
+
241
+ it "should set the parameters from a hash" do
242
+ instance.send("#{mode}=", {chained=>:foo})
243
+ instance.send(mode)[0].params.should == :foo
244
+ end
245
+
246
+ it "should clear the chain with nil" do
247
+ instance.send("#{mode}=", [chained,chained1,chained2])
248
+ instance.send(mode).length.should == 3
249
+ instance.send("#{mode}=", nil).should be_nil
250
+ instance.send(mode).length.should == 0
251
+ end
252
+
253
+ it "should NOT be a destructive assignment" do
254
+ instance.send("#{mode}=", [chained,chained1,chained2])
255
+ instance.send(mode).length.should == 3
256
+ instance.send("#{mode}=", {chained3=>:foo})
257
+ instance.send(mode).length.should == 4
258
+ instance.send(mode)[3].should == chained3
259
+ end
260
+
261
+ end # mode=
262
+ end # {success, failure, ensure}
263
+ end #chaining
264
+
265
+ describe " #for" do
266
+ before :each do
267
+ described_class.clear_all
268
+ tom_job; dick_job; harry_job
269
+ end
270
+
271
+ it "should find all jobs" do
272
+ described_class.for(@target.class, @opts[:finder], [@target.id]).should include(tom_job.orm, dick_job.orm, harry_job.orm)
273
+ end
274
+
275
+ it "should find a job by name" do
276
+ described_class.for(@target.class, @opts[:finder], [@target.id], "dick").first.should == dick_job.orm
277
+ end
278
+
279
+ it "should return an empty array if no job is found" do
280
+ foo = Foo.create
281
+ described_class.for(@target.class, @opts[:finder], [@target.id], "john").should be_empty
282
+ described_class.for(@target.class, @opts[:finder], [foo.id]).should be_empty
283
+ end
284
+
285
+ it "should not return a locked record" do
286
+ described_class.for(@target.class, @opts[:finder], [@target.id]).should include(tom_job.orm, dick_job.orm, harry_job.orm)
287
+ tom_job.orm.lock(Struct.new(:name).new('test_worker'))
288
+ described_class.for(@target.class, @opts[:finder], [@target.id]).should_not include(tom_job.orm)
289
+ end
290
+
291
+ end #for
292
+ end
@@ -17,7 +17,8 @@ describe "Special Parameter Substitution" do
17
17
 
18
18
  it "should substitute __params__ with params" do
19
19
  Foo.should_receive(:chained).with(anything(),:arg2,anything(), 'job params')
20
- @u.run(:arg1,:arg2)
20
+ @u.params = :arg2
21
+ @u.run(:arg1)
21
22
  end
22
23
 
23
24
  it "should substitute __self__ with the current job" do