jmongo 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +43 -0
  3. data/Rakefile +72 -0
  4. data/jmongo.gemspec +84 -6
  5. data/lib/jmongo.rb +6 -14
  6. data/lib/jmongo/collection.rb +196 -114
  7. data/lib/jmongo/connection.rb +39 -13
  8. data/lib/jmongo/cursor.rb +161 -63
  9. data/lib/jmongo/db.rb +119 -30
  10. data/lib/jmongo/exceptions.rb +39 -0
  11. data/lib/jmongo/mongo-2.6.5.gb1.jar +0 -0
  12. data/lib/jmongo/mongo/bson.rb +130 -0
  13. data/lib/jmongo/mongo/collection.rb +185 -0
  14. data/lib/jmongo/mongo/connection.rb +45 -0
  15. data/lib/jmongo/mongo/db.rb +31 -0
  16. data/lib/jmongo/mongo/jmongo.rb +44 -0
  17. data/lib/jmongo/mongo/mongo.rb +98 -0
  18. data/lib/jmongo/mongo/ruby_ext.rb +38 -0
  19. data/lib/jmongo/mongo/utils.rb +136 -0
  20. data/lib/jmongo/version.rb +1 -1
  21. data/test-results.txt +98 -0
  22. data/test/auxillary/1.4_features.rb +166 -0
  23. data/test/auxillary/authentication_test.rb +68 -0
  24. data/test/auxillary/autoreconnect_test.rb +41 -0
  25. data/test/auxillary/fork_test.rb +30 -0
  26. data/test/auxillary/repl_set_auth_test.rb +58 -0
  27. data/test/auxillary/slave_connection_test.rb +36 -0
  28. data/test/auxillary/threaded_authentication_test.rb +101 -0
  29. data/test/bson/binary_test.rb +15 -0
  30. data/test/bson/bson_test.rb +657 -0
  31. data/test/bson/byte_buffer_test.rb +208 -0
  32. data/test/bson/hash_with_indifferent_access_test.rb +38 -0
  33. data/test/bson/json_test.rb +17 -0
  34. data/test/bson/object_id_test.rb +138 -0
  35. data/test/bson/ordered_hash_test.rb +245 -0
  36. data/test/bson/test_helper.rb +46 -0
  37. data/test/bson/timestamp_test.rb +46 -0
  38. data/test/collection_test.rb +933 -0
  39. data/test/connection_test.rb +325 -0
  40. data/test/conversions_test.rb +121 -0
  41. data/test/cursor_fail_test.rb +75 -0
  42. data/test/cursor_message_test.rb +43 -0
  43. data/test/cursor_test.rb +547 -0
  44. data/test/data/empty_data +0 -0
  45. data/test/data/sample_data +0 -0
  46. data/test/data/sample_file.pdf +0 -0
  47. data/test/data/small_data.txt +1 -0
  48. data/test/db_api_test.rb +739 -0
  49. data/test/db_connection_test.rb +15 -0
  50. data/test/db_test.rb +325 -0
  51. data/test/grid_file_system_test.rb +260 -0
  52. data/test/grid_io_test.rb +210 -0
  53. data/test/grid_test.rb +259 -0
  54. data/test/load/thin/config.ru +6 -0
  55. data/test/load/thin/config.yml.template +6 -0
  56. data/test/load/thin/load.rb +24 -0
  57. data/test/load/unicorn/config.ru +6 -0
  58. data/test/load/unicorn/load.rb +23 -0
  59. data/test/load/unicorn/unicorn.rb.template +29 -0
  60. data/test/replica_sets/connect_test.rb +111 -0
  61. data/test/replica_sets/connection_string_test.rb +29 -0
  62. data/test/replica_sets/count_test.rb +36 -0
  63. data/test/replica_sets/insert_test.rb +54 -0
  64. data/test/replica_sets/pooled_insert_test.rb +58 -0
  65. data/test/replica_sets/query_secondaries.rb +109 -0
  66. data/test/replica_sets/query_test.rb +52 -0
  67. data/test/replica_sets/read_preference_test.rb +43 -0
  68. data/test/replica_sets/refresh_test.rb +123 -0
  69. data/test/replica_sets/replication_ack_test.rb +71 -0
  70. data/test/replica_sets/rs_test_helper.rb +27 -0
  71. data/test/safe_test.rb +68 -0
  72. data/test/support/hash_with_indifferent_access.rb +186 -0
  73. data/test/support/keys.rb +45 -0
  74. data/test/support_test.rb +19 -0
  75. data/test/test_helper.rb +111 -0
  76. data/test/threading/threading_with_large_pool_test.rb +90 -0
  77. data/test/threading_test.rb +88 -0
  78. data/test/tools/auth_repl_set_manager.rb +14 -0
  79. data/test/tools/keyfile.txt +1 -0
  80. data/test/tools/repl_set_manager.rb +377 -0
  81. data/test/unit/collection_test.rb +128 -0
  82. data/test/unit/connection_test.rb +85 -0
  83. data/test/unit/cursor_test.rb +127 -0
  84. data/test/unit/db_test.rb +96 -0
  85. data/test/unit/grid_test.rb +51 -0
  86. data/test/unit/node_test.rb +73 -0
  87. data/test/unit/pool_manager_test.rb +47 -0
  88. data/test/unit/pool_test.rb +9 -0
  89. data/test/unit/read_test.rb +101 -0
  90. data/test/unit/safe_test.rb +125 -0
  91. data/test/uri_test.rb +92 -0
  92. metadata +170 -99
  93. data/lib/jmongo/ajrb.rb +0 -189
  94. data/lib/jmongo/jmongo_jext.rb +0 -302
  95. data/lib/jmongo/mongo-2.6.3.jar +0 -0
  96. data/lib/jmongo/utils.rb +0 -61
@@ -0,0 +1,210 @@
1
+ __END__
2
+ require './test/test_helper'
3
+
4
+ class GridIOTest < Test::Unit::TestCase
5
+
6
+ context "GridIO" do
7
+ setup do
8
+ @db = standard_connection.db(MONGO_TEST_DB)
9
+ @files = @db.collection('fs.files')
10
+ @chunks = @db.collection('fs.chunks')
11
+ @chunks.create_index([['files_id', Mongo::ASCENDING], ['n', Mongo::ASCENDING]])
12
+ end
13
+
14
+ teardown do
15
+ @files.remove
16
+ @chunks.remove
17
+ end
18
+
19
+ context "Options" do
20
+ setup do
21
+ @filename = 'test'
22
+ @mode = 'w'
23
+ end
24
+
25
+ should "set default 256k chunk size" do
26
+ file = GridIO.new(@files, @chunks, @filename, @mode)
27
+ assert_equal 256 * 1024, file.chunk_size
28
+ end
29
+
30
+ should "set chunk size" do
31
+ file = GridIO.new(@files, @chunks, @filename, @mode, :chunk_size => 1000)
32
+ assert_equal 1000, file.chunk_size
33
+ end
34
+ end
35
+
36
+ context "StringIO methods" do
37
+ setup do
38
+ @filename = 'test'
39
+ @mode = 'w'
40
+ @data = "012345678\n" * 100000
41
+ @file = GridIO.new(@files, @chunks, @filename, @mode)
42
+ @file.write(@data)
43
+ @file.close
44
+ end
45
+
46
+ should "read data character by character using" do
47
+ bytes = 0
48
+ file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
49
+ while char = file.getc
50
+ bytes += 1
51
+ end
52
+ assert_equal bytes, 1_000_000
53
+ end
54
+
55
+ should "read length is a length is given" do
56
+ file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
57
+ string = file.gets(1000)
58
+ assert_equal string.length, 1000
59
+ bytes = 0
60
+ bytes += string.length
61
+ while string = file.gets(1000)
62
+ bytes += string.length
63
+ end
64
+ assert_equal bytes, 1_000_000
65
+ end
66
+
67
+ should "read to the end of the line by default and assign to $_" do
68
+ file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
69
+ string = file.gets
70
+ assert_equal 10, string.length
71
+ end
72
+
73
+ should "read to the end of the file one line at a time" do
74
+ file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
75
+ bytes = 0
76
+ while string = file.gets
77
+ bytes += string.length
78
+ end
79
+ assert_equal 1_000_000, bytes
80
+ end
81
+
82
+ should "read to the end of the file one multi-character separator at a time" do
83
+ file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
84
+ bytes = 0
85
+ while string = file.gets("45")
86
+ bytes += string.length
87
+ end
88
+ assert_equal 1_000_000, bytes
89
+ end
90
+
91
+ should "read to a given separator" do
92
+ file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
93
+ string = file.gets("5")
94
+ assert_equal 6, string.length
95
+ end
96
+
97
+ should "read a multi-character separator" do
98
+ file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
99
+ string = file.gets("45")
100
+ assert_equal 6, string.length
101
+ string = file.gets("45")
102
+ assert_equal "678\n012345", string
103
+ string = file.gets("\n01")
104
+ assert_equal "678\n01", string
105
+ end
106
+
107
+ should "read a mult-character separator with a length" do
108
+ file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
109
+ string = file.gets("45", 3)
110
+ assert_equal 3, string.length
111
+ end
112
+
113
+ should "tell position, eof, and rewind" do
114
+ file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
115
+ string = file.read(1000)
116
+ assert_equal 1000, file.pos
117
+ assert !file.eof?
118
+ file.read
119
+ assert file.eof?
120
+ file.rewind
121
+ assert_equal 0, file.pos
122
+ assert_equal 1_000_000, file.read.length
123
+ end
124
+ end
125
+
126
+ context "Seeking" do
127
+ setup do
128
+ @filename = 'test'
129
+ @mode = 'w'
130
+ @data = "1" * 1024 * 1024
131
+ @file = GridIO.new(@files, @chunks, @filename, @mode)
132
+ @file.write(@data)
133
+ @file.close
134
+ end
135
+
136
+ should "read all data using read_length and then be able to seek" do
137
+ file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
138
+ assert_equal @data, file.read(1024 * 1024)
139
+ file.seek(0)
140
+ assert_equal @data, file.read
141
+ end
142
+
143
+ should "read all data using read_all and then be able to seek" do
144
+ file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id})
145
+ assert_equal @data, file.read
146
+ file.seek(0)
147
+ assert_equal @data, file.read
148
+ file.seek(1024 * 512)
149
+ assert_equal 524288, file.file_position
150
+ assert_equal @data.length / 2, file.read.length
151
+ assert_equal 1048576, file.file_position
152
+ assert_nil file.read
153
+ file.seek(1024 * 512)
154
+ assert_equal 524288, file.file_position
155
+ end
156
+
157
+ end
158
+
159
+ context "Grid MD5 check" do
160
+ should "run in safe mode" do
161
+ file = GridIO.new(@files, @chunks, 'smallfile', 'w', :safe => true)
162
+ file.write("DATA" * 100)
163
+ assert file.close
164
+ assert_equal file.server_md5, file.client_md5
165
+ end
166
+
167
+ should "validate with a large file" do
168
+ io = File.open(File.join(File.dirname(__FILE__), 'data', 'sample_file.pdf'), 'r')
169
+ file = GridIO.new(@files, @chunks, 'bigfile', 'w', :safe => true)
170
+ file.write(io)
171
+ assert file.close
172
+ assert_equal file.server_md5, file.client_md5
173
+ end
174
+
175
+ should "raise an exception when check fails" do
176
+ io = File.open(File.join(File.dirname(__FILE__), 'data', 'sample_file.pdf'), 'r')
177
+ @db.stubs(:command).returns({'md5' => '12345'})
178
+ file = GridIO.new(@files, @chunks, 'bigfile', 'w', :safe => true)
179
+ file.write(io)
180
+ assert_raise GridMD5Failure do
181
+ assert file.close
182
+ end
183
+ assert_not_equal file.server_md5, file.client_md5
184
+ end
185
+ end
186
+
187
+ context "Content types" do
188
+ if defined?(MIME)
189
+ should "determine common content types from the extension" do
190
+ file = GridIO.new(@files, @chunks, 'sample.pdf', 'w')
191
+ assert_equal 'application/pdf', file.content_type
192
+
193
+ file = GridIO.new(@files, @chunks, 'sample.txt', 'w')
194
+ assert_equal 'text/plain', file.content_type
195
+ end
196
+ end
197
+
198
+ should "default to binary/octet-stream when type is unknown" do
199
+ file = GridIO.new(@files, @chunks, 'sample.l33t', 'w')
200
+ assert_equal 'binary/octet-stream', file.content_type
201
+ end
202
+
203
+ should "use any provided content type by default" do
204
+ file = GridIO.new(@files, @chunks, 'sample.l33t', 'w', :content_type => 'image/jpg')
205
+ assert_equal 'image/jpg', file.content_type
206
+ end
207
+ end
208
+ end
209
+
210
+ end
@@ -0,0 +1,259 @@
1
+ __END__
2
+ require './test/test_helper'
3
+ include Mongo
4
+
5
+ def read_and_write_stream(filename, read_length, opts={})
6
+ io = File.open(File.join(File.dirname(__FILE__), 'data', filename), 'r')
7
+ id = @grid.put(io, opts.merge!(:filename => filename + read_length.to_s))
8
+ file = @grid.get(id)
9
+ io.rewind
10
+ data = io.read
11
+ if data.respond_to?(:force_encoding)
12
+ data.force_encoding("binary")
13
+ end
14
+ read_data = ""
15
+ while(chunk = file.read(read_length))
16
+ read_data << chunk
17
+ break if chunk.empty?
18
+ end
19
+ assert_equal data.length, read_data.length
20
+ end
21
+
22
+ class GridTest < Test::Unit::TestCase
23
+ context "Tests:" do
24
+ setup do
25
+ @db = standard_connection.db(MONGO_TEST_DB)
26
+ @files = @db.collection('test-fs.files')
27
+ @chunks = @db.collection('test-fs.chunks')
28
+ end
29
+
30
+ teardown do
31
+ @files.remove
32
+ @chunks.remove
33
+ end
34
+
35
+ context "A one-chunk grid-stored file" do
36
+ setup do
37
+ @data = "GRIDDATA" * 5
38
+ @grid = Grid.new(@db, 'test-fs')
39
+ @id = @grid.put(@data, :filename => 'sample',
40
+ :metadata => {'app' => 'photos'})
41
+ end
42
+
43
+ should "retrieve the file" do
44
+ data = @grid.get(@id).data
45
+ assert_equal @data, data
46
+ end
47
+
48
+ end
49
+
50
+ context "A basic grid-stored file" do
51
+ setup do
52
+ @data = "GRIDDATA" * 50000
53
+ @grid = Grid.new(@db, 'test-fs')
54
+ @id = @grid.put(@data, :filename => 'sample',
55
+ :metadata => {'app' => 'photos'})
56
+ end
57
+
58
+ should "check existence" do
59
+ file = @grid.exist?(:filename => 'sample')
60
+ assert_equal 'sample', file['filename']
61
+ end
62
+
63
+ should "not be able to overwrite an exising file" do
64
+ assert_raise GridError do
65
+ @grid.put(@data, :filename => 'sample', :_id => @id, :safe => true)
66
+ end
67
+ end
68
+
69
+ should "return nil if it doesn't exist" do
70
+ assert_nil @grid.exist?(:metadata => 'foo')
71
+ end
72
+
73
+ should "retrieve the stored data" do
74
+ data = @grid.get(@id).data
75
+ assert_equal @data.length, data.length
76
+ end
77
+
78
+ should "have a unique index on chunks" do
79
+ assert @chunks.index_information['files_id_1_n_1']['unique']
80
+ end
81
+
82
+ should "store the filename" do
83
+ file = @grid.get(@id)
84
+ assert_equal 'sample', file.filename
85
+ end
86
+
87
+ should "store any relevant metadata" do
88
+ file = @grid.get(@id)
89
+ assert_equal 'photos', file.metadata['app']
90
+ end
91
+
92
+ should "delete the file and any chunks" do
93
+ @grid.delete(@id)
94
+ assert_raise GridFileNotFound do
95
+ @grid.get(@id)
96
+ end
97
+ assert_equal nil, @db['test-fs']['chunks'].find_one({:files_id => @id})
98
+ end
99
+ end
100
+
101
+ context "Filename not required" do
102
+ setup do
103
+ @data = "GRIDDATA" * 50000
104
+ @grid = Grid.new(@db, 'test-fs')
105
+ @metadata = {'app' => 'photos'}
106
+ end
107
+
108
+ should "store the file with the old filename api" do
109
+ id = @grid.put(@data, :filename => 'sample', :metadata => @metadata)
110
+ file = @grid.get(id)
111
+ assert_equal 'sample', file.filename
112
+ assert_equal @metadata, file.metadata
113
+ end
114
+
115
+ should "store without a filename" do
116
+ id = @grid.put(@data, :metadata => @metadata)
117
+ file = @grid.get(id)
118
+ assert_nil file.filename
119
+ file_doc = @files.find_one({'_id' => id})
120
+ assert !file_doc.has_key?('filename')
121
+ assert_equal @metadata, file.metadata
122
+ end
123
+
124
+ should "store with filename and metadata with the new api" do
125
+ id = @grid.put(@data, :filename => 'sample', :metadata => @metadata)
126
+ file = @grid.get(id)
127
+ assert_equal 'sample', file.filename
128
+ assert_equal @metadata, file.metadata
129
+ end
130
+ end
131
+
132
+ context "Writing arbitrary data fields" do
133
+ setup do
134
+ @data = "GRIDDATA" * 50000
135
+ @grid = Grid.new(@db, 'test-fs')
136
+ end
137
+
138
+ should "write random keys to the files collection" do
139
+ id = @grid.put(@data, :phrases => ["blimey", "ahoy!"])
140
+ file = @grid.get(id)
141
+
142
+ assert_equal ["blimey", "ahoy!"], file['phrases']
143
+ end
144
+
145
+ should "ignore special keys" do
146
+ id = @grid.put(@data, :file_length => 100, :phrase => "blimey")
147
+ file = @grid.get(id)
148
+
149
+ assert_equal "blimey", file['phrase']
150
+ assert_equal 400_000, file.file_length
151
+ end
152
+ end
153
+
154
+ context "Storing data with a length of zero" do
155
+ setup do
156
+ @grid = Grid.new(@db, 'test-fs')
157
+ @id = @grid.put('', :filename => 'sample',
158
+ :metadata => {'app' => 'photos'})
159
+ end
160
+
161
+ should "return the zero length" do
162
+ data = @grid.get(@id)
163
+ assert_equal 0, data.read.length
164
+ end
165
+ end
166
+
167
+ context "Grid streaming: " do
168
+ setup do
169
+ @grid = Grid.new(@db, 'test-fs')
170
+ filename = 'sample_data'
171
+ @io = File.open(File.join(File.dirname(__FILE__), 'data', filename), 'r')
172
+ id = @grid.put(@io, :filename => filename)
173
+ @file = @grid.get(id)
174
+ @io.rewind
175
+ @data = @io.read
176
+ if @data.respond_to?(:force_encoding)
177
+ @data.force_encoding("binary")
178
+ end
179
+ end
180
+
181
+ should "be equal in length" do
182
+ @io.rewind
183
+ assert_equal @io.read.length, @file.read.length
184
+ end
185
+
186
+ should "read the file" do
187
+ read_data = ""
188
+ @file.each do |chunk|
189
+ read_data << chunk
190
+ end
191
+ assert_equal @data.length, read_data.length
192
+ end
193
+
194
+ should "read the file if no block is given" do
195
+ read_data = @file.each
196
+ assert_equal @data.length, read_data.length
197
+ end
198
+ end
199
+
200
+ context "Grid streaming an empty file: " do
201
+ setup do
202
+ @grid = Grid.new(@db, 'test-fs')
203
+ filename = 'empty_data'
204
+ @io = File.open(File.join(File.dirname(__FILE__), 'data', filename), 'r')
205
+ id = @grid.put(@io, :filename => filename)
206
+ @file = @grid.get(id)
207
+ @io.rewind
208
+ @data = @io.read
209
+ if @data.respond_to?(:force_encoding)
210
+ @data.force_encoding("binary")
211
+ end
212
+ end
213
+
214
+ should "be equal in length" do
215
+ @io.rewind
216
+ assert_equal @io.read.length, @file.read.length
217
+ end
218
+
219
+ should "read the file" do
220
+ read_data = ""
221
+ @file.each do |chunk|
222
+ read_data << chunk
223
+ end
224
+ assert_equal @data.length, read_data.length
225
+ end
226
+
227
+ should "read the file if no block is given" do
228
+ read_data = @file.each
229
+ assert_equal @data.length, read_data.length
230
+ end
231
+ end
232
+
233
+ context "Streaming: " do || {}
234
+ setup do
235
+ @grid = Grid.new(@db, 'test-fs')
236
+ end
237
+
238
+ should "put and get a small io object with a small chunk size" do
239
+ read_and_write_stream('small_data.txt', 1, :chunk_size => 2)
240
+ end
241
+
242
+ should "put and get an empty io object" do
243
+ read_and_write_stream('empty_data', 1)
244
+ end
245
+
246
+ should "put and get a small io object" do
247
+ read_and_write_stream('small_data.txt', 1)
248
+ end
249
+
250
+ should "put and get a large io object if reading less than the chunk size" do
251
+ read_and_write_stream('sample_data', 256 * 1024)
252
+ end
253
+
254
+ should "put and get a large io object if reading more than the chunk size" do
255
+ read_and_write_stream('sample_data', 300 * 1024)
256
+ end
257
+ end
258
+ end
259
+ end