rfusefs 0.8.0 → 1.0.0.RC0

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.
@@ -0,0 +1,295 @@
1
+ require 'spec_helper'
2
+ require 'tmpdir'
3
+
4
+ describe FuseFS::MetaDir do
5
+
6
+ context "in ruby" do
7
+
8
+ before(:each) do
9
+ @metadir = FuseFS::MetaDir.new()
10
+ @metadir.mkdir("/test")
11
+ @metadir.mkdir("/test/hello")
12
+ @metadir.mkdir("/test/hello/emptydir")
13
+ @metadir.write_to("/test/hello/hello.txt","Hello World!\n")
14
+ end
15
+
16
+ context "general directory methods" do
17
+ it "should list directory contents" do
18
+ @metadir.contents("/").should =~ [ "test" ]
19
+ @metadir.contents("/test").should =~ [ "hello" ]
20
+ @metadir.contents("/test/hello").should =~ ["hello.txt", "emptydir" ]
21
+ end
22
+
23
+ it "should indicate paths which are/are not directories" do
24
+ @metadir.directory?("/test").should be_true
25
+ @metadir.directory?("/test/hello").should be_true
26
+ @metadir.directory?("/test/hello/hello.txt").should be_false
27
+ @metadir.directory?("/nodir").should be_false
28
+ @metadir.directory?("/test/nodir").should be_false
29
+ end
30
+
31
+ it "should indicate paths which are/are not files" do
32
+ @metadir.file?("/test").should be_false
33
+ @metadir.file?("/test/nodir").should be_false
34
+ @metadir.file?("/test/hello").should be_false
35
+ @metadir.file?("/test/hello/hello.txt").should be_true
36
+ end
37
+
38
+ it "should indicate the size of a file" do
39
+ @metadir.size("/test/hello/hello.txt").should be "Hello World!\n".length
40
+ end
41
+ end
42
+
43
+ context "with write access" do
44
+
45
+ around(:each) do |example|
46
+ FuseFS::RFuseFS.context(fuse_context(),&example)
47
+ end
48
+
49
+ before(:each) do
50
+ FuseFS::reader_uid.should == Process.uid
51
+ FuseFS::reader_gid.should == Process.gid
52
+ end
53
+
54
+
55
+ it "should allow directory creation" do
56
+ @metadir.can_mkdir?("/test/otherdir").should be_true
57
+ end
58
+
59
+ it "should allow file creation and update" do
60
+ @metadir.can_write?("/test/hello/newfile").should be_true
61
+ @metadir.can_write?("/test/hello/hello.txt").should be_true
62
+ end
63
+
64
+ it "should read files" do
65
+ @metadir.read_file("/test/hello/hello.txt").should == "Hello World!\n"
66
+ end
67
+
68
+ it "should update existing files" do
69
+ @metadir.write_to("/test/hello/hello.txt","new contents")
70
+ @metadir.read_file("/test/hello/hello.txt").should == "new contents"
71
+ end
72
+
73
+ it "should not allow deletion of non empty directories" do
74
+ @metadir.can_rmdir?("/test/hello").should be_false
75
+ end
76
+
77
+ it "should delete directories" do
78
+ @metadir.rmdir("/test/hello/emptydir")
79
+ @metadir.contents("/test/hello").should =~ ["hello.txt"]
80
+ end
81
+
82
+ it "should allow and delete files" do
83
+ @metadir.can_delete?("/test/hello/hello.txt").should be_true
84
+ @metadir.delete("/test/hello/hello.txt")
85
+ @metadir.contents("/test/hello").should =~ ["emptydir"]
86
+ end
87
+
88
+ it "should move directories at same level" do
89
+ before = @metadir.contents("/test/hello")
90
+ @metadir.rename("/test/hello","/test/moved").should be_true
91
+ @metadir.directory?("/test/moved").should be_true
92
+ @metadir.contents("/test/moved").should =~ before
93
+ @metadir.read_file("/test/moved/hello.txt").should == "Hello World!\n"
94
+ end
95
+
96
+ it "should move directories between different paths" do
97
+ @metadir.mkdir("/test/other")
98
+ @metadir.mkdir("/test/other/more")
99
+ before = @metadir.contents("/test/hello")
100
+ @metadir.rename("/test/hello","/test/other/more/hello").should be_true
101
+ @metadir.contents("/test/other/more/hello").should =~ before
102
+ @metadir.read_file("/test/other/more/hello/hello.txt").should == "Hello World!\n"
103
+ end
104
+
105
+ end
106
+
107
+ context "with readonly access" do
108
+ around(:each) do |example|
109
+ #Simulate a different userid..
110
+ FuseFS::RFuseFS.context(fuse_context(-1,-1),&example)
111
+ end
112
+
113
+ before(:each) do
114
+ FuseFS::reader_uid.should_not == Process.uid
115
+ FuseFS::reader_gid.should_not == Process.gid
116
+ end
117
+
118
+ it "should not allow directory creation" do
119
+ @metadir.can_mkdir?("/test/anydir").should be_false
120
+ @metadir.can_mkdir?("/test/hello/otherdir").should be_false
121
+ end
122
+
123
+ it "should not allow file creation or write access" do
124
+ @metadir.can_write?("/test/hello/hello.txt").should be_false
125
+ @metadir.can_write?("/test/hello/newfile").should be_false
126
+ end
127
+
128
+ it "should not allow file deletion" do
129
+ @metadir.can_delete?("/test/hello/hello.txt").should be_false
130
+ end
131
+
132
+ it "should not allow directory deletion" do
133
+ @metadir.can_rmdir?("/test/emptydir").should be_false
134
+ end
135
+
136
+ it "should not allow directory renames" do
137
+ @metadir.rename("/test/emptydir","/test/otherdir").should be_false
138
+ #TODO and make sure it doesn't rename
139
+ end
140
+
141
+ it "should not allow file renames" do
142
+ @metadir.rename("test/hello/hello.txt","test/hello.txt2").should be_false
143
+ #TODO and make sure it doesn't rename
144
+ end
145
+ end
146
+
147
+ context "with subdirectory containing another FuseFS" do
148
+ around(:each) do |example|
149
+ FuseFS::RFuseFS.context(fuse_context(),&example)
150
+ end
151
+
152
+ before(:each) do
153
+ @fusefs = mock("mock_fusefs")
154
+ @metadir.mkdir("/test")
155
+ @metadir.mkdir("/test/fusefs",@fusefs)
156
+ end
157
+
158
+ api_methods = [:directory?, :file?, :contents, :executable?, :size, :times, :read_file, :can_write?, :can_delete?, :delete, :can_mkdir?, :can_rmdir?, :rmdir, :touch, :raw_open, :raw_truncate, :raw_read, :raw_write, :raw_close]
159
+ api_methods.each do |method|
160
+ it "should pass on #{method}" do
161
+ arity = FuseFS::FuseDir.instance_method(method).arity().abs - 1
162
+ args = Array.new(arity) { |i| i }
163
+ @fusefs.should_receive(method).with("/path/to/file",*args).and_return("anything")
164
+ @metadir.send(method,"/test/fusefs/path/to/file",*args)
165
+ end
166
+ end
167
+
168
+ it "should pass on :write_to" do
169
+ @fusefs.should_receive(:write_to).with("/path/to/file","new contents\n")
170
+ @metadir.write_to("/test/fusefs/path/to/file","new contents\n")
171
+ end
172
+
173
+ it "should pass on :mkdir" do
174
+ @fusefs.should_receive(:mkdir).with("/path/to/file",nil).once().and_raise(ArgumentError)
175
+ @fusefs.should_receive(:mkdir).with("/path/to/file").once().and_return("true")
176
+ @metadir.mkdir("/test/fusefs/path/to/file")
177
+ end
178
+
179
+ it "should rename within same directory" do
180
+ @fusefs.should_receive(:rename).with("/oldfile","/newfile")
181
+ @metadir.rename("/test/fusefs/oldfile","/test/fusefs/newfile")
182
+ end
183
+
184
+ it "should pass rename down common directories" do
185
+ @fusefs.should_receive(:rename).with("/path/to/file" ,"/new/path/to/file")
186
+ @metadir.rename("/test/fusefs/path/to/file","/test/fusefs/new/path/to/file")
187
+ end
188
+
189
+ it "should rename across directories if from_path is a FuseFS object that accepts extended rename" do
190
+ @fusefs.should_receive(:rename).with("/path/to/file","/nonfusepath",
191
+ an_instance_of(FuseFS::MetaDir)) do | myPath, extPath, extFS |
192
+ extFS.write_to(extPath,"look Mum, no hands!")
193
+ end
194
+
195
+ @metadir.rename("/test/fusefs/path/to/file","/test/nonfusepath").should be_true
196
+ @metadir.read_file("/test/nonfusepath").should == "look Mum, no hands!"
197
+ end
198
+
199
+ it "should quietly return false if from_path is a FuseFS object that does not accept extended rename" do
200
+ @fusefs.should_receive(:rename).
201
+ with("/path/to/file","/nonfusepath",an_instance_of(FuseFS::MetaDir)).
202
+ and_raise(ArgumentError)
203
+ @metadir.rename("/test/fusefs/path/to/file","/test/nonfusepath").should be_false
204
+
205
+ end
206
+
207
+ it "should not attempt rename file unless :can_write? the destination" do
208
+ @fusefs.should_receive(:can_write?).with("/newpath/to/file").and_return(false)
209
+ @metadir.write_to("/test/aFile","some contents")
210
+ @metadir.rename("/test/aFile","/test/fusefs/newpath/to/file").should be_false
211
+ end
212
+
213
+ it "should not attempt rename directory unless :can_mkdir? the destination" do
214
+ @fusefs.should_receive(:can_mkdir?).with("/newpath/to/dir").and_return(false)
215
+ @metadir.mkdir("/test/aDir","some contents")
216
+ @metadir.rename("/test/aDir","/test/fusefs/newpath/to/dir").should be_false
217
+ end
218
+
219
+ end
220
+
221
+ end
222
+ context "in a mounted FUSE filesystem" do
223
+ before(:all) do
224
+ tmpdir = Pathname.new(Dir.tmpdir) + "rfusefs"
225
+ tmpdir.mkdir unless tmpdir.directory?
226
+ @mountpoint = tmpdir + "metadir_spec"
227
+ puts "#{@mountpoint}"
228
+ @mountpoint.mkdir unless @mountpoint.directory?
229
+ @metadir = FuseFS::MetaDir.new()
230
+ @metadir.mkdir("/test")
231
+ @metadir.write_to("/test/hello.txt","Hello World!\n")
232
+ FuseFS.mount(@metadir,@mountpoint)
233
+ @testdir = (@mountpoint + "test")
234
+ @testfile = (@testdir + "hello.txt")
235
+ #Give FUSE some time to get started
236
+ sleep(1)
237
+ end
238
+
239
+ after(:all) do
240
+ FuseFS.unmount(@mountpoint)
241
+ end
242
+
243
+ it "should list directory contents" do
244
+ @testdir.entries().should =~ pathnames(".","..","hello.txt")
245
+ end
246
+
247
+ it "should read files" do
248
+ @testfile.file?.should be_true
249
+ @testfile.read().should == "Hello World!\n"
250
+ end
251
+
252
+ it "should create directories" do
253
+ newdir = @testdir + "newdir"
254
+ newdir.mkdir()
255
+ newdir.directory?.should be_true
256
+ @testdir.entries().should =~ pathnames(".","..","hello.txt","newdir")
257
+ end
258
+
259
+ it "should create files" do
260
+ newfile = @testdir + "newfile"
261
+ newfile.open("w") do |file|
262
+ file << "A new file\n"
263
+ end
264
+ newfile.read.should == "A new file\n"
265
+ end
266
+
267
+ it "should move directories" do
268
+ fromdir = @testdir + "fromdir"
269
+ fromdir.mkdir()
270
+ subfile = fromdir + "afile"
271
+ subfile.open("w") do |file|
272
+ file << "testfile\n"
273
+ end
274
+
275
+ movedir = (@mountpoint + "movedir")
276
+ movedir.directory?.should be_false
277
+ fromdir.rename(movedir)
278
+ movedir.directory?.should be_true
279
+
280
+ subfile = movedir + "afile"
281
+ subfile.file?.should be_true
282
+ subfile.read.should == "testfile\n"
283
+ end
284
+
285
+ it "should move files" do
286
+ movefile = (@mountpoint + "moved.txt")
287
+ movefile.file?.should be_false
288
+ @testfile.should be_true
289
+ @testfile.rename(movefile)
290
+ movefile.read.should == "Hello World!\n"
291
+ end
292
+
293
+ end
294
+
295
+ end
@@ -0,0 +1,112 @@
1
+ #Pathmapper is hard to test because it is difficult to mock Dir/Pathname/File etc...
2
+ require "spec_helper"
3
+ require "fusefs/pathmapper"
4
+
5
+ describe FuseFS::PathMapperFS do
6
+ before(:all) do
7
+ @tmpdir = mktmpdir("pathmapper")
8
+ #create directory
9
+ pathmap(@tmpdir + "hello.txt","/textfiles/hello")
10
+ pathmap(@tmpdir + "mysong.mp3","/artist/album/mysong.mp3")
11
+ pathmap(@tmpdir + "apicture.jpeg","/pictures/201103/apicture.jpg")
12
+ @pathmapFS = FuseFS::PathMapperFS.create(@tmpdir) do |file|
13
+ File.file?(file) ? IO.read(file.to_s) : nil
14
+ end
15
+ end
16
+
17
+ context "in ruby" do
18
+
19
+ context "standard mapping" do
20
+
21
+ it "should map files and directories" do
22
+ @pathmapFS.directory?("/").should be_true
23
+ @pathmapFS.directory?("/textfiles").should be_true
24
+ @pathmapFS.directory?("/pictures/201103").should be_true
25
+ @pathmapFS.file?("/textfiles/hello").should be_true
26
+ @pathmapFS.file?("/artist/album/mysong.mp3").should be_true
27
+ end
28
+
29
+ it "should list the mapped contents of directories" do
30
+ @pathmapFS.contents("/").should =~ [ "textfiles","artist","pictures" ]
31
+ @pathmapFS.contents("/artist").should =~ [ "album" ]
32
+ @pathmapFS.contents("/textfiles").should =~ [ "hello" ]
33
+ end
34
+
35
+ it "should report the size of a file" do
36
+ @pathmapFS.size("/textfiles/hello").should == 16
37
+ end
38
+
39
+ it "should report the atime,mtime and ctime of the mapped file" do
40
+ atime,mtime,ctime = @pathmapFS.times("/pictures/201103/apicture.jpg")
41
+ picture = @tmpdir + "apicture.jpeg"
42
+ atime.should == picture.atime()
43
+ mtime.should == picture.mtime()
44
+ ctime.should == picture.ctime()
45
+ end
46
+ end
47
+
48
+ context "writing to a pathmapped FS"
49
+ context "using raw access"
50
+
51
+ context "a real Fuse mounted filesystem" do
52
+ before(:all) do
53
+ @mountpoint = Pathname.new(Dir.tmpdir) + "rfusefs-pathmapper"
54
+ @mountpoint.mkdir unless @mountpoint.directory?
55
+ @pathmapFS.use_raw_file_access = true
56
+ FuseFS.mount(@pathmapFS,@mountpoint)
57
+ sleep(1)
58
+ end
59
+
60
+ it "should map files and directories" do
61
+ (@mountpoint + "textfiles").directory?.should be_true
62
+ (@mountpoint + "pictures/201103").directory?.should be_true
63
+ (@mountpoint + "textfiles/hello").file?.should be_true
64
+ (@mountpoint + "artist/album/mysong.mp3").file?.should be_true
65
+ end
66
+
67
+ it "should list the mapped contents of directories" do
68
+ (@mountpoint + "textfiles").entries.should =~ pathnames(".","..","hello")
69
+ end
70
+
71
+ it "should represent the stat information of the underlying files" do
72
+ hellopath=(@mountpoint + "textfiles/hello")
73
+ realpath=(@tmpdir + "hello.txt")
74
+ mappedstat = hellopath.stat
75
+ realstat = realpath.stat
76
+ mappedstat.size.should == realstat.size
77
+ puts "#{realstat.atime.to_f},#{mappedstat.atime.to_f}"
78
+ mappedstat.atime.should == realstat.atime
79
+ mappedstat.mtime.should == realstat.mtime
80
+ mappedstat.ctime.should == realstat.ctime
81
+ end
82
+
83
+ it "should read the files" do
84
+ hellopath = (@mountpoint + "textfiles/hello")
85
+ hellopath.read.should == "/textfiles/hello"
86
+ hellopath.open do |f|
87
+ f.seek(2)
88
+ f.read(3).should == "ext"
89
+ end
90
+ hellopath.sysopen do |f|
91
+ f.sysseek(1)
92
+ f.sysread(3).should == "tex"
93
+ end
94
+ end
95
+
96
+
97
+ after(:all) do
98
+ FuseFS.unmount(@mountpoint)
99
+ end
100
+
101
+ end
102
+
103
+
104
+
105
+ end
106
+
107
+ after(:all) do
108
+ FileUtils.rm_rf(@tmpdir.to_s)
109
+ end
110
+
111
+
112
+ end