mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-28 15:46:43 +00:00
accounts/abi/bind: make link test case failure output the index of the subtest that failed.
This commit is contained in:
parent
b4f1a3c009
commit
7f301229bf
2 changed files with 175 additions and 30 deletions
124
accounts/abi/bind/bindv2_test.go
Normal file
124
accounts/abi/bind/bindv2_test.go
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
package bind
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
type bindV2Test struct {
|
||||
name string
|
||||
abis []string
|
||||
bytecodes []string
|
||||
types []string
|
||||
|
||||
expectedBindings string
|
||||
}
|
||||
|
||||
func bind(test *bindV2Test) (bound string, err error) {
|
||||
var (
|
||||
abis []string
|
||||
bins []string
|
||||
types []string
|
||||
)
|
||||
libs := make(map[string]string)
|
||||
for i := 0; i < len(test.types); i++ {
|
||||
// fully qualified name is of the form <solFilePath>:<type>
|
||||
typeName := test.types[i]
|
||||
bin := test.bytecodes[i]
|
||||
abis = append(abis, test.abis[i])
|
||||
bins = append(bins, bin)
|
||||
types = append(types, typeName)
|
||||
|
||||
// Derive the library placeholder which is a 34 character prefix of the
|
||||
// hex encoding of the keccak256 hash of the fully qualified library name.
|
||||
// Note that the fully qualified library name is the path of its source
|
||||
// file and the library name separated by ":".
|
||||
libPattern := crypto.Keccak256Hash([]byte(typeName)).String()[2:36] // the first 2 chars are 0x
|
||||
libs[libPattern] = typeName
|
||||
}
|
||||
code, err := BindV2(types, abis, bins, "bindv2test", libs, make(map[string]string))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error creating bindings: %v", err)
|
||||
}
|
||||
|
||||
return code, nil
|
||||
}
|
||||
|
||||
var bindTests2 = []bindV2Test{
|
||||
{
|
||||
"Empty",
|
||||
[]string{`[]`},
|
||||
[]string{`606060405260068060106000396000f3606060405200`},
|
||||
nil,
|
||||
`// Code generated via abigen V2 - DO NOT EDIT.
|
||||
// This file is a generated binding and any manual changes will be lost.
|
||||
|
||||
package bindv2test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var (
|
||||
_ = errors.New
|
||||
_ = big.NewInt
|
||||
_ = bind.Bind
|
||||
_ = common.Big1
|
||||
_ = types.BloomLookup
|
||||
_ = abi.ConvertType
|
||||
)
|
||||
`,
|
||||
},
|
||||
{
|
||||
"Token",
|
||||
[]string{`[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_extraData","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"spentAllowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"},{"name":"tokenName","type":"string"},{"name":"decimalUnits","type":"uint8"},{"name":"tokenSymbol","type":"string"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]`},
|
||||
[]string{`60606040526040516107fd3803806107fd83398101604052805160805160a05160c051929391820192909101600160a060020a0333166000908152600360209081526040822086905581548551838052601f6002600019610100600186161502019093169290920482018390047f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56390810193919290918801908390106100e857805160ff19168380011785555b506101189291505b8082111561017157600081556001016100b4565b50506002805460ff19168317905550505050610658806101a56000396000f35b828001600101855582156100ac579182015b828111156100ac5782518260005055916020019190600101906100fa565b50508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017557805160ff19168380011785555b506100c89291506100b4565b5090565b82800160010185558215610165579182015b8281111561016557825182600050559160200191906001019061018756606060405236156100775760e060020a600035046306fdde03811461007f57806323b872dd146100dc578063313ce5671461010e57806370a082311461011a57806395d89b4114610132578063a9059cbb1461018e578063cae9ca51146101bd578063dc3080f21461031c578063dd62ed3e14610341575b610365610002565b61036760008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b6103d5600435602435604435600160a060020a038316600090815260036020526040812054829010156104f357610002565b6103e760025460ff1681565b6103d560043560036020526000908152604090205481565b610367600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b610365600435602435600160a060020a033316600090815260036020526040902054819010156103f157610002565b60806020604435600481810135601f8101849004909302840160405260608381526103d5948235946024803595606494939101919081908382808284375094965050505050505060006000836004600050600033600160a060020a03168152602001908152602001600020600050600087600160a060020a031681526020019081526020016000206000508190555084905080600160a060020a0316638f4ffcb1338630876040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b50955050505050506000604051808303816000876161da5a03f11561000257505050509392505050565b6005602090815260043560009081526040808220909252602435815220546103d59081565b60046020818152903560009081526040808220909252602435815220546103d59081565b005b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a03821660009081526040902054808201101561041357610002565b806003600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550806003600050600084600160a060020a0316815260200190815260200160002060008282825054019250508190555081600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b505050505081565b600160a060020a03831681526040812054808301101561051257610002565b600160a060020a0380851680835260046020908152604080852033949094168086529382528085205492855260058252808520938552929052908220548301111561055c57610002565b816003600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816003600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816005600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054019250508190555082600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3939250505056`},
|
||||
nil,
|
||||
`// Code generated via abigen V2 - DO NOT EDIT.
|
||||
// This file is a generated binding and any manual changes will be lost.
|
||||
|
||||
package bindv2test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var (
|
||||
_ = errors.New
|
||||
_ = big.NewInt
|
||||
_ = bind.Bind
|
||||
_ = common.Big1
|
||||
_ = types.BloomLookup
|
||||
_ = abi.ConvertType
|
||||
)
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
func TestBindingV2(t *testing.T) {
|
||||
for _, tc := range bindTests2 {
|
||||
code, err := bind(&tc)
|
||||
if err != nil {
|
||||
t.Fatalf("got error from bind: %v", err)
|
||||
}
|
||||
if code != tc.expectedBindings {
|
||||
t.Fatalf("'%s'\n!=\n'%s'\n", code, tc.expectedBindings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ func __linkDeps(metadata MetaData, depMap map[string]*MetaData, roots *map[strin
|
|||
return linked
|
||||
}
|
||||
|
||||
func testLinkCase(t *testing.T, tcInput linkTestCaseInput) {
|
||||
func testLinkCase(tcInput linkTestCaseInput) error {
|
||||
testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
|
||||
var testAddrNonce uint64
|
||||
overridesAddrs := make(map[common.Address]struct{})
|
||||
|
|
@ -159,7 +159,7 @@ func testLinkCase(t *testing.T, tcInput linkTestCaseInput) {
|
|||
var dep common.Address
|
||||
dep.SetBytes(deployer[i : i+20])
|
||||
if _, ok := overridesAddrs[dep]; !ok {
|
||||
t.Fatalf("reference to dependent contract that has not yet been deployed: %x\n", dep)
|
||||
return common.Address{}, nil, fmt.Errorf("reference to dependent contract that has not yet been deployed: %x\n", dep)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -190,55 +190,60 @@ func testLinkCase(t *testing.T, tcInput linkTestCaseInput) {
|
|||
deployParams := NewDeploymentParams(contractsList, nil, overrides)
|
||||
res, err := LinkAndDeploy(deployParams, mockDeploy)
|
||||
if err != nil {
|
||||
t.Fatalf("got error from LinkAndDeploy: %v\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if len(res.Txs) != len(tcInput.expectDeployed) {
|
||||
t.Fatalf("got %d deployed contracts. expected %d.\n", len(res.Addrs), len(tcInput.expectDeployed))
|
||||
return fmt.Errorf("got %d deployed contracts. expected %d.\n", len(res.Addrs), len(tcInput.expectDeployed))
|
||||
}
|
||||
for contract, _ := range tcInput.expectDeployed {
|
||||
pattern := crypto.Keccak256Hash([]byte(string(contract))).String()[2:36]
|
||||
if _, ok := res.Addrs[pattern]; !ok {
|
||||
t.Fatalf("expected contract %s was not deployed\n", string(contract))
|
||||
return fmt.Errorf("expected contract %s was not deployed\n", string(contract))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestContractLinking(t *testing.T) {
|
||||
var linkTestCases = []linkTestCaseInput{
|
||||
// test simple contract without any dependencies or overrides
|
||||
testLinkCase(t, linkTestCaseInput{
|
||||
{
|
||||
map[rune][]rune{
|
||||
'a': {}},
|
||||
map[rune]struct{}{},
|
||||
map[rune]struct{}{
|
||||
'a': {}}})
|
||||
'a': {}},
|
||||
},
|
||||
// test deployment of a contract that depends on somes libraries.
|
||||
testLinkCase(t, linkTestCaseInput{
|
||||
{
|
||||
map[rune][]rune{
|
||||
'a': {'b', 'c', 'd', 'e'}},
|
||||
map[rune]struct{}{},
|
||||
map[rune]struct{}{
|
||||
'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}}})
|
||||
'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}},
|
||||
},
|
||||
// test deployment of a contract that depends on some libraries,
|
||||
// one of which has its own library dependencies.
|
||||
testLinkCase(t, linkTestCaseInput{
|
||||
{
|
||||
map[rune][]rune{
|
||||
'a': {'b', 'c', 'd', 'e'},
|
||||
'e': {'f', 'g', 'h', 'i'}},
|
||||
map[rune]struct{}{},
|
||||
map[rune]struct{}{
|
||||
'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {}, 'i': {}}})
|
||||
'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {}, 'i': {}},
|
||||
},
|
||||
// test single contract only without deps
|
||||
testLinkCase(t, linkTestCaseInput{
|
||||
{
|
||||
map[rune][]rune{
|
||||
'a': {}},
|
||||
map[rune]struct{}{},
|
||||
map[rune]struct{}{
|
||||
'a': {},
|
||||
}})
|
||||
},
|
||||
},
|
||||
// test that libraries at different levels of the tree can share deps,
|
||||
// and that these shared deps will only be deployed once.
|
||||
testLinkCase(t, linkTestCaseInput{
|
||||
{
|
||||
map[rune][]rune{
|
||||
'a': {'b', 'c', 'd', 'e'},
|
||||
'e': {'f', 'g', 'h', 'i', 'm'},
|
||||
|
|
@ -246,56 +251,63 @@ func TestContractLinking(t *testing.T) {
|
|||
map[rune]struct{}{},
|
||||
map[rune]struct{}{
|
||||
'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {}, 'i': {}, 'j': {}, 'k': {}, 'l': {}, 'm': {},
|
||||
}})
|
||||
},
|
||||
},
|
||||
// test two contracts can be deployed which don't share deps
|
||||
testLinkCase(t, linkTestCaseInput{
|
||||
linkTestCaseInput{
|
||||
map[rune][]rune{
|
||||
'a': {'b', 'c', 'd', 'e'},
|
||||
'f': {'g', 'h', 'i', 'j'}},
|
||||
map[rune]struct{}{},
|
||||
map[rune]struct{}{
|
||||
'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {}, 'i': {}, 'j': {},
|
||||
}})
|
||||
},
|
||||
},
|
||||
// test two contracts can be deployed which share deps
|
||||
testLinkCase(t, linkTestCaseInput{
|
||||
linkTestCaseInput{
|
||||
map[rune][]rune{
|
||||
'a': {'b', 'c', 'd', 'e'},
|
||||
'f': {'g', 'c', 'd', 'h'}},
|
||||
map[rune]struct{}{},
|
||||
map[rune]struct{}{
|
||||
'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {},
|
||||
}})
|
||||
},
|
||||
},
|
||||
// test one contract with overrides for all lib deps
|
||||
testLinkCase(t, linkTestCaseInput{
|
||||
linkTestCaseInput{
|
||||
map[rune][]rune{
|
||||
'a': {'b', 'c', 'd', 'e'}},
|
||||
map[rune]struct{}{'b': {}, 'c': {}, 'd': {}, 'e': {}},
|
||||
map[rune]struct{}{
|
||||
'a': {}}})
|
||||
'a': {}},
|
||||
},
|
||||
// test one contract with overrides for some lib deps
|
||||
testLinkCase(t, linkTestCaseInput{
|
||||
linkTestCaseInput{
|
||||
map[rune][]rune{
|
||||
'a': {'b', 'c'}},
|
||||
map[rune]struct{}{'b': {}, 'c': {}},
|
||||
map[rune]struct{}{
|
||||
'a': {}}})
|
||||
'a': {}},
|
||||
},
|
||||
// test deployment of a contract with overrides
|
||||
testLinkCase(t, linkTestCaseInput{
|
||||
linkTestCaseInput{
|
||||
map[rune][]rune{
|
||||
'a': {}},
|
||||
map[rune]struct{}{'a': {}},
|
||||
map[rune]struct{}{}})
|
||||
map[rune]struct{}{},
|
||||
},
|
||||
// two contracts ('a' and 'f') share some dependencies. contract 'a' is marked as an override. expect that any of
|
||||
// its depdencies that aren't shared with 'f' are not deployed.
|
||||
testLinkCase(t, linkTestCaseInput{map[rune][]rune{
|
||||
linkTestCaseInput{map[rune][]rune{
|
||||
'a': {'b', 'c', 'd', 'e'},
|
||||
'f': {'g', 'c', 'd', 'h'}},
|
||||
map[rune]struct{}{'a': {}},
|
||||
map[rune]struct{}{
|
||||
'f': {}, 'g': {}, 'c': {}, 'd': {}, 'h': {}}})
|
||||
'f': {}, 'g': {}, 'c': {}, 'd': {}, 'h': {}},
|
||||
},
|
||||
// test nested libraries that share deps at different levels of the tree... with override.
|
||||
// same condition as above test: no sub-dependencies of
|
||||
testLinkCase(t, linkTestCaseInput{
|
||||
{
|
||||
map[rune][]rune{
|
||||
'a': {'b', 'c', 'd', 'e'},
|
||||
'e': {'f', 'g', 'h', 'i', 'm'},
|
||||
|
|
@ -305,5 +317,14 @@ func TestContractLinking(t *testing.T) {
|
|||
'i': {},
|
||||
},
|
||||
map[rune]struct{}{
|
||||
'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {}, 'm': {}}})
|
||||
'a': {}, 'b': {}, 'c': {}, 'd': {}, 'e': {}, 'f': {}, 'g': {}, 'h': {}, 'm': {}},
|
||||
},
|
||||
}
|
||||
|
||||
func TestContractLinking(t *testing.T) {
|
||||
for i, tc := range linkTestCases {
|
||||
if err := testLinkCase(tc); err != nil {
|
||||
t.Fatalf("test case %d failed: %v", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue