virtfs 0.0.1

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 (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +154 -0
  8. data/Rakefile +5 -0
  9. data/lib/virtfs-nativefs-thick.rb +1 -0
  10. data/lib/virtfs-nativefs-thin.rb +1 -0
  11. data/lib/virtfs.rb +38 -0
  12. data/lib/virtfs/activation.rb +97 -0
  13. data/lib/virtfs/block_io.rb +140 -0
  14. data/lib/virtfs/byte_range.rb +71 -0
  15. data/lib/virtfs/context.rb +300 -0
  16. data/lib/virtfs/context_manager.rb +175 -0
  17. data/lib/virtfs/context_switch_class_methods.rb +96 -0
  18. data/lib/virtfs/delegate_module.rb +40 -0
  19. data/lib/virtfs/dir_instance_delegate.rb +3 -0
  20. data/lib/virtfs/exception.rb +13 -0
  21. data/lib/virtfs/file_instance_delegate.rb +3 -0
  22. data/lib/virtfs/file_modes_and_options.rb +293 -0
  23. data/lib/virtfs/find_class_methods.rb +106 -0
  24. data/lib/virtfs/io_buffer.rb +133 -0
  25. data/lib/virtfs/io_instance_delegate.rb +3 -0
  26. data/lib/virtfs/kernel.rb +146 -0
  27. data/lib/virtfs/nativefs/thick.rb +30 -0
  28. data/lib/virtfs/nativefs/thick/dir_class_methods.rb +38 -0
  29. data/lib/virtfs/nativefs/thick/file_class_methods.rb +178 -0
  30. data/lib/virtfs/nativefs/thin.rb +32 -0
  31. data/lib/virtfs/nativefs/thin/dir.rb +30 -0
  32. data/lib/virtfs/nativefs/thin/dir_class_methods.rb +41 -0
  33. data/lib/virtfs/nativefs/thin/file.rb +112 -0
  34. data/lib/virtfs/nativefs/thin/file_class_methods.rb +181 -0
  35. data/lib/virtfs/protofs/protofs.rb +7 -0
  36. data/lib/virtfs/protofs/protofs_base.rb +12 -0
  37. data/lib/virtfs/protofs/protofs_dir.rb +13 -0
  38. data/lib/virtfs/protofs/protofs_dir_class.rb +31 -0
  39. data/lib/virtfs/protofs/protofs_file.rb +27 -0
  40. data/lib/virtfs/protofs/protofs_file_class.rb +136 -0
  41. data/lib/virtfs/stat.rb +100 -0
  42. data/lib/virtfs/thin_dir_delegator.rb +79 -0
  43. data/lib/virtfs/thin_file_delegator.rb +77 -0
  44. data/lib/virtfs/thin_io_delegator_methods.rb +301 -0
  45. data/lib/virtfs/thin_io_delegator_methods_bufferio.rb +337 -0
  46. data/lib/virtfs/v_dir.rb +238 -0
  47. data/lib/virtfs/v_file.rb +480 -0
  48. data/lib/virtfs/v_io.rb +243 -0
  49. data/lib/virtfs/v_pathname.rb +128 -0
  50. data/lib/virtfs/version.rb +3 -0
  51. data/spec/activate_spec.rb +202 -0
  52. data/spec/chroot_spec.rb +120 -0
  53. data/spec/context_manager_class_spec.rb +246 -0
  54. data/spec/context_manager_instance_spec.rb +255 -0
  55. data/spec/context_spec.rb +335 -0
  56. data/spec/data/UTF-16LE-data.txt +0 -0
  57. data/spec/data/UTF-8-data.txt +212 -0
  58. data/spec/dir_class_spec.rb +506 -0
  59. data/spec/dir_instance_spec.rb +208 -0
  60. data/spec/file_class_spec.rb +2106 -0
  61. data/spec/file_instance_spec.rb +154 -0
  62. data/spec/file_modes_and_options_spec.rb +1556 -0
  63. data/spec/find_spec.rb +142 -0
  64. data/spec/io_bufferio_size_shared_examples.rb +371 -0
  65. data/spec/io_bufferio_size_spec.rb +861 -0
  66. data/spec/io_bufferio_spec.rb +801 -0
  67. data/spec/io_class_spec.rb +145 -0
  68. data/spec/io_instance_spec.rb +516 -0
  69. data/spec/kernel_spec.rb +285 -0
  70. data/spec/mount_spec.rb +186 -0
  71. data/spec/nativefs_local_root_spec.rb +132 -0
  72. data/spec/path_spec.rb +39 -0
  73. data/spec/spec_helper.rb +126 -0
  74. data/tasks/rspec.rake +3 -0
  75. data/tasks/yard.rake +7 -0
  76. data/test/UTF-8-demo.txt +212 -0
  77. data/test/bench.rb +18 -0
  78. data/test/bio_internal_test.rb +45 -0
  79. data/test/delegate_io.rb +31 -0
  80. data/test/delegate_module.rb +62 -0
  81. data/test/encode_test.rb +42 -0
  82. data/test/enoent_test.rb +30 -0
  83. data/test/namespace_test.rb +42 -0
  84. data/test/read_block_valid_encoding.rb +44 -0
  85. data/test/read_test.rb +78 -0
  86. data/test/stream_readers.rb +46 -0
  87. data/test/utf-16-demo.txt +0 -0
  88. data/test/utf8_to_utf16.rb +77 -0
  89. data/test/wrapper_test.rb +34 -0
  90. data/virtfs.gemspec +29 -0
  91. metadata +230 -0
@@ -0,0 +1,145 @@
1
+ require 'spec_helper'
2
+
3
+ describe VirtFS::VIO, "(#{$fs_interface} interface)" do
4
+ before(:all) do
5
+ @temp_file = Tempfile.new("VirtFS-IO")
6
+ @temp_file.write(@start_marker)
7
+ (0..9).each do
8
+ @temp_file.write(@data1)
9
+ @temp_file.write(@data2)
10
+ end
11
+ @temp_file.write(@end_marker)
12
+ @temp_file.close
13
+
14
+ @full_path = @temp_file.path
15
+
16
+ @temp_write = Tempfile.new("VirtFS-IO")
17
+ @temp_write.close
18
+ @write_file_path = @temp_write.path
19
+ end
20
+
21
+ before(:each) do
22
+ reset_context
23
+
24
+ @root = File::SEPARATOR
25
+ @native_fs = nativefs_class.new
26
+ VirtFS.mount(@native_fs, @root)
27
+
28
+ @vfile_read_obj = VirtFS::VFile.new(@full_path, "r")
29
+ @vfile_write_obj = VirtFS::VFile.new(@write_file_path, "w")
30
+ end
31
+
32
+ after(:each) do
33
+ VirtFS.umount(@root)
34
+ end
35
+
36
+ describe ".binread" do
37
+ it "should return the same data as IO.binread - whole file" do
38
+ expect(VirtFS::VIO.binread(@full_path)).to eq(VfsRealIO.binread(@full_path))
39
+ end
40
+
41
+ it "should return the same data as IO.binread - given length" do
42
+ length = 30
43
+ expect(VirtFS::VIO.binread(@full_path, length)).to eq(VfsRealIO.binread(@full_path, length))
44
+ end
45
+
46
+ it "should return the same data as IO.binread - given length and offset" do
47
+ length = 30
48
+ offset = 20
49
+ expect(VirtFS::VIO.binread(@full_path, length, offset)).to eq(VfsRealIO.binread(@full_path, length, offset))
50
+ end
51
+ end
52
+
53
+ describe ".copy_stream" do
54
+ it "should return the number of bytes copied" do
55
+ expect(VirtFS::VIO.copy_stream(@vfile_read_obj, @vfile_write_obj)).to eq(@vfile_read_obj.size)
56
+ end
57
+
58
+ it "should create a file of the same size" do
59
+ VirtFS::VIO.copy_stream(@vfile_read_obj, @vfile_write_obj)
60
+ expect(@vfile_write_obj.size).to eq(@vfile_read_obj.size)
61
+ end
62
+
63
+ it "should create a file with the same contents" do
64
+ VirtFS::VIO.copy_stream(@vfile_read_obj, @vfile_write_obj)
65
+ @vfile_read_obj.rewind
66
+ @vfile_write_obj.reopen(@write_file_path, "r")
67
+ expect(@vfile_write_obj.read).to eq(@vfile_read_obj.read)
68
+ end
69
+ end
70
+
71
+ describe ".foreach" do
72
+ it "should return an enum when no block is given" do
73
+ expect(VirtFS::VIO.foreach(@full_path)).to be_kind_of(Enumerator)
74
+ end
75
+
76
+ it "should return the nil object when block is given" do
77
+ expect(VirtFS::VIO.foreach(@full_path) { true }).to be_nil
78
+ end
79
+
80
+ it "should enumerate the same lines as the standard IO.foreach" do
81
+ expect(VirtFS::VIO.foreach(@full_path).to_a).to match_array(VfsRealIO.foreach(@full_path).to_a)
82
+ end
83
+ end
84
+
85
+ describe ".new" do
86
+ it "should do something"
87
+ end
88
+
89
+ describe ".open" do
90
+ it "should do something"
91
+ end
92
+
93
+ describe ".pipe" do
94
+ it "should do something"
95
+ end
96
+
97
+ describe ".popen" do
98
+ it "should do something"
99
+ end
100
+
101
+ describe ".read" do
102
+ it "should return the same data as IO.read - whole file" do
103
+ expect(VirtFS::VIO.read(@full_path)).to eq(VfsRealIO.read(@full_path))
104
+ end
105
+
106
+ it "should return the same data as IO.read - given length" do
107
+ length = 30
108
+ expect(VirtFS::VIO.read(@full_path, length)).to eq(VfsRealIO.read(@full_path, length))
109
+ end
110
+
111
+ it "should return the same data as IO.read - given length and offset" do
112
+ length = 30
113
+ offset = 20
114
+ expect(VirtFS::VIO.read(@full_path, length, offset)).to eq(VfsRealIO.read(@full_path, length, offset))
115
+ end
116
+ end
117
+
118
+ describe ".readlines" do
119
+ it "should return an Array" do
120
+ expect(VirtFS::VIO.readlines(@full_path)).to be_kind_of(Array)
121
+ end
122
+
123
+ it "should return the same lines as the standard IO.readlines" do
124
+ expect(VirtFS::VIO.readlines(@full_path)).to match_array(VfsRealIO.readlines(@full_path))
125
+ end
126
+ end
127
+
128
+ describe ".select" do
129
+ it "should do something"
130
+ end
131
+
132
+ describe ".sysopen" do
133
+ it "should do something"
134
+ end
135
+
136
+ describe ".try_convert" do
137
+ it "should return nil when not passed an IO object" do
138
+ expect(VirtFS::VIO.try_convert("this is a string")).to be_nil
139
+ end
140
+
141
+ it "should return the IO object when passed an IO object" do
142
+ expect(VirtFS::VIO.try_convert(@vfile_read_obj)).to eq(@vfile_read_obj)
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,516 @@
1
+ require 'spec_helper'
2
+ require 'fcntl'
3
+
4
+ describe VirtFS::VIO, "(#{$fs_interface} interface)" do
5
+ before(:all) do
6
+ @start_marker = "START OF FILE:\n"
7
+ @end_marker = ":END OF FILE"
8
+ @data1 = "0123456789"
9
+ @data2 = "abcdefghijklmnopqrstuvwzyz\n"
10
+
11
+ @temp_file = Tempfile.new("VirtFS-IO")
12
+ @temp_file.write(@start_marker)
13
+ (0..9).each do
14
+ @temp_file.write(@data1)
15
+ @temp_file.write(@data2)
16
+ end
17
+ @temp_file.write(@end_marker)
18
+ @temp_file.close
19
+
20
+ @full_path = @temp_file.path
21
+ @file_size = VfsRealFile.size(@full_path)
22
+
23
+ @temp_write = Tempfile.new("VirtFS-IO")
24
+ @temp_write.close
25
+ @write_file_path = @temp_write.path
26
+
27
+ @temp_rdwr = Tempfile.new("VirtFS-IO")
28
+ @temp_rdwr.close
29
+ @rdwr_file_path = @temp_rdwr.path
30
+
31
+ @binary_encoding = Encoding.find("ASCII-8BIT")
32
+ end
33
+
34
+ before(:each) do
35
+ reset_context
36
+
37
+ @root = File::SEPARATOR
38
+ @native_fs = nativefs_class.new
39
+ VirtFS.mount(@native_fs, @root)
40
+
41
+ @vfile_read_obj = VirtFS::VFile.new(@full_path, "r")
42
+ @vfile_write_obj = VirtFS::VFile.new(@write_file_path, "w")
43
+ @vfile_rdwr_obj = VirtFS::VFile.new(@rdwr_file_path, "w+")
44
+ end
45
+
46
+ after(:each) do
47
+ @vfile_read_obj.close unless @vfile_read_obj.closed?
48
+ @vfile_write_obj.close unless @vfile_write_obj.closed?
49
+ @vfile_rdwr_obj.close unless @vfile_rdwr_obj.closed?
50
+ VirtFS.umount(@root)
51
+ end
52
+
53
+ describe "#autoclose=" do
54
+ it "should change the value from true to false" do
55
+ expect(@vfile_read_obj.autoclose?).to be true
56
+ @vfile_read_obj.autoclose = false
57
+ expect(@vfile_read_obj.autoclose?).to be false
58
+ end
59
+
60
+ it "should change the value from true to false - given a 'falsey' value" do
61
+ expect(@vfile_read_obj.autoclose?).to be true
62
+ @vfile_read_obj.autoclose = nil
63
+ expect(@vfile_read_obj.autoclose?).to be false
64
+ end
65
+
66
+ it "should change the value from false to true" do
67
+ @vfile_read_obj.autoclose = false
68
+ expect(@vfile_read_obj.autoclose?).to be false
69
+ @vfile_read_obj.autoclose = true
70
+ expect(@vfile_read_obj.autoclose?).to be true
71
+ end
72
+
73
+ it "should change the value from false to true - given a 'truthy' value" do
74
+ @vfile_read_obj.autoclose = false
75
+ expect(@vfile_read_obj.autoclose?).to be false
76
+ @vfile_read_obj.autoclose = "???"
77
+ expect(@vfile_read_obj.autoclose?).to be true
78
+ end
79
+ end
80
+
81
+ describe "#autoclose?" do
82
+ it "should return the default value of true" do
83
+ expect(@vfile_read_obj.autoclose?).to be true
84
+ end
85
+ end
86
+
87
+ describe "#binmode" do
88
+ it "should return the IO object" do
89
+ expect(@vfile_read_obj.binmode).to eq(@vfile_read_obj)
90
+ end
91
+
92
+ it "should set binmode to true" do
93
+ expect(@vfile_read_obj.binmode?).to be false
94
+ @vfile_read_obj.binmode
95
+ expect(@vfile_read_obj.binmode?).to be true
96
+ end
97
+
98
+ it "should set the external_encoding to binary encoding" do
99
+ expect(@vfile_read_obj.external_encoding).to_not eq(@binary_encoding)
100
+ @vfile_read_obj.binmode
101
+ expect(@vfile_read_obj.external_encoding).to eq(@binary_encoding)
102
+ end
103
+
104
+ it "should set the internal_encoding to nil" do
105
+ # XXX Real File does not seem to change the internal encoding.
106
+ # @vfile_read_obj.set_encoding(":UTF-8")
107
+ # expect(@vfile_read_obj.internal_encoding).to_not be_nil
108
+ @vfile_read_obj.binmode
109
+ expect(@vfile_read_obj.internal_encoding).to be_nil
110
+ end
111
+ end
112
+
113
+ describe "#binmode?" do
114
+ it "should return false by default" do
115
+ expect(@vfile_read_obj.binmode?).to be false
116
+ end
117
+
118
+ it "should return true when in binmode" do
119
+ expect(@vfile_read_obj.binmode?).to be false
120
+ @vfile_read_obj.binmode
121
+ expect(@vfile_read_obj.binmode?).to be true
122
+ end
123
+ end
124
+
125
+ describe "#close" do
126
+ it "should return nil" do
127
+ expect(@vfile_read_obj.close).to be_nil
128
+ end
129
+
130
+ context "should cause subsequent operations to raise IOError" do
131
+ {
132
+ :<< => ["hello"],
133
+ :autoclose= => [true],
134
+ :autoclose? => [],
135
+ :binmode => [],
136
+ :binmode? => [],
137
+ :close => [],
138
+ :close_on_exec? => [],
139
+ :close_on_exec= => [true],
140
+ :close_read => [],
141
+ :close_write => [],
142
+ :each => [],
143
+ :each_byte => [],
144
+ :each_char => [],
145
+ :each_codepoint => [],
146
+ :eof => [],
147
+ :external_encoding => [],
148
+ :fcntl => [0, 1],
149
+ :fdatasync => [],
150
+ :fileno => [],
151
+ :flush => [],
152
+ :fsync => [],
153
+ :getbyte => [],
154
+ :getc => [],
155
+ :gets => [],
156
+ :internal_encoding => [],
157
+ :ioctl => [0, 1],
158
+ :isatty => [],
159
+ :lineno => [],
160
+ :lineno= => [10],
161
+ :pid => [],
162
+ :pos => [],
163
+ :pos= => [0],
164
+ :print => ["string"],
165
+ :printf => ["format"],
166
+ :putc => ["X"],
167
+ :puts => ["string"],
168
+ :read => [10],
169
+ :readbyte => [],
170
+ :readchar => [],
171
+ :readline => [],
172
+ :readlines => [],
173
+ :readpartial => [10],
174
+ :rewind => [],
175
+ :seek => [0],
176
+ :set_encoding => ["encoding"],
177
+ :stat => [],
178
+ :sync => [],
179
+ :sync= => [true],
180
+ :sysread => [10],
181
+ :sysseek => [0],
182
+ :syswrite => ["hello"],
183
+ :ungetbyte => ["x"],
184
+ :ungetc => ["X"],
185
+ :write => ["string"],
186
+ :write_nonblock => ["hello"],
187
+ }.each do |method, args|
188
+ it "should cause subsequent '#{method}' call to raise IOError" do
189
+ @vfile_read_obj.close
190
+ expect { @vfile_read_obj.send(method, *args) {} }.to raise_error(IOError, "closed stream")
191
+ end
192
+ end
193
+ end
194
+ end
195
+
196
+ describe "#close_on_exec?" do
197
+ it "should return true by default" do
198
+ expect(@vfile_read_obj.close_on_exec?).to be true
199
+ end
200
+
201
+ it "should return false when set to false" do
202
+ @vfile_read_obj.close_on_exec = false
203
+ expect(@vfile_read_obj.close_on_exec?).to be false
204
+ end
205
+ end
206
+
207
+ describe "#close_on_exec=" do
208
+ it "should change the close_on_exec setting" do
209
+ coe = @vfile_read_obj.close_on_exec?
210
+ @vfile_read_obj.close_on_exec = !coe
211
+ expect(@vfile_read_obj.close_on_exec?).to be !coe
212
+ end
213
+ end
214
+
215
+ describe "#close_read" do
216
+ it "should raise IOError when called on a closed file" do
217
+ @vfile_read_obj.close
218
+ expect do
219
+ @vfile_read_obj.close_read
220
+ end.to raise_error(IOError, "closed stream")
221
+ end
222
+
223
+ it "should raise IOError when called on a regular file opend rdwr" do
224
+ expect do
225
+ @vfile_rdwr_obj.close_read
226
+ end.to raise_error(IOError, "closing non-duplex IO for reading")
227
+ end
228
+
229
+ it "should raise IOError when called on a file not open for reading" do
230
+ expect do
231
+ @vfile_write_obj.close_read
232
+ end.to raise_error(IOError, "closing non-duplex IO for reading")
233
+ end
234
+
235
+ it "should close a file that's only open for reading" do
236
+ expect(@vfile_read_obj.close_read).to be nil
237
+ expect(@vfile_read_obj.closed?).to be true
238
+ end
239
+ end
240
+
241
+ describe "#close_write" do
242
+ it "should raise IOError when called on a closed file" do
243
+ @vfile_read_obj.close
244
+ expect do
245
+ @vfile_read_obj.close_write
246
+ end.to raise_error(IOError, "closed stream")
247
+ end
248
+
249
+ it "should raise IOError when called on a regular file opend rdwr" do
250
+ expect do
251
+ @vfile_rdwr_obj.close_write
252
+ end.to raise_error(IOError, "closing non-duplex IO for writing")
253
+ end
254
+
255
+ it "should raise IOError when called on a file not open for writing" do
256
+ expect do
257
+ @vfile_read_obj.close_write
258
+ end.to raise_error(IOError, "closing non-duplex IO for writing")
259
+ end
260
+
261
+ it "should close a file that's only open for writing" do
262
+ expect(@vfile_write_obj.close_write).to be nil
263
+ expect(@vfile_write_obj.closed?).to be true
264
+ end
265
+ end
266
+
267
+ describe "#closed?" do
268
+ it "should return false if the file is open" do
269
+ expect(@vfile_read_obj.closed?).to be false
270
+ end
271
+
272
+ it "should return true if the file is closed" do
273
+ @vfile_read_obj.close
274
+ expect(@vfile_read_obj.closed?).to be true
275
+ end
276
+ end
277
+
278
+ describe "#fcntl" do
279
+ it "should return the requested value" do
280
+ expect(@vfile_read_obj.fcntl(Fcntl::F_GETFD, nil)).to be_kind_of(Integer)
281
+ end
282
+ end
283
+
284
+ describe "#fileno" do
285
+ it "should return the integer file number" do
286
+ expect(@vfile_read_obj.fileno).to be_kind_of(Integer)
287
+ end
288
+ end
289
+
290
+ describe "#ioctl" do
291
+ it "should do something"
292
+ end
293
+
294
+ describe "#isatty" do
295
+ it "should return false for a regular file" do
296
+ expect(@vfile_read_obj.isatty).to be false
297
+ end
298
+ end
299
+
300
+ describe "#pid" do
301
+ it "should return nil for a regular file" do
302
+ expect(@vfile_read_obj.pid).to be nil
303
+ end
304
+ end
305
+
306
+ describe "#reopen" do
307
+ it "should return the IO object" do
308
+ expect(@vfile_read_obj.reopen(@vfile_write_obj)).to eq(@vfile_read_obj)
309
+ end
310
+
311
+ it "should take on the attributes of the new IO stream - given IO object" do
312
+ expect(@vfile_read_obj.path).to_not eq(@vfile_write_obj.path)
313
+ expect(@vfile_read_obj.size).to_not eq(@vfile_write_obj.size)
314
+
315
+ @vfile_read_obj.reopen(@vfile_write_obj)
316
+
317
+ expect(@vfile_read_obj.path).to eq(@vfile_write_obj.path)
318
+ expect(@vfile_read_obj.size).to eq(@vfile_write_obj.size)
319
+ end
320
+
321
+ it "should take on the attributes of the new IO stream - given open args" do
322
+ expect(@vfile_read_obj.path).to_not eq(@vfile_write_obj.path)
323
+ expect(@vfile_read_obj.size).to_not eq(@vfile_write_obj.size)
324
+
325
+ @vfile_read_obj.reopen(@write_file_path, "w")
326
+
327
+ expect(@vfile_read_obj.path).to eq(@vfile_write_obj.path)
328
+ expect(@vfile_read_obj.size).to eq(@vfile_write_obj.size)
329
+ end
330
+
331
+ it "should read the same data as the standard File#read - given IO object" do
332
+ rfile_obj = VfsRealFile.new(@full_path, "r")
333
+ @vfile_write_obj.reopen(@vfile_read_obj)
334
+
335
+ read_size = 20
336
+ loop do
337
+ rv1 = @vfile_write_obj.read(read_size)
338
+ rv2 = rfile_obj.read(read_size)
339
+ expect(rv1).to eq(rv2)
340
+ break if rv1.nil? || rv1.empty?
341
+ end
342
+ end
343
+
344
+ it "should read the same data as the standard File#read - given open args" do
345
+ rfile_obj = VfsRealFile.new(@full_path, "r")
346
+ @vfile_write_obj.reopen(@full_path, "r")
347
+
348
+ read_size = 20
349
+ loop do
350
+ rv1 = @vfile_write_obj.read(read_size)
351
+ rv2 = rfile_obj.read(read_size)
352
+ expect(rv1).to eq(rv2)
353
+ break if rv1.nil? || rv1.empty?
354
+ end
355
+ end
356
+ end
357
+
358
+ describe "#stat" do
359
+ it "should return the stat information for the regular file" do
360
+ expect(@vfile_write_obj.stat.symlink?).to be false
361
+ end
362
+ end
363
+
364
+ describe "#sysread" do
365
+ before(:each) do
366
+ @rfile_obj = VfsRealFile.new(@full_path, "r")
367
+ end
368
+
369
+ after(:each) do
370
+ @rfile_obj.close
371
+ end
372
+
373
+ it "should read the number of bytes requested - when EOF not reached" do
374
+ read_size = @file_size / 2
375
+ rv = @vfile_read_obj.sysread(read_size)
376
+ expect(rv.bytesize).to eq(read_size)
377
+ end
378
+
379
+ it "should read data into buffer, when supplied" do
380
+ read_size = @file_size / 2
381
+ rbuf = ""
382
+ rv = @vfile_read_obj.sysread(read_size, rbuf)
383
+ expect(rv).to eq(rbuf)
384
+ end
385
+
386
+ it "should read at most, the size of the file" do
387
+ rv = @vfile_read_obj.sysread(@file_size + 100)
388
+ expect(rv.bytesize).to eq(@file_size)
389
+ end
390
+
391
+ it "should raise EOFError when attempting to read at EOF" do
392
+ @vfile_read_obj.sysread(@file_size)
393
+ expect do
394
+ @vfile_read_obj.sysread(@file_size)
395
+ end.to raise_error(
396
+ EOFError, "end of file reached"
397
+ )
398
+ end
399
+
400
+ it "should read the same data as the standard File#sysread" do
401
+ read_size = 20
402
+ loop do
403
+ begin
404
+ rv1 = @vfile_read_obj.sysread(read_size)
405
+ rv2 = @rfile_obj.sysread(read_size)
406
+ rescue EOFError
407
+ break
408
+ end
409
+ expect(rv1).to eq(rv2)
410
+ end
411
+ end
412
+ end
413
+
414
+ describe "#sysseek" do
415
+ it "should raise Errno::EINVAL when attempting to seek before the beginning of the file" do
416
+ expect do
417
+ @vfile_read_obj.sysseek(-10, IO::SEEK_CUR)
418
+ end.to raise_error(
419
+ Errno::EINVAL, /Invalid argument/
420
+ )
421
+ end
422
+
423
+ it "should return the new offset into the file - IO::SEEK_SET" do
424
+ offset = @file_size / 2
425
+ pos = @vfile_read_obj.sysseek(offset, IO::SEEK_SET)
426
+ expect(pos).to eq(offset)
427
+ end
428
+
429
+ it "should return the new offset into the file - IO::SEEK_CUR" do
430
+ offset = @file_size / 2
431
+ @vfile_read_obj.sysseek(offset, IO::SEEK_SET)
432
+ pos = @vfile_read_obj.sysseek(-10, IO::SEEK_CUR)
433
+ expect(pos).to eq(offset - 10)
434
+ end
435
+
436
+ it "should return the new offset into the file - IO::SEEK_END" do
437
+ pos = @vfile_read_obj.sysseek(-10, IO::SEEK_END)
438
+ expect(pos).to eq(@file_size - 10)
439
+ end
440
+
441
+ it "should change the read position within the file - IO::SEEK_SET" do
442
+ @vfile_read_obj.sysseek(@start_marker.bytesize, IO::SEEK_SET)
443
+ rv = @vfile_read_obj.sysread(@data1.bytesize)
444
+ expect(rv).to eq(@data1)
445
+ end
446
+
447
+ it "should change the read position within the file - IO::SEEK_CUR" do
448
+ @vfile_read_obj.sysseek(@start_marker.bytesize, IO::SEEK_SET)
449
+ @vfile_read_obj.sysseek(@data1.bytesize, IO::SEEK_CUR)
450
+ rv = @vfile_read_obj.sysread(@data2.bytesize)
451
+ expect(rv).to eq(@data2)
452
+ end
453
+
454
+ it "should change the read position within the file - IO::SEEK_END" do
455
+ @vfile_read_obj.sysseek(-@end_marker.bytesize, IO::SEEK_END)
456
+ rv = @vfile_read_obj.sysread(@end_marker.bytesize)
457
+ expect(rv).to eq(@end_marker)
458
+ end
459
+ end
460
+
461
+ describe "#syswrite" do
462
+ it "should return the number of bytes written" do
463
+ write_str = "0123456789"
464
+ expect(@vfile_write_obj.syswrite(write_str)).to eq(write_str.bytesize)
465
+ end
466
+
467
+ it "should update the current file position" do
468
+ write_str = "0123456789"
469
+ last_pos = @vfile_write_obj.pos
470
+ (0..9).each do
471
+ @vfile_write_obj.syswrite(write_str)
472
+ pos = @vfile_write_obj.pos
473
+ expect(pos).to eq(last_pos + write_str.bytesize)
474
+ last_pos = pos
475
+ end
476
+ end
477
+
478
+ it "should update the size of the file" do
479
+ write_str = "0123456789"
480
+ last_size = @vfile_write_obj.size
481
+ (0..9).each do
482
+ @vfile_write_obj.syswrite(write_str)
483
+ size = @vfile_write_obj.size
484
+ expect(size).to eq(last_size + write_str.bytesize)
485
+ last_size = size
486
+ end
487
+ end
488
+
489
+ it "should write data that's readable" do
490
+ write_str = "0123456789"
491
+ (0..9).each do
492
+ @vfile_write_obj.syswrite(write_str)
493
+ end
494
+
495
+ @vfile_write_obj.close
496
+ @vfile_write_obj = VirtFS::VFile.new(@write_file_path, "r")
497
+
498
+ (0..9).each do
499
+ expect(@vfile_write_obj.sysread(write_str.bytesize)).to eq(write_str)
500
+ end
501
+
502
+ expect do
503
+ @vfile_write_obj.sysread(write_str.bytesize)
504
+ end.to raise_error(
505
+ EOFError, "end of file reached"
506
+ )
507
+ end
508
+ end
509
+
510
+ describe "#to_io" do
511
+ it "should return itself" do
512
+ @vfile_read_obj = VirtFS::VFile.new(@full_path, "r")
513
+ expect(@vfile_read_obj.to_io).to eq(@vfile_read_obj)
514
+ end
515
+ end
516
+ end