feat: add cache manager
This commit is contained in:
parent
c989aba61b
commit
5490bba12f
6 changed files with 101 additions and 8 deletions
43
internal/cache/cache_manager.go
vendored
Normal file
43
internal/cache/cache_manager.go
vendored
Normal 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
44
internal/cache/cache_manager_test.go
vendored
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ func ExecuteWorkflow(configuration Configuration, workflowFile string) error {
|
||||||
runnerInstance := runner.NewRunner(
|
runnerInstance := runner.NewRunner(
|
||||||
driver,
|
driver,
|
||||||
configuration.Runner.Labels,
|
configuration.Runner.Labels,
|
||||||
|
configuration.Cache.Dir,
|
||||||
)
|
)
|
||||||
|
|
||||||
workflow, err := workflow.FromYamlFile(workflowFile)
|
workflow, err := workflow.FromYamlFile(workflowFile)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package runner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
cache "courgette/internal/cache"
|
||||||
driver "courgette/internal/driver"
|
driver "courgette/internal/driver"
|
||||||
logger "courgette/internal/logging"
|
logger "courgette/internal/logging"
|
||||||
workflow "courgette/internal/workflow"
|
workflow "courgette/internal/workflow"
|
||||||
|
@ -13,14 +14,18 @@ import (
|
||||||
type Runner struct {
|
type Runner struct {
|
||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
Driver driver.ContainerDriver
|
Driver driver.ContainerDriver
|
||||||
|
Cache cache.CacheManager
|
||||||
Runs int
|
Runs int
|
||||||
// Deferred tasks, in order their were scheduled.
|
// Deferred tasks, in order their were scheduled.
|
||||||
deferred *DeferredTaskManager
|
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{
|
return Runner{
|
||||||
Driver: driver,
|
Driver: driver,
|
||||||
|
Cache: *cacheManager,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
deferred: NewDeferredTaskManager(),
|
deferred: NewDeferredTaskManager(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func TestRunJobInContainerSchedulesStoppingContainers(t *testing.T) {
|
||||||
mockDriver := driver.NewMockDriver()
|
mockDriver := driver.NewMockDriver()
|
||||||
mockDriver.WithMockedCall("Exec", driver.CommandResult{ExitCode: 1, Error: nil}, "test-container", "test-command", ".", fmt.Sprintf("%#v", map[string]string{}))
|
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(context.Background(), "currentJob", workflow.Job{})
|
||||||
jobCtx = context.WithValue(jobCtx, "workflow", workflow.Workflow{})
|
jobCtx = context.WithValue(jobCtx, "workflow", workflow.Workflow{})
|
||||||
|
|
|
@ -21,7 +21,7 @@ jobs:
|
||||||
workflow, _ := workflow.FromYamlBytes([]byte(workflowSample))
|
workflow, _ := workflow.FromYamlBytes([]byte(workflowSample))
|
||||||
mockDriver := driver.NewMockDriver()
|
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(context.Background(), "workflow", *workflow)
|
||||||
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
||||||
|
@ -46,7 +46,7 @@ jobs:
|
||||||
workflow, _ := workflow.FromYamlBytes([]byte(workflowSample))
|
workflow, _ := workflow.FromYamlBytes([]byte(workflowSample))
|
||||||
mockDriver := driver.NewMockDriver()
|
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(context.Background(), "workflow", *workflow)
|
||||||
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
||||||
|
@ -73,7 +73,7 @@ jobs:
|
||||||
mockDriver := driver.NewMockDriver()
|
mockDriver := driver.NewMockDriver()
|
||||||
|
|
||||||
mockDriver.WithMockedCall("Exec", driver.CommandResult{Error: errors.New("exit 1!"), ExitCode: 1}, "testContainer", "exit 1", fmt.Sprintf("%#v", map[string]string{}))
|
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(context.Background(), "workflow", *workflow)
|
||||||
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
||||||
|
@ -101,7 +101,7 @@ jobs:
|
||||||
mockDriver := driver.NewMockDriver()
|
mockDriver := driver.NewMockDriver()
|
||||||
|
|
||||||
mockDriver.WithMockedCall("Exec", driver.CommandResult{Error: errors.New("exit 1!"), ExitCode: 1}, "testContainer", "exit 1", fmt.Sprintf("%#v", map[string]string{}))
|
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(context.Background(), "workflow", *workflow)
|
||||||
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
||||||
|
@ -133,7 +133,7 @@ jobs:
|
||||||
mockDriver := driver.NewMockDriver()
|
mockDriver := driver.NewMockDriver()
|
||||||
|
|
||||||
mockDriver.WithMockedCall("Exec", driver.CommandResult{Error: errors.New("exit 1!"), ExitCode: 1}, "testContainer", "exit 1", ".", fmt.Sprintf("%#v", map[string]string{}))
|
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(context.Background(), "workflow", *workflow)
|
||||||
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
||||||
|
@ -164,7 +164,7 @@ jobs:
|
||||||
mockDriver := driver.NewMockDriver()
|
mockDriver := driver.NewMockDriver()
|
||||||
|
|
||||||
mockDriver.WithMockedCall("Exec", driver.CommandResult{Error: errors.New("exit 1!"), ExitCode: 1}, "testContainer", "exit 1", ".", fmt.Sprintf("%#v", map[string]string{}))
|
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(context.Background(), "workflow", *workflow)
|
||||||
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
jobContext = context.WithValue(jobContext, "currentJob", workflow.Jobs["jobA"])
|
||||||
|
|
Loading…
Reference in a new issue