lucid_works 0.7.18 → 0.9.4

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.
Files changed (68) hide show
  1. data/.rvmrc +2 -3
  2. data/Gemfile +2 -8
  3. data/Gemfile.lock +45 -53
  4. data/README.rdoc +2 -6
  5. data/Rakefile +1 -1
  6. data/config/locales/en.yml +221 -239
  7. data/lib/lucid_works/activity.rb +8 -5
  8. data/lib/lucid_works/base.rb +27 -16
  9. data/lib/lucid_works/cache.rb +13 -0
  10. data/lib/lucid_works/cluster.rb +84 -0
  11. data/lib/lucid_works/collection/settings.rb +15 -6
  12. data/lib/lucid_works/collection.rb +62 -92
  13. data/lib/lucid_works/datasource/history.rb +2 -1
  14. data/lib/lucid_works/datasource/mapping.rb +12 -0
  15. data/lib/lucid_works/datasource/schedule.rb +5 -2
  16. data/lib/lucid_works/datasource/status.rb +3 -2
  17. data/lib/lucid_works/datasource.rb +31 -48
  18. data/lib/lucid_works/datasource_property.rb +2 -1
  19. data/lib/lucid_works/datasource_type.rb +14 -0
  20. data/lib/lucid_works/dynamicfield.rb +12 -0
  21. data/lib/lucid_works/elevation.rb +93 -0
  22. data/lib/lucid_works/exceptions.rb +0 -4
  23. data/lib/lucid_works/field.rb +31 -111
  24. data/lib/lucid_works/field_commons.rb +133 -0
  25. data/lib/lucid_works/gem_version.rb +1 -1
  26. data/lib/lucid_works/inflections.rb +3 -0
  27. data/lib/lucid_works/patch_time.rb +4 -0
  28. data/lib/lucid_works/request_handler.rb +16 -0
  29. data/lib/lucid_works/role.rb +23 -8
  30. data/lib/lucid_works/schema/attribute.rb +1 -1
  31. data/lib/lucid_works/schema/boolean_attribute.rb +1 -1
  32. data/lib/lucid_works/schema/integer_attribute.rb +3 -4
  33. data/lib/lucid_works/server/crawlers_status.rb +15 -0
  34. data/lib/lucid_works/server.rb +35 -14
  35. data/lib/lucid_works/simple_naming.rb +1 -7
  36. data/lib/lucid_works/synonym.rb +1 -1
  37. data/lib/lucid_works/version.rb +1 -0
  38. data/lib/lucid_works.rb +8 -1
  39. data/lucid_works.gemspec +8 -9
  40. data/spec/fixtures/zookeeper/clusterstate.json +30 -0
  41. data/spec/fixtures/zookeeper/clusterstate_broken_shard.json +29 -0
  42. data/spec/fixtures/zookeeper/live_nodes.json +28 -0
  43. data/spec/fixtures/zookeeper/live_nodes_no_children.json +26 -0
  44. data/spec/fixtures/zookeeper/live_nodes_one_child.json +36 -0
  45. data/spec/lib/lucid_works/base_spec.rb +33 -24
  46. data/spec/lib/lucid_works/cache_spec.rb +44 -0
  47. data/spec/lib/lucid_works/cluster_spec.rb +109 -0
  48. data/spec/lib/lucid_works/collection/activity_spec.rb +29 -0
  49. data/spec/lib/lucid_works/collection/prime_activities_spec.rb +1 -1
  50. data/spec/lib/lucid_works/collection/settings_spec.rb +31 -0
  51. data/spec/lib/lucid_works/collection_spec.rb +166 -107
  52. data/spec/lib/lucid_works/datasource/schedule_spec.rb +75 -46
  53. data/spec/lib/lucid_works/datasource/status_spec.rb +5 -5
  54. data/spec/lib/lucid_works/datasource_property_spec.rb +41 -0
  55. data/spec/lib/lucid_works/datasource_spec.rb +40 -12
  56. data/spec/lib/lucid_works/datasource_type_spec.rb +31 -0
  57. data/spec/lib/lucid_works/dynamicfield_spec.rb +214 -0
  58. data/spec/lib/lucid_works/elevation_spec.rb +175 -0
  59. data/spec/lib/lucid_works/field_spec.rb +52 -21
  60. data/spec/lib/lucid_works/fieldtype_spec.rb +0 -1
  61. data/spec/lib/lucid_works/request_handler_spec.rb +11 -0
  62. data/spec/lib/lucid_works/role_spec.rb +77 -0
  63. data/spec/lib/lucid_works/server/crawlers_status_spec.rb +21 -0
  64. data/spec/lib/lucid_works/server_spec.rb +123 -22
  65. data/spec/lib/lucid_works/{collection/synonym_spec.rb → synonym_spec.rb} +23 -22
  66. data/spec/lib/lucid_works/version_spec.rb +6 -0
  67. metadata +132 -64
  68. data/spec/lib/lucid_works/collection/acl_config_spec.rb +0 -212
@@ -6,6 +6,8 @@ describe LucidWorks::Collection do
6
6
  @server.reset_collections!
7
7
  end
8
8
 
9
+ let(:collection) { @server.collections.first }
10
+
9
11
  describe "CRUD" do
10
12
  before do
11
13
  @collection_name = "a_new_collection"
@@ -17,6 +19,23 @@ describe LucidWorks::Collection do
17
19
  LucidWorks::Collection.all(:parent => @server).size
18
20
  end
19
21
 
22
+ describe "validations" do
23
+ it "requires 'num_shards' to be a positive integer" do
24
+ ['abc', 1.2, 0].each do |invalid_value|
25
+ resource = LucidWorks::Collection.new({:parent => @server, :num_shards => invalid_value})
26
+ resource.should_not be_valid
27
+ resource.errors[:num_shards].should == ["is not a valid value"]
28
+ end
29
+ end
30
+
31
+ it "requires 'num_shards' to be present when running in clustered mode" do
32
+ @server.stub(:clustered?) { true }
33
+ resource = LucidWorks::Collection.new({:parent => @server})
34
+ resource.should_not be_valid
35
+ resource.errors[:num_shards].should == ["can't be blank"]
36
+ end
37
+ end
38
+
20
39
  describe ".create" do
21
40
  context "with ideal circumstances" do
22
41
  it "should create a new collection with the appropriate parameters" do
@@ -72,26 +91,6 @@ describe LucidWorks::Collection do
72
91
  #end
73
92
  end
74
93
 
75
- describe ".find" do
76
- context "for a nonexistant collection" do
77
- it "should raise an exception" do
78
- lambda {
79
- LucidWorks::Collection.find('nonexistant_collection', :parent => @server)
80
- }.should raise_error(RestClient::ResourceNotFound)
81
- end
82
- end
83
-
84
- context "for an extant collection" do
85
- it "should return the collection" do
86
- c = LucidWorks::Collection.find(@collection_name, :parent => @server)
87
- c.should be_kind_of(LucidWorks::Collection)
88
- c.name.should == @collection_name
89
- c.instance_dir.should == @instance_dir
90
- c.should be_persisted
91
- end
92
- end
93
- end
94
-
95
94
  describe "#destroy" do
96
95
  it "should delete the collection" do
97
96
  c = @server.collection(@collection_name)
@@ -101,7 +100,7 @@ describe LucidWorks::Collection do
101
100
  end
102
101
  end
103
102
  end
104
-
103
+
105
104
  describe "#activities" do
106
105
  before do
107
106
  @collection = @server.collection('collection1')
@@ -136,13 +135,6 @@ describe LucidWorks::Collection do
136
135
  describe "#prime_activities" do
137
136
  before do
138
137
  @collection = @server.collection('collection1')
139
- # require 'ruby-debug'; debugger
140
- # activity = LucidWorks::Activity.create(
141
- # :type => 'optimize',
142
- # :start_time => 8600,
143
- # :collection => @collection
144
- # )
145
- # activity.should be_persisted
146
138
  end
147
139
 
148
140
  it "should not create activities that already exist" do
@@ -204,7 +196,7 @@ describe LucidWorks::Collection do
204
196
  @collection.synonyms.first.mapping.should == "lawyer, attorney"
205
197
  end
206
198
 
207
- it "associates each synonym to the collection" do
199
+ it "associates each synonym with the collection" do
208
200
  @collection.synonyms.first.collection.should be(@collection)
209
201
  end
210
202
 
@@ -214,6 +206,33 @@ describe LucidWorks::Collection do
214
206
  end
215
207
  end
216
208
 
209
+ describe "#elevations" do
210
+ before do
211
+ @collection = @server.collection('collection1')
212
+ @collection.settings.elevations = {
213
+ 'jeans' => [{'doc' => 'http://mystore.com/products/1', 'exclude' => 'true'}, {'doc' => 'http://mystore.com/products/2'}],
214
+ 'shirts' => [{'doc' => 'http://mystore.com/products/3'}]
215
+ }
216
+ @collection.settings.save
217
+ end
218
+
219
+ it "returns a list of elevations" do
220
+ @collection.should have(3).elevations
221
+ end
222
+
223
+ it "sets the elevations' attributes" do
224
+ elevation = @collection.elevations.first
225
+ elevation.query.should == 'jeans'
226
+ elevation.doc_id.should == 'http://mystore.com/products/1'
227
+ elevation.persisted?.should be_true
228
+ elevation.excluded?.should be_true
229
+ end
230
+
231
+ it "associates each elevation with the collection" do
232
+ @collection.elevations.first.collection.should be(@collection)
233
+ end
234
+ end
235
+
217
236
  describe "#info" do
218
237
  before :all do
219
238
  @collection = LucidWorks::Collection.first(:parent => @server)
@@ -256,7 +275,7 @@ describe LucidWorks::Collection do
256
275
  @collection.should be_valid
257
276
  @ds1 = LucidWorks::Datasource.create(
258
277
  :collection => @collection,
259
- :crawler => LucidWorks::Datasource::CRAWLERS['file'],
278
+ :crawler => 'lucid.aperture',
260
279
  :type => "file",
261
280
  :name => "US zoneinfo",
262
281
  :path => "/usr/share/zoneinfo/US",
@@ -265,7 +284,7 @@ describe LucidWorks::Collection do
265
284
  @ds1.should be_valid
266
285
  @ds2 = LucidWorks::Datasource.create(
267
286
  :collection => @collection,
268
- :crawler => LucidWorks::Datasource::CRAWLERS['web'],
287
+ :crawler => 'lucid.aperture',
269
288
  :type => 'web',
270
289
  :name => "nothing_com",
271
290
  :url => "http://nothing.com/",
@@ -359,110 +378,150 @@ describe LucidWorks::Collection do
359
378
  end
360
379
  end
361
380
 
362
- describe "#rsolr" do
363
- before :each do
381
+ describe "#search" do
382
+ def mock_solr_result
383
+ @mock_solr_result ||= mock('solr_result', :request => {:uri => 'some_uri'}, :response => {:status => 200})
384
+ end
385
+
386
+ before do
364
387
  @collection = LucidWorks::Collection.new(:name => "collection_to_search", :parent => @server)
365
- mock_server = double('server', :host => 'fake_url')
388
+ mock_server = double('server', :server_uri => 'http://fake-solr-host.com')
366
389
  @collection.stub(:server) { mock_server }
390
+ @mock_rsolr_client = double("RSolr::Client").as_null_object
391
+ RSolr.stub(:connect) { @mock_rsolr_client }
392
+ @mock_rsolr_client.stub(:get) { mock_solr_result }
367
393
  end
368
394
 
369
- it "should call RSolr.connect" do
370
- RSolr.should_receive(:connect).with(:url => 'fake_url')
371
- @collection.rsolr
395
+ it "opens a connection pointing to the proper server and collection" do
396
+ RSolr.should_receive(:connect).with(:url => 'http://fake-solr-host.com/solr/collection_to_search')
397
+ @collection.search(:some => :solr_params)
372
398
  end
373
399
 
374
- it "should return an RSolr::Client" do
375
- @collection.rsolr.should be_a(RSolr::Client)
400
+ it "caches the connection" do
401
+ RSolr.should_receive(:connect).once
402
+ @collection.search(:some => :solr_params)
403
+ @collection.search(:some => :solr_other_params)
376
404
  end
377
405
 
378
- it "should not call RSolr.connect again if it is called again" do
379
- mock_rsolr_client = double("RSolr::Client")
380
- RSolr.should_receive(:connect).once.and_return(mock_rsolr_client)
381
- @collection.rsolr
382
- @collection.rsolr
406
+ it "delegates to RSolr#get to perform the search" do
407
+ @mock_rsolr_client.should_receive(:get).
408
+ with('select', :params => {:some => :solr_params}).and_return(mock_solr_result)
409
+ @collection.search(:some => :solr_params)
383
410
  end
384
- end
385
-
386
- describe "#search" do
387
- context "using faked out Solr" do
388
- before do
389
- @collection = LucidWorks::Collection.new(:name => "collection_to_search", :parent => @server)
390
- mock_server = double('server', :host => 'http://fake-solr-host.com/fake_access_path')
391
- @collection.stub(:server) { mock_server }
392
- @mock_rsolr_client = double("RSolr::Client")
393
- RSolr::Ext.stub(:connect) { @mock_rsolr_client }
411
+
412
+ context "with pagination options" do
413
+ it "delegates to RSolr#paginate" do
414
+ @mock_rsolr_client.should_receive(:paginate).
415
+ with(33, 44, 'select', :params => {:some => :solr_params}).and_return(mock_solr_result)
416
+ @collection.search({:some => :solr_params}, {:page => 33, :per_page => 44})
394
417
  end
418
+ end
419
+ end
395
420
 
396
- it "should pass thru pagination variables" do
397
- @mock_rsolr_client.should_receive(:find).
398
- with('/fake_access_path/solr/collection_to_search/select', :q => 'fake_query', :wt => :ruby, :page => 33, :per_page => 44).
399
- and_return({})
421
+ describe "#fields" do
422
+ it "should return a valid LucidWorks::Field" do
423
+ collection.should respond_to(:field)
424
+ field = collection.field('body')
425
+ field.should be_a(LucidWorks::Field)
426
+ end
427
+ end
400
428
 
401
- @collection.search(:q => 'fake_query', :wt => :ruby, :page => 33, :per_page => 44)
402
- end
429
+ describe "#dynamic_fields" do
430
+ it "should return a valid LucidWorks::DynamicField" do
431
+ collection.should respond_to(:dynamicfield)
432
+ field = collection.dynamicfield('*_t')
433
+ field.should be_a(LucidWorks::Dynamicfield)
434
+ end
435
+ end
403
436
 
404
- context "when requesting an XML response" do
405
- before do
406
- @good_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<response>FooBar</response>\n</xml>"
407
- end
437
+ describe "#caches" do
438
+ it "returns all caches" do
439
+ collection.should have(4).caches
440
+ end
441
+ end
408
442
 
409
- it "should call RSolr.get to perform the search" do
410
- @mock_rsolr_client.should_receive(:find).
411
- with('/fake_access_path/solr/collection_to_search/select', :q => 'fake_query', :wt => :xml, :page => 1, :per_page => 10).
412
- and_return(@good_xml)
443
+ describe "#update_caches_attributes" do
444
+ before(:each) do
445
+ %w(document_cache filter_cache).each do |cache_name|
446
+ collection.cache(cache_name).update_attributes(:size => '512', :autowarm_count => '') # reset attributes used in nested examples
447
+ end
448
+ end
449
+
450
+ context "with valid attributes" do
451
+ it "updates the requested caches" do
452
+ collection.update_caches_attributes('document_cache' => {'size' => '1024'}, 'filter_cache' => {'size' => '2048'})
453
+ collection.cache('document_cache').size.should == '1024'
454
+ collection.cache('filter_cache').size.should == '2048'
455
+ end
456
+
457
+ it "returns true" do
458
+ collection.update_caches_attributes('document_cache' => {'size' => '1024'}, 'filter_cache' => {'size' => '2048'}).should be_true
459
+ end
460
+ end
413
461
 
414
- @collection.search(:q => 'fake_query', :wt => :xml)
462
+ context "with invalid attributes" do
463
+ context "triggering validation errors" do
464
+ let(:invalid_params) { {'document_cache' => {'size' => '1024'}, 'filter_cache' => {'size' => ''}} }
465
+
466
+ it "doesn't update any of the requested caches" do
467
+ collection.update_caches_attributes(invalid_params)
468
+ collection.cache('document_cache').size.should == '512'
469
+ collection.cache('filter_cache').size.should == '512'
415
470
  end
416
-
417
- it "should parse the XML results" do
418
- @mock_rsolr_client.stub(:find) { @good_xml }
419
- results = @collection.search(:q => 'fake_query', :wt => :xml)
420
- results.should be_a(Nokogiri::XML::Document)
421
- results.root.children.first.text.should == "FooBar"
471
+
472
+ it "reports errors" do
473
+ collection.update_caches_attributes(invalid_params)
474
+ filter_cache = collection.caches.detect {|cache| cache.name == 'filter_cache' } # don't reload the caches
475
+ filter_cache.errors.should_not be_empty
422
476
  end
423
477
 
424
- context "when the search returns invalid XML" do
425
- before do
426
- @mock_rsolr_client.stub(:get) { "this is not xml" }
427
- end
428
-
429
- it "should raise an error" do
430
- lambda {
431
- @collection.search(:wt => :xml)
432
- }.should raise_error
433
- end
478
+ it "returns false" do
479
+ collection.update_caches_attributes(invalid_params).should be_false
434
480
  end
435
481
  end
436
- end
437
-
438
- context "when using a live collection" do
439
- before do
440
- @collection = @server.collections.first
441
- end
442
-
443
- describe "when given a bad search" do
444
- before do
445
- @query_params = { :defType => 'lucene', :q => 'datefield:[FOO' }
482
+
483
+ context "triggering API errors" do
484
+ let(:invalid_params) { {'filter_cache' => {'autowarm_count' => 'abc'}} }
485
+
486
+ it "reports errors" do
487
+ collection.update_caches_attributes(invalid_params)
488
+ filter_cache = collection.caches.detect {|cache| cache.name == 'filter_cache' } # don't reload the caches
489
+ filter_cache.errors.should_not be_empty
446
490
  end
447
491
 
448
- it "should raise an error (until I decide what the right answer is)" do
449
- lambda {
450
- @collection.search @query_params
451
- }.should raise_error
492
+ it "returns false" do
493
+ collection.update_caches_attributes(invalid_params).should be_false
452
494
  end
453
495
  end
454
496
  end
455
497
  end
498
+
499
+ describe "#available_templates" do
500
+ it "returns all templates" do
501
+ collection.available_templates.should == ["default.zip","essential.zip"]
502
+ end
503
+ end
504
+
505
+ describe "#commit" do
506
+ def mock_rsolr_client
507
+ @mock_rsolr_client ||= double("RSolr::Client")
508
+ end
456
509
 
457
- describe "#fields" do
458
- before do
459
- @collection = @server.collections.first
510
+ before(:each) do
511
+ RSolr.stub(:connect) { @mock_rsolr_client }
460
512
  end
461
- it "should return a valid LucidWorks::Field" do
462
- @collection.should respond_to(:field)
463
- field = @collection.field('body')
464
- field.should be_a(LucidWorks::Field)
465
- field.should respond_to(:field_type)
513
+
514
+ it "delegates to RSolr" do
515
+ mock_rsolr_client.should_receive(:commit)
516
+ collection.commit
517
+ end
518
+ end
519
+
520
+ describe "#request_handler" do
521
+ it "returns the requested request handler" do
522
+ request_handler = collection.request_handler('lucid')
523
+ request_handler.should be_a(LucidWorks::RequestHandler)
524
+ request_handler.name.should == "lucid"
466
525
  end
467
526
  end
468
527
  end
@@ -29,6 +29,17 @@ describe LucidWorks::Datasource::Schedule do
29
29
  end
30
30
 
31
31
  describe '#frequency' do
32
+ it "assumes an 'every' frequency when period ranges from 1 to 59 minutes" do
33
+ @schedule.period = 0
34
+ @schedule.frequency.should_not == 'every'
35
+ @schedule.period = 1 * 60
36
+ @schedule.frequency.should == 'every'
37
+ @schedule.period = 59 * 60
38
+ @schedule.frequency.should == 'every'
39
+ @schedule.period = 60 * 60
40
+ @schedule.frequency.should_not == 'every'
41
+ end
42
+
32
43
  it "should return 'weekly' when period == num of seconds in a week" do
33
44
  @schedule.period = 604800
34
45
  @schedule.frequency.should == 'weekly'
@@ -70,7 +81,7 @@ describe LucidWorks::Datasource::Schedule do
70
81
  # Time objects are precise to the millisecond
71
82
  # we cheat by converting to string, which is only accurate to the second
72
83
  # but if these test are run on a second boundary, they might wrongly fail
73
- #
84
+ #
74
85
  context 'start_time is in the past' do
75
86
  before do
76
87
  @now = Time.iso8601(Time.now.utc.iso8601)
@@ -89,7 +100,7 @@ describe LucidWorks::Datasource::Schedule do
89
100
 
90
101
  context 'Time since self.start_time is not even multiple of self.period' do
91
102
  describe 'one interval has passed' do
92
- before do
103
+ before do
93
104
  @schedule.start_time = @now - 11.minutes
94
105
  @schedule.period = 10.minutes
95
106
  end
@@ -121,7 +132,7 @@ describe LucidWorks::Datasource::Schedule do
121
132
  end
122
133
  end
123
134
 
124
- describe '#active, #active=' do
135
+ describe '#active, #active=' do
125
136
  it 'should maintain specified value' do
126
137
  @schedule.active = true
127
138
  @schedule.active.should == true
@@ -177,6 +188,24 @@ describe LucidWorks::Datasource::Schedule do
177
188
  end
178
189
  end
179
190
 
191
+ describe "with an 'every' frequency" do
192
+ let(:attributes) { {"frequency"=>"every", "period" => "1800"} }
193
+
194
+ it "ceils start_time based on the period" do
195
+ Timecop.freeze Time.iso8601("2012-11-07T10:12:33Z") do
196
+ @schedule.schedule = attributes
197
+ @schedule.start_time.should == Time.iso8601("2012-11-07T10:30:00Z")
198
+ end
199
+ end
200
+
201
+ it "sets the period" do
202
+ Timecop.freeze Time.iso8601("2012-11-07T10:12:33Z") do
203
+ @schedule.schedule = attributes
204
+ @schedule.period.should == 1800
205
+ end
206
+ end
207
+ end
208
+
180
209
  context 'supplied start time has elapsed w/rt current interval' do
181
210
  describe 'with hourly frequency' do
182
211
  it "should advance the start time" do
@@ -184,11 +213,11 @@ describe LucidWorks::Datasource::Schedule do
184
213
  hourly_at_quarter_past = {"frequency"=>"hourly", "start"=>{"minutes"=>"15"}}
185
214
  quarter_past_1_am = Time.iso8601('2011-05-09T01:15:00Z').in_time_zone('Eastern Time (US & Canada)')
186
215
 
187
- Timecop.freeze half_past_midnight do
188
- @schedule.start_time.should_not == quarter_past_1_am
216
+ Timecop.freeze half_past_midnight do
217
+ @schedule.start_time.should_not == quarter_past_1_am
189
218
 
190
- @schedule.schedule = hourly_at_quarter_past
191
- @schedule.start_time.should == quarter_past_1_am
219
+ @schedule.schedule = hourly_at_quarter_past
220
+ @schedule.start_time.should == quarter_past_1_am
192
221
  end
193
222
  end
194
223
  end
@@ -198,11 +227,11 @@ describe LucidWorks::Datasource::Schedule do
198
227
  today_at_noon = Time.iso8601("2011-05-09T12:00:00Z").in_time_zone('Eastern Time (US & Canada)')
199
228
  tomorrow_at_eleven_am = Time.iso8601('2011-05-10T11:00:00Z').in_time_zone('Eastern Time (US & Canada)')
200
229
  daily_at_11_am = {"frequency"=>"daily", "start"=>{"hours" => "11", "minutes"=>"00"}}
201
- Timecop.freeze today_at_noon do
202
- @schedule.start_time.should_not == tomorrow_at_eleven_am
230
+ Timecop.freeze today_at_noon do
231
+ @schedule.start_time.should_not == tomorrow_at_eleven_am
203
232
 
204
- @schedule.schedule = daily_at_11_am
205
- @schedule.start_time.should == tomorrow_at_eleven_am
233
+ @schedule.schedule = daily_at_11_am
234
+ @schedule.start_time.should == tomorrow_at_eleven_am
206
235
  end
207
236
  end
208
237
  end
@@ -215,14 +244,14 @@ describe LucidWorks::Datasource::Schedule do
215
244
  weekly_on_wednesday = {"frequency"=>"weekly", "start"=>{"days" => "2", "hours" => "0", "minutes"=>"00"}}
216
245
 
217
246
  # just make sure I'm not on crack
218
- friday_of_this_week.weekday.should == 'Friday'
219
- wednesday_of_next_week.weekday.should == 'Wednesday'
247
+ friday_of_this_week.weekday.should == 'Friday'
248
+ wednesday_of_next_week.weekday.should == 'Wednesday'
220
249
 
221
- Timecop.freeze friday_of_this_week do
222
- @schedule.start_time.should_not == wednesday_of_next_week
250
+ Timecop.freeze friday_of_this_week do
251
+ @schedule.start_time.should_not == wednesday_of_next_week
223
252
 
224
- @schedule.schedule = weekly_on_wednesday
225
- @schedule.start_time.should == wednesday_of_next_week
253
+ @schedule.schedule = weekly_on_wednesday
254
+ @schedule.start_time.should == wednesday_of_next_week
226
255
  end
227
256
  end
228
257
  end
@@ -231,16 +260,16 @@ describe LucidWorks::Datasource::Schedule do
231
260
  context 'supplied time has not elapsed w/rt current interval' do
232
261
  describe 'with hourly frequency' do
233
262
  it "should not advance the start time" do
234
- half_past_midnight = Time.iso8601("2011-05-09T00:30:00Z")
235
- three_quarters_past_midnight = Time.iso8601('2011-05-09T00:45:00Z')
236
- hourly_at_three_quarters_past = {"frequency"=>"hourly", "start"=>{"minutes"=>"45"}}
263
+ half_past_midnight = Time.iso8601("2011-05-09T00:30:00Z")
264
+ three_quarters_past_midnight = Time.iso8601('2011-05-09T00:45:00Z')
265
+ hourly_at_three_quarters_past = {"frequency"=>"hourly", "start"=>{"minutes"=>"45"}}
237
266
 
238
- Timecop.freeze half_past_midnight do
239
- @schedule.start_time.should_not == three_quarters_past_midnight
267
+ Timecop.freeze half_past_midnight do
268
+ @schedule.start_time.should_not == three_quarters_past_midnight
240
269
  @schedule.frequency.should_not == 'hourly'
241
270
 
242
- @schedule.schedule = hourly_at_three_quarters_past
243
- @schedule.start_time.should == three_quarters_past_midnight
271
+ @schedule.schedule = hourly_at_three_quarters_past
272
+ @schedule.start_time.should == three_quarters_past_midnight
244
273
  @schedule.frequency.should == 'hourly'
245
274
  end
246
275
  end
@@ -248,16 +277,16 @@ describe LucidWorks::Datasource::Schedule do
248
277
 
249
278
  describe 'with daily frequency' do
250
279
  it "should not advance the start time" do
251
- today_at_noon = Time.iso8601("2011-05-09T12:00:00Z")
252
- today_at_1pm = Time.iso8601('2011-05-09T13:00:00Z')
253
- daily_at_1pm = {"frequency"=>"daily", "start"=>{"hours" => "13", "minutes"=>"00"}}
280
+ today_at_noon = Time.iso8601("2011-05-09T12:00:00Z")
281
+ today_at_1pm = Time.iso8601('2011-05-09T13:00:00Z')
282
+ daily_at_1pm = {"frequency"=>"daily", "start"=>{"hours" => "13", "minutes"=>"00"}}
254
283
 
255
- Timecop.freeze today_at_noon do
256
- @schedule.start_time.should_not == today_at_1pm
284
+ Timecop.freeze today_at_noon do
285
+ @schedule.start_time.should_not == today_at_1pm
257
286
  @schedule.frequency.should_not == 'daily'
258
287
 
259
- @schedule.schedule = daily_at_1pm
260
- @schedule.start_time.should == today_at_1pm
288
+ @schedule.schedule = daily_at_1pm
289
+ @schedule.start_time.should == today_at_1pm
261
290
  @schedule.frequency.should == 'daily'
262
291
  end
263
292
  end
@@ -266,20 +295,20 @@ describe LucidWorks::Datasource::Schedule do
266
295
  describe 'with weekly frequency' do
267
296
  it "should not advance the start time" do
268
297
  # note: Rails week starts on Monday
269
- wednesday_of_this_week = Time.iso8601("2011-05-11T00:00:00Z")
270
- thursday_of_this_week = Time.iso8601('2011-05-12T00:00:00Z')
271
- weekly_on_thursday = {"frequency"=>"weekly", "start"=>{"days" => "3", "hours" => "0", "minutes"=>"00"}}
298
+ wednesday_of_this_week = Time.iso8601("2011-05-11T00:00:00Z")
299
+ thursday_of_this_week = Time.iso8601('2011-05-12T00:00:00Z')
300
+ weekly_on_thursday = {"frequency"=>"weekly", "start"=>{"days" => "3", "hours" => "0", "minutes"=>"00"}}
272
301
 
273
302
  # just make sure I'm not on crack
274
- wednesday_of_this_week.weekday.should == 'Wednesday'
275
- thursday_of_this_week.weekday.should == 'Thursday'
303
+ wednesday_of_this_week.weekday.should == 'Wednesday'
304
+ thursday_of_this_week.weekday.should == 'Thursday'
276
305
 
277
- Timecop.freeze wednesday_of_this_week do
278
- @schedule.start_time.should_not == thursday_of_this_week
306
+ Timecop.freeze wednesday_of_this_week do
307
+ @schedule.start_time.should_not == thursday_of_this_week
279
308
  @schedule.frequency.should_not == 'weekly'
280
309
 
281
- @schedule.schedule = weekly_on_thursday
282
- @schedule.start_time.should == thursday_of_this_week
310
+ @schedule.schedule = weekly_on_thursday
311
+ @schedule.start_time.should == thursday_of_this_week
283
312
  @schedule.frequency.should == 'weekly'
284
313
  end
285
314
  end
@@ -334,9 +363,9 @@ describe LucidWorks::Datasource::Schedule do
334
363
 
335
364
  it 'should be true if period is standard but start_time is > 1 period from now' do
336
365
  some_random_time = Time.parse("2011-04-15 13:11:56")
337
- more_than_a_day_later = some_random_time.advance(:days => 2)
366
+ more_than_a_day_later = some_random_time.advance(:days => 2)
338
367
 
339
- Timecop.freeze some_random_time do
368
+ Timecop.freeze some_random_time do
340
369
  @schedule.frequency = 'daily'
341
370
  @schedule.start_time = more_than_a_day_later
342
371
 
@@ -351,8 +380,8 @@ describe LucidWorks::Datasource::Schedule do
351
380
  a_standard_schedule = {"frequency"=>"hourly", "start"=>{"minutes"=>"15"}}
352
381
  some_random_specific_time = Time.iso8601('2011-05-09T01:15:00Z')
353
382
 
354
- Timecop.freeze some_random_specific_time do
355
- @schedule.schedule = a_standard_schedule
383
+ Timecop.freeze some_random_specific_time do
384
+ @schedule.schedule = a_standard_schedule
356
385
 
357
386
  @schedule.should_not be_custom
358
387
  end
@@ -360,7 +389,7 @@ describe LucidWorks::Datasource::Schedule do
360
389
 
361
390
  it 'should be false if period is standard and start time is > 1 period in the past' do
362
391
  some_random_time = Time.parse("2011-04-15 13:11:56")
363
- more_than_a_day_ago = some_random_time.advance(:days => -2)
392
+ more_than_a_day_ago = some_random_time.advance(:days => -2)
364
393
  Timecop.freeze some_random_time do
365
394
  @schedule.frequency = 'daily'
366
395
  @schedule.start_time = more_than_a_day_ago
@@ -399,4 +428,4 @@ describe LucidWorks::Datasource::Schedule do
399
428
  @schedule.active.should == true
400
429
  end
401
430
  end
402
- end
431
+ end
@@ -8,7 +8,7 @@ describe LucidWorks::Datasource::Status do
8
8
 
9
9
  describe "state predicate methods" do
10
10
 
11
- STATES = %w{idle stopped aborted exception finished stopping aborting running}
11
+ STATES = %w{idle stopped aborted exception finished stopping aborting running unknown}
12
12
 
13
13
  STATES.each do |actual_state|
14
14
  describe "when state is #{actual_state}," do
@@ -36,8 +36,8 @@ describe LucidWorks::Datasource::Status do
36
36
  subject { @status }
37
37
 
38
38
  truth_table = {
39
- 'IDLE' => true, 'STOPPED' => true, 'ABORTED' => true, 'EXCEPTION' => true,
40
- 'FINISHED' => true, 'STOPPING' => false, 'ABORTING' => false, 'RUNNING' => false
39
+ 'IDLE' => true, 'STOPPED' => true, 'ABORTED' => true, 'EXCEPTION' => true, 'FINISHED' => true, 'UNKNOWN' => true,
40
+ 'STOPPING' => false, 'ABORTING' => false, 'RUNNING' => false
41
41
  }
42
42
  truth_table.each do |state, expected_result|
43
43
  describe "when state is #{state}" do
@@ -55,8 +55,8 @@ describe LucidWorks::Datasource::Status do
55
55
  subject { @status }
56
56
 
57
57
  truth_table = {
58
- 'IDLE' => false, 'STOPPED' => false, 'ABORTED' => false, 'EXCEPTION' => false,
59
- 'FINISHED' => false, 'STOPPING' => true, 'ABORTING' => true, 'RUNNING' => false
58
+ 'IDLE' => false, 'STOPPED' => false, 'ABORTED' => false, 'EXCEPTION' => false, 'FINISHED' => false, 'UNKNOWN' => false,
59
+ 'STOPPING' => true, 'ABORTING' => true, 'RUNNING' => false
60
60
  }
61
61
  truth_table.each do |state, expected_result|
62
62
  describe "when state is #{state}" do