mongo 1.10.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/LICENSE +190 -0
- data/README.md +149 -0
- data/Rakefile +31 -0
- data/VERSION +1 -0
- data/bin/mongo_console +43 -0
- data/ext/jsasl/target/jsasl.jar +0 -0
- data/lib/mongo.rb +90 -0
- data/lib/mongo/bulk_write_collection_view.rb +380 -0
- data/lib/mongo/collection.rb +1164 -0
- data/lib/mongo/collection_writer.rb +364 -0
- data/lib/mongo/connection.rb +19 -0
- data/lib/mongo/connection/node.rb +239 -0
- data/lib/mongo/connection/pool.rb +347 -0
- data/lib/mongo/connection/pool_manager.rb +325 -0
- data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
- data/lib/mongo/connection/socket.rb +18 -0
- data/lib/mongo/connection/socket/socket_util.rb +37 -0
- data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
- data/lib/mongo/connection/socket/tcp_socket.rb +86 -0
- data/lib/mongo/connection/socket/unix_socket.rb +39 -0
- data/lib/mongo/cursor.rb +719 -0
- data/lib/mongo/db.rb +735 -0
- data/lib/mongo/exception.rb +88 -0
- data/lib/mongo/functional.rb +21 -0
- data/lib/mongo/functional/authentication.rb +318 -0
- data/lib/mongo/functional/logging.rb +85 -0
- data/lib/mongo/functional/read_preference.rb +174 -0
- data/lib/mongo/functional/sasl_java.rb +48 -0
- data/lib/mongo/functional/uri_parser.rb +374 -0
- data/lib/mongo/functional/write_concern.rb +66 -0
- data/lib/mongo/gridfs.rb +18 -0
- data/lib/mongo/gridfs/grid.rb +112 -0
- data/lib/mongo/gridfs/grid_ext.rb +53 -0
- data/lib/mongo/gridfs/grid_file_system.rb +163 -0
- data/lib/mongo/gridfs/grid_io.rb +484 -0
- data/lib/mongo/legacy.rb +140 -0
- data/lib/mongo/mongo_client.rb +702 -0
- data/lib/mongo/mongo_replica_set_client.rb +523 -0
- data/lib/mongo/mongo_sharded_client.rb +159 -0
- data/lib/mongo/networking.rb +370 -0
- data/lib/mongo/utils.rb +19 -0
- data/lib/mongo/utils/conversions.rb +110 -0
- data/lib/mongo/utils/core_ext.rb +70 -0
- data/lib/mongo/utils/server_version.rb +69 -0
- data/lib/mongo/utils/support.rb +80 -0
- data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
- data/mongo.gemspec +36 -0
- data/test/functional/authentication_test.rb +35 -0
- data/test/functional/bulk_api_stress_test.rb +133 -0
- data/test/functional/bulk_write_collection_view_test.rb +1129 -0
- data/test/functional/client_test.rb +565 -0
- data/test/functional/collection_test.rb +2073 -0
- data/test/functional/collection_writer_test.rb +83 -0
- data/test/functional/conversions_test.rb +163 -0
- data/test/functional/cursor_fail_test.rb +63 -0
- data/test/functional/cursor_message_test.rb +57 -0
- data/test/functional/cursor_test.rb +625 -0
- data/test/functional/db_api_test.rb +819 -0
- data/test/functional/db_connection_test.rb +27 -0
- data/test/functional/db_test.rb +344 -0
- data/test/functional/grid_file_system_test.rb +285 -0
- data/test/functional/grid_io_test.rb +252 -0
- data/test/functional/grid_test.rb +273 -0
- data/test/functional/pool_test.rb +62 -0
- data/test/functional/safe_test.rb +98 -0
- data/test/functional/ssl_test.rb +29 -0
- data/test/functional/support_test.rb +62 -0
- data/test/functional/timeout_test.rb +58 -0
- data/test/functional/uri_test.rb +330 -0
- data/test/functional/write_concern_test.rb +118 -0
- data/test/helpers/general.rb +50 -0
- data/test/helpers/test_unit.rb +317 -0
- data/test/replica_set/authentication_test.rb +35 -0
- data/test/replica_set/basic_test.rb +174 -0
- data/test/replica_set/client_test.rb +341 -0
- data/test/replica_set/complex_connect_test.rb +77 -0
- data/test/replica_set/connection_test.rb +138 -0
- data/test/replica_set/count_test.rb +64 -0
- data/test/replica_set/cursor_test.rb +212 -0
- data/test/replica_set/insert_test.rb +140 -0
- data/test/replica_set/max_values_test.rb +145 -0
- data/test/replica_set/pinning_test.rb +55 -0
- data/test/replica_set/query_test.rb +73 -0
- data/test/replica_set/read_preference_test.rb +214 -0
- data/test/replica_set/refresh_test.rb +175 -0
- data/test/replica_set/replication_ack_test.rb +94 -0
- data/test/replica_set/ssl_test.rb +32 -0
- data/test/sharded_cluster/basic_test.rb +197 -0
- data/test/shared/authentication/basic_auth_shared.rb +286 -0
- data/test/shared/authentication/bulk_api_auth_shared.rb +259 -0
- data/test/shared/authentication/gssapi_shared.rb +164 -0
- data/test/shared/authentication/sasl_plain_shared.rb +96 -0
- data/test/shared/ssl_shared.rb +235 -0
- data/test/test_helper.rb +56 -0
- data/test/threading/basic_test.rb +120 -0
- data/test/tools/mongo_config.rb +608 -0
- data/test/tools/mongo_config_test.rb +160 -0
- data/test/unit/client_test.rb +347 -0
- data/test/unit/collection_test.rb +166 -0
- data/test/unit/connection_test.rb +325 -0
- data/test/unit/cursor_test.rb +299 -0
- data/test/unit/db_test.rb +136 -0
- data/test/unit/grid_test.rb +76 -0
- data/test/unit/mongo_sharded_client_test.rb +48 -0
- data/test/unit/node_test.rb +93 -0
- data/test/unit/pool_manager_test.rb +142 -0
- data/test/unit/read_pref_test.rb +115 -0
- data/test/unit/read_test.rb +159 -0
- data/test/unit/safe_test.rb +158 -0
- data/test/unit/sharding_pool_manager_test.rb +84 -0
- data/test/unit/write_concern_test.rb +175 -0
- metadata +260 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,140 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, 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
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
|
17
|
+
class ReplicaSetInsertTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
def setup
|
20
|
+
ensure_cluster(:rs)
|
21
|
+
@client = MongoReplicaSetClient.new @rs.repl_set_seeds
|
22
|
+
@version = @client.server_version
|
23
|
+
@db = @client.db(TEST_DB)
|
24
|
+
@db.drop_collection("test-sets")
|
25
|
+
@coll = @db.collection("test-sets")
|
26
|
+
end
|
27
|
+
|
28
|
+
def teardown
|
29
|
+
@client.close if @conn
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_insert
|
33
|
+
@coll.save({:a => 20}, :w => 3)
|
34
|
+
|
35
|
+
@rs.primary.stop
|
36
|
+
|
37
|
+
rescue_connection_failure do
|
38
|
+
@coll.save({:a => 30}, :w => 1)
|
39
|
+
end
|
40
|
+
|
41
|
+
@coll.save({:a => 40}, :w => 1)
|
42
|
+
@coll.save({:a => 50}, :w => 1)
|
43
|
+
@coll.save({:a => 60}, :w => 1)
|
44
|
+
@coll.save({:a => 70}, :w => 1)
|
45
|
+
|
46
|
+
# Restart the old master and wait for sync
|
47
|
+
@rs.start
|
48
|
+
sleep(5)
|
49
|
+
results = []
|
50
|
+
|
51
|
+
rescue_connection_failure do
|
52
|
+
@coll.find.each {|r| results << r}
|
53
|
+
[20, 30, 40, 50, 60, 70].each do |a|
|
54
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
@coll.save({:a => 80}, :w => 3)
|
59
|
+
@coll.find.each {|r| results << r}
|
60
|
+
[20, 30, 40, 50, 60, 70, 80].each do |a|
|
61
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a} on second find"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "Bulk API CollectionView" do
|
66
|
+
setup do
|
67
|
+
setup
|
68
|
+
end
|
69
|
+
|
70
|
+
should "handle error with deferred write concern error - spec Merging Results" do
|
71
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
72
|
+
@coll.remove
|
73
|
+
@coll.ensure_index(BSON::OrderedHash[:a, Mongo::ASCENDING], {:unique => true})
|
74
|
+
bulk = @coll.initialize_ordered_bulk_op
|
75
|
+
bulk.insert({:a => 1})
|
76
|
+
bulk.find({:a => 2}).upsert.update({'$set' => {:a => 2}})
|
77
|
+
bulk.insert({:a => 1})
|
78
|
+
ex = assert_raise BulkWriteError do
|
79
|
+
bulk.execute({:w => 5, :wtimeout => 1})
|
80
|
+
end
|
81
|
+
result = ex.result
|
82
|
+
assert_match_document(
|
83
|
+
{
|
84
|
+
"ok" => 1,
|
85
|
+
"n" => 2,
|
86
|
+
"writeErrors" => [
|
87
|
+
{
|
88
|
+
"index" => 2,
|
89
|
+
"code" => 11000,
|
90
|
+
"errmsg" => /duplicate key error/,
|
91
|
+
}
|
92
|
+
],
|
93
|
+
"writeConcernError" => [
|
94
|
+
{
|
95
|
+
"errmsg" => /waiting for replication timed out|timed out waiting for slaves|timeout/,
|
96
|
+
"code" => 64,
|
97
|
+
"errInfo" => {"wtimeout" => true},
|
98
|
+
"index" => 0
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"errmsg" => /waiting for replication timed out|timed out waiting for slaves|timeout/,
|
102
|
+
"code" => 64,
|
103
|
+
"errInfo" => {"wtimeout" => true},
|
104
|
+
"index" => 1
|
105
|
+
}
|
106
|
+
],
|
107
|
+
"code" => 65,
|
108
|
+
"errmsg" => "batch item errors occurred",
|
109
|
+
"nInserted" => 1
|
110
|
+
}, result, "wire_version:#{wire_version}")
|
111
|
+
end
|
112
|
+
assert_equal 2, @coll.find.to_a.size
|
113
|
+
end
|
114
|
+
|
115
|
+
should "handle unordered errors with deferred write concern error - spec Merging Results" do # TODO - spec review
|
116
|
+
with_write_commands_and_operations(@db.connection) do |wire_version|
|
117
|
+
@coll.remove
|
118
|
+
@coll.ensure_index(BSON::OrderedHash[:a, Mongo::ASCENDING], {:unique => true})
|
119
|
+
bulk = @coll.initialize_unordered_bulk_op
|
120
|
+
bulk.insert({:a => 1})
|
121
|
+
bulk.find({:a => 2}).upsert.update({'$set' => {:a => 1}})
|
122
|
+
bulk.insert({:a => 3})
|
123
|
+
ex = assert_raise BulkWriteError do
|
124
|
+
bulk.execute({:w => 5, :wtimeout => 1})
|
125
|
+
end
|
126
|
+
result = ex.result # unordered varies, don't use assert_bulk_exception
|
127
|
+
assert_equal(1, result["ok"], "wire_version:#{wire_version}")
|
128
|
+
assert_equal(2, result["n"], "wire_version:#{wire_version}")
|
129
|
+
assert(result["nInserted"] >= 1, "wire_version:#{wire_version}")
|
130
|
+
assert_equal(65, result["code"], "wire_version:#{wire_version}")
|
131
|
+
assert_equal("batch item errors occurred", result["errmsg"], "wire_version:#{wire_version}")
|
132
|
+
assert(result["writeErrors"].size >= 1, "wire_version:#{wire_version}")
|
133
|
+
assert(result["writeConcernError"].size >= 1, "wire_version:#{wire_version}") if wire_version >= 2
|
134
|
+
assert(@coll.size >= 1, "wire_version:#{wire_version}")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, 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
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
|
17
|
+
class MaxValuesTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
include Mongo
|
20
|
+
|
21
|
+
def setup
|
22
|
+
ensure_cluster(:rs)
|
23
|
+
@client = MongoReplicaSetClient.new(@rs.repl_set_seeds, :name => @rs.repl_set_name)
|
24
|
+
@db = new_mock_db
|
25
|
+
@client.stubs(:[]).returns(@db)
|
26
|
+
@ismaster = {
|
27
|
+
'hosts' => @client.local_manager.hosts.to_a,
|
28
|
+
'arbiters' => @client.local_manager.arbiters
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_initial_max_and_min_values
|
33
|
+
assert @client.max_bson_size
|
34
|
+
assert @client.max_message_size
|
35
|
+
assert @client.max_wire_version
|
36
|
+
assert @client.min_wire_version
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_updated_max_and_min_sizes_after_node_config_change
|
40
|
+
@db.stubs(:command).returns(
|
41
|
+
@ismaster.merge({'ismaster' => true}),
|
42
|
+
@ismaster.merge({'secondary' => true, 'maxMessageSizeBytes' => 1024 * MESSAGE_SIZE_FACTOR}),
|
43
|
+
@ismaster.merge({'secondary' => true, 'maxBsonObjectSize' => 1024}),
|
44
|
+
@ismaster.merge({'secondary' => true, 'maxWireVersion' => 0}),
|
45
|
+
@ismaster.merge({'secondary' => true, 'minWireVersion' => 0})
|
46
|
+
)
|
47
|
+
@client.local_manager.stubs(:refresh_required?).returns(true)
|
48
|
+
@client.refresh
|
49
|
+
|
50
|
+
assert_equal 1024, @client.max_bson_size
|
51
|
+
assert_equal 1024 * MESSAGE_SIZE_FACTOR, @client.max_message_size
|
52
|
+
assert_equal 0, @client.max_wire_version
|
53
|
+
assert_equal 0, @client.min_wire_version
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_no_values_in_config
|
57
|
+
@db.stubs(:command).returns(
|
58
|
+
@ismaster.merge({'ismaster' => true}),
|
59
|
+
@ismaster.merge({'secondary' => true}),
|
60
|
+
@ismaster.merge({'secondary' => true})
|
61
|
+
)
|
62
|
+
@client.local_manager.stubs(:refresh_required?).returns(true)
|
63
|
+
@client.refresh
|
64
|
+
|
65
|
+
assert_equal DEFAULT_MAX_BSON_SIZE, @client.max_bson_size
|
66
|
+
assert_equal DEFAULT_MAX_BSON_SIZE * MESSAGE_SIZE_FACTOR, @client.max_message_size
|
67
|
+
assert_equal 0, @client.max_wire_version
|
68
|
+
assert_equal 0, @client.min_wire_version
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_only_bson_size_in_config
|
72
|
+
@db.stubs(:command).returns(
|
73
|
+
@ismaster.merge({'ismaster' => true}),
|
74
|
+
@ismaster.merge({'secondary' => true}),
|
75
|
+
@ismaster.merge({'secondary' => true, 'maxBsonObjectSize' => 1024})
|
76
|
+
)
|
77
|
+
@client.local_manager.stubs(:refresh_required?).returns(true)
|
78
|
+
@client.refresh
|
79
|
+
|
80
|
+
assert_equal 1024, @client.max_bson_size
|
81
|
+
assert_equal 1024 * MESSAGE_SIZE_FACTOR, @client.max_message_size
|
82
|
+
assert_equal 0, @client.max_wire_version
|
83
|
+
assert_equal 0, @client.min_wire_version
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_values_in_config
|
87
|
+
#ismaster is called three times on the first node
|
88
|
+
@db.stubs(:command).returns(
|
89
|
+
@ismaster.merge({'ismaster' => true, 'maxMessageSizeBytes' => 1024 * 2 * MESSAGE_SIZE_FACTOR,
|
90
|
+
'maxBsonObjectSize' => 1024, 'maxWireVersion' => 2, 'minWireVersion' => 1}),
|
91
|
+
@ismaster.merge({'ismaster' => true, 'maxMessageSizeBytes' => 1024 * 2 * MESSAGE_SIZE_FACTOR,
|
92
|
+
'maxBsonObjectSize' => 1024, 'maxWireVersion' => 2, 'minWireVersion' => 1}),
|
93
|
+
@ismaster.merge({'ismaster' => true, 'maxMessageSizeBytes' => 1024 * 2 * MESSAGE_SIZE_FACTOR,
|
94
|
+
'maxBsonObjectSize' => 1024, 'maxWireVersion' => 2, 'minWireVersion' => 1}),
|
95
|
+
@ismaster.merge({'secondary' => true, 'maxMessageSizeBytes' => 1024 * 2 * MESSAGE_SIZE_FACTOR,
|
96
|
+
'maxBsonObjectSize' => 1024, 'maxWireVersion' => 2, 'minWireVersion' => 0}),
|
97
|
+
@ismaster.merge({'secondary' => true, 'maxMessageSizeBytes' => 1024 * 2 * MESSAGE_SIZE_FACTOR,
|
98
|
+
'maxBsonObjectSize' => 1024, 'maxWireVersion' => 1, 'minWireVersion' => 0})
|
99
|
+
)
|
100
|
+
@client.local_manager.stubs(:refresh_required?).returns(true)
|
101
|
+
@client.refresh
|
102
|
+
|
103
|
+
assert_equal 1024, @client.max_bson_size
|
104
|
+
assert_equal 1024 * 2 * MESSAGE_SIZE_FACTOR, @client.max_message_size
|
105
|
+
assert_equal 1, @client.max_wire_version # minimum of all max_wire_version
|
106
|
+
assert_equal 1, @client.min_wire_version # maximum of all min_wire_version
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_wire_version_not_in_range
|
110
|
+
min_wire_version, max_wire_version = [Mongo::MongoClient::MIN_WIRE_VERSION-1, Mongo::MongoClient::MIN_WIRE_VERSION-1]
|
111
|
+
#ismaster is called three times on the first node
|
112
|
+
@db.stubs(:command).returns(
|
113
|
+
@ismaster.merge({'ismaster' => true, 'maxWireVersion' => max_wire_version, 'minWireVersion' => min_wire_version}),
|
114
|
+
@ismaster.merge({'ismaster' => true, 'maxWireVersion' => max_wire_version, 'minWireVersion' => min_wire_version}),
|
115
|
+
@ismaster.merge({'ismaster' => true, 'maxWireVersion' => max_wire_version, 'minWireVersion' => min_wire_version}),
|
116
|
+
@ismaster.merge({'secondary' => true, 'maxWireVersion' => max_wire_version, 'minWireVersion' => min_wire_version}),
|
117
|
+
@ismaster.merge({'secondary' => true, 'maxWireVersion' => max_wire_version, 'minWireVersion' => min_wire_version})
|
118
|
+
)
|
119
|
+
@client.local_manager.stubs(:refresh_required?).returns(true)
|
120
|
+
assert_raises Mongo::ConnectionFailure do
|
121
|
+
@client.refresh
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_use_write_command
|
126
|
+
with_write_commands(@client) do
|
127
|
+
assert_true @client.use_write_command?({:w => 1})
|
128
|
+
assert_false @client.use_write_command?({:w => 0})
|
129
|
+
end
|
130
|
+
with_write_operations(@client) do
|
131
|
+
assert_false @client.use_write_command?({:w => 1})
|
132
|
+
assert_false @client.use_write_command?({:w => 0})
|
133
|
+
end
|
134
|
+
@client.local_manager.primary_pool.node.expects(:wire_version_feature?).at_least_once.returns(true)
|
135
|
+
assert_true @client.use_write_command?({:w => 1})
|
136
|
+
assert_false @client.use_write_command?({:w => 0})
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_max_write_batch_size
|
140
|
+
assert_equal Mongo::MongoClient::DEFAULT_MAX_WRITE_BATCH_SIZE, @client.max_write_batch_size
|
141
|
+
@client.local_manager.primary_pool.node.stubs(:max_write_batch_size).returns(999)
|
142
|
+
assert_equal 999, @client.max_write_batch_size
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, 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
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
|
17
|
+
class ReplicaSetPinningTest < Test::Unit::TestCase
|
18
|
+
def setup
|
19
|
+
ensure_cluster(:rs)
|
20
|
+
@client = MongoReplicaSetClient.new(@rs.repl_set_seeds, :name => @rs.repl_set_name)
|
21
|
+
@db = @client.db(TEST_DB)
|
22
|
+
@coll = @db.collection("test-sets")
|
23
|
+
@coll.insert({:a => 1})
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_unpinning
|
27
|
+
# pin primary
|
28
|
+
@coll.find_one
|
29
|
+
assert_equal @client.pinned_pool[:pool], @client.primary_pool
|
30
|
+
|
31
|
+
# pin secondary
|
32
|
+
@coll.find_one({}, :read => :secondary_preferred)
|
33
|
+
assert @client.secondary_pools.include? @client.pinned_pool[:pool]
|
34
|
+
|
35
|
+
# repin primary
|
36
|
+
@coll.find_one({}, :read => :primary_preferred)
|
37
|
+
assert_equal @client.pinned_pool[:pool], @client.primary_pool
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_pinned_pool_is_local_to_thread
|
41
|
+
threads = []
|
42
|
+
30.times do |i|
|
43
|
+
threads << Thread.new do
|
44
|
+
if i % 2 == 0
|
45
|
+
@coll.find_one({}, :read => :secondary_preferred)
|
46
|
+
assert @client.secondary_pools.include? @client.pinned_pool[:pool]
|
47
|
+
else
|
48
|
+
@coll.find_one({}, :read => :primary_preferred)
|
49
|
+
assert_equal @client.pinned_pool[:pool], @client.primary_pool
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
threads.each(&:join)
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, 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
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
|
17
|
+
class ReplicaSetQueryTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
def setup
|
20
|
+
ensure_cluster(:rs)
|
21
|
+
@client = MongoReplicaSetClient.new @rs.repl_set_seeds
|
22
|
+
@db = @client.db(TEST_DB)
|
23
|
+
@db.drop_collection("test-sets")
|
24
|
+
@coll = @db.collection("test-sets")
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
@client.close if @conn
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_query
|
32
|
+
@coll.save({:a => 20}, :w => 3)
|
33
|
+
@coll.save({:a => 30}, :w => 3)
|
34
|
+
@coll.save({:a => 40}, :w => 3)
|
35
|
+
results = []
|
36
|
+
@coll.find.each {|r| results << r}
|
37
|
+
[20, 30, 40].each do |a|
|
38
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
39
|
+
end
|
40
|
+
|
41
|
+
@rs.primary.stop
|
42
|
+
|
43
|
+
results = []
|
44
|
+
rescue_connection_failure do
|
45
|
+
@coll.find.each {|r| results << r}
|
46
|
+
[20, 30, 40].each do |a|
|
47
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create a large collection and do a secondary query that returns
|
53
|
+
# enough records to require sending a GETMORE. In between opening
|
54
|
+
# the cursor and sending the GETMORE, do a :primary query. Confirm
|
55
|
+
# that the cursor reading from the secondary continues to talk to
|
56
|
+
# the secondary, rather than trying to read the cursor from the
|
57
|
+
# primary, where it does not exist.
|
58
|
+
# def test_secondary_getmore
|
59
|
+
# 200.times do |i|
|
60
|
+
# @coll.save({:a => i}, :w => 3)
|
61
|
+
# end
|
62
|
+
# as = []
|
63
|
+
# # Set an explicit batch size, in case the default ever changes.
|
64
|
+
# @coll.find({}, { :batch_size => 100, :read => :secondary }) do |c|
|
65
|
+
# c.each do |result|
|
66
|
+
# as << result['a']
|
67
|
+
# @coll.find({:a => result['a']}, :read => :primary).map
|
68
|
+
# end
|
69
|
+
# end
|
70
|
+
# assert_equal(as.sort, 0.upto(199).to_a)
|
71
|
+
# end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
# Copyright (C) 2009-2013 MongoDB, 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
|
+
|
15
|
+
require 'test_helper'
|
16
|
+
|
17
|
+
class ReadPreferenceTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
def setup
|
20
|
+
ensure_cluster(:rs, :replicas => 2, :arbiters => 0)
|
21
|
+
|
22
|
+
# Insert data
|
23
|
+
primary = @rs.primary
|
24
|
+
conn = Connection.new(primary.host, primary.port)
|
25
|
+
db = conn.db(TEST_DB)
|
26
|
+
coll = db.collection("test-sets")
|
27
|
+
coll.save({:a => 20}, {:w => 2})
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_read_primary
|
31
|
+
conn = make_connection
|
32
|
+
rescue_connection_failure do
|
33
|
+
assert conn.read_primary?
|
34
|
+
assert conn.primary?
|
35
|
+
end
|
36
|
+
|
37
|
+
conn = make_connection(:primary_preferred)
|
38
|
+
rescue_connection_failure do
|
39
|
+
assert conn.read_primary?
|
40
|
+
assert conn.primary?
|
41
|
+
end
|
42
|
+
|
43
|
+
conn = make_connection(:secondary)
|
44
|
+
rescue_connection_failure do
|
45
|
+
assert !conn.read_primary?
|
46
|
+
assert !conn.primary?
|
47
|
+
end
|
48
|
+
|
49
|
+
conn = make_connection(:secondary_preferred)
|
50
|
+
rescue_connection_failure do
|
51
|
+
assert !conn.read_primary?
|
52
|
+
assert !conn.primary?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_connection_pools
|
57
|
+
conn = make_connection
|
58
|
+
assert conn.primary_pool, "No primary pool!"
|
59
|
+
assert conn.read_pool, "No read pool!"
|
60
|
+
assert conn.primary_pool.port == conn.read_pool.port,
|
61
|
+
"Primary port and read port are not the same!"
|
62
|
+
|
63
|
+
conn = make_connection(:primary_preferred)
|
64
|
+
assert conn.primary_pool, "No primary pool!"
|
65
|
+
assert conn.read_pool, "No read pool!"
|
66
|
+
assert conn.primary_pool.port == conn.read_pool.port,
|
67
|
+
"Primary port and read port are not the same!"
|
68
|
+
|
69
|
+
conn = make_connection(:secondary)
|
70
|
+
assert conn.primary_pool, "No primary pool!"
|
71
|
+
assert conn.read_pool, "No read pool!"
|
72
|
+
assert conn.primary_pool.port != conn.read_pool.port,
|
73
|
+
"Primary port and read port are the same!"
|
74
|
+
|
75
|
+
conn = make_connection(:secondary_preferred)
|
76
|
+
assert conn.primary_pool, "No primary pool!"
|
77
|
+
assert conn.read_pool, "No read pool!"
|
78
|
+
assert conn.primary_pool.port != conn.read_pool.port,
|
79
|
+
"Primary port and read port are the same!"
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_read_routing
|
83
|
+
prepare_routing_test
|
84
|
+
|
85
|
+
# Test that reads are going to the right members
|
86
|
+
assert_query_route(@primary, @primary_direct)
|
87
|
+
assert_query_route(@primary_preferred, @primary_direct)
|
88
|
+
assert_query_route(@secondary, @secondary_direct)
|
89
|
+
assert_query_route(@secondary_preferred, @secondary_direct)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_read_routing_with_primary_down
|
93
|
+
prepare_routing_test
|
94
|
+
|
95
|
+
# Test that reads are going to the right members
|
96
|
+
assert_query_route(@primary, @primary_direct)
|
97
|
+
assert_query_route(@primary_preferred, @primary_direct)
|
98
|
+
assert_query_route(@secondary, @secondary_direct)
|
99
|
+
assert_query_route(@secondary_preferred, @secondary_direct)
|
100
|
+
|
101
|
+
# Kill the primary so only a single secondary exists
|
102
|
+
@rs.primary.kill
|
103
|
+
|
104
|
+
# Test that reads are going to the right members
|
105
|
+
assert_raise_error ConnectionFailure do
|
106
|
+
@primary[TEST_DB]['test-sets'].find_one
|
107
|
+
end
|
108
|
+
assert_query_route(@primary_preferred, @secondary_direct)
|
109
|
+
assert_query_route(@secondary, @secondary_direct)
|
110
|
+
assert_query_route(@secondary_preferred, @secondary_direct)
|
111
|
+
|
112
|
+
# Restore set
|
113
|
+
@rs.restart
|
114
|
+
sleep(1)
|
115
|
+
@repl_cons.each { |con| con.refresh }
|
116
|
+
sleep(1)
|
117
|
+
@primary_direct = Connection.new(
|
118
|
+
@rs.config['host'],
|
119
|
+
@primary.read_pool.port
|
120
|
+
)
|
121
|
+
|
122
|
+
# Test that reads are going to the right members
|
123
|
+
assert_query_route(@primary, @primary_direct)
|
124
|
+
assert_query_route(@primary_preferred, @primary_direct)
|
125
|
+
assert_query_route(@secondary, @secondary_direct)
|
126
|
+
assert_query_route(@secondary_preferred, @secondary_direct)
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_read_routing_with_secondary_down
|
130
|
+
prepare_routing_test
|
131
|
+
|
132
|
+
# Test that reads are going to the right members
|
133
|
+
assert_query_route(@primary, @primary_direct)
|
134
|
+
assert_query_route(@primary_preferred, @primary_direct)
|
135
|
+
assert_query_route(@secondary, @secondary_direct)
|
136
|
+
assert_query_route(@secondary_preferred, @secondary_direct)
|
137
|
+
|
138
|
+
# Kill the secondary so that only primary exists
|
139
|
+
@rs.secondaries.first.kill
|
140
|
+
|
141
|
+
# Test that reads are going to the right members
|
142
|
+
assert_query_route(@primary, @primary_direct)
|
143
|
+
assert_query_route(@primary_preferred, @primary_direct)
|
144
|
+
assert_raise_error ConnectionFailure do
|
145
|
+
@secondary[TEST_DB]['test-sets'].find_one
|
146
|
+
end
|
147
|
+
assert_query_route(@secondary_preferred, @primary_direct)
|
148
|
+
|
149
|
+
# Restore set
|
150
|
+
@rs.restart
|
151
|
+
sleep(1)
|
152
|
+
@repl_cons.each { |con| con.refresh }
|
153
|
+
sleep(1)
|
154
|
+
@secondary_direct = Connection.new(
|
155
|
+
@rs.config['host'],
|
156
|
+
@secondary.read_pool.port,
|
157
|
+
:slave_ok => true
|
158
|
+
)
|
159
|
+
|
160
|
+
# Test that reads are going to the right members
|
161
|
+
assert_query_route(@primary, @primary_direct)
|
162
|
+
assert_query_route(@primary_preferred, @primary_direct)
|
163
|
+
assert_query_route(@secondary, @secondary_direct)
|
164
|
+
assert_query_route(@secondary_preferred, @secondary_direct)
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_write_lots_of_data
|
168
|
+
@conn = make_connection(:secondary_preferred)
|
169
|
+
@db = @conn[TEST_DB]
|
170
|
+
@coll = @db.collection("test-sets", {:w => 2})
|
171
|
+
|
172
|
+
6000.times do |n|
|
173
|
+
@coll.save({:a => n})
|
174
|
+
end
|
175
|
+
|
176
|
+
cursor = @coll.find()
|
177
|
+
cursor.next
|
178
|
+
cursor.close
|
179
|
+
end
|
180
|
+
|
181
|
+
private
|
182
|
+
|
183
|
+
def prepare_routing_test
|
184
|
+
# Setup replica set connections
|
185
|
+
@primary = make_connection(:primary)
|
186
|
+
@primary_preferred = make_connection(:primary_preferred)
|
187
|
+
@secondary = make_connection(:secondary)
|
188
|
+
@secondary_preferred = make_connection(:secondary_preferred)
|
189
|
+
@repl_cons = [@primary, @primary_preferred, @secondary, @secondary_preferred]
|
190
|
+
|
191
|
+
# Setup direct connections
|
192
|
+
@primary_direct = Connection.new(@rs.config['host'], @primary.read_pool.port)
|
193
|
+
@secondary_direct = Connection.new(@rs.config['host'], @secondary.read_pool.port, :slave_ok => true)
|
194
|
+
end
|
195
|
+
|
196
|
+
def make_connection(mode = :primary, opts = {})
|
197
|
+
opts.merge!({:read => mode})
|
198
|
+
MongoReplicaSetClient.new(@rs.repl_set_seeds, opts)
|
199
|
+
end
|
200
|
+
|
201
|
+
def query_count(connection)
|
202
|
+
connection['admin'].command({:serverStatus => 1})['opcounters']['query']
|
203
|
+
end
|
204
|
+
|
205
|
+
def assert_query_route(test_connection, expected_target)
|
206
|
+
#puts "#{test_connection.read_pool.port} #{expected_target.read_pool.port}"
|
207
|
+
queries_before = query_count(expected_target)
|
208
|
+
assert_nothing_raised do
|
209
|
+
test_connection[TEST_DB]['test-sets'].find_one
|
210
|
+
end
|
211
|
+
queries_after = query_count(expected_target)
|
212
|
+
assert_equal 1, queries_after - queries_before
|
213
|
+
end
|
214
|
+
end
|