Commit 31845fd2 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

ci: Refactor dependencies to reduce runtime (#9335)

* ci: Refactor dependencies to reduce runtime

This PR makes the following changes in order to reduce CI runtime:

1. Move the long-running Cannon E2E tests into a scheduled job. This reduces E2E runtime by 8 minutes.
2. Updates the `devnet` task to leverage the contract artifacts and cannon pre-state created in order jobs. This job was also updated to use a Geth binary rather than compiling it from source. This reduces devnet runtime by 5 minutes.
3. Removes intermediate linting, allocs, and geth version check jobs by putting them all in `pnpm-monorepo`. `pnpm-monorepo` already builds the contracts, devnet allocs, and checks the Geth version in parallel so splitting these jobs out actually makes things slower due to CCI image download/environment spin-up overhead. The `pnpm-monorepo` job now plugs into a bunch of downstream jobs.
4. Refactors the action tests to take advantage of multiple test executors.
5. Swaps the `bedrock-go-tests` image to a simple CCI base image to reduce runtime (this job alone was taking ~1min due to spin up overhead).
6. Puts linting in `go-mod-download` to avoid spin-up overhead.

In sum, this PR reduces overall CI runtime from 22 minutes to ~13.

* Use develop as a trigger rather than schedule

* schedule fpp-verify
parent 5a2ac1b4
This diff is collapsed.
...@@ -29,6 +29,11 @@ test-http: pre-test ...@@ -29,6 +29,11 @@ test-http: pre-test
test-cannon: pre-test test-cannon: pre-test
OP_E2E_CANNON_ENABLED=true $(go_test) $(go_test_flags) ./faultproofs OP_E2E_CANNON_ENABLED=true $(go_test) $(go_test_flags) ./faultproofs
.PHONY: test-cannon
test-fault-proofs: pre-test
$(go_test) $(go_test_flags) ./faultproofs
.PHONY: test-faultproofs
cannon-prestate: cannon-prestate:
make -C .. cannon-prestate make -C .. cannon-prestate
......
...@@ -2,26 +2,12 @@ package actions ...@@ -2,26 +2,12 @@ package actions
import ( import (
"context" "context"
"os"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
) )
var enableParallelTesting bool = true
func init() {
if os.Getenv("OP_E2E_DISABLE_PARALLEL") == "true" {
enableParallelTesting = false
}
}
func parallel(t e2eutils.TestingBase) {
t.Helper()
if enableParallelTesting {
t.Parallel()
}
}
// Testing is an interface to Go-like testing, // Testing is an interface to Go-like testing,
// extended with a context getter for the test runner to shut down individual actions without interrupting the test, // extended with a context getter for the test runner to shut down individual actions without interrupting the test,
// and a signaling function for when an invalid action is hit. // and a signaling function for when an invalid action is hit.
...@@ -69,7 +55,8 @@ type StatefulTesting interface { ...@@ -69,7 +55,8 @@ type StatefulTesting interface {
// NewDefaultTesting returns a new testing obj, and enables parallel test execution. // NewDefaultTesting returns a new testing obj, and enables parallel test execution.
// Returns an interface, we're likely changing the behavior here as we build more action tests. // Returns an interface, we're likely changing the behavior here as we build more action tests.
func NewDefaultTesting(tb e2eutils.TestingBase) StatefulTesting { func NewDefaultTesting(tb e2eutils.TestingBase) StatefulTesting {
parallel(tb) op_e2e.InitParallel(tb)
return &defaultTesting{ return &defaultTesting{
TestingBase: tb, TestingBase: tb,
ctx: context.Background(), ctx: context.Background(),
......
...@@ -11,7 +11,7 @@ import ( ...@@ -11,7 +11,7 @@ import (
) )
func TestMultipleGameTypes(t *testing.T) { func TestMultipleGameTypes(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(0)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, _ := startFaultDisputeSystem(t) sys, _ := startFaultDisputeSystem(t)
......
...@@ -14,7 +14,7 @@ import ( ...@@ -14,7 +14,7 @@ import (
) )
func TestOutputAlphabetGame_ChallengerWins(t *testing.T) { func TestOutputAlphabetGame_ChallengerWins(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UseExecutor(1)) op_e2e.InitParallel(t)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
t.Cleanup(sys.Close) t.Cleanup(sys.Close)
...@@ -71,7 +71,7 @@ func TestOutputAlphabetGame_ChallengerWins(t *testing.T) { ...@@ -71,7 +71,7 @@ func TestOutputAlphabetGame_ChallengerWins(t *testing.T) {
} }
func TestOutputAlphabetGame_ValidOutputRoot(t *testing.T) { func TestOutputAlphabetGame_ValidOutputRoot(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UseExecutor(1)) op_e2e.InitParallel(t)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
t.Cleanup(sys.Close) t.Cleanup(sys.Close)
...@@ -102,7 +102,7 @@ func TestOutputAlphabetGame_ValidOutputRoot(t *testing.T) { ...@@ -102,7 +102,7 @@ func TestOutputAlphabetGame_ValidOutputRoot(t *testing.T) {
} }
func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UseExecutor(1)) op_e2e.InitParallel(t)
testCase := func(t *testing.T, isRootCorrect bool) { testCase := func(t *testing.T, isRootCorrect bool) {
ctx := context.Background() ctx := context.Background()
...@@ -159,11 +159,11 @@ func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { ...@@ -159,11 +159,11 @@ func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) {
} }
t.Run("RootCorrect", func(t *testing.T) { t.Run("RootCorrect", func(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UseExecutor(1)) op_e2e.InitParallel(t)
testCase(t, true) testCase(t, true)
}) })
t.Run("RootIncorrect", func(t *testing.T) { t.Run("RootIncorrect", func(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UseExecutor(1)) op_e2e.InitParallel(t)
testCase(t, false) testCase(t, false)
}) })
} }
...@@ -16,7 +16,7 @@ import ( ...@@ -16,7 +16,7 @@ import (
) )
func TestOutputCannonGame(t *testing.T) { func TestOutputCannonGame(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(0)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
t.Cleanup(sys.Close) t.Cleanup(sys.Close)
...@@ -72,7 +72,7 @@ func TestOutputCannonGame(t *testing.T) { ...@@ -72,7 +72,7 @@ func TestOutputCannonGame(t *testing.T) {
func TestOutputCannon_ChallengeAllZeroClaim(t *testing.T) { func TestOutputCannon_ChallengeAllZeroClaim(t *testing.T) {
// The dishonest actor always posts claims with all zeros. // The dishonest actor always posts claims with all zeros.
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(1)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
t.Cleanup(sys.Close) t.Cleanup(sys.Close)
...@@ -109,7 +109,7 @@ func TestOutputCannon_PublishCannonRootClaim(t *testing.T) { ...@@ -109,7 +109,7 @@ func TestOutputCannon_PublishCannonRootClaim(t *testing.T) {
for _, test := range tests { for _, test := range tests {
test := test test := test
t.Run(fmt.Sprintf("Dispute_%v", test.disputeL2BlockNumber), func(t *testing.T) { t.Run(fmt.Sprintf("Dispute_%v", test.disputeL2BlockNumber), func(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(2)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, _ := startFaultDisputeSystem(t) sys, _ := startFaultDisputeSystem(t)
...@@ -139,7 +139,7 @@ func TestOutputCannonDisputeGame(t *testing.T) { ...@@ -139,7 +139,7 @@ func TestOutputCannonDisputeGame(t *testing.T) {
for _, test := range tests { for _, test := range tests {
test := test test := test
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(3)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
...@@ -176,7 +176,7 @@ func TestOutputCannonDisputeGame(t *testing.T) { ...@@ -176,7 +176,7 @@ func TestOutputCannonDisputeGame(t *testing.T) {
} }
func TestOutputCannonDefendStep(t *testing.T) { func TestOutputCannonDefendStep(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(4)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
...@@ -212,7 +212,7 @@ func TestOutputCannonDefendStep(t *testing.T) { ...@@ -212,7 +212,7 @@ func TestOutputCannonDefendStep(t *testing.T) {
} }
func TestOutputCannonStepWithLargePreimage(t *testing.T) { func TestOutputCannonStepWithLargePreimage(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(0)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, _ := startFaultDisputeSystem(t, withLargeBatches()) sys, _ := startFaultDisputeSystem(t, withLargeBatches())
...@@ -258,7 +258,7 @@ func TestOutputCannonStepWithLargePreimage(t *testing.T) { ...@@ -258,7 +258,7 @@ func TestOutputCannonStepWithLargePreimage(t *testing.T) {
func TestOutputCannonStepWithPreimage(t *testing.T) { func TestOutputCannonStepWithPreimage(t *testing.T) {
testPreimageStep := func(t *testing.T, preloadPreimage bool) { testPreimageStep := func(t *testing.T, preloadPreimage bool) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(5)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
...@@ -315,9 +315,6 @@ func TestOutputCannonProposedOutputRootValid(t *testing.T) { ...@@ -315,9 +315,6 @@ func TestOutputCannonProposedOutputRootValid(t *testing.T) {
// performStep is called once the maximum game depth is reached. It should perform a step to counter the // performStep is called once the maximum game depth is reached. It should perform a step to counter the
// claim at parentClaimIdx. Since the proposed output root is invalid, the step call should always revert. // claim at parentClaimIdx. Since the proposed output root is invalid, the step call should always revert.
performStep func(ctx context.Context, game *disputegame.OutputCannonGameHelper, correctTrace *disputegame.OutputHonestHelper, parentClaimIdx int64) performStep func(ctx context.Context, game *disputegame.OutputCannonGameHelper, correctTrace *disputegame.OutputHonestHelper, parentClaimIdx int64)
// executor to run the task on
executor uint64
}{ }{
{ {
name: "AttackWithCorrectTrace", name: "AttackWithCorrectTrace",
...@@ -330,7 +327,6 @@ func TestOutputCannonProposedOutputRootValid(t *testing.T) { ...@@ -330,7 +327,6 @@ func TestOutputCannonProposedOutputRootValid(t *testing.T) {
return correctTrace.AttackClaim(ctx, claim) return correctTrace.AttackClaim(ctx, claim)
}, },
performStep: honestStepsFail, performStep: honestStepsFail,
executor: 6,
}, },
{ {
name: "DefendWithCorrectTrace", name: "DefendWithCorrectTrace",
...@@ -349,14 +345,13 @@ func TestOutputCannonProposedOutputRootValid(t *testing.T) { ...@@ -349,14 +345,13 @@ func TestOutputCannonProposedOutputRootValid(t *testing.T) {
return correctTrace.DefendClaim(ctx, claim) return correctTrace.DefendClaim(ctx, claim)
}, },
performStep: honestStepsFail, performStep: honestStepsFail,
executor: 7,
}, },
} }
for _, test := range tests { for _, test := range tests {
test := test test := test
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(test.executor)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
...@@ -390,7 +385,7 @@ func TestOutputCannonProposedOutputRootValid(t *testing.T) { ...@@ -390,7 +385,7 @@ func TestOutputCannonProposedOutputRootValid(t *testing.T) {
} }
func TestOutputCannonPoisonedPostState(t *testing.T) { func TestOutputCannonPoisonedPostState(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(1)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
...@@ -454,7 +449,7 @@ func TestOutputCannonPoisonedPostState(t *testing.T) { ...@@ -454,7 +449,7 @@ func TestOutputCannonPoisonedPostState(t *testing.T) {
} }
func TestDisputeOutputRootBeyondProposedBlock_ValidOutputRoot(t *testing.T) { func TestDisputeOutputRootBeyondProposedBlock_ValidOutputRoot(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(2)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
...@@ -504,7 +499,7 @@ func TestDisputeOutputRootBeyondProposedBlock_ValidOutputRoot(t *testing.T) { ...@@ -504,7 +499,7 @@ func TestDisputeOutputRootBeyondProposedBlock_ValidOutputRoot(t *testing.T) {
} }
func TestDisputeOutputRootBeyondProposedBlock_InvalidOutputRoot(t *testing.T) { func TestDisputeOutputRootBeyondProposedBlock_InvalidOutputRoot(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(3)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
...@@ -555,7 +550,7 @@ func TestDisputeOutputRootBeyondProposedBlock_InvalidOutputRoot(t *testing.T) { ...@@ -555,7 +550,7 @@ func TestDisputeOutputRootBeyondProposedBlock_InvalidOutputRoot(t *testing.T) {
} }
func TestDisputeOutputRoot_ChangeClaimedOutputRoot(t *testing.T) { func TestDisputeOutputRoot_ChangeClaimedOutputRoot(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(4)) op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background() ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t) sys, l1Client := startFaultDisputeSystem(t)
......
...@@ -4,7 +4,8 @@ import ( ...@@ -4,7 +4,8 @@ import (
"crypto/md5" "crypto/md5"
"os" "os"
"strconv" "strconv"
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
) )
var enableParallelTesting bool = os.Getenv("OP_E2E_DISABLE_PARALLEL") != "true" var enableParallelTesting bool = os.Getenv("OP_E2E_DISABLE_PARALLEL") != "true"
...@@ -13,7 +14,7 @@ type testopts struct { ...@@ -13,7 +14,7 @@ type testopts struct {
executor uint64 executor uint64
} }
func InitParallel(t *testing.T, args ...func(t *testing.T, opts *testopts)) { func InitParallel(t e2eutils.TestingBase, args ...func(t e2eutils.TestingBase, opts *testopts)) {
t.Helper() t.Helper()
if enableParallelTesting { if enableParallelTesting {
t.Parallel() t.Parallel()
...@@ -32,7 +33,7 @@ func InitParallel(t *testing.T, args ...func(t *testing.T, opts *testopts)) { ...@@ -32,7 +33,7 @@ func InitParallel(t *testing.T, args ...func(t *testing.T, opts *testopts)) {
checkExecutor(t, info, opts.executor) checkExecutor(t, info, opts.executor)
} }
func UsesCannon(t *testing.T, opts *testopts) { func UsesCannon(t e2eutils.TestingBase, opts *testopts) {
if os.Getenv("OP_E2E_CANNON_ENABLED") == "false" { if os.Getenv("OP_E2E_CANNON_ENABLED") == "false" {
t.Skip("Skipping cannon test") t.Skip("Skipping cannon test")
} }
...@@ -44,8 +45,8 @@ func UsesCannon(t *testing.T, opts *testopts) { ...@@ -44,8 +45,8 @@ func UsesCannon(t *testing.T, opts *testopts) {
// InitParallel(t, UseExecutor(1)) // InitParallel(t, UseExecutor(1))
// Any tests assigned to an executor greater than the number available automatically use the last executor. // Any tests assigned to an executor greater than the number available automatically use the last executor.
// Executor indexes start from 0 // Executor indexes start from 0
func UseExecutor(assignedIdx uint64) func(t *testing.T, opts *testopts) { func UseExecutor(assignedIdx uint64) func(t e2eutils.TestingBase, opts *testopts) {
return func(t *testing.T, opts *testopts) { return func(t e2eutils.TestingBase, opts *testopts) {
opts.executor = assignedIdx opts.executor = assignedIdx
} }
} }
...@@ -56,7 +57,7 @@ type executorInfo struct { ...@@ -56,7 +57,7 @@ type executorInfo struct {
splitInUse bool splitInUse bool
} }
func getExecutorInfo(t *testing.T) executorInfo { func getExecutorInfo(t e2eutils.TestingBase) executorInfo {
var info executorInfo var info executorInfo
envTotal := os.Getenv("CIRCLE_NODE_TOTAL") envTotal := os.Getenv("CIRCLE_NODE_TOTAL")
envIdx := os.Getenv("CIRCLE_NODE_INDEX") envIdx := os.Getenv("CIRCLE_NODE_INDEX")
...@@ -81,7 +82,7 @@ func getExecutorInfo(t *testing.T) executorInfo { ...@@ -81,7 +82,7 @@ func getExecutorInfo(t *testing.T) executorInfo {
return info return info
} }
func checkExecutor(t *testing.T, info executorInfo, assignedIdx uint64) { func checkExecutor(t e2eutils.TestingBase, info executorInfo, assignedIdx uint64) {
if !info.splitInUse { if !info.splitInUse {
t.Logf("Test splitting not in use.") t.Logf("Test splitting not in use.")
return return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment