rocketjob 3.5.2 → 4.0.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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +63 -1
  3. data/bin/rocketjob +1 -0
  4. data/bin/rocketjob_batch_perf +11 -0
  5. data/lib/rocket_job/batch.rb +32 -0
  6. data/lib/rocket_job/batch/callbacks.rb +40 -0
  7. data/lib/rocket_job/batch/io.rb +154 -0
  8. data/lib/rocket_job/batch/logger.rb +57 -0
  9. data/lib/rocket_job/batch/lower_priority.rb +54 -0
  10. data/lib/rocket_job/batch/model.rb +157 -0
  11. data/lib/rocket_job/batch/performance.rb +99 -0
  12. data/lib/rocket_job/batch/result.rb +8 -0
  13. data/lib/rocket_job/batch/results.rb +9 -0
  14. data/lib/rocket_job/batch/state_machine.rb +102 -0
  15. data/lib/rocket_job/batch/statistics.rb +88 -0
  16. data/lib/rocket_job/batch/tabular.rb +56 -0
  17. data/lib/rocket_job/batch/tabular/input.rb +123 -0
  18. data/lib/rocket_job/batch/tabular/output.rb +59 -0
  19. data/lib/rocket_job/batch/throttle.rb +91 -0
  20. data/lib/rocket_job/batch/throttle_running_slices.rb +53 -0
  21. data/lib/rocket_job/batch/worker.rb +288 -0
  22. data/lib/rocket_job/cli.rb +29 -7
  23. data/lib/rocket_job/config.rb +1 -1
  24. data/lib/rocket_job/extensions/mongoid/clients/options.rb +37 -0
  25. data/lib/rocket_job/extensions/mongoid/contextual/mongo.rb +17 -0
  26. data/lib/rocket_job/extensions/mongoid/factory.rb +4 -4
  27. data/lib/rocket_job/extensions/mongoid_5/clients/options.rb +38 -0
  28. data/lib/rocket_job/extensions/mongoid_5/contextual/mongo.rb +64 -0
  29. data/lib/rocket_job/extensions/mongoid_5/factory.rb +13 -0
  30. data/lib/rocket_job/jobs/on_demand_batch_job.rb +127 -0
  31. data/lib/rocket_job/jobs/performance_job.rb +18 -0
  32. data/lib/rocket_job/jobs/upload_file_job.rb +2 -5
  33. data/lib/rocket_job/plugins/document.rb +2 -8
  34. data/lib/rocket_job/plugins/job/persistence.rb +6 -4
  35. data/lib/rocket_job/plugins/job/throttle.rb +3 -6
  36. data/lib/rocket_job/plugins/job/worker.rb +2 -2
  37. data/lib/rocket_job/server.rb +14 -3
  38. data/lib/rocket_job/sliced/input.rb +336 -0
  39. data/lib/rocket_job/sliced/output.rb +99 -0
  40. data/lib/rocket_job/sliced/slice.rb +166 -0
  41. data/lib/rocket_job/sliced/slices.rb +166 -0
  42. data/lib/rocket_job/sliced/writer/input.rb +60 -0
  43. data/lib/rocket_job/sliced/writer/output.rb +82 -0
  44. data/lib/rocket_job/version.rb +1 -1
  45. data/lib/rocket_job/worker.rb +2 -2
  46. data/lib/rocketjob.rb +28 -0
  47. metadata +51 -62
  48. data/test/config/database.yml +0 -5
  49. data/test/config/mongoid.yml +0 -88
  50. data/test/config_test.rb +0 -10
  51. data/test/dirmon_entry_test.rb +0 -313
  52. data/test/dirmon_job_test.rb +0 -216
  53. data/test/files/text.txt +0 -3
  54. data/test/job_test.rb +0 -71
  55. data/test/jobs/housekeeping_job_test.rb +0 -102
  56. data/test/jobs/on_demand_job_test.rb +0 -59
  57. data/test/jobs/upload_file_job_test.rb +0 -107
  58. data/test/plugins/cron_test.rb +0 -166
  59. data/test/plugins/job/callbacks_test.rb +0 -166
  60. data/test/plugins/job/defaults_test.rb +0 -53
  61. data/test/plugins/job/logger_test.rb +0 -56
  62. data/test/plugins/job/model_test.rb +0 -94
  63. data/test/plugins/job/persistence_test.rb +0 -94
  64. data/test/plugins/job/state_machine_test.rb +0 -116
  65. data/test/plugins/job/throttle_test.rb +0 -111
  66. data/test/plugins/job/worker_test.rb +0 -199
  67. data/test/plugins/processing_window_test.rb +0 -109
  68. data/test/plugins/restart_test.rb +0 -193
  69. data/test/plugins/retry_test.rb +0 -88
  70. data/test/plugins/singleton_test.rb +0 -92
  71. data/test/plugins/state_machine_event_callbacks_test.rb +0 -102
  72. data/test/plugins/state_machine_test.rb +0 -67
  73. data/test/plugins/transaction_test.rb +0 -84
  74. data/test/test_db.sqlite3 +0 -0
  75. data/test/test_helper.rb +0 -17
@@ -1,313 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- # Unit Test for RocketJob::Job
4
- class DirmonEntryTest < Minitest::Test
5
- class TestJob < RocketJob::Job
6
- # Dirmon will store the filename in this property when starting the job
7
- field :upload_file_name, type: String
8
-
9
- field :user_id, type: Integer
10
-
11
- def perform
12
- # Do something with the file name stored in :upload_file_name
13
- end
14
- end
15
-
16
- describe RocketJob::DirmonEntry do
17
- let :archive_directory do
18
- '/tmp/archive_directory'
19
- end
20
-
21
- let :archive_path do
22
- archive_path = Pathname.new(archive_directory)
23
- archive_path.mkpath
24
- archive_path.realdirpath
25
- end
26
-
27
- let :dirmon_entry do
28
- dirmon_entry = RocketJob::DirmonEntry.new(
29
- name: 'Test',
30
- job_class_name: 'DirmonEntryTest::TestJob',
31
- pattern: 'test/files/**',
32
- properties: {user_id: 341},
33
- archive_directory: archive_directory
34
- )
35
- dirmon_entry.enable!
36
- assert dirmon_entry.valid?, dirmon_entry.errors.messages.ai
37
- dirmon_entry
38
- end
39
-
40
- before do
41
- RocketJob::Jobs::DirmonJob.delete_all
42
- RocketJob::Jobs::UploadFileJob.delete_all
43
- RocketJob::DirmonEntry.delete_all
44
- end
45
-
46
- describe '.config' do
47
- it 'support multiple databases' do
48
- assert_equal 'rocketjob_test', RocketJob::DirmonEntry.collection.database.name
49
- end
50
- end
51
-
52
- describe '#job_class' do
53
- describe 'with a nil job_class_name' do
54
- it 'return nil' do
55
- entry = RocketJob::DirmonEntry.new
56
- assert_nil entry.job_class
57
- end
58
- end
59
-
60
- describe 'with an unknown job_class_name' do
61
- it 'return nil' do
62
- entry = RocketJob::DirmonEntry.new(job_class_name: 'FakeJobThatDoesNotExistAnyWhereIPromise')
63
- assert_nil entry.job_class
64
- end
65
- end
66
-
67
- describe 'with a valid job_class_name' do
68
- it 'return job class' do
69
- entry = RocketJob::DirmonEntry.new(job_class_name: 'RocketJob::Job')
70
- assert_equal RocketJob::Job, entry.job_class
71
- assert_equal 0, entry.properties.size
72
- end
73
- end
74
- end
75
-
76
- describe '.whitelist_paths' do
77
- it 'default to []' do
78
- assert_equal [], RocketJob::DirmonEntry.whitelist_paths
79
- end
80
- end
81
-
82
- describe '.add_whitelist_path' do
83
- after do
84
- RocketJob::DirmonEntry.whitelist_paths.each { |path| RocketJob::DirmonEntry.delete_whitelist_path(path) }
85
- end
86
-
87
- it 'convert relative path to an absolute one' do
88
- path = Pathname('test/files').realpath.to_s
89
- assert_equal path, RocketJob::DirmonEntry.add_whitelist_path('test/files')
90
- assert_equal [path], RocketJob::DirmonEntry.whitelist_paths
91
- end
92
-
93
- it 'prevent duplicates' do
94
- path = Pathname('test/files').realpath.to_s
95
- assert_equal path, RocketJob::DirmonEntry.add_whitelist_path('test/files')
96
- assert_equal path, RocketJob::DirmonEntry.add_whitelist_path('test/files')
97
- assert_equal path, RocketJob::DirmonEntry.add_whitelist_path(path)
98
- assert_equal [path], RocketJob::DirmonEntry.whitelist_paths
99
- end
100
- end
101
-
102
- describe '#fail!' do
103
- it 'fail with message' do
104
- dirmon_entry.fail!('myworker:2323', 'oh no')
105
- assert dirmon_entry.failed?
106
- assert_equal 'RocketJob::DirmonEntryException', dirmon_entry.exception.class_name
107
- assert_equal 'oh no', dirmon_entry.exception.message
108
- end
109
-
110
- it 'fail with exception' do
111
- exception = nil
112
- begin
113
- blah
114
- rescue Exception => exc
115
- exception = exc
116
- end
117
- dirmon_entry.fail!('myworker:2323', exception)
118
-
119
- assert_equal true, dirmon_entry.failed?
120
- assert_equal exception.class.name.to_s, dirmon_entry.exception.class_name
121
- assert dirmon_entry.exception.message.include?('undefined local variable or method'), dirmon_entry.attributes.inspect
122
- end
123
- end
124
-
125
- describe '#validate' do
126
- it 'strip_whitespace' do
127
- dirmon_entry.pattern = ' test/files/*'
128
- dirmon_entry.archive_directory = ' test/archive/ '
129
- assert dirmon_entry.valid?
130
- assert_equal 'test/files/*', dirmon_entry.pattern
131
- assert_equal 'test/archive/', dirmon_entry.archive_directory
132
- end
133
-
134
- describe 'pattern' do
135
- it 'present' do
136
- dirmon_entry.pattern = nil
137
- refute dirmon_entry.valid?
138
- assert_equal ["can't be blank"], dirmon_entry.errors[:pattern], dirmon_entry.errors.messages.ai
139
- end
140
- end
141
-
142
- describe 'job_class_name' do
143
- it 'ensure presence' do
144
- dirmon_entry.job_class_name = nil
145
- refute dirmon_entry.valid?
146
- assert_equal ["can't be blank"], dirmon_entry.errors[:job_class_name], dirmon_entry.errors.messages.ai
147
- end
148
-
149
- it 'is a RocketJob::Job' do
150
- dirmon_entry.job_class_name = 'String'
151
- refute dirmon_entry.valid?
152
- assert_equal ['Job String must be defined and inherit from RocketJob::Job'], dirmon_entry.errors[:job_class_name], dirmon_entry.errors.messages.ai
153
- end
154
-
155
- it 'is invalid' do
156
- dirmon_entry.job_class_name = 'Blah'
157
- refute dirmon_entry.valid?
158
- assert_equal ['Job Blah must be defined and inherit from RocketJob::Job'], dirmon_entry.errors[:job_class_name], dirmon_entry.errors.messages.ai
159
- end
160
- end
161
-
162
- describe 'properties' do
163
- it 'are valid' do
164
- dirmon_entry.properties = {user_id: 123}
165
- assert dirmon_entry.valid?, dirmon_entry.errors.messages.ai
166
- end
167
-
168
- it 'not valid' do
169
- dirmon_entry.properties = {blah: 123}
170
- refute dirmon_entry.valid?
171
- assert_equal ['Unknown Property: Attempted to set a value for :blah which is not allowed on the job DirmonEntryTest::TestJob'], dirmon_entry.errors[:properties], dirmon_entry.errors.messages.ai
172
- end
173
- end
174
- end
175
-
176
- describe 'with valid entry' do
177
- let :file do
178
- file = Tempfile.new('archive')
179
- File.open(file.path, 'w') { |file| file.write('Hello World') }
180
- file
181
- end
182
-
183
- let :file_name do
184
- file.path
185
- end
186
-
187
- let :pathname do
188
- Pathname.new(file_name)
189
- end
190
-
191
- after do
192
- file.delete
193
- RocketJob::Jobs::DirmonJob.delete_all
194
- end
195
-
196
- describe '#each' do
197
- it 'without archive path' do
198
- dirmon_entry.archive_directory = nil
199
- files = []
200
- dirmon_entry.each do |file_name|
201
- files << file_name
202
- end
203
- assert_nil dirmon_entry.archive_directory
204
- assert_equal 1, files.count
205
- assert_equal Pathname.new('test/files/text.txt').realpath, files.first
206
- end
207
-
208
- it 'with archive path' do
209
- files = []
210
- dirmon_entry.each do |file_name|
211
- files << file_name
212
- end
213
- assert_equal 1, files.count
214
- assert_equal Pathname.new('test/files/text.txt').realpath, files.first
215
- end
216
-
217
- it 'with case-insensitive pattern' do
218
- dirmon_entry.pattern = 'test/files/**/*.TxT'
219
- files = []
220
- dirmon_entry.each do |file_name|
221
- files << file_name
222
- end
223
- assert_equal 1, files.count
224
- assert_equal Pathname.new('test/files/text.txt').realpath, files.first
225
- end
226
-
227
- it 'reads paths inside of the whitelist' do
228
- dirmon_entry.archive_directory = nil
229
- files = []
230
- dirmon_entry.stub(:whitelist_paths, [Pathname.new('test/files').realpath.to_s]) do
231
- dirmon_entry.each do |file_name|
232
- files << file_name
233
- end
234
- end
235
- assert_nil dirmon_entry.archive_directory
236
- assert_equal 1, files.count
237
- assert_equal Pathname.new('test/files/text.txt').realpath, files.first
238
- end
239
-
240
- it 'skips paths outside of the whitelist' do
241
- dirmon_entry.archive_directory = nil
242
- files = []
243
- dirmon_entry.stub(:whitelist_paths, [Pathname.new('test/config').realpath.to_s]) do
244
- dirmon_entry.each do |file_name|
245
- files << file_name
246
- end
247
- end
248
- assert_nil dirmon_entry.archive_directory
249
- assert_equal 0, files.count
250
- end
251
- end
252
-
253
- describe '#later' do
254
- it 'enqueues job' do
255
- job = dirmon_entry.later(pathname)
256
- assert created_job = RocketJob::Jobs::UploadFileJob.last
257
- assert_equal job.id, created_job.id
258
- assert job.queued?
259
- end
260
-
261
- it 'sets attributes' do
262
- job = dirmon_entry.later(pathname)
263
-
264
- upload_file_name = Pathname.new(archive_directory).join("#{job.job_id}_#{File.basename(file_name)}").realdirpath.to_s
265
-
266
- assert_equal dirmon_entry.job_class_name, job.job_class_name
267
- assert_equal dirmon_entry.properties, job.properties
268
- assert_equal upload_file_name, job.upload_file_name
269
- assert_equal "#{dirmon_entry.name}: #{pathname.basename}", job.description
270
- assert_equal pathname.to_s, job.original_file_name
271
- assert job.job_id
272
- end
273
- end
274
-
275
- describe '#archive_file' do
276
- it 'moves file to archive dir' do
277
- job_id = BSON::ObjectId.new
278
- archive_real_name = archive_path.join("#{job_id}_#{File.basename(file_name)}").to_s
279
-
280
- assert File.exist?(file_name)
281
- assert_equal archive_real_name, dirmon_entry.send(:archive_file, job_id, pathname)
282
- refute File.exist?(file_name)
283
- assert File.exist?(archive_real_name)
284
- end
285
- end
286
-
287
- describe '#archive_pathname' do
288
- it 'with fully qualified archive directory' do
289
- assert_equal archive_path.to_s, dirmon_entry.send(:archive_pathname, pathname).to_s
290
- end
291
-
292
- describe 'with relative' do
293
- let :archive_directory do
294
- 'my_archive/files'
295
- end
296
-
297
- it 'archive directory' do
298
- archive_dir = File.join(pathname.realdirpath.dirname, archive_directory)
299
- assert_equal archive_dir, dirmon_entry.send(:archive_pathname, pathname).to_s
300
- end
301
- end
302
-
303
- it 'has a default archive directory' do
304
- e = RocketJob::DirmonEntry.new(
305
- pattern: 'test/files/**/*',
306
- job_class_name: 'RocketJob::Jobs::DirmonJob'
307
- )
308
- assert_equal 'archive', e.archive_directory
309
- end
310
- end
311
- end
312
- end
313
- end
@@ -1,216 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- # Unit Test for RocketJob::Job
4
- class DirmonJobTest < Minitest::Test
5
- class TestJob < RocketJob::Job
6
- def perform
7
- 3645
8
- end
9
- end
10
-
11
- describe RocketJob::Jobs::DirmonJob do
12
- let :dirmon_job do
13
- RocketJob::Jobs::DirmonJob.new
14
- end
15
-
16
- let :directory do
17
- '/tmp/directory'
18
- end
19
-
20
- let :archive_directory do
21
- '/tmp/archive_directory'
22
- end
23
-
24
- let :dirmon_entry do
25
- RocketJob::DirmonEntry.new(
26
- pattern: "#{directory}/abc/*",
27
- job_class_name: 'DirmonJobTest::TestJob',
28
- properties: {priority: 23},
29
- archive_directory: archive_directory
30
- )
31
- end
32
-
33
- before do
34
- RocketJob::Jobs::DirmonJob.delete_all
35
- FileUtils.makedirs("#{directory}/abc")
36
- end
37
-
38
- after do
39
- FileUtils.remove_dir(archive_directory, true) if Dir.exist?(archive_directory)
40
- FileUtils.remove_dir(directory, true) if Dir.exist?(directory)
41
- end
42
-
43
- describe '#check_file' do
44
- it 'check growing file' do
45
- previous_size = 5
46
- new_size = 10
47
- file = create_temp_file(new_size)
48
- result = dirmon_entry.stub(:later, nil) do
49
- dirmon_job.send(:check_file, dirmon_entry, file, previous_size)
50
- end
51
- assert_equal new_size, result
52
- end
53
-
54
- it 'check completed file' do
55
- previous_size = 10
56
- new_size = 10
57
- file = create_temp_file(new_size)
58
- started = false
59
- result = dirmon_entry.stub(:later, ->(_fn) { started = true }) do
60
- dirmon_job.send(:check_file, dirmon_entry, file, previous_size)
61
- end
62
- assert_nil result
63
- assert started
64
- end
65
-
66
- it 'check deleted file' do
67
- previous_size = 5
68
- file_name = Pathname.new('blah')
69
- assert_raises Errno::ENOENT do
70
- dirmon_job.send(:check_file, dirmon_entry, file_name, previous_size)
71
- end
72
- end
73
- end
74
-
75
- describe '#check_directories' do
76
- before do
77
- RocketJob::DirmonEntry.destroy_all
78
- dirmon_entry.enable!
79
- end
80
-
81
- it 'no files' do
82
- result = dirmon_job.send(:check_directories)
83
- assert_equal 0, result.count
84
- end
85
-
86
- it 'collect new files without enqueuing them' do
87
- create_file("#{directory}/abc/file1", 5)
88
- create_file("#{directory}/abc/file2", 10)
89
-
90
- result = dirmon_job.send(:check_directories)
91
- assert_equal [5, 10], result.values.sort
92
- end
93
-
94
- it 'allow files to grow' do
95
- create_file("#{directory}/abc/file1", 5)
96
- create_file("#{directory}/abc/file2", 10)
97
- dirmon_job.send(:check_directories)
98
- create_file("#{directory}/abc/file1", 10)
99
- create_file("#{directory}/abc/file2", 15)
100
- result = dirmon_job.send(:check_directories)
101
- assert_equal [10, 15], result.values.sort
102
- end
103
-
104
- it 'start all files' do
105
- create_file("#{directory}/abc/file1", 5)
106
- create_file("#{directory}/abc/file2", 10)
107
- files = dirmon_job.send(:check_directories)
108
- assert_equal 2, files.count, files
109
- assert_equal 2, dirmon_job.previous_file_names.count, files
110
-
111
- # files = dirmon_job.send(:check_directories)
112
- # assert_equal 0, files.count, files
113
-
114
- count = 0
115
- result = RocketJob::DirmonEntry.stub_any_instance(:later, ->(_path) { count += 1 }) do
116
- dirmon_job.send(:check_directories)
117
- end
118
- assert_equal 0, result.count, result
119
- assert 2, count
120
- end
121
-
122
- it 'skip files in archive directory' do
123
- dirmon_entry.archive_directory = 'archive'
124
- dirmon_entry.pattern = "#{directory}/abc/**/*"
125
-
126
- file_pathname = Pathname.new("#{directory}/abc/file1")
127
- create_file(file_pathname.to_s, 5)
128
- create_file("#{directory}/abc/file2", 10)
129
-
130
- archive_pathname = dirmon_entry.send(:archive_pathname, file_pathname)
131
- create_file("#{archive_pathname}/file3", 21)
132
-
133
- result = dirmon_job.send(:check_directories)
134
- assert_equal [5, 10], result.values.sort
135
- end
136
- end
137
-
138
- describe '#perform' do
139
- it 'check directories and reschedule' do
140
- previous_file_names = {
141
- "#{directory}/abc/file1" => 5,
142
- "#{directory}/abc/file2" => 10
143
- }
144
- new_file_names = {
145
- "#{directory}/abc/file1" => 10,
146
- "#{directory}/abc/file2" => 10
147
- }
148
- assert_equal 0, RocketJob::Jobs::DirmonJob.count
149
- # perform_now does not save the job, just runs it
150
- dirmon_job = RocketJob::Jobs::DirmonJob.create!(
151
- previous_file_names: previous_file_names,
152
- priority: 11,
153
- check_seconds: 30
154
- )
155
- RocketJob::Jobs::DirmonJob.stub_any_instance(:check_directories, new_file_names) do
156
- dirmon_job.perform_now
157
- end
158
- assert dirmon_job.completed?, dirmon_job.status.inspect
159
- # Job must destroy on complete
160
- assert_equal 0, RocketJob::Jobs::DirmonJob.where(id: dirmon_job.id).count, -> { RocketJob::Jobs::DirmonJob.all.to_a.ai }
161
-
162
- # Must have enqueued another instance to run in the future
163
- assert_equal 1, RocketJob::Jobs::DirmonJob.count
164
- assert new_dirmon_job = RocketJob::Jobs::DirmonJob.last
165
- refute_equal dirmon_job.id.to_s, new_dirmon_job.id.to_s
166
- assert new_dirmon_job.run_at
167
- assert_equal 11, new_dirmon_job.priority
168
- assert_equal 30, new_dirmon_job.check_seconds
169
- assert new_dirmon_job.queued?
170
-
171
- new_dirmon_job.destroy
172
- end
173
-
174
- it 'check directories and reschedule even on exception' do
175
- RocketJob::Jobs::DirmonJob.destroy_all
176
- # perform_now does not save the job, just runs it
177
- dirmon_job = RocketJob::Jobs::DirmonJob.create!(
178
- priority: 11,
179
- check_seconds: 30,
180
- destroy_on_complete: false
181
- )
182
- RocketJob::Jobs::DirmonJob.stub_any_instance(:check_directories, -> { raise 'Oh no' }) do
183
- assert_raises RuntimeError do
184
- dirmon_job.perform_now
185
- end
186
- end
187
- dirmon_job.save!
188
- assert dirmon_job.aborted?, dirmon_job.status.ai
189
- assert_equal 'RuntimeError', dirmon_job.exception.class_name, dirmon_job.exception.attributes
190
- assert_equal 'Oh no', dirmon_job.exception.message, dirmon_job.exception.attributes
191
-
192
- # Must have enqueued another instance to run in the future
193
- assert_equal 2, RocketJob::Jobs::DirmonJob.count, -> { RocketJob::Jobs::DirmonJob.all.ai }
194
- assert new_dirmon_job = RocketJob::Jobs::DirmonJob.queued.first
195
- assert new_dirmon_job.run_at
196
- assert_equal 11, new_dirmon_job.priority, -> { new_dirmon_job.attributes.ai }
197
- assert_equal 30, new_dirmon_job.check_seconds
198
- assert new_dirmon_job.queued?, new_dirmon_job.state
199
-
200
- new_dirmon_job.destroy
201
- end
202
- end
203
-
204
- def create_file(file_name, size)
205
- File.open(file_name, 'wb') { |file| file.write('*' * size) }
206
- end
207
-
208
- def create_temp_file(size)
209
- file = Tempfile.new('check_file')
210
- file_name = file.path
211
- File.open(file_name, 'wb') { |f| f.write('*' * size) }
212
- assert_equal size, File.size(file_name)
213
- file
214
- end
215
- end
216
- end