rfusefs 0.8.0 → 1.0.0.RC0

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