mirror of
https://github.com/roddhjav/apparmor.d.git
synced 2024-11-15 07:54:17 +01:00
433 lines
13 KiB
Go
433 lines
13 KiB
Go
|
/*
|
||
|
* This file is part of PathsHelper library.
|
||
|
*
|
||
|
* Copyright 2018 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 (
|
||
|
"path/filepath"
|
||
|
"runtime"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
func pathEqualsTo(t *testing.T, expected string, actual *Path) {
|
||
|
require.Equal(t, expected, filepath.ToSlash(actual.String()))
|
||
|
}
|
||
|
|
||
|
func TestPathNew(t *testing.T) {
|
||
|
test1 := New("path")
|
||
|
require.Equal(t, "path", test1.String())
|
||
|
|
||
|
test2 := New("path", "path")
|
||
|
require.Equal(t, filepath.Join("path", "path"), test2.String())
|
||
|
|
||
|
test3 := New()
|
||
|
require.Nil(t, test3)
|
||
|
|
||
|
test4 := New("")
|
||
|
require.Nil(t, test4)
|
||
|
}
|
||
|
|
||
|
func TestPath(t *testing.T) {
|
||
|
testPath := New("testdata", "fileset")
|
||
|
pathEqualsTo(t, "testdata/fileset", testPath)
|
||
|
isDir, err := testPath.IsDirCheck()
|
||
|
require.True(t, isDir)
|
||
|
require.NoError(t, err)
|
||
|
require.True(t, testPath.IsDir())
|
||
|
require.False(t, testPath.IsNotDir())
|
||
|
exist, err := testPath.ExistCheck()
|
||
|
require.True(t, exist)
|
||
|
require.NoError(t, err)
|
||
|
require.True(t, testPath.Exist())
|
||
|
require.False(t, testPath.NotExist())
|
||
|
|
||
|
folderPath := testPath.Join("folder")
|
||
|
pathEqualsTo(t, "testdata/fileset/folder", folderPath)
|
||
|
isDir, err = folderPath.IsDirCheck()
|
||
|
require.True(t, isDir)
|
||
|
require.NoError(t, err)
|
||
|
require.True(t, folderPath.IsDir())
|
||
|
require.False(t, folderPath.IsNotDir())
|
||
|
|
||
|
exist, err = folderPath.ExistCheck()
|
||
|
require.True(t, exist)
|
||
|
require.NoError(t, err)
|
||
|
require.True(t, folderPath.Exist())
|
||
|
require.False(t, folderPath.NotExist())
|
||
|
|
||
|
filePath := testPath.Join("file")
|
||
|
pathEqualsTo(t, "testdata/fileset/file", filePath)
|
||
|
isDir, err = filePath.IsDirCheck()
|
||
|
require.False(t, isDir)
|
||
|
require.NoError(t, err)
|
||
|
require.False(t, filePath.IsDir())
|
||
|
require.True(t, filePath.IsNotDir())
|
||
|
exist, err = filePath.ExistCheck()
|
||
|
require.True(t, exist)
|
||
|
require.NoError(t, err)
|
||
|
require.True(t, filePath.Exist())
|
||
|
require.False(t, filePath.NotExist())
|
||
|
|
||
|
anotherFilePath := filePath.Join("notexistent")
|
||
|
pathEqualsTo(t, "testdata/fileset/file/notexistent", anotherFilePath)
|
||
|
isDir, err = anotherFilePath.IsDirCheck()
|
||
|
require.False(t, isDir)
|
||
|
require.Error(t, err)
|
||
|
require.False(t, anotherFilePath.IsDir())
|
||
|
require.False(t, anotherFilePath.IsNotDir())
|
||
|
exist, err = anotherFilePath.ExistCheck()
|
||
|
require.False(t, exist)
|
||
|
require.NoError(t, err)
|
||
|
require.False(t, anotherFilePath.Exist())
|
||
|
require.True(t, anotherFilePath.NotExist())
|
||
|
|
||
|
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])
|
||
|
|
||
|
list2 := list.Clone()
|
||
|
list2.FilterDirs()
|
||
|
require.Len(t, list2, 1)
|
||
|
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list2[0])
|
||
|
|
||
|
list2 = list.Clone()
|
||
|
list2.FilterOutHiddenFiles()
|
||
|
require.Len(t, list2, 3)
|
||
|
pathEqualsTo(t, "testdata/fileset/folder/file2", list2[0])
|
||
|
pathEqualsTo(t, "testdata/fileset/folder/file3", list2[1])
|
||
|
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list2[2])
|
||
|
|
||
|
list2 = list.Clone()
|
||
|
list2.FilterOutPrefix("file")
|
||
|
require.Len(t, list2, 2)
|
||
|
pathEqualsTo(t, "testdata/fileset/folder/.hidden", list2[0])
|
||
|
pathEqualsTo(t, "testdata/fileset/folder/subfolder", list2[1])
|
||
|
}
|
||
|
|
||
|
func TestResetStatCacheWhenFollowingSymlink(t *testing.T) {
|
||
|
testdata := New("testdata", "fileset")
|
||
|
files, err := testdata.ReadDir()
|
||
|
require.NoError(t, err)
|
||
|
for _, file := range files {
|
||
|
if file.Base() == "symlinktofolder" {
|
||
|
err = file.FollowSymLink()
|
||
|
require.NoError(t, err)
|
||
|
isDir, err := file.IsDirCheck()
|
||
|
require.NoError(t, err)
|
||
|
require.True(t, isDir)
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestIsInsideDir(t *testing.T) {
|
||
|
notInside := func(a, b *Path) {
|
||
|
isInside, err := a.IsInsideDir(b)
|
||
|
require.NoError(t, err)
|
||
|
require.False(t, isInside, "%s is inside %s", a, b)
|
||
|
}
|
||
|
|
||
|
inside := func(a, b *Path) {
|
||
|
isInside, err := a.IsInsideDir(b)
|
||
|
require.NoError(t, err)
|
||
|
require.True(t, isInside, "%s is inside %s", a, b)
|
||
|
notInside(b, a)
|
||
|
}
|
||
|
|
||
|
f1 := New("/a/b/c")
|
||
|
f2 := New("/a/b/c/d")
|
||
|
f3 := New("/a/b/c/d/e")
|
||
|
|
||
|
notInside(f1, f1)
|
||
|
notInside(f1, f2)
|
||
|
inside(f2, f1)
|
||
|
notInside(f1, f3)
|
||
|
inside(f3, f1)
|
||
|
|
||
|
r1 := New("a/b/c")
|
||
|
r2 := New("a/b/c/d")
|
||
|
r3 := New("a/b/c/d/e")
|
||
|
r4 := New("f/../a/b/c/d/e")
|
||
|
r5 := New("a/b/c/d/e/f/..")
|
||
|
|
||
|
notInside(r1, r1)
|
||
|
notInside(r1, r2)
|
||
|
inside(r2, r1)
|
||
|
notInside(r1, r3)
|
||
|
inside(r3, r1)
|
||
|
inside(r4, r1)
|
||
|
notInside(r1, r4)
|
||
|
inside(r5, r1)
|
||
|
notInside(r1, r5)
|
||
|
|
||
|
f4 := New("/home/megabug/aide/arduino-1.8.6/hardware/arduino/avr")
|
||
|
f5 := New("/home/megabug/a15/packages")
|
||
|
notInside(f5, f4)
|
||
|
notInside(f4, f5)
|
||
|
|
||
|
if runtime.GOOS == "windows" {
|
||
|
f6 := New("C:\\", "A")
|
||
|
f7 := New("C:\\", "A", "B", "C")
|
||
|
f8 := New("E:\\", "A", "B", "C")
|
||
|
inside(f7, f6)
|
||
|
notInside(f8, f6)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestReadFileAsLines(t *testing.T) {
|
||
|
lines, err := New("testdata/fileset/anotherFile").ReadFileAsLines()
|
||
|
require.NoError(t, err)
|
||
|
require.Len(t, lines, 4)
|
||
|
require.Equal(t, "line 1", lines[0])
|
||
|
require.Equal(t, "line 2", lines[1])
|
||
|
require.Equal(t, "", lines[2])
|
||
|
require.Equal(t, "line 3", lines[3])
|
||
|
}
|
||
|
|
||
|
func TestCanonicaTempDir(t *testing.T) {
|
||
|
require.Equal(t, TempDir().String(), TempDir().Canonical().String())
|
||
|
}
|
||
|
|
||
|
func TestCopyDir(t *testing.T) {
|
||
|
tmp, err := MkTempDir("", "")
|
||
|
require.NoError(t, err)
|
||
|
defer tmp.RemoveAll()
|
||
|
|
||
|
src := New("testdata", "fileset")
|
||
|
err = src.CopyDirTo(tmp.Join("dest"))
|
||
|
require.NoError(t, err, "copying dir")
|
||
|
|
||
|
exist, err := tmp.Join("dest", "folder", "subfolder", "file4").ExistCheck()
|
||
|
require.True(t, exist)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
isdir, err := tmp.Join("dest", "folder", "subfolder", "file4").IsDirCheck()
|
||
|
require.False(t, isdir)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
err = src.CopyDirTo(tmp.Join("dest"))
|
||
|
require.Error(t, err, "copying dir to already existing")
|
||
|
|
||
|
err = src.Join("file").CopyDirTo(tmp.Join("dest2"))
|
||
|
require.Error(t, err, "copying file as dir")
|
||
|
}
|
||
|
|
||
|
func TestParents(t *testing.T) {
|
||
|
parents := New("/a/very/long/path").Parents()
|
||
|
require.Len(t, parents, 5)
|
||
|
pathEqualsTo(t, "/a/very/long/path", parents[0])
|
||
|
pathEqualsTo(t, "/a/very/long", parents[1])
|
||
|
pathEqualsTo(t, "/a/very", parents[2])
|
||
|
pathEqualsTo(t, "/a", parents[3])
|
||
|
pathEqualsTo(t, "/", parents[4])
|
||
|
|
||
|
parents2 := New("a/very/relative/path").Parents()
|
||
|
require.Len(t, parents, 5)
|
||
|
pathEqualsTo(t, "a/very/relative/path", parents2[0])
|
||
|
pathEqualsTo(t, "a/very/relative", parents2[1])
|
||
|
pathEqualsTo(t, "a/very", parents2[2])
|
||
|
pathEqualsTo(t, "a", parents2[3])
|
||
|
pathEqualsTo(t, ".", parents2[4])
|
||
|
}
|
||
|
|
||
|
func TestFilterDirs(t *testing.T) {
|
||
|
testPath := New("testdata", "fileset")
|
||
|
|
||
|
list, err := testPath.ReadDir()
|
||
|
require.NoError(t, err)
|
||
|
require.Len(t, list, 6)
|
||
|
|
||
|
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/symlinktofolder", list[3])
|
||
|
pathEqualsTo(t, "testdata/fileset/test.txt", list[4])
|
||
|
pathEqualsTo(t, "testdata/fileset/test.txt.gz", list[5])
|
||
|
|
||
|
list.FilterDirs()
|
||
|
require.Len(t, list, 2)
|
||
|
pathEqualsTo(t, "testdata/fileset/folder", list[0])
|
||
|
pathEqualsTo(t, "testdata/fileset/symlinktofolder", list[1])
|
||
|
}
|
||
|
|
||
|
func TestFilterOutDirs(t *testing.T) {
|
||
|
{
|
||
|
testPath := New("testdata", "fileset")
|
||
|
|
||
|
list, err := testPath.ReadDir()
|
||
|
require.NoError(t, err)
|
||
|
require.Len(t, list, 6)
|
||
|
|
||
|
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/symlinktofolder", list[3])
|
||
|
pathEqualsTo(t, "testdata/fileset/test.txt", list[4])
|
||
|
pathEqualsTo(t, "testdata/fileset/test.txt.gz", list[5])
|
||
|
|
||
|
list.FilterOutDirs()
|
||
|
require.Len(t, list, 4)
|
||
|
pathEqualsTo(t, "testdata/fileset/anotherFile", list[0])
|
||
|
pathEqualsTo(t, "testdata/fileset/file", list[1])
|
||
|
pathEqualsTo(t, "testdata/fileset/test.txt", list[2])
|
||
|
pathEqualsTo(t, "testdata/fileset/test.txt.gz", list[3])
|
||
|
}
|
||
|
|
||
|
{
|
||
|
list, err := New("testdata", "broken_symlink", "dir_1").ReadDirRecursive()
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
require.Len(t, list, 7)
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/broken_link", list[0])
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/file2", list[1])
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/linked_dir", list[2])
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/linked_dir/file1", list[3])
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/linked_file", list[4])
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/real_dir", list[5])
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/real_dir/file1", list[6])
|
||
|
|
||
|
list.FilterOutDirs()
|
||
|
require.Len(t, list, 5)
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/broken_link", list[0])
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/file2", list[1])
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/linked_dir/file1", list[2])
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/linked_file", list[3])
|
||
|
pathEqualsTo(t, "testdata/broken_symlink/dir_1/real_dir/file1", list[4])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestEquivalentPaths(t *testing.T) {
|
||
|
wd, err := Getwd()
|
||
|
require.NoError(t, err)
|
||
|
require.True(t, New("file1").EquivalentTo(New("file1", "somethingelse", "..")))
|
||
|
require.True(t, New("file1", "abc").EquivalentTo(New("file1", "abc", "def", "..")))
|
||
|
require.True(t, wd.Join("file1").EquivalentTo(New("file1")))
|
||
|
require.True(t, wd.Join("file1").EquivalentTo(New("file1", "abc", "..")))
|
||
|
|
||
|
if runtime.GOOS == "windows" {
|
||
|
q := New("testdata", "fileset", "anotherFile")
|
||
|
r := New("testdata", "fileset", "ANOTHE~1")
|
||
|
require.True(t, q.EquivalentTo(r))
|
||
|
require.True(t, r.EquivalentTo(q))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestCanonicalize(t *testing.T) {
|
||
|
wd, err := Getwd()
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
p := New("testdata", "fileset", "anotherFile").Canonical()
|
||
|
require.Equal(t, wd.Join("testdata", "fileset", "anotherFile").String(), p.String())
|
||
|
|
||
|
p = New("testdata", "fileset", "nonexistentFile").Canonical()
|
||
|
require.Equal(t, wd.Join("testdata", "fileset", "nonexistentFile").String(), p.String())
|
||
|
|
||
|
if runtime.GOOS == "windows" {
|
||
|
q := New("testdata", "fileset", "ANOTHE~1").Canonical()
|
||
|
require.Equal(t, wd.Join("testdata", "fileset", "anotherFile").String(), q.String())
|
||
|
|
||
|
r := New("c:\\").Canonical()
|
||
|
require.Equal(t, "C:\\", r.String())
|
||
|
|
||
|
tmp, err := MkTempDir("", "pref")
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, tmp.String(), tmp.Canonical().String())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestRelativeTo(t *testing.T) {
|
||
|
res, err := New("/my/abs/path/123/456").RelTo(New("/my/abs/path"))
|
||
|
require.NoError(t, err)
|
||
|
pathEqualsTo(t, "../..", res)
|
||
|
|
||
|
res, err = New("/my/abs/path").RelTo(New("/my/abs/path/123/456"))
|
||
|
require.NoError(t, err)
|
||
|
pathEqualsTo(t, "123/456", res)
|
||
|
|
||
|
res, err = New("my/path").RelTo(New("/other/path"))
|
||
|
require.Error(t, err)
|
||
|
require.Nil(t, res)
|
||
|
|
||
|
res, err = New("/my/abs/path/123/456").RelFrom(New("/my/abs/path"))
|
||
|
pathEqualsTo(t, "123/456", res)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
res, err = New("/my/abs/path").RelFrom(New("/my/abs/path/123/456"))
|
||
|
require.NoError(t, err)
|
||
|
pathEqualsTo(t, "../..", res)
|
||
|
|
||
|
res, err = New("my/path").RelFrom(New("/other/path"))
|
||
|
require.Error(t, err)
|
||
|
require.Nil(t, res)
|
||
|
}
|
||
|
|
||
|
func TestWriteToTempFile(t *testing.T) {
|
||
|
tmpDir := New("testdata", "fileset", "tmp")
|
||
|
err := tmpDir.MkdirAll()
|
||
|
require.NoError(t, err)
|
||
|
defer tmpDir.RemoveAll()
|
||
|
|
||
|
tmpData := []byte("test")
|
||
|
tmp, err := WriteToTempFile(tmpData, tmpDir, "prefix")
|
||
|
defer tmp.Remove()
|
||
|
require.NoError(t, err)
|
||
|
require.True(t, strings.HasPrefix(tmp.Base(), "prefix"))
|
||
|
isInside, err := tmp.IsInsideDir(tmpDir)
|
||
|
require.NoError(t, err)
|
||
|
require.True(t, isInside)
|
||
|
data, err := tmp.ReadFile()
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, tmpData, data)
|
||
|
}
|
||
|
|
||
|
func TestCopyToSamePath(t *testing.T) {
|
||
|
tmpDir := New(t.TempDir())
|
||
|
srcFile := tmpDir.Join("test_file")
|
||
|
dstFile := srcFile
|
||
|
|
||
|
// create the source file in tmp dir
|
||
|
err := srcFile.WriteFile([]byte("hello"))
|
||
|
require.NoError(t, err)
|
||
|
content, err := srcFile.ReadFile()
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, []byte("hello"), content)
|
||
|
|
||
|
// cannot copy the same file
|
||
|
err = srcFile.CopyTo(dstFile)
|
||
|
require.Error(t, err)
|
||
|
require.Contains(t, err.Error(), "are the same file")
|
||
|
}
|