couchbase-jruby-client 0.1.0-java

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 (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +203 -0
  6. data/README.md +347 -0
  7. data/Rakefile +10 -0
  8. data/couchbase-jruby-client.gemspec +30 -0
  9. data/lib/couchbase/async/callback.rb +19 -0
  10. data/lib/couchbase/async/queue.rb +26 -0
  11. data/lib/couchbase/async.rb +139 -0
  12. data/lib/couchbase/bucket.rb +663 -0
  13. data/lib/couchbase/cluster.rb +105 -0
  14. data/lib/couchbase/constants.rb +12 -0
  15. data/lib/couchbase/error.rb +28 -0
  16. data/lib/couchbase/jruby/couchbase_client.rb +22 -0
  17. data/lib/couchbase/jruby/future.rb +8 -0
  18. data/lib/couchbase/operations/arithmetic.rb +301 -0
  19. data/lib/couchbase/operations/delete.rb +104 -0
  20. data/lib/couchbase/operations/get.rb +298 -0
  21. data/lib/couchbase/operations/stats.rb +16 -0
  22. data/lib/couchbase/operations/store.rb +468 -0
  23. data/lib/couchbase/operations/touch.rb +123 -0
  24. data/lib/couchbase/operations/utils.rb +49 -0
  25. data/lib/couchbase/operations.rb +23 -0
  26. data/lib/couchbase/result.rb +43 -0
  27. data/lib/couchbase/transcoder.rb +83 -0
  28. data/lib/couchbase/utils.rb +62 -0
  29. data/lib/couchbase/version.rb +3 -0
  30. data/lib/couchbase/view.rb +506 -0
  31. data/lib/couchbase/view_row.rb +272 -0
  32. data/lib/couchbase.rb +177 -0
  33. data/lib/jars/commons-codec-1.5.jar +0 -0
  34. data/lib/jars/couchbase-client-1.2.0-javadoc.jar +0 -0
  35. data/lib/jars/couchbase-client-1.2.0-sources.jar +0 -0
  36. data/lib/jars/couchbase-client-1.2.0.jar +0 -0
  37. data/lib/jars/httpcore-4.1.1.jar +0 -0
  38. data/lib/jars/httpcore-nio-4.1.1.jar +0 -0
  39. data/lib/jars/jettison-1.1.jar +0 -0
  40. data/lib/jars/netty-3.5.5.Final.jar +0 -0
  41. data/lib/jars/spymemcached-2.10.0-javadoc.jar +0 -0
  42. data/lib/jars/spymemcached-2.10.0-sources.jar +0 -0
  43. data/lib/jars/spymemcached-2.10.0.jar +0 -0
  44. data/test/profile/.gitignore +1 -0
  45. data/test/profile/Gemfile +6 -0
  46. data/test/profile/benchmark.rb +195 -0
  47. data/test/setup.rb +201 -0
  48. data/test/test_arithmetic.rb +177 -0
  49. data/test/test_async.rb +324 -0
  50. data/test/test_bucket.rb +213 -0
  51. data/test/test_cas.rb +78 -0
  52. data/test/test_couchbase.rb +29 -0
  53. data/test/test_couchbase_rails_cache_store.rb +341 -0
  54. data/test/test_delete.rb +125 -0
  55. data/test/test_errors.rb +82 -0
  56. data/test/test_format.rb +161 -0
  57. data/test/test_get.rb +417 -0
  58. data/test/test_stats.rb +57 -0
  59. data/test/test_store.rb +216 -0
  60. data/test/test_timer.rb +42 -0
  61. data/test/test_touch.rb +97 -0
  62. data/test/test_unlock.rb +119 -0
  63. data/test/test_utils.rb +58 -0
  64. data/test/test_version.rb +52 -0
  65. metadata +226 -0
data/test/setup.rb ADDED
@@ -0,0 +1,201 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2011, 2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ gem 'minitest'
19
+ require 'minitest/autorun'
20
+ require 'couchbase'
21
+
22
+ require 'socket'
23
+ require 'open-uri'
24
+
25
+ # Surpress connection logging
26
+ # java_import java.lang.System
27
+ # java_import java.util.logging.Logger
28
+ # java_import java.util.logging.Level
29
+
30
+ # properties = System.getProperties
31
+ # properties.put("net.spy.log.LoggerImpl", "net.spy.memcached.compat.log.Log4JLogger")
32
+ # System.setProperties(properties)
33
+
34
+ # Logger.getLogger('net.spy.memcached').setLevel(Level::SEVERE)
35
+ # Logger.getLogger('com.couchbase.client').setLevel(Level::SEVERE)
36
+ # Logger.getLogger('com.couchbase.client.vbucket').setLevel(Level::SEVERE)
37
+
38
+ # $stderr = StringIO.new
39
+
40
+ Minitest.after_run { Couchbase.disconnect }
41
+
42
+ class CouchbaseServer
43
+ attr_accessor :host, :port, :num_nodes, :buckets_spec
44
+
45
+ def real?
46
+ true
47
+ end
48
+
49
+ def initialize(params = {})
50
+ @host, @port = ['localhost', 8091] #ENV['COUCHBASE_SERVER'].split(':')
51
+ @port = @port.to_i
52
+
53
+ if @host.nil? || @host.empty? || @port == 0
54
+ raise ArgumentError, "Check COUCHBASE_SERVER variable. It should be hostname:port"
55
+ end
56
+
57
+ @config = MultiJson.load(open("http://#{@host}:#{@port}/pools/default"))
58
+ @num_nodes = @config["nodes"].size
59
+ @buckets_spec = params[:buckets_spec] || "default:" # "default:,protected:secret,cache::memcache"
60
+ end
61
+
62
+ def start
63
+ # flush all buckets
64
+ @buckets_spec.split(',') do |bucket|
65
+ name, password, _ = bucket.split(':')
66
+ connection = Couchbase.new(:hostname => @host,
67
+ :port => @port,
68
+ :username => name,
69
+ :bucket => name,
70
+ :password => password)
71
+ begin
72
+ connection.flush
73
+ rescue Couchbase::Error::NotSupported
74
+ # on recent server flush is disabled
75
+ ensure
76
+ connection.disconnect
77
+ end
78
+ end if ENV['COUCHBASE_FLUSH_BUCKETS']
79
+ end
80
+
81
+ def stop
82
+ end
83
+ end
84
+
85
+ class CouchbaseMock
86
+ Monitor = Struct.new(:pid, :client, :socket, :port)
87
+
88
+ attr_accessor :host, :port, :buckets_spec, :num_nodes, :num_vbuckets
89
+
90
+ def real?
91
+ false
92
+ end
93
+
94
+ def initialize(params = {})
95
+ @host = "127.0.0.1"
96
+ @port = 0
97
+ @num_nodes = 10
98
+ @num_vbuckets = 4096
99
+ @buckets_spec = "default:" # "default:,protected:secret,cache::memcache"
100
+ params.each do |key, value|
101
+ send("#{key}=", value)
102
+ end
103
+ yield self if block_given?
104
+ if @num_vbuckets < 1 || (@num_vbuckets & (@num_vbuckets - 1) != 0)
105
+ raise ArgumentError, "Number of vbuckets should be a power of two and greater than zero"
106
+ end
107
+ end
108
+
109
+ def start
110
+ @monitor = Monitor.new
111
+ @monitor.socket = TCPServer.new(nil, 0)
112
+ @monitor.socket.listen(10)
113
+ _, @monitor.port, _, _ = @monitor.socket.addr
114
+ trap("CLD") do
115
+ puts "CouchbaseMock.jar died unexpectedly during startup"
116
+ exit(1)
117
+ end
118
+ @monitor.pid = fork
119
+ if @monitor.pid.nil?
120
+ rc = exec(command_line("--harakiri-monitor=:#{@monitor.port}"))
121
+ else
122
+ trap("CLD", "SIG_DFL")
123
+ @monitor.client, _ = @monitor.socket.accept
124
+ @port = @monitor.client.recv(100).to_i
125
+ end
126
+ end
127
+
128
+ def stop
129
+ @monitor.client.close
130
+ @monitor.socket.close
131
+ Process.kill("TERM", @monitor.pid)
132
+ Process.wait(@monitor.pid)
133
+ end
134
+
135
+ def failover_node(index, bucket = "default")
136
+ @monitor.client.send("failover,#{index},#{bucket}", 0)
137
+ end
138
+
139
+ def respawn_node(index, bucket = "default")
140
+ @monitor.client.send("respawn,#{index},#{bucket}", 0)
141
+ end
142
+
143
+ protected
144
+
145
+ def command_line(extra = nil)
146
+ cmd = "java -jar #{File.dirname(__FILE__)}/CouchbaseMock.jar"
147
+ cmd << " --host #{@host}" if @host
148
+ cmd << " --port #{@port}" if @port
149
+ cmd << " --nodes #{@num_nodes}" if @num_nodes
150
+ cmd << " --vbuckets #{@num_vbuckets}" if @num_vbuckets
151
+ cmd << " --buckets #{@buckets_spec}" if @buckets_spec
152
+ cmd << " #{extra}"
153
+ cmd
154
+ end
155
+ end
156
+
157
+ class MiniTest::Test
158
+
159
+ def start_mock(params = {})
160
+ mock = nil
161
+ if true # ENV['COUCHBASE_SERVER']
162
+ mock = CouchbaseServer.new(params)
163
+ if (params[:port] && mock.port != params[:port]) ||
164
+ (params[:host] && mock.host != params[:host]) ||
165
+ mock.buckets_spec != "default:"
166
+ skip("Unable to configure real cluster. Requested config is: #{params.inspect}")
167
+ end
168
+ else
169
+ mock = CouchbaseMock.new(params)
170
+ end
171
+ mock.start
172
+ mock
173
+ end
174
+
175
+ def stop_mock(mock)
176
+ assert(mock)
177
+ mock.stop
178
+ end
179
+
180
+ def with_mock(params = {})
181
+ return
182
+ mock = nil
183
+ if block_given?
184
+ mock = start_mock(params)
185
+ yield mock
186
+ end
187
+ ensure
188
+ stop_mock(mock) if mock
189
+ end
190
+
191
+ def uniq_id(*suffixes)
192
+ test_id = [caller.first[/.*[` ](.*)'/, 1], suffixes].compact.join("_")
193
+ @ids ||= {}
194
+ @ids[test_id] ||= Time.now.to_f
195
+ [test_id, @ids[test_id]].join("_")
196
+ end
197
+
198
+ def after_teardown
199
+ GC.start
200
+ end
201
+ end
@@ -0,0 +1,177 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2011, 2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require File.join(File.dirname(__FILE__), 'setup')
19
+
20
+ class TestArithmetic < MiniTest::Test
21
+
22
+ def setup
23
+ @mock = start_mock
24
+ end
25
+
26
+ def teardown
27
+ stop_mock(@mock)
28
+ end
29
+
30
+ def test_trivial_incr_decr
31
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
32
+
33
+ connection.set(uniq_id, 1)
34
+ val = connection.incr(uniq_id)
35
+ assert_equal 2, val
36
+ val = connection.get(uniq_id)
37
+ assert_equal 2, val
38
+
39
+ connection.set(uniq_id, 7)
40
+ val = connection.decr(uniq_id)
41
+ assert_equal 6, val
42
+ val = connection.get(uniq_id)
43
+ assert_equal 6, val
44
+ end
45
+
46
+ def test_it_fails_to_incr_decr_missing_key
47
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
48
+
49
+ assert_raises(Couchbase::Error::NotFound) do
50
+ connection.incr(uniq_id(:missing))
51
+ end
52
+ assert_raises(Couchbase::Error::NotFound) do
53
+ connection.decr(uniq_id(:missing))
54
+ end
55
+ end
56
+
57
+ def test_it_allows_to_make_increments_less_verbose_by_forcing_create_by_default
58
+ connection = Couchbase.connect(:hostname => @mock.host, :port => @mock.port,
59
+ :default_arithmetic_init => true)
60
+ assert_raises(Couchbase::Error::NotFound) do
61
+ connection.get(uniq_id)
62
+ end
63
+ assert_equal 0, connection.incr(uniq_id), "return value"
64
+ assert_equal 0, connection.get(uniq_id), "via get command"
65
+ end
66
+
67
+ def test_it_allows_to_setup_initial_value_during_connection
68
+ connection = Couchbase.connect(:hostname => @mock.host, :port => @mock.port,
69
+ :default_arithmetic_init => 10)
70
+ assert_raises(Couchbase::Error::NotFound) do
71
+ connection.get(uniq_id)
72
+ end
73
+
74
+ assert_equal 10, connection.incr(uniq_id), "return value"
75
+ assert_equal 10, connection.get(uniq_id), "via get command"
76
+ end
77
+
78
+ def test_it_allows_to_change_default_initial_value_after_connection
79
+ connection = Couchbase.connect(:hostname => @mock.host, :port => @mock.port)
80
+
81
+ assert_equal 0, connection.default_arithmetic_init
82
+ assert_raises(Couchbase::Error::NotFound) do
83
+ connection.incr(uniq_id)
84
+ end
85
+
86
+ connection.default_arithmetic_init = 10
87
+ assert_equal 10, connection.default_arithmetic_init
88
+ assert_raises(Couchbase::Error::NotFound) do
89
+ connection.get(uniq_id)
90
+ end
91
+ assert_equal 10, connection.incr(uniq_id), "return value"
92
+ assert_equal 10, connection.get(uniq_id), "via get command"
93
+ end
94
+
95
+ def test_it_creates_missing_key_when_initial_value_specified
96
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
97
+
98
+ val = connection.incr(uniq_id(:missing), :initial => 5)
99
+ assert_equal 5, val
100
+ val = connection.incr(uniq_id(:missing), :initial => 5)
101
+ assert_equal 6, val
102
+ val = connection.get(uniq_id(:missing))
103
+ assert_equal 6, val
104
+ end
105
+
106
+ def test_it_uses_zero_as_default_value_for_missing_keys
107
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
108
+
109
+ val = connection.incr(uniq_id(:missing), :create => true)
110
+ assert_equal 0, val
111
+ val = connection.incr(uniq_id(:missing), :create => true)
112
+ assert_equal 1, val
113
+ val = connection.get(uniq_id(:missing))
114
+ assert_equal 1, val
115
+ end
116
+
117
+ def test_it_allows_custom_ttl
118
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
119
+
120
+ val = connection.incr(uniq_id(:missing), :create => true, :ttl => 1)
121
+ assert_equal 0, val
122
+ val = connection.incr(uniq_id(:missing), :create => true)
123
+ assert_equal 1, val
124
+ sleep(2)
125
+ assert_raises(Couchbase::Error::NotFound) do
126
+ connection.get(uniq_id(:missing))
127
+ end
128
+ end
129
+
130
+ def test_decrement_with_absolute_ttl
131
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
132
+ # absolute TTL: one second from now
133
+ exp = Time.now.to_i + 1
134
+ val = connection.decr(uniq_id, 12, :initial => 0, :ttl => exp)
135
+ assert_equal 0, val
136
+ assert_equal 0, connection.get(uniq_id)
137
+ sleep(2)
138
+ assert_raises(Couchbase::Error::NotFound) do
139
+ refute connection.get(uniq_id)
140
+ end
141
+ end
142
+
143
+ def test_it_allows_custom_delta
144
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
145
+
146
+ connection.set(uniq_id, 12)
147
+ val = connection.incr(uniq_id, 10)
148
+ assert_equal 22, val
149
+ end
150
+
151
+ def test_it_allows_to_specify_delta_in_options
152
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
153
+
154
+ connection.set(uniq_id, 12)
155
+ options = {:delta => 10}
156
+ val = connection.incr(uniq_id, options)
157
+ assert_equal 22, val
158
+ end
159
+
160
+ def test_multi_incr
161
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
162
+ connection.set(uniq_id(:foo) => 1, uniq_id(:bar) => 1)
163
+
164
+ assert_equal [2, 2], connection.incr(uniq_id(:foo), uniq_id(:bar)).values.sort
165
+ assert_equal [12, 12], connection.incr(uniq_id(:foo), uniq_id(:bar), :delta => 10).values.sort
166
+ assert_equal [14, 15], connection.incr(uniq_id(:foo) => 2, uniq_id(:bar) => 3).values.sort
167
+ end
168
+
169
+ def test_multi_decr
170
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
171
+ connection.set(uniq_id(:foo) => 14, uniq_id(:bar) => 15)
172
+
173
+ assert_equal [12, 12], connection.decr(uniq_id(:foo) => 2, uniq_id(:bar) => 3).values.sort
174
+ assert_equal [2, 2], connection.decr(uniq_id(:foo), uniq_id(:bar), :delta => 10).values.sort
175
+ assert_equal [1, 1], connection.decr(uniq_id(:foo), uniq_id(:bar)).values.sort
176
+ end
177
+ end
@@ -0,0 +1,324 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2011, 2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require File.join(File.dirname(__FILE__), 'setup')
19
+
20
+ class TestAsync < MiniTest::Test
21
+
22
+ def setup
23
+ @mock = start_mock
24
+ end
25
+
26
+ def teardown
27
+ stop_mock(@mock)
28
+ end
29
+
30
+ def test_result_object_provides_enough_info
31
+ obj = Couchbase::Result.new
32
+ assert obj.respond_to?(:success?)
33
+ assert obj.respond_to?(:error)
34
+ assert obj.respond_to?(:key)
35
+ assert obj.respond_to?(:value)
36
+ assert obj.respond_to?(:node)
37
+ assert obj.respond_to?(:cas)
38
+ end
39
+
40
+ def test_it_requires_block_for_running_loop
41
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
42
+ refute connection.async?
43
+ assert_raises(LocalJumpError) do
44
+ connection.run
45
+ end
46
+ connection.run do |conn|
47
+ assert conn.async?
48
+ end
49
+ end
50
+
51
+ def test_it_resets_async_flag_when_raising_exception_from_callback
52
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
53
+
54
+ assert_raises(RuntimeError) do
55
+ connection.run do |conn|
56
+ conn.set(uniq_id, "foo") { raise }
57
+ end
58
+ end
59
+ refute connection.async?
60
+ end
61
+
62
+ def test_nested_async_get_set
63
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
64
+ connection.set(uniq_id, {"bar" => 1})
65
+ connection.set(uniq_id(:hit), 0)
66
+
67
+ connection.run do |conn|
68
+ conn.get(uniq_id) do
69
+ conn.get(uniq_id(:hit)) do |res|
70
+ conn.set(uniq_id(:hit), res.value + 1)
71
+ end
72
+ end
73
+ end
74
+
75
+ val = connection.get(uniq_id(:hit))
76
+ assert_equal 1, val
77
+ end
78
+
79
+ def test_nested_async_set_get
80
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
81
+ val = nil
82
+
83
+ connection.run do |conn|
84
+ conn.set(uniq_id, "foo") do
85
+ conn.get(uniq_id) do |res|
86
+ val = res.value
87
+ end
88
+ end
89
+ end
90
+
91
+ assert_equal "foo", val
92
+ end
93
+
94
+ def test_nested_async_touch_get
95
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
96
+ connection.set(uniq_id, "foo")
97
+ success = false
98
+ val = nil
99
+
100
+ connection.run do |conn|
101
+ conn.touch(uniq_id, :ttl => 1) do |res1|
102
+ success = res1.success?
103
+ conn.get(uniq_id) do |res2|
104
+ val = res2.value
105
+ end
106
+ end
107
+ end
108
+
109
+ assert success
110
+ assert_equal "foo", val
111
+ sleep(2)
112
+ assert_raises(Couchbase::Error::NotFound) do
113
+ connection.get(uniq_id)
114
+ end
115
+ end
116
+
117
+ def test_nested_async_delete_get
118
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
119
+ cas = connection.set(uniq_id, "foo")
120
+ success = false
121
+ val = :unknown
122
+
123
+ connection.run do |conn|
124
+ conn.delete(uniq_id, :cas => cas) do |res1|
125
+ success = res1.success?
126
+ conn.get(uniq_id, :quiet => true) do |res2|
127
+ val = res2.value
128
+ end
129
+ end
130
+ end
131
+
132
+ assert success
133
+ refute val
134
+ end
135
+
136
+ def test_nested_async_stats_set
137
+ skip
138
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
139
+ stats = {}
140
+
141
+ connection.run do |conn|
142
+ conn.stats do |res1|
143
+ id = uniq_id(res1.node, res1.key)
144
+ stats[id] = false
145
+ conn.set(id, res1.value) do |res2|
146
+ stats[id] = res2.cas
147
+ end
148
+ end
149
+ end
150
+
151
+ stats.keys.each do |key|
152
+ assert stats[key].is_a?(Numeric)
153
+ end
154
+ end
155
+
156
+ def test_nested_async_flush_set
157
+ skip
158
+ if @mock.real?
159
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
160
+ cas = connection.set(uniq_id, "foo")
161
+ res = {}
162
+
163
+ connection.run do |conn|
164
+ conn.flush do |res1|
165
+ assert res1.success?, "Expected: successful status code.\nActual: #{res1.error.inspect}"
166
+ id = uniq_id(res1.node)
167
+ res[id] = false
168
+ conn.set(id, true) do |res2|
169
+ res[id] = res2.cas
170
+ end
171
+ end
172
+ end
173
+
174
+ assert_raises(Couchbase::Error::NotFound) do
175
+ connection.get(uniq_id)
176
+ end
177
+ res.keys.each do |key|
178
+ assert res[key].is_a?(Numeric)
179
+ assert connection.get(key)
180
+ end
181
+ else
182
+ skip("REST FLUSH isn't implemented in CouchbaseMock.jar yet")
183
+ end
184
+ end
185
+
186
+ def test_nested_async_incr_get
187
+ skip
188
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
189
+ cas = connection.set(uniq_id, 1)
190
+ val = nil
191
+
192
+ connection.run do |conn|
193
+ conn.incr(uniq_id) do
194
+ conn.get(uniq_id) do |res|
195
+ val = res.value
196
+ end
197
+ end
198
+ end
199
+
200
+ assert_equal 2, val
201
+ end
202
+
203
+ def test_it_doesnt_accept_callbacks_in_synchronous_mode
204
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
205
+ refute connection.async?
206
+
207
+ assert_raises(ArgumentError) { connection.add(uniq_id, "foo") {} }
208
+ assert_raises(ArgumentError) { connection.set(uniq_id, "foo") {} }
209
+ assert_raises(ArgumentError) { connection.replace(uniq_id, "foo") {} }
210
+ assert_raises(ArgumentError) { connection.get(uniq_id) {} }
211
+ assert_raises(ArgumentError) { connection.touch(uniq_id) {} }
212
+ assert_raises(ArgumentError) { connection.incr(uniq_id) {} }
213
+ assert_raises(ArgumentError) { connection.decr(uniq_id) {} }
214
+ assert_raises(ArgumentError) { connection.delete(uniq_id) {} }
215
+ assert_raises(ArgumentError) { connection.append(uniq_id, "bar") {} }
216
+ assert_raises(ArgumentError) { connection.prepend(uniq_id, "bar") {} }
217
+ assert_raises(ArgumentError) { connection.flush {} }
218
+ assert_raises(ArgumentError) { connection.stats {} }
219
+ end
220
+
221
+ def test_it_disallow_nested_run
222
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
223
+ assert_raises(Couchbase::Error::Invalid) do
224
+ connection.run do
225
+ connection.run do
226
+ end
227
+ end
228
+ end
229
+ end
230
+
231
+ def test_it_extends_timeout_in_async_mode_if_needed
232
+ skip
233
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
234
+ connection.set(uniq_id, "foo")
235
+
236
+ connection.timeout = 100_000 # 100_000 us
237
+ connection.run do
238
+ connection.get(uniq_id) do |ret|
239
+ assert ret.success?
240
+ assert_equal "foo", ret.value
241
+ end
242
+ sleep(1.5) # 1_500_000 us
243
+ end
244
+ end
245
+
246
+ def test_send_threshold
247
+ skip
248
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
249
+
250
+ sent = false
251
+ connection.run(:send_threshold => 100) do # 100 bytes
252
+ connection.set(uniq_id, "foo" * 100) {|r| sent = true}
253
+ assert sent
254
+ end
255
+ end
256
+
257
+ def test_asynchronous_connection
258
+ skip
259
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port, :async => true)
260
+ refute connection.connected?, "new asynchronous connection must be disconnected"
261
+ connection.on_connect do |res|
262
+ assert res.success?, "on_connect called with error #{res.error.inspect}"
263
+ assert_same connection, res.bucket
264
+ end
265
+ connection.run {}
266
+ assert connection.connected?, "it should be connected after first run"
267
+ end
268
+
269
+ def test_it_calls_callback_immediately_if_connected_sync
270
+ skip
271
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
272
+ assert connection.connected?, "connection wasn't established in sync mode"
273
+ called = false
274
+ connection.on_connect do |res|
275
+ assert res.success?, "on_connect called with error #{res.error.inspect}"
276
+ called = true
277
+ end
278
+ assert called, "the callback hasn't been called on set"
279
+ called = false
280
+ connection.on_connect do |res|
281
+ assert res.success?, "on_connect called with error #{res.error.inspect}"
282
+ called = true
283
+ end
284
+ refute called, "the callback must not be called on subsequent sets"
285
+ end
286
+
287
+ def test_it_calls_callback_immediately_if_connected_async
288
+ skip
289
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port, :async => true)
290
+ refute connection.connected?, "new asynchronous connection must be disconnected"
291
+ called = false
292
+ connection.run {}
293
+ assert connection.connected?, "the connection must be established"
294
+ connection.run do
295
+ connection.on_connect do |res|
296
+ assert res.success?, "on_connect called with error #{res.error.inspect}"
297
+ called = true
298
+ end
299
+ end
300
+ assert called, "the callback hasn't been called on set"
301
+ called = false
302
+ connection.run do
303
+ connection.on_connect do |res|
304
+ assert res.success?, "on_connect called with error #{res.error.inspect}"
305
+ called = true
306
+ end
307
+ end
308
+ refute called, "the callback must not be called on subsequent sets"
309
+ end
310
+
311
+ def test_it_returns_error_if_user_start_work_on_disconnected_instance_outside_on_connect_callback
312
+ skip
313
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port, :async => true)
314
+ refute connection.connected?, "new asynchronous connection must be disconnected"
315
+ error = nil
316
+ connection.on_error do |ex|
317
+ error = ex
318
+ end
319
+ connection.run do |c|
320
+ c.set("foo", "bar")
321
+ end
322
+ assert_instance_of(Couchbase::Error::Connect, error)
323
+ end
324
+ end