Skip to content

Commit 60803b6

Browse files
tests(operations-gen): add EVM golden test
Add test for EVM to test generation of deploy link token and MCMS JIRA: https://smartcontract-it.atlassian.net/browse/CLD-1777
1 parent 4e3e764 commit 60803b6

8 files changed

Lines changed: 467 additions & 0 deletions

File tree

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package evm
2+
3+
import (
4+
"flag"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
"text/template"
9+
10+
"gopkg.in/yaml.v3"
11+
12+
"github.com/smartcontractkit/chainlink-deployments-framework/tools/operations-gen/internal/core"
13+
)
14+
15+
var update = flag.Bool("update", false, "update golden files")
16+
17+
// TestGenerateLinkToken is an end-to-end test that runs the generator against the
18+
// real LinkToken ABI/bytecode and verifies that the generated output matches golden.
19+
func TestGenerateLinkToken(t *testing.T) {
20+
t.Parallel()
21+
runGoldenGenerationTest(t, "operations_gen_config.yaml", "link_token.golden.go")
22+
}
23+
24+
// TestGenerateManyChainMultiSig verifies generation against an MCMS-like ABI fixture.
25+
func TestGenerateManyChainMultiSig(t *testing.T) {
26+
t.Parallel()
27+
runGoldenGenerationTest(t, "operations_gen_mcms_config.yaml", "many_chain_multi_sig.golden.go")
28+
}
29+
30+
func runGoldenGenerationTest(t *testing.T, configFileName string, goldenFileName string) {
31+
t.Helper()
32+
33+
evmTestdataDir, err := filepath.Abs(filepath.Join("..", "..", "..", "testdata", "evm"))
34+
if err != nil {
35+
t.Fatal(err)
36+
}
37+
38+
configData, err := os.ReadFile(filepath.Join(evmTestdataDir, configFileName))
39+
if err != nil {
40+
t.Fatalf("reading config: %v", err)
41+
}
42+
43+
var cfg core.Config
44+
if err = yaml.Unmarshal(configData, &cfg); err != nil {
45+
t.Fatalf("parsing config: %v", err)
46+
}
47+
48+
// Override paths: inputs point to fixture dirs, output to a temp dir.
49+
cfg.Input = mustYAMLNode(t, evmInputConfig{
50+
ABIBasePath: filepath.Join(evmTestdataDir, "abi"),
51+
BytecodeBasePath: filepath.Join(evmTestdataDir, "bytecode"),
52+
})
53+
tmpDir := t.TempDir()
54+
cfg.Output = mustYAMLNode(t, evmOutputConfig{BasePath: tmpDir})
55+
cfg.ConfigDir = ""
56+
57+
handler := Handler{}
58+
tmpl, err := loadTemplateForTest()
59+
if err != nil {
60+
t.Fatalf("loadTemplate: %v", err)
61+
}
62+
63+
if err = handler.Generate(cfg, tmpl); err != nil {
64+
t.Fatalf("Generate: %v", err)
65+
}
66+
67+
// Derive the output path from the first contract in the config, mirroring extractContractInfo.
68+
var contractCfgs []evmContractConfig
69+
if err = cfg.Contracts.Decode(&contractCfgs); err != nil || len(contractCfgs) == 0 {
70+
t.Fatalf("decoding contract configs: %v", err)
71+
}
72+
first := contractCfgs[0]
73+
pkgName := first.PackageName
74+
if pkgName == "" {
75+
pkgName = toSnakeCase(first.Name)
76+
}
77+
vPath := core.VersionToPath(first.Version)
78+
if first.VersionPath != "" {
79+
vPath = first.VersionPath
80+
}
81+
outputPath := core.ContractOutputPath(tmpDir, vPath, pkgName)
82+
83+
got, err := os.ReadFile(outputPath)
84+
if err != nil {
85+
t.Fatalf("reading generated file %s: %v", outputPath, err)
86+
}
87+
88+
goldenPath := filepath.Join(evmTestdataDir, goldenFileName)
89+
90+
if *update {
91+
if err = os.WriteFile(goldenPath, got, 0o600); err != nil {
92+
t.Fatalf("writing golden file: %v", err)
93+
}
94+
95+
return
96+
}
97+
98+
want, err := os.ReadFile(goldenPath)
99+
if err != nil {
100+
t.Fatalf("reading golden file %s: %v (run with -update to create it)", goldenPath, err)
101+
}
102+
103+
if string(got) != string(want) {
104+
t.Errorf("generated output does not match golden file %s\n\nrun: go test ./... -run %s -update", goldenPath, t.Name())
105+
}
106+
}
107+
108+
func mustYAMLNode(t *testing.T, value any) yaml.Node {
109+
t.Helper()
110+
b, err := yaml.Marshal(value)
111+
if err != nil {
112+
t.Fatalf("marshal yaml node: %v", err)
113+
}
114+
var n yaml.Node
115+
if err = yaml.Unmarshal(b, &n); err != nil {
116+
t.Fatalf("unmarshal yaml node: %v", err)
117+
}
118+
119+
return n
120+
}
121+
122+
func loadTemplateForTest() (*template.Template, error) {
123+
path := filepath.Join("..", "..", "..", "templates", "evm", "operations.tmpl")
124+
content, err := os.ReadFile(path)
125+
if err != nil {
126+
return nil, err
127+
}
128+
129+
return template.New("operations").Parse(string(content))
130+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"transferAndCall","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"data","type":"bytes"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"signerAddresses","type":"address[]"},{"internalType":"uint8[]","name":"signerGroups","type":"uint8[]"},{"internalType":"uint8[32]","name":"groupQuorums","type":"uint8[32]"},{"internalType":"uint8[32]","name":"groupParents","type":"uint8[32]"},{"internalType":"bool","name":"clearRoot","type":"bool"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"uint32","name":"validUntil","type":"uint32"},{"components":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"multiSig","type":"address"},{"internalType":"uint40","name":"preOpCount","type":"uint40"},{"internalType":"uint40","name":"postOpCount","type":"uint40"},{"internalType":"bool","name":"overridePreviousRoot","type":"bool"}],"internalType":"struct ManyChainMultiSig.RootMetadata","name":"metadata","type":"tuple"},{"internalType":"bytes32[]","name":"metadataProof","type":"bytes32[]"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct ManyChainMultiSig.Signature[]","name":"signatures","type":"tuple[]"}],"name":"setRoot","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
6060604052341561000f57600080fd5b5b600160a060020a03331660009081526001602052604090206b033b2e3c9fd0803ce800000090555b5b610c51806100486000396000f300606060405236156100b75763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100bc578063095ea7b31461014757806318160ddd1461017d57806323b872dd146101a2578063313ce567146101de5780634000aea014610207578063661884631461028057806370a08231146102b657806395d89b41146102e7578063a9059cbb14610372578063d73dd623146103a8578063dd62ed3e146103de575b600080fd5b34156100c757600080fd5b6100cf610415565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561010c5780820151818401525b6020016100f3565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610169600160a060020a036004351660243561044c565b604051901515815260200160405180910390f35b341561018857600080fd5b610190610499565b60405190815260200160405180910390f35b34156101ad57600080fd5b610169600160a060020a03600435811690602435166044356104a9565b604051901515815260200160405180910390f35b34156101e957600080fd5b6101f16104f8565b60405160ff909116815260200160405180910390f35b341561021257600080fd5b61016960048035600160a060020a03169060248035919060649060443590810190830135806020601f820181900481020160405190810160405281815292919060208401838380828437509496506104fd95505050505050565b604051901515815260200160405180910390f35b341561028b57600080fd5b610169600160a060020a036004351660243561054c565b604051901515815260200160405180910390f35b34156102c157600080fd5b610190600160a060020a0360043516610648565b60405190815260200160405180910390f35b34156102f257600080fd5b6100cf610667565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561010c5780820151818401525b6020016100f3565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037d57600080fd5b610169600160a060020a036004351660243561069e565b604051901515815260200160405180910390f35b34156103b357600080fd5b610169600160a060020a03600435166024356106eb565b604051901515815260200160405180910390f35b34156103e957600080fd5b610190600160a060020a0360043581169060243516610790565b60405190815260200160405180910390f35b60408051908101604052600f81527f436861696e4c696e6b20546f6b656e0000000000000000000000000000000000602082015281565b600082600160a060020a03811615801590610479575030600160a060020a031681600160a060020a031614155b151561048457600080fd5b61048e84846107bd565b91505b5b5092915050565b6b033b2e3c9fd0803ce800000081565b600082600160a060020a038116158015906104d6575030600160a060020a031681600160a060020a031614155b15156104e157600080fd5b6104ec85858561082a565b91505b5b509392505050565b601281565b600083600160a060020a0381161580159061052a575030600160a060020a031681600160a060020a031614155b151561053557600080fd5b6104ec85858561093c565b91505b5b509392505050565b600160a060020a033381166000908152600260209081526040808320938616835292905290812054808311156105a957600160a060020a0333811660009081526002602090815260408083209388168352929052908120556105e0565b6105b9818463ffffffff610a2316565b600160a060020a033381166000908152600260209081526040808320938916835292905220555b600160a060020a0333811660008181526002602090815260408083209489168084529490915290819020547f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925915190815260200160405180910390a3600191505b5092915050565b600160a060020a0381166000908152600160205260409020545b919050565b60408051908101604052600481527f4c494e4b00000000000000000000000000000000000000000000000000000000602082015281565b600082600160a060020a038116158015906106cb575030600160a060020a031681600160a060020a031614155b15156106d657600080fd5b61048e8484610a3a565b91505b5b5092915050565b600160a060020a033381166000908152600260209081526040808320938616835292905290812054610723908363ffffffff610afa16565b600160a060020a0333811660008181526002602090815260408083209489168084529490915290819020849055919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591905190815260200160405180910390a35060015b92915050565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b600160a060020a03338116600081815260026020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a35060015b92915050565b600160a060020a03808416600081815260026020908152604080832033909516835293815283822054928252600190529182205461086e908463ffffffff610a2316565b600160a060020a0380871660009081526001602052604080822093909355908616815220546108a3908463ffffffff610afa16565b600160a060020a0385166000908152600160205260409020556108cc818463ffffffff610a2316565b600160a060020a03808716600081815260026020908152604080832033861684529091529081902093909355908616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9086905190815260200160405180910390a3600191505b509392505050565b60006109488484610a3a565b5083600160a060020a031633600160a060020a03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16858560405182815260406020820181815290820183818151815260200191508051906020019080838360005b838110156109c35780820151818401525b6020016109aa565b50505050905090810190601f1680156109f05780820380516001836020036101000a031916815260200191505b50935050505060405180910390a3610a0784610b14565b15610a1757610a17848484610b23565b5b5060015b9392505050565b600082821115610a2f57fe5b508082035b92915050565b600160a060020a033316600090815260016020526040812054610a63908363ffffffff610a2316565b600160a060020a033381166000908152600160205260408082209390935590851681522054610a98908363ffffffff610afa16565b600160a060020a0380851660008181526001602052604090819020939093559133909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060015b92915050565b600082820183811015610b0957fe5b8091505b5092915050565b6000813b908111905b50919050565b82600160a060020a03811663a4c0ed363385856040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610bbd5780820151818401525b602001610ba4565b50505050905090810190601f168015610bea5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1515610c0a57600080fd5b6102c65a03f11515610c1b57600080fd5b5050505b505050505600a165627a7a72305820c5f438ff94e5ddaf2058efa0019e246c636c37a622e04bb67827c7374acad8d60029
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0x60006000

0 commit comments

Comments
 (0)