Files
zot/pkg/test/common/fs_test.go
T
Andrei Aaron 9dfa7c3ae6 refactor(test): new apis for creating temporary files (#3605)
Replace MakeTempFile usage with MakeTempFilePath and MakeTempFileWithContent
helpers that automatically handle file lifecycle. This prevents resource
leaks by ensuring temporary files are properly closed.

Shoudld also make the tests easier to read.

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2025-12-05 09:54:38 +02:00

284 lines
7.0 KiB
Go

package common_test
import (
"encoding/json"
"errors"
"os"
"path"
"path/filepath"
"testing"
"time"
ispec "github.com/opencontainers/image-spec/specs-go/v1"
. "github.com/smartystreets/goconvey/convey"
"golang.org/x/crypto/bcrypt"
tcommon "zotregistry.dev/zot/v2/pkg/test/common"
)
var ErrTestError = errors.New("ErrTestError")
func TestCopyFiles(t *testing.T) {
Convey("sourceDir does not exist", t, func() {
err := tcommon.CopyFiles("/path/to/some/unexisting/directory", t.TempDir())
So(err, ShouldNotBeNil)
})
Convey("destDir is a file", t, func() {
dir := t.TempDir()
err := tcommon.CopyFiles("../../../test/data", dir)
So(err, ShouldBeNil)
err = tcommon.CopyFiles(dir, "/etc/passwd")
So(err, ShouldNotBeNil)
})
Convey("sourceDir does not have read permissions", t, func() {
dir := t.TempDir()
err := os.Chmod(dir, 0o300)
So(err, ShouldBeNil)
err = tcommon.CopyFiles(dir, t.TempDir())
So(err, ShouldNotBeNil)
})
Convey("sourceDir has a subfolder that does not have read permissions", t, func() {
dir := t.TempDir()
sdir := "subdir"
err := os.Mkdir(path.Join(dir, sdir), 0o300)
So(err, ShouldBeNil)
err = tcommon.CopyFiles(dir, t.TempDir())
So(err, ShouldNotBeNil)
})
Convey("sourceDir has a file that does not have read permissions", t, func() {
dir := t.TempDir()
filePath := path.Join(dir, "file.txt")
err := os.WriteFile(filePath, []byte("some dummy file content"), 0o644) //nolint: gosec
if err != nil {
panic(err)
}
err = os.Chmod(filePath, 0o300)
So(err, ShouldBeNil)
err = tcommon.CopyFiles(dir, t.TempDir())
So(err, ShouldNotBeNil)
})
Convey("sourceDir contains a folder starting with invalid characters", t, func() {
srcDir := t.TempDir()
dstDir := t.TempDir()
err := os.MkdirAll(path.Join(srcDir, "_trivy", "db"), 0o755)
if err != nil {
panic(err)
}
err = os.MkdirAll(path.Join(srcDir, "test-index"), 0o755)
if err != nil {
panic(err)
}
filePathTrivy := path.Join(srcDir, "_trivy", "db", "trivy.db")
err = os.WriteFile(filePathTrivy, []byte("some dummy file content"), 0o644) //nolint: gosec
if err != nil {
panic(err)
}
var index ispec.Index
content, err := json.Marshal(index)
if err != nil {
panic(err)
}
err = os.WriteFile(path.Join(srcDir, "test-index", "index.json"), content, 0o644) //nolint: gosec
if err != nil {
panic(err)
}
err = tcommon.CopyFiles(srcDir, dstDir)
So(err, ShouldBeNil)
_, err = os.Stat(path.Join(dstDir, "_trivy", "db", "trivy.db"))
So(err, ShouldNotBeNil)
So(os.IsNotExist(err), ShouldBeTrue)
_, err = os.Stat(path.Join(dstDir, "test-index", "index.json"))
So(err, ShouldBeNil)
})
}
func TestCopyFile(t *testing.T) {
Convey("destFilePath does not exist", t, func() {
err := tcommon.CopyFile("/path/to/srcFile", "~/path/to/some/unexisting/destDir/file")
So(err, ShouldNotBeNil)
})
Convey("sourceFile does not exist", t, func() {
err := tcommon.CopyFile("/path/to/some/unexisting/file", path.Join(t.TempDir(), "destFile.txt"))
So(err, ShouldNotBeNil)
})
}
func TestReadLogFileAndSearchString(t *testing.T) {
logPath := tcommon.MakeTempFilePath(t, "zot-log.txt")
Convey("Invalid path", t, func() {
_, err := tcommon.ReadLogFileAndSearchString("invalidPath",
"cve-db update completed, next update scheduled after interval", 1*time.Second)
So(err, ShouldNotBeNil)
})
Convey("Time too short", t, func() {
// Create an empty file so ReadLogFileAndSearchString can read it
file, err := os.Create(logPath)
if err != nil {
panic(err)
}
file.Close()
ok, err := tcommon.ReadLogFileAndSearchString(logPath, "invalid string", time.Microsecond)
So(err, ShouldBeNil)
So(ok, ShouldBeFalse)
})
}
func TestReadLogFileAndCountStringOccurence(t *testing.T) {
logFile := tcommon.MakeTempFile(t, "zot-log.txt")
defer logFile.Close()
_, err := logFile.WriteString("line1\n line2\n line3 line1 line2\n line1")
if err != nil {
panic(err)
}
logPath := logFile.Name()
Convey("Invalid path", t, func() {
_, err = tcommon.ReadLogFileAndCountStringOccurence("invalidPath",
"cve-db update completed, next update scheduled after interval", 1*time.Second, 1)
So(err, ShouldNotBeNil)
})
Convey("Time too short", t, func() {
ok, err := tcommon.ReadLogFileAndCountStringOccurence(logPath, "invalid string", time.Microsecond, 1)
So(err, ShouldBeNil)
So(ok, ShouldBeFalse)
})
Convey("Count occurrence working", t, func() {
ok, err := tcommon.ReadLogFileAndCountStringOccurence(logPath, "line1", 90*time.Second, 3)
So(err, ShouldBeNil)
So(ok, ShouldBeTrue)
})
}
func TestCopyTestKeysAndCerts(t *testing.T) {
Convey("CopyTestKeysAndCerts", t, func() {
// ------- Make test files unreadable -------
dir := t.TempDir()
file := filepath.Join(dir, "ca.crt")
_, err := os.Create(file)
So(err, ShouldBeNil)
err = os.Chmod(file, 0o000)
So(err, ShouldBeNil)
err = tcommon.CopyTestKeysAndCerts(dir)
So(err, ShouldNotBeNil)
err = os.Chmod(file, 0o777)
So(err, ShouldBeNil)
// ------- Copy fails -------
err = os.Chmod(dir, 0o000)
So(err, ShouldBeNil)
err = tcommon.CopyTestKeysAndCerts(file)
So(err, ShouldNotBeNil)
err = os.Chmod(dir, 0o777)
So(err, ShouldBeNil)
// ------- Folder creation fails -------
file = filepath.Join(dir, "a-file.file")
_, err = os.Create(file)
So(err, ShouldBeNil)
_, err = os.Stat(file)
So(err, ShouldBeNil)
err = tcommon.CopyTestKeysAndCerts(file)
So(err, ShouldNotBeNil)
// ----- /test/data doesn't exist ------
workDir, err := os.Getwd()
So(err, ShouldBeNil)
defer func() { _ = os.Chdir(workDir) }()
dir = t.TempDir()
file = filepath.Join(dir, "go.mod")
_, err = os.Create(file)
So(err, ShouldBeNil)
_, err = os.Stat(file)
So(err, ShouldBeNil)
err = os.Chdir(dir)
So(err, ShouldBeNil)
err = tcommon.CopyTestKeysAndCerts(dir)
So(err, ShouldNotBeNil)
So(err.Error(), ShouldContainSubstring, "CopyFiles os.Stat failed")
// --- GetProjectRootDir call fails -----
tempDir := t.TempDir()
err = os.Chdir(tempDir)
So(err, ShouldBeNil)
err = tcommon.CopyTestKeysAndCerts(tempDir)
So(err, ShouldNotBeNil)
So(err, ShouldEqual, tcommon.ErrNoGoModFileFound)
})
}
func TestGetProjectRootDir(t *testing.T) {
Convey("GetProjectRootDir", t, func() {
path, err := tcommon.GetProjectRootDir()
So(err, ShouldBeNil)
So(len(path), ShouldBeGreaterThan, 0)
})
Convey("GetProjectRootDir negative testing", t, func() {
workDir, err := os.Getwd()
So(err, ShouldBeNil)
defer func() { _ = os.Chdir(workDir) }()
tempDir := t.TempDir()
err = os.Chdir(tempDir)
So(err, ShouldBeNil)
path, err := tcommon.GetProjectRootDir()
So(err, ShouldNotBeNil)
So(err, ShouldEqual, tcommon.ErrNoGoModFileFound)
So(path, ShouldBeZeroValue)
})
}
func TestGetBcryptCredString(t *testing.T) {
Convey("GetBcryptCredString panics", t, func() {
passwordSize := 100
pass := make([]byte, passwordSize)
for i := range passwordSize {
pass[i] = 'Y'
}
f := func() { tcommon.GetBcryptCredString("testUser", string(pass)) }
So(f, ShouldPanicWith, bcrypt.ErrPasswordTooLong)
})
}