mongo 1.0.5 → 1.0.6
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.
- 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
|