apparmor.d/pkg/paths/paths_test.go
2024-04-28 00:30:59 +01:00

432 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")
}