diff options
author | Gustav Simonsson <gustav.simonsson@gmail.com> | 2015-04-10 17:55:31 +0800 |
---|---|---|
committer | Gustav Simonsson <gustav.simonsson@gmail.com> | 2015-04-10 17:55:31 +0800 |
commit | 9ac5671c18ae3c36370981cd42a99639f9799042 (patch) | |
tree | 8957bac6f83e33209686d2dc221783bc5b42cce7 /tests | |
parent | 1e18f4544b7e85619c8902a5e2fb408984f277b6 (diff) | |
download | go-tangerine-9ac5671c18ae3c36370981cd42a99639f9799042.tar.gz go-tangerine-9ac5671c18ae3c36370981cd42a99639f9799042.tar.zst go-tangerine-9ac5671c18ae3c36370981cd42a99639f9799042.zip |
Add TransactionTests wrapped as Go tests
* Add initial go wrapping for TransactionTests with some tests
disabled in lieu of consistent HEX encodings and a few other
pending bugfixes
* TODO: Consider better way of perhaps modelling each test in
the JSON files as a single Go test, instead of one Go test per
JSON file
Diffstat (limited to 'tests')
-rw-r--r-- | tests/blocktest.go | 22 | ||||
-rw-r--r-- | tests/transaction_test.go | 58 | ||||
-rw-r--r-- | tests/transaction_test_util.go | 134 |
3 files changed, 211 insertions, 3 deletions
diff --git a/tests/blocktest.go b/tests/blocktest.go index 6b8ee9d4a..84b70678d 100644 --- a/tests/blocktest.go +++ b/tests/blocktest.go @@ -81,7 +81,7 @@ type BlockTest struct { // LoadBlockTests loads a block test JSON file. func LoadBlockTests(file string) (map[string]*BlockTest, error) { bt := make(map[string]*btJSON) - if err := loadJSON(file, &bt); err != nil { + if err := LoadJSON(file, &bt); err != nil { return nil, err } out := make(map[string]*BlockTest) @@ -250,6 +250,14 @@ func mustConvertBigInt10(in string) *big.Int { return out } +func mustConvertBigIntHex(in string) *big.Int { + out, ok := new(big.Int).SetString(in, 16) + if !ok { + panic(fmt.Errorf("invalid integer: %q", in)) + } + return out +} + func mustConvertUint(in string) uint64 { out, err := strconv.ParseUint(in, 0, 64) if err != nil { @@ -258,8 +266,16 @@ func mustConvertUint(in string) uint64 { return out } -// loadJSON reads the given file and unmarshals its content. -func loadJSON(file string, val interface{}) error { +func mustConvertUintHex(in string) uint64 { + out, err := strconv.ParseUint(in, 16, 64) + if err != nil { + panic(fmt.Errorf("invalid integer: %q", in)) + } + return out +} + +// LoadJSON reads the given file and unmarshals its content. +func LoadJSON(file string, val interface{}) error { content, err := ioutil.ReadFile(file) if err != nil { return err diff --git a/tests/transaction_test.go b/tests/transaction_test.go new file mode 100644 index 000000000..5e903e4b4 --- /dev/null +++ b/tests/transaction_test.go @@ -0,0 +1,58 @@ +package tests + +import ( + "testing" +) + +func TestTransactions(t *testing.T) { + notWorking := make(map[string]bool, 100) + // TODO: all commented out tests should work! + + snafus := []string{ + "AddressLessThan20Prefixed0", + "DataTest", + "EmptyTransaction", + "RightVRSTest", + "SenderTest", + "TransactionWithGasLimitxPriceOverflow", + "TransactionWithHihghGas", + "TransactionWithHihghGasPrice", + "TransactionWithHihghNonce", + "TransactionWithHihghValue", + "TransactionWithRvalueWrongSize", + "TransactionWithSvalueHigh", + "TransactionWithSvalueTooHigh", + "TransactionWithSvalueWrongSize", + "ValuesAsDec", + "ValuesAsHex", + "libsecp256k1test", + "unpadedRValue"} + + for _, name := range snafus { + notWorking[name] = true + } + + var err error + err = RunTransactionTests("./files/TransactionTests/ttTransactionTest.json", + notWorking) + if err != nil { + t.Fatal(err) + } +} + +func TestWrongRLPTransactions(t *testing.T) { + notWorking := make(map[string]bool, 100) + // TODO: all commented out tests should work! + notWorking[""] = true + notWorking[""] = true + notWorking[""] = true + notWorking[""] = true + notWorking[""] = true + + var err error + err = RunTransactionTests("./files/TransactionTests/ttWrongRLPTransaction.json", + notWorking) + if err != nil { + t.Fatal(err) + } +} diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go new file mode 100644 index 000000000..800891887 --- /dev/null +++ b/tests/transaction_test_util.go @@ -0,0 +1,134 @@ +package tests + +import ( + "bytes" + "fmt" + "math/big" + "runtime" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// Transaction Test JSON Format +type TtTransaction struct { + Data string + GasLimit string + GasPrice string + Nonce string + R string + S string + To string + V string + Value string +} + +type TransactionTest struct { + Rlp string + Sender string + Transaction TtTransaction +} + +func RunTransactionTests(file string, notWorking map[string]bool) error { + bt := make(map[string]TransactionTest) + if err := LoadJSON(file, &bt); err != nil { + return err + } + for name, in := range bt { + var err error + // TODO: remove this, we currently ignore some tests which are broken + if !notWorking[name] { + if err = runTest(in); err != nil { + return fmt.Errorf("bad test %s: %v", name, err) + } + fmt.Println("Test passed:", name) + } + } + return nil +} + +func runTest(txTest TransactionTest) (err error) { + expectedSender, expectedTo, expectedData, rlpBytes, expectedGasLimit, expectedGasPrice, expectedValue, expectedR, expectedS, expectedNonce, expectedV, err := convertTestTypes(txTest) + + if err != nil { + if txTest.Sender == "" { // tx is invalid and this is expected (test OK) + return nil + } else { + return err // tx is invalid and this is NOT expected (test FAIL) + } + } + tx := new(types.Transaction) + rlp.DecodeBytes(rlpBytes, tx) + + sender, err := tx.From() + if err != nil { + return err + } + + if expectedSender != sender { + return fmt.Errorf("Sender mismatch: %v %v", expectedSender, sender) + } + if !bytes.Equal(expectedData, tx.Payload) { + return fmt.Errorf("Tx input data mismatch: %#v %#v", expectedData, tx.Payload) + } + if expectedGasLimit.Cmp(tx.GasLimit) != 0 { + return fmt.Errorf("GasLimit mismatch: %v %v", expectedGasLimit, tx.GasLimit) + } + if expectedGasPrice.Cmp(tx.Price) != 0 { + return fmt.Errorf("GasPrice mismatch: %v %v", expectedGasPrice, tx.Price) + } + if expectedNonce != tx.AccountNonce { + return fmt.Errorf("Nonce mismatch: %v %v", expectedNonce, tx.AccountNonce) + } + if expectedR.Cmp(tx.R) != 0 { + return fmt.Errorf("R mismatch: %v %v", expectedR, tx.R) + } + if expectedS.Cmp(tx.S) != 0 { + return fmt.Errorf("S mismatch: %v %v", expectedS, tx.S) + } + if expectedV != uint64(tx.V) { + return fmt.Errorf("V mismatch: %v %v", expectedV, uint64(tx.V)) + } + if expectedTo != *tx.Recipient { + return fmt.Errorf("To mismatch: %v %v", expectedTo, *tx.Recipient) + } + if expectedValue.Cmp(tx.Amount) != 0 { + return fmt.Errorf("Value mismatch: %v %v", expectedValue, tx.Amount) + } + + return nil +} + +func convertTestTypes(txTest TransactionTest) (sender, to common.Address, + txInputData, rlpBytes []byte, + gasLimit, gasPrice, value, r, s *big.Int, + nonce, v uint64, + err error) { + + defer func() { + if recovered := recover(); recovered != nil { + buf := make([]byte, 64<<10) + buf = buf[:runtime.Stack(buf, false)] + err = fmt.Errorf("%v\n%s", recovered, buf) + } + }() + + sender = mustConvertAddress(txTest.Sender) + to = mustConvertAddress(txTest.Transaction.To) + + txInputData = mustConvertBytes(txTest.Transaction.Data) + rlpBytes = mustConvertBytes(txTest.Rlp) + + gasLimit = mustConvertBigIntHex(txTest.Transaction.GasLimit) + gasPrice = mustConvertBigIntHex(txTest.Transaction.GasPrice) + value = mustConvertBigIntHex(txTest.Transaction.Value) + + r = common.Bytes2Big(mustConvertBytes(txTest.Transaction.R)) + s = common.Bytes2Big(mustConvertBytes(txTest.Transaction.S)) + + nonce = mustConvertUintHex(txTest.Transaction.Nonce) + v = mustConvertUintHex(txTest.Transaction.V) + + return sender, to, txInputData, rlpBytes, gasLimit, gasPrice, value, r, s, nonce, v, nil +} |