forked from mirrors/pkg-proxy
* Fix all golangci-lint issues across the codebase Resolve 77 lint issues reported by golangci-lint with gocritic, gocognit, gocyclo, maintidx, dupl, mnd, unparam, ireturn, goconst, and errcheck enabled. Net reduction of ~175 lines through shared helpers and deduplication. * Suppress staticcheck SA1019 for intentional deprecated field usage The Storage.Path field is deprecated but still read for backwards compatibility with existing configs that haven't migrated to the URL field.
248 lines
5.8 KiB
Go
248 lines
5.8 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestNewFilesystem(t *testing.T) {
|
|
dir := t.TempDir()
|
|
root := filepath.Join(dir, "cache")
|
|
|
|
fs, err := NewFilesystem(root)
|
|
if err != nil {
|
|
t.Fatalf("NewFilesystem failed: %v", err)
|
|
}
|
|
|
|
if _, err := os.Stat(root); err != nil {
|
|
t.Errorf("root directory not created: %v", err)
|
|
}
|
|
|
|
if fs.Root() != root {
|
|
t.Errorf("Root() = %q, want %q", fs.Root(), root)
|
|
}
|
|
}
|
|
|
|
func TestFilesystemStore(t *testing.T) {
|
|
fs := createTestFilesystem(t)
|
|
ctx := context.Background()
|
|
content := "test content for storage"
|
|
|
|
size, hash, err := fs.Store(ctx, "npm/lodash/4.17.21/lodash.tgz", strings.NewReader(content))
|
|
if err != nil {
|
|
t.Fatalf("Store failed: %v", err)
|
|
}
|
|
|
|
if size != int64(len(content)) {
|
|
t.Errorf("size = %d, want %d", size, len(content))
|
|
}
|
|
|
|
h := sha256.Sum256([]byte(content))
|
|
wantHash := hex.EncodeToString(h[:])
|
|
if hash != wantHash {
|
|
t.Errorf("hash = %s, want %s", hash, wantHash)
|
|
}
|
|
|
|
// Verify file exists on disk
|
|
fullPath := fs.FullPath("npm/lodash/4.17.21/lodash.tgz")
|
|
data, err := os.ReadFile(fullPath)
|
|
if err != nil {
|
|
t.Fatalf("reading stored file: %v", err)
|
|
}
|
|
if string(data) != content {
|
|
t.Errorf("stored content = %q, want %q", string(data), content)
|
|
}
|
|
}
|
|
|
|
func TestFilesystemStoreAtomic(t *testing.T) {
|
|
fs := createTestFilesystem(t)
|
|
ctx := context.Background()
|
|
|
|
// Store initial content
|
|
_, _, err := fs.Store(ctx, "test/file.txt", strings.NewReader("initial"))
|
|
if err != nil {
|
|
t.Fatalf("initial Store failed: %v", err)
|
|
}
|
|
|
|
// Overwrite with new content
|
|
_, _, err = fs.Store(ctx, "test/file.txt", strings.NewReader("updated"))
|
|
if err != nil {
|
|
t.Fatalf("update Store failed: %v", err)
|
|
}
|
|
|
|
// Verify updated content
|
|
r, err := fs.Open(ctx, "test/file.txt")
|
|
if err != nil {
|
|
t.Fatalf("Open failed: %v", err)
|
|
}
|
|
defer func() { _ = r.Close() }()
|
|
|
|
data, _ := io.ReadAll(r)
|
|
if string(data) != "updated" {
|
|
t.Errorf("content = %q, want %q", string(data), "updated")
|
|
}
|
|
}
|
|
|
|
func TestFilesystemOpen(t *testing.T) {
|
|
fs := createTestFilesystem(t)
|
|
ctx := context.Background()
|
|
content := "readable content"
|
|
|
|
_, _, _ = fs.Store(ctx, "test/read.txt", strings.NewReader(content))
|
|
|
|
r, err := fs.Open(ctx, "test/read.txt")
|
|
if err != nil {
|
|
t.Fatalf("Open failed: %v", err)
|
|
}
|
|
defer func() { _ = r.Close() }()
|
|
|
|
data, err := io.ReadAll(r)
|
|
if err != nil {
|
|
t.Fatalf("ReadAll failed: %v", err)
|
|
}
|
|
if string(data) != content {
|
|
t.Errorf("content = %q, want %q", string(data), content)
|
|
}
|
|
}
|
|
|
|
func TestFilesystemOpenNotFound(t *testing.T) {
|
|
fs := createTestFilesystem(t)
|
|
ctx := context.Background()
|
|
|
|
_, err := fs.Open(ctx, "does/not/exist.txt")
|
|
if !errors.Is(err, ErrNotFound) {
|
|
t.Errorf("Open non-existent = %v, want ErrNotFound", err)
|
|
}
|
|
}
|
|
|
|
func TestFilesystemExists(t *testing.T) {
|
|
fs := createTestFilesystem(t)
|
|
ctx := context.Background()
|
|
|
|
exists, err := fs.Exists(ctx, "test/exists.txt")
|
|
if err != nil {
|
|
t.Fatalf("Exists failed: %v", err)
|
|
}
|
|
if exists {
|
|
t.Error("Exists returned true for non-existent file")
|
|
}
|
|
|
|
_, _, _ = fs.Store(ctx, "test/exists.txt", strings.NewReader("content"))
|
|
|
|
exists, err = fs.Exists(ctx, "test/exists.txt")
|
|
if err != nil {
|
|
t.Fatalf("Exists after store failed: %v", err)
|
|
}
|
|
if !exists {
|
|
t.Error("Exists returned false for existing file")
|
|
}
|
|
}
|
|
|
|
func TestFilesystemDelete(t *testing.T) {
|
|
fs := createTestFilesystem(t)
|
|
ctx := context.Background()
|
|
|
|
_, _, _ = fs.Store(ctx, "test/delete/nested/file.txt", strings.NewReader("content"))
|
|
|
|
err := fs.Delete(ctx, "test/delete/nested/file.txt")
|
|
if err != nil {
|
|
t.Fatalf("Delete failed: %v", err)
|
|
}
|
|
|
|
exists, _ := fs.Exists(ctx, "test/delete/nested/file.txt")
|
|
if exists {
|
|
t.Error("file still exists after delete")
|
|
}
|
|
|
|
// Empty parent directories should be cleaned up
|
|
nestedDir := fs.FullPath("test/delete/nested")
|
|
if _, err := os.Stat(nestedDir); !os.IsNotExist(err) {
|
|
t.Error("empty nested directory not cleaned up")
|
|
}
|
|
}
|
|
|
|
func TestFilesystemDeleteNotFound(t *testing.T) {
|
|
fs := createTestFilesystem(t)
|
|
ctx := context.Background()
|
|
|
|
// Delete non-existent file should not error
|
|
err := fs.Delete(ctx, "does/not/exist.txt")
|
|
if err != nil {
|
|
t.Errorf("Delete non-existent = %v, want nil", err)
|
|
}
|
|
}
|
|
|
|
func TestFilesystemSize(t *testing.T) {
|
|
fs := createTestFilesystem(t)
|
|
ctx := context.Background()
|
|
content := "size test content"
|
|
|
|
_, _, _ = fs.Store(ctx, "test/size.txt", strings.NewReader(content))
|
|
|
|
size, err := fs.Size(ctx, "test/size.txt")
|
|
if err != nil {
|
|
t.Fatalf("Size failed: %v", err)
|
|
}
|
|
if size != int64(len(content)) {
|
|
t.Errorf("Size = %d, want %d", size, len(content))
|
|
}
|
|
}
|
|
|
|
func TestFilesystemSizeNotFound(t *testing.T) {
|
|
fs := createTestFilesystem(t)
|
|
ctx := context.Background()
|
|
|
|
_, err := fs.Size(ctx, "does/not/exist.txt")
|
|
if !errors.Is(err, ErrNotFound) {
|
|
t.Errorf("Size non-existent = %v, want ErrNotFound", err)
|
|
}
|
|
}
|
|
|
|
func TestFilesystemUsedSpace(t *testing.T) {
|
|
fs := createTestFilesystem(t)
|
|
ctx := context.Background()
|
|
|
|
// Empty storage
|
|
used, err := fs.UsedSpace(ctx)
|
|
if err != nil {
|
|
t.Fatalf("UsedSpace failed: %v", err)
|
|
}
|
|
if used != 0 {
|
|
t.Errorf("UsedSpace empty = %d, want 0", used)
|
|
}
|
|
|
|
// Add some files
|
|
_, _, _ = fs.Store(ctx, "a.txt", strings.NewReader("aaaa")) // 4 bytes
|
|
_, _, _ = fs.Store(ctx, "b.txt", strings.NewReader("bbbbbb")) // 6 bytes
|
|
_, _, _ = fs.Store(ctx, "c/d.txt", strings.NewReader("ccccc")) // 5 bytes
|
|
|
|
used, err = fs.UsedSpace(ctx)
|
|
if err != nil {
|
|
t.Fatalf("UsedSpace failed: %v", err)
|
|
}
|
|
if used != 15 {
|
|
t.Errorf("UsedSpace = %d, want 15", used)
|
|
}
|
|
}
|
|
|
|
func TestFilesystemLargeFile(t *testing.T) {
|
|
assertLargeFileRoundTrip(t, createTestFilesystem(t))
|
|
}
|
|
|
|
func createTestFilesystem(t *testing.T) *Filesystem {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
|
|
fs, err := NewFilesystem(dir)
|
|
if err != nil {
|
|
t.Fatalf("NewFilesystem failed: %v", err)
|
|
}
|
|
return fs
|
|
}
|