virtfs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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