mirror of
https://github.com/minio/minio.git
synced 2025-01-23 12:43:16 -05:00
posix: Re-do tests for readDir(). (#1996)
This commit is contained in:
parent
d0be09fdd3
commit
293ba00249
@ -21,6 +21,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ func readDir(dirPath string) (entries []string, err error) {
|
|||||||
defer d.Close()
|
defer d.Close()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
// Read 1000 entries.
|
||||||
fis, err := d.Readdir(1000)
|
fis, err := d.Readdir(1000)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
@ -54,6 +56,22 @@ func readDir(dirPath string) (entries []string, err error) {
|
|||||||
if hasPosixReservedPrefix(fi.Name()) {
|
if hasPosixReservedPrefix(fi.Name()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// Stat symbolic link and follow to get the final value.
|
||||||
|
if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||||
|
var st os.FileInfo
|
||||||
|
st, err = os.Stat(preparePath(path.Join(dirPath, fi.Name())))
|
||||||
|
if err != nil {
|
||||||
|
errorIf(err, "Unable to stat path %s", path.Join(dirPath, fi.Name()))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Append to entries if symbolic link exists and is valid.
|
||||||
|
if st.IsDir() {
|
||||||
|
entries = append(entries, fi.Name()+slashSeparator)
|
||||||
|
} else if st.Mode().IsRegular() {
|
||||||
|
entries = append(entries, fi.Name())
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
if fi.Mode().IsDir() {
|
if fi.Mode().IsDir() {
|
||||||
// Append "/" instead of "\" so that sorting is achieved as expected.
|
// Append "/" instead of "\" so that sorting is achieved as expected.
|
||||||
entries = append(entries, fi.Name()+slashSeparator)
|
entries = append(entries, fi.Name()+slashSeparator)
|
||||||
@ -62,5 +80,5 @@ func readDir(dirPath string) (entries []string, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return entries, nil
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,13 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test to check for different input arguments.
|
// Test to check for different input arguments.
|
||||||
func TestReadDir0(t *testing.T) {
|
func TestReadDirFail(t *testing.T) {
|
||||||
// Check non existent directory.
|
// Check non existent directory.
|
||||||
if _, err := readDir("/tmp/non-existent-directory"); err != errFileNotFound {
|
if _, err := readDir("/tmp/non-existent-directory"); err != errFileNotFound {
|
||||||
t.Fatalf("expected = %s, got: %s", errFileNotFound, err)
|
t.Fatalf("expected = %s, got: %s", errFileNotFound, err)
|
||||||
@ -37,85 +38,133 @@ func TestReadDir0(t *testing.T) {
|
|||||||
t.Fatalf("expected = %s, got: %s", errFileNotFound, err)
|
t.Fatalf("expected = %s, got: %s", errFileNotFound, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if permission denied.
|
// Only valid for linux.
|
||||||
if _, err := readDir("/proc/1/fd"); err == nil {
|
if runtime.GOOS == "linux" {
|
||||||
t.Fatalf("expected = an error, got: nil")
|
// Check if permission denied.
|
||||||
|
if _, err := readDir("/proc/1/fd"); err == nil {
|
||||||
|
t.Fatalf("expected = an error, got: nil")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Represents data type for all the test results.
|
||||||
type result struct {
|
type result struct {
|
||||||
dir string
|
dir string
|
||||||
entries []string
|
entries []string
|
||||||
}
|
}
|
||||||
|
|
||||||
var testResults = []result{}
|
func mustSetupDir(t *testing.T) string {
|
||||||
|
// Create unique test directory.
|
||||||
|
dir, err := ioutil.TempDir("", "minio-posix-list-dir")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to setup directory, %s", err)
|
||||||
|
}
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
|
||||||
// Test to read empty directory.
|
// Test to read empty directory.
|
||||||
func setupTestReadDir1(t *testing.T) {
|
func setupTestReadDirEmpty(t *testing.T) (testResults []result) {
|
||||||
// Create unique test directory.
|
// Add empty entry slice for this test directory.
|
||||||
if dir, err := ioutil.TempDir("", "minio-posix-list-dir"); err != nil {
|
testResults = append(testResults, result{mustSetupDir(t), []string{}})
|
||||||
t.Fatal("failed to setup.", err)
|
return testResults
|
||||||
} else {
|
|
||||||
// Add empty entry slice for this test directory.
|
|
||||||
testResults = append(testResults, result{dir, []string{}})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test to read empty directory with reserved names.
|
// Test to read empty directory with only reserved names.
|
||||||
func setupTestReadDir2(t *testing.T) {
|
func setupTestReadDirReserved(t *testing.T) (testResults []result) {
|
||||||
// Create unique test directory.
|
dir := mustSetupDir(t)
|
||||||
if dir, err := ioutil.TempDir("", "minio-posix-list-dir"); err != nil {
|
entries := []string{}
|
||||||
t.Fatal("failed to setup.", err)
|
// Create a file with reserved name.
|
||||||
} else {
|
for _, reservedName := range posixReservedPrefix {
|
||||||
entries := []string{}
|
if err := ioutil.WriteFile(filepath.Join(dir, reservedName), []byte{}, os.ModePerm); err != nil {
|
||||||
// Create a file with reserved name.
|
// For cleanup, its required to add these entries into test results.
|
||||||
for _, reservedName := range posixReservedPrefix {
|
testResults = append(testResults, result{dir, entries})
|
||||||
if err := ioutil.WriteFile(filepath.Join(dir, reservedName), []byte{}, os.ModePerm); err != nil {
|
t.Fatalf("Unable to create file, %s", err)
|
||||||
// For cleanup, its required to add these entries into test results.
|
|
||||||
sort.Strings(entries)
|
|
||||||
testResults = append(testResults, result{dir, entries})
|
|
||||||
t.Fatal("failed to setup.", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// entries = append(entries, reservedName) - reserved files are skipped.
|
||||||
sort.Strings(entries)
|
|
||||||
|
|
||||||
// Add entries slice for this test directory.
|
|
||||||
testResults = append(testResults, result{dir, entries})
|
|
||||||
}
|
}
|
||||||
|
sort.Strings(entries)
|
||||||
|
|
||||||
|
// Add entries slice for this test directory.
|
||||||
|
testResults = append(testResults, result{dir, entries})
|
||||||
|
return testResults
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test to read non-empty directory.
|
// Test to read non-empty directory with only files.
|
||||||
func setupTestReadDir3(t *testing.T) {
|
func setupTestReadDirFiles(t *testing.T) (testResults []result) {
|
||||||
if dir, err := ioutil.TempDir("", "minio-posix-list-dir"); err != nil {
|
dir := mustSetupDir(t)
|
||||||
t.Fatal("failed to setup.", err)
|
entries := []string{}
|
||||||
} else {
|
for i := 0; i < 10; i++ {
|
||||||
entries := []string{}
|
name := fmt.Sprintf("file-%d", i)
|
||||||
for i := 0; i < 10; i++ {
|
if err := ioutil.WriteFile(filepath.Join(dir, name), []byte{}, os.ModePerm); err != nil {
|
||||||
name := fmt.Sprintf("file-%d", i)
|
// For cleanup, its required to add these entries into test results.
|
||||||
entries = append(entries, name)
|
testResults = append(testResults, result{dir, entries})
|
||||||
if err := ioutil.WriteFile(filepath.Join(dir, name), []byte{}, os.ModePerm); err != nil {
|
t.Fatalf("Unable to create file, %s", err)
|
||||||
// Keep entries sorted for easier comparison.
|
|
||||||
sort.Strings(entries)
|
|
||||||
// For cleanup, its required to add these entries into test results.
|
|
||||||
testResults = append(testResults, result{dir, entries})
|
|
||||||
t.Fatal("failed to setup.", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
entries = append(entries, name)
|
||||||
// Keep entries sorted for easier comparison.
|
|
||||||
sort.Strings(entries)
|
|
||||||
|
|
||||||
// Add entries slice for this test directory.
|
|
||||||
testResults = append(testResults, result{dir, entries})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep entries sorted for easier comparison.
|
||||||
|
sort.Strings(entries)
|
||||||
|
|
||||||
|
// Add entries slice for this test directory.
|
||||||
|
testResults = append(testResults, result{dir, entries})
|
||||||
|
return testResults
|
||||||
}
|
}
|
||||||
|
|
||||||
// teardown - cleans up test directories.
|
// Test to read non-empty directory with directories and files.
|
||||||
func teardown() {
|
func setupTestReadDirGeneric(t *testing.T) (testResults []result) {
|
||||||
for _, r := range testResults {
|
dir := mustSetupDir(t)
|
||||||
os.RemoveAll(r.dir)
|
if err := os.MkdirAll(filepath.Join(dir, "mydir"), 0777); err != nil {
|
||||||
|
t.Fatalf("Unable to create prefix directory \"mydir\", %s", err)
|
||||||
}
|
}
|
||||||
|
entries := []string{"mydir/"}
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
name := fmt.Sprintf("file-%d", i)
|
||||||
|
if err := ioutil.WriteFile(filepath.Join(dir, "mydir", name), []byte{}, os.ModePerm); err != nil {
|
||||||
|
// For cleanup, its required to add these entries into test results.
|
||||||
|
testResults = append(testResults, result{dir, entries})
|
||||||
|
t.Fatalf("Unable to write file, %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Keep entries sorted for easier comparison.
|
||||||
|
sort.Strings(entries)
|
||||||
|
|
||||||
|
// Add entries slice for this test directory.
|
||||||
|
testResults = append(testResults, result{dir, entries})
|
||||||
|
return testResults
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test to read non-empty directory with symlinks.
|
||||||
|
func setupTestReadDirSymlink(t *testing.T) (testResults []result) {
|
||||||
|
dir := mustSetupDir(t)
|
||||||
|
entries := []string{}
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
name1 := fmt.Sprintf("file-%d", i)
|
||||||
|
name2 := fmt.Sprintf("file-%d", i+10)
|
||||||
|
if err := ioutil.WriteFile(filepath.Join(dir, name1), []byte{}, os.ModePerm); err != nil {
|
||||||
|
// For cleanup, its required to add these entries into test results.
|
||||||
|
testResults = append(testResults, result{dir, entries})
|
||||||
|
t.Fatalf("Unable to create a file, %s", err)
|
||||||
|
}
|
||||||
|
// Symlink will not be added to entries.
|
||||||
|
if err := os.Symlink(filepath.Join(dir, name1), filepath.Join(dir, name2)); err != nil {
|
||||||
|
t.Fatalf("Unable to create a symlink, %s", err)
|
||||||
|
}
|
||||||
|
// Add to entries.
|
||||||
|
entries = append(entries, name1)
|
||||||
|
entries = append(entries, name2)
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(filepath.Join(dir, "mydir"), 0777); err != nil {
|
||||||
|
t.Fatalf("Unable to create \"mydir\", %s", err)
|
||||||
|
}
|
||||||
|
entries = append(entries, "mydir/")
|
||||||
|
|
||||||
|
// Keep entries sorted for easier comparison.
|
||||||
|
sort.Strings(entries)
|
||||||
|
|
||||||
|
// Add entries slice for this test directory.
|
||||||
|
testResults = append(testResults, result{dir, entries})
|
||||||
|
return testResults
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkResult - checks whether entries are got are same as expected entries.
|
// checkResult - checks whether entries are got are same as expected entries.
|
||||||
@ -136,13 +185,32 @@ func checkResult(expected []string, got []string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// teardown - cleans up test directories.
|
||||||
|
func teardown(testResults []result) {
|
||||||
|
for _, r := range testResults {
|
||||||
|
os.RemoveAll(r.dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestReadDir - test function to run various readDir() tests.
|
// TestReadDir - test function to run various readDir() tests.
|
||||||
func TestReadDir(t *testing.T) {
|
func TestReadDir(t *testing.T) {
|
||||||
defer teardown()
|
var testResults []result
|
||||||
setupTestReadDir1(t)
|
|
||||||
setupTestReadDir2(t)
|
|
||||||
setupTestReadDir3(t)
|
|
||||||
|
|
||||||
|
// Setup and capture test results for empty directory.
|
||||||
|
testResults = append(testResults, setupTestReadDirEmpty(t)...)
|
||||||
|
// Setup and capture test results for reserved files.
|
||||||
|
testResults = append(testResults, setupTestReadDirReserved(t)...)
|
||||||
|
// Setup and capture test results for directory with only files.
|
||||||
|
testResults = append(testResults, setupTestReadDirFiles(t)...)
|
||||||
|
// Setup and capture test results for directory with files and directories.
|
||||||
|
testResults = append(testResults, setupTestReadDirGeneric(t)...)
|
||||||
|
// Setup and capture test results for directory with files and symlink.
|
||||||
|
testResults = append(testResults, setupTestReadDirSymlink(t)...)
|
||||||
|
|
||||||
|
// Remove all dirs once tests are over.
|
||||||
|
defer teardown(testResults)
|
||||||
|
|
||||||
|
// Validate all the results.
|
||||||
for _, r := range testResults {
|
for _, r := range testResults {
|
||||||
if entries, err := readDir(r.dir); err != nil {
|
if entries, err := readDir(r.dir); err != nil {
|
||||||
t.Fatal("failed to run test.", err)
|
t.Fatal("failed to run test.", err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user