Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add benchmark to template #705

Merged
merged 5 commits into from
Jun 28, 2023
Merged
Changes from 2 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
210 changes: 116 additions & 94 deletions accounts/abi/bind/precompilebind/precompile_contract_test_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,106 +23,109 @@ 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
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 run tests to your custom tests
darioush marked this conversation as resolved.
Show resolved Hide resolved
// 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}}
}

`