mongo 1.0.5 → 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +5 -0
- data/Rakefile +28 -8
- data/lib/mongo.rb +1 -1
- data/lib/mongo/collection.rb +0 -1
- data/lib/mongo/connection.rb +146 -41
- data/lib/mongo/cursor.rb +2 -2
- data/test/collection_test.rb +5 -8
- data/test/connection_test.rb +10 -0
- data/test/{replica → replica_pairs}/count_test.rb +0 -0
- data/test/{replica → replica_pairs}/insert_test.rb +0 -0
- data/test/{replica → replica_pairs}/pooled_insert_test.rb +0 -0
- data/test/{replica → replica_pairs}/query_test.rb +0 -0
- data/test/replica_sets/count_test.rb +33 -0
- data/test/replica_sets/insert_test.rb +51 -0
- data/test/replica_sets/pooled_insert_test.rb +56 -0
- data/test/replica_sets/query_test.rb +40 -0
- data/test/unit/connection_test.rb +50 -6
- data/test/unit/cursor_test.rb +4 -0
- metadata +51 -8
data/HISTORY
CHANGED
data/Rakefile
CHANGED
@@ -58,23 +58,43 @@ namespace :test do
|
|
58
58
|
t.verbose = true
|
59
59
|
end
|
60
60
|
|
61
|
-
Rake::TestTask.new(:
|
62
|
-
t.test_files = FileList['test/
|
61
|
+
Rake::TestTask.new(:replica_pair_count) do |t|
|
62
|
+
t.test_files = FileList['test/replica_pairs/count_test.rb']
|
63
63
|
t.verbose = true
|
64
64
|
end
|
65
65
|
|
66
|
-
Rake::TestTask.new(:
|
67
|
-
t.test_files = FileList['test/
|
66
|
+
Rake::TestTask.new(:replica_pair_insert) do |t|
|
67
|
+
t.test_files = FileList['test/replica_pairs/insert_test.rb']
|
68
68
|
t.verbose = true
|
69
69
|
end
|
70
70
|
|
71
|
-
Rake::TestTask.new(:
|
72
|
-
t.test_files = FileList['test/
|
71
|
+
Rake::TestTask.new(:pooled_replica_pair_insert) do |t|
|
72
|
+
t.test_files = FileList['test/replica_pairs/pooled_insert_test.rb']
|
73
73
|
t.verbose = true
|
74
74
|
end
|
75
75
|
|
76
|
-
Rake::TestTask.new(:
|
77
|
-
t.test_files = FileList['test/
|
76
|
+
Rake::TestTask.new(:replica_pair_query) do |t|
|
77
|
+
t.test_files = FileList['test/replica_pairs/query_test.rb']
|
78
|
+
t.verbose = true
|
79
|
+
end
|
80
|
+
|
81
|
+
Rake::TestTask.new(:replica_set_count) do |t|
|
82
|
+
t.test_files = FileList['test/replica_sets/count_test.rb']
|
83
|
+
t.verbose = true
|
84
|
+
end
|
85
|
+
|
86
|
+
Rake::TestTask.new(:replica_set_insert) do |t|
|
87
|
+
t.test_files = FileList['test/replica_sets/insert_test.rb']
|
88
|
+
t.verbose = true
|
89
|
+
end
|
90
|
+
|
91
|
+
Rake::TestTask.new(:pooled_replica_set_insert) do |t|
|
92
|
+
t.test_files = FileList['test/replica_sets/pooled_insert_test.rb']
|
93
|
+
t.verbose = true
|
94
|
+
end
|
95
|
+
|
96
|
+
Rake::TestTask.new(:replica_set_query) do |t|
|
97
|
+
t.test_files = FileList['test/replica_sets/query_test.rb']
|
78
98
|
t.verbose = true
|
79
99
|
end
|
80
100
|
|
data/lib/mongo.rb
CHANGED
data/lib/mongo/collection.rb
CHANGED
@@ -480,7 +480,6 @@ module Mongo
|
|
480
480
|
#
|
481
481
|
# @core mapreduce map_reduce-instance_method
|
482
482
|
def map_reduce(map, reduce, opts={})
|
483
|
-
opts.assert_valid_keys(:query, :sort, :limit, :finalize, :out, :keeptemp, :verbose, :raw)
|
484
483
|
map = BSON::Code.new(map) unless map.is_a?(BSON::Code)
|
485
484
|
reduce = BSON::Code.new(reduce) unless reduce.is_a?(BSON::Code)
|
486
485
|
raw = opts.delete(:raw)
|
data/lib/mongo/connection.rb
CHANGED
@@ -40,16 +40,15 @@ module Mongo
|
|
40
40
|
# Counter for generating unique request ids.
|
41
41
|
@@current_request_id = 0
|
42
42
|
|
43
|
-
# Create a connection to MongoDB.
|
44
|
-
# along with a maximum connection pool size and timeout.
|
43
|
+
# Create a connection to MongoDB.
|
45
44
|
#
|
46
45
|
# If connecting to just one server, you may specify whether connection to slave is permitted.
|
47
46
|
# In all cases, the default host is "localhost" and the default port is 27017.
|
48
47
|
#
|
49
|
-
# To specify
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
48
|
+
# To specify more than one host pair to be used as seeds in a replica set
|
49
|
+
# or replica pair, use Connection.multi. If you're only specifying one node in the
|
50
|
+
# replica set, you can use Connection.new, as any other host known to the set will be
|
51
|
+
# cached.
|
53
52
|
#
|
54
53
|
# @param [String, Hash] host.
|
55
54
|
# @param [Integer] port specify a port number here if only one host is being specified.
|
@@ -57,7 +56,8 @@ module Mongo
|
|
57
56
|
# @option options [Boolean] :slave_ok (false) Must be set to +true+ when connecting
|
58
57
|
# to a single, slave node.
|
59
58
|
# @option options [Logger, #debug] :logger (nil) Logger instance to receive driver operation log.
|
60
|
-
# @option options [Integer] :pool_size (1) The maximum number of socket connections that can be
|
59
|
+
# @option options [Integer] :pool_size (1) The maximum number of socket connections that can be
|
60
|
+
# opened to the database.
|
61
61
|
# @option options [Float] :timeout (5.0) When all of the connections to the pool are checked out,
|
62
62
|
# this is the number of seconds to wait for a new connection to be released before throwing an exception.
|
63
63
|
#
|
@@ -110,14 +110,52 @@ module Mongo
|
|
110
110
|
@checked_out = []
|
111
111
|
|
112
112
|
# slave_ok can be true only if one node is specified
|
113
|
-
@
|
113
|
+
if @nodes.length > 1 && options[:slave_ok]
|
114
|
+
raise MongoArgumentError, "Can't specify more than one node when :slave_ok is true."
|
115
|
+
else
|
116
|
+
@slave_ok = options[:slave_ok]
|
117
|
+
end
|
118
|
+
|
114
119
|
@logger = options[:logger] || nil
|
115
120
|
@options = options
|
116
121
|
|
117
122
|
should_connect = options[:connect].nil? ? true : options[:connect]
|
118
|
-
|
123
|
+
connect if should_connect
|
119
124
|
end
|
120
125
|
|
126
|
+
# Initialize a connection to a MongoDB replica set using an array of seed nodes.
|
127
|
+
#
|
128
|
+
# Note that, even when connecting to a replica set, you can use Connection.new specifying
|
129
|
+
# just a single node. If the replica set is up, the remaining nodes in the set will be cached
|
130
|
+
# for failover.
|
131
|
+
#
|
132
|
+
# @param nodes [Array] An array of arrays, each of which specifies a host and port.
|
133
|
+
# @param opts Takes the same options as Connection.new
|
134
|
+
#
|
135
|
+
# @example
|
136
|
+
# Connection.multi([["db1.example.com", 27017],
|
137
|
+
# ["db2.example.com", 27017]])
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
# Connection.multi([["db1.example.com", 27017], ["db2.example.com", 27017], ["db3.example.com", 27017]],
|
141
|
+
# :pool_size => 20, :timeout => 5)
|
142
|
+
#
|
143
|
+
# @return [Mongo::Connection]
|
144
|
+
def self.multi(nodes, opts={})
|
145
|
+
unless nodes.length > 0 && nodes.all? {|n| n.is_a? Array}
|
146
|
+
raise MongoArgumentError, "Connection.paired requires at least one node to be specified."
|
147
|
+
end
|
148
|
+
# Block returns an array, the first element being an array of nodes and the second an array
|
149
|
+
# of authorizations for the database.
|
150
|
+
new(nil, nil, opts) do |con|
|
151
|
+
nodes.map do |node|
|
152
|
+
con.pair_val_to_connection(node)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# @deprecated
|
158
|
+
#
|
121
159
|
# Initialize a paired connection to MongoDB.
|
122
160
|
#
|
123
161
|
# @param nodes [Array] An array of arrays, each of which specified a host and port.
|
@@ -134,6 +172,7 @@ module Mongo
|
|
134
172
|
#
|
135
173
|
# @return [Mongo::Connection]
|
136
174
|
def self.paired(nodes, opts={})
|
175
|
+
warn "Connection.paired is deprecated. Please use Connection.multi instead."
|
137
176
|
unless nodes.length == 2 && nodes.all? {|n| n.is_a? Array}
|
138
177
|
raise MongoArgumentError, "Connection.paired requires that exactly two nodes be specified."
|
139
178
|
end
|
@@ -415,43 +454,34 @@ module Mongo
|
|
415
454
|
# Create a new socket and attempt to connect to master.
|
416
455
|
# If successful, sets host and port to master and returns the socket.
|
417
456
|
#
|
457
|
+
# If connecting to a replica set, this method will update the
|
458
|
+
# initially-provided seed list with any nodes known to the set.
|
459
|
+
#
|
418
460
|
# @raise [ConnectionFailure] if unable to connect to any host or port.
|
419
|
-
def
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
# If we're connected to master, set the @host and @port
|
429
|
-
result = self['admin'].command({:ismaster => 1}, :check_response => false, :sock => socket)
|
430
|
-
if Mongo::Support.ok?(result) &&
|
431
|
-
((is_master = result['ismaster'] == 1) || @slave_ok)
|
432
|
-
@host, @port = host, port
|
433
|
-
apply_saved_authentication
|
434
|
-
end
|
435
|
-
|
436
|
-
# Note: slave_ok can be true only when connecting to a single node.
|
437
|
-
if @nodes.length == 1 && !is_master && !@slave_ok
|
438
|
-
raise ConfigurationError, "Trying to connect directly to slave; " +
|
439
|
-
"if this is what you want, specify :slave_ok => true."
|
461
|
+
def connect
|
462
|
+
reset_connection
|
463
|
+
|
464
|
+
while !connected? && !(nodes_to_try = @nodes - @nodes_tried).empty?
|
465
|
+
nodes_to_try.each do |node|
|
466
|
+
if is_primary?(check_is_master(node))
|
467
|
+
set_primary(node)
|
468
|
+
break
|
440
469
|
end
|
441
|
-
|
442
|
-
break if is_master || @slave_ok
|
443
|
-
rescue SocketError, SystemCallError, IOError => ex
|
444
|
-
close
|
445
|
-
false
|
446
|
-
ensure
|
447
|
-
socket.close if socket
|
448
470
|
end
|
449
471
|
end
|
450
|
-
|
472
|
+
|
473
|
+
raise ConnectionFailure, "failed to connect to any given host:port" unless connected?
|
474
|
+
end
|
475
|
+
|
476
|
+
# @deprecated
|
477
|
+
#
|
478
|
+
# Create a new socket and attempt to connect to master.
|
479
|
+
# If successful, sets host and port to master and returns the socket.
|
480
|
+
def connect_to_master
|
481
|
+
warn "Connection#connect_to_master is deprecated. Use Connection#connect instead."
|
482
|
+
connect
|
451
483
|
end
|
452
484
|
|
453
|
-
# Are we connected to MongoDB? This is determined by checking whether
|
454
|
-
# host and port have values, since they're set to nil on calls to #close.
|
455
485
|
def connected?
|
456
486
|
@host && @port
|
457
487
|
end
|
@@ -542,6 +572,81 @@ module Mongo
|
|
542
572
|
|
543
573
|
private
|
544
574
|
|
575
|
+
# If a ConnectionFailure is raised, this method will be called
|
576
|
+
# to close the connection and reset connection values.
|
577
|
+
def reset_connection
|
578
|
+
close
|
579
|
+
@host = nil
|
580
|
+
@port = nil
|
581
|
+
@nodes_tried = []
|
582
|
+
end
|
583
|
+
|
584
|
+
# Primary is defined as either a master node or a slave if
|
585
|
+
# :slave_ok has been set to +true+.
|
586
|
+
#
|
587
|
+
# If a primary node is discovered, we set the the @host and @port and
|
588
|
+
# apply any saved authentication.
|
589
|
+
#
|
590
|
+
# TODO: use the 'primary', and 'seconday' fields if we're in a replica set
|
591
|
+
def is_primary?(config)
|
592
|
+
config && (config['ismaster'] == 1 || config['ismaster'] == true) || @slave_ok
|
593
|
+
end
|
594
|
+
|
595
|
+
# @return
|
596
|
+
def check_is_master(node)
|
597
|
+
begin
|
598
|
+
host, port = *node
|
599
|
+
socket = TCPSocket.new(host, port)
|
600
|
+
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
601
|
+
|
602
|
+
config = self['admin'].command({:ismaster => 1}, :sock => socket)
|
603
|
+
|
604
|
+
rescue OperationFailure, SocketError, SystemCallError, IOError => ex
|
605
|
+
close
|
606
|
+
ensure
|
607
|
+
@nodes_tried << node
|
608
|
+
if config
|
609
|
+
update_node_list(config['hosts']) if config['hosts']
|
610
|
+
if @logger
|
611
|
+
@logger.warn(config['msg']) if config['msg']
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
socket.close if socket
|
616
|
+
end
|
617
|
+
|
618
|
+
config
|
619
|
+
end
|
620
|
+
|
621
|
+
# Set the specified node as primary, and
|
622
|
+
# apply any saved authentication credentials.
|
623
|
+
def set_primary(node)
|
624
|
+
@host, @port = *node
|
625
|
+
apply_saved_authentication
|
626
|
+
end
|
627
|
+
|
628
|
+
# Update the list of known nodes. Only applies to replica sets,
|
629
|
+
# where the response to the ismaster command will return a list
|
630
|
+
# of known hosts.
|
631
|
+
#
|
632
|
+
# @param hosts [Array] a list of hosts, specified as string-encoded
|
633
|
+
# host-port values. Example: ["myserver-1.org:27017", "myserver-1.org:27017"]
|
634
|
+
#
|
635
|
+
# @return [Array] the updated list of nodes
|
636
|
+
def update_node_list(hosts)
|
637
|
+
new_nodes = hosts.map do |host|
|
638
|
+
if !host.respond_to?(:split)
|
639
|
+
warn "Could not parse host #{host.inspect}."
|
640
|
+
next
|
641
|
+
end
|
642
|
+
|
643
|
+
host, port = host.split(':')
|
644
|
+
[host, port.to_i]
|
645
|
+
end
|
646
|
+
|
647
|
+
@nodes |= new_nodes
|
648
|
+
end
|
649
|
+
|
545
650
|
# Return a socket to the pool.
|
546
651
|
def checkin(socket)
|
547
652
|
@connection_mutex.synchronize do
|
@@ -581,7 +686,7 @@ module Mongo
|
|
581
686
|
# pool size has not been exceeded. Otherwise, wait for the next
|
582
687
|
# available socket.
|
583
688
|
def checkout
|
584
|
-
|
689
|
+
connect if !connected?
|
585
690
|
start_time = Time.now
|
586
691
|
loop do
|
587
692
|
if (Time.now - start_time) > @timeout
|
data/lib/mongo/cursor.rb
CHANGED
@@ -45,7 +45,7 @@ module Mongo
|
|
45
45
|
@order = options[:order]
|
46
46
|
@hint = options[:hint]
|
47
47
|
@snapshot = options[:snapshot]
|
48
|
-
@timeout = options[:timeout] ||
|
48
|
+
@timeout = options[:timeout] || true
|
49
49
|
@explain = options[:explain]
|
50
50
|
@socket = options[:socket]
|
51
51
|
@tailable = options[:tailable] || false
|
@@ -71,8 +71,8 @@ module Mongo
|
|
71
71
|
# pair but it has died or something like that) then we close that
|
72
72
|
# connection. The next request will re-open on master server.
|
73
73
|
if err == "not master"
|
74
|
-
raise ConnectionFailure, err
|
75
74
|
@connection.close
|
75
|
+
raise ConnectionFailure, err
|
76
76
|
end
|
77
77
|
|
78
78
|
raise OperationFailure, err
|
data/test/collection_test.rb
CHANGED
@@ -297,6 +297,11 @@ class TestCollection < Test::Unit::TestCase
|
|
297
297
|
end
|
298
298
|
end
|
299
299
|
|
300
|
+
def test_defualt_timeout
|
301
|
+
cursor = @@test.find
|
302
|
+
assert_equal true, cursor.timeout
|
303
|
+
end
|
304
|
+
|
300
305
|
def test_fields_as_hash
|
301
306
|
@@test.save(:a => 1, :b => 1, :c => 1)
|
302
307
|
|
@@ -448,14 +453,6 @@ class TestCollection < Test::Unit::TestCase
|
|
448
453
|
assert res["counts"]
|
449
454
|
assert res["timeMillis"]
|
450
455
|
end
|
451
|
-
|
452
|
-
def test_allows_only_valid_keys
|
453
|
-
m = Code.new("function() { emit(this.user_id, 1); }")
|
454
|
-
r = Code.new("function(k,vals) { return 1; }")
|
455
|
-
assert_raise ArgumentError do
|
456
|
-
@@test.map_reduce(m, r, :foo => true)
|
457
|
-
end
|
458
|
-
end
|
459
456
|
end
|
460
457
|
|
461
458
|
if @@version > "1.3.0"
|
data/test/connection_test.rb
CHANGED
@@ -18,6 +18,10 @@ class TestConnection < Test::Unit::TestCase
|
|
18
18
|
@mongo.db(MONGO_TEST_DB).error
|
19
19
|
end
|
20
20
|
|
21
|
+
def test_slave_ok_with_multiple_nodes
|
22
|
+
|
23
|
+
end
|
24
|
+
|
21
25
|
def test_server_info
|
22
26
|
server_info = @mongo.server_info
|
23
27
|
assert server_info.keys.include?("version")
|
@@ -133,6 +137,12 @@ class TestConnection < Test::Unit::TestCase
|
|
133
137
|
assert_equal ['bar', 27018], nodes[1]
|
134
138
|
end
|
135
139
|
|
140
|
+
def test_slave_ok_with_multiple_nodes
|
141
|
+
assert_raise MongoArgumentError do
|
142
|
+
Connection.paired([['foo', 27017], ['bar', 27018]], :connect => false, :slave_ok => true)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
136
146
|
context "Saved authentications" do
|
137
147
|
setup do
|
138
148
|
@conn = Mongo::Connection.new
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'mongo'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'test/test_helper'
|
5
|
+
|
6
|
+
# NOTE: This test expects a replica set of three nodes to be running
|
7
|
+
# on the local host.
|
8
|
+
class ReplicaSetCountTest < Test::Unit::TestCase
|
9
|
+
include Mongo
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@conn = Mongo::Connection.multi([['localhost', 27017], ['localhost', 27018], ['localhost', 27019]])
|
13
|
+
@db = @conn.db(MONGO_TEST_DB)
|
14
|
+
@db.drop_collection("test-sets")
|
15
|
+
@coll = @db.collection("test-sets")
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_correct_count_after_insertion_reconnect
|
19
|
+
@coll.insert({:a => 20})#, :safe => {:w => 3, :wtimeout => 10000})
|
20
|
+
assert_equal 1, @coll.count
|
21
|
+
|
22
|
+
puts "Please disconnect the current master."
|
23
|
+
gets
|
24
|
+
|
25
|
+
rescue_connection_failure do
|
26
|
+
@coll.insert({:a => 30}, :safe => true)
|
27
|
+
end
|
28
|
+
|
29
|
+
@coll.insert({:a => 40}, :safe => true)
|
30
|
+
assert_equal 3, @coll.count, "Second count failed"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'mongo'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'test/test_helper'
|
5
|
+
|
6
|
+
# NOTE: This test expects a replica set of three nodes to be running
|
7
|
+
# on the local host.
|
8
|
+
class ReplicaSetInsertTest < Test::Unit::TestCase
|
9
|
+
include Mongo
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@conn = Mongo::Connection.multi([['localhost', 27017], ['localhost', 27018], ['localhost', 27019]])
|
13
|
+
@db = @conn.db(MONGO_TEST_DB)
|
14
|
+
@db.drop_collection("test-sets")
|
15
|
+
@coll = @db.collection("test-sets")
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_insert
|
19
|
+
@coll.save({:a => 20}, :safe => true)
|
20
|
+
puts "Please disconnect the current master."
|
21
|
+
gets
|
22
|
+
|
23
|
+
rescue_connection_failure do
|
24
|
+
@coll.save({:a => 30}, :safe => true)
|
25
|
+
end
|
26
|
+
|
27
|
+
@coll.save({:a => 40}, :safe => true)
|
28
|
+
@coll.save({:a => 50}, :safe => true)
|
29
|
+
@coll.save({:a => 60}, :safe => true)
|
30
|
+
@coll.save({:a => 70}, :safe => true)
|
31
|
+
|
32
|
+
puts "Please reconnect the old master to make sure that the new master " +
|
33
|
+
"has synced with the previous master. Note: this may have happened already."
|
34
|
+
gets
|
35
|
+
results = []
|
36
|
+
|
37
|
+
rescue_connection_failure do
|
38
|
+
@coll.find.each {|r| results << r}
|
39
|
+
[20, 30, 40, 50, 60, 70].each do |a|
|
40
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
@coll.save({:a => 80}, :safe => true)
|
45
|
+
@coll.find.each {|r| results << r}
|
46
|
+
[20, 30, 40, 50, 60, 70, 80].each do |a|
|
47
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a} on second find"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'mongo'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'test/test_helper'
|
5
|
+
|
6
|
+
# NOTE: This test expects a replica set of three nodes to be running
|
7
|
+
# on the local host.
|
8
|
+
class ReplicaSetPooledInsertTest < Test::Unit::TestCase
|
9
|
+
include Mongo
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@conn = Mongo::Connection.multi([['localhost', 27017], ['localhost', 27018], ['localhost', 27019]],
|
13
|
+
:pool_size => 10, :timeout => 5)
|
14
|
+
@db = @conn.db(MONGO_TEST_DB)
|
15
|
+
@db.drop_collection("test-sets")
|
16
|
+
@coll = @db.collection("test-sets")
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_insert
|
20
|
+
expected_results = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
21
|
+
@coll.save({:a => -1}, :safe => true)
|
22
|
+
puts "Please disconnect the current master."
|
23
|
+
gets
|
24
|
+
|
25
|
+
threads = []
|
26
|
+
10.times do |i|
|
27
|
+
threads[i] = Thread.new do
|
28
|
+
rescue_connection_failure do
|
29
|
+
@coll.save({:a => i}, :safe => true)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
puts "Please reconnect the old master to make sure that the new master " +
|
35
|
+
"has synced with the previous master. Note: this may have happened already." +
|
36
|
+
"Note also that when connection with multiple threads, you may need to wait a few seconds" +
|
37
|
+
"after restarting the old master so that all the data has had a chance to sync." +
|
38
|
+
"This is a case of eventual consistency."
|
39
|
+
gets
|
40
|
+
results = []
|
41
|
+
|
42
|
+
rescue_connection_failure do
|
43
|
+
@coll.find.each {|r| results << r}
|
44
|
+
expected_results.each do |a|
|
45
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
@coll.save({:a => 10}, :safe => true)
|
50
|
+
@coll.find.each {|r| results << r}
|
51
|
+
(expected_results + [10]).each do |a|
|
52
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a} on second find"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'mongo'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'test/test_helper'
|
5
|
+
|
6
|
+
# NOTE: This test expects a replica set of three nodes to be running
|
7
|
+
# on the local host.
|
8
|
+
class ReplicaPairQueryTest < Test::Unit::TestCase
|
9
|
+
include Mongo
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@conn = Mongo::Connection.multi([['localhost', 27017], ['localhost', 27018], ['localhost', 27019]])
|
13
|
+
@db = @conn.db(MONGO_TEST_DB)
|
14
|
+
@db.drop_collection("test-sets")
|
15
|
+
@coll = @db.collection("test-sets")
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_query
|
19
|
+
@coll.save({:a => 20})
|
20
|
+
@coll.save({:a => 30})
|
21
|
+
@coll.save({:a => 40})
|
22
|
+
results = []
|
23
|
+
@coll.find.each {|r| results << r}
|
24
|
+
[20, 30, 40].each do |a|
|
25
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
26
|
+
end
|
27
|
+
|
28
|
+
puts "Please disconnect the current master."
|
29
|
+
gets
|
30
|
+
|
31
|
+
results = []
|
32
|
+
rescue_connection_failure do
|
33
|
+
@coll.find.each {|r| results << r}
|
34
|
+
[20, 30, 40].each do |a|
|
35
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -18,13 +18,13 @@ class ConnectionTest < Test::Unit::TestCase
|
|
18
18
|
|
19
19
|
context "given a single node" do
|
20
20
|
setup do
|
21
|
-
TCPSocket.stubs(:new).returns(new_mock_socket)
|
22
21
|
@conn = Connection.new('localhost', 27017, :connect => false)
|
22
|
+
TCPSocket.stubs(:new).returns(new_mock_socket)
|
23
23
|
|
24
24
|
admin_db = new_mock_db
|
25
25
|
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
|
26
26
|
@conn.expects(:[]).with('admin').returns(admin_db)
|
27
|
-
@conn.
|
27
|
+
@conn.connect
|
28
28
|
end
|
29
29
|
|
30
30
|
should "set localhost and port to master" do
|
@@ -41,19 +41,63 @@ class ConnectionTest < Test::Unit::TestCase
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
context "connecting to a replica set" do
|
45
|
+
setup do
|
46
|
+
TCPSocket.stubs(:new).returns(new_mock_socket)
|
47
|
+
@conn = Connection.new('localhost', 27017, :connect => false)
|
48
|
+
|
49
|
+
admin_db = new_mock_db
|
50
|
+
@hosts = ['localhost:27018', 'localhost:27019']
|
51
|
+
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'hosts' => @hosts})
|
52
|
+
@conn.expects(:[]).with('admin').returns(admin_db)
|
53
|
+
@conn.connect
|
54
|
+
end
|
55
|
+
|
56
|
+
should "store the hosts returned from the ismaster command" do
|
57
|
+
@hosts.each do |host|
|
58
|
+
host, port = host.split(":")
|
59
|
+
port = port.to_i
|
60
|
+
assert @conn.nodes.include?([host, port]), "Connection doesn't include host #{host.inspect}."
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "connecting to a replica set and providing seed nodes" do
|
66
|
+
setup do
|
67
|
+
TCPSocket.stubs(:new).returns(new_mock_socket)
|
68
|
+
@conn = Connection.multi([['localhost', 27017], ['localhost', 27019]], :connect => false)
|
69
|
+
|
70
|
+
admin_db = new_mock_db
|
71
|
+
@hosts = ['localhost:27017', 'localhost:27018', 'localhost:27019']
|
72
|
+
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1, 'hosts' => @hosts})
|
73
|
+
@conn.expects(:[]).with('admin').returns(admin_db)
|
74
|
+
@conn.connect
|
75
|
+
end
|
76
|
+
|
77
|
+
should "not store any hosts redundantly" do
|
78
|
+
assert_equal 3, @conn.nodes.size
|
79
|
+
|
80
|
+
@hosts.each do |host|
|
81
|
+
host, port = host.split(":")
|
82
|
+
port = port.to_i
|
83
|
+
assert @conn.nodes.include?([host, port]), "Connection doesn't include host #{host.inspect}."
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
44
88
|
context "initializing a paired connection" do
|
45
89
|
should "require left and right nodes" do
|
46
90
|
assert_raise MongoArgumentError do
|
47
|
-
Connection.
|
91
|
+
Connection.multi(['localhost', 27018], :connect => false)
|
48
92
|
end
|
49
93
|
|
50
94
|
assert_raise MongoArgumentError do
|
51
|
-
Connection.
|
95
|
+
Connection.multi(['localhost', 27018], :connect => false)
|
52
96
|
end
|
53
97
|
end
|
54
98
|
|
55
99
|
should "store both nodes" do
|
56
|
-
@conn = Connection.
|
100
|
+
@conn = Connection.multi([['localhost', 27017], ['localhost', 27018]], :connect => false)
|
57
101
|
|
58
102
|
assert_equal ['localhost', 27017], @conn.nodes[0]
|
59
103
|
assert_equal ['localhost', 27018], @conn.nodes[1]
|
@@ -103,7 +147,7 @@ class ConnectionTest < Test::Unit::TestCase
|
|
103
147
|
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
|
104
148
|
@conn.expects(:[]).with('admin').returns(admin_db)
|
105
149
|
@conn.expects(:apply_saved_authentication)
|
106
|
-
@conn.
|
150
|
+
@conn.connect
|
107
151
|
end
|
108
152
|
|
109
153
|
should "raise an error on invalid uris" do
|
data/test/unit/cursor_test.rb
CHANGED
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 1
|
7
8
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
9
|
+
- 6
|
10
|
+
version: 1.0.6
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Jim Menard
|
@@ -16,16 +17,18 @@ autorequire:
|
|
16
17
|
bindir: bin
|
17
18
|
cert_chain: []
|
18
19
|
|
19
|
-
date: 2010-07-
|
20
|
+
date: 2010-07-26 00:00:00 -04:00
|
20
21
|
default_executable:
|
21
22
|
dependencies:
|
22
23
|
- !ruby/object:Gem::Dependency
|
23
24
|
name: bson
|
24
25
|
prerelease: false
|
25
26
|
requirement: &id001 !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
26
28
|
requirements:
|
27
29
|
- - ">="
|
28
30
|
- !ruby/object:Gem::Version
|
31
|
+
hash: 31
|
29
32
|
segments:
|
30
33
|
- 1
|
31
34
|
- 0
|
@@ -73,6 +76,38 @@ files:
|
|
73
76
|
- examples/types.rb
|
74
77
|
- bin/bson_benchmark.rb
|
75
78
|
- bin/fail_if_no_c.rb
|
79
|
+
- test/auxillary/1.4_features.rb
|
80
|
+
- test/auxillary/authentication_test.rb
|
81
|
+
- test/auxillary/autoreconnect_test.rb
|
82
|
+
- test/collection_test.rb
|
83
|
+
- test/connection_test.rb
|
84
|
+
- test/conversions_test.rb
|
85
|
+
- test/cursor_fail_test.rb
|
86
|
+
- test/cursor_message_test.rb
|
87
|
+
- test/cursor_test.rb
|
88
|
+
- test/db_api_test.rb
|
89
|
+
- test/db_connection_test.rb
|
90
|
+
- test/db_test.rb
|
91
|
+
- test/grid_file_system_test.rb
|
92
|
+
- test/grid_io_test.rb
|
93
|
+
- test/grid_test.rb
|
94
|
+
- test/replica_pairs/count_test.rb
|
95
|
+
- test/replica_pairs/insert_test.rb
|
96
|
+
- test/replica_pairs/pooled_insert_test.rb
|
97
|
+
- test/replica_pairs/query_test.rb
|
98
|
+
- test/replica_sets/count_test.rb
|
99
|
+
- test/replica_sets/insert_test.rb
|
100
|
+
- test/replica_sets/pooled_insert_test.rb
|
101
|
+
- test/replica_sets/query_test.rb
|
102
|
+
- test/slave_connection_test.rb
|
103
|
+
- test/support_test.rb
|
104
|
+
- test/test_helper.rb
|
105
|
+
- test/threading/test_threading_large_pool.rb
|
106
|
+
- test/threading_test.rb
|
107
|
+
- test/unit/collection_test.rb
|
108
|
+
- test/unit/connection_test.rb
|
109
|
+
- test/unit/cursor_test.rb
|
110
|
+
- test/unit/db_test.rb
|
76
111
|
has_rdoc: true
|
77
112
|
homepage: http://www.mongodb.org
|
78
113
|
licenses: []
|
@@ -85,23 +120,27 @@ rdoc_options:
|
|
85
120
|
require_paths:
|
86
121
|
- lib
|
87
122
|
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
88
124
|
requirements:
|
89
125
|
- - ">="
|
90
126
|
- !ruby/object:Gem::Version
|
127
|
+
hash: 3
|
91
128
|
segments:
|
92
129
|
- 0
|
93
130
|
version: "0"
|
94
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
95
133
|
requirements:
|
96
134
|
- - ">="
|
97
135
|
- !ruby/object:Gem::Version
|
136
|
+
hash: 3
|
98
137
|
segments:
|
99
138
|
- 0
|
100
139
|
version: "0"
|
101
140
|
requirements: []
|
102
141
|
|
103
142
|
rubyforge_project:
|
104
|
-
rubygems_version: 1.3.
|
143
|
+
rubygems_version: 1.3.7
|
105
144
|
signing_key:
|
106
145
|
specification_version: 3
|
107
146
|
summary: Ruby driver for the MongoDB
|
@@ -121,10 +160,14 @@ test_files:
|
|
121
160
|
- test/grid_file_system_test.rb
|
122
161
|
- test/grid_io_test.rb
|
123
162
|
- test/grid_test.rb
|
124
|
-
- test/
|
125
|
-
- test/
|
126
|
-
- test/
|
127
|
-
- test/
|
163
|
+
- test/replica_pairs/count_test.rb
|
164
|
+
- test/replica_pairs/insert_test.rb
|
165
|
+
- test/replica_pairs/pooled_insert_test.rb
|
166
|
+
- test/replica_pairs/query_test.rb
|
167
|
+
- test/replica_sets/count_test.rb
|
168
|
+
- test/replica_sets/insert_test.rb
|
169
|
+
- test/replica_sets/pooled_insert_test.rb
|
170
|
+
- test/replica_sets/query_test.rb
|
128
171
|
- test/slave_connection_test.rb
|
129
172
|
- test/support_test.rb
|
130
173
|
- test/test_helper.rb
|