parent
0cd0262bed
commit
f66789d381
47 changed files with 2513 additions and 0 deletions
343
pkg/paths/readdir_test.go
Normal file
343
pkg/paths/readdir_test.go
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
* This file is part of PathsHelper library.
|
||||
*
|
||||
* Copyright 2018-2022 Arduino AG (http://www.arduino.cc/)
|
||||
*
|
||||
* PathsHelper library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
|
||||
package paths
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestReadDirRecursive(t *testing.T) {
|
||||
testPath := New("testdata", "fileset")
|
||||
|
||||
list, err := testPath.ReadDirRecursive()
|
||||
require.NoError(t, err)
|
||||
require.Len(t, list, 16)
|
||||
|
||||
pathEqualsTo(t, "testdata/fileset/anotherFile", list[0])
|
||||
pathEqualsTo(t, "testdata/fileset/file", list[1])
|
||||
pathEqualsTo(t, "testdata/fileset/folder", list[2])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/.hidden", list[3])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/file2", list[4])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/file3", list[5])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list[6])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/subfolder/file4", list[7])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder", list[8])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", list[9])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", list[10])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file3", list[11])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", list[12])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder/file4", list[13])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt", list[14])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt.gz", list[15])
|
||||
}
|
||||
|
||||
func TestReadDirRecursiveSymLinkLoop(t *testing.T) {
|
||||
// Test symlink loop
|
||||
tmp, err := MkTempDir("", "")
|
||||
require.NoError(t, err)
|
||||
defer tmp.RemoveAll()
|
||||
|
||||
folder := tmp.Join("folder")
|
||||
err = os.Symlink(tmp.String(), folder.String())
|
||||
require.NoError(t, err)
|
||||
|
||||
l, err := tmp.ReadDirRecursive()
|
||||
require.Error(t, err)
|
||||
fmt.Println(err)
|
||||
require.Nil(t, l)
|
||||
|
||||
l, err = tmp.ReadDirRecursiveFiltered(nil)
|
||||
require.Error(t, err)
|
||||
fmt.Println(err)
|
||||
require.Nil(t, l)
|
||||
}
|
||||
|
||||
func TestReadDirFiltered(t *testing.T) {
|
||||
folderPath := New("testdata/fileset/folder")
|
||||
list, err := folderPath.ReadDir()
|
||||
require.NoError(t, err)
|
||||
require.Len(t, list, 4)
|
||||
pathEqualsTo(t, "testdata/fileset/folder/.hidden", list[0])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/file2", list[1])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/file3", list[2])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list[3])
|
||||
|
||||
list, err = folderPath.ReadDir(FilterDirectories())
|
||||
require.NoError(t, err)
|
||||
require.Len(t, list, 1)
|
||||
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list[0])
|
||||
|
||||
list, err = folderPath.ReadDir(FilterOutPrefixes("file"))
|
||||
require.NoError(t, err)
|
||||
require.Len(t, list, 2)
|
||||
pathEqualsTo(t, "testdata/fileset/folder/.hidden", list[0])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list[1])
|
||||
}
|
||||
|
||||
func TestReadDirRecursiveFiltered(t *testing.T) {
|
||||
testdata := New("testdata", "fileset")
|
||||
l, err := testdata.ReadDirRecursiveFiltered(nil)
|
||||
require.NoError(t, err)
|
||||
l.Sort()
|
||||
require.Len(t, l, 16)
|
||||
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
|
||||
pathEqualsTo(t, "testdata/fileset/file", l[1])
|
||||
pathEqualsTo(t, "testdata/fileset/folder", l[2])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/.hidden", l[3])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/file2", l[4])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/file3", l[5])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/subfolder", l[6])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/subfolder/file4", l[7])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[8])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[9])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", l[10])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file3", l[11])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[12])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder/file4", l[13])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt", l[14])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[15])
|
||||
|
||||
l, err = testdata.ReadDirRecursiveFiltered(FilterOutDirectories())
|
||||
require.NoError(t, err)
|
||||
l.Sort()
|
||||
require.Len(t, l, 6)
|
||||
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
|
||||
pathEqualsTo(t, "testdata/fileset/file", l[1])
|
||||
pathEqualsTo(t, "testdata/fileset/folder", l[2]) // <- this is listed but not traversed
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[3]) // <- this is listed but not traversed
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt", l[4])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[5])
|
||||
|
||||
l, err = testdata.ReadDirRecursiveFiltered(nil, FilterOutDirectories())
|
||||
require.NoError(t, err)
|
||||
l.Sort()
|
||||
require.Len(t, l, 12)
|
||||
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
|
||||
pathEqualsTo(t, "testdata/fileset/file", l[1])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/.hidden", l[2])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/file2", l[3])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/file3", l[4])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/subfolder/file4", l[5])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[6])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", l[7])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file3", l[8])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder/file4", l[9])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt", l[10])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[11])
|
||||
|
||||
l, err = testdata.ReadDirRecursiveFiltered(FilterOutDirectories(), FilterOutDirectories())
|
||||
require.NoError(t, err)
|
||||
l.Sort()
|
||||
require.Len(t, l, 4)
|
||||
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
|
||||
pathEqualsTo(t, "testdata/fileset/file", l[1])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt", l[2])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[3])
|
||||
|
||||
l, err = testdata.ReadDirRecursiveFiltered(FilterOutPrefixes("sub"), FilterOutSuffixes("3"))
|
||||
require.NoError(t, err)
|
||||
l.Sort()
|
||||
require.Len(t, l, 12)
|
||||
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
|
||||
pathEqualsTo(t, "testdata/fileset/file", l[1])
|
||||
pathEqualsTo(t, "testdata/fileset/folder", l[2])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/.hidden", l[3])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/file2", l[4])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/subfolder", l[5]) // <- subfolder skipped by Prefix("sub")
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[6])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[7])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", l[8])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[9]) // <- subfolder skipped by Prefix("sub")
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt", l[10])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[11])
|
||||
|
||||
l, err = testdata.ReadDirRecursiveFiltered(FilterOutPrefixes("sub"), AndFilter(FilterOutSuffixes("3"), FilterOutPrefixes("fil")))
|
||||
require.NoError(t, err)
|
||||
l.Sort()
|
||||
require.Len(t, l, 9)
|
||||
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
|
||||
pathEqualsTo(t, "testdata/fileset/folder", l[1])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/.hidden", l[2])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/subfolder", l[3])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[4])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[5])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[6])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt", l[7])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[8])
|
||||
|
||||
l, err = testdata.ReadDirRecursiveFiltered(FilterOutPrefixes("sub"), AndFilter(FilterOutSuffixes("3"), FilterOutPrefixes("fil"), FilterOutSuffixes(".gz")))
|
||||
require.NoError(t, err)
|
||||
l.Sort()
|
||||
require.Len(t, l, 8)
|
||||
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
|
||||
pathEqualsTo(t, "testdata/fileset/folder", l[1])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/.hidden", l[2])
|
||||
pathEqualsTo(t, "testdata/fileset/folder/subfolder", l[3])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[4])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[5])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[6])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt", l[7])
|
||||
|
||||
l, err = testdata.ReadDirRecursiveFiltered(OrFilter(FilterPrefixes("sub"), FilterSuffixes("tofolder")))
|
||||
require.NoError(t, err)
|
||||
l.Sort()
|
||||
require.Len(t, l, 11)
|
||||
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
|
||||
pathEqualsTo(t, "testdata/fileset/file", l[1])
|
||||
pathEqualsTo(t, "testdata/fileset/folder", l[2])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[3])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/.hidden", l[4])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", l[5])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file3", l[6])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[7])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder/file4", l[8])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt", l[9])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[10])
|
||||
|
||||
l, err = testdata.ReadDirRecursiveFiltered(nil, FilterNames("folder"))
|
||||
require.NoError(t, err)
|
||||
l.Sort()
|
||||
require.Len(t, l, 1)
|
||||
pathEqualsTo(t, "testdata/fileset/folder", l[0])
|
||||
|
||||
l, err = testdata.ReadDirRecursiveFiltered(FilterNames("symlinktofolder"), FilterOutNames(".hidden"))
|
||||
require.NoError(t, err)
|
||||
require.Len(t, l, 9)
|
||||
l.Sort()
|
||||
pathEqualsTo(t, "testdata/fileset/anotherFile", l[0])
|
||||
pathEqualsTo(t, "testdata/fileset/file", l[1])
|
||||
pathEqualsTo(t, "testdata/fileset/folder", l[2])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder", l[3])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file2", l[4])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/file3", l[5])
|
||||
pathEqualsTo(t, "testdata/fileset/symlinktofolder/subfolder", l[6])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt", l[7])
|
||||
pathEqualsTo(t, "testdata/fileset/test.txt.gz", l[8])
|
||||
}
|
||||
|
||||
func TestReadDirRecursiveLoopDetection(t *testing.T) {
|
||||
loopsPath := New("testdata", "loops")
|
||||
unbuondedReaddir := func(testdir string) (PathList, error) {
|
||||
var files PathList
|
||||
var err error
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
files, err = loopsPath.Join(testdir).ReadDirRecursive()
|
||||
done <- true
|
||||
}()
|
||||
require.Eventually(
|
||||
t,
|
||||
func() bool {
|
||||
select {
|
||||
case <-done:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
},
|
||||
5*time.Second,
|
||||
10*time.Millisecond,
|
||||
"Infinite symlink loop while loading sketch",
|
||||
)
|
||||
return files, err
|
||||
}
|
||||
|
||||
for _, dir := range []string{"loop_1", "loop_2", "loop_3", "loop_4"} {
|
||||
l, err := unbuondedReaddir(dir)
|
||||
require.EqualError(t, err, "directories symlink loop detected", "loop not detected in %s", dir)
|
||||
require.Nil(t, l)
|
||||
}
|
||||
|
||||
{
|
||||
l, err := unbuondedReaddir("regular_1")
|
||||
require.NoError(t, err)
|
||||
require.Len(t, l, 4)
|
||||
l.Sort()
|
||||
pathEqualsTo(t, "testdata/loops/regular_1/dir1", l[0])
|
||||
pathEqualsTo(t, "testdata/loops/regular_1/dir1/file1", l[1])
|
||||
pathEqualsTo(t, "testdata/loops/regular_1/dir2", l[2])
|
||||
pathEqualsTo(t, "testdata/loops/regular_1/dir2/file1", l[3])
|
||||
}
|
||||
|
||||
{
|
||||
l, err := unbuondedReaddir("regular_2")
|
||||
require.NoError(t, err)
|
||||
require.Len(t, l, 6)
|
||||
l.Sort()
|
||||
pathEqualsTo(t, "testdata/loops/regular_2/dir1", l[0])
|
||||
pathEqualsTo(t, "testdata/loops/regular_2/dir1/file1", l[1])
|
||||
pathEqualsTo(t, "testdata/loops/regular_2/dir2", l[2])
|
||||
pathEqualsTo(t, "testdata/loops/regular_2/dir2/dir1", l[3])
|
||||
pathEqualsTo(t, "testdata/loops/regular_2/dir2/dir1/file1", l[4])
|
||||
pathEqualsTo(t, "testdata/loops/regular_2/dir2/file2", l[5])
|
||||
}
|
||||
|
||||
{
|
||||
l, err := unbuondedReaddir("regular_3")
|
||||
require.NoError(t, err)
|
||||
require.Len(t, l, 7)
|
||||
l.Sort()
|
||||
pathEqualsTo(t, "testdata/loops/regular_3/dir1", l[0])
|
||||
pathEqualsTo(t, "testdata/loops/regular_3/dir1/file1", l[1])
|
||||
pathEqualsTo(t, "testdata/loops/regular_3/dir2", l[2])
|
||||
pathEqualsTo(t, "testdata/loops/regular_3/dir2/dir1", l[3])
|
||||
pathEqualsTo(t, "testdata/loops/regular_3/dir2/dir1/file1", l[4])
|
||||
pathEqualsTo(t, "testdata/loops/regular_3/dir2/file2", l[5])
|
||||
pathEqualsTo(t, "testdata/loops/regular_3/link", l[6]) // broken symlink is reported in files
|
||||
}
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
dir1 := loopsPath.Join("regular_4_with_permission_error", "dir1")
|
||||
|
||||
l, err := unbuondedReaddir("regular_4_with_permission_error")
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, l)
|
||||
|
||||
dir1Stat, err := dir1.Stat()
|
||||
require.NoError(t, err)
|
||||
err = dir1.Chmod(fs.FileMode(0)) // Enforce permission error
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
// Restore normal permission after the test
|
||||
dir1.Chmod(dir1Stat.Mode())
|
||||
})
|
||||
|
||||
l, err = unbuondedReaddir("regular_4_with_permission_error")
|
||||
require.Error(t, err)
|
||||
require.Nil(t, l)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue