Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jacobsa-fuse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
jacobsa-fuse
Commits
590e5940
Commit
590e5940
authored
Mar 23, 2015
by
Aaron Jacobs
Browse files
Options
Browse Files
Download
Plain Diff
Added tests for the behavior of dup and dup2 with regards to flushing.
parents
f7264729
fef27210
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
244 additions
and
102 deletions
+244
-102
samples/flushfs/flush_fs.go
samples/flushfs/flush_fs.go
+21
-0
samples/flushfs/flush_fs_test.go
samples/flushfs/flush_fs_test.go
+223
-102
No files found.
samples/flushfs/flush_fs.go
View file @
590e5940
...
@@ -149,6 +149,27 @@ func (fs *flushFS) OpenFile(
...
@@ -149,6 +149,27 @@ func (fs *flushFS) OpenFile(
return
return
}
}
func
(
fs
*
flushFS
)
ReadFile
(
ctx
context
.
Context
,
req
*
fuse
.
ReadFileRequest
)
(
resp
*
fuse
.
ReadFileResponse
,
err
error
)
{
resp
=
&
fuse
.
ReadFileResponse
{}
fs
.
mu
.
Lock
()
defer
fs
.
mu
.
Unlock
()
// Ensure the offset is in range.
if
req
.
Offset
>
int64
(
len
(
fs
.
fooContents
))
{
return
}
// Read what we can.
resp
.
Data
=
make
([]
byte
,
req
.
Size
)
copy
(
resp
.
Data
,
fs
.
fooContents
[
req
.
Offset
:
])
return
}
func
(
fs
*
flushFS
)
WriteFile
(
func
(
fs
*
flushFS
)
WriteFile
(
ctx
context
.
Context
,
ctx
context
.
Context
,
req
*
fuse
.
WriteFileRequest
)
(
req
*
fuse
.
WriteFileRequest
)
(
...
...
samples/flushfs/flush_fs_test.go
View file @
590e5940
...
@@ -16,9 +16,12 @@ package flushfs_test
...
@@ -16,9 +16,12 @@ package flushfs_test
import
(
import
(
"io"
"io"
"io/ioutil"
"os"
"os"
"path"
"path"
"runtime"
"sync"
"sync"
"syscall"
"testing"
"testing"
"github.com/jacobsa/fuse"
"github.com/jacobsa/fuse"
...
@@ -37,6 +40,10 @@ func TestFlushFS(t *testing.T) { RunTests(t) }
...
@@ -37,6 +40,10 @@ func TestFlushFS(t *testing.T) { RunTests(t) }
type
FlushFSTest
struct
{
type
FlushFSTest
struct
{
samples
.
SampleTest
samples
.
SampleTest
// File handles that are closed in TearDown if non-nil.
f1
*
os
.
File
f2
*
os
.
File
mu
sync
.
Mutex
mu
sync
.
Mutex
// GUARDED_BY(mu)
// GUARDED_BY(mu)
...
@@ -76,6 +83,20 @@ func (t *FlushFSTest) SetUp(ti *TestInfo) {
...
@@ -76,6 +83,20 @@ func (t *FlushFSTest) SetUp(ti *TestInfo) {
t
.
SampleTest
.
SetUp
(
ti
)
t
.
SampleTest
.
SetUp
(
ti
)
}
}
func
(
t
*
FlushFSTest
)
TearDown
()
{
// Close files if non-nil.
if
t
.
f1
!=
nil
{
ExpectEq
(
nil
,
t
.
f1
.
Close
())
}
if
t
.
f2
!=
nil
{
ExpectEq
(
nil
,
t
.
f2
.
Close
())
}
// Finish tearing down.
t
.
SampleTest
.
TearDown
()
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// Helpers
// Helpers
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
...
@@ -120,6 +141,19 @@ func (t *FlushFSTest) setFsyncError(err error) {
...
@@ -120,6 +141,19 @@ func (t *FlushFSTest) setFsyncError(err error) {
t
.
fsyncErr
=
err
t
.
fsyncErr
=
err
}
}
// Like syscall.Dup2, but correctly annotates the syscall as blocking. See here
// for more info: https://github.com/golang/go/issues/10202
func
dup2
(
oldfd
int
,
newfd
int
)
(
err
error
)
{
_
,
_
,
e1
:=
syscall
.
Syscall
(
syscall
.
SYS_DUP2
,
uintptr
(
oldfd
),
uintptr
(
newfd
),
0
)
if
e1
!=
0
{
err
=
e1
}
return
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// Tests
// Tests
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
...
@@ -131,26 +165,20 @@ func (t *FlushFSTest) CloseReports_ReadWrite() {
...
@@ -131,26 +165,20 @@ func (t *FlushFSTest) CloseReports_ReadWrite() {
buf
:=
make
([]
byte
,
1024
)
buf
:=
make
([]
byte
,
1024
)
// Open the file.
// Open the file.
f
,
err
:
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_RDWR
,
0
)
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_RDWR
,
0
)
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
defer
func
()
{
if
f
!=
nil
{
ExpectEq
(
nil
,
f
.
Close
())
}
}()
// Write some contents to the file.
// Write some contents to the file.
n
,
err
=
f
.
Write
([]
byte
(
"taco"
))
n
,
err
=
t
.
f1
.
Write
([]
byte
(
"taco"
))
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertEq
(
4
,
n
)
AssertEq
(
4
,
n
)
// Seek and read them back.
// Seek and read them back.
off
,
err
=
f
.
Seek
(
0
,
0
)
off
,
err
=
t
.
f1
.
Seek
(
0
,
0
)
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertEq
(
0
,
off
)
AssertEq
(
0
,
off
)
n
,
err
=
f
.
Read
(
buf
)
n
,
err
=
t
.
f1
.
Read
(
buf
)
AssertThat
(
err
,
AnyOf
(
nil
,
io
.
EOF
))
AssertThat
(
err
,
AnyOf
(
nil
,
io
.
EOF
))
AssertEq
(
"taco"
,
string
(
buf
[
:
n
]))
AssertEq
(
"taco"
,
string
(
buf
[
:
n
]))
...
@@ -159,8 +187,8 @@ func (t *FlushFSTest) CloseReports_ReadWrite() {
...
@@ -159,8 +187,8 @@ func (t *FlushFSTest) CloseReports_ReadWrite() {
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Close the file.
// Close the file.
err
=
f
.
Close
()
err
=
t
.
f1
.
Close
()
f
=
nil
t
.
f1
=
nil
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
// Now we should have received the flush operation (but still no fsync).
// Now we should have received the flush operation (but still no fsync).
...
@@ -172,22 +200,16 @@ func (t *FlushFSTest) CloseReports_ReadOnly() {
...
@@ -172,22 +200,16 @@ func (t *FlushFSTest) CloseReports_ReadOnly() {
var
err
error
var
err
error
// Open the file.
// Open the file.
f
,
err
:
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_RDONLY
,
0
)
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_RDONLY
,
0
)
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
defer
func
()
{
if
f
!=
nil
{
ExpectEq
(
nil
,
f
.
Close
())
}
}()
// At this point, no flushes or fsyncs should have happened.
// At this point, no flushes or fsyncs should have happened.
AssertThat
(
t
.
getFlushes
(),
ElementsAre
())
AssertThat
(
t
.
getFlushes
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Close the file.
// Close the file.
err
=
f
.
Close
()
err
=
t
.
f1
.
Close
()
f
=
nil
t
.
f1
=
nil
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
// Now we should have received the flush operation (but still no fsync).
// Now we should have received the flush operation (but still no fsync).
...
@@ -200,17 +222,11 @@ func (t *FlushFSTest) CloseReports_WriteOnly() {
...
@@ -200,17 +222,11 @@ func (t *FlushFSTest) CloseReports_WriteOnly() {
var
err
error
var
err
error
// Open the file.
// Open the file.
f
,
err
:
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
defer
func
()
{
if
f
!=
nil
{
ExpectEq
(
nil
,
f
.
Close
())
}
}()
// Write some contents to the file.
// Write some contents to the file.
n
,
err
=
f
.
Write
([]
byte
(
"taco"
))
n
,
err
=
t
.
f1
.
Write
([]
byte
(
"taco"
))
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertEq
(
4
,
n
)
AssertEq
(
4
,
n
)
...
@@ -219,8 +235,8 @@ func (t *FlushFSTest) CloseReports_WriteOnly() {
...
@@ -219,8 +235,8 @@ func (t *FlushFSTest) CloseReports_WriteOnly() {
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Close the file.
// Close the file.
err
=
f
.
Close
()
err
=
t
.
f1
.
Close
()
f
=
nil
t
.
f1
=
nil
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
// Now we should have received the flush operation (but still no fsync).
// Now we should have received the flush operation (but still no fsync).
...
@@ -233,17 +249,11 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_NonOverlappingFileHandles() {
...
@@ -233,17 +249,11 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_NonOverlappingFileHandles() {
var
err
error
var
err
error
// Open the file.
// Open the file.
f
,
err
:
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
defer
func
()
{
if
f
!=
nil
{
ExpectEq
(
nil
,
f
.
Close
())
}
}()
// Write some contents to the file.
// Write some contents to the file.
n
,
err
=
f
.
Write
([]
byte
(
"taco"
))
n
,
err
=
t
.
f1
.
Write
([]
byte
(
"taco"
))
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertEq
(
4
,
n
)
AssertEq
(
4
,
n
)
...
@@ -252,8 +262,8 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_NonOverlappingFileHandles() {
...
@@ -252,8 +262,8 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_NonOverlappingFileHandles() {
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Close the file.
// Close the file.
err
=
f
.
Close
()
err
=
t
.
f1
.
Close
()
f
=
nil
t
.
f1
=
nil
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
// Now we should have received the flush operation (but still no fsync).
// Now we should have received the flush operation (but still no fsync).
...
@@ -261,11 +271,11 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_NonOverlappingFileHandles() {
...
@@ -261,11 +271,11 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_NonOverlappingFileHandles() {
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Open the file again.
// Open the file again.
f
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
// Write again; expect no further flushes.
// Write again; expect no further flushes.
n
,
err
=
f
.
Write
([]
byte
(
"p"
))
n
,
err
=
t
.
f1
.
Write
([]
byte
(
"p"
))
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertEq
(
1
,
n
)
AssertEq
(
1
,
n
)
...
@@ -273,8 +283,8 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_NonOverlappingFileHandles() {
...
@@ -273,8 +283,8 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_NonOverlappingFileHandles() {
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Close the file. Now the new contents should be flushed.
// Close the file. Now the new contents should be flushed.
err
=
f
.
Close
()
err
=
t
.
f1
.
Close
()
f
=
nil
t
.
f1
=
nil
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertThat
(
t
.
getFlushes
(),
ElementsAre
(
"taco"
,
"paco"
))
AssertThat
(
t
.
getFlushes
(),
ElementsAre
(
"taco"
,
"paco"
))
...
@@ -286,28 +296,18 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_OverlappingFileHandles() {
...
@@ -286,28 +296,18 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_OverlappingFileHandles() {
var
err
error
var
err
error
// Open the file with two handles.
// Open the file with two handles.
f1
,
err
:
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
f2
,
err
:
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
t
.
f2
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
defer
func
()
{
if
f1
!=
nil
{
ExpectEq
(
nil
,
f1
.
Close
())
}
if
f2
!=
nil
{
ExpectEq
(
nil
,
f2
.
Close
())
}
}()
// Write some contents with each handle.
// Write some contents with each handle.
n
,
err
=
f1
.
Write
([]
byte
(
"taco"
))
n
,
err
=
t
.
f1
.
Write
([]
byte
(
"taco"
))
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertEq
(
4
,
n
)
AssertEq
(
4
,
n
)
n
,
err
=
f2
.
Write
([]
byte
(
"p"
))
n
,
err
=
t
.
f2
.
Write
([]
byte
(
"p"
))
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertEq
(
1
,
n
)
AssertEq
(
1
,
n
)
...
@@ -316,15 +316,15 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_OverlappingFileHandles() {
...
@@ -316,15 +316,15 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_OverlappingFileHandles() {
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Close one handle. The current contents should be flushed.
// Close one handle. The current contents should be flushed.
err
=
f1
.
Close
()
err
=
t
.
f1
.
Close
()
f1
=
nil
t
.
f1
=
nil
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertThat
(
t
.
getFlushes
(),
ElementsAre
(
"paco"
))
AssertThat
(
t
.
getFlushes
(),
ElementsAre
(
"paco"
))
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Write some more contents via the other handle. Again, no further flushes.
// Write some more contents via the other handle. Again, no further flushes.
n
,
err
=
f2
.
Write
([]
byte
(
"orp"
))
n
,
err
=
t
.
f2
.
Write
([]
byte
(
"orp"
))
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertEq
(
3
,
n
)
AssertEq
(
3
,
n
)
...
@@ -332,35 +332,27 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_OverlappingFileHandles() {
...
@@ -332,35 +332,27 @@ func (t *FlushFSTest) CloseReports_MultipleTimes_OverlappingFileHandles() {
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Close the handle. Now the new contents should be flushed.
// Close the handle. Now the new contents should be flushed.
err
=
f2
.
Close
()
err
=
t
.
f2
.
Close
()
f2
=
nil
t
.
f2
=
nil
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertThat
(
t
.
getFlushes
(),
ElementsAre
(
"paco"
,
"porp"
))
AssertThat
(
t
.
getFlushes
(),
ElementsAre
(
"paco"
,
"porp"
))
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
}
}
func
(
t
*
FlushFSTest
)
CloseReports_DuplicatedFileDescriptor
()
{
AssertTrue
(
false
,
"TODO"
)
}
func
(
t
*
FlushFSTest
)
CloseError
()
{
func
(
t
*
FlushFSTest
)
CloseError
()
{
var
err
error
// Open the file.
// Open the file.
f
,
err
:
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_RDWR
,
0
)
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_RDWR
,
0
)
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
defer
func
()
{
if
f
!=
nil
{
ExpectEq
(
nil
,
f
.
Close
())
}
}()
// Configure a flush error.
// Configure a flush error.
t
.
setFlushError
(
fuse
.
ENOENT
)
t
.
setFlushError
(
fuse
.
ENOENT
)
// Close the file.
// Close the file.
err
=
f
.
Close
()
err
=
t
.
f1
.
Close
()
f
=
nil
t
.
f1
=
nil
AssertNe
(
nil
,
err
)
AssertNe
(
nil
,
err
)
ExpectThat
(
err
,
Error
(
HasSubstr
(
"no such file"
)))
ExpectThat
(
err
,
Error
(
HasSubstr
(
"no such file"
)))
...
@@ -371,17 +363,11 @@ func (t *FlushFSTest) FsyncReports() {
...
@@ -371,17 +363,11 @@ func (t *FlushFSTest) FsyncReports() {
var
err
error
var
err
error
// Open the file.
// Open the file.
f
,
err
:
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
defer
func
()
{
if
f
!=
nil
{
ExpectEq
(
nil
,
f
.
Close
())
}
}()
// Write some contents to the file.
// Write some contents to the file.
n
,
err
=
f
.
Write
([]
byte
(
"taco"
))
n
,
err
=
t
.
f1
.
Write
([]
byte
(
"taco"
))
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertEq
(
4
,
n
)
AssertEq
(
4
,
n
)
...
@@ -389,14 +375,14 @@ func (t *FlushFSTest) FsyncReports() {
...
@@ -389,14 +375,14 @@ func (t *FlushFSTest) FsyncReports() {
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Fsync.
// Fsync.
err
=
f
.
Sync
()
err
=
t
.
f1
.
Sync
()
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertThat
(
t
.
getFlushes
(),
ElementsAre
())
AssertThat
(
t
.
getFlushes
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
(
"taco"
))
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
(
"taco"
))
// Write some more contents.
// Write some more contents.
n
,
err
=
f
.
Write
([]
byte
(
"s"
))
n
,
err
=
t
.
f1
.
Write
([]
byte
(
"s"
))
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertEq
(
1
,
n
)
AssertEq
(
1
,
n
)
...
@@ -404,7 +390,7 @@ func (t *FlushFSTest) FsyncReports() {
...
@@ -404,7 +390,7 @@ func (t *FlushFSTest) FsyncReports() {
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
(
"taco"
))
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
(
"taco"
))
// Fsync.
// Fsync.
err
=
f
.
Sync
()
err
=
t
.
f1
.
Sync
()
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
AssertThat
(
t
.
getFlushes
(),
ElementsAre
())
AssertThat
(
t
.
getFlushes
(),
ElementsAre
())
...
@@ -412,40 +398,175 @@ func (t *FlushFSTest) FsyncReports() {
...
@@ -412,40 +398,175 @@ func (t *FlushFSTest) FsyncReports() {
}
}
func
(
t
*
FlushFSTest
)
FsyncError
()
{
func
(
t
*
FlushFSTest
)
FsyncError
()
{
var
err
error
// Open the file.
// Open the file.
f
,
err
:
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_RDWR
,
0
)
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_RDWR
,
0
)
AssertEq
(
nil
,
err
)
AssertEq
(
nil
,
err
)
defer
func
()
{
if
f
!=
nil
{
ExpectEq
(
nil
,
f
.
Close
())
}
}()
// Configure an fsync error.
// Configure an fsync error.
t
.
setFsyncError
(
fuse
.
ENOENT
)
t
.
setFsyncError
(
fuse
.
ENOENT
)
// Fsync.
// Fsync.
err
=
f
.
Sync
()
err
=
t
.
f1
.
Sync
()
AssertNe
(
nil
,
err
)
AssertNe
(
nil
,
err
)
ExpectThat
(
err
,
Error
(
HasSubstr
(
"no such file"
)))
ExpectThat
(
err
,
Error
(
HasSubstr
(
"no such file"
)))
}
}
func
(
t
*
FlushFSTest
)
Dup
()
{
func
(
t
*
FlushFSTest
)
Dup
()
{
AssertTrue
(
false
,
"TODO"
)
var
n
int
var
err
error
isDarwin
:=
runtime
.
GOOS
==
"darwin"
var
expectedFlushes
[]
interface
{}
// Open the file.
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
AssertEq
(
nil
,
err
)
fd1
:=
t
.
f1
.
Fd
()
// Use dup(2) to get another copy.
fd2
,
err
:=
syscall
.
Dup
(
int
(
fd1
))
AssertEq
(
nil
,
err
)
t
.
f2
=
os
.
NewFile
(
uintptr
(
fd2
),
t
.
f1
.
Name
())
// Write some contents with each handle.
n
,
err
=
t
.
f1
.
Write
([]
byte
(
"taco"
))
AssertEq
(
nil
,
err
)
AssertEq
(
4
,
n
)
n
,
err
=
t
.
f2
.
Write
([]
byte
(
"s"
))
AssertEq
(
nil
,
err
)
AssertEq
(
1
,
n
)
// At this point, no flushes or fsyncs should have happened.
AssertThat
(
t
.
getFlushes
(),
ElementsAre
())
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Close one handle. On Linux the current contents should be flushed. On OS
// X, where the semantics of handles are different, they apparently are not.
// (Cf. https://github.com/osxfuse/osxfuse/issues/199)
err
=
t
.
f1
.
Close
()
t
.
f1
=
nil
AssertEq
(
nil
,
err
)
if
!
isDarwin
{
expectedFlushes
=
append
(
expectedFlushes
,
"tacos"
)
}
AssertThat
(
t
.
getFlushes
(),
ElementsAre
(
expectedFlushes
...
))
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Write some more contents via the other handle. Again, no further flushes.
n
,
err
=
t
.
f2
.
Write
([]
byte
(
"!"
))
AssertEq
(
nil
,
err
)
AssertEq
(
1
,
n
)
AssertThat
(
t
.
getFlushes
(),
ElementsAre
(
expectedFlushes
...
))
AssertThat
(
t
.
getFsyncs
(),
ElementsAre
())
// Close the handle. Now the new contents should be flushed.
err
=
t
.
f2
.
Close
()
t
.
f2
=
nil
AssertEq
(
nil
,
err
)
expectedFlushes
=
append
(
expectedFlushes
,
"tacos!"
)
ExpectThat
(
t
.
getFlushes
(),
ElementsAre
(
expectedFlushes
...
))
ExpectThat
(
t
.
getFsyncs
(),
ElementsAre
())
}
}
func
(
t
*
FlushFSTest
)
Dup_CloseError
()
{
func
(
t
*
FlushFSTest
)
Dup_FlushError
()
{
AssertTrue
(
false
,
"TODO"
)
var
err
error
// Open the file.
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
AssertEq
(
nil
,
err
)
fd1
:=
t
.
f1
.
Fd
()
// Use dup(2) to get another copy.
fd2
,
err
:=
syscall
.
Dup
(
int
(
fd1
))
AssertEq
(
nil
,
err
)
t
.
f2
=
os
.
NewFile
(
uintptr
(
fd2
),
t
.
f1
.
Name
())
// Configure a flush error.
t
.
setFlushError
(
fuse
.
ENOENT
)
// Close by the first handle. On OS X, where the semantics of file handles
// are different (cf. https://github.com/osxfuse/osxfuse/issues/199), this
// does not result in an error.
err
=
t
.
f1
.
Close
()
t
.
f1
=
nil
if
runtime
.
GOOS
==
"darwin"
{
AssertEq
(
nil
,
err
)
}
else
{
AssertNe
(
nil
,
err
)
ExpectThat
(
err
,
Error
(
HasSubstr
(
"no such file"
)))
}
// Close by the second handle.
err
=
t
.
f2
.
Close
()
t
.
f2
=
nil
AssertNe
(
nil
,
err
)
ExpectThat
(
err
,
Error
(
HasSubstr
(
"no such file"
)))
}
}
func
(
t
*
FlushFSTest
)
Dup2
()
{
func
(
t
*
FlushFSTest
)
Dup2
()
{
AssertTrue
(
false
,
"TODO"
)
var
n
int
var
err
error
// Open the file.
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
AssertEq
(
nil
,
err
)
// Write some contents to the file.
n
,
err
=
t
.
f1
.
Write
([]
byte
(
"taco"
))
AssertEq
(
nil
,
err
)
AssertEq
(
4
,
n
)
// Open and unlink some temporary file.
t
.
f2
,
err
=
ioutil
.
TempFile
(
""
,
""
)
AssertEq
(
nil
,
err
)
err
=
os
.
Remove
(
t
.
f2
.
Name
())
AssertEq
(
nil
,
err
)
// Duplicate the temporary file descriptor on top of the file from our file
// system. We should see a flush.
err
=
dup2
(
int
(
t
.
f2
.
Fd
()),
int
(
t
.
f1
.
Fd
()))
ExpectEq
(
nil
,
err
)
ExpectThat
(
t
.
getFlushes
(),
ElementsAre
(
"taco"
))
ExpectThat
(
t
.
getFsyncs
(),
ElementsAre
())
}
}
func
(
t
*
FlushFSTest
)
Dup2_CloseError
()
{
func
(
t
*
FlushFSTest
)
Dup2_FlushError
()
{
AssertTrue
(
false
,
"TODO"
)
var
err
error
// Open the file.
t
.
f1
,
err
=
os
.
OpenFile
(
path
.
Join
(
t
.
Dir
,
"foo"
),
os
.
O_WRONLY
,
0
)
AssertEq
(
nil
,
err
)
// Open and unlink some temporary file.
t
.
f2
,
err
=
ioutil
.
TempFile
(
""
,
""
)
AssertEq
(
nil
,
err
)
err
=
os
.
Remove
(
t
.
f2
.
Name
())
AssertEq
(
nil
,
err
)
// Configure a flush error.
t
.
setFlushError
(
fuse
.
ENOENT
)
// Duplicate the temporary file descriptor on top of the file from our file
// system. We shouldn't see the flush error.
err
=
dup2
(
int
(
t
.
f2
.
Fd
()),
int
(
t
.
f1
.
Fd
()))
ExpectEq
(
nil
,
err
)
}
}
func
(
t
*
FlushFSTest
)
Mmap
()
{
func
(
t
*
FlushFSTest
)
Mmap
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment