lucid_works 0.7.18 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
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
data/lib/lucid_works.rb CHANGED
@@ -9,13 +9,13 @@ require 'active_support/inflector'
9
9
  require 'restclient'
10
10
  require 'json'
11
11
  require 'rsolr'
12
- require 'rsolr-ext'
13
12
  require 'nokogiri'
14
13
 
15
14
  require 'lucid_works/utils'
16
15
  require 'lucid_works/patch_restclient'
17
16
  require 'lucid_works/patch_time'
18
17
  require 'lucid_works/simple_naming'
18
+ require 'lucid_works/inflections'
19
19
 
20
20
  require 'lucid_works/exceptions'
21
21
  require 'lucid_works/associations'
@@ -43,6 +43,7 @@ require 'lucid_works/activity/status'
43
43
  require 'lucid_works/activity/history'
44
44
  require 'lucid_works/crawler'
45
45
  require 'lucid_works/datasource'
46
+ require 'lucid_works/datasource/mapping'
46
47
  require 'lucid_works/datasource/index'
47
48
  require 'lucid_works/datasource/status'
48
49
  require 'lucid_works/datasource/history'
@@ -51,17 +52,23 @@ require 'lucid_works/datasource/crawldata'
51
52
  require 'lucid_works/datasource/job'
52
53
  require 'lucid_works/datasource_type'
53
54
  require 'lucid_works/datasource_property'
55
+ require 'lucid_works/dynamicfield'
54
56
  require 'lucid_works/field'
55
57
  require 'lucid_works/fieldtype'
56
58
  require 'lucid_works/jdbcdriver'
57
59
  require 'lucid_works/role'
60
+ require 'lucid_works/cache'
58
61
  require 'lucid_works/synonym'
62
+ require 'lucid_works/elevation'
59
63
  require 'lucid_works/logs'
60
64
  require 'lucid_works/logs/query'
61
65
  require 'lucid_works/logs/query/summary'
62
66
  require 'lucid_works/logs/index'
63
67
  require 'lucid_works/logs/index/summary'
68
+ require 'lucid_works/server/crawlers_status'
64
69
  require 'lucid_works/version'
70
+ require 'lucid_works/cluster'
71
+ require 'lucid_works/request_handler'
65
72
 
66
73
  I18n.load_path += Dir.glob(File.join(File.dirname(__FILE__), '..', 'config', 'locales', '*.yml'))
67
74
  I18n.reload! if Rails.env == 'development' rescue nil
data/lucid_works.gemspec CHANGED
@@ -6,10 +6,10 @@ Gem::Specification.new do |s|
6
6
  s.name = "lucid_works"
7
7
  s.version = LucidWorks::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
- s.authors = ["Sam Pierson"]
10
- s.email = ["sam.pierson@lucidimagination.com"]
11
- s.homepage = ""
12
- s.summary = %q{Ruby wrapper for the LucidWorks REST API}
9
+ s.authors = ["Lucid Imagination"]
10
+ s.email = ["support@lucidimagination.com"]
11
+ s.homepage = "http://github.com/lucidimagination/lucidworks-ruby"
12
+ s.summary = %q{LucidWorks REST API client}
13
13
  s.description = %q{Ruby wrapper for the LucidWorks REST API}
14
14
 
15
15
  s.rubyforge_project = "lucid_works"
@@ -19,11 +19,10 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
21
 
22
- s.add_runtime_dependency 'activesupport', '>= 3'
23
- s.add_runtime_dependency 'activemodel', '>= 3'
24
- s.add_runtime_dependency 'rest-client', '>= 1.6.1'
22
+ s.add_runtime_dependency 'activesupport', '>= 4'
23
+ s.add_runtime_dependency 'activemodel', '>= 4'
24
+ s.add_runtime_dependency 'rest-client', '1.6.7'
25
25
  s.add_runtime_dependency 'json'
26
- s.add_runtime_dependency 'rsolr'
27
- s.add_runtime_dependency 'rsolr-ext'
26
+ s.add_runtime_dependency 'rsolr', '1.0.9'
28
27
  s.add_runtime_dependency 'nokogiri'
29
28
  end
@@ -0,0 +1,30 @@
1
+ {
2
+ "znode":{
3
+ "path":"/clusterstate.json",
4
+ "prop":{
5
+ "version":15,
6
+ "aversion":0,
7
+ "children_count":0,
8
+ "ctime":"Wed Aug 22 16:38:45 PDT 2012 (1345678725057)",
9
+ "cversion":0,
10
+ "czxid":12,
11
+ "dataLength":1803,
12
+ "ephemeralOwner":0,
13
+ "mtime":"Wed Aug 22 16:39:07 PDT 2012 (1345678747682)",
14
+ "mzxid":149,
15
+ "pzxid":12
16
+ },
17
+ "data":"{\n \"collection1\":{\n \"shards\":{\n \"shard1\":{\n \"range\":\"80000000-ffffffff\",\n \"replicas\":{\n \"myserver:8888_solr_collection1\":{\n \"shard\":\"shard1\",\n \"roles\":null,\n \"state\":\"active\",\n \"core\":\"collection1\",\n \"collection\":\"collection1\",\n \"node_name\":\"myserver:8888_solr\",\n \"base_url\":\"http://myserver:8888/solr\",\n \"leader\":\"true\"},\n \"myserver:14888_solr_collection1\":{\n \"shard\":\"shard1\",\n \"roles\":null,\n \"state\":\"recovering\",\n \"core\":\"collection1\",\n \"collection\":\"collection1\",\n \"node_name\":\"myserver:14888_solr\",\n \"base_url\":\"http://myserver:14888/solr\"}}},\n \"shard2\":{\n \"range\":\"0-7fffffff\",\n \"replicas\":{\"myserver:13888_solr_collection1\":{\n \"shard\":\"shard2\",\n \"roles\":null,\n \"state\":\"active\",\n \"core\":\"collection1\",\n \"collection\":\"collection1\",\n \"node_name\":\"myserver:13888_solr\",\n \"base_url\":\"http://myserver:13888/solr\",\n \"leader\":\"true\"}}}}},\n \"LucidWorksLogs\":{\n \"shards\":{\n \"shard1\":{\n \"range\":\"80000000-ffffffff\",\n \"replicas\":{\n \"myserver:8888_solr_LucidWorksLogs\":{\n \"shard\":\"shard1\",\n \"roles\":null,\n \"state\":\"active\",\n \"core\":\"LucidWorksLogs\",\n \"collection\":\"LucidWorksLogs\",\n \"node_name\":\"myserver:8888_solr\",\n \"base_url\":\"http://myserver:8888/solr\",\n \"leader\":\"true\"},\n \"myserver:14888_solr_LucidWorksLogs\":{\n \"shard\":\"shard1\",\n \"roles\":null,\n \"state\":\"recovering\",\n \"core\":\"LucidWorksLogs\",\n \"collection\":\"LucidWorksLogs\",\n \"node_name\":\"myserver:14888_solr\",\n \"base_url\":\"http://myserver:14888/solr\"}}},\n \"shard2\":{\n \"range\":\"0-7fffffff\",\n \"replicas\":{\"myserver:13888_solr_LucidWorksLogs\":{\n \"shard\":\"shard2\",\n \"roles\":null,\n \"state\":\"active\",\n \"core\":\"LucidWorksLogs\",\n \"collection\":\"LucidWorksLogs\",\n \"node_name\":\"myserver:13888_solr\",\n \"base_url\":\"http://myserver:13888/solr\",\n \"leader\":\"true\"}}}}}}"
18
+ },
19
+ "tree":[
20
+ {
21
+ "data":{
22
+ "title":"/clusterstate.json",
23
+ "attr":{
24
+ "href":"zookeeper?detail=true&path=%2Fclusterstate.json"
25
+ }
26
+ }
27
+ }
28
+ ]
29
+ }
30
+
@@ -0,0 +1,29 @@
1
+ {
2
+ "znode":{
3
+ "path":"/clusterstate.json",
4
+ "prop":{
5
+ "version":16,
6
+ "aversion":0,
7
+ "children_count":0,
8
+ "ctime":"Sun Jul 15 22:58:05 UTC 2012 (1342393085065)",
9
+ "cversion":0,
10
+ "czxid":12,
11
+ "dataLength":1250,
12
+ "ephemeralOwner":0,
13
+ "mtime":"Wed Jul 18 16:16:21 UTC 2012 (1342628181385)",
14
+ "mzxid":307,
15
+ "pzxid":12
16
+ },
17
+ "data":"{\n \"collection1\":{\n \"shards\":{\n \"shard1\":{\n \"range\":\"80000000-ffffffff\",\n \"replicas\":{\n \"myserver:8888_solr_collection1\":{\n \"shard\":\"shard1\",\n \"leader\":\"true\",\n \"state\":\"active\",\n \"core\":\"collection1\",\n \"collection\":\"collection1\",\n \"node_name\":\"myserver:8888_solr\",\n \"base_url\":\"http://myserver:8888/solr\"}}}},\n \"shard2\":{}},\n \"LucidWorksLogs\":{\n \"shards\":{\n \"shard1\":{\n \"range\":\"80000000-ffffffff\",\n \"replicas\":{\n \"myserver:8888_solr_LucidWorksLogs\":{\n \"shard\":\"shard1\",\n \"leader\":\"true\",\n \"state\":\"active\",\n \"core\":\"LucidWorksLogs\",\n \"collection\":\"LucidWorksLogs\",\n \"node_name\":\"myserver:8888_solr\",\n \"base_url\":\"http://myserver:8888/solr\"}}},\n \"shard2\":{\n \"range\":\"80000000-ffffffff\",\n \"replicas\":{\n \"myserver:13888_solr_LucidWorksLogs\":{\n \"shard\":\"shard2\",\n \"leader\":\"true\",\n \"state\":\"active\",\n \"core\":\"LucidWorksLogs\",\n \"collection\":\"LucidWorksLogs\",\n \"node_name\":\"myserver:13888_solr\",\n \"base_url\":\"http://myserver:13888/solr\"}}}}}}"
18
+ },
19
+ "tree":[
20
+ {
21
+ "data":{
22
+ "title":"/clusterstate.json",
23
+ "attr":{
24
+ "href":"zookeeper?detail=true&path=%2Fclusterstate.json"
25
+ }
26
+ }
27
+ }
28
+ ]
29
+ }
@@ -0,0 +1,28 @@
1
+ {"znode":{
2
+ "path":"/live_nodes","prop":{
3
+ "version":0,
4
+ "aversion":0,
5
+ "children_count":3,
6
+ "ctime":"Wed Aug 22 16:38:44 PDT 2012 (1345678724992)",
7
+ "cversion":3,
8
+ "czxid":2,
9
+ "dataLength":0,
10
+ "ephemeralOwner":0,
11
+ "mtime":"Wed Aug 22 16:38:44 PDT 2012 (1345678724992)",
12
+ "mzxid":2,
13
+ "pzxid":132}},"tree":[{"data":{
14
+ "title":"/live_nodes","attr":{
15
+ "href":"zookeeper?detail=true&path=%2Flive_nodes"}},
16
+ "children":[{"data":{
17
+ "title":"myserver:13888_solr","attr":{
18
+ "href":"zookeeper?detail=true&path=%2Flive_nodes%2Fmyserver%3A13888_solr"}},
19
+ "ephemeral":true,
20
+ "version":0},{"data":{
21
+ "title":"myserver:14888_solr","attr":{
22
+ "href":"zookeeper?detail=true&path=%2Flive_nodes%2Fmyserver%3A14888_solr"}},
23
+ "ephemeral":true,
24
+ "version":0},{"data":{
25
+ "title":"myserver:8888_solr","attr":{
26
+ "href":"zookeeper?detail=true&path=%2Flive_nodes%2Fmyserver%3A8888_solr"}},
27
+ "ephemeral":true,
28
+ "version":0}]}]}
@@ -0,0 +1,26 @@
1
+ {
2
+ "znode":{
3
+ "path":"/live_nodes",
4
+ "prop":{
5
+ "version":0,
6
+ "aversion":0,
7
+ "children_count":1,
8
+ "ctime":"Sun Jul 15 22:58:05 UTC 2012 (1342393085027)",
9
+ "cversion":17,
10
+ "czxid":2,
11
+ "dataLength":0,
12
+ "ephemeralOwner":0,
13
+ "mtime":"Sun Jul 15 22:58:05 UTC 2012 (1342393085027)",
14
+ "mzxid":2,
15
+ "pzxid":298
16
+ }
17
+ },
18
+ "tree":[{
19
+ "data":{
20
+ "title":"/live_nodes",
21
+ "attr":{
22
+ "href":"zookeeper?detail=true&path=%2Flive_nodes"
23
+ }
24
+ }
25
+ }]
26
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "znode":{
3
+ "path":"/live_nodes",
4
+ "prop":{
5
+ "version":0,
6
+ "aversion":0,
7
+ "children_count":1,
8
+ "ctime":"Sun Jul 15 22:58:05 UTC 2012 (1342393085027)",
9
+ "cversion":17,
10
+ "czxid":2,
11
+ "dataLength":0,
12
+ "ephemeralOwner":0,
13
+ "mtime":"Sun Jul 15 22:58:05 UTC 2012 (1342393085027)",
14
+ "mzxid":2,
15
+ "pzxid":298
16
+ }
17
+ },
18
+ "tree":[{
19
+ "data":{
20
+ "title":"/live_nodes",
21
+ "attr":{
22
+ "href":"zookeeper?detail=true&path=%2Flive_nodes"
23
+ }
24
+ },
25
+ "children":[{
26
+ "data":{
27
+ "title":"myserver:8888_solr",
28
+ "attr":{
29
+ "href":"zookeeper?detail=true&path=%2Flive_nodes%2Fmyserver%3A8888_solr"
30
+ }
31
+ },
32
+ "ephemeral":true,
33
+ "version":0
34
+ }]
35
+ }]
36
+ }
@@ -40,37 +40,36 @@ describe LucidWorks::Base do
40
40
  it_should_behave_like "ActiveModel"
41
41
 
42
42
  describe "naming support" do
43
- context "for a namespaced model" do
44
- class LucidWorks::NamespacedModel < LucidWorks::Base
43
+ context "for a regular model" do
44
+ module LucidWorks
45
+ class Foo < Base
46
+ end
45
47
  end
46
48
 
47
- it "demodulizes the model's singular name" do
48
- LucidWorks::NamespacedModel.model_name.singular.should == "namespaced_model"
49
- end
50
-
51
- it "demodulizes the model's plural name" do
52
- LucidWorks::NamespacedModel.model_name.plural.should == "namespaced_models"
53
- end
54
-
55
- it "demodulizes the model's collection name" do
56
- LucidWorks::NamespacedModel.model_name.collection.should == "namespaced_models"
49
+ it "demodulizes the model's name" do
50
+ LucidWorks::Foo.model_name.should == "Foo"
57
51
  end
58
52
  end
59
53
 
60
- context "for a top-level model" do
61
- class TopLevelModel < LucidWorks::Base
54
+ context "for a nested model" do
55
+ module LucidWorks
56
+ class Foo < Base
57
+ class Bar < Base
58
+ end
59
+ end
62
60
  end
63
61
 
64
- it "returns the model's singular name" do
65
- TopLevelModel.model_name.singular.should == "top_level_model"
62
+ it "demodulizes the model's name" do
63
+ LucidWorks::Foo::Bar.model_name.should == "Foo::Bar"
66
64
  end
65
+ end
67
66
 
68
- it "returns the model's plural name" do
69
- TopLevelModel.model_name.plural.should == "top_level_models"
67
+ context "for a top-level model" do
68
+ class TopLevel < LucidWorks::Base
70
69
  end
71
70
 
72
- it "returns the model's collection name" do
73
- TopLevelModel.model_name.plural.should == "top_level_models"
71
+ it "doesn't change the model's name" do
72
+ TopLevel.model_name.should == "TopLevel"
74
73
  end
75
74
  end
76
75
  end
@@ -419,18 +418,28 @@ describe LucidWorks::Base do
419
418
  before do
420
419
  RestClient.stub(:post) {
421
420
  e = RestClient::UnprocessableEntity.new
422
- e.response = '{"errors":[{"message":"name is a required key","key":"name"},{"message":"name must consist of only A-Z a-z 0-9 - _","key":"name"}],"http_status_name":"Unprocessable Entity","http_status_code":422}'
421
+ # e.response = '{"errors":[{"message":"name is a required key","key":"name"},{"message":"name must consist of only A-Z a-z 0-9 - _","key":"name"}],"http_status_name":"Unprocessable Entity","http_status_code":422}'
422
+ e.response = '{"errors":[' +
423
+ '{"message":"some message","key":"name"},' +
424
+ '{"message":"some message","key":"class"}' +
425
+ '],"http_status_name":"Unprocessable Entity","http_status_code":422}'
423
426
  raise e
424
427
  }
425
- @widget = Widget.new(:name => '', :size => '', :parent => @server)
428
+ @widget = Widget.new(:name => '', :size => '', :_class => '', :parent => @server)
426
429
  end
427
430
 
428
- it "should set errors on the model" do
431
+ it "should attach errors to simple attributes" do
429
432
  @widget.save
430
433
  @widget.errors.should_not be_empty
431
434
  @widget.errors['name'].should_not be_empty
432
435
  end
433
436
 
437
+ it "should attach errors to mapped (reserved names) attributes" do
438
+ @widget.save
439
+ @widget.errors.should_not be_empty
440
+ @widget.errors['_class'].should_not be_empty
441
+ end
442
+
434
443
  it "should not set persisted" do
435
444
  @widget.save
436
445
  @widget.should_not be_persisted
@@ -629,7 +638,7 @@ describe LucidWorks::Base do
629
638
 
630
639
  it "should attach errors to the model" do
631
640
  @widget.destroy
632
- @widget.errors.should == {:name => ["Field Type currently in use: text_en"]}
641
+ @widget.errors[:name].should == ["Field Type currently in use: text_en"]
633
642
  end
634
643
 
635
644
  it "should return false" do
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe LucidWorks::Cache do
4
+ before :all do
5
+ @server = connect_to_live_server
6
+ @server.reset_collections!
7
+ @collection = @server.collection('collection1')
8
+ end
9
+
10
+ it "is connected to the rest api" do
11
+ LucidWorks::Cache.new(:parent => @collection).should be_a(LucidWorks::Base)
12
+ end
13
+
14
+ describe "validations" do
15
+ it "requires 'size' to be present" do
16
+ field = LucidWorks::Cache.new(:parent => @collection)
17
+ field.should_not be_valid
18
+ field.errors[:size].should == ["can't be blank"]
19
+ end
20
+
21
+ [:initial_size, :size].each do |attribute|
22
+ it "requires #{attribute} to be >= 0" do
23
+ field = LucidWorks::Cache.new(:parent => @collection, attribute => -1)
24
+ field.should_not be_valid
25
+ field.errors[attribute].should == ["is not a valid value"]
26
+ end
27
+
28
+ it "requires #{attribute} to be an integer" do
29
+ field = LucidWorks::Cache.new(:parent => @collection, attribute => 1.2)
30
+ field.should_not be_valid
31
+ field.errors[attribute].should == ["is not a valid value"]
32
+ end
33
+ end
34
+ end
35
+
36
+ it "exposes cache details" do
37
+ cache = @collection.caches.find('document_cache')
38
+ cache.name.should == 'document_cache'
39
+ cache._class.should == 'solr.LRUCache'
40
+ cache.initial_size.should == '512'
41
+ cache.size.should == '512'
42
+ cache.autowarm_count.should == '0'
43
+ end
44
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe LucidWorks::Cluster do
4
+ before(:each) do
5
+ RestClient.stub(:get).with('http://myserver:8888/solr/zookeeper?detail=true&path=/clusterstate.json') do
6
+ File.read(fixture_path('zookeeper/clusterstate.json'))
7
+ end
8
+ RestClient.stub(:get).with('http://myserver:8888/solr/zookeeper?detail=true&path=/live_nodes/') do
9
+ File.read(fixture_path('zookeeper/live_nodes.json'))
10
+ end
11
+ end
12
+
13
+ let(:cluster) { LucidWorks::Cluster.new('http://myserver:8888/solr') }
14
+
15
+ [8888, 13888, 14888].each do |port|
16
+ let("node_on_port_#{port}") { cluster.nodes.find {|node| node.port == port } }
17
+ end
18
+
19
+ context "with multiple nodes in different states" do
20
+ it "builds a list of nodes" do
21
+ cluster.should have(3).nodes
22
+ end
23
+
24
+ it "indicates the state of each node" do
25
+ node_on_port_8888.state.should == 'live'
26
+ node_on_port_13888.state.should == 'live'
27
+ node_on_port_14888.state.should == 'recovering'
28
+ end
29
+ end
30
+
31
+ context "without any children under /live_nodes" do
32
+ before(:each) do
33
+ RestClient.stub(:get).with('http://myserver:8888/solr/zookeeper?detail=true&path=/live_nodes/') do
34
+ File.read(fixture_path('zookeeper/live_nodes_no_children.json'))
35
+ end
36
+ end
37
+
38
+ it "builds a list of nodes" do
39
+ cluster.should have(3).nodes
40
+ end
41
+
42
+ it "indicates the state of each node" do
43
+ cluster.nodes.all? {|node| node.state == 'down' }.should be_true
44
+ end
45
+ end
46
+
47
+ context "with a broken shard" do
48
+ before(:each) do
49
+ RestClient.stub(:get).with('http://myserver:8888/solr/zookeeper?detail=true&path=/clusterstate.json') do
50
+ File.read(fixture_path('zookeeper/clusterstate_broken_shard.json'))
51
+ end
52
+ end
53
+
54
+ it "builds a list of nodes" do
55
+ cluster.should have(2).nodes # the clusterstate fixture used here only has 2 nodes
56
+ end
57
+
58
+ it "only attaches valid shards to nodes" do
59
+ cluster.nodes.second.should have(1).shard
60
+ end
61
+ end
62
+
63
+ it "extracts the address and port from the base URL" do
64
+ cluster.nodes.first.host.should == 'myserver'
65
+ cluster.nodes.first.port.should == 8888
66
+ end
67
+
68
+ it "exposes the access URLs" do
69
+ node_on_port_8888.solr_url.should == 'http://myserver:8888/solr'
70
+ node_on_port_13888.api_url.should == 'http://myserver:13888/api'
71
+ end
72
+
73
+ describe "a shard" do
74
+ let(:a_shard) { node_on_port_8888.shards.first }
75
+
76
+ it "belong to nodes" do
77
+ node_on_port_8888.should have(2).shards
78
+ node_on_port_8888.shards.first.node.should be(node_on_port_8888)
79
+ end
80
+
81
+ it "have an id" do
82
+ a_shard.id.should == 'collection1_shard1'
83
+ end
84
+
85
+ it "have a collection" do
86
+ a_shard.collection.should == 'collection1'
87
+ end
88
+
89
+ it "have a name" do
90
+ a_shard.name.should == 'shard1'
91
+ end
92
+
93
+ it "can be a leader" do
94
+ node_on_port_8888.shards.first.should be_leader
95
+ node_on_port_14888.shards.first.should_not be_leader
96
+ end
97
+ end
98
+
99
+ it "is serializable" do
100
+ cluster.nodes.to_json.should == "[" +
101
+ %Q({"id":"myserver_8888","host":"myserver","port":8888,"state":"live","solr_url":"http://myserver:8888/solr","api_url":"http://myserver:8888/api",) +
102
+ %Q("shards":[{"name":"shard1","collection":"collection1","leader":true},{"name":"shard1","collection":"LucidWorksLogs","leader":true}]},) +
103
+ %Q({"id":"myserver_14888","host":"myserver","port":14888,"state":"recovering","solr_url":"http://myserver:14888/solr","api_url":"http://myserver:14888/api",) +
104
+ %Q("shards":[{"name":"shard1","collection":"collection1","leader":false},{"name":"shard1","collection":"LucidWorksLogs","leader":false}]},) +
105
+ %Q({"id":"myserver_13888","host":"myserver","port":13888,"state":"live","solr_url":"http://myserver:13888/solr","api_url":"http://myserver:13888/api",) +
106
+ %Q("shards":[{"name":"shard2","collection":"collection1","leader":true},{"name":"shard2","collection":"LucidWorksLogs","leader":true}]}) +
107
+ "]"
108
+ end
109
+ end
@@ -31,6 +31,17 @@ describe LucidWorks::Activity do
31
31
  end
32
32
 
33
33
  describe '#frequency' do
34
+ it "assumes an 'every' frequency when period ranges from 1 to 59 minutes" do
35
+ @activity.period = 0
36
+ @activity.frequency.should_not == 'every'
37
+ @activity.period = 1 * 60
38
+ @activity.frequency.should == 'every'
39
+ @activity.period = 59 * 60
40
+ @activity.frequency.should == 'every'
41
+ @activity.period = 60 * 60
42
+ @activity.frequency.should_not == 'every'
43
+ end
44
+
34
45
  it "should return 'weekly' when period == num of seconds in a week" do
35
46
  @activity.period = 604800
36
47
  @activity.frequency.should == 'weekly'
@@ -184,6 +195,24 @@ describe LucidWorks::Activity do
184
195
  end
185
196
  end
186
197
 
198
+ describe "with an 'every' frequency" do
199
+ let(:attributes) { {"frequency"=>"every", "period" => "1800"} }
200
+
201
+ it "ceils start_time based on the period" do
202
+ Timecop.freeze Time.iso8601("2012-11-07T10:12:33Z") do
203
+ @activity.schedule = attributes
204
+ @activity.start_time.should == Time.iso8601("2012-11-07T10:30:00Z")
205
+ end
206
+ end
207
+
208
+ it "sets the period" do
209
+ Timecop.freeze Time.iso8601("2012-11-07T10:12:33Z") do
210
+ @activity.schedule = attributes
211
+ @activity.period.should == 1800
212
+ end
213
+ end
214
+ end
215
+
187
216
  context 'supplied start time has elapsed w/rt current interval' do
188
217
  describe 'with hourly frequency' do
189
218
  it "should advance the start time" do
@@ -41,7 +41,7 @@ describe "LucidWorks::Collection#prime_activities" do
41
41
  it "should not create duplicates for existing types" do
42
42
  lambda {
43
43
  @collection.prime_activities
44
- }.should change(@collection, :activities_count).by (LucidWorks::Activity::TYPES.size - 1)
44
+ }.should change(@collection, :activities_count).by(LucidWorks::Activity::TYPES.size - 1)
45
45
  end
46
46
  end
47
47
 
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe LucidWorks::Collection::Settings do
4
+ before :all do
5
+ @server = connect_to_live_server
6
+ @server.reset_collections!
7
+ @collection = @server.collection('collection1')
8
+ end
9
+
10
+ it "is connected to the rest api" do
11
+ LucidWorks::Collection::Settings.new(:parent => @collection).should be_a(LucidWorks::Base)
12
+ end
13
+
14
+ describe "validations" do
15
+ subject { LucidWorks::Collection::Settings.new(:parent => @collection) }
16
+
17
+ [:update_handler_autocommit_max_docs].each do |attribute|
18
+ it "requires #{attribute} to be an integer" do
19
+ resource = LucidWorks::Collection::Settings.new(:parent => @collection, attribute => 1.2)
20
+ resource.should_not be_valid
21
+ resource.errors[attribute].should == ["is not a valid value"]
22
+ end
23
+
24
+ it "requires #{attribute} to be > 0" do
25
+ resource = LucidWorks::Collection::Settings.new(:parent => @collection, attribute => 0)
26
+ resource.should_not be_valid
27
+ resource.errors[attribute].should == ["is not a valid value"]
28
+ end
29
+ end
30
+ end
31
+ end