diff --git a/test/fuse_integration/posix_Makefile b/test/fuse_integration/posix_Makefile index 7e87d6e23..9a40c3d6a 100644 --- a/test/fuse_integration/posix_Makefile +++ b/test/fuse_integration/posix_Makefile @@ -7,6 +7,7 @@ TEST_TIMEOUT := 45m COVERAGE_FILE := posix_coverage.out REPORT_DIR := reports EXTERNAL_TOOLS_DIR := external_tools +MOUNT_POINT ?= /tmp/seaweedfs_mount # Test categories POSIX_BASIC_TESTS := posix_compliance_test.go @@ -244,7 +245,7 @@ create-fio-configs: setup-reports @echo "time_based" >> $(REPORT_DIR)/fio_random_rw.conf @echo "" >> $(REPORT_DIR)/fio_random_rw.conf @echo "[random_rw_test]" >> $(REPORT_DIR)/fio_random_rw.conf - @echo "directory=/tmp/seaweedfs_mount" >> $(REPORT_DIR)/fio_random_rw.conf + @echo "directory=$(MOUNT_POINT)" >> $(REPORT_DIR)/fio_random_rw.conf @echo "[global]" > $(REPORT_DIR)/fio_sequential.conf @echo "name=posix_sequential" >> $(REPORT_DIR)/fio_sequential.conf @echo "ioengine=sync" >> $(REPORT_DIR)/fio_sequential.conf @@ -257,11 +258,11 @@ create-fio-configs: setup-reports @echo "" >> $(REPORT_DIR)/fio_sequential.conf @echo "[seq_write]" >> $(REPORT_DIR)/fio_sequential.conf @echo "rw=write" >> $(REPORT_DIR)/fio_sequential.conf - @echo "directory=/tmp/seaweedfs_mount" >> $(REPORT_DIR)/fio_sequential.conf + @echo "directory=$(MOUNT_POINT)" >> $(REPORT_DIR)/fio_sequential.conf @echo "" >> $(REPORT_DIR)/fio_sequential.conf @echo "[seq_read]" >> $(REPORT_DIR)/fio_sequential.conf @echo "rw=read" >> $(REPORT_DIR)/fio_sequential.conf - @echo "directory=/tmp/seaweedfs_mount" >> $(REPORT_DIR)/fio_sequential.conf + @echo "directory=$(MOUNT_POINT)" >> $(REPORT_DIR)/fio_sequential.conf # Reporting and analysis generate-report: setup-reports diff --git a/test/fuse_integration/posix_compliance_test.go b/test/fuse_integration/posix_compliance_test.go index e7ce60ec7..c187be102 100644 --- a/test/fuse_integration/posix_compliance_test.go +++ b/test/fuse_integration/posix_compliance_test.go @@ -325,8 +325,11 @@ func (s *POSIXComplianceTestSuite) TestTimestamps(t *testing.T) { stat2, err := os.Stat(testFile) require.NoError(t, err) - // Access time should have changed (or at least not be earlier) - require.True(t, stat2.ModTime().Equal(stat1.ModTime()) || stat2.ModTime().After(stat1.ModTime())) + // Access time should have been updated, and modification time should be unchanged. + stat1Sys := stat1.Sys().(*syscall.Stat_t) + stat2Sys := stat2.Sys().(*syscall.Stat_t) + require.True(t, stat2Sys.Atimespec.Nano() >= stat1Sys.Atimespec.Nano(), "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) { @@ -445,6 +448,37 @@ func (s *POSIXComplianceTestSuite) TestIOOperations(t *testing.T) { require.NoError(t, err) 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) { diff --git a/test/fuse_integration/posix_extended_test.go b/test/fuse_integration/posix_extended_test.go index 341c11ee8..df4dfe401 100644 --- a/test/fuse_integration/posix_extended_test.go +++ b/test/fuse_integration/posix_extended_test.go @@ -207,29 +207,28 @@ func (s *POSIXExtendedTestSuite) TestAdvancedIO(t *testing.T) { require.NoError(t, err) defer syscall.Close(fd) - // Positioned I/O test - use standard library approach - _, err = syscall.Seek(fd, 5, 0) // Seek to position 5 - require.NoError(t, err) - + // Positioned I/O test writeData := []byte("XYZ") - n, err := syscall.Write(fd, writeData) + n, err := syscall.Pwrite(fd, writeData, 5) // pwrite at offset 5 require.NoError(t, err) require.Equal(t, len(writeData), n) - // Seek back and read - _, err = syscall.Seek(fd, 5, 0) + // Verify file position is unchanged + 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.Read(fd, readBuffer) + 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 wasn't changed by pread/pwrite - currentPos, err := syscall.Seek(fd, 0, 1) // SEEK_CUR + // Verify file position is still unchanged + currentPos, err = syscall.Seek(fd, 0, 1) // SEEK_CUR require.NoError(t, err) - require.Equal(t, int64(0), currentPos) // Should still be at beginning + require.Equal(t, int64(0), currentPos, "file offset should not be changed by pread") }) } diff --git a/test/fuse_integration/posix_external_test.go b/test/fuse_integration/posix_external_test.go index 6d8cd60ba..821225c84 100644 --- a/test/fuse_integration/posix_external_test.go +++ b/test/fuse_integration/posix_external_test.go @@ -1,7 +1,6 @@ package fuse import ( - "bufio" "fmt" "os" "os/exec" @@ -171,9 +170,17 @@ set -e cd "$1" echo "test" > original ln original hardlink -[ $(stat -c %h original) -eq 2 ] +if [[ "$(uname)" == "Darwin" ]]; then + [ $(stat -f %l original) -eq 2 ] +else + [ $(stat -c %h original) -eq 2 ] +fi rm hardlink -[ $(stat -c %h original) -eq 1 ] +if [[ "$(uname)" == "Darwin" ]]; then + [ $(stat -f %l original) -eq 1 ] +else + [ $(stat -c %h original) -eq 1 ] +fi echo "PASS: Hard link counting works" `, }, @@ -530,37 +537,3 @@ func (s *ExternalPOSIXTestSuite) testEdgeCases(t *testing.T, mountPoint string) } }) } - -// ReportPOSIXCompliance generates a comprehensive POSIX compliance report -func (s *ExternalPOSIXTestSuite) ReportPOSIXCompliance(t *testing.T) { - reportPath := filepath.Join(s.workDir, "posix_compliance_report.txt") - file, err := os.Create(reportPath) - require.NoError(t, err) - defer file.Close() - - writer := bufio.NewWriter(file) - defer writer.Flush() - - fmt.Fprintf(writer, "SeaweedFS FUSE POSIX Compliance Report\n") - fmt.Fprintf(writer, "=====================================\n") - fmt.Fprintf(writer, "Generated: %s\n\n", time.Now().Format(time.RFC3339)) - - fmt.Fprintf(writer, "Mount Point: %s\n", s.framework.GetMountPoint()) - fmt.Fprintf(writer, "Filer Address: %s\n\n", s.framework.GetFilerAddr()) - - // This would be populated by running the actual tests and collecting results - fmt.Fprintf(writer, "Test Results Summary:\n") - fmt.Fprintf(writer, "--------------------\n") - fmt.Fprintf(writer, "Basic File Operations: PASS\n") - fmt.Fprintf(writer, "Directory Operations: PASS\n") - fmt.Fprintf(writer, "Symlink Operations: PASS\n") - fmt.Fprintf(writer, "Permission Tests: PASS\n") - fmt.Fprintf(writer, "Timestamp Tests: PASS\n") - fmt.Fprintf(writer, "Extended Attributes: CONDITIONAL\n") - fmt.Fprintf(writer, "File Locking: PASS\n") - fmt.Fprintf(writer, "Advanced I/O: PARTIAL\n") - fmt.Fprintf(writer, "Memory Mapping: PASS\n") - fmt.Fprintf(writer, "External Test Suites: VARIABLE\n") - - t.Logf("POSIX compliance report generated: %s", reportPath) -}