mirror of
https://github.com/project-zot/zot.git
synced 2026-06-17 21:17:58 +08:00
9dfa7c3ae6
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>
284 lines
7.0 KiB
Go
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)
|
|
})
|
|
}
|