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,285 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Load/Require operations through VirtFS -" do
4
+ before(:all) do
5
+ @root = VfsRealFile::SEPARATOR
6
+ @mnt = VfsRealDir.mktmpdir
7
+ @top_dir = "Dir1"
8
+
9
+ @rb_file = "hello_world.rb"
10
+ @lib_name = "hello_world"
11
+ @module_name = 'HelloWorld'
12
+
13
+ @rb_code = <<-END_OF_CODE
14
+ module #{@module_name}
15
+ def self.hello
16
+ "Hello World!"
17
+ end
18
+ end
19
+ END_OF_CODE
20
+
21
+ @dir_full_path = VfsRealFile.join(@mnt, @top_dir)
22
+ @file_full_path = VfsRealFile.join(@dir_full_path, @rb_file)
23
+
24
+ reset_context
25
+
26
+ @native_fs1 = nativefs_class.new
27
+ VirtFS.mount(@native_fs1, @root) # mount / on /
28
+ end
29
+
30
+ after(:all) do
31
+ VirtFS.umount(@root) if VirtFS.mounted?(@root)
32
+ VfsRealDir.rmdir(@mnt)
33
+ end
34
+
35
+ before(:each) do
36
+ @tmp_dir = VfsRealDir.mktmpdir # The subdirectory to mount
37
+
38
+ @native_fs2 = nativefs_class.new(@tmp_dir)
39
+ VirtFS.mount(@native_fs2, @mnt) # mount @tmp_dir on @mnt
40
+
41
+ VirtFS::VDir.mkdir(@dir_full_path)
42
+ VirtFS::VFile.open(@file_full_path, "w") do |f|
43
+ f.write(@rb_code)
44
+ end
45
+ end
46
+
47
+ after(:each) do
48
+ VirtFS.umount(@mnt) if VirtFS.mounted?(@mnt)
49
+ FileUtils.remove_dir(@tmp_dir)
50
+ end
51
+
52
+ context "inject" do
53
+ before(:each) do
54
+ VirtFS::Kernel.withdraw
55
+ end
56
+
57
+ context "pre injection" do
58
+ it "virtfs_original_require should be undefined" do
59
+ expect(::Kernel.private_method_defined?(:virtfs_original_require)).to be false
60
+ end
61
+
62
+ it "virtfs_original_load should be undefined" do
63
+ expect(::Kernel.private_method_defined?(:virtfs_original_load)).to be false
64
+ end
65
+
66
+ it "virtfs_require should be undefined" do
67
+ expect(::Kernel.private_method_defined?(:virtfs_require)).to be false
68
+ end
69
+
70
+ it "virtfs_load should be undefined" do
71
+ expect(::Kernel.private_method_defined?(:virtfs_load)).to be false
72
+ end
73
+ end
74
+
75
+ context "post injection" do
76
+ it "virtfs_original_require should be defined" do
77
+ VirtFS::Kernel.inject
78
+ expect(::Kernel.private_method_defined?(:virtfs_original_require)).to be true
79
+ end
80
+
81
+ it "virtfs_original_load should be defined" do
82
+ VirtFS::Kernel.inject
83
+ expect(::Kernel.private_method_defined?(:virtfs_original_load)).to be true
84
+ end
85
+
86
+ it "virtfs_require should be defined" do
87
+ VirtFS::Kernel.inject
88
+ expect(::Kernel.private_method_defined?(:virtfs_require)).to be true
89
+ end
90
+
91
+ it "virtfs_load should be defined" do
92
+ VirtFS::Kernel.inject
93
+ expect(::Kernel.private_method_defined?(:virtfs_load)).to be true
94
+ end
95
+ end
96
+ end
97
+
98
+ context "withdraw" do
99
+ before(:each) do
100
+ VirtFS::Kernel.inject
101
+ end
102
+
103
+ context "pre withdraw" do
104
+ it "virtfs_original_require should be defined" do
105
+ expect(::Kernel.private_method_defined?(:virtfs_original_require)).to be true
106
+ end
107
+
108
+ it "virtfs_original_load should be defined" do
109
+ expect(::Kernel.private_method_defined?(:virtfs_original_load)).to be true
110
+ end
111
+
112
+ it "virtfs_require should be defined" do
113
+ expect(::Kernel.private_method_defined?(:virtfs_require)).to be true
114
+ end
115
+
116
+ it "virtfs_load should be defined" do
117
+ expect(::Kernel.private_method_defined?(:virtfs_load)).to be true
118
+ end
119
+ end
120
+
121
+ context "post withdraw" do
122
+ it "virtfs_original_require should be undefined" do
123
+ VirtFS::Kernel.withdraw
124
+ expect(::Kernel.private_method_defined?(:virtfs_original_require)).to be false
125
+ end
126
+
127
+ it "virtfs_original_load should be undefined" do
128
+ VirtFS::Kernel.withdraw
129
+ expect(::Kernel.private_method_defined?(:virtfs_original_load)).to be false
130
+ end
131
+
132
+ it "virtfs_require should be undefined" do
133
+ VirtFS::Kernel.withdraw
134
+ expect(::Kernel.private_method_defined?(:virtfs_require)).to be false
135
+ end
136
+
137
+ it "virtfs_load should be undefined" do
138
+ VirtFS::Kernel.withdraw
139
+ expect(::Kernel.private_method_defined?(:virtfs_load)).to be false
140
+ end
141
+ end
142
+ end
143
+
144
+ context "Check source file" do
145
+ context "Not Activated" do
146
+ it "Should exist under MetakitFS" do
147
+ expect(VirtFS::VFile.exist?(@file_full_path)).to be true
148
+ end
149
+
150
+ it "Should not be visible outside of VirtFS" do
151
+ expect(VfsRealFile.exist?(@file_full_path)).to be false
152
+ end
153
+
154
+ it "Should be of expected size" do
155
+ expect(VirtFS::VFile.size(@file_full_path)).to eq(@rb_code.length)
156
+ end
157
+
158
+ it "Should contain expected code" do
159
+ expect(VirtFS::VFile.read(@file_full_path)).to eq(@rb_code)
160
+ end
161
+ end
162
+
163
+ context "Activated" do
164
+ it "Should exist under MetakitFS" do
165
+ VirtFS.with do
166
+ expect(File.exist?(@file_full_path)).to be true
167
+ end
168
+ end
169
+
170
+ it "Should be of expected size" do
171
+ VirtFS.with do
172
+ expect(File.size(@file_full_path)).to eq(@rb_code.length)
173
+ end
174
+ end
175
+
176
+ it "Should contain expected code" do
177
+ VirtFS.with do
178
+ expect(File.read(@file_full_path)).to eq(@rb_code)
179
+ end
180
+ end
181
+ end
182
+ end
183
+
184
+ context "load" do
185
+ before(:each) do
186
+ Object.send(:remove_const, @module_name) if Object.const_defined?(@module_name)
187
+ end
188
+
189
+ context "Activated" do
190
+ it "Should return true on successful load" do
191
+ VirtFS::Kernel.inject
192
+ VirtFS.with do
193
+ VirtFS::Kernel.enable # Add option to activate
194
+ expect(load(@file_full_path)).to be true
195
+ VirtFS::Kernel.disable
196
+ end
197
+ end
198
+
199
+ it "Should load code as expected" do
200
+ VirtFS::Kernel.inject
201
+ VirtFS.with do
202
+ VirtFS::Kernel.enable # Add option to activate
203
+ expect(load(@file_full_path)).to be true
204
+ VirtFS::Kernel.disable
205
+ mod = Object.const_get(@module_name)
206
+ expect(mod.hello).to eq("Hello World!")
207
+ end
208
+ end
209
+ end
210
+
211
+ context "Not Activated" do
212
+ it "Should raise LoadError" do
213
+ expect do
214
+ load(@file_full_path)
215
+ end.to raise_error(
216
+ LoadError, /cannot load such file/
217
+ )
218
+ end
219
+ end
220
+ end
221
+
222
+ context "require" do
223
+ before(:each) do
224
+ Object.send(:remove_const, @module_name) if Object.const_defined?(@module_name)
225
+ $LOADED_FEATURES.delete(@file_full_path)
226
+ $LOAD_PATH.delete(@dir_full_path)
227
+ end
228
+
229
+ context "Activated" do
230
+ it "Should raise LoadError when not in $LOAD_PATH" do
231
+ VirtFS.with(true) do
232
+ expect do
233
+ require(@lib_name)
234
+ end.to raise_error(
235
+ LoadError, /cannot load such file/
236
+ )
237
+ end
238
+ end
239
+
240
+ it "Should return true when loaded" do
241
+ $LOAD_PATH << @dir_full_path
242
+ VirtFS.with(true) do
243
+ expect(require(@lib_name)).to be true
244
+ end
245
+ end
246
+
247
+ it "Should return false when already loaded" do
248
+ $LOAD_PATH << @dir_full_path
249
+ VirtFS.with(true) do
250
+ expect(require(@lib_name)).to be true
251
+ expect(require(@lib_name)).to be false
252
+ end
253
+ end
254
+
255
+ it "Should add the lib's canonical name to $LOADED_FEATURES" do
256
+ $LOAD_PATH << @dir_full_path
257
+ VirtFS.with(true) do
258
+ expect(require(@lib_name)).to be true
259
+ expect($LOADED_FEATURES.include?(@file_full_path))
260
+ end
261
+ end
262
+
263
+ it "Should load the code as expected" do
264
+ $LOAD_PATH << @dir_full_path
265
+ VirtFS.with(true) do
266
+ expect(require(@lib_name)).to be true
267
+ expect(Object.const_defined?(@module_name)).to be true
268
+ mod = Object.const_get(@module_name)
269
+ expect(mod.hello).to eq("Hello World!")
270
+ end
271
+ end
272
+ end
273
+
274
+ context "Not Activated" do
275
+ it "Should raise LoadError" do
276
+ $LOAD_PATH << @dir_full_path
277
+ expect do
278
+ require(@lib_name)
279
+ end.to raise_error(
280
+ LoadError, /cannot load such file/
281
+ )
282
+ end
283
+ end
284
+ end
285
+ end
@@ -0,0 +1,186 @@
1
+ require 'spec_helper'
2
+
3
+ describe VirtFS, "mount indirection (#{$fs_interface} interface) -" do
4
+ before(:all) do
5
+ @full_path = File.expand_path(__FILE__)
6
+ @rel_path = File.basename(@full_path)
7
+ @this_dir = File.dirname(@full_path)
8
+ @root = File::SEPARATOR
9
+ end
10
+
11
+ before(:each) do
12
+ reset_context
13
+ end
14
+
15
+ describe ".mount" do
16
+ before(:each) do
17
+ @native_fs = nativefs_class.new
18
+ end
19
+
20
+ context "single filesystem:" do
21
+ it "should raise RuntimeError when an invalid filesystem is provided" do
22
+ expect do
23
+ VirtFS.mount(nil, @root)
24
+ end.to raise_error(
25
+ RuntimeError, "mount: invalid filesystem object #{nil.class.name}"
26
+ )
27
+ end
28
+
29
+ it "should raise Errno::ENOENT when mount point doesn't exist" do
30
+ expect do
31
+ VirtFS.mount(@native_fs, @this_dir)
32
+ end.to raise_error(
33
+ Errno::ENOENT, "No such file or directory - #{@this_dir}"
34
+ )
35
+ end
36
+
37
+ it "should raise RuntimeError when attempting to reuse mount point" do
38
+ expect do
39
+ VirtFS.mount(@native_fs, @root)
40
+ VirtFS.mount(nativefs_class.new, @root)
41
+ end.to raise_error(
42
+ RuntimeError, "mount: mount point #{@root} is busy"
43
+ )
44
+ end
45
+
46
+ it "should raise RuntimeError when attempting to mount a mounted filesystem" do
47
+ expect do
48
+ VirtFS.mount(@native_fs, @root)
49
+ VirtFS.mount(@native_fs, @this_dir)
50
+ end.to raise_error(
51
+ RuntimeError, "mount: filesystem is busy"
52
+ )
53
+ end
54
+
55
+ it "should return nil on successful mount" do
56
+ expect(VirtFS.mount(@native_fs, @root)).to be_nil
57
+ end
58
+ end
59
+
60
+ context "second filesystem:" do
61
+ before(:each) do
62
+ @native_fs2 = nativefs_class.new
63
+ VirtFS.mount(@native_fs, @root)
64
+ end
65
+
66
+ it "should raise RuntimeError when attempting to reuse mount point" do
67
+ expect do
68
+ VirtFS.mount(@native_fs2, @this_dir)
69
+ VirtFS.mount(nativefs_class.new, @this_dir)
70
+ end.to raise_error(
71
+ RuntimeError, "mount: mount point #{@this_dir} is busy"
72
+ )
73
+ end
74
+
75
+ it "should return nil on successful mount" do
76
+ expect(VirtFS.mount(@native_fs2, @this_dir)).to be_nil
77
+ end
78
+ end
79
+ end
80
+
81
+ describe ".umount" do
82
+ before(:each) do
83
+ @native_fs = nativefs_class.new
84
+ end
85
+
86
+ it "should raise RuntimeError when nothing mounted on mount point" do
87
+ VirtFS.mount(@native_fs, @root)
88
+ expect do
89
+ VirtFS.umount(@this_dir)
90
+ end.to raise_error(
91
+ RuntimeError, "umount: nothing mounted on #{@this_dir}"
92
+ )
93
+ end
94
+
95
+ it "should return nil on successful umount" do
96
+ VirtFS.mount(@native_fs, @root)
97
+ expect(VirtFS.umount(@root)).to be_nil
98
+ end
99
+
100
+ it "should enable re-mount" do
101
+ VirtFS.mount(@native_fs, @root)
102
+ VirtFS.umount(@root)
103
+ expect(VirtFS.mount(@native_fs, @root)).to be_nil
104
+ end
105
+ end
106
+
107
+ describe ".path_lookup" do
108
+ context "with no filesystems mounted" do
109
+ it "should raise Errno::ENOENT" do
110
+ expect do
111
+ VirtFS.path_lookup(@full_path)
112
+ end.to raise_error(
113
+ Errno::ENOENT, "No such file or directory - #{@full_path}"
114
+ )
115
+ end
116
+
117
+ it "should raise Errno::ENOENT with original path in message" do
118
+ expect do
119
+ VirtFS.path_lookup(@rel_path)
120
+ end.to raise_error(
121
+ Errno::ENOENT, "No such file or directory - #{@rel_path}"
122
+ )
123
+ end
124
+ end
125
+
126
+ context "with FS mounted on #{@root}" do
127
+ before(:each) do
128
+ @native_fs = nativefs_class.new
129
+ VirtFS.mount(@native_fs, @root)
130
+ end
131
+
132
+ it "should return native_fs, when given fully qualified path" do
133
+ fs, _path = VirtFS.path_lookup(@full_path)
134
+ expect(fs).to eq(@native_fs)
135
+ end
136
+
137
+ it "should return the full path, when given fully qualified path" do
138
+ _fs, path = VirtFS.path_lookup(@full_path)
139
+ expect(path).to eq(@full_path) # .sub(@native_fs.mount_point, '')
140
+ end
141
+
142
+ it "should return native_fs, when given relative path" do
143
+ VirtFS.dir_chdir(@this_dir)
144
+ fs, _path = VirtFS.path_lookup(@rel_path)
145
+ expect(fs).to eq(@native_fs)
146
+ end
147
+
148
+ it "should return the full path, when given relative path" do
149
+ VirtFS.dir_chdir(@this_dir)
150
+ _fs, path = VirtFS.path_lookup(@rel_path)
151
+ expect(path).to eq(@full_path) # .sub(@native_fs.mount_point, '')
152
+ end
153
+ end
154
+
155
+ context "with FS mounted on #{@this_dir}" do
156
+ before(:each) do
157
+ @native_fs = nativefs_class.new
158
+ @native_fs2 = nativefs_class.new
159
+ VirtFS.mount(@native_fs, @root)
160
+ VirtFS.mount(@native_fs2, @this_dir)
161
+ end
162
+
163
+ it "should return native_fs2, when given fully qualified path" do
164
+ fs, _path = VirtFS.path_lookup(@full_path)
165
+ expect(fs).to eq(@native_fs2)
166
+ end
167
+
168
+ it "should return the path relative to the mount point, when given fully qualified path" do
169
+ _fs, path = VirtFS.path_lookup(@full_path)
170
+ expect(path).to eq(@full_path.sub(@native_fs2.mount_point, File::SEPARATOR))
171
+ end
172
+
173
+ it "should return native_fs2, when given relative path" do
174
+ VirtFS.dir_chdir(@this_dir)
175
+ fs, _path = VirtFS.path_lookup(@rel_path)
176
+ expect(fs).to eq(@native_fs2)
177
+ end
178
+
179
+ it "should return the path relative to the mount point, when given relative path" do
180
+ VirtFS.dir_chdir(@this_dir)
181
+ _fs, path = VirtFS.path_lookup(@rel_path)
182
+ expect(path).to eq(@full_path.sub(@native_fs2.mount_point, File::SEPARATOR))
183
+ end
184
+ end
185
+ end
186
+ end