|
|
@ -326,33 +326,10 @@ func (s *POSIXComplianceTestSuite) TestTimestamps(t *testing.T) { |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
// Access time should have been updated, and modification time should be unchanged.
|
|
|
|
// Note: Some filesystems may not update atime on read due to noatime mount options
|
|
|
|
// We'll focus on ensuring modification time is not affected by reads
|
|
|
|
require.Equal(t, stat1.ModTime(), stat2.ModTime(), "modification time should not change on read") |
|
|
|
|
|
|
|
// For access time, we use a cross-platform approach
|
|
|
|
stat1Sys := stat1.Sys().(*syscall.Stat_t) |
|
|
|
stat2Sys := stat2.Sys().(*syscall.Stat_t) |
|
|
|
|
|
|
|
// Get access time in nanoseconds - handle different field names across platforms
|
|
|
|
var atime1, atime2 int64 |
|
|
|
|
|
|
|
// Try different field names based on platform
|
|
|
|
if hasAtimespec(stat1Sys) { |
|
|
|
// macOS and some other systems use Atimespec
|
|
|
|
atime1 = getAtimespecNano(stat1Sys) |
|
|
|
atime2 = getAtimespecNano(stat2Sys) |
|
|
|
} else { |
|
|
|
// Linux and others may use different field names
|
|
|
|
// For now, we'll skip detailed atime testing on unsupported platforms
|
|
|
|
atime1 = 0 |
|
|
|
atime2 = 0 |
|
|
|
} |
|
|
|
|
|
|
|
// Access time should be >= original (or filesystem may not update it due to noatime)
|
|
|
|
if atime1 > 0 && atime2 > 0 { |
|
|
|
require.True(t, atime2 >= atime1, "access time should be updated or stay the same") |
|
|
|
} |
|
|
|
require.True(t, getAtimeNano(stat2Sys) >= getAtimeNano(stat1Sys), "access time should be updated or stay the same") |
|
|
|
require.Equal(t, stat1.ModTime(), stat2.ModTime(), "modification time should not change on read") |
|
|
|
}) |
|
|
|
|
|
|
|
t.Run("ModificationTime", func(t *testing.T) { |
|
|
@ -472,6 +449,36 @@ func (s *POSIXComplianceTestSuite) TestIOOperations(t *testing.T) { |
|
|
|
require.Equal(t, 1, n) |
|
|
|
require.Equal(t, []byte("A"), buffer) |
|
|
|
|
|
|
|
// Test positioned I/O operations (pread/pwrite)
|
|
|
|
syscall.Close(fd) |
|
|
|
|
|
|
|
// Open for read/write to test pwrite
|
|
|
|
fd, err = syscall.Open(testFile, syscall.O_RDWR, 0) |
|
|
|
require.NoError(t, err) |
|
|
|
defer syscall.Close(fd) |
|
|
|
|
|
|
|
// Positioned write test
|
|
|
|
writeData := []byte("XYZ") |
|
|
|
n, err = syscall.Pwrite(fd, writeData, 5) // pwrite at offset 5
|
|
|
|
require.NoError(t, err) |
|
|
|
require.Equal(t, len(writeData), n) |
|
|
|
|
|
|
|
// Verify file position is unchanged by pwrite
|
|
|
|
currentPos, err := syscall.Seek(fd, 0, 1) // SEEK_CUR
|
|
|
|
require.NoError(t, err) |
|
|
|
require.Equal(t, int64(0), currentPos, "file offset should not be changed by pwrite") |
|
|
|
|
|
|
|
// Read back with pread
|
|
|
|
readBuffer := make([]byte, len(writeData)) |
|
|
|
n, err = syscall.Pread(fd, readBuffer, 5) // pread at offset 5
|
|
|
|
require.NoError(t, err) |
|
|
|
require.Equal(t, len(writeData), n) |
|
|
|
require.Equal(t, writeData, readBuffer) |
|
|
|
|
|
|
|
// Verify file position is still unchanged by pread
|
|
|
|
currentPos, err = syscall.Seek(fd, 0, 1) // SEEK_CUR
|
|
|
|
require.NoError(t, err) |
|
|
|
require.Equal(t, int64(0), currentPos, "file offset should not be changed by pread") |
|
|
|
}) |
|
|
|
|
|
|
|
t.Run("AppendMode", func(t *testing.T) { |
|
|
@ -626,7 +633,7 @@ func (s *POSIXComplianceTestSuite) TestConcurrentAccess(t *testing.T) { |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
t.Run("ConcurrentFileCreations", func(t *testing.T) { |
|
|
|
t.Run("ConcurrentWrites", func(t *testing.T) { |
|
|
|
testFile := filepath.Join(mountPoint, "concurrent_write.txt") |
|
|
|
|
|
|
|
// Launch multiple concurrent writers
|
|
|
@ -699,14 +706,3 @@ func (s *POSIXComplianceTestSuite) TestErrorHandling(t *testing.T) { |
|
|
|
require.True(t, os.IsPermission(err)) |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
// Cross-platform helper functions for access time handling
|
|
|
|
func hasAtimespec(stat *syscall.Stat_t) bool { |
|
|
|
// Always return true for now - we'll handle platform differences in getAtimespecNano
|
|
|
|
return true |
|
|
|
} |
|
|
|
|
|
|
|
func getAtimespecNano(stat *syscall.Stat_t) int64 { |
|
|
|
// Use the field that exists on this platform
|
|
|
|
return stat.Atimespec.Sec*1e9 + stat.Atimespec.Nsec |
|
|
|
} |