• mbaxter's avatar
    cannon: Add MTCannon-specific differential tests (#11605) · e53a86ac
    mbaxter authored
    * cannon: Implement multithreaded clone fuzz test
    
    * cannon: Add more clone evm tests
    
    * cannon: Add evm test for GetTID syscall
    
    * cannon: Add evm test for SysExit
    
    * cannon: Add evm test for popping exited threads from the stack
    
    * cannon: Fix futex wait handling, add evm test
    
    * cannon: Add evm test for handling waiting thread
    
    * cannon: Add test utils for defining / validating MTState expectations
    
    * cannon: Add tests for futex wake, wake traversal
    
    * cannon: Add test for SysYield
    
    * cannon: Add SysOpen test, todos
    
    * cannon: Add test for SchedQuantum preemption, fix inconsistency
    
    * cannon: Add tests for noop, unsupported syscalls
    
    * cannon: Remove duplicate constants
    
    * cannon: Add tests for unsupported futex ops
    
    * cannon: Group traversal tests, fix TestEVM_WakeupTraversalStep
    
    * cannon: Add tests for nanosleep
    
    * cannon: Add additional testcase for wakeup traversal
    
    * cannon: Tweak futex wake tests
    
    * cannon: Update mt fuzz test to use new test utils
    
    * cannon: Rename contructor method for consistency
    
    * cannon: Add some simple tests for ExpectedMTState util
    
    * cannon: Add another validation test
    
    * cannon: Move syscall lists to tests where they're used
    
    * cannon: Add comment
    
    * cannon: Extract some evm test helpers
    
    * cannon: Cleanup - use require.Equalf for formatting
    
    * cannon: Rename test util to AssertEVMReverts
    
    * cannon: Add GetThreadStacks helper
    
    * cannon: Add a few more traversal tests
    e53a86ac
fuzz_evm_multithreaded_test.go 2.29 KB
package tests

import (
	"os"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/ethereum-optimism/optimism/cannon/mipsevm/exec"
	"github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded"
	mttestutil "github.com/ethereum-optimism/optimism/cannon/mipsevm/multithreaded/testutil"
	"github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil"
)

func FuzzStateSyscallCloneMT(f *testing.F) {
	v := GetMultiThreadedTestCase(f)
	f.Fuzz(func(t *testing.T, nextThreadId, stackPtr uint32, seed int64) {
		goVm := v.VMFactory(nil, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(seed))
		state := mttestutil.GetMtState(t, goVm)
		// Update existing threads to avoid collision with nextThreadId
		if mttestutil.FindThread(state, nextThreadId) != nil {
			for i, t := range mttestutil.GetAllThreads(state) {
				t.ThreadId = nextThreadId - uint32(i+1)
			}
		}

		// Setup
		state.NextThreadId = nextThreadId
		state.GetMemory().SetMemory(state.GetPC(), syscallInsn)
		state.GetRegistersRef()[2] = exec.SysClone
		state.GetRegistersRef()[4] = exec.ValidCloneFlags
		state.GetRegistersRef()[5] = stackPtr
		step := state.GetStep()

		// Set up expectations
		expected := mttestutil.NewExpectedMTState(state)
		expected.Step += 1
		// Set original thread expectations
		expected.PrestateActiveThread().PC = state.GetCpu().NextPC
		expected.PrestateActiveThread().NextPC = state.GetCpu().NextPC + 4
		expected.PrestateActiveThread().Registers[2] = nextThreadId
		expected.PrestateActiveThread().Registers[7] = 0
		// Set expectations for new, cloned thread
		expected.ActiveThreadId = nextThreadId
		epxectedNewThread := expected.ExpectNewThread()
		epxectedNewThread.PC = state.GetCpu().NextPC
		epxectedNewThread.NextPC = state.GetCpu().NextPC + 4
		epxectedNewThread.Registers[2] = 0
		epxectedNewThread.Registers[7] = 0
		epxectedNewThread.Registers[29] = stackPtr
		expected.NextThreadId = nextThreadId + 1
		expected.StepsSinceLastContextSwitch = 0
		if state.TraverseRight {
			expected.RightStackSize += 1
		} else {
			expected.LeftStackSize += 1
		}

		stepWitness, err := goVm.Step(true)
		require.NoError(t, err)
		require.False(t, stepWitness.HasPreimage())

		expected.Validate(t, state)
		testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), v.Contracts, nil)
	})
}