riak-client 0.9.8 → 1.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. data/.gitignore +32 -0
  2. data/Gemfile +17 -11
  3. data/Guardfile +14 -0
  4. data/Rakefile +18 -44
  5. data/erl_src/riak_kv_test_backend.beam +0 -0
  6. data/erl_src/riak_kv_test_backend.erl +461 -128
  7. data/erl_src/riak_search_test_backend.beam +0 -0
  8. data/erl_src/riak_search_test_backend.erl +175 -0
  9. data/lib/active_support/cache/riak_store.rb +0 -13
  10. data/lib/riak.rb +11 -16
  11. data/lib/riak/bucket.rb +59 -41
  12. data/lib/riak/cache_store.rb +1 -14
  13. data/lib/riak/client.rb +145 -73
  14. data/lib/riak/client/beefcake/messages.rb +36 -31
  15. data/lib/riak/client/beefcake/object_methods.rb +27 -19
  16. data/lib/riak/client/beefcake_protobuffs_backend.rb +27 -33
  17. data/lib/riak/client/excon_backend.rb +0 -13
  18. data/lib/riak/client/http_backend.rb +95 -60
  19. data/lib/riak/client/http_backend/configuration.rb +144 -19
  20. data/lib/riak/client/http_backend/key_streamer.rb +1 -14
  21. data/lib/riak/client/http_backend/object_methods.rb +16 -16
  22. data/lib/riak/client/http_backend/request_headers.rb +0 -13
  23. data/lib/riak/client/http_backend/transport_methods.rb +26 -56
  24. data/lib/riak/client/net_http_backend.rb +11 -13
  25. data/lib/riak/client/protobuffs_backend.rb +21 -19
  26. data/lib/riak/client/pump.rb +1 -15
  27. data/lib/riak/client/search.rb +85 -0
  28. data/lib/riak/cluster.rb +151 -0
  29. data/lib/riak/core_ext.rb +1 -0
  30. data/lib/riak/core_ext/deep_dup.rb +13 -0
  31. data/lib/riak/core_ext/json.rb +15 -0
  32. data/lib/riak/core_ext/stringify_keys.rb +1 -1
  33. data/lib/riak/core_ext/symbolize_keys.rb +1 -1
  34. data/lib/riak/encoding.rb +6 -0
  35. data/lib/riak/failed_request.rb +2 -15
  36. data/lib/riak/i18n.rb +0 -13
  37. data/lib/riak/json.rb +19 -8
  38. data/lib/riak/link.rb +18 -20
  39. data/lib/riak/locale/en.yml +13 -16
  40. data/lib/riak/map_reduce.rb +40 -20
  41. data/lib/riak/map_reduce/filter_builder.rb +14 -18
  42. data/lib/riak/map_reduce/phase.rb +0 -13
  43. data/lib/riak/map_reduce_error.rb +0 -13
  44. data/lib/riak/node.rb +38 -0
  45. data/lib/riak/node/configuration.rb +286 -0
  46. data/lib/riak/node/console.rb +139 -0
  47. data/lib/riak/node/control.rb +207 -0
  48. data/lib/riak/node/defaults.rb +70 -0
  49. data/lib/riak/node/generation.rb +99 -0
  50. data/lib/riak/node/log.rb +34 -0
  51. data/lib/riak/node/version.rb +37 -0
  52. data/lib/riak/robject.rb +45 -41
  53. data/lib/riak/search.rb +2 -161
  54. data/lib/riak/serializers.rb +74 -0
  55. data/lib/riak/stamp.rb +77 -0
  56. data/lib/riak/test_server.rb +56 -220
  57. data/lib/riak/util/escape.rb +58 -17
  58. data/lib/riak/util/headers.rb +2 -15
  59. data/lib/riak/util/multipart.rb +0 -13
  60. data/lib/riak/util/multipart/stream_parser.rb +0 -13
  61. data/lib/riak/util/tcp_socket_extensions.rb +1 -14
  62. data/lib/riak/util/translation.rb +0 -13
  63. data/lib/riak/version.rb +3 -0
  64. data/lib/riak/walk_spec.rb +0 -13
  65. data/riak-client.gemspec +27 -47
  66. data/spec/fixtures/multipart-with-marked-tombstones.txt +17 -0
  67. data/spec/fixtures/multipart-with-unmarked-tombstone.txt +16 -0
  68. data/spec/integration/riak/cache_store_spec.rb +2 -40
  69. data/spec/integration/riak/cluster_spec.rb +88 -0
  70. data/spec/integration/riak/http_backends_spec.rb +6 -30
  71. data/spec/integration/riak/node_spec.rb +184 -0
  72. data/spec/integration/riak/protobuffs_backends_spec.rb +2 -26
  73. data/spec/integration/riak/test_server_spec.rb +31 -167
  74. data/spec/riak/beefcake_protobuffs_backend_spec.rb +5 -4
  75. data/spec/riak/bucket_spec.rb +26 -36
  76. data/spec/riak/client_spec.rb +44 -38
  77. data/spec/riak/escape_spec.rb +56 -30
  78. data/spec/riak/excon_backend_spec.rb +4 -17
  79. data/spec/riak/headers_spec.rb +1 -14
  80. data/spec/riak/http_backend/configuration_spec.rb +211 -34
  81. data/spec/riak/http_backend/object_methods_spec.rb +52 -18
  82. data/spec/riak/http_backend/transport_methods_spec.rb +5 -38
  83. data/spec/riak/http_backend_spec.rb +84 -78
  84. data/spec/riak/link_spec.rb +19 -18
  85. data/spec/riak/map_reduce/filter_builder_spec.rb +1 -14
  86. data/spec/riak/map_reduce/phase_spec.rb +1 -14
  87. data/spec/riak/map_reduce_spec.rb +141 -43
  88. data/spec/riak/multipart_spec.rb +1 -14
  89. data/spec/riak/net_http_backend_spec.rb +2 -15
  90. data/spec/riak/robject_spec.rb +129 -97
  91. data/spec/riak/search_spec.rb +45 -62
  92. data/spec/riak/serializers_spec.rb +93 -0
  93. data/spec/riak/stamp_spec.rb +54 -0
  94. data/spec/riak/stream_parser_spec.rb +3 -16
  95. data/spec/riak/walk_spec_spec.rb +1 -14
  96. data/spec/spec_helper.rb +22 -27
  97. data/spec/support/http_backend_implementation_examples.rb +49 -79
  98. data/spec/support/integration_setup.rb +10 -0
  99. data/spec/support/mock_server.rb +0 -14
  100. data/spec/support/mocks.rb +0 -13
  101. data/spec/support/test_server.rb +30 -0
  102. data/spec/support/test_server.yml.example +14 -2
  103. data/spec/support/unified_backend_examples.rb +36 -27
  104. metadata +100 -31
  105. data/lib/riak/client/curb_backend.rb +0 -89
  106. data/spec/riak/curb_backend_spec.rb +0 -76
@@ -0,0 +1,184 @@
1
+ require 'spec_helper'
2
+ require 'riak/node'
3
+ require 'yaml'
4
+
5
+ describe Riak::Node, :test_server => false, :slow => true do
6
+ let(:test_server_config){ YAML.load_file("spec/support/test_server.yml") }
7
+ subject { described_class.new(:root => ".ripplenode", :source => test_server_config['source']) }
8
+ after { subject.stop if subject.started? }
9
+ after(:all) { subject.destroy }
10
+
11
+ context "creation" do
12
+ before { subject.create }
13
+ after { subject.destroy }
14
+
15
+ describe "finding the base_dir and version" do
16
+ it "should return a valid directory for base_dir" do
17
+ subject.base_dir.should be_exist
18
+ end
19
+
20
+ it "should read a version from the releases directory" do
21
+ subject.version.should match /\d+.\d+.\d+/
22
+ end
23
+
24
+ it "should return nil for base_dir if RUNNER_BASE_DIR is not found" do
25
+ Pathname.any_instance.stub(:readlines).and_return([])
26
+ subject.base_dir.should be_nil
27
+ end
28
+
29
+ it "should return nil for version if base_dir is nil" do
30
+ Pathname.any_instance.stub(:readlines).and_return([])
31
+ subject.version.should be_nil
32
+ end
33
+ end
34
+
35
+ describe "generating the manifest" do
36
+ it "should store the configuration manifest in the node directory" do
37
+ (subject.root + '.node.yml').should be_exist
38
+ end
39
+ end
40
+
41
+ describe "generating app.config" do
42
+ let(:file) { subject.etc + 'app.config'}
43
+ let(:contents) { file.read }
44
+
45
+ it "should create the app.config file in the node directory" do
46
+ file.should be_exist
47
+ end
48
+
49
+ it "should generate a correct Erlang configuration" do
50
+ contents.should =~ /\A\[.*\]\.\Z/m
51
+ end
52
+
53
+ it "should set the ports starting from the given port" do
54
+ contents.should include('{http, [{"127.0.0.1", 8080}]}')
55
+ contents.should include('{pb_port, 8081}')
56
+ contents.should include('{handoff_port, 8082}')
57
+ end
58
+
59
+ it "should set the ring directory to point to the node directory" do
60
+ contents.should include("{ring_state_dir, \"#{subject.root + 'ring'}\"}")
61
+ end
62
+ end
63
+
64
+ describe "generating vm.args" do
65
+ let(:file){ subject.etc + 'vm.args' }
66
+ let(:contents) { file.read }
67
+
68
+ it "should create the vm.args file in the node directory" do
69
+ file.should be_exist
70
+ end
71
+
72
+ it "should set a quasi-random node name by default" do
73
+ contents.should match(/-name riak\d+@127\.0\.0\.1/)
74
+ end
75
+
76
+ it "should set a quasi-random cookie by default" do
77
+ contents.should match(/-setcookie \d+_\d+/)
78
+ end
79
+ end
80
+
81
+ describe "generating the start script" do
82
+ let(:file) { subject.control_script }
83
+ let(:contents) { file.read }
84
+
85
+ it "should create the script in the node directory" do
86
+ file.should be_exist
87
+ end
88
+
89
+ it "should modify the RUNNER_SCRIPT_DIR to point to the node directory" do
90
+ contents.should match(/RUNNER_SCRIPT_DIR=#{subject.bin.to_s}/)
91
+ end
92
+
93
+ it "should modify the RUNNER_ETC_DIR to point to the node directory" do
94
+ contents.should match(/RUNNER_ETC_DIR=#{subject.etc.to_s}/)
95
+ end
96
+
97
+ it "should modify the RUNNER_USER to point to none" do
98
+ contents.should match(/RUNNER_USER=$/)
99
+ end
100
+
101
+ it "should modify the RUNNER_LOG_DIR to point to the node directory" do
102
+ contents.should match(/RUNNER_LOG_DIR=#{subject.log.to_s}/)
103
+ end
104
+
105
+ it "should modify the RUNNER_BASE_DIR so that it is not relative" do
106
+ contents.should_not match(/RUNNER_BASE_DIR=\$\{RUNNER_SCRIPT_DIR%\/\*\}/)
107
+ contents.should match(/RUNNER_BASE_DIR=(.*)/) do |path|
108
+ path.strip.should == subject.root.to_s
109
+ end
110
+ end
111
+
112
+ it "should modify the PIPE_DIR to point to the node directory" do
113
+ contents.should match(/PIPE_DIR=#{subject.pipe.to_s}\/?/)
114
+ end
115
+ end
116
+ end
117
+
118
+ context "destroying" do
119
+ before { subject.create; subject.destroy }
120
+
121
+ it "should remove the node directory and all its contents" do
122
+ subject.root.should_not be_exist
123
+ end
124
+ end
125
+
126
+ context "dropping data" do
127
+ before do
128
+ subject.create
129
+ subject.start # Make it create some data directories
130
+ subject.with_console do |console|
131
+ # Write a ringfile
132
+ console.command "riak_core_ring_manager:write_ringfile()."
133
+ end
134
+ # Don't restart the node after dropping so we can see the handiwork
135
+ subject.stop
136
+ subject.drop
137
+ end
138
+
139
+ it "should remove all data from the node" do
140
+ (subject.root + 'data').children.map {|dir| dir.children }.flatten.should be_empty
141
+ end
142
+
143
+ it "should not remove the ring" do
144
+ (subject.root + 'ring').children.should_not be_empty
145
+ end
146
+ end
147
+
148
+ context "starting" do
149
+ before { subject.create; subject.start }
150
+ it { should be_started }
151
+ after { subject.stop }
152
+ end
153
+
154
+ context "stopping" do
155
+ before { subject.create; subject.start; subject.stop }
156
+ it { should be_stopped }
157
+ end
158
+
159
+ context "attaching" do
160
+ before { subject.create; subject.start }
161
+
162
+ it "should attach to the running node" do
163
+ console = subject.attach
164
+ console.should be_kind_of(Riak::Node::Console)
165
+ expect {
166
+ console.command "ok."
167
+ console.close
168
+ }.should_not raise_error
169
+ end
170
+ end
171
+
172
+ context "running" do
173
+ before { subject.create; subject.start; subject.stop }
174
+
175
+ it "should read the console log" do
176
+ if subject.version >= "1.0.0"
177
+ subject.read_console_log(:debug, :info, :notice).should_not be_empty
178
+ subject.read_console_log(:debug..:emergency).should_not be_empty
179
+ subject.read_console_log(:info).should_not be_empty
180
+ subject.read_console_log(:foo).should be_empty
181
+ end
182
+ end
183
+ end
184
+ end
@@ -1,35 +1,11 @@
1
- # Copyright 2010 Sean Cribbs and Basho Technologies, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
- require File.expand_path("../../spec_helper", File.dirname(__FILE__))
1
+ require 'spec_helper'
15
2
 
16
3
  describe "Protocol Buffers" do
17
- before :all do
18
- if $test_server
19
- @pbc_port = 9002
20
- $test_server.start
21
- end
22
- end
23
-
24
4
  before do
25
- @pbc_port ||= 8087
5
+ @pbc_port ||= $test_server.pb_port
26
6
  @client = Riak::Client.new(:pb_port => @pbc_port, :protocol => "pbc")
27
7
  end
28
8
 
29
- after do
30
- $test_server.recycle if $test_server.started?
31
- end
32
-
33
9
  [:BeefcakeProtobuffsBackend].each do |klass|
34
10
  bklass = Riak::Client.const_get(klass)
35
11
  if bklass.configured?
@@ -1,174 +1,38 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
- require File.expand_path("../../spec_helper", File.dirname(__FILE__))
1
+ require 'spec_helper'
2
+ require 'riak/test_server'
15
3
 
16
- if $test_server
17
- describe Riak::TestServer do
18
- before do
19
- @server = $test_server
20
- end
4
+ describe Riak::TestServer do
5
+ subject { $test_server }
6
+ let(:app_config) { (subject.etc + 'app.config').read }
21
7
 
22
- after do
23
- @server.stop
24
- @server.cleanup
25
- end
26
-
27
- describe "isolation from and modification of the existing install" do
28
- before do
29
- @server.prepare!
30
- @riak_bin = "#{@server.temp_dir}/bin/riak"
31
- @vm_args = "#{@server.temp_dir}/etc/vm.args"
32
- @app_config = "#{@server.temp_dir}/etc/app.config"
33
- end
34
-
35
- describe "for app.config" do
36
- it "should create the app.config file in the temporary directory" do
37
- File.should be_exist(File.expand_path(@app_config))
38
- end
39
-
40
- it "should be a correct Erlang config" do
41
- config = File.read(@app_config)
42
- config[-2..-1].should == '].'
43
- config[0..0].should == '['
44
- end
45
-
46
- it "should set the backend to use the test backend" do
47
- File.readlines(@app_config).should be_any do |line|
48
- line =~ /\{storage_backend\s*,\s*(.*)\}/ && $1 == "riak_kv_test_backend"
49
- end
50
- end
51
-
52
- it "should set the default ports to 9000-9002" do
53
- config = File.readlines(@app_config)
54
- config.should be_any do |line|
55
- line =~ /\{web_port\s*,\s*(.*)\}/ && $1 == "9000"
56
- end
57
- config.should be_any do |line|
58
- line =~ /\{handoff_port\s*,\s*(.*)\}/ && $1 == "9001"
59
- end
60
- config.should be_any do |line|
61
- line =~ /\{pb_port\s*,\s*(.*)\}/ && $1 == "9002"
62
- end
63
- end
64
-
65
- it "should set the ring directory to point to the temporary directory" do
66
- config = File.readlines(@app_config)
67
- config.should be_any do |line|
68
- line =~ /\{ring_state_dir\s*,\s*(.*)\}/ && $1 == File.join(@server.temp_dir, "data", "ring")
69
- end
70
- end
71
- end
72
-
73
- describe "for vm.args" do
74
- it "should create the vm.args file in the temporary directory" do
75
- File.should be_exist(File.expand_path(@vm_args))
76
- end
77
-
78
- it "should set a quasi-random node name" do
79
- File.readlines(@vm_args).should be_any do |line|
80
- line =~ /^-name (.*)/ && $1 =~ /riaktest\d+@/
81
- end
82
- end
83
-
84
- it "should set a quasi-random cookie" do
85
- File.readlines(@vm_args).should be_any do |line|
86
- line =~ /^-setcookie (.*)/ && $1 != "riak"
87
- end
88
- end
89
- end
90
-
91
- describe "for the riak script" do
92
- it "should create the script in the temporary directory" do
93
- File.should be_exist(File.expand_path(@riak_bin))
94
- end
95
-
96
- it "should modify the RUNNER_SCRIPT_DIR to point to the temporary directory" do
97
- File.readlines(@riak_bin).should be_any do |line|
98
- line =~ /RUNNER_SCRIPT_DIR=(.*)/ && $1 == File.expand_path("#{@server.temp_dir}/bin")
99
-
100
- end
101
- end
102
-
103
- it "should modify the RUNNER_ETC_DIR to point to the temporary directory" do
104
- File.readlines(@riak_bin).should be_any do |line|
105
- line =~ /RUNNER_ETC_DIR=(.*)/ && $1 == File.expand_path("#{@server.temp_dir}/etc")
106
- end
107
- end
108
-
109
- it "should modify the RUNNER_USER to point to the current user" do
110
- File.readlines(@riak_bin).should be_any do |line|
111
- line =~ /RUNNER_USER=(.*)/ && $1 == (ENV['USER'] || `whoami`)
112
- end
113
- end
114
-
115
- it "should modify the RUNNER_LOG_DIR to point to the temporary directory" do
116
- File.readlines(@riak_bin).should be_any do |line|
117
- line =~ /RUNNER_LOG_DIR=(.*)/ && $1 == File.expand_path("#{@server.temp_dir}/log")
118
- end
119
- end
120
-
121
- it "should modify the RUNNER_BASE_DIR so that it is not relative" do
122
- File.readlines(@riak_bin).should be_any do |line|
123
- line =~ /RUNNER_BASE_DIR=(.*)/ && $1.strip != "${RUNNER_SCRIPT_DIR%/*}" && File.directory?($1)
124
- end
125
- end
126
-
127
- it "should modify the PIPE_DIR to point to the temporary directory" do
128
- File.readlines(@riak_bin).should be_any do |line|
129
- line =~ /PIPE_DIR=(.*)/ && $1 == File.expand_path("#{@server.temp_dir}/pipe") && File.directory?($1)
130
- end
131
- end
132
- end
133
- end
134
-
135
- it "should cleanup the existing config" do
136
- @server.prepare!
137
- @server.cleanup
138
- File.should_not be_directory(@server.temp_dir)
139
- end
140
-
141
- it "should start Riak in the background" do
142
- @server.prepare!
143
- @server.start.should be_true
144
- @server.should be_started
145
- end
146
-
147
- it "should stop a started test server" do
148
- @server.prepare!
149
- @server.start.should be_true
150
- @server.stop
151
- @server.should_not be_started
152
- end
8
+ it "should add the test backends to the code path" do
9
+ erl_src = File.expand_path("../../../../erl_src", __FILE__)
10
+ subject.env[:riak_kv][:add_paths].should include(erl_src)
11
+ app_config.should match(/\{add_paths, \[.*#{erl_src.inspect}.*\]\}/)
12
+ end
153
13
 
154
- it "should recycle the server contents" do
155
- begin
156
- @server.prepare!
157
- @server.start.should be_true
14
+ it "should use the KV test backend" do
15
+ subject.kv_backend.should == :riak_kv_test_backend
16
+ subject.env[:riak_kv][:storage_backend].should == :riak_kv_test_backend
17
+ app_config.should include("{storage_backend, riak_kv_test_backend}")
18
+ end
158
19
 
159
- client = Riak::Client.new(:http_port => 9000)
160
- obj = client['test_bucket'].new("test_item")
161
- obj.data = {"data" => "testing"}
162
- obj.store rescue nil
20
+ it "should use the Search test backend" do
21
+ subject.search_backend.should == :riak_search_test_backend
22
+ subject.env[:riak_search][:search_backend].should == :riak_search_test_backend
23
+ app_config.should include("{search_backend, riak_search_test_backend}")
24
+ end
163
25
 
164
- @server.recycle
165
- @server.should be_started
166
- lambda do
167
- client['test_bucket']['test_item']
168
- end.should raise_error(Riak::FailedRequest)
169
- ensure
170
- @server.stop
171
- end
172
- end
26
+ it "should clear stored data" do
27
+ # TODO: use $test_server.to_host when client/host split is finished.
28
+ client = Riak::Client.new(:http_port => subject.http_port)
29
+ obj = client['test_bucket'].new("test_item")
30
+ obj.data = {"data" => "testing"}
31
+ obj.store # rescue nil
32
+
33
+ subject.drop
34
+ expect {
35
+ client['test_bucket']['test_item']
36
+ }.to raise_error(Riak::FailedRequest)
173
37
  end
174
38
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path("../spec_helper", File.dirname(__FILE__))
1
+ require 'spec_helper'
2
2
  require 'riak/client/beefcake/messages'
3
3
 
4
4
  describe Riak::Client::BeefcakeProtobuffsBackend do
@@ -45,7 +45,7 @@ describe Riak::Client::BeefcakeProtobuffsBackend, '#mapred' do
45
45
  @backend = Riak::Client::BeefcakeProtobuffsBackend.new(@client)
46
46
  @backend.instance_variable_set(:@server_config, {})
47
47
  end
48
-
48
+
49
49
  it "should not return nil for previous phases that don't return anything" do
50
50
  socket = stub(:socket).as_null_object
51
51
  socket.stub(:read).and_return(stub(:socket_header, :unpack => [2, 24]), stub(:socket_message), stub(:socket_header_2, :unpack => [0, 1]))
@@ -53,7 +53,8 @@ describe Riak::Client::BeefcakeProtobuffsBackend, '#mapred' do
53
53
  message.stub(:done).and_return(false, true)
54
54
  Riak::Client::BeefcakeProtobuffsBackend::RpbMapRedResp.stub(:decode => message)
55
55
  TCPSocket.stub(:new => socket)
56
-
56
+ @backend.send(:reset_socket)
57
+
57
58
  @backend.mapred('').should == [{}]
58
59
  end
59
- end
60
+ end