Add testdata generator
This commit is contained in:
parent
d0187608aa
commit
9e6ece0959
21
go/dev/generate_testdata.go
Normal file
21
go/dev/generate_testdata.go
Normal 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)
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
1
go/testdata/bar
vendored
@ -1 +0,0 @@
|
|||||||
i am in bar
|
|
BIN
go/testdata/bar.bin
vendored
BIN
go/testdata/bar.bin
vendored
Binary file not shown.
1
go/testdata/root
vendored
1
go/testdata/root
vendored
@ -1 +0,0 @@
|
|||||||
hello world
|
|
BIN
go/testdata/root.bin
vendored
BIN
go/testdata/root.bin
vendored
Binary file not shown.
118
go/testdata/testdata.go
vendored
Normal file
118
go/testdata/testdata.go
vendored
Normal 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()
|
||||||
|
}
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user