mongo 1.4.0 → 1.5.0.rc0

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.
Files changed (49) hide show
  1. data/docs/HISTORY.md +15 -0
  2. data/docs/REPLICA_SETS.md +19 -7
  3. data/lib/mongo.rb +1 -0
  4. data/lib/mongo/collection.rb +1 -1
  5. data/lib/mongo/connection.rb +29 -351
  6. data/lib/mongo/cursor.rb +88 -6
  7. data/lib/mongo/gridfs/grid.rb +4 -2
  8. data/lib/mongo/gridfs/grid_file_system.rb +4 -2
  9. data/lib/mongo/networking.rb +345 -0
  10. data/lib/mongo/repl_set_connection.rb +236 -191
  11. data/lib/mongo/util/core_ext.rb +45 -0
  12. data/lib/mongo/util/logging.rb +5 -0
  13. data/lib/mongo/util/node.rb +6 -4
  14. data/lib/mongo/util/pool.rb +73 -26
  15. data/lib/mongo/util/pool_manager.rb +100 -30
  16. data/lib/mongo/util/uri_parser.rb +29 -21
  17. data/lib/mongo/version.rb +1 -1
  18. data/test/bson/binary_test.rb +6 -8
  19. data/test/bson/bson_test.rb +1 -0
  20. data/test/bson/ordered_hash_test.rb +2 -0
  21. data/test/bson/test_helper.rb +0 -17
  22. data/test/collection_test.rb +22 -0
  23. data/test/connection_test.rb +1 -1
  24. data/test/cursor_test.rb +3 -3
  25. data/test/load/thin/load.rb +4 -7
  26. data/test/replica_sets/basic_test.rb +46 -0
  27. data/test/replica_sets/connect_test.rb +35 -58
  28. data/test/replica_sets/count_test.rb +15 -6
  29. data/test/replica_sets/insert_test.rb +6 -7
  30. data/test/replica_sets/query_test.rb +4 -6
  31. data/test/replica_sets/read_preference_test.rb +112 -8
  32. data/test/replica_sets/refresh_test.rb +66 -36
  33. data/test/replica_sets/refresh_with_threads_test.rb +55 -0
  34. data/test/replica_sets/replication_ack_test.rb +3 -6
  35. data/test/replica_sets/rs_test_helper.rb +12 -6
  36. data/test/replica_sets/threading_test.rb +111 -0
  37. data/test/test_helper.rb +9 -2
  38. data/test/threading_test.rb +14 -6
  39. data/test/tools/repl_set_manager.rb +55 -40
  40. data/test/unit/collection_test.rb +2 -1
  41. data/test/unit/connection_test.rb +8 -8
  42. data/test/unit/grid_test.rb +4 -2
  43. data/test/unit/pool_manager_test.rb +1 -0
  44. data/test/unit/read_test.rb +17 -5
  45. data/test/uri_test.rb +9 -4
  46. metadata +13 -28
  47. data/test/replica_sets/connection_string_test.rb +0 -29
  48. data/test/replica_sets/pooled_insert_test.rb +0 -58
  49. data/test/replica_sets/query_secondaries.rb +0 -109
@@ -20,7 +20,7 @@ module Mongo
20
20
  class URIParser
21
21
 
22
22
  DEFAULT_PORT = 27017
23
- MONGODB_URI_MATCHER = /(([-.\w]+):([^@]+)@)?([-.\w]+)(:([\w]+))?(\/([-\w]+))?/
23
+ MONGODB_URI_MATCHER = /(([-.\w:]+):([^@,]+)@)?((?:(?:[-.\w]+)(?::(?:[\w]+))?,?)+)(\/([-\w]+))?/
24
24
  MONGODB_URI_SPEC = "mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/database]"
25
25
  SPEC_ATTRS = [:nodes, :auths]
26
26
  OPT_ATTRS = [:connect, :replicaset, :slaveok, :safe, :w, :wtimeout, :fsync]
@@ -108,35 +108,43 @@ module Mongo
108
108
 
109
109
  private
110
110
 
111
- def parse_hosts(hosts)
111
+ def parse_hosts(uri_without_proto)
112
112
  @nodes = []
113
113
  @auths = []
114
- specs = hosts.split(',')
115
- specs.each do |spec|
116
- matches = MONGODB_URI_MATCHER.match(spec)
117
- if !matches
118
- raise MongoArgumentError, "MongoDB URI must match this spec: #{MONGODB_URI_SPEC}"
119
- end
120
114
 
121
- uname = matches[2]
122
- pwd = matches[3]
123
- host = matches[4]
124
- port = matches[6] || DEFAULT_PORT
115
+ matches = MONGODB_URI_MATCHER.match(uri_without_proto)
116
+
117
+ if !matches
118
+ raise MongoArgumentError, "MongoDB URI must match this spec: #{MONGODB_URI_SPEC}"
119
+ end
120
+
121
+ uname = matches[2]
122
+ pwd = matches[3]
123
+ hosturis = matches[4].split(',')
124
+ db = matches[6]
125
+
126
+ hosturis.each do |hosturi|
127
+ # If port is present, use it, otherwise use default port
128
+ host, port = hosturi.split(':') + [DEFAULT_PORT]
129
+
125
130
  if !(port.to_s =~ /^\d+$/)
126
131
  raise MongoArgumentError, "Invalid port #{port}; port must be specified as digits."
127
132
  end
128
- port = port.to_i
129
- db = matches[8]
130
-
131
- if uname && pwd && db
132
- auths << {'db_name' => db, 'username' => uname, 'password' => pwd}
133
- elsif uname || pwd || db
134
- raise MongoArgumentError, "MongoDB URI must include all three of username, password, " +
135
- "and db if any one of these is specified."
136
- end
133
+
134
+ port = port.to_i
137
135
 
138
136
  @nodes << [host, port]
139
137
  end
138
+
139
+ if uname && pwd && db
140
+ auths << {'db_name' => db, 'username' => uname, 'password' => pwd}
141
+ elsif uname || pwd
142
+ raise MongoArgumentError, "MongoDB URI must include username, password, "
143
+ "and db if username and password are specified."
144
+ end
145
+
146
+ # The auths are repeated for each host in a replica set
147
+ @auths *= hosturis.length
140
148
  end
141
149
 
142
150
  # This method uses the lambdas defined in OPT_VALID and OPT_CONV to validate
@@ -1,3 +1,3 @@
1
1
  module Mongo
2
- VERSION = "1.4.0"
2
+ VERSION = "1.5.0.rc0"
3
3
  end
@@ -2,14 +2,12 @@
2
2
  require './test/bson/test_helper'
3
3
 
4
4
  class BinaryTest < Test::Unit::TestCase
5
- context "Inspecting" do
6
- setup do
7
- @data = ("THIS IS BINARY " * 50).unpack("c*")
8
- end
5
+ def setup
6
+ @data = ("THIS IS BINARY " * 50).unpack("c*")
7
+ end
9
8
 
10
- should "not display actual data" do
11
- binary = BSON::Binary.new(@data)
12
- assert_equal "<BSON::Binary:#{binary.object_id}>", binary.inspect
13
- end
9
+ def test_do_not_display_binary_data
10
+ binary = BSON::Binary.new(@data)
11
+ assert_equal "<BSON::Binary:#{binary.object_id}>", binary.inspect
14
12
  end
15
13
  end
@@ -9,6 +9,7 @@ end
9
9
  require 'bigdecimal'
10
10
 
11
11
  begin
12
+ require 'date'
12
13
  require 'tzinfo'
13
14
  require 'active_support/core_ext'
14
15
  Time.zone = "Pacific Time (US & Canada)"
@@ -212,6 +212,8 @@ class OrderedHashTest < Test::Unit::TestCase
212
212
  assert @oh.keys.include?('z')
213
213
  @oh.delete_if { |k,v| k == 'z' }
214
214
  assert !@oh.keys.include?('z')
215
+ @oh.delete_if { |k, v| v > 0 }
216
+ assert @oh.keys.empty?
215
217
  end
216
218
 
217
219
  def test_reject
@@ -10,23 +10,6 @@ def silently
10
10
  result
11
11
  end
12
12
 
13
- begin
14
- require 'rubygems' if RUBY_VERSION < "1.9.0" && !ENV['C_EXT']
15
- silently { require 'shoulda' }
16
- silently { require 'mocha' }
17
- rescue LoadError
18
- puts <<MSG
19
-
20
- This test suite requires shoulda and mocha.
21
- You can install them as follows:
22
- gem install shoulda
23
- gem install mocha
24
-
25
- MSG
26
-
27
- exit
28
- end
29
-
30
13
  require 'bson_ext/cbson' if !(RUBY_PLATFORM =~ /java/) && ENV['C_EXT']
31
14
 
32
15
  class Test::Unit::TestCase
@@ -301,6 +301,7 @@ class TestCollection < Test::Unit::TestCase
301
301
  @conn = standard_connection
302
302
  @db = @conn[MONGO_TEST_DB]
303
303
  @test = @db['test-safe-remove']
304
+ @test.remove
304
305
  @test.save({:a => 50})
305
306
  assert_equal 1, @test.remove({}, :safe => true)["n"]
306
307
  @test.drop
@@ -704,6 +705,26 @@ class TestCollection < Test::Unit::TestCase
704
705
  coll.ensure_index([['a', 1]])
705
706
  end
706
707
 
708
+
709
+ if @@version > '2.0.0'
710
+ def test_show_disk_loc
711
+ @@test.save({:a => 1})
712
+ @@test.save({:a => 2})
713
+ assert @@test.find({:a => 1}, :show_disk_loc => true).show_disk_loc
714
+ assert @@test.find({:a => 1}, :show_disk_loc => true).next['$diskLoc']
715
+ @@test.remove
716
+ end
717
+
718
+ def test_max_scan
719
+ 1000.times do |n|
720
+ @@test.save({:a => n})
721
+ end
722
+ assert @@test.find({:a => 999}).next
723
+ assert !@@test.find({:a => 999}, :max_scan => 500).next
724
+ @@test.remove
725
+ end
726
+ end
727
+
707
728
  context "Grouping" do
708
729
  setup do
709
730
  @@test.remove
@@ -782,6 +803,7 @@ class TestCollection < Test::Unit::TestCase
782
803
  context "A collection with two records" do
783
804
  setup do
784
805
  @collection = @@db.collection('test-collection')
806
+ @collection.remove
785
807
  @collection.insert({:name => "Jones"})
786
808
  @collection.insert({:name => "Smith"})
787
809
  end
@@ -318,7 +318,7 @@ class TestConnection < Test::Unit::TestCase
318
318
  TCPSocket.stubs(:new).returns(fake_socket)
319
319
 
320
320
  @con.primary_pool.checkout_new_socket
321
- assert_equal [], @con.primary_pool.close
321
+ assert @con.primary_pool.close
322
322
  end
323
323
  end
324
324
  end
@@ -53,8 +53,8 @@ class CursorTest < Test::Unit::TestCase
53
53
  def test_exhaust
54
54
  if @@version >= "2.0"
55
55
  @@coll.remove
56
- data = "1" * 100_000
57
- 10_000.times do |n|
56
+ data = "1" * 10_000
57
+ 5000.times do |n|
58
58
  @@coll.insert({:n => n, :data => data})
59
59
  end
60
60
 
@@ -65,7 +65,7 @@ class CursorTest < Test::Unit::TestCase
65
65
 
66
66
  c = Cursor.new(@@coll)
67
67
  c.add_option(OP_QUERY_EXHAUST)
68
- 9999.times do
68
+ 4999.times do
69
69
  c.next
70
70
  end
71
71
  assert c.has_next?
@@ -1,7 +1,7 @@
1
1
  require File.join(File.dirname(__FILE__), '..', '..', '..', 'lib', 'mongo')
2
2
  require 'logger'
3
3
 
4
- $con = Mongo::Connection.new
4
+ $con = Mongo::ReplSetConnection.new(['localhost', 30000], ['localhost', 30001], :read => :secondary, :refresh_mode => :sync, :refresh_interval => 30)
5
5
  $db = $con['foo']
6
6
 
7
7
  class Load < Sinatra::Base
@@ -13,12 +13,9 @@ class Load < Sinatra::Base
13
13
  end
14
14
 
15
15
  get '/' do
16
- 3.times do |n|
17
- if (v=$db.eval("1 + #{n}")) != 1 + n
18
- STDERR << "#{1 + n} expected but got #{v}"
19
- raise StandardError, "#{1 + n} expected but got #{v}"
20
- end
21
- end
16
+ $db['test'].insert({:a => rand(1000)})
17
+ $db['test'].find({:a => {'$gt' => rand(2)}}, :read => :secondary).limit(2).to_a
18
+ "ok"
22
19
  end
23
20
 
24
21
  end
@@ -0,0 +1,46 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require './test/replica_sets/rs_test_helper'
3
+
4
+ class BasicTest < Test::Unit::TestCase
5
+ include ReplicaSetTest
6
+
7
+ def teardown
8
+ self.rs.restart_killed_nodes
9
+ @conn.close if defined?(@conn) && @conn
10
+ end
11
+
12
+ def test_connect
13
+ @conn = ReplSetConnection.new([self.rs.host, self.rs.ports[1]], [self.rs.host, self.rs.ports[0]],
14
+ [self.rs.host, self.rs.ports[2]], :name => self.rs.name)
15
+ assert @conn.connected?
16
+
17
+ assert_equal self.rs.primary, @conn.primary
18
+ assert_equal self.rs.secondaries.sort, @conn.secondaries.sort
19
+ assert_equal self.rs.arbiters.sort, @conn.arbiters.sort
20
+
21
+ @conn = ReplSetConnection.new([self.rs.host, self.rs.ports[1]], [self.rs.host, self.rs.ports[0]],
22
+ :name => self.rs.name)
23
+ assert @conn.connected?
24
+ end
25
+
26
+ def test_accessors
27
+ seeds = [[self.rs.host, self.rs.ports[0]], [self.rs.host, self.rs.ports[1]],
28
+ [self.rs.host, self.rs.ports[2]]]
29
+ args = seeds << {:name => self.rs.name}
30
+ @conn = ReplSetConnection.new(*args)
31
+
32
+ assert_equal @conn.host, self.rs.primary[0]
33
+ assert_equal @conn.port, self.rs.primary[1]
34
+ assert_equal @conn.host, @conn.primary_pool.host
35
+ assert_equal @conn.port, @conn.primary_pool.port
36
+ assert_equal @conn.nodes.sort, @conn.seeds.sort
37
+ assert_equal 2, @conn.secondaries.length
38
+ assert_equal 0, @conn.arbiters.length
39
+ assert_equal 2, @conn.secondary_pools.length
40
+ assert_equal self.rs.name, @conn.replica_set_name
41
+ assert @conn.secondary_pools.include?(@conn.read_pool)
42
+ assert_equal 5, @conn.tag_map.keys.length
43
+ assert_equal 90, @conn.refresh_interval
44
+ assert_equal @conn.refresh_mode, false
45
+ end
46
+ end
@@ -1,111 +1,88 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require './test/replica_sets/rs_test_helper'
3
3
 
4
- # NOTE: This test expects a replica set of three nodes to be running on RS.host,
5
- # on ports TEST_PORT, RS.ports[1], and TEST + 2.
6
4
  class ConnectTest < Test::Unit::TestCase
7
- include Mongo
5
+ include ReplicaSetTest
8
6
 
9
7
  def teardown
10
- RS.restart_killed_nodes
8
+ self.rs.restart_killed_nodes
11
9
  @conn.close if defined?(@conn) && @conn
12
10
  end
13
11
 
12
+ # TODO: test connect timeout.
13
+
14
14
  def test_connect_with_deprecated_multi
15
- @conn = Connection.multi([[RS.host, RS.ports[0]], [RS.host, RS.ports[1]]], :name => RS.name)
15
+ @conn = Connection.multi([[self.rs.host, self.rs.ports[0]], [self.rs.host, self.rs.ports[1]]], :name => self.rs.name)
16
16
  assert @conn.is_a?(ReplSetConnection)
17
17
  assert @conn.connected?
18
18
  end
19
19
 
20
20
  def test_connect_bad_name
21
21
  assert_raise_error(ReplicaSetConnectionError, "-wrong") do
22
- @conn = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]],
23
- [RS.host, RS.ports[2]], :name => RS.name + "-wrong")
22
+ @conn = ReplSetConnection.new([self.rs.host, self.rs.ports[0]], [self.rs.host, self.rs.ports[1]],
23
+ [self.rs.host, self.rs.ports[2]], :name => self.rs.name + "-wrong")
24
24
  end
25
25
  end
26
26
 
27
- # def test_connect_timeout
28
- # passed = false
29
- # timeout = 3
30
- # begin
31
- # t0 = Time.now
32
- # @conn = ReplSetConnection.new(['192.169.169.1', 27017], :connect_timeout => timeout)
33
- # rescue OperationTimeout
34
- # passed = true
35
- # t1 = Time.now
36
- # end
37
-
38
- # assert passed
39
- # assert t1 - t0 < timeout + 1
40
- # end
41
-
42
- def test_connect
43
- @conn = ReplSetConnection.new([RS.host, RS.ports[1]], [RS.host, RS.ports[0]],
44
- [RS.host, RS.ports[2]], :name => RS.name)
45
- assert @conn.connected?
46
-
47
- assert_equal RS.primary, @conn.primary
48
- assert_equal RS.secondaries.sort, @conn.secondaries.sort
49
- assert_equal RS.arbiters.sort, @conn.arbiters.sort
50
-
51
- @conn = ReplSetConnection.new([RS.host, RS.ports[1]], [RS.host, RS.ports[0]],
52
- :name => RS.name)
53
- assert @conn.connected?
54
- end
55
-
56
- def test_host_port_accessors
57
- @conn = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]],
58
- [RS.host, RS.ports[2]], :name => RS.name)
59
-
60
- assert_equal @conn.host, RS.primary[0]
61
- assert_equal @conn.port, RS.primary[1]
62
- end
63
-
64
27
  def test_connect_with_primary_node_killed
65
- node = RS.kill_primary
28
+ node = self.rs.kill_primary
66
29
 
67
30
  # Becuase we're killing the primary and trying to connect right away,
68
31
  # this is going to fail right away.
69
32
  assert_raise_error(ConnectionFailure, "Failed to connect to primary node") do
70
- @conn = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]],
71
- [RS.host, RS.ports[2]])
33
+ @conn = ReplSetConnection.new([self.rs.host, self.rs.ports[0]], [self.rs.host, self.rs.ports[1]],
34
+ [self.rs.host, self.rs.ports[2]])
72
35
  end
73
36
 
74
37
  # This allows the secondary to come up as a primary
75
38
  rescue_connection_failure do
76
- @conn = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]],
77
- [RS.host, RS.ports[2]])
39
+ @conn = ReplSetConnection.new([self.rs.host, self.rs.ports[0]], [self.rs.host, self.rs.ports[1]],
40
+ [self.rs.host, self.rs.ports[2]])
78
41
  end
79
42
  end
80
43
 
81
44
  def test_connect_with_secondary_node_killed
82
- node = RS.kill_secondary
45
+ node = self.rs.kill_secondary
83
46
 
84
47
  rescue_connection_failure do
85
- @conn = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]],
86
- [RS.host, RS.ports[2]])
48
+ @conn = ReplSetConnection.new([self.rs.host, self.rs.ports[0]], [self.rs.host, self.rs.ports[1]],
49
+ [self.rs.host, self.rs.ports[2]])
87
50
  end
88
51
  assert @conn.connected?
89
52
  end
90
53
 
91
54
  def test_connect_with_third_node_killed
92
- RS.kill(RS.get_node_from_port(RS.ports[2]))
55
+ self.rs.kill(self.rs.get_node_from_port(self.rs.ports[2]))
93
56
 
94
57
  rescue_connection_failure do
95
- @conn = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]],
96
- [RS.host, RS.ports[2]])
58
+ @conn = ReplSetConnection.new([self.rs.host, self.rs.ports[0]], [self.rs.host, self.rs.ports[1]],
59
+ [self.rs.host, self.rs.ports[2]])
97
60
  end
98
61
  assert @conn.connected?
99
62
  end
100
63
 
101
64
  def test_connect_with_primary_stepped_down
102
- RS.step_down_primary
65
+ self.rs.step_down_primary
103
66
 
104
67
  rescue_connection_failure do
105
- @conn = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]],
106
- [RS.host, RS.ports[2]])
68
+ @conn = ReplSetConnection.new([self.rs.host, self.rs.ports[0]], [self.rs.host, self.rs.ports[1]],
69
+ [self.rs.host, self.rs.ports[2]])
107
70
  end
108
71
  assert @conn.connected?
109
72
  end
110
73
 
74
+ def test_connect_with_connection_string
75
+ @conn = Connection.from_uri("mongodb://#{self.rs.host}:#{self.rs.ports[0]},#{self.rs.host}:#{self.rs.ports[1]}?replicaset=#{self.rs.name}")
76
+ assert @conn.is_a?(ReplSetConnection)
77
+ assert @conn.connected?
78
+ end
79
+
80
+ def test_connect_with_full_connection_string
81
+ @conn = Connection.from_uri("mongodb://#{self.rs.host}:#{self.rs.ports[0]},#{self.rs.host}:#{self.rs.ports[1]}?replicaset=#{self.rs.name};safe=true;w=2;fsync=true;slaveok=true")
82
+ assert @conn.is_a?(ReplSetConnection)
83
+ assert @conn.connected?
84
+ assert_equal 2, @conn.safe[:w]
85
+ assert @conn.safe[:fsync]
86
+ assert @conn.read_pool
87
+ end
111
88
  end
@@ -1,20 +1,22 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require './test/replica_sets/rs_test_helper'
3
3
 
4
- # NOTE: This test expects a replica set of three nodes to be running
5
- # on the local host.
6
4
  class ReplicaSetCountTest < Test::Unit::TestCase
7
- include Mongo
5
+ include ReplicaSetTest
8
6
 
9
7
  def setup
10
- @conn = ReplSetConnection.new([RS.host, RS.ports[0]], [RS.host, RS.ports[1]], [RS.host, RS.ports[2]])
8
+ @conn = ReplSetConnection.new([self.rs.host, self.rs.ports[0]],
9
+ [self.rs.host, self.rs.ports[1]], [self.rs.host, self.rs.ports[2]],
10
+ :read => :secondary)
11
+ assert @conn.primary_pool
12
+ @primary = Connection.new(@conn.primary_pool.host, @conn.primary_pool.port)
11
13
  @db = @conn.db(MONGO_TEST_DB)
12
14
  @db.drop_collection("test-sets")
13
15
  @coll = @db.collection("test-sets")
14
16
  end
15
17
 
16
18
  def teardown
17
- RS.restart_killed_nodes
19
+ self.rs.restart_killed_nodes
18
20
  @conn.close if @conn
19
21
  end
20
22
 
@@ -23,7 +25,7 @@ class ReplicaSetCountTest < Test::Unit::TestCase
23
25
  assert_equal 1, @coll.count
24
26
 
25
27
  # Kill the current master node
26
- @node = RS.kill_primary
28
+ @node = self.rs.kill_primary
27
29
 
28
30
  rescue_connection_failure do
29
31
  @coll.insert({:a => 30}, :safe => true)
@@ -33,4 +35,11 @@ class ReplicaSetCountTest < Test::Unit::TestCase
33
35
  assert_equal 3, @coll.count, "Second count failed"
34
36
  end
35
37
 
38
+ def test_count_command_sent_to_primary
39
+ @coll.insert({:a => 20}, :safe => {:w => 2, :wtimeout => 10000})
40
+ count_before = @primary['admin'].command({:serverStatus => 1})['opcounters']['command']
41
+ assert_equal 1, @coll.count
42
+ count_after = @primary['admin'].command({:serverStatus => 1})['opcounters']['command']
43
+ assert_equal 2, count_after - count_before
44
+ end
36
45
  end