Skip to content

Commit f4631e0

Browse files
authored
chore: improve test engine docs (#487)
Updates the test engine docs to include the new API changes for setting up the environment and runtime. Also add information on the MCMS related tasks and usage patterns.
1 parent f318c97 commit f4631e0

File tree

1 file changed

+68
-44
lines changed

1 file changed

+68
-44
lines changed

engine/test/runtime/doc.go

Lines changed: 68 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -37,38 +37,35 @@
3737
//
3838
// Here's a simple example of using the runtime to execute a changeset:
3939
//
40-
// import (
41-
// "testing"
40+
// import (
41+
// "testing"
4242
//
43-
// "github.com/stretchr/testify/require"
43+
// "github.com/stretchr/testify/require"
4444
//
45-
// testenv "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/environment"
46-
// "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/runtime"
47-
// )
48-
//
49-
// func TestMyDeployment(t *testing.T) {
50-
// // Test environment with a simulated EVM blockchain
51-
// loader := testenv.NewLoader()
52-
// env, err := loader.Load(t, testenv.WithEVMSimulatedN(t, 1))
53-
// require.NoError(t, err)
45+
// testenv "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/environment"
46+
// "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/runtime"
47+
// )
5448
//
55-
// // Create runtime instance
56-
// runtime := NewFromEnvironment(*env)
49+
// func TestMyDeployment(t *testing.T) {
50+
// // Create runtime instance with a simulated EVM blockchain
51+
// runtime := New(t.Context(), WithEnvOpts(
52+
// testenv.WithEVMSimulatedN(t, 1)
53+
// ))
5754
//
58-
// // Execute a changeset
59-
// task := ChangesetTask(myChangeset, MyChangesetConfig{
60-
// Parameter1: "value1",
61-
// Parameter2: 42,
62-
// })
55+
// // Execute a changeset
56+
// task := ChangesetTask(myChangeset, MyChangesetConfig{
57+
// Parameter1: "value1",
58+
// Parameter2: 42,
59+
// })
6360
//
64-
// err := runtime.Exec(task)
65-
// require.NoError(t, err)
61+
// err := runtime.Exec(task)
62+
// require.NoError(t, err)
6663
//
67-
// // Verify deployment results
68-
// addrs, err := runtime.State().DataStore.Addresses().Fetch()
69-
// require.NoError(t, err)
70-
// assert.Len(t, addrs, 1)
71-
// }
64+
// // Verify deployment results
65+
// addrs, err := runtime.State().DataStore.Addresses().Fetch()
66+
// require.NoError(t, err)
67+
// assert.Len(t, addrs, 1)
68+
// }
7269
//
7370
// # Sequential Changeset Execution
7471
//
@@ -77,12 +74,10 @@
7774
// will include the data of the previous changesets execution.
7875
//
7976
// func TestMultiStepDeployment(t *testing.T) {
80-
// // Load test environment with multiple EVM chains
81-
// loader := testenv.NewLoader()
82-
// env, err := loader.Load(t, testenv.WithEVMSimulatedN(t, 1))
83-
// require.NoError(t, err)
84-
//
85-
// runtime := NewFromEnvironment(*env)
77+
// // Create runtime instance with a simulated EVM blockchain
78+
// runtime := New(t.Context(), WithEnvOpts(
79+
// testenv.WithEVMSimulatedN(t, 1)
80+
// ))
8681
//
8782
// // Define the first changeset
8883
// coreTask := ChangesetTask(coreChangeset, CoreConfig{})
@@ -106,16 +101,16 @@
106101
// The engine/test/environment package provides various blockchain loading options:
107102
//
108103
// // EVM simulated blockchains (fast, in-memory)
109-
// env, err := loader.Load(t, testenv.WithEVMSimulatedN(t, 2))
104+
// env, err := testenv.New(ctx, testenv.WithEVMSimulatedN(t, 2))
110105
//
111106
// // Specific chain selectors
112-
// env, err := loader.Load(t, testenv.WithEVMSimulated(t, []uint64{
107+
// env, err := testenv.New(ctx, testenv.WithEVMSimulated(t, []uint64{
113108
// chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector,
114109
// chainsel.POLYGON_TESTNET_MUMBAI.Selector,
115110
// }))
116111
//
117112
// // Multiple blockchain types
118-
// env, err := loader.Load(t,
113+
// env, err := testenv.New(ctx,
119114
// testenv.WithEVMSimulatedN(t, 1),
120115
// testenv.WithSolanaContainerN(t, 1, "/path/to/programs", programIDs),
121116
// testenv.WithTonContainerN(t, 1),
@@ -126,7 +121,7 @@
126121
// ChainID: 1337,
127122
// BlockTime: time.Second,
128123
// }
129-
// env, err := loader.Load(t, testenv.WithEVMSimulatedWithConfigN(t, 1, cfg))
124+
// env, err := testenv.New(t, testenv.WithEVMSimulatedWithConfigN(t, 1, cfg))
130125
//
131126
// # Error Handling
132127
//
@@ -135,8 +130,7 @@
135130
//
136131
// func TestErrorHandling(t *testing.T) {
137132
// // Load test environment
138-
// loader := testenv.NewLoader()
139-
// env, err := loader.Load(t, testenv.WithEVMSimulatedN(t, 1))
133+
// env, err := testenv.New(t, testenv.WithEVMSimulatedN(t, 1))
140134
// require.NoError(t, err)
141135
//
142136
// runtime := NewFromEnvironment(*env)
@@ -162,8 +156,7 @@
162156
//
163157
// func TestStateInspection(t *testing.T) {
164158
// // Load test environment
165-
// loader := testenv.NewLoader()
166-
// env, err := loader.Load(t, testenv.WithEVMSimulatedN(t, 1))
159+
// env, err := testenv.New(t, testenv.WithEVMSimulatedN(t, 1))
167160
// require.NoError(t, err)
168161
//
169162
// runtime := NewFromEnvironment(*env)
@@ -205,8 +198,7 @@
205198
//
206199
// // Subtests can each have their own runtime instance
207200
// t.Run("deployment_scenario_1", func(t *testing.T) {
208-
// loader := testenv.NewLoader()
209-
// env, err := loader.Load(t, testenv.WithEVMSimulatedN(t, 1))
201+
// env, err := testenv.New(ctx, testenv.WithEVMSimulatedN(t, 1))
210202
// require.NoError(t, err)
211203
//
212204
// runtime := NewFromEnvironment(*env)
@@ -216,8 +208,7 @@
216208
// })
217209
//
218210
// t.Run("deployment_scenario_2", func(t *testing.T) {
219-
// loader := testenv.NewLoader()
220-
// env, err := loader.Load(t, testenv.WithEVMSimulatedN(t, 2))
211+
// env, err := testenv.New(t, testenv.WithEVMSimulatedN(t, 2))
221212
// require.NoError(t, err)
222213
//
223214
// runtime := NewFromEnvironment(*env)
@@ -227,13 +218,46 @@
227218
// })
228219
// }
229220
//
221+
// # MCMS Proposals
222+
//
223+
// The runtime provides specialized tasks for handling Multi-Chain Multi-Sig (MCMS) proposals.
224+
//
225+
// ## Available MCMS Tasks
226+
//
227+
// **SignProposalTask(proposalID, signingKeys...)** - Signs MCMS or Timelock proposals with
228+
// one or more private keys. The task automatically detects the proposal type and applies
229+
// the appropriate signing logic. Multiple signatures can be added in a single operation
230+
// or accumulated across multiple signing tasks.
231+
//
232+
// **ExecuteProposalTask(proposalID)** - Executes a signed MCMS or Timelock proposal on
233+
// the target blockchain networks. The task handles chain-specific configurations, sets
234+
// merkle roots, executes operations sequentially, and confirms all transactions. For
235+
// Timelock proposals, it manages scheduling and delay mechanisms.
236+
//
237+
// **SignAndExecuteProposalsTask(signingKeys)** - Processes all pending proposals in the
238+
// runtime state by signing them with the provided keys and executing them in batch.
239+
// This is useful for scenarios where multiple changesets generate proposals that need
240+
// to be processed together or you want to just execute all pending proposals.
241+
//
242+
// ## Usage Pattern
243+
//
244+
// MCMS proposals follow a three-phase workflow:
245+
// 1. **Generation**: Changesets create proposals and store them in runtime state. This is done by running a ChangesetTask.
246+
// 2. **Signing**: Use SignProposalTask to add cryptographic signatures
247+
// 3. **Execution**: Use ExecuteProposalTask to apply changes on target chains
248+
//
249+
// The runtime automatically manages proposal state, tracking which proposals are pending,
250+
// signed, or executed. Both standard MCMS proposals and Timelock proposals are supported
251+
// through the same task interface.
252+
//
230253
// # Best Practices
231254
//
232255
// - Create a new runtime instance for each test to ensure isolation.
233256
// - Be wary when using containerized chains as they take a long time to start containers. It is better to write a
234257
// longer test with a single containerized chain than to write a shorter test with multiple containerized chains.
235258
// - Verify both intermediate and final state in multi-step tests
236259
// - Leverage the runtime's error handling for negative test cases
260+
// - Use SignAndExecuteProposalsTask for processing, avoiding the need to fetch the proposal ID from state.
237261
//
238262
// # Common Patterns
239263
//

0 commit comments

Comments
 (0)