mongo 1.0 → 1.1.5
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/LICENSE.txt +1 -13
- data/{README.rdoc → README.md} +129 -149
- data/Rakefile +94 -58
- data/bin/mongo_console +21 -0
- data/docs/1.0_UPGRADE.md +21 -0
- data/docs/CREDITS.md +123 -0
- data/docs/FAQ.md +112 -0
- data/docs/GridFS.md +158 -0
- data/docs/HISTORY.md +185 -0
- data/docs/REPLICA_SETS.md +75 -0
- data/docs/TUTORIAL.md +247 -0
- data/docs/WRITE_CONCERN.md +28 -0
- data/lib/mongo/collection.rb +225 -105
- data/lib/mongo/connection.rb +374 -315
- data/lib/mongo/cursor.rb +122 -77
- data/lib/mongo/db.rb +109 -85
- data/lib/mongo/exceptions.rb +6 -0
- data/lib/mongo/gridfs/grid.rb +19 -11
- data/lib/mongo/gridfs/grid_ext.rb +36 -9
- data/lib/mongo/gridfs/grid_file_system.rb +15 -9
- data/lib/mongo/gridfs/grid_io.rb +49 -16
- data/lib/mongo/gridfs/grid_io_fix.rb +38 -0
- data/lib/mongo/repl_set_connection.rb +290 -0
- data/lib/mongo/util/conversions.rb +3 -1
- data/lib/mongo/util/core_ext.rb +17 -4
- data/lib/mongo/util/pool.rb +125 -0
- data/lib/mongo/util/server_version.rb +2 -0
- data/lib/mongo/util/support.rb +12 -0
- data/lib/mongo/util/uri_parser.rb +71 -0
- data/lib/mongo.rb +23 -7
- data/{mongo-ruby-driver.gemspec → mongo.gemspec} +9 -7
- data/test/auxillary/1.4_features.rb +2 -2
- data/test/auxillary/authentication_test.rb +1 -1
- data/test/auxillary/autoreconnect_test.rb +1 -1
- data/test/{slave_connection_test.rb → auxillary/slave_connection_test.rb} +6 -6
- data/test/bson/binary_test.rb +15 -0
- data/test/bson/bson_test.rb +537 -0
- data/test/bson/byte_buffer_test.rb +190 -0
- data/test/bson/hash_with_indifferent_access_test.rb +38 -0
- data/test/bson/json_test.rb +17 -0
- data/test/bson/object_id_test.rb +141 -0
- data/test/bson/ordered_hash_test.rb +197 -0
- data/test/collection_test.rb +195 -15
- data/test/connection_test.rb +93 -56
- data/test/conversions_test.rb +1 -1
- data/test/cursor_fail_test.rb +75 -0
- data/test/cursor_message_test.rb +43 -0
- data/test/cursor_test.rb +93 -32
- data/test/db_api_test.rb +28 -55
- data/test/db_connection_test.rb +2 -3
- data/test/db_test.rb +45 -40
- data/test/grid_file_system_test.rb +14 -6
- data/test/grid_io_test.rb +36 -7
- data/test/grid_test.rb +54 -10
- data/test/replica_sets/connect_test.rb +84 -0
- data/test/replica_sets/count_test.rb +35 -0
- data/test/{replica → replica_sets}/insert_test.rb +17 -14
- data/test/replica_sets/pooled_insert_test.rb +55 -0
- data/test/replica_sets/query_secondaries.rb +80 -0
- data/test/replica_sets/query_test.rb +41 -0
- data/test/replica_sets/replication_ack_test.rb +64 -0
- data/test/replica_sets/rs_test_helper.rb +29 -0
- data/test/safe_test.rb +68 -0
- data/test/support/hash_with_indifferent_access.rb +199 -0
- data/test/support/keys.rb +45 -0
- data/test/support_test.rb +19 -0
- data/test/test_helper.rb +53 -15
- data/test/threading/{test_threading_large_pool.rb → threading_with_large_pool_test.rb} +2 -2
- data/test/threading_test.rb +2 -2
- data/test/tools/repl_set_manager.rb +241 -0
- data/test/tools/test.rb +13 -0
- data/test/unit/collection_test.rb +70 -7
- data/test/unit/connection_test.rb +18 -39
- data/test/unit/cursor_test.rb +7 -8
- data/test/unit/db_test.rb +14 -17
- data/test/unit/grid_test.rb +49 -0
- data/test/unit/pool_test.rb +9 -0
- data/test/unit/repl_set_connection_test.rb +82 -0
- data/test/unit/safe_test.rb +125 -0
- metadata +132 -51
- data/bin/bson_benchmark.rb +0 -59
- data/bin/fail_if_no_c.rb +0 -11
- data/examples/admin.rb +0 -43
- data/examples/capped.rb +0 -22
- data/examples/cursor.rb +0 -48
- data/examples/gridfs.rb +0 -44
- data/examples/index_test.rb +0 -126
- data/examples/info.rb +0 -31
- data/examples/queries.rb +0 -70
- data/examples/simple.rb +0 -24
- data/examples/strict.rb +0 -35
- data/examples/types.rb +0 -36
- data/test/replica/count_test.rb +0 -34
- data/test/replica/pooled_insert_test.rb +0 -54
- data/test/replica/query_test.rb +0 -39
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
STDOUT.sync = true
|
|
4
|
+
|
|
5
|
+
unless defined? Mongo
|
|
6
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'mongo')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class ReplSetManager
|
|
10
|
+
|
|
11
|
+
attr_accessor :host, :start_port, :ports, :name, :mongods
|
|
12
|
+
|
|
13
|
+
def initialize(opts={})
|
|
14
|
+
@start_port = opts[:start_port] || 30000
|
|
15
|
+
@ports = []
|
|
16
|
+
@name = opts[:name] || 'replica-set-foo'
|
|
17
|
+
@host = opts[:host] || 'localhost'
|
|
18
|
+
@retries = opts[:retries] || 60
|
|
19
|
+
@config = {"_id" => @name, "members" => []}
|
|
20
|
+
@path = File.join(File.expand_path(File.dirname(__FILE__)), "data")
|
|
21
|
+
|
|
22
|
+
@arbiter_count = opts[:arbiter_count] || 2
|
|
23
|
+
@secondary_count = opts[:secondary_count] || 1
|
|
24
|
+
@passive_count = opts[:passive_count] || 1
|
|
25
|
+
@primary_count = 1
|
|
26
|
+
|
|
27
|
+
@count = @primary_count + @passive_count + @arbiter_count + @secondary_count
|
|
28
|
+
if @count > 7
|
|
29
|
+
raise StandardError, "Cannot create a replica set with #{node_count} nodes. 7 is the max."
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
@mongods = {}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def start_set
|
|
36
|
+
puts "** Starting a replica set with #{@count} nodes"
|
|
37
|
+
|
|
38
|
+
system("killall mongod")
|
|
39
|
+
|
|
40
|
+
n = 0
|
|
41
|
+
(@primary_count + @secondary_count).times do |n|
|
|
42
|
+
init_node(n)
|
|
43
|
+
n += 1
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
@passive_count.times do
|
|
47
|
+
init_node(n) do |attrs|
|
|
48
|
+
attrs['priority'] = 0
|
|
49
|
+
end
|
|
50
|
+
n += 1
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
@arbiter_count.times do
|
|
54
|
+
init_node(n) do |attrs|
|
|
55
|
+
attrs['arbiterOnly'] = true
|
|
56
|
+
end
|
|
57
|
+
n += 1
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
initiate
|
|
61
|
+
ensure_up
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def init_node(n)
|
|
65
|
+
@mongods[n] ||= {}
|
|
66
|
+
port = @start_port + n
|
|
67
|
+
@ports << port
|
|
68
|
+
@mongods[n]['port'] = port
|
|
69
|
+
@mongods[n]['db_path'] = get_path("rs-#{port}")
|
|
70
|
+
@mongods[n]['log_path'] = get_path("log-#{port}")
|
|
71
|
+
system("rm -rf #{@mongods[n]['db_path']}")
|
|
72
|
+
system("mkdir -p #{@mongods[n]['db_path']}")
|
|
73
|
+
|
|
74
|
+
@mongods[n]['start'] = "mongod --replSet #{@name} --logpath '#{@mongods[n]['log_path']}' " +
|
|
75
|
+
" --dbpath #{@mongods[n]['db_path']} --port #{@mongods[n]['port']} --fork"
|
|
76
|
+
|
|
77
|
+
start(n)
|
|
78
|
+
|
|
79
|
+
member = {'_id' => n, 'host' => "#{@host}:#{@mongods[n]['port']}"}
|
|
80
|
+
|
|
81
|
+
if block_given?
|
|
82
|
+
custom_attrs = {}
|
|
83
|
+
yield custom_attrs
|
|
84
|
+
member.merge!(custom_attrs)
|
|
85
|
+
@mongods[n].merge!(custom_attrs)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
@config['members'] << member
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def kill(node)
|
|
92
|
+
pid = @mongods[node]['pid']
|
|
93
|
+
puts "** Killing node with pid #{pid} at port #{@mongods[node]['port']}"
|
|
94
|
+
system("kill -2 #{@mongods[node]['pid']}")
|
|
95
|
+
@mongods[node]['up'] = false
|
|
96
|
+
sleep(1)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def kill_primary
|
|
100
|
+
node = get_node_with_state(1)
|
|
101
|
+
kill(node)
|
|
102
|
+
return node
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Note that we have to rescue a connection failure
|
|
106
|
+
# when we run the StepDown command because that
|
|
107
|
+
# command will close the connection.
|
|
108
|
+
def step_down_primary
|
|
109
|
+
primary = get_node_with_state(1)
|
|
110
|
+
con = get_connection(primary)
|
|
111
|
+
begin
|
|
112
|
+
con['admin'].command({'replSetStepDown' => 90})
|
|
113
|
+
rescue Mongo::ConnectionFailure
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def kill_secondary
|
|
118
|
+
node = get_node_with_state(2)
|
|
119
|
+
kill(node)
|
|
120
|
+
return node
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def restart_killed_nodes
|
|
124
|
+
nodes = @mongods.keys.select do |key|
|
|
125
|
+
@mongods[key]['up'] == false
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
nodes.each do |node|
|
|
129
|
+
start(node)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
ensure_up
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def get_node_from_port(port)
|
|
136
|
+
@mongods.keys.detect { |key| @mongods[key]['port'] == port }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def start(node)
|
|
140
|
+
system(@mongods[node]['start'])
|
|
141
|
+
@mongods[node]['up'] = true
|
|
142
|
+
sleep(0.5)
|
|
143
|
+
@mongods[node]['pid'] = File.open(File.join(@mongods[node]['db_path'], 'mongod.lock')).read.strip
|
|
144
|
+
end
|
|
145
|
+
alias :restart :start
|
|
146
|
+
|
|
147
|
+
def ensure_up
|
|
148
|
+
print "** Ensuring members are up..."
|
|
149
|
+
|
|
150
|
+
attempt do
|
|
151
|
+
con = get_connection
|
|
152
|
+
status = con['admin'].command({'replSetGetStatus' => 1})
|
|
153
|
+
print "."
|
|
154
|
+
if status['members'].all? { |m| m['health'] == 1 && [1, 2, 7].include?(m['state']) } &&
|
|
155
|
+
status['members'].any? { |m| m['state'] == 1 }
|
|
156
|
+
print "all members up!\n\n"
|
|
157
|
+
return status
|
|
158
|
+
else
|
|
159
|
+
raise Mongo::OperationFailure
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def primary
|
|
165
|
+
nodes = get_all_host_pairs_with_state(1)
|
|
166
|
+
nodes.empty? ? nil : nodes[0]
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def secondaries
|
|
170
|
+
get_all_host_pairs_with_state(2)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def arbiters
|
|
174
|
+
get_all_host_pairs_with_state(7)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
private
|
|
178
|
+
|
|
179
|
+
def initiate
|
|
180
|
+
con = get_connection
|
|
181
|
+
|
|
182
|
+
attempt do
|
|
183
|
+
con['admin'].command({'replSetInitiate' => @config})
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def get_node_with_state(state)
|
|
188
|
+
status = ensure_up
|
|
189
|
+
node = status['members'].detect {|m| m['state'] == state}
|
|
190
|
+
if node
|
|
191
|
+
host_port = node['name'].split(':')
|
|
192
|
+
port = host_port[1] ? host_port[1].to_i : 27017
|
|
193
|
+
key = @mongods.keys.detect {|key| @mongods[key]['port'] == port}
|
|
194
|
+
return key
|
|
195
|
+
else
|
|
196
|
+
return false
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def get_all_host_pairs_with_state(state)
|
|
201
|
+
status = ensure_up
|
|
202
|
+
nodes = status['members'].select {|m| m['state'] == state}
|
|
203
|
+
nodes.map do |node|
|
|
204
|
+
host_port = node['name'].split(':')
|
|
205
|
+
port = host_port[1] ? host_port[1].to_i : 27017
|
|
206
|
+
[host, port]
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def get_connection(node=nil)
|
|
211
|
+
con = attempt do
|
|
212
|
+
if !node
|
|
213
|
+
node = @mongods.keys.detect {|key| !@mongods[key]['arbiterOnly'] && @mongods[key]['up'] }
|
|
214
|
+
end
|
|
215
|
+
con = Mongo::Connection.new(@host, @mongods[node]['port'], :slave_ok => true)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
return con
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def get_path(name)
|
|
222
|
+
File.join(@path, name)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def attempt
|
|
226
|
+
raise "No block given!" unless block_given?
|
|
227
|
+
count = 0
|
|
228
|
+
|
|
229
|
+
while count < @retries do
|
|
230
|
+
begin
|
|
231
|
+
return yield
|
|
232
|
+
rescue Mongo::OperationFailure, Mongo::ConnectionFailure
|
|
233
|
+
sleep(1)
|
|
234
|
+
count += 1
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
raise exception
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
end
|
data/test/tools/test.rb
ADDED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require 'test/test_helper'
|
|
1
|
+
require File.expand_path('./test/test_helper.rb')
|
|
2
2
|
|
|
3
3
|
class CollectionTest < Test::Unit::TestCase
|
|
4
4
|
|
|
@@ -12,8 +12,9 @@ class CollectionTest < Test::Unit::TestCase
|
|
|
12
12
|
@db = @conn['testing']
|
|
13
13
|
@coll = @db.collection('books')
|
|
14
14
|
@conn.expects(:send_message).with do |op, msg, log|
|
|
15
|
-
op == 2001
|
|
15
|
+
op == 2001
|
|
16
16
|
end
|
|
17
|
+
@logger.stubs(:debug)
|
|
17
18
|
@coll.update({}, {:title => 'Moby Dick'})
|
|
18
19
|
end
|
|
19
20
|
|
|
@@ -22,7 +23,10 @@ class CollectionTest < Test::Unit::TestCase
|
|
|
22
23
|
@db = @conn['testing']
|
|
23
24
|
@coll = @db.collection('books')
|
|
24
25
|
@conn.expects(:send_message).with do |op, msg, log|
|
|
25
|
-
op == 2002
|
|
26
|
+
op == 2002
|
|
27
|
+
end
|
|
28
|
+
@logger.expects(:debug).with do |msg|
|
|
29
|
+
msg.include?("Moby")
|
|
26
30
|
end
|
|
27
31
|
@coll.insert({:title => 'Moby Dick'})
|
|
28
32
|
end
|
|
@@ -32,8 +36,11 @@ class CollectionTest < Test::Unit::TestCase
|
|
|
32
36
|
@db = @conn['testing']
|
|
33
37
|
@coll = @db.collection('books')
|
|
34
38
|
@conn.expects(:receive_message).with do |op, msg, log, sock|
|
|
35
|
-
op == 2004
|
|
39
|
+
op == 2004
|
|
36
40
|
end.returns([[], 0, 0])
|
|
41
|
+
@logger.expects(:debug).with do |msg|
|
|
42
|
+
msg.include?('Moby')
|
|
43
|
+
end
|
|
37
44
|
@coll.find({:title => 'Moby Dick'}).sort([['title', 1], ['author', 1]]).next_document
|
|
38
45
|
end
|
|
39
46
|
|
|
@@ -43,7 +50,10 @@ class CollectionTest < Test::Unit::TestCase
|
|
|
43
50
|
@coll = @db.collection('books')
|
|
44
51
|
data = BSON::Binary.new(("BINARY " * 1000).unpack("c*"))
|
|
45
52
|
@conn.expects(:send_message).with do |op, msg, log|
|
|
46
|
-
op == 2002
|
|
53
|
+
op == 2002
|
|
54
|
+
end
|
|
55
|
+
@logger.expects(:debug).with do |msg|
|
|
56
|
+
msg.include?("Binary")
|
|
47
57
|
end
|
|
48
58
|
@coll.insert({:data => data})
|
|
49
59
|
end
|
|
@@ -53,7 +63,10 @@ class CollectionTest < Test::Unit::TestCase
|
|
|
53
63
|
@db = @conn['testing']
|
|
54
64
|
@coll = @db.collection('books')
|
|
55
65
|
@conn.expects(:send_message_with_safe_check).with do |op, msg, db_name, log|
|
|
56
|
-
op == 2001
|
|
66
|
+
op == 2001
|
|
67
|
+
end
|
|
68
|
+
@logger.expects(:debug).with do |msg|
|
|
69
|
+
msg.include?("testing['books'].update")
|
|
57
70
|
end
|
|
58
71
|
@coll.update({}, {:title => 'Moby Dick'}, :safe => true)
|
|
59
72
|
end
|
|
@@ -63,9 +76,59 @@ class CollectionTest < Test::Unit::TestCase
|
|
|
63
76
|
@db = @conn['testing']
|
|
64
77
|
@coll = @db.collection('books')
|
|
65
78
|
@conn.expects(:send_message_with_safe_check).with do |op, msg, db_name, log|
|
|
66
|
-
op == 2001
|
|
79
|
+
op == 2001
|
|
67
80
|
end
|
|
81
|
+
@logger.stubs(:debug)
|
|
68
82
|
@coll.update({}, {:title => 'Moby Dick'}, :safe => true)
|
|
69
83
|
end
|
|
84
|
+
|
|
85
|
+
should "not call insert for each ensure_index call" do
|
|
86
|
+
@conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
|
|
87
|
+
@db = @conn['testing']
|
|
88
|
+
@coll = @db.collection('books')
|
|
89
|
+
@coll.expects(:generate_indexes).once
|
|
90
|
+
|
|
91
|
+
@coll.ensure_index [["x", Mongo::DESCENDING]]
|
|
92
|
+
@coll.ensure_index [["x", Mongo::DESCENDING]]
|
|
93
|
+
|
|
94
|
+
end
|
|
95
|
+
should "call generate_indexes for a new direction on the same field for ensure_index" do
|
|
96
|
+
@conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
|
|
97
|
+
@db = @conn['testing']
|
|
98
|
+
@coll = @db.collection('books')
|
|
99
|
+
@coll.expects(:generate_indexes).twice
|
|
100
|
+
|
|
101
|
+
@coll.ensure_index [["x", Mongo::DESCENDING]]
|
|
102
|
+
@coll.ensure_index [["x", Mongo::ASCENDING]]
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
should "call generate_indexes twice because the cache time is 0 seconds" do
|
|
107
|
+
@conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
|
|
108
|
+
@db = @conn['testing']
|
|
109
|
+
@db.cache_time = 0
|
|
110
|
+
@coll = @db.collection('books')
|
|
111
|
+
@coll.expects(:generate_indexes).twice
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@coll.ensure_index [["x", Mongo::DESCENDING]]
|
|
115
|
+
@coll.ensure_index [["x", Mongo::DESCENDING]]
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
should "call generate_indexes for each key when calling ensure_indexes" do
|
|
120
|
+
@conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
|
|
121
|
+
@db = @conn['testing']
|
|
122
|
+
@db.cache_time = 300
|
|
123
|
+
@coll = @db.collection('books')
|
|
124
|
+
@coll.expects(:generate_indexes).once.with do |a, b, c|
|
|
125
|
+
a == {"x"=>-1, "y"=>-1}
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
@coll.ensure_index [["x", Mongo::DESCENDING], ["y", Mongo::DESCENDING]]
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
70
133
|
end
|
|
71
134
|
end
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
require 'test/test_helper'
|
|
1
|
+
require './test/test_helper'
|
|
2
2
|
include Mongo
|
|
3
3
|
|
|
4
4
|
class ConnectionTest < Test::Unit::TestCase
|
|
5
5
|
context "Initialization: " do
|
|
6
6
|
setup do
|
|
7
|
-
def new_mock_socket
|
|
7
|
+
def new_mock_socket(host='localhost', port=27017)
|
|
8
8
|
socket = Object.new
|
|
9
9
|
socket.stubs(:setsockopt).with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
10
|
+
socket.stubs(:close)
|
|
10
11
|
socket
|
|
11
12
|
end
|
|
12
13
|
|
|
@@ -17,22 +18,22 @@ class ConnectionTest < Test::Unit::TestCase
|
|
|
17
18
|
|
|
18
19
|
context "given a single node" do
|
|
19
20
|
setup do
|
|
20
|
-
TCPSocket.stubs(:new).returns(new_mock_socket)
|
|
21
21
|
@conn = Connection.new('localhost', 27017, :connect => false)
|
|
22
|
+
TCPSocket.stubs(:new).returns(new_mock_socket)
|
|
22
23
|
|
|
23
24
|
admin_db = new_mock_db
|
|
24
25
|
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
|
|
25
26
|
@conn.expects(:[]).with('admin').returns(admin_db)
|
|
26
|
-
@conn.
|
|
27
|
+
@conn.connect
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
should "set localhost and port to master" do
|
|
30
|
-
assert_equal 'localhost', @conn.host
|
|
31
|
-
assert_equal 27017, @conn.port
|
|
31
|
+
assert_equal 'localhost', @conn.primary_pool.host
|
|
32
|
+
assert_equal 27017, @conn.primary_pool.port
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
should "set connection pool to 1" do
|
|
35
|
-
assert_equal 1, @conn.size
|
|
36
|
+
assert_equal 1, @conn.primary_pool.size
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
should "default slave_ok to false" do
|
|
@@ -40,45 +41,23 @@ class ConnectionTest < Test::Unit::TestCase
|
|
|
40
41
|
end
|
|
41
42
|
end
|
|
42
43
|
|
|
43
|
-
context "initializing a paired connection" do
|
|
44
|
-
should "require left and right nodes" do
|
|
45
|
-
assert_raise MongoArgumentError do
|
|
46
|
-
Connection.paired(['localhost', 27018], :connect => false)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
assert_raise MongoArgumentError do
|
|
50
|
-
Connection.paired(['localhost', 27018], :connect => false)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
should "store both nodes" do
|
|
55
|
-
@conn = Connection.paired([['localhost', 27017], ['localhost', 27018]], :connect => false)
|
|
56
|
-
|
|
57
|
-
assert_equal ['localhost', 27017], @conn.nodes[0]
|
|
58
|
-
assert_equal ['localhost', 27018], @conn.nodes[1]
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
44
|
context "initializing with a mongodb uri" do
|
|
63
45
|
should "parse a simple uri" do
|
|
64
46
|
@conn = Connection.from_uri("mongodb://localhost", :connect => false)
|
|
65
|
-
assert_equal ['localhost', 27017], @conn.
|
|
47
|
+
assert_equal ['localhost', 27017], @conn.host_to_try
|
|
66
48
|
end
|
|
67
49
|
|
|
68
|
-
should "
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
assert_equal [
|
|
50
|
+
should "allow a complex host names" do
|
|
51
|
+
host_name = "foo.bar-12345.org"
|
|
52
|
+
@conn = Connection.from_uri("mongodb://#{host_name}", :connect => false)
|
|
53
|
+
assert_equal [host_name, 27017], @conn.host_to_try
|
|
72
54
|
end
|
|
73
55
|
|
|
74
|
-
should "parse a uri
|
|
75
|
-
@conn = Connection.from_uri("mongodb://
|
|
76
|
-
assert_equal ['localhost', 27017], @conn.
|
|
77
|
-
|
|
78
|
-
auth_hash = {'username' => 'kyle', 'password' => 's3cr3t', 'db_name' => 'app'}
|
|
56
|
+
should "parse a uri with a hyphen & underscore in the username or password" do
|
|
57
|
+
@conn = Connection.from_uri("mongodb://hyphen-user_name:p-s_s@localhost:27017/db", :connect => false)
|
|
58
|
+
assert_equal ['localhost', 27017], @conn.host_to_try
|
|
59
|
+
auth_hash = { 'db_name' => 'db', 'username' => 'hyphen-user_name', "password" => 'p-s_s' }
|
|
79
60
|
assert_equal auth_hash, @conn.auths[0]
|
|
80
|
-
auth_hash = {'username' => 'mickey', 'password' => 'm0u5e', 'db_name' => 'dsny'}
|
|
81
|
-
assert_equal auth_hash, @conn.auths[1]
|
|
82
61
|
end
|
|
83
62
|
|
|
84
63
|
should "attempt to connect" do
|
|
@@ -89,7 +68,7 @@ class ConnectionTest < Test::Unit::TestCase
|
|
|
89
68
|
admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1})
|
|
90
69
|
@conn.expects(:[]).with('admin').returns(admin_db)
|
|
91
70
|
@conn.expects(:apply_saved_authentication)
|
|
92
|
-
@conn.
|
|
71
|
+
@conn.connect
|
|
93
72
|
end
|
|
94
73
|
|
|
95
74
|
should "raise an error on invalid uris" do
|
data/test/unit/cursor_test.rb
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
require 'test/test_helper'
|
|
1
|
+
require './test/test_helper'
|
|
2
2
|
|
|
3
3
|
class CursorTest < Test::Unit::TestCase
|
|
4
4
|
context "Cursor options" do
|
|
5
5
|
setup do
|
|
6
|
-
@
|
|
6
|
+
@logger = mock()
|
|
7
|
+
@logger.stubs(:debug)
|
|
8
|
+
@connection = stub(:class => Connection, :logger => @logger)
|
|
7
9
|
@db = stub(:name => "testing", :slave_ok? => false, :connection => @connection)
|
|
8
10
|
@collection = stub(:db => @db, :name => "items")
|
|
9
11
|
@cursor = Cursor.new(@collection)
|
|
10
12
|
end
|
|
11
13
|
|
|
12
|
-
should "set
|
|
13
|
-
assert_equal
|
|
14
|
-
|
|
15
|
-
@cursor = Cursor.new(@collection, :admin => true)
|
|
16
|
-
assert_equal true, @cursor.admin
|
|
14
|
+
should "set timeout" do
|
|
15
|
+
assert_equal true, @cursor.timeout
|
|
17
16
|
end
|
|
18
17
|
|
|
19
18
|
should "set selector" do
|
|
@@ -73,7 +72,7 @@ class CursorTest < Test::Unit::TestCase
|
|
|
73
72
|
|
|
74
73
|
context "Query fields" do
|
|
75
74
|
setup do
|
|
76
|
-
@connection = stub(:class => Collection)
|
|
75
|
+
@connection = stub(:class => Collection, :logger => @logger)
|
|
77
76
|
@db = stub(:slave_ok? => true, :name => "testing", :connection => @connection)
|
|
78
77
|
@collection = stub(:db => @db, :name => "items")
|
|
79
78
|
end
|
data/test/unit/db_test.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require 'test/test_helper'
|
|
1
|
+
require './test/test_helper'
|
|
2
2
|
|
|
3
3
|
class DBTest < Test::Unit::TestCase
|
|
4
4
|
context "DBTest: " do
|
|
@@ -16,38 +16,42 @@ class DBTest < Test::Unit::TestCase
|
|
|
16
16
|
context "DB commands" do
|
|
17
17
|
setup do
|
|
18
18
|
@conn = stub()
|
|
19
|
+
@conn.stubs(:safe)
|
|
19
20
|
@db = DB.new("testing", @conn)
|
|
21
|
+
@db.stubs(:safe)
|
|
20
22
|
@collection = mock()
|
|
21
23
|
@db.stubs(:system_command_collection).returns(@collection)
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
should "raise an error if given a hash with more than one key" do
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
if RUBY_VERSION < '1.9'
|
|
28
|
+
assert_raise MongoArgumentError do
|
|
29
|
+
@db.command(:buildinfo => 1, :somekey => 1)
|
|
30
|
+
end
|
|
27
31
|
end
|
|
28
32
|
end
|
|
29
33
|
|
|
30
34
|
should "raise an error if the selector is omitted" do
|
|
31
35
|
assert_raise MongoArgumentError do
|
|
32
|
-
@db.command({}, true)
|
|
36
|
+
@db.command({}, :check_response => true)
|
|
33
37
|
end
|
|
34
38
|
end
|
|
35
39
|
|
|
36
40
|
should "create the proper cursor" do
|
|
37
41
|
@cursor = mock(:next_document => {"ok" => 1})
|
|
38
|
-
Cursor.expects(:new).with(@collection,
|
|
42
|
+
Cursor.expects(:new).with(@collection,
|
|
39
43
|
:limit => -1, :selector => {:buildinfo => 1}, :socket => nil).returns(@cursor)
|
|
40
44
|
command = {:buildinfo => 1}
|
|
41
|
-
@db.command(command, true)
|
|
45
|
+
@db.command(command, :check_response => true)
|
|
42
46
|
end
|
|
43
47
|
|
|
44
48
|
should "raise an error when the command fails" do
|
|
45
49
|
@cursor = mock(:next_document => {"ok" => 0})
|
|
46
|
-
Cursor.expects(:new).with(@collection,
|
|
50
|
+
Cursor.expects(:new).with(@collection,
|
|
47
51
|
:limit => -1, :selector => {:buildinfo => 1}, :socket => nil).returns(@cursor)
|
|
48
52
|
assert_raise OperationFailure do
|
|
49
53
|
command = {:buildinfo => 1}
|
|
50
|
-
@db.command(command,
|
|
54
|
+
@db.command(command, :check_response => true)
|
|
51
55
|
end
|
|
52
56
|
end
|
|
53
57
|
|
|
@@ -60,7 +64,7 @@ class DBTest < Test::Unit::TestCase
|
|
|
60
64
|
|
|
61
65
|
should "raise an error if collection creation fails" do
|
|
62
66
|
@db.expects(:collection_names).returns([])
|
|
63
|
-
@db.expects(:command).returns({})
|
|
67
|
+
@db.expects(:command).returns({'ok' => 0})
|
|
64
68
|
assert_raise Mongo::MongoDBError do
|
|
65
69
|
@db.create_collection("foo")
|
|
66
70
|
end
|
|
@@ -69,14 +73,7 @@ class DBTest < Test::Unit::TestCase
|
|
|
69
73
|
should "raise an error if getlasterror fails" do
|
|
70
74
|
@db.expects(:command).returns({})
|
|
71
75
|
assert_raise Mongo::MongoDBError do
|
|
72
|
-
@db.
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
should "raise an error if rename fails" do
|
|
77
|
-
@db.expects(:command).returns({})
|
|
78
|
-
assert_raise Mongo::MongoDBError do
|
|
79
|
-
@db.rename_collection("foo", "bar")
|
|
76
|
+
@db.get_last_error
|
|
80
77
|
end
|
|
81
78
|
end
|
|
82
79
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require './test/test_helper'
|
|
2
|
+
|
|
3
|
+
class GridTest < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
context "GridFS: " do
|
|
6
|
+
setup do
|
|
7
|
+
@conn = stub()
|
|
8
|
+
@conn.stubs(:safe)
|
|
9
|
+
@db = DB.new("testing", @conn)
|
|
10
|
+
@files = mock()
|
|
11
|
+
@chunks = mock()
|
|
12
|
+
|
|
13
|
+
@db.expects(:[]).with('fs.files').returns(@files)
|
|
14
|
+
@db.expects(:[]).with('fs.chunks').returns(@chunks)
|
|
15
|
+
@db.stubs(:safe)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context "Grid classe with standard connections" do
|
|
19
|
+
setup do
|
|
20
|
+
@conn.expects(:slave_ok?).returns(false)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
should "create indexes for Grid" do
|
|
24
|
+
@chunks.expects(:create_index)
|
|
25
|
+
Grid.new(@db)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
should "create indexes for GridFileSystem" do
|
|
29
|
+
@files.expects(:create_index)
|
|
30
|
+
@chunks.expects(:create_index)
|
|
31
|
+
GridFileSystem.new(@db)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context "Grid classes with slave connection" do
|
|
36
|
+
setup do
|
|
37
|
+
@conn.expects(:slave_ok?).returns(true)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
should "not create indexes for Grid" do
|
|
41
|
+
Grid.new(@db)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
should "not create indexes for GridFileSystem" do
|
|
45
|
+
GridFileSystem.new(@db)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|