logoAcademy

Modify Autogenerated Tests

Learn how to modify autogenerated tests in Go.

The autogenerated tests will help us making sure, that our precompile throw an error in case not enough gas is supplied. To start, go to calculator/contract_test.go, where you will see the following:

// Code generated
// This file is a generated precompile contract test with the skeleton of test functions.
// The file is generated by a template. Please inspect every code and comment in this file before use.
 
package calculator
 
import (
    "testing"
 
    "github.com/ava-labs/subnet-evm/core/state"
    "github.com/ava-labs/subnet-evm/precompile/testutils"
    "github.com/ava-labs/subnet-evm/vmerrs"
    "github.com/ethereum/go-ethereum/common"
    "github.com/stretchr/testify/require"
)
 
// 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{
        "insufficient gas for add should fail": {
            Caller: common.Address{1},
            InputFn: func(t testing.TB) []byte {
                // CUSTOM CODE STARTS HERE
                // populate test input here
                testInput := AddInput{}
                input, err := PackAdd(testInput)
                require.NoError(t, err)
                return input
            },
            SuppliedGas: AddGasCost - 1,
            ReadOnly:    false,
            ExpectedErr: vmerrs.ErrOutOfGas.Error(),
        },
        "insufficient gas for nextTwo should fail": {
            Caller: common.Address{1},
            InputFn: func(t testing.TB) []byte {
                // CUSTOM CODE STARTS HERE
                // set test input to a value here
                var testInput *big.Int
                input, err := PackNextTwo(testInput)
                require.NoError(t, err)
                return input
            },
            SuppliedGas: NextTwoGasCost - 1,
            ReadOnly:    false,
            ExpectedErr: vmerrs.ErrOutOfGas.Error(),
        },
        "insufficient gas for repeat should fail": {
            Caller: common.Address{1},
            InputFn: func(t testing.TB) []byte {
                // CUSTOM CODE STARTS HERE
                // populate test input here
                testInput := RepeatInput{}
                input, err := PackRepeat(testInput)
                require.NoError(t, err)
                return input
            },
            SuppliedGas: RepeatGasCost - 1,
            ReadOnly:    false,
            ExpectedErr: vmerrs.ErrOutOfGas.Error(),
        },
    }
)
 
// TestCalculatorEmptyRun tests the Run function of the precompile contract.
func TestCalculatorEmptyRun(t *testing.T) {
    // Run tests.
    for name, test := range tests {
        t.Run(name, func(t *testing.T) {
            test.Run(t, Module, state.NewTestStateDB(t))
        })
    }
}
 
func BenchmarkCalculatorEmpty(b *testing.B) {
    // Benchmark tests.
    for name, test := range tests {
        b.Run(name, func(b *testing.B) {
            test.Bench(b, Module, state.NewTestStateDB(b))
        })
    }
}

There is a lot to digest in contract_test.go, but the file can be divided into the following three sections:

  • Unit Tests
  • TestCalculatorEmptyRun
  • BenchmarkCalculator

The autogenerated unit tests are stored in the variable var, which is a mapping from strings (the description of the tests cases) to individual unit tests (testutils.PrecompileTest). Upon inspecting the keys of each pair, you will see that all three autogenerated unit tests are checking the same thing that: add, nextTwo, and repeat fail if not enough gas is provided. Each test expects to fail when supplying too little gas:

{
  // ...
  SuppliedGas: RepeatGasCost - 1,
  ExpectedErr: vmerrs.ErrOutOfGas.Error(),
}

As of currently, if you attempt to build and run the test cases, you will not get very far because there is one step we need to do to: pass in arguments for each autogenerated unit test. For each variable testInput defined in each unit test, add an argument. What argument to put down does not matter, it just needs to be a valid argument. An example of what arguments to put in can be found below:

var (
    tests = map[string]testutils.PrecompileTest{
        "insufficient gas for add should fail": {
            Caller: common.Address{1},
            InputFn: func(t testing.TB) []byte {
                // CUSTOM CODE STARTS HERE
                // populate test input here
                testInput := AddInput{big.NewInt(1), big.NewInt(1)}
                input, err := PackAdd(testInput)
                require.NoError(t, err)
                return input
            },
            SuppliedGas: AddGasCost - 1,
            ReadOnly:    false,
            ExpectedErr: vmerrs.ErrOutOfGas.Error(),
        },
        "insufficient gas for nextTwo should fail": {
            Caller: common.Address{1},
            InputFn: func(t testing.TB) []byte {
                // CUSTOM CODE STARTS HERE
                // set test input to a value here
                // var testInput *big.Int
                testInput := big.NewInt(1)
                input, err := PackNextTwo(testInput)
                require.NoError(t, err)
                return input
            },
            SuppliedGas: NextTwoGasCost - 1,
            ReadOnly:    false,
            ExpectedErr: vmerrs.ErrOutOfGas.Error(),
        },
        "insufficient gas for repeat should fail": {
            Caller: common.Address{1},
            InputFn: func(t testing.TB) []byte {
                // CUSTOM CODE STARTS HERE
                // populate test input here
                testInput := RepeatInput{big.NewInt(1), "EGS"}
                input, err := PackRepeat(testInput)
                require.NoError(t, err)
                return input
            },
            SuppliedGas: RepeatGasCost - 1,
            ReadOnly:    false,
            ExpectedErr: vmerrs.ErrOutOfGas.Error(),
        },
    }
)

Now run the test by running the following command from the project root:

./scripts/build_test.sh

On this page

No Headings