Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add tests for cache pkg
  • Loading branch information
Kai Kummerer committed May 15, 2024
commit c7e29d01971218ee0f8e7834e81172960bb1798c
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.22

require (
github.com/goccy/go-yaml v1.11.3
github.com/adrg/xdg v0.4.0
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.6.0
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
github.com/alessio/shellescape v1.4.2 h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4uEoM0=
github.com/alessio/shellescape v1.4.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
Expand Down Expand Up @@ -161,6 +163,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
Expand Down Expand Up @@ -198,6 +201,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
Expand Down
44 changes: 10 additions & 34 deletions internal/pkg/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,74 +4,50 @@ import (
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
)

const (
cacheFolder = ".stackit/cache"
"github.com/adrg/xdg"
)

var ErrorInvalidCacheIdentifier = fmt.Errorf("invalid cache identifier")
var (
cacheFolderPath = xdg.CacheHome + "/stackit"

var identifierRegex = regexp.MustCompile("^[a-zA-Z0-9-]+$")
identifierRegex = regexp.MustCompile("^[a-zA-Z0-9-]+$")
ErrorInvalidCacheIdentifier = fmt.Errorf("invalid cache identifier")
)

func GetObject(identifier string) ([]byte, error) {
if !identifierRegex.MatchString(identifier) {
return nil, ErrorInvalidCacheIdentifier
}

cacheFolderPath, err := getCacheFolderPath()
if err != nil {
return nil, err
}

return os.ReadFile(cacheFolderPath + "/" + identifier + ".txt")
return os.ReadFile(cacheFolderPath + "/" + identifier)
}

func PutObject(identifier string, data []byte) error {
if !identifierRegex.MatchString(identifier) {
return ErrorInvalidCacheIdentifier
}

cacheFolderPath, err := getCacheFolderPath()
if err != nil {
return err
}

err = createFolderIfNotExists(cacheFolderPath)
err := createFolderIfNotExists(cacheFolderPath)
if err != nil {
return err
}

return os.WriteFile(cacheFolderPath+"/"+identifier+".txt", data, 0o600)
return os.WriteFile(cacheFolderPath+"/"+identifier, data, 0o600)
}

func DeleteObject(identifier string) error {
if !identifierRegex.MatchString(identifier) {
return ErrorInvalidCacheIdentifier
}

cacheFolderPath, err := getCacheFolderPath()
if err != nil {
return err
}

if err = os.Remove(cacheFolderPath + "/" + identifier + ".txt"); !errors.Is(err, os.ErrNotExist) {
if err := os.Remove(cacheFolderPath + "/" + identifier); !errors.Is(err, os.ErrNotExist) {
return err
}
return nil
}

func getCacheFolderPath() (string, error) {
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
configFolderPath := filepath.Join(home, cacheFolder)
return configFolderPath, nil
}

func createFolderIfNotExists(folderPath string) error {
_, err := os.Stat(folderPath)
if os.IsNotExist(err) {
Expand Down
195 changes: 195 additions & 0 deletions internal/pkg/cache/cache_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package cache

import (
"errors"
"os"
"testing"

"github.com/adrg/xdg"
"github.com/google/uuid"
)

func TestGetObject(t *testing.T) {
tests := []struct {
description string
identifier string
expectFile bool
expectedErr error
}{
{
description: "identifier exists",
identifier: "test-cache-get-exists",
expectFile: true,
expectedErr: nil,
},
{
description: "identifier does not exist",
identifier: "test-cache-get-not-exists",
expectFile: false,
expectedErr: os.ErrNotExist,
},
{
description: "identifier is invalid",
identifier: "in../../valid",
expectFile: false,
expectedErr: ErrorInvalidCacheIdentifier,
},
}

for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
id := tt.identifier + "-" + uuid.NewString()

// setup
if tt.expectFile {
err := createFolderIfNotExists(cacheFolderPath)
if err != nil {
t.Fatalf("create cache folder: %s", err.Error())
}
path := cacheFolderPath + "/" + id
if err := os.WriteFile(path, []byte("dummy"), 0o600); err != nil {
t.Fatalf("setup: WriteFile (%s) failed", path)
}
}
// test
file, err := GetObject(id)

if !errors.Is(err, tt.expectedErr) {
t.Fatalf("returned error (%q) does not match %q", err.Error(), tt.expectedErr.Error())
}

if tt.expectFile {
if len(file) < 1 {
t.Fatalf("expected a file but byte array is empty (len %d)", len(file))
}
} else {
if len(file) > 0 {
t.Fatalf("didn't expect a file, but byte array is not empty (len %d)", len(file))
}
}
})
}
}
func TestPutObject(t *testing.T) {
// Also test createFolderIfNotExists here
tests := []struct {
description string
identifier string
existingFile bool
expectFile bool
expectedErr error
customPath string
}{
{
description: "identifier already exists",
identifier: "test-cache-put-exists",
existingFile: true,
expectFile: true,
expectedErr: nil,
},
{
description: "identifier does not exist",
identifier: "test-cache-put-not-exists",
expectFile: true,
expectedErr: nil,
},
{
description: "identifier is invalid",
identifier: "in../../valid",
expectFile: false,
expectedErr: ErrorInvalidCacheIdentifier,
},
{
description: "directory does not yet exist",
identifier: "test-cache-put-folder-not-exists",
expectFile: true,
expectedErr: nil,
customPath: "/tmp/stackit-cli-test",
},
}

for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
id := tt.identifier + "-" + uuid.NewString()
if tt.customPath != "" {
cacheFolderPath = tt.customPath
} else {
cacheFolderPath = xdg.CacheHome
}
path := cacheFolderPath + "/" + id

// setup
if tt.existingFile {
if err := os.WriteFile(path, []byte("dummy"), 0o600); err != nil {
t.Fatalf("setup: WriteFile (%s) failed", path)
}
}
// test
err := PutObject(id, []byte("dummy"))

if !errors.Is(err, tt.expectedErr) {
t.Fatalf("returned error (%q) does not match %q", err.Error(), tt.expectedErr.Error())
}

if tt.expectFile {
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
t.Fatalf("expected file (%q) to exist", path)
}
}
})
}
}

func TestDeleteObject(t *testing.T) {
tests := []struct {
description string
identifier string
existingFile bool
expectedErr error
}{
{
description: "identifier exists",
identifier: "test-cache-delete-exists",
existingFile: true,
expectedErr: nil,
},
{
description: "identifier does not exist",
identifier: "test-cache-delete-not-exists",
existingFile: false,
expectedErr: nil,
},
{
description: "identifier is invalid",
identifier: "in../../valid",
existingFile: false,
expectedErr: ErrorInvalidCacheIdentifier,
},
}

for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
id := tt.identifier + "-" + uuid.NewString()
path := cacheFolderPath + "/" + id

// setup
if tt.existingFile {
if err := os.WriteFile(path, []byte("dummy"), 0o600); err != nil {
t.Fatalf("setup: WriteFile (%s) failed", path)
}
}
// test
err := DeleteObject(id)

if !errors.Is(err, tt.expectedErr) {
t.Fatalf("returned error (%q) does not match %q", err.Error(), tt.expectedErr.Error())
}

if tt.existingFile {
if _, err := os.Stat(path); !errors.Is(err, os.ErrNotExist) {
t.Fatalf("expected file (%q) to not exist", path)
}
}
})
}
}