feat: add cache manager

This commit is contained in:
Marc 2024-08-30 22:20:56 -04:00
parent c989aba61b
commit 5490bba12f
Signed by: marc
GPG key ID: 048E042F22B5DC79
6 changed files with 101 additions and 8 deletions

43
internal/cache/cache_manager.go vendored Normal file
View file

@ -0,0 +1,43 @@
package cache_manager
import (
"errors"
"os"
"path/filepath"
)
type CacheManager struct {
Root string
}
// Creates a new cache manager rooted at <cacheRoot>.
//
// If <cacheRoot> does not exist, returns an error.
func NewCacheManager(cacheRoot string) (*CacheManager, error) {
if _, err := os.Stat(cacheRoot); errors.Is(err, os.ErrNotExist) {
return nil, errors.New("Cache root must exist.")
}
return &CacheManager{
Root: cacheRoot,
}, nil
}
// Returns a path prefixed with the cache root.
func (c CacheManager) Path(elems ...string) string {
return filepath.Join(c.Root, filepath.Join(elems...))
}
// Checks whether a specific top-level items exists in the cache.
func (c CacheManager) Exists(key string) bool {
if _, err := os.Stat(c.Path(key)); errors.Is(err, os.ErrNotExist) {
return false
}
return true
}
// Deletes an element from the cache, if it exists.
func (c CacheManager) Evict(key string) {
os.RemoveAll(c.Path(key))
}

44
internal/cache/cache_manager_test.go vendored Normal file
View file

@ -0,0 +1,44 @@
package cache_manager
import (
"path/filepath"
"testing"
)
func TestNewCacheManagerFailsIfNonExistentRoot(t *testing.T) {
nonPath := "/not/a/path"
mgr, err := NewCacheManager(nonPath)
if err == nil {
t.Error("Expected error, got nil.")
}
if mgr != nil {
t.Error("Expected nil manager, got non-nil.")
}
}
func TestNewCacheManagerReturnsCacheManagerPointer(t *testing.T) {
mgr, err := NewCacheManager(t.TempDir())
if err != nil {
t.Errorf("Expected nil error, got %s.", err)
}
if mgr == nil {
t.Error("Expected non-nil manager, got nil.")
}
}
func TestCacheManagerPathReturnsPathRootedAtCacheRoot(t *testing.T) {
tmpRoot := t.TempDir()
mgr, _ := NewCacheManager(tmpRoot)
rootedPath := mgr.Path("test")
expectedPath := filepath.Join(tmpRoot, "test")
if rootedPath != expectedPath {
t.Errorf("Expected %s, got %s.", expectedPath, rootedPath)
}
}

View file

@ -19,6 +19,7 @@ func ExecuteWorkflow(configuration Configuration, workflowFile string) error {
runnerInstance := runner.NewRunner(
driver,
configuration.Runner.Labels,
configuration.Cache.Dir,
)
workflow, err := workflow.FromYamlFile(workflowFile)

View file

@ -2,6 +2,7 @@ package runner
import (
"context"
cache "courgette/internal/cache"
driver "courgette/internal/driver"
logger "courgette/internal/logging"
workflow "courgette/internal/workflow"
@ -13,14 +14,18 @@ import (
type Runner struct {
Labels map[string]string
Driver driver.ContainerDriver
Cache cache.CacheManager
Runs int
// Deferred tasks, in order their were scheduled.
deferred *DeferredTaskManager
}
func NewRunner(driver driver.ContainerDriver, labels map[string]string) Runner {
func NewRunner(driver driver.ContainerDriver, labels map[string]string, cacheRoot string) Runner {
cacheManager, _ := cache.NewCacheManager(cacheRoot)
return Runner{
Driver: driver,
Cache: *cacheManager,
Labels: labels,
deferred: NewDeferredTaskManager(),
}

View file

@ -48,7 +48,7 @@ func TestRunJobInContainerSchedulesStoppingContainers(t *testing.T) {
mockDriver := driver.NewMockDriver()
mockDriver.WithMockedCall("Exec", driver.CommandResult{ExitCode: 1, Error: nil}, "test-container", "test-command", ".", fmt.Sprintf("%#v", map[string]string{}))
runner := NewRunner(&mockDriver, map[string]string{})
runner := NewRunner(&mockDriver, map[string]string{}, t.TempDir())
jobCtx := context.WithValue(context.Background(), "currentJob", workflow.Job{})
jobCtx = context.WithValue(jobCtx, "workflow", workflow.Workflow{})

View file

@ -21,7 +21,7 @@ jobs:
workflow, _ := workflow.FromYamlBytes([]byte(workflowSample))
mockDriver := driver.NewMockDriver()
runner := NewRunner(&mockDriver, map[string]string{"test": "test"})
runner := NewRunner(&mockDriver, map[string]string{"test": "test"}, t.TempDir())
jobContext := context.WithValue(context.Background(), "workflow", *workflow)
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
@ -46,7 +46,7 @@ jobs:
workflow, _ := workflow.FromYamlBytes([]byte(workflowSample))
mockDriver := driver.NewMockDriver()
runner := NewRunner(&mockDriver, map[string]string{"test": "test"})
runner := NewRunner(&mockDriver, map[string]string{"test": "test"}, t.TempDir())
jobContext := context.WithValue(context.Background(), "workflow", *workflow)
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
@ -73,7 +73,7 @@ jobs:
mockDriver := driver.NewMockDriver()
mockDriver.WithMockedCall("Exec", driver.CommandResult{Error: errors.New("exit 1!"), ExitCode: 1}, "testContainer", "exit 1", fmt.Sprintf("%#v", map[string]string{}))
runner := NewRunner(&mockDriver, map[string]string{"test": "test"})
runner := NewRunner(&mockDriver, map[string]string{"test": "test"}, t.TempDir())
jobContext := context.WithValue(context.Background(), "workflow", *workflow)
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
@ -101,7 +101,7 @@ jobs:
mockDriver := driver.NewMockDriver()
mockDriver.WithMockedCall("Exec", driver.CommandResult{Error: errors.New("exit 1!"), ExitCode: 1}, "testContainer", "exit 1", fmt.Sprintf("%#v", map[string]string{}))
runner := NewRunner(&mockDriver, map[string]string{"test": "test"})
runner := NewRunner(&mockDriver, map[string]string{"test": "test"}, t.TempDir())
jobContext := context.WithValue(context.Background(), "workflow", *workflow)
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
@ -133,7 +133,7 @@ jobs:
mockDriver := driver.NewMockDriver()
mockDriver.WithMockedCall("Exec", driver.CommandResult{Error: errors.New("exit 1!"), ExitCode: 1}, "testContainer", "exit 1", ".", fmt.Sprintf("%#v", map[string]string{}))
runner := NewRunner(&mockDriver, map[string]string{"test": "test"})
runner := NewRunner(&mockDriver, map[string]string{"test": "test"}, t.TempDir())
jobContext := context.WithValue(context.Background(), "workflow", *workflow)
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
@ -164,7 +164,7 @@ jobs:
mockDriver := driver.NewMockDriver()
mockDriver.WithMockedCall("Exec", driver.CommandResult{Error: errors.New("exit 1!"), ExitCode: 1}, "testContainer", "exit 1", ".", fmt.Sprintf("%#v", map[string]string{}))
runner := NewRunner(&mockDriver, map[string]string{"test": "test"})
runner := NewRunner(&mockDriver, map[string]string{"test": "test"}, t.TempDir())
jobContext := context.WithValue(context.Background(), "workflow", *workflow)
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])