jmoses-couchbase 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.gitignore +15 -0
  2. data/.travis.yml +22 -0
  3. data/.yardopts +5 -0
  4. data/CONTRIBUTING.markdown +75 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +201 -0
  7. data/Makefile +3 -0
  8. data/README.markdown +665 -0
  9. data/RELEASE_NOTES.markdown +819 -0
  10. data/Rakefile +20 -0
  11. data/couchbase.gemspec +49 -0
  12. data/examples/chat-em/Gemfile +7 -0
  13. data/examples/chat-em/README.markdown +45 -0
  14. data/examples/chat-em/server.rb +82 -0
  15. data/examples/chat-goliath-grape/Gemfile +5 -0
  16. data/examples/chat-goliath-grape/README.markdown +50 -0
  17. data/examples/chat-goliath-grape/app.rb +67 -0
  18. data/examples/chat-goliath-grape/config/app.rb +20 -0
  19. data/examples/transcoders/Gemfile +3 -0
  20. data/examples/transcoders/README.markdown +59 -0
  21. data/examples/transcoders/cb-zcat +40 -0
  22. data/examples/transcoders/cb-zcp +45 -0
  23. data/examples/transcoders/gzip_transcoder.rb +49 -0
  24. data/examples/transcoders/options.rb +54 -0
  25. data/ext/couchbase_ext/.gitignore +4 -0
  26. data/ext/couchbase_ext/arguments.c +956 -0
  27. data/ext/couchbase_ext/arithmetic.c +316 -0
  28. data/ext/couchbase_ext/bucket.c +1373 -0
  29. data/ext/couchbase_ext/context.c +65 -0
  30. data/ext/couchbase_ext/couchbase_ext.c +1364 -0
  31. data/ext/couchbase_ext/couchbase_ext.h +644 -0
  32. data/ext/couchbase_ext/delete.c +163 -0
  33. data/ext/couchbase_ext/eventmachine_plugin.c +452 -0
  34. data/ext/couchbase_ext/extconf.rb +169 -0
  35. data/ext/couchbase_ext/get.c +316 -0
  36. data/ext/couchbase_ext/gethrtime.c +129 -0
  37. data/ext/couchbase_ext/http.c +432 -0
  38. data/ext/couchbase_ext/multithread_plugin.c +1090 -0
  39. data/ext/couchbase_ext/observe.c +171 -0
  40. data/ext/couchbase_ext/plugin_common.c +171 -0
  41. data/ext/couchbase_ext/result.c +129 -0
  42. data/ext/couchbase_ext/stats.c +163 -0
  43. data/ext/couchbase_ext/store.c +542 -0
  44. data/ext/couchbase_ext/timer.c +192 -0
  45. data/ext/couchbase_ext/touch.c +186 -0
  46. data/ext/couchbase_ext/unlock.c +176 -0
  47. data/ext/couchbase_ext/utils.c +551 -0
  48. data/ext/couchbase_ext/version.c +142 -0
  49. data/lib/action_dispatch/middleware/session/couchbase_store.rb +38 -0
  50. data/lib/active_support/cache/couchbase_store.rb +430 -0
  51. data/lib/couchbase.rb +155 -0
  52. data/lib/couchbase/bucket.rb +457 -0
  53. data/lib/couchbase/cluster.rb +119 -0
  54. data/lib/couchbase/connection_pool.rb +58 -0
  55. data/lib/couchbase/constants.rb +12 -0
  56. data/lib/couchbase/result.rb +26 -0
  57. data/lib/couchbase/transcoder.rb +120 -0
  58. data/lib/couchbase/utils.rb +62 -0
  59. data/lib/couchbase/version.rb +21 -0
  60. data/lib/couchbase/view.rb +506 -0
  61. data/lib/couchbase/view_row.rb +272 -0
  62. data/lib/ext/multi_json_fix.rb +56 -0
  63. data/lib/rack/session/couchbase.rb +108 -0
  64. data/tasks/benchmark.rake +6 -0
  65. data/tasks/compile.rake +160 -0
  66. data/tasks/test.rake +100 -0
  67. data/tasks/util.rake +21 -0
  68. data/test/profile/.gitignore +1 -0
  69. data/test/profile/Gemfile +6 -0
  70. data/test/profile/benchmark.rb +195 -0
  71. data/test/setup.rb +178 -0
  72. data/test/test_arithmetic.rb +185 -0
  73. data/test/test_async.rb +316 -0
  74. data/test/test_bucket.rb +276 -0
  75. data/test/test_cas.rb +235 -0
  76. data/test/test_couchbase.rb +77 -0
  77. data/test/test_couchbase_connection_pool.rb +77 -0
  78. data/test/test_couchbase_rails_cache_store.rb +361 -0
  79. data/test/test_delete.rb +120 -0
  80. data/test/test_errors.rb +82 -0
  81. data/test/test_eventmachine.rb +70 -0
  82. data/test/test_format.rb +164 -0
  83. data/test/test_get.rb +407 -0
  84. data/test/test_stats.rb +57 -0
  85. data/test/test_store.rb +216 -0
  86. data/test/test_timer.rb +42 -0
  87. data/test/test_touch.rb +97 -0
  88. data/test/test_unlock.rb +119 -0
  89. data/test/test_utils.rb +58 -0
  90. data/test/test_version.rb +52 -0
  91. metadata +353 -0
@@ -0,0 +1,185 @@
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
+ assert_equal 10, connection.incr(uniq_id), "return value"
74
+ assert_equal 10, connection.get(uniq_id), "via get command"
75
+ end
76
+
77
+ def test_it_allows_to_change_default_initial_value_after_connection
78
+ connection = Couchbase.connect(:hostname => @mock.host, :port => @mock.port)
79
+
80
+ assert_equal 0, connection.default_arithmetic_init
81
+ assert_raises(Couchbase::Error::NotFound) do
82
+ connection.incr(uniq_id)
83
+ end
84
+
85
+ connection.default_arithmetic_init = 10
86
+ assert_equal 10, connection.default_arithmetic_init
87
+ assert_raises(Couchbase::Error::NotFound) do
88
+ connection.get(uniq_id)
89
+ end
90
+ assert_equal 10, connection.incr(uniq_id), "return value"
91
+ assert_equal 10, connection.get(uniq_id), "via get command"
92
+ end
93
+
94
+ def test_it_creates_missing_key_when_initial_value_specified
95
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
96
+
97
+ val = connection.incr(uniq_id(:missing), :initial => 5)
98
+ assert_equal 5, val
99
+ val = connection.incr(uniq_id(:missing), :initial => 5)
100
+ assert_equal 6, val
101
+ val = connection.get(uniq_id(:missing))
102
+ assert_equal 6, val
103
+ end
104
+
105
+ def test_it_uses_zero_as_default_value_for_missing_keys
106
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
107
+
108
+ val = connection.incr(uniq_id(:missing), :create => true)
109
+ assert_equal 0, val
110
+ val = connection.incr(uniq_id(:missing), :create => true)
111
+ assert_equal 1, val
112
+ val = connection.get(uniq_id(:missing))
113
+ assert_equal 1, val
114
+ end
115
+
116
+ def test_it_allows_custom_ttl
117
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
118
+
119
+ val = connection.incr(uniq_id(:missing), :create => true, :ttl => 1)
120
+ assert_equal 0, val
121
+ val = connection.incr(uniq_id(:missing), :create => true)
122
+ assert_equal 1, val
123
+ sleep(2)
124
+ assert_raises(Couchbase::Error::NotFound) do
125
+ connection.get(uniq_id(:missing))
126
+ end
127
+ end
128
+
129
+ def test_decrement_with_absolute_ttl
130
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
131
+ # absolute TTL: one second from now
132
+ exp = Time.now.to_i + 1
133
+ val = connection.decr(uniq_id, 12, :initial => 0, :ttl => exp)
134
+ assert_equal 0, val
135
+ assert_equal 0, connection.get(uniq_id)
136
+ sleep(2)
137
+ assert_raises(Couchbase::Error::NotFound) do
138
+ refute connection.get(uniq_id)
139
+ end
140
+ end
141
+
142
+ def test_it_allows_custom_delta
143
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
144
+
145
+ connection.set(uniq_id, 12)
146
+ val = connection.incr(uniq_id, 10)
147
+ assert_equal 22, val
148
+ end
149
+
150
+ def test_it_allows_to_specify_delta_in_options
151
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
152
+
153
+ connection.set(uniq_id, 12)
154
+ options = {:delta => 10}
155
+ val = connection.incr(uniq_id, options)
156
+ assert_equal 22, val
157
+ end
158
+
159
+ def test_multi_incr
160
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
161
+ connection.set(uniq_id(:foo) => 1, uniq_id(:bar) => 1)
162
+
163
+ assert_equal [2, 2], connection.incr(uniq_id(:foo), uniq_id(:bar)).values.sort
164
+ assert_equal [12, 12], connection.incr(uniq_id(:foo), uniq_id(:bar), :delta => 10).values.sort
165
+ assert_equal [14, 15], connection.incr(uniq_id(:foo) => 2, uniq_id(:bar) => 3).values.sort
166
+ end
167
+
168
+ def test_multi_decr
169
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
170
+ connection.set(uniq_id(:foo) => 14, uniq_id(:bar) => 15)
171
+
172
+ assert_equal [12, 12], connection.decr(uniq_id(:foo) => 2, uniq_id(:bar) => 3).values.sort
173
+ assert_equal [2, 2], connection.decr(uniq_id(:foo), uniq_id(:bar), :delta => 10).values.sort
174
+ assert_equal [1, 1], connection.decr(uniq_id(:foo), uniq_id(:bar)).values.sort
175
+ end
176
+
177
+ def test_it_returns_cas_value_in_extended_mode
178
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
179
+ orig_cas = connection.set(uniq_id(:foo), 1)
180
+ val, cas = connection.incr(uniq_id(:foo), :extended => true)
181
+ assert_equal 2, val
182
+ assert cas.is_a?(Numeric), "CAS should be numeric value: #{cas.inspect}"
183
+ refute_equal orig_cas, cas
184
+ end
185
+ end
@@ -0,0 +1,316 @@
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
+ assert obj.respond_to?(:flags)
39
+ end
40
+
41
+ def test_it_requires_block_for_running_loop
42
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
43
+ refute connection.async?
44
+ assert_raises(LocalJumpError) do
45
+ connection.run
46
+ end
47
+ connection.run do |conn|
48
+ assert conn.async?
49
+ end
50
+ end
51
+
52
+ def test_it_resets_async_flag_when_raising_exception_from_callback
53
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
54
+
55
+ assert_raises(RuntimeError) do
56
+ connection.run do |conn|
57
+ conn.set(uniq_id, "foo") { raise }
58
+ end
59
+ end
60
+ refute connection.async?
61
+ end
62
+
63
+ def test_nested_async_get_set
64
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
65
+ connection.set(uniq_id, {"bar" => 1})
66
+ connection.set(uniq_id(:hit), 0)
67
+
68
+ connection.run do |conn|
69
+ conn.get(uniq_id) do
70
+ conn.get(uniq_id(:hit)) do |res|
71
+ conn.set(uniq_id(:hit), res.value + 1)
72
+ end
73
+ end
74
+ end
75
+
76
+ val = connection.get(uniq_id(:hit))
77
+ assert_equal 1, val
78
+ end
79
+
80
+ def test_nested_async_set_get
81
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
82
+ val = nil
83
+
84
+ connection.run do |conn|
85
+ conn.set(uniq_id, "foo") do
86
+ conn.get(uniq_id) do |res|
87
+ val = res.value
88
+ end
89
+ end
90
+ end
91
+
92
+ assert_equal "foo", val
93
+ end
94
+
95
+ def test_nested_async_touch_get
96
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
97
+ connection.set(uniq_id, "foo")
98
+ success = false
99
+ val = nil
100
+
101
+ connection.run do |conn|
102
+ conn.touch(uniq_id, :ttl => 1) do |res1|
103
+ success = res1.success?
104
+ conn.get(uniq_id) do |res2|
105
+ val = res2.value
106
+ end
107
+ end
108
+ end
109
+
110
+ assert success
111
+ assert_equal "foo", val
112
+ sleep(2)
113
+ assert_raises(Couchbase::Error::NotFound) do
114
+ connection.get(uniq_id)
115
+ end
116
+ end
117
+
118
+ def test_nested_async_delete_get
119
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
120
+ cas = connection.set(uniq_id, "foo")
121
+ success = false
122
+ val = :unknown
123
+
124
+ connection.run do |conn|
125
+ conn.delete(uniq_id, :cas => cas) do |res1|
126
+ success = res1.success?
127
+ conn.get(uniq_id, :quiet => true) do |res2|
128
+ val = res2.value
129
+ end
130
+ end
131
+ end
132
+
133
+ assert success
134
+ refute val
135
+ end
136
+
137
+ def test_nested_async_stats_set
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
+ if @mock.real?
158
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
159
+ cas = connection.set(uniq_id, "foo")
160
+ res = {}
161
+
162
+ connection.run do |conn|
163
+ conn.flush do |res1|
164
+ assert res1.success?, "Expected: successful status code.\nActual: #{res1.error.inspect}"
165
+ id = uniq_id(res1.node)
166
+ res[id] = false
167
+ conn.set(id, true) do |res2|
168
+ res[id] = res2.cas
169
+ end
170
+ end
171
+ end
172
+
173
+ assert_raises(Couchbase::Error::NotFound) do
174
+ connection.get(uniq_id)
175
+ end
176
+ res.keys.each do |key|
177
+ assert res[key].is_a?(Numeric)
178
+ assert connection.get(key)
179
+ end
180
+ else
181
+ skip("REST FLUSH isn't implemented in CouchbaseMock.jar yet")
182
+ end
183
+ end
184
+
185
+ def test_nested_async_incr_get
186
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
187
+ cas = connection.set(uniq_id, 1)
188
+ val = nil
189
+
190
+ connection.run do |conn|
191
+ conn.incr(uniq_id) do
192
+ conn.get(uniq_id) do |res|
193
+ val = res.value
194
+ end
195
+ end
196
+ end
197
+
198
+ assert_equal 2, val
199
+ end
200
+
201
+ def test_it_doesnt_accept_callbacks_in_synchronous_mode
202
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
203
+ refute connection.async?
204
+
205
+ assert_raises(ArgumentError) { connection.add(uniq_id, "foo") {} }
206
+ assert_raises(ArgumentError) { connection.set(uniq_id, "foo") {} }
207
+ assert_raises(ArgumentError) { connection.replace(uniq_id, "foo") {} }
208
+ assert_raises(ArgumentError) { connection.get(uniq_id) {} }
209
+ assert_raises(ArgumentError) { connection.touch(uniq_id) {} }
210
+ assert_raises(ArgumentError) { connection.incr(uniq_id) {} }
211
+ assert_raises(ArgumentError) { connection.decr(uniq_id) {} }
212
+ assert_raises(ArgumentError) { connection.delete(uniq_id) {} }
213
+ assert_raises(ArgumentError) { connection.append(uniq_id, "bar") {} }
214
+ assert_raises(ArgumentError) { connection.prepend(uniq_id, "bar") {} }
215
+ assert_raises(ArgumentError) { connection.flush {} }
216
+ assert_raises(ArgumentError) { connection.stats {} }
217
+ end
218
+
219
+ def test_it_disallow_nested_run
220
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
221
+ assert_raises(Couchbase::Error::Invalid) do
222
+ connection.run do
223
+ connection.run do
224
+ end
225
+ end
226
+ end
227
+ end
228
+
229
+ def test_it_extends_timeout_in_async_mode_if_needed
230
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
231
+ connection.set(uniq_id, "foo")
232
+
233
+ connection.timeout = 100_000 # 100_000 us
234
+ connection.run do
235
+ connection.get(uniq_id) do |ret|
236
+ assert ret.success?
237
+ assert_equal "foo", ret.value
238
+ end
239
+ sleep(1.5) # 1_500_000 us
240
+ end
241
+ end
242
+
243
+ def test_send_threshold
244
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
245
+
246
+ sent = false
247
+ connection.run(:send_threshold => 100) do # 100 bytes
248
+ connection.set(uniq_id, "foo" * 100) {|r| sent = true}
249
+ assert sent
250
+ end
251
+ end
252
+
253
+ def test_asynchronous_connection
254
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port, :async => true)
255
+ refute connection.connected?, "new asynchronous connection must be disconnected"
256
+ connection.on_connect do |res|
257
+ assert res.success?, "on_connect called with error #{res.error.inspect}"
258
+ assert_same connection, res.bucket
259
+ end
260
+ connection.run {}
261
+ assert connection.connected?, "it should be connected after first run"
262
+ end
263
+
264
+ def test_it_calls_callback_immediately_if_connected_sync
265
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port)
266
+ assert connection.connected?, "connection wasn't established in sync mode"
267
+ called = false
268
+ connection.on_connect do |res|
269
+ assert res.success?, "on_connect called with error #{res.error.inspect}"
270
+ called = true
271
+ end
272
+ assert called, "the callback hasn't been called on set"
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
+ refute called, "the callback must not be called on subsequent sets"
279
+ end
280
+
281
+ def test_it_calls_callback_immediately_if_connected_async
282
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port, :async => true)
283
+ refute connection.connected?, "new asynchronous connection must be disconnected"
284
+ called = false
285
+ connection.run {}
286
+ assert connection.connected?, "the connection must be established"
287
+ connection.run do
288
+ connection.on_connect do |res|
289
+ assert res.success?, "on_connect called with error #{res.error.inspect}"
290
+ called = true
291
+ end
292
+ end
293
+ assert called, "the callback hasn't been called on set"
294
+ called = false
295
+ connection.run do
296
+ connection.on_connect do |res|
297
+ assert res.success?, "on_connect called with error #{res.error.inspect}"
298
+ called = true
299
+ end
300
+ end
301
+ refute called, "the callback must not be called on subsequent sets"
302
+ end
303
+
304
+ def test_it_returns_error_if_user_start_work_on_disconnected_instance_outside_on_connect_callback
305
+ connection = Couchbase.new(:hostname => @mock.host, :port => @mock.port, :async => true)
306
+ refute connection.connected?, "new asynchronous connection must be disconnected"
307
+ error = nil
308
+ connection.on_error do |ex|
309
+ error = ex
310
+ end
311
+ connection.run do |c|
312
+ c.set("foo", "bar")
313
+ end
314
+ assert_instance_of(Couchbase::Error::Connect, error)
315
+ end
316
+ end