Add testdata generator

This commit is contained in:
lash 2023-04-02 09:07:53 +01:00
parent d0187608aa
commit 9e6ece0959
Signed by untrusted user who does not match committer: lash
GPG Key ID: 21D2E7BB88C2A746
10 changed files with 170 additions and 16 deletions

View File

@ -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)
}

View File

@ -31,8 +31,8 @@ func NewEngine(st *state.State, rs resource.Resource) Engine {
// Init must be explicitly called before using the Engine instance. // 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. // 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 { func(en *Engine) Init(sym string, ctx context.Context) error {
b := vm.NewLine([]byte{}, vm.MOVE, []string{"root"}, nil, nil) b := vm.NewLine([]byte{}, vm.MOVE, []string{sym}, nil, nil)
var err error var err error
_, err = vm.Run(b, en.st, en.rs, ctx) _, err = vm.Run(b, en.st, en.rs, ctx)
if err != nil { if err != nil {
@ -65,6 +65,7 @@ func (en *Engine) Exec(input []byte, ctx context.Context) error {
if err != nil { if err != nil {
return err return err
} }
log.Printf("new execution with input 0x%x (%v)", input, len(input))
code, err := en.st.GetCode() code, err := en.st.GetCode()
if err != nil { if err != nil {
return err return err

View File

@ -9,10 +9,14 @@ import (
"text/template" "text/template"
"testing" "testing"
testdataloader "github.com/peteole/testdata-loader"
"git.defalsify.org/festive/state"
"git.defalsify.org/festive/resource" "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 { type FsWrapper struct {
@ -65,13 +69,24 @@ func(fs FsWrapper) GetCode(sym string) ([]byte, error) {
return r, err 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) { func TestEngineInit(t *testing.T) {
st := state.NewState(17).WithCacheSize(1024) st := state.NewState(17).WithCacheSize(1024)
dir := path.Join(testdataloader.GetBasePath(), "testdata") generateTestData(t)
ctx := context.TODO() ctx := context.TODO()
rs := NewFsWrapper(dir, &st, ctx) rs := NewFsWrapper(dataDir, &st, ctx)
en := NewEngine(&st, &rs) en := NewEngine(&st, &rs)
err := en.Init(ctx) err := en.Init("root", ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -85,13 +100,14 @@ func TestEngineInit(t *testing.T) {
if !bytes.Equal(b, []byte("hello world")) { if !bytes.Equal(b, []byte("hello world")) {
t.Fatalf("expected result 'hello world', got %v", b) t.Fatalf("expected result 'hello world', got %v", b)
} }
input := []byte("ooo")
input := []byte("1")
err = en.Exec(input, ctx) err = en.Exec(input, ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
r := st.Where() r := st.Where()
if r != "bar" { if r != "foo" {
t.Fatalf("expected where-string 'bar', got %v", r) t.Fatalf("expected where-string 'foo', got %v", r)
} }
} }

View File

@ -363,13 +363,13 @@ func(st *State) Size() (uint32, uint32) {
// Appendcode adds the given bytecode to the end of the existing code. // Appendcode adds the given bytecode to the end of the existing code.
func(st *State) AppendCode(b []byte) error { func(st *State) AppendCode(b []byte) error {
st.code = append(st.code, b...) st.code = append(st.code, b...)
log.Printf("code changed to %v", b) log.Printf("code changed to 0x%x", b)
return nil return nil
} }
// SetCode replaces the current bytecode with the given bytecode. // SetCode replaces the current bytecode with the given bytecode.
func(st *State) SetCode(b []byte) { func(st *State) SetCode(b []byte) {
log.Printf("code set to %v", b) log.Printf("code set to 0x%x", b)
st.code = b st.code = b
} }

1
go/testdata/bar vendored
View File

@ -1 +0,0 @@
i am in bar

BIN
go/testdata/bar.bin vendored

Binary file not shown.

1
go/testdata/root vendored
View File

@ -1 +0,0 @@
hello world

BIN
go/testdata/root.bin vendored

Binary file not shown.

118
go/testdata/testdata.go vendored Normal file
View File

@ -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()
}

View File

@ -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) { func Run(instruction []byte, st *state.State, rs resource.Resource, ctx context.Context) ([]byte, error) {
var err error var err error
for len(instruction) > 0 { 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]) op := binary.BigEndian.Uint16(instruction[:2])
if op > _MAX { if op > _MAX {
return instruction, fmt.Errorf("opcode value %v out of range (%v)", op, _MAX) return instruction, fmt.Errorf("opcode value %v out of range (%v)", op, _MAX)