rfusefs 1.0.2.RC0 → 1.1.0.rc202009.34

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
- require 'rfusefs'
3
- require 'tmpdir'
4
- require 'pathname'
5
-
6
- describe "a mounted FuseFS" do
7
- let(:mountpoint) { Pathname.new(Dir.mktmpdir("rfusefs_mount_unmount")) }
8
-
9
- after(:each) { FileUtils.rmdir mountpoint }
10
-
11
- it "should get mounted and unmounted callbacks" do
12
- mock_fs = FuseFS::FuseDir.new()
13
- mock_fs.should_receive(:mounted)
14
- mock_fs.should_receive(:unmounted)
15
-
16
- t = Thread.new { sleep 0.5 ; puts "exiting" ; FuseFS.exit }
17
- FuseFS.start(mock_fs,mountpoint)
18
- t.join
19
- end
20
- end
21
-
@@ -1,202 +0,0 @@
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
- require 'tmpdir'
5
- require 'pathname'
6
-
7
- class PMFixture
8
- attr_reader :tmpdir
9
-
10
- def initialize()
11
- @tmpdir = Pathname.new(Dir.mktmpdir("rfusefs_pathmapper"))
12
- pathmap(@tmpdir + "hello.txt","/textfiles/hello")
13
- pathmap(@tmpdir + "mysong.mp3","/artist/album/mysong.mp3")
14
- pathmap(@tmpdir + "apicture.jpeg","/pictures/201103/apicture.jpg")
15
- end
16
-
17
- def pathmap(real_file,mapped_path)
18
- File.open(real_file.to_s,"w") do |f|
19
- f << mapped_path
20
- end
21
- end
22
-
23
- def fs
24
- @fs ||= FuseFS::PathMapperFS.create(@tmpdir) do |file|
25
- File.file?(file) ? IO.read(file.to_s) : nil
26
- end
27
- end
28
-
29
- def mount()
30
- return @mountpoint if @mountpoint
31
- @mountpoint = Pathname.new(Dir.mktmpdir("rfusefs_pathmapper_mnt"))
32
- FuseFS.mount(fs,@mountpoint)
33
- sleep(0.5)
34
- @mountpoint
35
- end
36
-
37
- def cleanup
38
- if @mountpoint
39
- FuseFS.unmount(@mountpoint)
40
- sleep(0.5)
41
- FileUtils.rmdir(@mountpoint)
42
- end
43
- FileUtils.rm_r(@tmpdir)
44
- end
45
- end
46
-
47
-
48
- describe FuseFS::PathMapperFS do
49
- before(:each) do
50
- @fixture = PMFixture.new
51
- @tmpdir = @fixture.tmpdir
52
- @pathmapFS = @fixture.fs
53
- end
54
-
55
- after(:each) do
56
- @fixture.cleanup
57
- end
58
-
59
- context "fusefs api" do
60
-
61
- it "maps files and directories" do
62
- @pathmapFS.directory?("/").should be_true
63
- @pathmapFS.directory?("/textfiles").should be_true
64
- @pathmapFS.directory?("/pictures/201103").should be_true
65
- @pathmapFS.file?("/textfiles/hello").should be_true
66
- @pathmapFS.directory?("/textfiles/hello").should be_false
67
- @pathmapFS.file?("/artist/album/mysong.mp3").should be_true
68
- @pathmapFS.directory?("/artist/album/mysong.mp3").should be_false
69
- @pathmapFS.file?("/some/unknown/path").should be_false
70
- @pathmapFS.directory?("/some/unknown/path").should be_false
71
- end
72
-
73
- it "lists the mapped contents of directories" do
74
- @pathmapFS.contents("/").should =~ [ "textfiles","artist","pictures" ]
75
- @pathmapFS.contents("/artist").should =~ [ "album" ]
76
- @pathmapFS.contents("/textfiles").should =~ [ "hello" ]
77
- end
78
-
79
- it "reports the size of a file" do
80
- @pathmapFS.size("/textfiles/hello").should == 16
81
- end
82
-
83
- it "reads the contents of a file" do
84
- @pathmapFS.read_file("/textfiles/hello").should == "/textfiles/hello"
85
- end
86
-
87
- it "does not allow writes" do
88
- @pathmapFS.can_write?("/textfiles/hello").should be_false
89
- end
90
-
91
- it "reports the atime,mtime and ctime of the mapped file" do
92
- atime,mtime,ctime = @pathmapFS.times("/pictures/201103/apicture.jpg")
93
- picture = @tmpdir + "apicture.jpeg"
94
- atime.should == picture.atime()
95
- mtime.should == picture.mtime()
96
- ctime.should == picture.ctime()
97
- end
98
-
99
- it "reports filesystem statistics"
100
-
101
- context "writing to a pathmapped FS" do
102
- before(:each) do
103
- @pathmapFS.allow_write=true
104
- @pathmapFS.write_to("textfiles/hello","updated content")
105
- end
106
-
107
- it "updates the contents of the real file" do
108
- hello_path = @tmpdir + "hello.txt"
109
- hello_path.read.should == "updated content"
110
- end
111
-
112
- it "updates the contents of the mapped file" do
113
- @pathmapFS.read_file("textfiles/hello").should == "updated content"
114
- end
115
-
116
- it "changes the reported file size" do
117
- @pathmapFS.size("textfiles/hello").should == 15
118
- end
119
-
120
- it "changes the filesystem statistics"
121
- end
122
-
123
- end
124
-
125
- context "a real Fuse mounted filesystem" do
126
- before(:each) do
127
- @pathmapFS.allow_write=true
128
- @mountpoint = @fixture.mount
129
- end
130
-
131
- it "maps files and directories" do
132
- (@mountpoint + "textfiles").directory?.should be_true
133
- (@mountpoint + "textfiles/hello").file?.should be_true
134
- end
135
-
136
- it "lists the mapped contents of directories" do
137
- (@mountpoint + "textfiles").entries.should =~ pathnames(".","..","hello")
138
- end
139
-
140
- it "represents the stat information of the underlying files" do
141
- hellopath=(@mountpoint + "textfiles/hello")
142
- realpath=(@tmpdir + "hello.txt")
143
- mappedstat = hellopath.stat
144
- realstat = realpath.stat
145
- mappedstat.size.should == realstat.size
146
- mappedstat.atime.should == realstat.atime
147
- mappedstat.mtime.should == realstat.mtime
148
- mappedstat.ctime.should == realstat.ctime
149
- end
150
-
151
- it "reads the files" do
152
- hellopath= @mountpoint + "textfiles/hello"
153
- hellopath.read.should == "/textfiles/hello"
154
- end
155
-
156
- it "writes the files" do
157
- hellopath= @mountpoint + "textfiles/hello"
158
- real_path = @tmpdir + "hello.txt"
159
- hellopath.open("w") do |f|
160
- f.print "updated content"
161
- end
162
- hellopath.read.should == "updated content"
163
- real_path.read.should == "updated content"
164
- end
165
- end
166
-
167
- context "a real Fuse mount with raw file access" do
168
-
169
- before(:each) do
170
- @pathmapFS.use_raw_file_access = true
171
- @pathmapFS.allow_write = true
172
- @mountpoint = @fixture.mount
173
- end
174
-
175
- it "reads files" do
176
- hello_path = (@mountpoint + "textfiles/hello")
177
- hello_path.open do |f|
178
- f.seek(2)
179
- f.read(3).should == "ext"
180
- end
181
-
182
- hello_path.sysopen do |f|
183
- f.sysseek(1)
184
- f.sysread(3).should == "tex"
185
- end
186
- end
187
-
188
- it "writes files" do
189
- hello_path = (@mountpoint + "textfiles/hello")
190
- real_path = @tmpdir + "hello.txt"
191
- hello_path.open("r+") do |f|
192
- f.sysseek(2)
193
- f.syswrite("zzz")
194
- f.sysseek(0)
195
- f.sysread(6).should == "/tzzzf"
196
- end
197
-
198
- real_path.read.should == "/tzzzfiles/hello"
199
- end
200
-
201
- end
202
- end
@@ -1,421 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe FuseFS do
4
-
5
- TEST_FILE = "/aPath/aFile"
6
- TEST_DIR = "/aPath"
7
- ROOT_PATH = "/"
8
- Struct.new("FuseFileInfo",:flags,:fh)
9
-
10
- describe "an empty FuseFS object" do
11
- before(:each) do
12
- @fuse = FuseFS::RFuseFS.new(Object.new())
13
- end
14
-
15
- it "should return an appropriate Stat for the root directory" do
16
- stat = @fuse.getattr(nil,ROOT_PATH)
17
- stat.should respond_to(:dev)
18
- (stat.mode & RFuse::Stat::S_IFDIR).should_not == 0
19
- (stat.mode & RFuse::Stat::S_IFREG).should == 0
20
- permissions(stat.mode).should == 0555
21
- end
22
-
23
- it "should have an empty root directory" do
24
- filler = mock("entries_filler")
25
- filler.should_receive(:push).with(".",nil,0)
26
- filler.should_receive(:push).with("..",nil,0)
27
- @fuse.readdir(nil,"/",filler,nil,nil)
28
- end
29
-
30
- it "should raise ENOENT for other paths" do
31
- lambda { @fuse.getattr(nil,"/somepath") }.should raise_error(Errno::ENOENT)
32
- end
33
-
34
- it "should not allow new files or directories" do
35
- lambda { @fuse.mknod(nil,"/afile",0100644,0,0) }.should raise_error(Errno::EACCES)
36
- lambda { @fuse.mkdir(nil,"/adir",0040555) }.should raise_error(Errno::EACCES)
37
- end
38
- end
39
-
40
- describe "a FuseFS filesystem" do
41
- before(:each) do
42
- @mock_fuse = FuseFS::FuseDir.new()
43
- @fuse = FuseFS::RFuseFS.new(@mock_fuse)
44
- end
45
-
46
- describe :readdir do
47
- before(:each) do
48
- @mock_fuse.should_receive(:contents).with("/apath").and_return(["afile"])
49
- end
50
-
51
- it "should add . and .. to the results of :contents when listing a directory" do
52
- filler = mock("entries_filler")
53
- filler.should_receive(:push).with(".",nil,0)
54
- filler.should_receive(:push).with("..",nil,0)
55
- filler.should_receive(:push).with("afile",nil,0)
56
- @fuse.readdir(nil,"/apath",filler,nil,nil)
57
- end
58
-
59
- end
60
-
61
- describe :getattr do
62
-
63
- #Root directory is special (ish) so we need to run these specs twice.
64
- [ROOT_PATH,TEST_DIR].each do |dir|
65
-
66
- context "of a directory #{ dir }" do
67
-
68
- before(:each) do
69
- @mock_fuse.stub!(:file?).and_return(false)
70
- @mock_fuse.should_receive(:directory?).with(dir).at_most(:once).and_return(true)
71
- @checkfile = (dir == "/" ? "" : dir ) + FuseFS::RFuseFS::CHECK_FILE
72
- end
73
-
74
- it "should return a Stat like object representing a directory" do
75
- @mock_fuse.should_receive(:can_write?).with(@checkfile).at_most(:once).and_return(false)
76
- @mock_fuse.should_receive(:can_mkdir?).with(@checkfile).at_most(:once).and_return(false)
77
- stat = @fuse.getattr(nil,dir)
78
- #Apparently find relies on nlink accurately listing the number of files/directories or nlink being 1
79
- stat.nlink.should == 1
80
- filetype(stat.mode).should == RFuse::Stat::S_IFDIR
81
- permissions(stat.mode).should == 0555
82
- end
83
-
84
-
85
- it "should return writable mode if can_mkdir?" do
86
- @mock_fuse.should_receive(:can_mkdir?).with(@checkfile).at_most(:once).and_return(true)
87
-
88
- stat = @fuse.getattr(nil,dir)
89
- permissions(stat.mode).should == 0777
90
- end
91
-
92
- it "should return writable mode if can_write?" do
93
- @mock_fuse.should_receive(:can_write?).with(@checkfile).at_most(:once).and_return(true)
94
-
95
- stat = @fuse.getattr(nil,dir)
96
- permissions(stat.mode).should == 0777
97
-
98
- end
99
-
100
- it "should return times in the result if available" do
101
- @mock_fuse.should_receive(:times).with(dir).and_return([10,20,30])
102
- stat = @fuse.getattr(nil,dir)
103
- stat.atime.should == 10
104
- stat.mtime.should == 20
105
- stat.ctime.should == 30
106
- end
107
- end
108
- end
109
-
110
- describe "a file" do
111
-
112
- before(:each) do
113
- @file="/aPath/aFile"
114
- @mock_fuse.stub!(:directory?).and_return(false)
115
- @mock_fuse.should_receive(:file?).with(@file).at_most(:once).and_return(true)
116
- end
117
-
118
-
119
- it "should return a Stat like object representing a file" do
120
- stat = @fuse.getattr(nil,@file)
121
- (stat.mode & RFuse::Stat::S_IFDIR).should == 0
122
- (stat.mode & RFuse::Stat::S_IFREG).should_not == 0
123
- permissions(stat.mode).should == 0444
124
- end
125
-
126
- it "should indicate executable mode if executable?" do
127
- @mock_fuse.should_receive(:executable?).with(@file).and_return(true)
128
- stat = @fuse.getattr(nil,@file)
129
- permissions(stat.mode).should == 0555
130
- end
131
-
132
- it "should indicate writable mode if can_write?" do
133
- @mock_fuse.should_receive(:can_write?).with(@file).and_return(true)
134
- stat = @fuse.getattr(nil,@file)
135
- permissions(stat.mode).should == 0666
136
- end
137
-
138
- it "should by 777 mode if can_write? and exectuable?" do
139
- @mock_fuse.should_receive(:can_write?).with(@file).and_return(true)
140
- @mock_fuse.should_receive(:executable?).with(@file).and_return(true)
141
- stat = @fuse.getattr(nil,@file)
142
- permissions(stat.mode).should == 0777
143
- end
144
-
145
- it "should include size in the result if available" do
146
- @mock_fuse.should_receive(:size).with(@file).and_return(234)
147
- stat = @fuse.getattr(nil,@file)
148
- stat.size.should == 234
149
- end
150
-
151
- it "should include times in the result if available" do
152
- @mock_fuse.should_receive(:times).with(@file).and_return([22,33,44])
153
- stat = @fuse.getattr(nil,@file)
154
- stat.atime.should == 22
155
- stat.mtime.should == 33
156
- stat.ctime.should == 44
157
- end
158
- end
159
-
160
- it "should raise ENOENT for a path that does not exist" do
161
- @mock_fuse.should_receive(:file?).with(TEST_FILE).and_return(false)
162
- @mock_fuse.should_receive(:directory?).with(TEST_FILE).and_return(false)
163
- lambda{stat = @fuse.getattr(nil,TEST_FILE) }.should raise_error(Errno::ENOENT)
164
- end
165
- end
166
-
167
- context "creating files and directories" do
168
-
169
- it ":mknod should raise EACCES unless :can_write?" do
170
- @mock_fuse.stub!(:file?).with(TEST_FILE).and_return(false)
171
- @mock_fuse.stub!(:directory?).with(TEST_FILE).and_return(false)
172
- @mock_fuse.should_receive(:can_write?).with(TEST_FILE).and_return(false)
173
- lambda{@fuse.mknod(nil,TEST_FILE,0100644,0,0)}.should raise_error(Errno::EACCES)
174
- end
175
-
176
- it ":mkdir should raise EACCES unless :can_mkdir?" do
177
- @mock_fuse.stub!(:file?).with(TEST_FILE).and_return(false)
178
- @mock_fuse.stub!(:directory?).with(TEST_FILE).and_return(false)
179
- @mock_fuse.should_receive(:can_mkdir?).with(TEST_FILE).and_return(false)
180
- lambda{@fuse.mkdir(nil,TEST_FILE,004555)}.should raise_error(Errno::EACCES)
181
- end
182
-
183
- it ":mknod should raise EACCES unless mode requests a regular file" do
184
- @mock_fuse.stub!(:file?).with(TEST_FILE).and_return(false)
185
- @mock_fuse.stub!(:directory?).with(TEST_FILE).and_return(false)
186
- @mock_fuse.stub!(:can_write?).with(TEST_FILE).and_return(true)
187
- lambda{@fuse.mknod(nil,TEST_FILE,RFuse::Stat::S_IFLNK | 0644,0,0)}.should raise_error(Errno::EACCES)
188
- end
189
-
190
- it ":mknod should result in getattr returning a Stat like object representing an empty file" do
191
- @mock_fuse.stub!(:file?).with(TEST_FILE).and_return(false)
192
- @mock_fuse.stub!(:directory?).with(TEST_FILE).and_return(false)
193
- @mock_fuse.stub!(:can_write?).with(TEST_FILE).and_return(true)
194
- @fuse.mknod(nil,TEST_FILE,RFuse::Stat::S_IFREG | 0644,0,0)
195
-
196
- stat = @fuse.getattr(nil,TEST_FILE)
197
- filetype(stat.mode).should == RFuse::Stat::S_IFREG
198
- stat.size.should == 0
199
- end
200
-
201
- it ":mkdir should not raise error if can_mkdir?" do
202
- @mock_fuse.should_receive(:can_mkdir?).with(TEST_FILE).and_return(true)
203
- @fuse.mkdir(nil,TEST_FILE,004555)
204
- end
205
-
206
- end
207
-
208
- context "reading files" do
209
- it "should read the contents of a file" do
210
- ffi = Struct::FuseFileInfo.new()
211
- ffi.flags = Fcntl::O_RDONLY
212
- @mock_fuse.stub!(:file?).with(TEST_FILE).and_return(true)
213
- @mock_fuse.stub!(:read_file).with(TEST_FILE).and_return("Hello World\n")
214
- @fuse.open(nil,TEST_FILE,ffi)
215
- #to me fuse is backwards -- size, offset!
216
- @fuse.read(nil,TEST_FILE,5,0,ffi).should == "Hello"
217
- @fuse.read(nil,TEST_FILE,4,6,ffi).should == "Worl"
218
- @fuse.read(nil,TEST_FILE,10,8,ffi).should == "rld\n"
219
- @fuse.flush(nil,TEST_FILE,ffi)
220
- @fuse.release(nil,TEST_FILE,ffi)
221
- end
222
- end
223
-
224
- context "writing files" do
225
- it "should overwrite a file opened WR_ONLY" do
226
- ffi = Struct::FuseFileInfo.new()
227
- ffi.flags = Fcntl::O_WRONLY
228
- @mock_fuse.stub!(:can_write?).with(TEST_FILE).and_return(true)
229
- @mock_fuse.stub!(:read_file).with(TEST_FILE).and_return("I'm writing a file\n")
230
- @mock_fuse.should_receive(:write_to).once().with(TEST_FILE,"My new contents\n")
231
- @fuse.open(nil,TEST_FILE,ffi)
232
- @fuse.ftruncate(nil,TEST_FILE,0,ffi)
233
- @fuse.write(nil,TEST_FILE,"My new c",0,ffi)
234
- @fuse.write(nil,TEST_FILE,"ontents\n",8,ffi)
235
- @fuse.flush(nil,TEST_FILE,ffi)
236
- #that's right flush can be called more than once.
237
- @fuse.flush(nil,TEST_FILE,ffi)
238
- #but then we can write some more and flush again
239
- @fuse.release(nil,TEST_FILE,ffi)
240
- end
241
-
242
- it "should append to a file opened WR_ONLY | APPEND" do
243
- ffi = Struct::FuseFileInfo.new()
244
- ffi.flags = Fcntl::O_WRONLY | Fcntl::O_APPEND
245
- @mock_fuse.stub!(:can_write?).with(TEST_FILE).and_return(true)
246
- @mock_fuse.stub!(:read_file).with(TEST_FILE).and_return("I'm writing a file\n")
247
- @mock_fuse.should_receive(:write_to).once().with(TEST_FILE,"I'm writing a file\nMy new contents\n")
248
- @fuse.open(nil,TEST_FILE,ffi)
249
- @fuse.write(nil,TEST_FILE,"My new c",0,ffi)
250
- @fuse.write(nil,TEST_FILE,"ontents\n",8,ffi)
251
- @fuse.flush(nil,TEST_FILE,ffi)
252
- #that's right flush can be called more than once. But we should only write-to the first time
253
- @fuse.flush(nil,TEST_FILE,ffi)
254
- @fuse.release(nil,TEST_FILE,ffi)
255
-
256
- end
257
-
258
- it "should do sensible things for files opened RDWR"
259
-
260
- end
261
-
262
- context "raw reading" do
263
- it "should call the raw_read/raw_close if raw_open returns true" do
264
- ffi = Struct::FuseFileInfo.new()
265
- ffi.flags = Fcntl::O_RDONLY
266
- @mock_fuse.stub!(:can_write?).with(TEST_FILE).and_return(true)
267
- @mock_fuse.should_receive(:raw_open).with(TEST_FILE,"r",true).and_return("raw")
268
- @mock_fuse.should_receive(:raw_read).with(TEST_FILE,5,0,"raw").and_return("12345")
269
- @mock_fuse.should_receive(:raw_read).with(TEST_FILE,5,5,"raw").and_return("67890")
270
- @mock_fuse.should_receive(:raw_close).with(TEST_FILE,"raw")
271
- @fuse.open(nil,TEST_FILE,ffi)
272
- @fuse.read(nil,TEST_FILE,0,5,ffi).should == "12345"
273
- @fuse.read(nil,TEST_FILE,5,5,ffi).should == "67890"
274
- @fuse.flush(nil,TEST_FILE,ffi)
275
- @fuse.release(nil,TEST_FILE,ffi)
276
- end
277
-
278
- end
279
-
280
- context "raw writing" do
281
- it "should call raw_truncate,raw_write,raw_close if raw_open returns true" do
282
- ffi = Struct::FuseFileInfo.new()
283
- ffi.flags = Fcntl::O_WRONLY
284
- raw = Object.new()
285
- @mock_fuse.stub!(:can_write?).with(TEST_FILE).and_return(true)
286
- @mock_fuse.should_receive(:raw_open).with(TEST_FILE,"w",true).and_return(raw)
287
- @mock_fuse.should_receive(:raw_truncate).with(TEST_FILE,0,raw)
288
- @mock_fuse.should_receive(:raw_write).with(TEST_FILE,0,5,"12345",raw).once().and_return(5)
289
- @mock_fuse.should_receive(:raw_write).with(TEST_FILE,5,5,"67890",raw).once().and_return(5)
290
- @mock_fuse.should_receive(:raw_close).with(TEST_FILE,raw)
291
- @fuse.open(nil,TEST_FILE,ffi)
292
- @fuse.ftruncate(nil,TEST_FILE,0,ffi)
293
- @fuse.write(nil,TEST_FILE,"12345",0,ffi).should == 5
294
- @fuse.write(nil,TEST_FILE,"67890",5,ffi).should == 5
295
- @fuse.flush(nil,TEST_FILE,ffi)
296
- @fuse.release(nil,TEST_FILE,ffi)
297
- end
298
-
299
- it "should pass 'wa' to raw_open if fuse sends WRONLY | APPEND" do
300
- ffi = Struct::FuseFileInfo.new()
301
- ffi.flags = Fcntl::O_WRONLY | Fcntl::O_APPEND
302
- raw = Object.new()
303
- @mock_fuse.stub!(:can_write?).with(TEST_FILE).and_return(true)
304
- @mock_fuse.should_receive(:raw_open).with(TEST_FILE,"wa",true).and_return(raw)
305
- @fuse.open(nil,TEST_FILE,ffi)
306
- end
307
- end
308
-
309
- context "deleting files" do
310
- it "should raise EACCES unless :can_delete?" do
311
- @mock_fuse.should_receive(:can_delete?).with(TEST_FILE).and_return(false)
312
- lambda {@fuse.unlink(nil,TEST_FILE)}.should raise_error(Errno::EACCES)
313
- end
314
-
315
- it "should :delete without error if :can_delete?" do
316
- @mock_fuse.stub!(:can_delete?).with(TEST_FILE).and_return(true)
317
- @mock_fuse.should_receive(:delete).with(TEST_FILE)
318
- @fuse.unlink(nil,TEST_FILE)
319
- end
320
-
321
- it "should remove entries created with mknod that have never been opened" do
322
- @mock_fuse.stub!(:file?).with(TEST_FILE).and_return(false)
323
- @mock_fuse.stub!(:directory?).with(TEST_FILE).and_return(false)
324
- @mock_fuse.stub!(:can_delete?).with(TEST_FILE).and_return(true)
325
- @mock_fuse.stub!(:can_write?).with(TEST_FILE).and_return(true)
326
- @fuse.mknod(nil,TEST_FILE,RFuse::Stat::S_IFREG | 0644,0,0)
327
-
328
- @fuse.unlink(nil,TEST_FILE)
329
- lambda {@fuse.getattr(nil,TEST_FILE)}.should raise_error(Errno::ENOENT)
330
- end
331
- end
332
-
333
- context "deleting directories" do
334
- it "should raise EACCES unless :can_rmdir?" do
335
- @mock_fuse.should_receive(:can_rmdir?).with(TEST_DIR).and_return(false)
336
- lambda{@fuse.rmdir(nil,TEST_DIR)}.should raise_error(Errno::EACCES)
337
- end
338
-
339
- it "should :rmdir without error if :can_rmdir?" do
340
- @mock_fuse.stub!(:can_rmdir?).with(TEST_DIR).and_return(true)
341
- @fuse.rmdir(nil,TEST_DIR)
342
- end
343
- end
344
-
345
- context "touching files" do
346
- it "should call :touch in response to utime" do
347
- @mock_fuse.should_receive(:touch).with(TEST_FILE,220)
348
- @fuse.utime(nil,TEST_FILE,100,220)
349
- end
350
- end
351
-
352
- context "renaming files" do
353
- before(:each) do
354
- @oldfile = "/aPath/oldFile"
355
- @newfile = "/aNewFile"
356
- @mock_fuse.stub!(:file?).with(@oldfile).and_return(true)
357
- @mock_fuse.stub!(:directory?).with(@oldfile).and_return(false)
358
- end
359
- it "should raise EACCES unless :can_write? the new file" do
360
- @mock_fuse.stub!(:can_delete?).with(@oldfile).and_return(true)
361
- @mock_fuse.should_receive(:can_write?).with(@newfile).and_return(false)
362
- lambda {@fuse.rename(nil,@oldfile,@newfile)}.should raise_error(Errno::EACCES)
363
- end
364
-
365
- it "should raise EACCES unless :can_delete the old file" do
366
- @mock_fuse.stub!(:can_write?).with(@newfile).and_return(true)
367
- @mock_fuse.should_receive(:can_delete?).with(@oldfile).and_return(false)
368
- lambda {@fuse.rename(nil,@oldfile,@newfile)}.should raise_error(Errno::EACCES)
369
- end
370
-
371
- it "should copy and delete files" do
372
- @mock_fuse.stub!(:can_write?).with(@newfile).and_return(true)
373
- @mock_fuse.stub!(:can_delete?).with(@oldfile).and_return(true)
374
- @mock_fuse.should_receive(:read_file).with(@oldfile).and_return("some contents\n")
375
- @mock_fuse.should_receive(:write_to).with(@newfile,"some contents\n")
376
- @mock_fuse.should_receive(:delete).with(@oldfile)
377
- @fuse.rename(nil,@oldfile,@newfile)
378
- end
379
-
380
- it "should not copy and delete files if fs responds_to? :rename" do
381
- @mock_fuse.should_receive(:rename).with(@oldfile,@newfile).and_return(true)
382
- @fuse.rename(nil,@oldfile,@newfile)
383
- end
384
-
385
- it "should raise EACCES if moving a directory and rename not supported" do
386
- @mock_fuse.stub!(:file?).with(@oldfile).and_return(false)
387
- @mock_fuse.stub!(:directory?).with(@oldfile).and_return(true)
388
- @mock_fuse.stub!(:can_write?).with(@newfile).and_return(true)
389
- @mock_fuse.stub!(:can_delete?).with(@oldfile).and_return(true)
390
- lambda{@fuse.rename(nil,@oldfile,@newfile)}.should raise_error(Errno::EACCES)
391
- end
392
-
393
- end
394
- context "extended attributes" do
395
-
396
- let(:xattr) { {} }
397
- before(:each) { @mock_fuse.stub!(:xattr).with(TEST_FILE).and_return(xattr) }
398
-
399
- it "should get, set and list attributes" do
400
- xattr["user.one"] = "xattr one"
401
-
402
- @fuse.getxattr(nil,TEST_FILE,"user.one").should == "xattr one"
403
- @fuse.setxattr(nil,TEST_FILE,"user.two","xattr two")
404
- xattr["user.two"].should == "xattr two"
405
- @fuse.listxattr(nil,TEST_FILE).should =~ [ "user.one", "user.two" ]
406
- @fuse.removexattr(nil,TEST_FILE,"user.two")
407
- xattr.keys.should =~ [ "user.one" ]
408
- end
409
-
410
- it "should raise ENODATA is no attribute is available" do
411
- lambda{@fuse.getxattr(nil,TEST_FILE,"user.xxxx") }.should raise_error(Errno::ENODATA)
412
- end
413
- end
414
- end
415
-
416
- describe "a FuseFS filesystem with gid/uid specific behaviour" do
417
- it "should provide context uid and gid for all API methods"
418
- end
419
- end
420
-
421
-