OSDN Git Service

Merge pull request #201 from Bytom/v0.1
[bytom/vapor.git] / vendor / github.com / bytom / protocol / vm / ops_test.go
diff --git a/vendor/github.com/bytom/protocol/vm/ops_test.go b/vendor/github.com/bytom/protocol/vm/ops_test.go
new file mode 100644 (file)
index 0000000..da09cf8
--- /dev/null
@@ -0,0 +1,179 @@
+package vm
+
+import (
+       "fmt"
+       "reflect"
+       "testing"
+
+       "github.com/bytom/errors"
+       "github.com/bytom/math/checked"
+       "github.com/bytom/testutil"
+)
+
+func TestParseOp(t *testing.T) {
+       cases := []struct {
+               prog    []byte
+               pc      uint32
+               want    Instruction
+               wantErr error
+       }{{
+               prog: []byte{byte(OP_ADD)},
+               want: Instruction{Op: OP_ADD, Len: 1},
+       }, {
+               prog: []byte{byte(OP_16)},
+               want: Instruction{Op: OP_16, Data: []byte{16}, Len: 1},
+       }, {
+               prog: []byte{byte(OP_DATA_5), 1, 1, 1, 1, 1},
+               want: Instruction{Op: OP_DATA_5, Data: []byte{1, 1, 1, 1, 1}, Len: 6},
+       }, {
+               prog: []byte{byte(OP_DATA_5), 1, 1, 1, 1, 1, 255},
+               want: Instruction{Op: OP_DATA_5, Data: []byte{1, 1, 1, 1, 1}, Len: 6},
+       }, {
+               prog: []byte{byte(OP_PUSHDATA1), 1, 1},
+               want: Instruction{Op: OP_PUSHDATA1, Data: []byte{1}, Len: 3},
+       }, {
+               prog: []byte{byte(OP_PUSHDATA1), 1, 1, 255},
+               want: Instruction{Op: OP_PUSHDATA1, Data: []byte{1}, Len: 3},
+       }, {
+               prog: []byte{byte(OP_PUSHDATA2), 1, 0, 1},
+               want: Instruction{Op: OP_PUSHDATA2, Data: []byte{1}, Len: 4},
+       }, {
+               prog: []byte{byte(OP_PUSHDATA2), 1, 0, 1, 255},
+               want: Instruction{Op: OP_PUSHDATA2, Data: []byte{1}, Len: 4},
+       }, {
+               prog: []byte{byte(OP_PUSHDATA4), 1, 0, 0, 0, 1},
+               want: Instruction{Op: OP_PUSHDATA4, Data: []byte{1}, Len: 6},
+       }, {
+               prog: []byte{byte(OP_PUSHDATA4), 1, 0, 0, 0, 1, 255},
+               want: Instruction{Op: OP_PUSHDATA4, Data: []byte{1}, Len: 6},
+       }, {
+               prog:    []byte{},
+               wantErr: ErrShortProgram,
+       }, {
+               prog:    []byte{byte(OP_0)},
+               pc:      1,
+               wantErr: ErrShortProgram,
+       }, {
+               prog:    []byte{byte(OP_DATA_1)},
+               wantErr: ErrShortProgram,
+       }, {
+               prog:    []byte{byte(OP_PUSHDATA1)},
+               wantErr: ErrShortProgram,
+       }, {
+               prog:    []byte{byte(OP_PUSHDATA1), 1},
+               wantErr: ErrShortProgram,
+       }, {
+               prog:    []byte{byte(OP_PUSHDATA2)},
+               wantErr: ErrShortProgram,
+       }, {
+               prog:    []byte{byte(OP_PUSHDATA2), 1, 0},
+               wantErr: ErrShortProgram,
+       }, {
+               prog:    []byte{byte(OP_PUSHDATA4)},
+               wantErr: ErrShortProgram,
+       }, {
+               prog:    []byte{byte(OP_PUSHDATA4), 1, 0, 0, 0},
+               wantErr: ErrShortProgram,
+       }, {
+               pc:      71,
+               prog:    []byte{0x6d, 0x6b, 0xaa, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0, 0x0, 0x4e, 0xff, 0xff, 0xff, 0xff, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
+               wantErr: checked.ErrOverflow,
+       }}
+
+       for _, c := range cases {
+               t.Run(fmt.Sprintf("%d: %x", c.pc, c.prog), func(t *testing.T) {
+                       got, gotErr := ParseOp(c.prog, c.pc)
+
+                       if errors.Root(gotErr) != c.wantErr {
+                               t.Errorf("ParseOp(%x, %d) error = %v want %v", c.prog, c.pc, gotErr, c.wantErr)
+                       }
+
+                       if c.wantErr != nil {
+                               return
+                       }
+
+                       if !testutil.DeepEqual(got, c.want) {
+                               t.Errorf("ParseOp(%x, %d) = %+v want %+v", c.prog, c.pc, got, c.want)
+                       }
+               })
+       }
+}
+
+func TestParseProgram(t *testing.T) {
+       cases := []struct {
+               prog    []byte
+               want    []Instruction
+               wantErr error
+       }{
+               {
+                       prog: []byte{byte(OP_2), byte(OP_3), byte(OP_ADD), byte(OP_5), byte(OP_NUMEQUAL)},
+                       want: []Instruction{
+                               {Op: OP_2, Data: []byte{0x02}, Len: 1},
+                               {Op: OP_3, Data: []byte{0x03}, Len: 1},
+                               {Op: OP_ADD, Len: 1},
+                               {Op: OP_5, Data: []byte{0x05}, Len: 1},
+                               {Op: OP_NUMEQUAL, Len: 1},
+                       },
+               },
+               {
+                       prog: []byte{255},
+                       want: []Instruction{
+                               {Op: 255, Len: 1},
+                       },
+               },
+       }
+
+       for _, c := range cases {
+               got, gotErr := ParseProgram(c.prog)
+
+               if errors.Root(gotErr) != c.wantErr {
+                       t.Errorf("ParseProgram(%x) error = %v want %v", c.prog, gotErr, c.wantErr)
+               }
+
+               if c.wantErr != nil {
+                       continue
+               }
+
+               if !testutil.DeepEqual(got, c.want) {
+                       t.Errorf("ParseProgram(%x) = %+v want %+v", c.prog, got, c.want)
+               }
+       }
+}
+
+func TestIsPushData(t *testing.T) {
+       cases := []struct {
+               want    Instruction
+               wantErr error
+       }{
+               {
+                       want: Instruction{Op: OP_16, Data: []byte{16}, Len: 1},
+               },
+               {
+                       want: Instruction{Op: OP_DATA_32, Data: []byte{16}, Len: 1},
+               },
+               {
+                       want: Instruction{Op: OP_FALSE, Data: []byte{}, Len: 1},
+               },
+               {
+                       want: Instruction{Op: OP_TRUE, Data: []byte{1}, Len: 1},
+               },
+               {
+                       want:    Instruction{Op: OP_JUMP, Data: []byte{0x00000000}, Len: 1},
+                       wantErr: ErrShortProgram,
+               },
+               {
+                       want:    Instruction{Op: OP_ADD, Data: []byte{0x12, 0x56}, Len: 2},
+                       wantErr: ErrShortProgram,
+               },
+       }
+
+       for _, c := range cases {
+               if c.want.IsPushdata() {
+                       t.Logf("check success")
+               } else if c.wantErr != nil {
+                       t.Logf("check err success")
+               } else {
+                       t.Errorf("check false: %v -- %v", reflect.ValueOf(ops[OP_1].fn), reflect.ValueOf(ops[c.want.Op].fn))
+               }
+       }
+}