commit b922c3fb94942c4d980548bd44ad813ecd8dcad4
parent a479131b7f619bff3342218587dcf42605606258
Author: lash <dev@holbrook.no>
Date: Thu, 20 Apr 2023 14:36:24 +0100
Add persisted engine object for interactive use
Diffstat:
3 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/engine/engine.go b/engine/engine.go
@@ -28,6 +28,7 @@ type Engine struct {
ca cache.Memory
vm *vm.Vm
root string
+ session string
initd bool
}
@@ -45,6 +46,7 @@ func NewEngine(cfg Config, st *state.State, rs resource.Resource, ca cache.Memor
vm: vm.NewVm(st, rs, ca, szr),
}
engine.root = cfg.Root
+ engine.session = cfg.SessionId
return engine
}
diff --git a/engine/persist.go b/engine/persist.go
@@ -8,6 +8,36 @@ import (
"git.defalsify.org/vise.git/resource"
)
+type PersistedEngine struct {
+ *Engine
+ pr persist.Persister
+}
+
+
+func NewPersistedEngine(cfg Config, pr persist.Persister, rs resource.Resource, ctx context.Context) (PersistedEngine, error) {
+ err := pr.Load(cfg.SessionId)
+ if err != nil {
+ return PersistedEngine{}, err
+ }
+ st := pr.GetState()
+ ca := pr.GetMemory()
+ enb := NewEngine(cfg, st, rs, ca, ctx)
+ en := PersistedEngine{
+ &enb,
+ pr,
+ }
+ return en, nil
+}
+
+func(pe *PersistedEngine) Exec(input []byte, ctx context.Context) (bool, error) {
+ v, err := pe.Engine.Exec(input, ctx)
+ if err != nil {
+ return v, err
+ }
+ err = pe.pr.Save(pe.Engine.session)
+ return v, err
+}
+
// RunPersisted performs a single vm execution from client input using a persisted state.
//
// State is first loaded from storage. The vm is initialized with the state and executed. The new state is then saved to storage.
diff --git a/engine/persist_test.go b/engine/persist_test.go
@@ -11,7 +11,7 @@ import (
"git.defalsify.org/vise.git/state"
)
-func TestPersist(t *testing.T) {
+func TestRunPersist(t *testing.T) {
generateTestData(t)
cfg := Config{
OutputSize: 83,
@@ -69,5 +69,85 @@ func TestPersist(t *testing.T) {
if idx != 1 {
t.Fatalf("expected '1', got %v", idx)
}
+}
+
+func TestEnginePersist(t *testing.T) {
+ generateTestData(t)
+ cfg := Config{
+ OutputSize: 83,
+ SessionId: "xyzzy",
+ Root: "root",
+ }
+ rs := NewFsWrapper(dataDir, nil)
+
+ persistDir, err := ioutil.TempDir("", "vise_engine_persist")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ st := state.NewState(3)
+ ca := cache.NewCache().WithCacheSize(1024)
+ pr := persist.NewFsPersister(persistDir).WithContent(&st, ca)
+
+ //w := os.Stdout
+ ctx := context.TODO()
+
+ st = state.NewState(cfg.FlagCount)
+ ca = cache.NewCache()
+ ca = ca.WithCacheSize(cfg.CacheSize)
+ pr = persist.NewFsPersister(persistDir).WithContent(&st, ca)
+ err = pr.Save(cfg.SessionId)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ en, err := NewPersistedEngine(cfg, pr, rs, ctx)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ _, err = en.Init(ctx)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ _, err = en.Exec([]byte("1"), ctx)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ _, err = en.Exec([]byte("2"), ctx)
+ if err != nil {
+ t.Fatal(err)
+ }
+ _, err = en.Exec([]byte("00"), ctx)
+ if err != nil {
+ t.Fatal(err)
+ }
+ location, idx := st.Where()
+ if location != "long" {
+ t.Fatalf("expected location 'long', got %s", location)
+ }
+ if idx != 1 {
+ t.Fatalf("expected index '1', got %v", idx)
+ }
+
+ pr = persist.NewFsPersister(persistDir)
+ en, err = NewPersistedEngine(cfg, pr, rs, ctx)
+ if err != nil {
+ t.Fatal(err)
+ }
+ st_loaded := pr.GetState()
+ location, _ = st_loaded.Where()
+ if location != "long" {
+ t.Fatalf("expected location 'long', got %s", location)
+ }
+ if idx != 1 {
+ t.Fatalf("expected index '1', got %v", idx)
+ }
+ _, err = en.Exec([]byte("11"), ctx)
+ if err != nil {
+ t.Fatal(err)
+ }
}