mongo 1.10.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.
- 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
|