@@ -18,27 +18,27 @@ def test_get_more_secondary
18
18
19
19
def test_close_primary
20
20
setup_client ( :primary )
21
- cursor_close_test ( :primary )
21
+ kill_cursor_test ( :primary )
22
22
end
23
23
24
24
def test_close_secondary
25
25
setup_client ( :secondary )
26
- cursor_close_test ( :secondary )
26
+ kill_cursor_test ( :secondary )
27
27
end
28
28
29
29
def test_cursors_get_closed
30
30
setup_client
31
- assert_cursor_count
31
+ assert_cursors_on_members
32
32
end
33
33
34
34
def test_cursors_get_closed_secondary
35
35
setup_client ( :secondary )
36
- assert_cursor_count ( :secondary )
36
+ assert_cursors_on_members ( :secondary )
37
37
end
38
38
39
39
def test_cursors_get_closed_secondary_query
40
40
setup_client ( :primary )
41
- assert_cursor_count ( :secondary )
41
+ assert_cursors_on_members ( :secondary )
42
42
end
43
43
44
44
private
@@ -51,24 +51,17 @@ def setup_client(read=:primary)
51
51
@db = @client . db ( MONGO_TEST_DB )
52
52
@db . drop_collection ( "cursor_tests" )
53
53
@coll = @db . collection ( "cursor_tests" )
54
-
55
- @coll . insert ( { :a => 1 } , :w => 3 )
56
- @coll . insert ( { :b => 2 } , :w => 3 )
57
- @coll . insert ( { :c => 3 } , :w => 3 )
58
-
59
- # Pin reader
60
- @coll . find_one
54
+ insert_docs
61
55
62
56
# Setup Direct Connections
63
57
@primary = Mongo ::MongoClient . new ( *@client . manager . primary )
64
58
end
65
59
66
- def cursor_count ( client )
67
- client [ 'cursor_tests' ] . command ( { :cursorInfo => 1 } ) [ 'totalOpen' ]
68
- end
69
-
70
- def query_count ( client )
71
- client [ 'admin' ] . command ( { :serverStatus => 1 } ) [ 'opcounters' ] [ 'query' ]
60
+ def insert_docs
61
+ @n_docs = 102 # batch size is 101
62
+ @n_docs . times do |i |
63
+ @coll . insert ( { "x" => i } , :w => 3 )
64
+ end
72
65
end
73
66
74
67
def set_read_client_and_tag ( read )
@@ -80,66 +73,100 @@ def set_read_client_and_tag(read)
80
73
cursor . next
81
74
pool = cursor . instance_variable_get ( :@pool )
82
75
cursor . close
83
- @read = Mongo ::MongoClient . new ( pool . host , pool . port )
76
+ @read = Mongo ::MongoClient . new ( pool . host , pool . port , :slave_ok => true )
84
77
tag
85
78
rescue Mongo ::ConnectionFailure
86
79
false
87
80
end
88
81
end
89
82
end
90
83
91
- def assert_cursor_count ( read = :primary )
92
- set_read_client_and_tag ( read )
93
-
94
- before_primary_cursor = cursor_count ( @primary )
95
- before_read_cursor = cursor_count ( @read )
96
- before_read_query = query_count ( @read )
97
-
84
+ def route_query ( read )
98
85
read_opts = { :read => read }
99
86
read_opts [ :tag_sets ] = [ { :node => @tag } ] unless read == :primary
100
- @coll . find ( { } , read_opts ) . limit ( 2 ) . to_a
101
-
102
- after_primary_cursor = cursor_count ( @primary )
103
- after_read_cursor = cursor_count ( @read )
104
- after_read_query = query_count ( @read )
87
+ object_id = BSON ::ObjectId . new
88
+ read_opts [ :comment ] = object_id
89
+
90
+ # set profiling level to 2 on client and member to which the query will be routed
91
+ @client . db ( MONGO_TEST_DB ) . profiling_level = :all
92
+ @client . secondaries . each do |node |
93
+ node = Mongo ::MongoClient . new ( node [ 0 ] , node [ 1 ] , :slave_ok => true )
94
+ node . db ( MONGO_TEST_DB ) . profiling_level = :all
95
+ end
105
96
106
- assert_equal before_primary_cursor , after_primary_cursor
107
- assert_equal before_read_cursor , after_read_cursor
108
- assert_equal 1 , after_read_query - before_read_query
109
- end
97
+ @cursor = @coll . find ( { } , read_opts )
98
+ @cursor . next
110
99
111
- def insert_docs
112
- 102 . times do |i |
113
- @coll . insert ( { :i => i } , :w => 3 )
100
+ # on client and other members set profiling level to 0
101
+ @client . db ( MONGO_TEST_DB ) . profiling_level = :off
102
+ @client . secondaries . each do |node |
103
+ node = Mongo ::MongoClient . new ( node [ 0 ] , node [ 1 ] , :slave_ok => true )
104
+ node . db ( MONGO_TEST_DB ) . profiling_level = :off
114
105
end
106
+ # do a query on system.profile of the reader to see if it was used for the query
107
+ profiled_queries = @read . db ( MONGO_TEST_DB ) . collection ( 'system.profile' ) . find ( {
108
+ 'ns' => "#{ MONGO_TEST_DB } .cursor_tests" , "query.$comment" => object_id } )
109
+
110
+ assert_equal 1 , profiled_queries . count
115
111
end
116
112
117
113
# batch from send_initial_query is 101 documents
114
+ # check that you get n_docs back from the query, with the same port
118
115
def cursor_get_more_test ( read = :primary )
119
- insert_docs
116
+ set_read_client_and_tag ( read )
120
117
10 . times do
121
- cursor = @coll . find ( { } , :read => read )
122
- cursor . next
123
- port = cursor . instance_variable_get ( :@pool ) . port
124
- assert cursor . alive?
125
- while cursor . has_next?
126
- cursor . next
127
- assert_equal port , cursor . instance_variable_get ( :@pool ) . port
118
+ # assert that the query went to the correct member
119
+ route_query ( read )
120
+ docs_count = 1
121
+ port = @cursor . instance_variable_get ( :@pool ) . port
122
+ assert @cursor . alive?
123
+ while @cursor . has_next?
124
+ docs_count += 1
125
+ @cursor . next
126
+ assert_equal port , @cursor . instance_variable_get ( :@pool ) . port
128
127
end
129
- assert !cursor . alive?
130
- cursor . close #cursor is already closed
128
+ assert !@cursor . alive?
129
+ assert_equal @n_docs , docs_count
130
+ @cursor . close #cursor is already closed
131
131
end
132
132
end
133
133
134
134
# batch from get_more can be huge, so close after send_initial_query
135
- def cursor_close_test ( read = :primary )
136
- insert_docs
135
+ def kill_cursor_test ( read = :primary )
136
+ set_read_client_and_tag ( read )
137
137
10 . times do
138
- cursor = @coll . find ( { } , :read => read )
139
- cursor . next
140
- assert cursor . instance_variable_get ( :@pool )
141
- assert cursor . alive?
142
- cursor . close
138
+ # assert that the query went to the correct member
139
+ route_query ( read )
140
+ cursor_id = @cursor . cursor_id
141
+ cursor_clone = @cursor . clone
142
+ assert_equal cursor_id , cursor_clone . cursor_id
143
+ assert @cursor . instance_variable_get ( :@pool )
144
+ # .next was called once already and leave one for get more
145
+ ( @n_docs -2 ) . times { @cursor . next }
146
+ @cursor . close
147
+ # an exception confirms the cursor has indeed been closed
148
+ assert_raise Mongo ::OperationFailure do
149
+ cursor_clone . next
150
+ end
151
+ end
152
+ end
153
+
154
+ def assert_cursors_on_members ( read = :primary )
155
+ set_read_client_and_tag ( read )
156
+ # assert that the query went to the correct member
157
+ route_query ( read )
158
+ cursor_id = @cursor . cursor_id
159
+ cursor_clone = @cursor . clone
160
+ assert_equal cursor_id , cursor_clone . cursor_id
161
+ assert @cursor . instance_variable_get ( :@pool )
162
+ port = @cursor . instance_variable_get ( :@pool ) . port
163
+ while @cursor . has_next?
164
+ @cursor . next
165
+ assert_equal port , @cursor . instance_variable_get ( :@pool ) . port
166
+ end
167
+ # an exception confirms the cursor has indeed been closed after query
168
+ assert_raise Mongo ::OperationFailure do
169
+ cursor_clone . next
143
170
end
144
171
end
145
- end
172
+ end
0 commit comments