Skip to content

Commit

Permalink
feat(io): compare actual size in CheckIsFileSizeSame
Browse files Browse the repository at this point in the history
longhorn/longhorn-4105

Signed-off-by: Chin-Ya Huang <[email protected]>
  • Loading branch information
c3y1huang authored and derekbit committed Jul 2, 2024
1 parent d78642c commit ad3e7f0
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 7 deletions.
32 changes: 28 additions & 4 deletions io/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,8 @@ func IsDirectoryEmpty(directory string) (bool, error) {
return false, nil
}

// CheckIsFileSizeSame verifies if all files in the provided paths have the same size.
// CheckIsFileSizeSame verifies if all files in the provided paths have the same
// apparent and actual size.
// It returns an error if any file is a directory, does not exist, or has a different size.
func CheckIsFileSizeSame(paths ...string) error {
referenceInfo, err := os.Stat(paths[0])
Expand All @@ -339,7 +340,12 @@ func CheckIsFileSizeSame(paths ...string) error {
return errors.Errorf("file %v is a directory", paths[0])
}

referenceSize := referenceInfo.Size()
referenceApparentSize := referenceInfo.Size()

referenceActualSize, err := getFileBlockSizeEstimate(paths[0])
if err != nil {
return err
}

for _, path := range paths {
fileInfo, err := os.Stat(path)
Expand All @@ -352,10 +358,28 @@ func CheckIsFileSizeSame(paths ...string) error {

}

if fileInfo.Size() != referenceSize {
return errors.Errorf("file %v size %v is not equal to %v", path, fileInfo.Size(), referenceSize)
if fileInfo.Size() != referenceApparentSize {
return errors.Errorf("file %v apparent size %v is not equal to %v", path, fileInfo.Size(), referenceApparentSize)
}

actualSize, err := getFileBlockSizeEstimate(path)
if err != nil {
return err
}

if actualSize != referenceActualSize {
return errors.Errorf("file %v actual size %v is not equal to %v", path, actualSize, referenceActualSize)
}
}

return nil
}

func getFileBlockSizeEstimate(path string) (uint64, error) {
var stat syscall.Stat_t
if err := syscall.Stat(path, &stat); err != nil {
return 0, err
}

return uint64(stat.Blocks) * uint64(stat.Blksize), nil
}
10 changes: 7 additions & 3 deletions io/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ func (s *TestSuite) TestCopyFile(c *C) {
},
"CopyFile(...): sparse file": {
doOverWrite: true,
sparseSize: 20,
expectedSameSize: true,
sparseSize: 4097,
expectedSameSize: false,
},
}
for testName, testCase := range testCases {
Expand Down Expand Up @@ -350,7 +350,11 @@ func (s *TestSuite) TestCopyFile(c *C) {
}
c.Assert(string(content), Equals, expectedContent)
err := CheckIsFileSizeSame(destFile, fakeSourceFile)
c.Assert(err, IsNil)
if testCase.expectedSameSize {
c.Assert(err, IsNil)
} else {
c.Assert(err, NotNil)
}
}
}
}
Expand Down

0 comments on commit ad3e7f0

Please sign in to comment.