go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

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:
Mengine/engine.go | 2++
Mengine/persist.go | 30++++++++++++++++++++++++++++++
Mengine/persist_test.go | 82++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
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) + } }