diff --git a/accounts/abi/bind/precompilebind/precompile_contract_test_template.go b/accounts/abi/bind/precompilebind/precompile_contract_test_template.go index 10c1a12f8e..c8ae9a2eb9 100644 --- a/accounts/abi/bind/precompilebind/precompile_contract_test_template.go +++ b/accounts/abi/bind/precompilebind/precompile_contract_test_template.go @@ -23,109 +23,112 @@ import ( "github.com/stretchr/testify/require" ) -// TestRun tests the Run function of the precompile contract. -// These tests are run against the precompile contract directly with -// the given input and expected output. They're just a guide to -// help you write your own tests. These tests are for general cases like -// allowlist, readOnly behaviour, and gas cost. You should write your own -// tests for specific cases. -func TestRun(t *testing.T) { - tests := map[string]testutils.PrecompileTest{ - {{- $contract := .Contract}} - {{- $structs := .Structs}} - {{- range .Contract.Funcs}} - {{- $func := .}} - {{- if $contract.AllowList}} - {{- $roles := mkList "NoRole" "Enabled" "Admin"}} - {{- range $role := $roles}} - {{- $fail := and (not $func.Original.IsConstant) (eq $role "NoRole")}} - "calling {{decapitalise $func.Normalized.Name}} from {{$role}} should {{- if $fail}} fail {{- else}} succeed{{- end}}": { - Caller: allowlist.Test{{$role}}Addr, - BeforeHook: allowlist.SetDefaultRoles(Module.Address), - InputFn: func(t testing.TB) []byte { - {{- if len $func.Normalized.Inputs | lt 1}} + // These tests are run against the precompile contract directly with + // the given input and expected output. They're just a guide to + // help you write your own tests. These tests are for general cases like + // allowlist, readOnly behaviour, and gas cost. You should write your own + // tests for specific cases. + var( + tests = map[string]testutils.PrecompileTest{ + {{- $contract := .Contract}} + {{- $structs := .Structs}} + {{- range .Contract.Funcs}} + {{- $func := .}} + {{- if $contract.AllowList}} + {{- $roles := mkList "NoRole" "Enabled" "Admin"}} + {{- range $role := $roles}} + {{- $fail := and (not $func.Original.IsConstant) (eq $role "NoRole")}} + "calling {{decapitalise $func.Normalized.Name}} from {{$role}} should {{- if $fail}} fail {{- else}} succeed{{- end}}": { + Caller: allowlist.Test{{$role}}Addr, + BeforeHook: allowlist.SetDefaultRoles(Module.Address), + InputFn: func(t testing.TB) []byte { + {{- if len $func.Normalized.Inputs | lt 1}} + // CUSTOM CODE STARTS HERE + // populate test input here + testInput := {{capitalise $func.Normalized.Name}}Input{} + input, err := Pack{{$func.Normalized.Name}}(testInput) + {{- else if len $func.Normalized.Inputs | eq 1 }} + {{- $input := index $func.Normalized.Inputs 0}} + // CUSTOM CODE STARTS HERE + // set test input to a value here + var testInput {{bindtype $input.Type $structs}} + input, err := Pack{{$func.Normalized.Name}}(testInput) + {{- else}} + input, err := Pack{{$func.Normalized.Name}}() + {{- end}} + require.NoError(t, err) + return input + }, + {{- if not $fail}} + // This test is for a successful call. You can set the expected output here. // CUSTOM CODE STARTS HERE - // populate test input here - testInput := {{capitalise $func.Normalized.Name}}Input{} - input, err := Pack{{$func.Normalized.Name}}(testInput) - {{- else if len $func.Normalized.Inputs | eq 1 }} - {{- $input := index $func.Normalized.Inputs 0}} - // CUSTOM CODE STARTS HERE - // set test input to a value here - var testInput {{bindtype $input.Type $structs}} - input, err := Pack{{$func.Normalized.Name}}(testInput) - {{- else}} - input, err := Pack{{$func.Normalized.Name}}() + ExpectedRes: []byte{}, {{- end}} - require.NoError(t, err) - return input + SuppliedGas: {{$func.Normalized.Name}}GasCost, + ReadOnly: false, + ExpectedErr: {{if $fail}} ErrCannot{{$func.Normalized.Name}}.Error() {{- else}} "" {{- end}}, }, - {{- if not $fail}} - // This test is for a successful call. You can set the expected output here. - // CUSTOM CODE STARTS HERE - ExpectedRes: []byte{}, {{- end}} - SuppliedGas: {{$func.Normalized.Name}}GasCost, - ReadOnly: false, - ExpectedErr: {{if $fail}} ErrCannot{{$func.Normalized.Name}}.Error() {{- else}} "" {{- end}}, - }, - {{- end}} - {{- end}} - {{- if not $func.Original.IsConstant}} - "readOnly {{decapitalise $func.Normalized.Name}} should fail": { - Caller: common.Address{1}, - InputFn: func(t testing.TB) []byte { - {{- if len $func.Normalized.Inputs | lt 1}} - // CUSTOM CODE STARTS HERE - // populate test input here - testInput := {{capitalise $func.Normalized.Name}}Input{} - input, err := Pack{{$func.Normalized.Name}}(testInput) - {{- else if len $func.Normalized.Inputs | eq 1 }} - {{- $input := index $func.Normalized.Inputs 0}} - // CUSTOM CODE STARTS HERE - // set test input to a value here - var testInput {{bindtype $input.Type $structs}} - input, err := Pack{{$func.Normalized.Name}}(testInput) - {{- else}} - input, err := Pack{{$func.Normalized.Name}}() - {{- end}} - require.NoError(t, err) - return input + {{- end}} + {{- if not $func.Original.IsConstant}} + "readOnly {{decapitalise $func.Normalized.Name}} should fail": { + Caller: common.Address{1}, + InputFn: func(t testing.TB) []byte { + {{- if len $func.Normalized.Inputs | lt 1}} + // CUSTOM CODE STARTS HERE + // populate test input here + testInput := {{capitalise $func.Normalized.Name}}Input{} + input, err := Pack{{$func.Normalized.Name}}(testInput) + {{- else if len $func.Normalized.Inputs | eq 1 }} + {{- $input := index $func.Normalized.Inputs 0}} + // CUSTOM CODE STARTS HERE + // set test input to a value here + var testInput {{bindtype $input.Type $structs}} + input, err := Pack{{$func.Normalized.Name}}(testInput) + {{- else}} + input, err := Pack{{$func.Normalized.Name}}() + {{- end}} + require.NoError(t, err) + return input + }, + SuppliedGas: {{$func.Normalized.Name}}GasCost, + ReadOnly: true, + ExpectedErr: vmerrs.ErrWriteProtection.Error(), }, - SuppliedGas: {{$func.Normalized.Name}}GasCost, - ReadOnly: true, - ExpectedErr: vmerrs.ErrWriteProtection.Error(), - }, - {{- end}} - "insufficient gas for {{decapitalise $func.Normalized.Name}} should fail": { - Caller: common.Address{1}, - InputFn: func(t testing.TB) []byte { - {{- if len $func.Normalized.Inputs | lt 1}} - // CUSTOM CODE STARTS HERE - // populate test input here - testInput := {{capitalise $func.Normalized.Name}}Input{} - input, err := Pack{{$func.Normalized.Name}}(testInput) - {{- else if len $func.Normalized.Inputs | eq 1 }} - {{- $input := index $func.Normalized.Inputs 0}} - // CUSTOM CODE STARTS HERE - // set test input to a value here - var testInput {{bindtype $input.Type $structs}} - input, err := Pack{{$func.Normalized.Name}}(testInput) - {{- else}} - input, err := Pack{{$func.Normalized.Name}}() - {{- end}} - require.NoError(t, err) - return input + {{- end}} + "insufficient gas for {{decapitalise $func.Normalized.Name}} should fail": { + Caller: common.Address{1}, + InputFn: func(t testing.TB) []byte { + {{- if len $func.Normalized.Inputs | lt 1}} + // CUSTOM CODE STARTS HERE + // populate test input here + testInput := {{capitalise $func.Normalized.Name}}Input{} + input, err := Pack{{$func.Normalized.Name}}(testInput) + {{- else if len $func.Normalized.Inputs | eq 1 }} + {{- $input := index $func.Normalized.Inputs 0}} + // CUSTOM CODE STARTS HERE + // set test input to a value here + var testInput {{bindtype $input.Type $structs}} + input, err := Pack{{$func.Normalized.Name}}(testInput) + {{- else}} + input, err := Pack{{$func.Normalized.Name}}() + {{- end}} + require.NoError(t, err) + return input + }, + SuppliedGas: {{$func.Normalized.Name}}GasCost - 1, + ReadOnly: false, + ExpectedErr: vmerrs.ErrOutOfGas.Error(), }, - SuppliedGas: {{$func.Normalized.Name}}GasCost - 1, - ReadOnly: false, - ExpectedErr: vmerrs.ErrOutOfGas.Error(), - }, - {{- end}} - } + {{- end}} + } + ) + +// Test{{.Contract.Type}}Run tests the Run function of the precompile contract. +func Test{{.Contract.Type}}Run(t *testing.T) { {{- if .Contract.AllowList}} // Run tests with allowlist tests. - // This adds allowlist run tests to your custom tests + // This adds allowlist tests to your custom tests // and runs them all together. // Even if you don't add any custom tests, keep this. This will still // run the default allowlist tests. @@ -139,4 +142,23 @@ func TestRun(t *testing.T) { } {{- end}} } + +func Benchmark{{.Contract.Type}}(b *testing.B) { + {{- if .Contract.AllowList}} + // Benchmark tests with allowlist tests. + // This adds allowlist tests to your custom tests + // and benchmarks them all together. + // Even if you don't add any custom tests, keep this. This will still + // run the default allowlist tests. + allowlist.BenchPrecompileWithAllowList(b, Module, state.NewTestStateDB, tests) + {{- else}} + // Benchmark tests. + for name, test := range tests { + b.Run(name, func(b *testing.B) { + test.Bench(b, module, newStateDB(b)) + }) + } + {{- end}} +} + `