jonbell-mongo 1.3.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +190 -0
- data/README.md +333 -0
- data/Rakefile +215 -0
- data/bin/mongo_console +21 -0
- data/docs/CREDITS.md +123 -0
- data/docs/FAQ.md +116 -0
- data/docs/GridFS.md +158 -0
- data/docs/HISTORY.md +263 -0
- data/docs/RELEASES.md +33 -0
- data/docs/REPLICA_SETS.md +72 -0
- data/docs/TUTORIAL.md +247 -0
- data/docs/WRITE_CONCERN.md +28 -0
- data/lib/mongo.rb +97 -0
- data/lib/mongo/collection.rb +895 -0
- data/lib/mongo/connection.rb +926 -0
- data/lib/mongo/cursor.rb +474 -0
- data/lib/mongo/db.rb +617 -0
- data/lib/mongo/exceptions.rb +71 -0
- data/lib/mongo/gridfs/grid.rb +107 -0
- data/lib/mongo/gridfs/grid_ext.rb +57 -0
- data/lib/mongo/gridfs/grid_file_system.rb +146 -0
- data/lib/mongo/gridfs/grid_io.rb +485 -0
- data/lib/mongo/gridfs/grid_io_fix.rb +38 -0
- data/lib/mongo/repl_set_connection.rb +356 -0
- data/lib/mongo/util/conversions.rb +89 -0
- data/lib/mongo/util/core_ext.rb +60 -0
- data/lib/mongo/util/pool.rb +177 -0
- data/lib/mongo/util/server_version.rb +71 -0
- data/lib/mongo/util/support.rb +82 -0
- data/lib/mongo/util/uri_parser.rb +185 -0
- data/mongo.gemspec +34 -0
- data/test/auxillary/1.4_features.rb +166 -0
- data/test/auxillary/authentication_test.rb +68 -0
- data/test/auxillary/autoreconnect_test.rb +41 -0
- data/test/auxillary/fork_test.rb +30 -0
- data/test/auxillary/repl_set_auth_test.rb +58 -0
- data/test/auxillary/slave_connection_test.rb +36 -0
- data/test/auxillary/threaded_authentication_test.rb +101 -0
- data/test/bson/binary_test.rb +15 -0
- data/test/bson/bson_test.rb +654 -0
- data/test/bson/byte_buffer_test.rb +208 -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 +154 -0
- data/test/bson/ordered_hash_test.rb +210 -0
- data/test/bson/timestamp_test.rb +24 -0
- data/test/collection_test.rb +910 -0
- data/test/connection_test.rb +324 -0
- data/test/conversions_test.rb +119 -0
- data/test/cursor_fail_test.rb +75 -0
- data/test/cursor_message_test.rb +43 -0
- data/test/cursor_test.rb +483 -0
- data/test/db_api_test.rb +738 -0
- data/test/db_connection_test.rb +15 -0
- data/test/db_test.rb +315 -0
- data/test/grid_file_system_test.rb +259 -0
- data/test/grid_io_test.rb +209 -0
- data/test/grid_test.rb +258 -0
- data/test/load/thin/load.rb +24 -0
- data/test/load/unicorn/load.rb +23 -0
- data/test/replica_sets/connect_test.rb +112 -0
- data/test/replica_sets/connection_string_test.rb +32 -0
- data/test/replica_sets/count_test.rb +35 -0
- data/test/replica_sets/insert_test.rb +53 -0
- data/test/replica_sets/pooled_insert_test.rb +55 -0
- data/test/replica_sets/query_secondaries.rb +108 -0
- data/test/replica_sets/query_test.rb +51 -0
- data/test/replica_sets/replication_ack_test.rb +66 -0
- data/test/replica_sets/rs_test_helper.rb +27 -0
- data/test/safe_test.rb +68 -0
- data/test/support/hash_with_indifferent_access.rb +186 -0
- data/test/support/keys.rb +45 -0
- data/test/support_test.rb +18 -0
- data/test/test_helper.rb +102 -0
- data/test/threading/threading_with_large_pool_test.rb +90 -0
- data/test/threading_test.rb +87 -0
- data/test/tools/auth_repl_set_manager.rb +14 -0
- data/test/tools/repl_set_manager.rb +266 -0
- data/test/unit/collection_test.rb +130 -0
- data/test/unit/connection_test.rb +85 -0
- data/test/unit/cursor_test.rb +109 -0
- data/test/unit/db_test.rb +94 -0
- data/test/unit/grid_test.rb +49 -0
- data/test/unit/pool_test.rb +9 -0
- data/test/unit/repl_set_connection_test.rb +59 -0
- data/test/unit/safe_test.rb +125 -0
- data/test/uri_test.rb +91 -0
- metadata +224 -0
data/mongo.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require "./lib/mongo"
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'jonbell-mongo'
|
5
|
+
|
6
|
+
s.version = Mongo::VERSION + ".2"
|
7
|
+
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.summary = 'Ruby driver for the MongoDB'
|
10
|
+
s.description = 'A Ruby driver for MongoDB. For more information about Mongo, see http://www.mongodb.org.'
|
11
|
+
|
12
|
+
s.require_paths = ['lib']
|
13
|
+
|
14
|
+
s.files = ['README.md', 'Rakefile', 'mongo.gemspec', 'LICENSE.txt']
|
15
|
+
s.files += ['lib/mongo.rb'] + Dir['lib/mongo/**/*.rb']
|
16
|
+
s.files += Dir['docs/**/*.md'] + Dir['examples/**/*.rb'] + Dir['bin/**/*.rb']
|
17
|
+
s.files += Dir['bin/mongo_console']
|
18
|
+
s.test_files = Dir['test/**/*.rb']
|
19
|
+
|
20
|
+
s.executables = ['mongo_console']
|
21
|
+
|
22
|
+
s.has_rdoc = true
|
23
|
+
s.test_files = Dir['test/**/*.rb']
|
24
|
+
|
25
|
+
s.has_rdoc = true
|
26
|
+
s.rdoc_options = ['--main', 'README.md', '--inline-source']
|
27
|
+
s.extra_rdoc_files = ['README.md']
|
28
|
+
|
29
|
+
s.authors = ['Jim Menard', 'Mike Dirolf', 'Kyle Banker']
|
30
|
+
s.email = 'mongodb-dev@googlegroups.com'
|
31
|
+
s.homepage = 'http://www.mongodb.org'
|
32
|
+
|
33
|
+
s.add_dependency(%q<bson>, [">= #{Mongo::VERSION}"])
|
34
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'mongo'
|
3
|
+
require 'test/unit'
|
4
|
+
require './test/test_helper'
|
5
|
+
|
6
|
+
# Demonstrate features in MongoDB 1.4
|
7
|
+
class Features14Test < Test::Unit::TestCase
|
8
|
+
|
9
|
+
context "MongoDB 1.4" do
|
10
|
+
setup do
|
11
|
+
@con = Mongo::Connection.new
|
12
|
+
@db = @con['mongo-ruby-test']
|
13
|
+
@col = @db['new-features']
|
14
|
+
end
|
15
|
+
|
16
|
+
teardown do
|
17
|
+
@col.drop
|
18
|
+
end
|
19
|
+
|
20
|
+
context "new query operators: " do
|
21
|
+
|
22
|
+
context "$elemMatch: " do
|
23
|
+
setup do
|
24
|
+
@col.save({:user => 'bob', :updates => [{:date => Time.now.utc, :body => 'skiing', :n => 1},
|
25
|
+
{:date => Time.now.utc, :body => 'biking', :n => 2}]})
|
26
|
+
|
27
|
+
@col.save({:user => 'joe', :updates => [{:date => Time.now.utc, :body => 'skiing', :n => 2},
|
28
|
+
{:date => Time.now.utc, :body => 'biking', :n => 10}]})
|
29
|
+
end
|
30
|
+
|
31
|
+
should "match a document with a matching object element in an array" do
|
32
|
+
doc = @col.find_one({"updates" => {"$elemMatch" => {"body" => "skiing", "n" => 2}}})
|
33
|
+
assert_equal 'joe', doc['user']
|
34
|
+
end
|
35
|
+
|
36
|
+
should "$elemMatch with a conditional operator" do
|
37
|
+
doc1 = @col.find_one({"updates" => {"$elemMatch" => {"body" => "biking", "n" => {"$gt" => 5}}}})
|
38
|
+
assert_equal 'joe', doc1['user']
|
39
|
+
end
|
40
|
+
|
41
|
+
should "note the difference between $elemMatch and a traditional match" do
|
42
|
+
doc = @col.find({"updates.body" => "skiing", "updates.n" => 2}).to_a
|
43
|
+
assert_equal 2, doc.size
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "$all with regexes" do
|
48
|
+
setup do
|
49
|
+
@col.save({:n => 1, :a => 'whale'})
|
50
|
+
@col.save({:n => 2, :a => 'snake'})
|
51
|
+
end
|
52
|
+
|
53
|
+
should "match multiple regexes" do
|
54
|
+
doc = @col.find({:a => {'$all' => [/ha/, /le/]}}).to_a
|
55
|
+
assert_equal 1, doc.size
|
56
|
+
assert_equal 1, doc.first['n']
|
57
|
+
end
|
58
|
+
|
59
|
+
should "not match if not every regex matches" do
|
60
|
+
doc = @col.find({:a => {'$all' => [/ha/, /sn/]}}).to_a
|
61
|
+
assert_equal 0, doc.size
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "the $not operator" do
|
66
|
+
setup do
|
67
|
+
@col.save({:a => ['x']})
|
68
|
+
@col.save({:a => ['x', 'y']})
|
69
|
+
@col.save({:a => ['x', 'y', 'z']})
|
70
|
+
end
|
71
|
+
|
72
|
+
should "negate a standard operator" do
|
73
|
+
results = @col.find({:a => {'$not' => {'$size' => 2}}}).to_a
|
74
|
+
assert_equal 2, results.size
|
75
|
+
results = results.map {|r| r['a']}
|
76
|
+
assert_equal ['x'], results.sort.first
|
77
|
+
assert_equal ['x', 'y', 'z'], results.sort.last
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "new update operators: " do
|
83
|
+
|
84
|
+
context "$addToSet (pushing a unique value)" do
|
85
|
+
setup do
|
86
|
+
@col.save({:username => 'bob', :interests => ['skiing', 'guitar']})
|
87
|
+
end
|
88
|
+
|
89
|
+
should "add an item to a set uniquely ($addToSet)" do
|
90
|
+
@col.update({:username => 'bob'}, {'$addToSet' => {'interests' => 'skiing'}})
|
91
|
+
@col.update({:username => 'bob'}, {'$addToSet' => {'interests' => 'kayaking'}})
|
92
|
+
document = @col.find_one({:username => 'bob'})
|
93
|
+
assert_equal ['guitar', 'kayaking', 'skiing'], document['interests'].sort
|
94
|
+
end
|
95
|
+
|
96
|
+
should "add an array of items uniquely ($addToSet with $each)" do
|
97
|
+
@col.update({:username => 'bob'}, {'$addToSet' => {'interests' => {'$each' => ['skiing', 'kayaking', 'biking']}}})
|
98
|
+
document = @col.find_one({:username => 'bob'})
|
99
|
+
assert_equal ['biking', 'guitar', 'kayaking', 'skiing'], document['interests'].sort
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "the positional operator ($)" do
|
104
|
+
setup do
|
105
|
+
@id1 = @col.insert({:text => 'hello',
|
106
|
+
:comments => [{'by' => 'bob',
|
107
|
+
'text' => 'lol!'},
|
108
|
+
{'by' => 'susie',
|
109
|
+
'text' => 'bye bye!'}]})
|
110
|
+
@id2 = @col.insert({:text => 'goodbye',
|
111
|
+
:comments => [{'by' => 'bob',
|
112
|
+
'text' => 'au revoir'},
|
113
|
+
{'by' => 'susie',
|
114
|
+
'text' => 'bye bye!'}]})
|
115
|
+
end
|
116
|
+
|
117
|
+
should "update a matching array item" do
|
118
|
+
@col.update({"_id" => @id1, "comments.by" => 'bob'}, {'$set' => {'comments.$.text' => 'lmao!'}}, :multi => true)
|
119
|
+
result = @col.find_one({"_id" => @id1})
|
120
|
+
assert_equal 'lmao!', result['comments'][0]['text']
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "Geoindexing" do
|
126
|
+
setup do
|
127
|
+
@places = @db['places']
|
128
|
+
@places.create_index([['loc', Mongo::GEO2D]])
|
129
|
+
|
130
|
+
@empire_state = ([40.748371, -73.985031])
|
131
|
+
@jfk = ([40.643711, -73.790009])
|
132
|
+
|
133
|
+
@places.insert({'name' => 'Empire State Building', 'loc' => ([40.748371, -73.985031])})
|
134
|
+
@places.insert({'name' => 'Flatiron Building', 'loc' => ([40.741581, -73.987549])})
|
135
|
+
@places.insert({'name' => 'Grand Central', 'loc' => ([40.751678, -73.976562])})
|
136
|
+
@places.insert({'name' => 'Columbia University', 'loc' => ([40.808922, -73.961617])})
|
137
|
+
@places.insert({'name' => 'NYSE', 'loc' => ([40.71455, -74.007124])})
|
138
|
+
@places.insert({'name' => 'JFK', 'loc' => ([40.643711, -73.790009])})
|
139
|
+
end
|
140
|
+
|
141
|
+
teardown do
|
142
|
+
@places.drop
|
143
|
+
end
|
144
|
+
|
145
|
+
should "find the nearest addresses" do
|
146
|
+
results = @places.find({'loc' => {'$near' => @empire_state}}).limit(2).to_a
|
147
|
+
assert_equal 2, results.size
|
148
|
+
assert_equal 'Empire State Building', results[0]['name']
|
149
|
+
assert_equal 'Flatiron Building', results[1]['name']
|
150
|
+
end
|
151
|
+
|
152
|
+
should "use geoNear command to return distances from a point" do
|
153
|
+
cmd = BSON::OrderedHash.new
|
154
|
+
cmd['geoNear'] = 'places'
|
155
|
+
cmd['near'] = @empire_state
|
156
|
+
cmd['num'] = 6
|
157
|
+
r = @db.command(cmd)
|
158
|
+
|
159
|
+
assert_equal 6, r['results'].length
|
160
|
+
r['results'].each do |result|
|
161
|
+
puts result.inspect
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,68 @@
|
|
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 requires bouncing the server.
|
7
|
+
# It also requires that a user exists on the admin database.
|
8
|
+
class AuthenticationTest < Test::Unit::TestCase
|
9
|
+
include Mongo
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@conn = Mongo::Connection.new
|
13
|
+
@db1 = @conn.db('mongo-ruby-test-auth1')
|
14
|
+
@db2 = @conn.db('mongo-ruby-test-auth2')
|
15
|
+
@admin = @conn.db('admin')
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
@db1.authenticate('user1', 'secret')
|
20
|
+
@db2.authenticate('user2', 'secret')
|
21
|
+
@conn.drop_database('mongo-ruby-test-auth1')
|
22
|
+
@conn.drop_database('mongo-ruby-test-auth2')
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_authenticate
|
26
|
+
@admin.authenticate('bob', 'secret')
|
27
|
+
@db1.add_user('user1', 'secret')
|
28
|
+
@db2.add_user('user2', 'secret')
|
29
|
+
@admin.logout
|
30
|
+
|
31
|
+
assert_raise Mongo::OperationFailure do
|
32
|
+
@db1['stuff'].insert({:a => 2}, :safe => true)
|
33
|
+
end
|
34
|
+
|
35
|
+
assert_raise Mongo::OperationFailure do
|
36
|
+
@db2['stuff'].insert({:a => 2}, :safe => true)
|
37
|
+
end
|
38
|
+
|
39
|
+
@db1.authenticate('user1', 'secret')
|
40
|
+
@db2.authenticate('user2', 'secret')
|
41
|
+
|
42
|
+
assert @db1['stuff'].insert({:a => 2}, :safe => true)
|
43
|
+
assert @db2['stuff'].insert({:a => 2}, :safe => true)
|
44
|
+
|
45
|
+
puts "Please bounce the server."
|
46
|
+
gets
|
47
|
+
|
48
|
+
# Here we reconnect.
|
49
|
+
begin
|
50
|
+
@db1['stuff'].find.to_a
|
51
|
+
rescue Mongo::ConnectionFailure
|
52
|
+
end
|
53
|
+
|
54
|
+
assert @db1['stuff'].insert({:a => 2}, :safe => true)
|
55
|
+
assert @db2['stuff'].insert({:a => 2}, :safe => true)
|
56
|
+
|
57
|
+
@db1.logout
|
58
|
+
assert_raise Mongo::OperationFailure do
|
59
|
+
@db1['stuff'].insert({:a => 2}, :safe => true)
|
60
|
+
end
|
61
|
+
|
62
|
+
@db2.logout
|
63
|
+
assert_raise Mongo::OperationFailure do
|
64
|
+
assert @db2['stuff'].insert({:a => 2}, :safe => true)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,41 @@
|
|
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 requires bouncing the server
|
7
|
+
class AutoreconnectTest < Test::Unit::TestCase
|
8
|
+
include Mongo
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@conn = Mongo::Connection.new
|
12
|
+
@db = @conn.db('mongo-ruby-test')
|
13
|
+
@db.drop_collection("test-connect")
|
14
|
+
@coll = @db.collection("test-connect")
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_query
|
18
|
+
@coll.save({:a => 20})
|
19
|
+
@coll.save({:a => 30})
|
20
|
+
@coll.save({:a => 40})
|
21
|
+
results = []
|
22
|
+
@coll.find.each {|r| results << r}
|
23
|
+
[20, 30, 40].each do |a|
|
24
|
+
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
25
|
+
end
|
26
|
+
|
27
|
+
puts "Please disconnect and then reconnect the current master."
|
28
|
+
gets
|
29
|
+
|
30
|
+
begin
|
31
|
+
@coll.find.to_a
|
32
|
+
rescue Mongo::ConnectionFailure
|
33
|
+
end
|
34
|
+
|
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
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'mongo'
|
3
|
+
require 'test/unit'
|
4
|
+
require './test/test_helper'
|
5
|
+
|
6
|
+
class ForkTest < Test::Unit::TestCase
|
7
|
+
include Mongo
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@conn = standard_connection
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_fork
|
14
|
+
# Now insert some data
|
15
|
+
10.times do |n|
|
16
|
+
@conn[MONGO_TEST_DB]['nums'].insert({:a => n})
|
17
|
+
end
|
18
|
+
|
19
|
+
# Now fork. You'll almost always see an exception here.
|
20
|
+
if !Kernel.fork
|
21
|
+
10.times do
|
22
|
+
assert @conn[MONGO_TEST_DB]['nums'].find_one
|
23
|
+
end
|
24
|
+
else
|
25
|
+
10.times do
|
26
|
+
assert @conn[MONGO_TEST_DB]['nums'].find_one
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require './test/test_helper'
|
3
|
+
require './test/tools/auth_repl_set_manager'
|
4
|
+
|
5
|
+
class AuthTest < Test::Unit::TestCase
|
6
|
+
include Mongo
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@manager = AuthReplSetManager.new(:start_port => 40000)
|
10
|
+
@manager.start_set
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
@manager.cleanup_set
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_repl_set_auth
|
18
|
+
@conn = ReplSetConnection.new([@manager.host, @manager.ports[0]], [@manager.host, @manager.ports[1]],
|
19
|
+
[@manager.host, @manager.ports[2]], :name => @manager.name)
|
20
|
+
|
21
|
+
# Add an admin user
|
22
|
+
@conn['admin'].add_user("me", "secret")
|
23
|
+
|
24
|
+
# Ensure that insert fails
|
25
|
+
assert_raise_error Mongo::OperationFailure, "unauthorized" do
|
26
|
+
@conn['foo']['stuff'].insert({:a => 2}, :safe => {:w => 3})
|
27
|
+
end
|
28
|
+
|
29
|
+
# Then authenticate
|
30
|
+
assert @conn['admin'].authenticate("me", "secret")
|
31
|
+
|
32
|
+
# Insert should succeed now
|
33
|
+
assert @conn['foo']['stuff'].insert({:a => 2}, :safe => {:w => 3})
|
34
|
+
|
35
|
+
# So should a query
|
36
|
+
assert @conn['foo']['stuff'].find_one
|
37
|
+
|
38
|
+
# But not when we logout
|
39
|
+
@conn['admin'].logout
|
40
|
+
|
41
|
+
assert_raise_error Mongo::OperationFailure, "unauthorized" do
|
42
|
+
@conn['foo']['stuff'].find_one
|
43
|
+
end
|
44
|
+
|
45
|
+
# Same should apply to a random secondary
|
46
|
+
@slave1 = Connection.new(@conn.secondary_pools[0].host,
|
47
|
+
@conn.secondary_pools[0].port, :slave_ok => true)
|
48
|
+
|
49
|
+
# Find should fail
|
50
|
+
assert_raise_error Mongo::OperationFailure, "unauthorized" do
|
51
|
+
@slave1['foo']['stuff'].find_one
|
52
|
+
end
|
53
|
+
|
54
|
+
# But not when authenticated
|
55
|
+
@slave1['admin'].authenticate("me", "secret")
|
56
|
+
assert @slave1['foo']['stuff'].find_one
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require './test/test_helper'
|
2
|
+
|
3
|
+
# NOTE: these tests are run only if we can connect to a single MongoDB in slave mode.
|
4
|
+
class SlaveConnectionTest < Test::Unit::TestCase
|
5
|
+
include Mongo
|
6
|
+
|
7
|
+
def self.connect_to_slave
|
8
|
+
@@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
9
|
+
@@port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
|
10
|
+
conn = Connection.new(@@host, @@port, :slave_ok => true)
|
11
|
+
response = conn['admin'].command(:ismaster => 1)
|
12
|
+
Mongo::Support.ok?(response) && response['ismaster'] != 1
|
13
|
+
end
|
14
|
+
|
15
|
+
if self.connect_to_slave
|
16
|
+
puts "Connected to slave; running slave tests."
|
17
|
+
|
18
|
+
def test_connect_to_slave
|
19
|
+
assert_raise Mongo::ConnectionFailure do
|
20
|
+
@db = Connection.new(@@host, @@port, :slave_ok => false).db('ruby-mongo-demo')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_slave_ok_sent_to_queries
|
25
|
+
@con = Connection.new(@@host, @@port, :slave_ok => true)
|
26
|
+
assert_equal true, @con.slave_ok?
|
27
|
+
end
|
28
|
+
else
|
29
|
+
puts "Not connected to slave; skipping slave connection tests."
|
30
|
+
|
31
|
+
def test_slave_ok_false_on_queries
|
32
|
+
@conn = Connection.new(@@host, @@port)
|
33
|
+
assert !@conn.slave_ok?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'mongo'
|
3
|
+
require 'thread'
|
4
|
+
require 'test/unit'
|
5
|
+
require './test/test_helper'
|
6
|
+
|
7
|
+
# NOTE: This test requires bouncing the server.
|
8
|
+
# It also requires that a user exists on the admin database.
|
9
|
+
class AuthenticationTest < Test::Unit::TestCase
|
10
|
+
include Mongo
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@conn = standard_connection(:pool_size => 10)
|
14
|
+
@db1 = @conn.db('mongo-ruby-test-auth1')
|
15
|
+
@db2 = @conn.db('mongo-ruby-test-auth2')
|
16
|
+
@admin = @conn.db('admin')
|
17
|
+
end
|
18
|
+
|
19
|
+
def teardown
|
20
|
+
@db1.authenticate('user1', 'secret')
|
21
|
+
@db2.authenticate('user2', 'secret')
|
22
|
+
@conn.drop_database('mongo-ruby-test-auth1')
|
23
|
+
@conn.drop_database('mongo-ruby-test-auth2')
|
24
|
+
end
|
25
|
+
|
26
|
+
def threaded_exec
|
27
|
+
threads = []
|
28
|
+
|
29
|
+
100.times do
|
30
|
+
threads << Thread.new do
|
31
|
+
yield
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
100.times do |n|
|
36
|
+
threads[n].join
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_authenticate
|
41
|
+
@admin.authenticate('bob', 'secret')
|
42
|
+
@db1.add_user('user1', 'secret')
|
43
|
+
@db2.add_user('user2', 'secret')
|
44
|
+
@admin.logout
|
45
|
+
|
46
|
+
threaded_exec do
|
47
|
+
assert_raise Mongo::OperationFailure do
|
48
|
+
@db1['stuff'].insert({:a => 2}, :safe => true)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
threaded_exec do
|
53
|
+
assert_raise Mongo::OperationFailure do
|
54
|
+
@db2['stuff'].insert({:a => 2}, :safe => true)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
@db1.authenticate('user1', 'secret')
|
59
|
+
@db2.authenticate('user2', 'secret')
|
60
|
+
|
61
|
+
threaded_exec do
|
62
|
+
assert @db1['stuff'].insert({:a => 2}, :safe => true)
|
63
|
+
end
|
64
|
+
|
65
|
+
threaded_exec do
|
66
|
+
assert @db2['stuff'].insert({:a => 2}, :safe => true)
|
67
|
+
end
|
68
|
+
|
69
|
+
puts "Please bounce the server."
|
70
|
+
gets
|
71
|
+
|
72
|
+
# Here we reconnect.
|
73
|
+
begin
|
74
|
+
@db1['stuff'].find.to_a
|
75
|
+
rescue Mongo::ConnectionFailure
|
76
|
+
end
|
77
|
+
|
78
|
+
threaded_exec do
|
79
|
+
assert @db1['stuff'].insert({:a => 2}, :safe => true)
|
80
|
+
end
|
81
|
+
|
82
|
+
threaded_exec do
|
83
|
+
assert @db2['stuff'].insert({:a => 2}, :safe => true)
|
84
|
+
end
|
85
|
+
|
86
|
+
@db1.logout
|
87
|
+
threaded_exec do
|
88
|
+
assert_raise Mongo::OperationFailure do
|
89
|
+
@db1['stuff'].insert({:a => 2}, :safe => true)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
@db2.logout
|
94
|
+
threaded_exec do
|
95
|
+
assert_raise Mongo::OperationFailure do
|
96
|
+
assert @db2['stuff'].insert({:a => 2}, :safe => true)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|