Skip to content

Commit 6e25c48

Browse files
authored
feat: implement test runner (#589)
* feat: implement test runner * chore: nit * chore: forgot to add the launcher part
1 parent 3df4ba5 commit 6e25c48

7 files changed

Lines changed: 152 additions & 2 deletions

File tree

.github/tests/additional-services.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ args:
1010
- observability
1111
# - pless_zkevm_node # zkevm-node doesn't support fork12.
1212
- status_checker
13+
- test_runner
1314
- tx_spammer

main.star

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,10 @@ def run(plan, args={}):
278278
plan.print("Skipping the deployment of OP Succinct")
279279

280280
# Deploy additional services.
281-
additional_services.launch(plan, args, contract_setup_addresses, genesis_artifact)
281+
deploy_optimism_rollup = deployment_stages.get("deploy_optimism_rollup", False)
282+
additional_services.launch(
283+
plan, args, contract_setup_addresses, genesis_artifact, deploy_optimism_rollup
284+
)
282285

283286

284287
def deploy_helper_service(plan, args):

src/additional_services/launcher.star

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ panoptichain = import_module("./panoptichain.star")
1010
pless_zkevm_node = import_module("./pless_zkevm_node.star")
1111
prometheus = import_module("./prometheus.star")
1212
status_checker = import_module("./status_checker.star")
13+
test_runner = import_module("./test_runner.star")
1314
tx_spammer = import_module("./tx_spammer.star")
1415

1516

16-
def launch(plan, args, contract_setup_addresses, genesis_artifact):
17+
def launch(
18+
plan, args, contract_setup_addresses, genesis_artifact, deploy_optimism_rollup=False
19+
):
1720
for svc in args.get("additional_services", []):
1821
if svc == constants.ADDITIONAL_SERVICES.arpeggio:
1922
arpeggio.run(plan, args)
@@ -41,6 +44,10 @@ def launch(plan, args, contract_setup_addresses, genesis_artifact):
4144
grafana.run(plan, args)
4245
elif svc == constants.ADDITIONAL_SERVICES.status_checker:
4346
status_checker.run(plan, args)
47+
elif svc == constants.ADDITIONAL_SERVICES.test_runner:
48+
test_runner.run(
49+
plan, args, contract_setup_addresses, deploy_optimism_rollup
50+
)
4451
elif svc == constants.ADDITIONAL_SERVICES.tx_spammer:
4552
tx_spammer.run(plan, args, contract_setup_addresses)
4653
else:
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
hex = import_module("../hex/hex.star")
2+
service_package = import_module("../../lib/service.star")
3+
wallet_module = import_module("../wallet/wallet.star")
4+
5+
TEST_RUNNER_IMAGE = "leovct/e2e:454aadc" # https://github.com/agglayer/e2e/commit/454aadcc4008a2e95b0888521d770149d60ec6c1
6+
7+
8+
def run(plan, args, contract_setup_addresses, deploy_optimism_rollup):
9+
l1_rpc_url = args.get("mitm_rpc_url").get("agglayer", args.get("l1_rpc_url"))
10+
11+
# Note: Getting values this way is not clean at all!!!
12+
bridge_service_url = ""
13+
l2_rpc_url = ""
14+
l2_bridge_address = ""
15+
if deploy_optimism_rollup:
16+
# Bridge service url.
17+
bridge_service_name = "sovereign-bridge-service{}".format(
18+
args.get("deployment_suffix")
19+
)
20+
bridge_service = plan.get_service(bridge_service_name)
21+
bridge_service_url = "http://{}:{}".format(
22+
bridge_service.name,
23+
bridge_service.ports.get("rpc").number,
24+
)
25+
26+
# L2 rpc url.
27+
op_el_rpc_name = "op-el-1-op-geth-op-node{}".format(
28+
args.get("deployment_suffix")
29+
)
30+
op_el_rpc_service = plan.get_service(op_el_rpc_name)
31+
l2_rpc_url = "http://{}:{}".format(
32+
op_el_rpc_service.name,
33+
op_el_rpc_service.ports.get("rpc").number,
34+
)
35+
36+
# L2 bridge contract address.
37+
l2_bridge_address = contract_setup_addresses.get("sovereign_bridge_proxy_addr")
38+
else:
39+
# Bridge service url.
40+
bridge_service_name = "zkevm-bridge-service{}".format(
41+
args.get("deployment_suffix")
42+
)
43+
bridge_service = plan.get_service(bridge_service_name)
44+
bridge_service_url = "http://{}:{}".format(
45+
bridge_service.name,
46+
bridge_service.ports.get("rpc").number,
47+
)
48+
49+
# L2 rpc url.
50+
l2_rpc_url = service_package.get_l2_rpc_url(plan, args).http
51+
52+
# L2 bridge contract address.
53+
l2_bridge_address = contract_setup_addresses.get("zkevm_bridge_l2_address")
54+
55+
# Generate a new wallet and fund it on L1 and L2.
56+
funder_private_key = args.get("zkevm_l2_admin_private_key")
57+
wallet = wallet_module.new(plan)
58+
wallet_module.fund(
59+
plan,
60+
address=wallet.address,
61+
rpc_url=l1_rpc_url,
62+
funder_private_key=funder_private_key,
63+
)
64+
wallet_module.fund(
65+
plan,
66+
address=wallet.address,
67+
rpc_url=l2_rpc_url,
68+
funder_private_key=funder_private_key,
69+
)
70+
71+
plan.add_service(
72+
name="test-runner",
73+
config=ServiceConfig(
74+
image=TEST_RUNNER_IMAGE,
75+
env_vars={
76+
# For now, we've only defined variables used by `tests/agglayer/bridges.bats`.
77+
# https://github.com/agglayer/e2e/blob/jhilliard/gas-token-test/tests/agglayer/bridges.bats
78+
# Agglayer and bridge.
79+
"AGGLAYER_RPC_URL": args.get("agglayer_readrpc_url"),
80+
"BRIDGE_SERVICE_URL": bridge_service_url,
81+
"CLAIMTXMANAGER_ADDR": args.get("zkevm_l2_claimtxmanager_address"),
82+
# L1.
83+
"L1_PRIVATE_KEY": wallet.private_key,
84+
"L1_RPC_URL": l1_rpc_url,
85+
"L1_BRIDGE_ADDR": contract_setup_addresses.get("zkevm_bridge_address"),
86+
# L2.
87+
"L2_PRIVATE_KEY": wallet.private_key,
88+
"L2_RPC_URL": l2_rpc_url,
89+
"L2_BRIDGE_ADDR": l2_bridge_address,
90+
},
91+
entrypoint=["bash", "-c"],
92+
cmd=["sleep infinity"],
93+
),
94+
)

src/hex/hex.star

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def normalize(s):
2+
return "0x" + s.removeprefix("0x")

src/package_io/constants.star

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ ADDITIONAL_SERVICES = struct(
88
observability="observability",
99
pless_zkevm_node="pless_zkevm_node",
1010
status_checker="status_checker",
11+
test_runner="test_runner",
1112
tx_spammer="tx_spammer",
1213
)
1314

src/wallet/wallet.star

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
constants = import_module("../../src/package_io/constants.star")
2+
3+
4+
def new(plan):
5+
result = plan.run_sh(
6+
name="private-key-generator",
7+
description="Generating a new private key",
8+
image=constants.TOOLBOX_IMAGE,
9+
run="cast wallet new --json | jq --raw-output '.[0].private_key' | tr -d '\n'",
10+
)
11+
private_key = result.output
12+
13+
result = plan.run_sh(
14+
name="address-deriver",
15+
description="Deriving address from private key",
16+
image=constants.TOOLBOX_IMAGE,
17+
run="cast wallet address --private-key ${PRIVATE_KEY} | tr -d '\n'",
18+
env_vars={
19+
"PRIVATE_KEY": private_key,
20+
},
21+
)
22+
address = result.output
23+
24+
return struct(
25+
address=address,
26+
private_key=private_key,
27+
)
28+
29+
30+
def fund(plan, address, rpc_url, funder_private_key, value="50ether"):
31+
plan.run_sh(
32+
name="address-funder",
33+
description="Funding address on network {}".format(rpc_url),
34+
image=constants.TOOLBOX_IMAGE,
35+
run="cast send --legacy --rpc-url ${RPC_URL} --private-key ${PRIVATE_KEY} --value ${VALUE} ${ADDRESS}",
36+
env_vars={
37+
"ADDRESS": address,
38+
"PRIVATE_KEY": funder_private_key,
39+
"RPC_URL": rpc_url,
40+
"VALUE": value,
41+
},
42+
)

0 commit comments

Comments
 (0)