207 lines
6.3 KiB
Go
207 lines
6.3 KiB
Go
package utils
|
|
|
|
import (
|
|
"archive/tar"
|
|
"bytes"
|
|
"compress/gzip"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func createTestTarGz(t *testing.T, files map[string]string, modifyHeader func(hdr *tar.Header)) io.Reader {
|
|
t.Helper()
|
|
var buf bytes.Buffer
|
|
gzw := gzip.NewWriter(&buf)
|
|
tw := tar.NewWriter(gzw)
|
|
|
|
for name, content := range files {
|
|
hdr := &tar.Header{
|
|
Name: name,
|
|
Mode: 0644,
|
|
Size: int64(len(content)),
|
|
}
|
|
if modifyHeader != nil {
|
|
modifyHeader(hdr)
|
|
}
|
|
if err := tw.WriteHeader(hdr); err != nil {
|
|
t.Fatalf("Failed to write tar header for %s: %v", name, err)
|
|
}
|
|
if _, err := tw.Write([]byte(content)); err != nil {
|
|
t.Fatalf("Failed to write tar content for %s: %v", name, err)
|
|
}
|
|
}
|
|
|
|
if err := tw.Close(); err != nil {
|
|
t.Fatalf("Failed to close tar writer: %v", err)
|
|
}
|
|
if err := gzw.Close(); err != nil {
|
|
t.Fatalf("Failed to close gzip writer: %v", err)
|
|
}
|
|
return &buf
|
|
}
|
|
|
|
func TestUntarQuadlets_Valid(t *testing.T) {
|
|
inputFiles := map[string]string{
|
|
"workload.kat": "kind: Workload",
|
|
"vlb.kat": "kind: VirtualLoadBalancer",
|
|
}
|
|
reader := createTestTarGz(t, inputFiles, nil)
|
|
|
|
outputFiles, err := UntarQuadlets(reader)
|
|
if err != nil {
|
|
t.Fatalf("UntarQuadlets() error = %v, wantErr %v", err, false)
|
|
}
|
|
|
|
if len(outputFiles) != len(inputFiles) {
|
|
t.Errorf("Expected %d files, got %d", len(inputFiles), len(outputFiles))
|
|
}
|
|
for name, content := range inputFiles {
|
|
outContent, ok := outputFiles[name]
|
|
if !ok {
|
|
t.Errorf("Expected file %s not found in output", name)
|
|
}
|
|
if string(outContent) != content {
|
|
t.Errorf("Content mismatch for %s: got '%s', want '%s'", name, string(outContent), content)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUntarQuadlets_EmptyArchive(t *testing.T) {
|
|
reader := createTestTarGz(t, map[string]string{}, nil)
|
|
_, err := UntarQuadlets(reader)
|
|
if err == nil {
|
|
t.Fatal("UntarQuadlets() with empty archive did not return an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "no .kat files found") {
|
|
t.Errorf("Expected 'no .kat files found' error, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUntarQuadlets_NonKatFile(t *testing.T) {
|
|
inputFiles := map[string]string{"config.txt": "some data"}
|
|
reader := createTestTarGz(t, inputFiles, nil)
|
|
_, err := UntarQuadlets(reader)
|
|
if err == nil {
|
|
t.Fatal("UntarQuadlets() with non-.kat file did not return an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "only .kat files are allowed") {
|
|
t.Errorf("Expected 'only .kat files are allowed' error, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUntarQuadlets_FileInSubdirectory(t *testing.T) {
|
|
inputFiles := map[string]string{"subdir/workload.kat": "kind: Workload"}
|
|
reader := createTestTarGz(t, inputFiles, nil)
|
|
_, err := UntarQuadlets(reader)
|
|
if err == nil {
|
|
t.Fatal("UntarQuadlets() with file in subdirectory did not return an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "subdirectories are not allowed") {
|
|
t.Errorf("Expected 'subdirectories are not allowed' error, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUntarQuadlets_PathTraversal(t *testing.T) {
|
|
inputFiles := map[string]string{"../workload.kat": "kind: Workload"}
|
|
reader := createTestTarGz(t, inputFiles, nil)
|
|
_, err := UntarQuadlets(reader)
|
|
if err == nil {
|
|
t.Fatal("UntarQuadlets() with path traversal did not return an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "contains '..'") {
|
|
t.Errorf("Expected 'contains ..' error, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUntarQuadlets_FileTooLarge(t *testing.T) {
|
|
largeContent := strings.Repeat("a", int(maxQuadletFileSize)+1)
|
|
inputFiles := map[string]string{"large.kat": largeContent}
|
|
reader := createTestTarGz(t, inputFiles, nil)
|
|
_, err := UntarQuadlets(reader)
|
|
if err == nil {
|
|
t.Fatal("UntarQuadlets() with large file did not return an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "file large.kat in tar is too large") {
|
|
t.Errorf("Expected 'file ... too large' error, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUntarQuadlets_TotalSizeTooLarge(t *testing.T) {
|
|
numFiles := (maxTotalQuadletSize / maxQuadletFileSize) + 2
|
|
fileSize := maxQuadletFileSize / 2
|
|
|
|
inputFiles := make(map[string]string)
|
|
content := strings.Repeat("a", int(fileSize))
|
|
for i := 0; i < int(numFiles); i++ {
|
|
inputFiles[filepath.Join(".", "file"+string(rune(i+'0'))+".kat")] = content
|
|
}
|
|
|
|
reader := createTestTarGz(t, inputFiles, nil)
|
|
_, err := UntarQuadlets(reader)
|
|
if err == nil {
|
|
t.Fatal("UntarQuadlets() with total large size did not return an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "total size of files in tar is too large") {
|
|
t.Errorf("Expected 'total size ... too large' error, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUntarQuadlets_TooManyFiles(t *testing.T) {
|
|
inputFiles := make(map[string]string)
|
|
for i := 0; i <= maxQuadletFiles; i++ {
|
|
inputFiles[filepath.Join(".", "file"+string(rune(i+'a'))+".kat")] = "content"
|
|
}
|
|
reader := createTestTarGz(t, inputFiles, nil)
|
|
_, err := UntarQuadlets(reader)
|
|
if err == nil {
|
|
t.Fatal("UntarQuadlets() with too many files did not return an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "too many files in quadlet bundle") {
|
|
t.Errorf("Expected 'too many files' error, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUntarQuadlets_UnsupportedFileType(t *testing.T) {
|
|
reader := createTestTarGz(t, map[string]string{"link.kat": ""}, func(hdr *tar.Header) {
|
|
hdr.Typeflag = tar.TypeSymlink
|
|
hdr.Linkname = "target.kat"
|
|
hdr.Size = 0
|
|
})
|
|
_, err := UntarQuadlets(reader)
|
|
if err == nil {
|
|
t.Fatal("UntarQuadlets() with symlink did not return an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "unsupported file type") {
|
|
t.Errorf("Expected 'unsupported file type' error, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUntarQuadlets_CorruptedGzip(t *testing.T) {
|
|
corruptedInput := bytes.NewBufferString("this is not a valid gzip stream")
|
|
_, err := UntarQuadlets(corruptedInput)
|
|
if err == nil {
|
|
t.Fatal("UntarQuadlets() with corrupted gzip did not return an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "failed to create gzip reader") && !strings.Contains(err.Error(), "gzip: invalid header") {
|
|
t.Errorf("Expected 'gzip format' or 'invalid header' error, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUntarQuadlets_CorruptedTar(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
gzw := gzip.NewWriter(&buf)
|
|
_, _ = gzw.Write([]byte("this is not a valid tar stream but inside gzip"))
|
|
_ = gzw.Close()
|
|
|
|
_, err := UntarQuadlets(&buf)
|
|
if err == nil {
|
|
t.Fatal("UntarQuadlets() with corrupted tar did not return an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "tar") {
|
|
t.Errorf("Expected error related to 'tar' format, got: %v", err)
|
|
}
|
|
}
|