cellect-client 0.0.1

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 (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +2 -0
  5. data/README.md +19 -0
  6. data/Rakefile +9 -0
  7. data/cellect-client.gemspec +35 -0
  8. data/cellect.gemspec +33 -0
  9. data/data/.gitkeep +0 -0
  10. data/lib/cellect/client/connection.rb +58 -0
  11. data/lib/cellect/client/node_set.rb +35 -0
  12. data/lib/cellect/client.rb +28 -0
  13. data/lib/cellect/node_set.rb +38 -0
  14. data/lib/cellect/version.rb +3 -0
  15. data/lib/cellect.rb +7 -0
  16. data/log/.gitkeep +0 -0
  17. data/spec/client/connection_spec.rb +64 -0
  18. data/spec/client/node_set_spec.rb +24 -0
  19. data/spec/fixtures/project_data/grouped_pairwise_priority.json +109 -0
  20. data/spec/fixtures/project_data/grouped_pairwise_random.json +89 -0
  21. data/spec/fixtures/project_data/grouped_priority.json +59 -0
  22. data/spec/fixtures/project_data/grouped_random.json +49 -0
  23. data/spec/fixtures/project_data/pairwise_priority.json +49 -0
  24. data/spec/fixtures/project_data/pairwise_random.json +39 -0
  25. data/spec/fixtures/project_data/priority.json +49 -0
  26. data/spec/fixtures/project_data/random.json +39 -0
  27. data/spec/fixtures/user_data/complete_user.json +118 -0
  28. data/spec/fixtures/user_data/new_user.json +26 -0
  29. data/spec/fixtures/user_data/partial_user.json +58 -0
  30. data/spec/spec_helper.rb +43 -0
  31. data/spec/support/cellect_helper.rb +12 -0
  32. data/spec/support/shared_api_context.rb +11 -0
  33. data/spec/support/shared_examples_for_node_set.rb +27 -0
  34. data/spec/support/shared_examples_for_project.rb +26 -0
  35. data/spec/support/shared_examples_for_set.rb +34 -0
  36. data/spec/support/spec_adapter.rb +43 -0
  37. data/spec/support/zk_setup.rb +26 -0
  38. data/tmp/.gitkeep +0 -0
  39. metadata +242 -0
@@ -0,0 +1,49 @@
1
+ {
2
+ "id": 3,
3
+ "name": "grouped_random",
4
+ "prioritized": false,
5
+ "pairwise": false,
6
+ "grouped": true,
7
+ "entries": [
8
+ {
9
+ "id": 1,
10
+ "group_id": 1
11
+ },
12
+ {
13
+ "id": 2,
14
+ "group_id": 2
15
+ },
16
+ {
17
+ "id": 3,
18
+ "group_id": 3
19
+ },
20
+ {
21
+ "id": 4,
22
+ "group_id": 1
23
+ },
24
+ {
25
+ "id": 5,
26
+ "group_id": 2
27
+ },
28
+ {
29
+ "id": 6,
30
+ "group_id": 3
31
+ },
32
+ {
33
+ "id": 7,
34
+ "group_id": 1
35
+ },
36
+ {
37
+ "id": 8,
38
+ "group_id": 2
39
+ },
40
+ {
41
+ "id": 9,
42
+ "group_id": 3
43
+ },
44
+ {
45
+ "id": 10,
46
+ "group_id": 1
47
+ }
48
+ ]
49
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "id": 6,
3
+ "name": "pairwise_priority",
4
+ "prioritized": true,
5
+ "pairwise": true,
6
+ "grouped": false,
7
+ "entries": [
8
+ {
9
+ "id": 10,
10
+ "priority": 0
11
+ },
12
+ {
13
+ "id": 6,
14
+ "priority": 4
15
+ },
16
+ {
17
+ "id": 5,
18
+ "priority": 5
19
+ },
20
+ {
21
+ "id": 2,
22
+ "priority": 8
23
+ },
24
+ {
25
+ "id": 4,
26
+ "priority": 6
27
+ },
28
+ {
29
+ "id": 3,
30
+ "priority": 7
31
+ },
32
+ {
33
+ "id": 8,
34
+ "priority": 2
35
+ },
36
+ {
37
+ "id": 9,
38
+ "priority": 1
39
+ },
40
+ {
41
+ "id": 7,
42
+ "priority": 3
43
+ },
44
+ {
45
+ "id": 1,
46
+ "priority": 9
47
+ }
48
+ ]
49
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "id": 5,
3
+ "name": "pairwise_random",
4
+ "prioritized": false,
5
+ "pairwise": true,
6
+ "grouped": false,
7
+ "entries": [
8
+ {
9
+ "id": 1
10
+ },
11
+ {
12
+ "id": 2
13
+ },
14
+ {
15
+ "id": 3
16
+ },
17
+ {
18
+ "id": 4
19
+ },
20
+ {
21
+ "id": 5
22
+ },
23
+ {
24
+ "id": 6
25
+ },
26
+ {
27
+ "id": 7
28
+ },
29
+ {
30
+ "id": 8
31
+ },
32
+ {
33
+ "id": 9
34
+ },
35
+ {
36
+ "id": 10
37
+ }
38
+ ]
39
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "id": 2,
3
+ "name": "priority",
4
+ "prioritized": true,
5
+ "pairwise": false,
6
+ "grouped": false,
7
+ "entries": [
8
+ {
9
+ "id": 7,
10
+ "priority": 3
11
+ },
12
+ {
13
+ "id": 6,
14
+ "priority": 4
15
+ },
16
+ {
17
+ "id": 1,
18
+ "priority": 9
19
+ },
20
+ {
21
+ "id": 3,
22
+ "priority": 7
23
+ },
24
+ {
25
+ "id": 10,
26
+ "priority": 0
27
+ },
28
+ {
29
+ "id": 8,
30
+ "priority": 2
31
+ },
32
+ {
33
+ "id": 2,
34
+ "priority": 8
35
+ },
36
+ {
37
+ "id": 5,
38
+ "priority": 5
39
+ },
40
+ {
41
+ "id": 4,
42
+ "priority": 6
43
+ },
44
+ {
45
+ "id": 9,
46
+ "priority": 1
47
+ }
48
+ ]
49
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "id": 1,
3
+ "name": "random",
4
+ "prioritized": false,
5
+ "pairwise": false,
6
+ "grouped": false,
7
+ "entries": [
8
+ {
9
+ "id": 1
10
+ },
11
+ {
12
+ "id": 2
13
+ },
14
+ {
15
+ "id": 3
16
+ },
17
+ {
18
+ "id": 4
19
+ },
20
+ {
21
+ "id": 5
22
+ },
23
+ {
24
+ "id": 6
25
+ },
26
+ {
27
+ "id": 7
28
+ },
29
+ {
30
+ "id": 8
31
+ },
32
+ {
33
+ "id": 9
34
+ },
35
+ {
36
+ "id": 10
37
+ }
38
+ ]
39
+ }
@@ -0,0 +1,118 @@
1
+ {
2
+ "random": [
3
+ 1,
4
+ 2,
5
+ 3,
6
+ 4,
7
+ 5,
8
+ 6,
9
+ 7,
10
+ 8,
11
+ 9,
12
+ 10
13
+ ],
14
+ "priority": [
15
+ 7,
16
+ 6,
17
+ 1,
18
+ 3,
19
+ 10,
20
+ 8,
21
+ 2,
22
+ 5,
23
+ 4,
24
+ 9
25
+ ],
26
+ "grouped_random": [
27
+ 1,
28
+ 2,
29
+ 3,
30
+ 4,
31
+ 5,
32
+ 6,
33
+ 7,
34
+ 8,
35
+ 9,
36
+ 10
37
+ ],
38
+ "grouped_priority": [
39
+ 8,
40
+ 7,
41
+ 10,
42
+ 5,
43
+ 6,
44
+ 2,
45
+ 3,
46
+ 1,
47
+ 9,
48
+ 4
49
+ ],
50
+ "pairwise_random": [
51
+ 1,
52
+ 2,
53
+ 3,
54
+ 4,
55
+ 5,
56
+ 6,
57
+ 7,
58
+ 8,
59
+ 9,
60
+ 10
61
+ ],
62
+ "pairwise_priority": [
63
+ 10,
64
+ 6,
65
+ 5,
66
+ 2,
67
+ 4,
68
+ 3,
69
+ 8,
70
+ 9,
71
+ 7,
72
+ 1
73
+ ],
74
+ "grouped_pairwise_random": [
75
+ 1,
76
+ 2,
77
+ 3,
78
+ 4,
79
+ 5,
80
+ 6,
81
+ 7,
82
+ 8,
83
+ 9,
84
+ 10,
85
+ 11,
86
+ 12,
87
+ 13,
88
+ 14,
89
+ 15,
90
+ 16,
91
+ 17,
92
+ 18,
93
+ 19,
94
+ 20
95
+ ],
96
+ "grouped_pairwise_priority": [
97
+ 16,
98
+ 17,
99
+ 3,
100
+ 8,
101
+ 7,
102
+ 13,
103
+ 14,
104
+ 4,
105
+ 6,
106
+ 18,
107
+ 12,
108
+ 1,
109
+ 11,
110
+ 10,
111
+ 9,
112
+ 20,
113
+ 2,
114
+ 15,
115
+ 5,
116
+ 19
117
+ ]
118
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "random": [
3
+
4
+ ],
5
+ "priority": [
6
+
7
+ ],
8
+ "grouped_random": [
9
+
10
+ ],
11
+ "grouped_priority": [
12
+
13
+ ],
14
+ "pairwise_random": [
15
+
16
+ ],
17
+ "pairwise_priority": [
18
+
19
+ ],
20
+ "grouped_pairwise_random": [
21
+
22
+ ],
23
+ "grouped_pairwise_priority": [
24
+
25
+ ]
26
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "random": [
3
+ 1,
4
+ 2,
5
+ 3,
6
+ 4,
7
+ 5
8
+ ],
9
+ "priority": [
10
+ 7,
11
+ 6,
12
+ 1,
13
+ 3,
14
+ 10
15
+ ],
16
+ "grouped_random": [
17
+ 1,
18
+ 2,
19
+ 3,
20
+ 4,
21
+ 5
22
+ ],
23
+ "grouped_priority": [
24
+ 8,
25
+ 7,
26
+ 10,
27
+ 5,
28
+ 6
29
+ ],
30
+ "pairwise_random": [
31
+ 1,
32
+ 2,
33
+ 3,
34
+ 4,
35
+ 5
36
+ ],
37
+ "pairwise_priority": [
38
+ 10,
39
+ 6,
40
+ 5,
41
+ 2,
42
+ 4
43
+ ],
44
+ "grouped_pairwise_random": [
45
+ 1,
46
+ 2,
47
+ 3,
48
+ 4,
49
+ 5
50
+ ],
51
+ "grouped_pairwise_priority": [
52
+ 16,
53
+ 17,
54
+ 3,
55
+ 8,
56
+ 7
57
+ ]
58
+ }
@@ -0,0 +1,43 @@
1
+ CELLECT_ROOT = File.expand_path File.join(File.dirname(__FILE__), '../')
2
+
3
+ %w(lib ext).each do |name|
4
+ dir = File.join CELLECT_ROOT, name
5
+ $LOAD_PATH.unshift dir unless $LOAD_PATH.include? dir
6
+ end
7
+
8
+ Bundler.require :test, :development
9
+
10
+ ENV['CELLECT_POOL_SIZE'] = '3'
11
+
12
+ require 'pry'
13
+ require 'oj'
14
+ require './spec/support/zk_setup.rb'
15
+ require 'cellect/server'
16
+ require 'cellect/client'
17
+ require 'celluloid/rspec'
18
+ require 'rack/test'
19
+ Celluloid.shutdown_timeout = 1
20
+ Celluloid.logger = nil
21
+
22
+ Dir["./spec/support/**/*.rb"].sort.each{ |f| require f }
23
+
24
+ Cellect::Server.adapter = SpecAdapter.new
25
+ SET_TYPES = %w(random priority pairwise_random pairwise_priority)
26
+
27
+ RSpec.configure do |config|
28
+ config.treat_symbols_as_metadata_keys_with_true_values = true
29
+ config.run_all_when_everything_filtered = true
30
+ config.filter_run :focus
31
+ config.order = 'random'
32
+ config.include CellectHelper
33
+
34
+ config.around(:each) do |example|
35
+ Celluloid.boot
36
+ example.run
37
+ Celluloid.shutdown
38
+ end
39
+
40
+ config.after(:suite) do
41
+ `zkServer stop #{ CELLECT_ZK_CONFIG } > /dev/null 2>&1`
42
+ end
43
+ end
@@ -0,0 +1,12 @@
1
+ require 'timeout'
2
+
3
+ module CellectHelper
4
+ def pass_until(obj, is: is)
5
+ Timeout::timeout(1) do
6
+ Thread.pass until obj.state == is
7
+ end
8
+ rescue => e
9
+ puts "Timeout waiting for #{ obj.inspect } to be #{ is }"
10
+ raise e
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ shared_context 'API' do
2
+ include Rack::Test::Methods
3
+
4
+ def app
5
+ $app ||= Cellect::Server::API.new
6
+ end
7
+
8
+ def json
9
+ Oj.strict_load last_response.body
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ shared_examples_for 'node set' do
2
+ let(:node_set){ Cellect::NodeSet.new }
3
+
4
+ it 'should connect to zoo keeper' do
5
+ node_set.zk.should be_nil
6
+ pass_until node_set, is: :ready
7
+ node_set.zk.should be_connected
8
+ end
9
+
10
+ it 'should know the connection state' do
11
+ node_set.state.should be :initializing
12
+ pass_until node_set, is: :ready
13
+ node_set.should be_ready
14
+ end
15
+
16
+ it 'should accept a connection string' do
17
+ begin
18
+ pass_until node_set, is: :ready
19
+ ENV['ZK_URL'] = 'foobar'
20
+ node_set.send(:zk_url).should == 'foobar'
21
+ ENV.delete 'ZK_URL'
22
+ node_set.send(:zk_url).should == 'localhost:2181'
23
+ ensure
24
+ ENV['ZK_URL'] = 'localhost:21811'
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ shared_examples_for 'project' do |name|
2
+ let(:obj){ send name }
3
+
4
+ before(:each) do
5
+ Cellect::Server.adapter.load_project obj.name
6
+ end
7
+
8
+ it 'should add singleton instances to the registry' do
9
+ obj.class[:foo].should be_a_kind_of Cellect::Server::Project
10
+ obj.class[:foo].object_id.should == obj.class[:foo].object_id
11
+ end
12
+
13
+ it 'should initialize empty' do
14
+ obj.name.should be_a String
15
+ obj.users.should be_a Hash
16
+
17
+ set_klass = obj.prioritized? ? DiffSet::PrioritySet : DiffSet::RandomSet
18
+ obj.subjects.should be_a set_klass
19
+ end
20
+
21
+ it 'should provide a user lookup' do
22
+ obj.user(1).should be_a Cellect::Server::User
23
+ obj.user(1).object_id.should == obj.user(1).object_id
24
+ obj.users.keys.should include 1
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ shared_examples_for 'a set' do
2
+ it 'should convert to an Array' do
3
+ set.to_a.should =~ (1..5).to_a
4
+ end
5
+
6
+ it 'should add elements' do
7
+ set.add 100
8
+ set.to_a.should include 100
9
+ end
10
+
11
+ it 'should remove elements' do
12
+ set.remove 1
13
+ set.to_a.should_not include 1
14
+ end
15
+
16
+ it 'should sample elements' do
17
+ set.sample(2).length.should == 2
18
+ end
19
+
20
+ it 'should not include removed elements in samples' do
21
+ set.remove 5
22
+ set.sample(5).should_not include 5
23
+ end
24
+
25
+ it 'should know how many elements it contains' do
26
+ expect{ set.add 100 }.to change{ set.size }.from(5).to 6
27
+ end
28
+
29
+ it 'should know if it contains an element' do
30
+ set.should_not include 100
31
+ set.add 100
32
+ set.should include 100
33
+ end
34
+ end
@@ -0,0 +1,43 @@
1
+ require 'oj'
2
+
3
+ class SpecAdapter < Cellect::Server::Adapters::Default
4
+ def project_list
5
+ fixtures.values
6
+ end
7
+
8
+ def load_data_for(project_name)
9
+ fixtures.fetch(project_name, { }).fetch 'entries', []
10
+ end
11
+
12
+ def fixtures
13
+ @fixtures ||= { }.tap do |fixtures|
14
+ Dir["#{ _fixture_path }/project_data/*.json"].collect do |f|
15
+ name = File.basename(f).sub /\.json$/, ''
16
+ data = Oj.strict_load File.read f
17
+ fixtures[name] = data
18
+ end
19
+ end
20
+ end
21
+
22
+ def user_fixtures
23
+ @user_fixtures ||= { }.tap do |user_fixtures|
24
+ Dir["#{ _fixture_path }/user_data/*.json"].sort.collect.with_index do |f, i|
25
+ name = File.basename(f).sub /\.json$/, ''
26
+ data = Oj.strict_load File.read f
27
+ user_fixtures[name] = data
28
+ user_fixtures[i + 1] = data
29
+ end
30
+ end
31
+ end
32
+
33
+ def load_user(project_name, id)
34
+ user = user_fixtures[id]
35
+ user ? user[project_name] : user_fixtures['new_user'][project_name]
36
+ end
37
+
38
+ protected
39
+
40
+ def _fixture_path
41
+ File.expand_path File.join(__FILE__, '../../fixtures')
42
+ end
43
+ end
@@ -0,0 +1,26 @@
1
+ zk_dir = File.join CELLECT_ROOT, 'tmp/zookeeper'
2
+
3
+ `rm -rf #{ zk_dir }; mkdir -p #{ zk_dir }`
4
+
5
+ CELLECT_ZK_CONFIG = "#{ zk_dir }/zoo.cfg"
6
+ File.open(CELLECT_ZK_CONFIG, 'w') do |out|
7
+ out.puts <<-TEXT
8
+ tickTime=2000
9
+ initLimit=10
10
+ syncLimit=5
11
+ dataDir=#{ zk_dir }
12
+ clientPort=21811
13
+ forceSync=no
14
+ snapCount=1000000
15
+ TEXT
16
+ end
17
+
18
+ if `echo ruok | nc 127.0.0.1 21811`.chomp == 'imok'
19
+ pid = `ps aux | grep -e 'Cellect[\/]tmp[\/]zookeeper'`.split[1]
20
+ puts "Killing rogue zookeeper process: #{ pid }..."
21
+ `kill -s TERM #{ pid }`
22
+ sleep 1
23
+ end
24
+
25
+ `zkServer start #{ CELLECT_ZK_CONFIG } > /dev/null 2>&1`
26
+ ENV['ZK_URL'] = 'localhost:21811'
data/tmp/.gitkeep ADDED
File without changes