Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 117 additions & 95 deletions accounts/abi/bind/precompilebind/precompile_contract_test_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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}}
}

`