jmongo 1.0.3 → 1.1.0

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 (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