Add basic tests for vm
This commit is contained in:
parent
17c53d1081
commit
ef364900bb
3 changed files with 119 additions and 3 deletions
|
@ -2,11 +2,14 @@ package vm
|
|||
|
||||
import "github.com/CityOfZion/neo-go/pkg/vm/stack"
|
||||
|
||||
var opFunc = map[stack.Instruction]func(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation) error{
|
||||
var opFunc = map[stack.Instruction]func(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation) (Vmstate, error){
|
||||
stack.ADD: Add,
|
||||
stack.SUB: Sub,
|
||||
stack.PUSHBYTES1: PushNBytes,
|
||||
stack.PUSHBYTES75: PushNBytes,
|
||||
stack.RET: RET,
|
||||
stack.EQUAL: EQUAL,
|
||||
stack.THROWIFNOT: THROWIFNOT,
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -24,7 +24,7 @@ func TestAddOp(t *testing.T) {
|
|||
ctx := stack.NewContext([]byte{})
|
||||
ctx.Estack.Push(a).Push(b)
|
||||
|
||||
v.ExecuteOp(stack.ADD, ctx)
|
||||
v.executeOp(stack.ADD, ctx)
|
||||
|
||||
// Stack should have one item
|
||||
assert.Equal(t, 1, ctx.Estack.Len())
|
||||
|
@ -54,7 +54,7 @@ func TestSubOp(t *testing.T) {
|
|||
ctx := stack.NewContext([]byte{})
|
||||
ctx.Estack.Push(a).Push(b)
|
||||
|
||||
v.ExecuteOp(stack.SUB, ctx)
|
||||
v.executeOp(stack.SUB, ctx)
|
||||
|
||||
// Stack should have one item
|
||||
assert.Equal(t, 1, ctx.Estack.Len())
|
||||
|
|
113
pkg/vm/vm_test.go
Normal file
113
pkg/vm/vm_test.go
Normal file
|
@ -0,0 +1,113 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/vm/stack"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPushAdd(t *testing.T) {
|
||||
builder := stack.NewBuilder()
|
||||
|
||||
// PUSH TWO NUMBER
|
||||
// ADD THEM TOGETHER
|
||||
builder.EmitInt(20).EmitInt(34).EmitOpcode(stack.ADD)
|
||||
|
||||
// Pass program to VM
|
||||
vm := NewVM(builder.Bytes())
|
||||
|
||||
// Execute first OPCODE
|
||||
// Should be PUSH(20)
|
||||
state, err := vm.step()
|
||||
assert.Equal(t, NONE, int(state))
|
||||
assert.Nil(t, err)
|
||||
|
||||
// We should have the number 20 on stack
|
||||
ok := peekTopEStackIsValue(t, vm, 20)
|
||||
assert.True(t, ok)
|
||||
|
||||
// Excute second OPCODE
|
||||
// Should be PUSH(34)
|
||||
state, err = vm.step()
|
||||
assert.Equal(t, NONE, int(state))
|
||||
assert.Nil(t, err)
|
||||
|
||||
// We should have the number 34 at the top of the stack
|
||||
ok = peekTopEStackIsValue(t, vm, 34)
|
||||
assert.True(t, ok)
|
||||
|
||||
// Excute third OPCODE
|
||||
// Should Add both values on the stack
|
||||
state, err = vm.step()
|
||||
assert.Equal(t, NONE, int(state))
|
||||
assert.Nil(t, err)
|
||||
|
||||
// We should now have one value on the stack
|
||||
//It should be equal to 20+34 = 54
|
||||
ok = EstackLen(t, vm, 1)
|
||||
assert.True(t, ok)
|
||||
ok = peekTopEStackIsValue(t, vm, 54)
|
||||
assert.True(t, ok)
|
||||
|
||||
// If we try to step again, we should get an error and HALT
|
||||
// because we have gone over the instruction pointer
|
||||
state, err = vm.step()
|
||||
assert.Equal(t, HALT, int(state))
|
||||
assert.NotNil(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestSimpleRun(t *testing.T) {
|
||||
|
||||
// Program pushes 20 and 34 to the stack
|
||||
// Adds them together
|
||||
// pushes 54 to the stack
|
||||
// Checks if result of addition and 54 are equal
|
||||
// Faults if not
|
||||
|
||||
// Push(20)
|
||||
// Push(34)
|
||||
// Add
|
||||
// Push(54)
|
||||
// Equal
|
||||
//THROWIFNOT
|
||||
builder := stack.NewBuilder()
|
||||
builder.EmitInt(20).EmitInt(34).EmitOpcode(stack.ADD)
|
||||
builder.EmitInt(54).EmitOpcode(stack.EQUAL).EmitOpcode(stack.THROWIFNOT)
|
||||
// Pass program to VM
|
||||
vm := NewVM(builder.Bytes())
|
||||
|
||||
_, err := vm.Run()
|
||||
assert.Nil(t, err)
|
||||
|
||||
}
|
||||
|
||||
// returns true if the value at the top of the evaluation stack is a integer
|
||||
// and equals the value passed in
|
||||
func peekTopEStackIsValue(t *testing.T, vm *VM, value int64) bool {
|
||||
item := peakTopEstack(t, vm)
|
||||
integer, err := item.Integer()
|
||||
assert.Nil(t, err)
|
||||
return value == integer.Value().Int64()
|
||||
}
|
||||
|
||||
// peaks the stack item on the top of the evaluation stack
|
||||
// if the current context and returns it
|
||||
func peakTopEstack(t *testing.T, vm *VM) stack.Item {
|
||||
ctx, err := vm.InvocationStack.CurrentContext()
|
||||
fmt.Println(err)
|
||||
assert.Nil(t, err)
|
||||
item, err := ctx.Estack.Peek(0)
|
||||
assert.Nil(t, err)
|
||||
return item
|
||||
}
|
||||
|
||||
// returns true if the total number of items on the evaluation stack
|
||||
// is equal to value
|
||||
func EstackLen(t *testing.T, vm *VM, value int) bool {
|
||||
ctx, err := vm.InvocationStack.CurrentContext()
|
||||
assert.Nil(t, err)
|
||||
return value == ctx.Estack.Len()
|
||||
}
|
Loading…
Reference in a new issue