From 9e6ece0959f4650df00b1d621906b1cf7e6b5b71 Mon Sep 17 00:00:00 2001 From: lash Date: Sun, 2 Apr 2023 09:07:53 +0100 Subject: [PATCH] Add testdata generator --- go/dev/generate_testdata.go | 21 +++++++ go/engine/engine.go | 5 +- go/engine/engine_test.go | 34 ++++++++--- go/state/state.go | 4 +- go/testdata/bar | 1 - go/testdata/bar.bin | Bin 20 -> 0 bytes go/testdata/root | 1 - go/testdata/root.bin | Bin 20 -> 0 bytes go/testdata/testdata.go | 118 ++++++++++++++++++++++++++++++++++++ go/vm/vm.go | 2 +- 10 files changed, 170 insertions(+), 16 deletions(-) create mode 100644 go/dev/generate_testdata.go delete mode 100644 go/testdata/bar delete mode 100644 go/testdata/bar.bin delete mode 100644 go/testdata/root delete mode 100644 go/testdata/root.bin create mode 100644 go/testdata/testdata.go diff --git a/go/dev/generate_testdata.go b/go/dev/generate_testdata.go new file mode 100644 index 0000000..b40e3aa --- /dev/null +++ b/go/dev/generate_testdata.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "os" + + "git.defalsify.org/festive/testdata" +) + +func main() { + var err error + if len(os.Args) > 1 { + err = testdata.GenerateTo(os.Args[1]) + } else { + _, err = testdata.Generate() + } + if err != nil { + os.Exit(1) + } + fmt.Println(testdata.DataDir) +} diff --git a/go/engine/engine.go b/go/engine/engine.go index c93b70b..10a6bec 100644 --- a/go/engine/engine.go +++ b/go/engine/engine.go @@ -31,8 +31,8 @@ func NewEngine(st *state.State, rs resource.Resource) Engine { // Init must be explicitly called before using the Engine instance. // // It makes sure bootstrapping code has been executed, and that the exposed bytecode is ready for user input. -func(en *Engine) Init(ctx context.Context) error { - b := vm.NewLine([]byte{}, vm.MOVE, []string{"root"}, nil, nil) +func(en *Engine) Init(sym string, ctx context.Context) error { + b := vm.NewLine([]byte{}, vm.MOVE, []string{sym}, nil, nil) var err error _, err = vm.Run(b, en.st, en.rs, ctx) if err != nil { @@ -65,6 +65,7 @@ func (en *Engine) Exec(input []byte, ctx context.Context) error { if err != nil { return err } + log.Printf("new execution with input 0x%x (%v)", input, len(input)) code, err := en.st.GetCode() if err != nil { return err diff --git a/go/engine/engine_test.go b/go/engine/engine_test.go index 7d6936a..c83fb9d 100644 --- a/go/engine/engine_test.go +++ b/go/engine/engine_test.go @@ -9,10 +9,14 @@ import ( "text/template" "testing" - testdataloader "github.com/peteole/testdata-loader" - - "git.defalsify.org/festive/state" "git.defalsify.org/festive/resource" + "git.defalsify.org/festive/state" + "git.defalsify.org/festive/testdata" +) + +var ( + dataGenerated bool = false + dataDir string = testdata.DataDir ) type FsWrapper struct { @@ -65,13 +69,24 @@ func(fs FsWrapper) GetCode(sym string) ([]byte, error) { return r, err } +func generateTestData(t *testing.T) { + if dataGenerated { + return + } + var err error + dataDir, err = testdata.Generate() + if err != nil { + t.Fatal(err) + } +} + func TestEngineInit(t *testing.T) { st := state.NewState(17).WithCacheSize(1024) - dir := path.Join(testdataloader.GetBasePath(), "testdata") + generateTestData(t) ctx := context.TODO() - rs := NewFsWrapper(dir, &st, ctx) + rs := NewFsWrapper(dataDir, &st, ctx) en := NewEngine(&st, &rs) - err := en.Init(ctx) + err := en.Init("root", ctx) if err != nil { t.Fatal(err) } @@ -85,13 +100,14 @@ func TestEngineInit(t *testing.T) { if !bytes.Equal(b, []byte("hello world")) { t.Fatalf("expected result 'hello world', got %v", b) } - input := []byte("ooo") + + input := []byte("1") err = en.Exec(input, ctx) if err != nil { t.Fatal(err) } r := st.Where() - if r != "bar" { - t.Fatalf("expected where-string 'bar', got %v", r) + if r != "foo" { + t.Fatalf("expected where-string 'foo', got %v", r) } } diff --git a/go/state/state.go b/go/state/state.go index 78ac368..a4fe872 100644 --- a/go/state/state.go +++ b/go/state/state.go @@ -363,13 +363,13 @@ func(st *State) Size() (uint32, uint32) { // Appendcode adds the given bytecode to the end of the existing code. func(st *State) AppendCode(b []byte) error { st.code = append(st.code, b...) - log.Printf("code changed to %v", b) + log.Printf("code changed to 0x%x", b) return nil } // SetCode replaces the current bytecode with the given bytecode. func(st *State) SetCode(b []byte) { - log.Printf("code set to %v", b) + log.Printf("code set to 0x%x", b) st.code = b } diff --git a/go/testdata/bar b/go/testdata/bar deleted file mode 100644 index 7c05411..0000000 --- a/go/testdata/bar +++ /dev/null @@ -1 +0,0 @@ -i am in bar diff --git a/go/testdata/bar.bin b/go/testdata/bar.bin deleted file mode 100644 index be35b153a533343ed2a8180c6e46997e55f0f5c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20 XcmZQzW=_k`XJBAw-~cgLQh@*fB2ol7 diff --git a/go/testdata/root b/go/testdata/root deleted file mode 100644 index 3b18e51..0000000 --- a/go/testdata/root +++ /dev/null @@ -1 +0,0 @@ -hello world diff --git a/go/testdata/root.bin b/go/testdata/root.bin deleted file mode 100644 index 35a110ea95ab74e2f9bce882d1054c1750cc1b89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20 bcmZSJU`|U*V@}J@XW(GY&(CL0N-P2ZE$0Ol diff --git a/go/testdata/testdata.go b/go/testdata/testdata.go new file mode 100644 index 0000000..54ee8cd --- /dev/null +++ b/go/testdata/testdata.go @@ -0,0 +1,118 @@ +package testdata + +import ( + "fmt" + "io/ioutil" + "os" + "path" + + testdataloader "github.com/peteole/testdata-loader" + + "git.defalsify.org/festive/vm" +) + +type genFunc func() error + +var ( + BaseDir = testdataloader.GetBasePath() + DataDir = "" + dirLock = false +) + +func out(sym string, b []byte, tpl string) error { + fp := path.Join(DataDir, sym) + err := ioutil.WriteFile(fp, []byte(tpl), 0644) + if err != nil { + return err + } + + fb := sym + ".bin" + fp = path.Join(DataDir, fb) + err = ioutil.WriteFile(fp, b, 0644) + if err != nil { + return err + } + return nil +} + +func root() error { + b := []byte{} + b = vm.NewLine(b, vm.INCMP, []string{"1", "foo"}, nil, nil) + b = vm.NewLine(b, vm.INCMP, []string{"2", "bar"}, nil, nil) + + tpl := "hello world" + + return out("root", b, tpl) +} + +func foo() error { + b := []byte{} + b = vm.NewLine(b, vm.LOAD, []string{"inky"}, []byte{20}, nil) + b = vm.NewLine(b, vm.HALT, nil, nil, nil) + b = vm.NewLine(b, vm.INCMP, []string{"0", "_back"}, nil, nil) + b = vm.NewLine(b, vm.INCMP, []string{"1", "baz"}, nil, nil) + b = vm.NewLine(b, vm.CATCH, []string{"_catch"}, []byte{1}, []uint8{1}) + + tpl := `this is in foo + +it has more lines` + + return out("foo", b, tpl) +} + +func bar() error { + b := []byte{} + b = vm.NewLine(b, vm.LOAD, []string{"pinky"}, []byte{0}, nil) + b = vm.NewLine(b, vm.HALT, nil, nil, nil) + b = vm.NewLine(b, vm.INCMP, []string{"0", "_home"}, nil, nil) + + tpl := "this is bar - an end node" + + return out("bar", b, tpl) +} + +func baz() error { + b := []byte{} + b = vm.NewLine(b, vm.MAP, []string{"inky"}, nil, nil) + b = vm.NewLine(b, vm.HALT, nil, nil, nil) + + tpl := "this is baz which uses the var {{.inky}} in the template." + + return out("baz", b, tpl) +} + +func generate() error { + err := os.MkdirAll(DataDir, 0755) + if err != nil { + return err + } + + fns := []genFunc{root, foo, bar, baz} + for _, fn := range fns { + err = fn() + if err != nil { + return err + } + } + return nil +} + +func Generate() (string, error) { + dir, err := ioutil.TempDir("", "festive_testdata_") + if err != nil { + return "", err + } + DataDir = dir + dirLock = true + err = generate() + return dir, err +} + +func GenerateTo(dir string) error { + if dirLock { + return fmt.Errorf("directory already overridden") + } + DataDir = dir + dirLock = true + return generate() +} diff --git a/go/vm/vm.go b/go/vm/vm.go index 6853bab..2ec9b86 100644 --- a/go/vm/vm.go +++ b/go/vm/vm.go @@ -29,7 +29,7 @@ func argFromBytes(input []byte) (string, []byte, error) { func Run(instruction []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) { var err error for len(instruction) > 0 { - log.Printf("instruction is now %v", instruction) + log.Printf("instruction is now 0x%x", instruction) op := binary.BigEndian.Uint16(instruction[:2]) if op > _MAX { return instruction, fmt.Errorf("opcode value %v out of range (%v)", op, _MAX)