Skip to content

Commit

Permalink
internal/plugintest: Switch from (os.File).Readdir() to os.ReadDir() (#…
Browse files Browse the repository at this point in the history
…1056)

Reference: https://pkg.go.dev/os#File.Readdir
Reference: https://pkg.go.dev/os#ReadDir

While attempting to troubleshoot macOS kernel panic behaviors while running acceptance testing, I was able to capture a log whose last entry was `Symlinking source directories to work directory`. Since that operation tends to occur in temporary directory space, there is at least some potential there for strange macOS and Go behaviors.

The `(os.File).Readdir()` method does make this mention in particular:

> Most clients are better served by the more efficient ReadDir method.

Making this a branch so others potentially affected by macOS kernel panics can try this out. This may not be the root cause, as there is a lot more process-oriented logic that occurs to start and stop providers in the testing framework, but if nothing else it could help performance slightly.
  • Loading branch information
bflad committed Sep 14, 2022
1 parent ef65fde commit a096f3a
Showing 1 changed file with 18 additions and 57 deletions.
75 changes: 18 additions & 57 deletions internal/plugintest/util.go
Expand Up @@ -28,79 +28,40 @@ func symlinkFile(src string, dest string) error {
return nil
}

// symlinkDir is a simplistic function for recursively symlinking all files in a directory to a new path.
// It is intended only for limited internal use and does not cover all edge cases.
func symlinkDir(srcDir string, destDir string) (err error) {
srcInfo, err := os.Stat(srcDir)
if err != nil {
return err
}

err = os.MkdirAll(destDir, srcInfo.Mode())
if err != nil {
return err
}

directory, _ := os.Open(srcDir)
defer directory.Close()
objects, err := directory.Readdir(-1)

for _, obj := range objects {
srcPath := filepath.Join(srcDir, obj.Name())
destPath := filepath.Join(destDir, obj.Name())

if obj.IsDir() {
err = symlinkDir(srcPath, destPath)
if err != nil {
return err
}
} else {
err = symlinkFile(srcPath, destPath)
if err != nil {
return err
}
}

}
return
}

// symlinkDirectoriesOnly finds only the first-level child directories in srcDir
// and symlinks them into destDir.
// Unlike symlinkDir, this is done non-recursively in order to limit the number
// of file descriptors used.
func symlinkDirectoriesOnly(srcDir string, destDir string) (err error) {
func symlinkDirectoriesOnly(srcDir string, destDir string) error {
srcInfo, err := os.Stat(srcDir)
if err != nil {
return err
return fmt.Errorf("unable to stat source directory %q: %w", srcDir, err)
}

err = os.MkdirAll(destDir, srcInfo.Mode())
if err != nil {
return err
return fmt.Errorf("unable to make destination directory %q: %w", destDir, err)
}

directory, err := os.Open(srcDir)
if err != nil {
return err
}
defer directory.Close()
objects, err := directory.Readdir(-1)
dirEntries, err := os.ReadDir(srcDir)

if err != nil {
return err
return fmt.Errorf("unable to read source directory %q: %w", srcDir, err)
}

for _, obj := range objects {
srcPath := filepath.Join(srcDir, obj.Name())
destPath := filepath.Join(destDir, obj.Name())

if obj.IsDir() {
err = symlinkFile(srcPath, destPath)
if err != nil {
return err
}
for _, dirEntry := range dirEntries {
if !dirEntry.IsDir() {
continue
}

srcPath := filepath.Join(srcDir, dirEntry.Name())
destPath := filepath.Join(destDir, dirEntry.Name())
err := symlinkFile(srcPath, destPath)

if err != nil {
return fmt.Errorf("unable to symlink directory %q to %q: %w", srcPath, destPath, err)
}
}
return

return nil
}

0 comments on commit a096f3a

Please sign in to comment.