go-vise

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

commit fa0c7a0043bdbf05a175b94d463d705b6e1f6647
parent 41dc0ccbaaf9366b8d92c4770dc7ee8754b2d862
Author: lash <dev@holbrook.no>
Date:   Mon,  2 Sep 2024 01:30:58 +0100

Finish persister setup for engine

Diffstat:
Mengine/db.go | 72+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mengine/db_test.go | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mvm/runner.go | 1-
3 files changed, 136 insertions(+), 4 deletions(-)

diff --git a/engine/db.go b/engine/db.go @@ -2,6 +2,7 @@ package engine import ( "context" + "errors" "fmt" "io" "os" @@ -139,6 +140,59 @@ func(en *DbEngine) ensureMemory() { } } +func(en *DbEngine) preparePersist() error { + if en.pe == nil { + return nil + } + st := en.pe.GetState() + if st != nil { + if en.st != nil { + return errors.New("state cannot be explicitly set in both persister and engine.") + } + en.st = st + } else { + if en.st == nil { + logg.Debugf("defer persist state set until state set in engine") + } else { + en.st = st + } + } + ca := en.pe.GetMemory().(*cache.Cache) + if ca != nil { + if en.ca == nil { + return errors.New("cache cannot be explicitly set in both persister and engine.") + } + en.ca = ca + } else { + if en.ca == nil { + logg.Debugf("defer persist memory set until state set in engine") + } else { + en.ca = ca + } + } + return nil +} + +func(en *DbEngine) ensurePersist() error { + if en.pe == nil { + return nil + } + st := en.pe.GetState() + if st == nil { + st = en.st + } + ca := en.pe.GetMemory() + if ca == nil { + ca = en.ca + } + cac, ok := ca.(*cache.Cache) + if !ok { + return errors.New("Memory is not a *cache.Cache. For the time being it has to be, because of the way persister serialization is implemented. This hopefully changes in the future.") + } + en.pe = en.pe.WithContent(st, cac) + return nil +} + func(en *DbEngine) setupVm() { var szr *render.Sizer if en.cfg.OutputSize > 0 { @@ -147,10 +201,19 @@ func(en *DbEngine) setupVm() { en.vm = vm.NewVm(en.st, en.rs, en.ca, szr) } -func(en *DbEngine) prepare() { +func(en *DbEngine) prepare() error { + err := en.preparePersist() + if err != nil { + return err + } en.ensureState() en.ensureMemory() + err = en.ensurePersist() + if err != nil { + return err + } en.setupVm() + return nil } // execute the first function, if set @@ -228,7 +291,10 @@ func(en *DbEngine) restore() { // // It loads and executes code for the start node. func(en *DbEngine) Init(ctx context.Context) (bool, error) { - en.prepare() + err := en.prepare() + if err != nil { + return false, err + } en.restore() if en.initd { logg.DebugCtxf(ctx, "already initialized") @@ -241,7 +307,7 @@ func(en *DbEngine) Init(ctx context.Context) (bool, error) { } inSave, _ := en.st.GetInput() - err := en.st.SetInput([]byte{}) + err = en.st.SetInput([]byte{}) if err != nil { return false, err } diff --git a/engine/db_test.go b/engine/db_test.go @@ -3,12 +3,23 @@ package engine import ( "context" "fmt" + "io" + "os" "testing" "git.defalsify.org/vise.git/resource" + "git.defalsify.org/vise.git/state" "git.defalsify.org/vise.git/vm" ) +func getNull() io.WriteCloser { + nul, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0700) + if err != nil { + panic(err) + } + return nul +} + func codeGet(ctx context.Context, s string) ([]byte, error) { var b []byte var err error @@ -22,6 +33,13 @@ func codeGet(ctx context.Context, s string) ([]byte, error) { return b, err } +func flagSet(ctx context.Context, nodeSym string, input []byte) (resource.Result, error) { + return resource.Result{ + Content: "xyzzy", + FlagSet: []uint32{state.FLAG_USERSTART}, + }, nil +} + func TestDbEngineMinimal(t *testing.T) { ctx := context.Background() cfg := Config{} @@ -37,6 +55,8 @@ func TestDbEngineMinimal(t *testing.T) { } func TestDbEngineRoot(t *testing.T) { + nul := getNull() + defer nul.Close() ctx := context.Background() cfg := Config{} rs := resource.NewMenuResource() @@ -49,4 +69,51 @@ func TestDbEngineRoot(t *testing.T) { if !cont { t.Fatalf("expected continue") } + + cont, err = en.Exec(ctx, []byte{0x30}) + if err == nil { + t.Fatalf("expected loadfail") + } + + _, err = en.WriteResult(ctx, nul) + if err != nil { + t.Fatal(err) + } + + cont, err = en.Exec(ctx, []byte{0x30}) + if err == nil { + t.Fatalf("expected nocode") + } +} + +func TestDbEnginePersist(t *testing.T) { + nul := getNull() + defer nul.Close() + ctx := context.Background() + cfg := Config{ + FlagCount: 1, + SessionId: "bar", + } + rs := resource.NewMenuResource() + rs.WithCodeGetter(codeGet) + rs.AddLocalFunc("foo", flagSet) + en := NewDbEngine(cfg, rs) + cont, err := en.Init(ctx) + if err != nil { + t.Fatal(err) + } + if !cont { + t.Fatalf("expected continue") + } + + cont, err = en.Exec(ctx, []byte{0x30}) + if err != nil { + t.Fatal(err) + } + + _, err = en.WriteResult(ctx, nul) + if err != nil { + t.Fatal(err) + } + } diff --git a/vm/runner.go b/vm/runner.go @@ -482,7 +482,6 @@ func(vm *Vm) refresh(key string, rs resource.Resource, ctx context.Context) (str _ = vm.st.SetFlag(state.FLAG_LOADFAIL) return "", NewExternalCodeError(key, err).WithCode(r.Status) } - logg.TraceCtxf(ctx, "foo", "flags", r.FlagSet) for _, flag := range r.FlagReset { if !state.IsWriteableFlag(flag) { continue