Skip to content

Commit 2b84f94

Browse files
authored
test: add zetaclient only upgrade tests (#4310)
* add file based trigger for zetaclient binary download * update zetae2e * add new makefile commands * update comments * remove wait for upgrade height * upgrade contracts on zetaclient test * fixes 1 * add issue to track sui upgrade tests * add issue to track sui upgrade tests * add nosec
1 parent a4d4fac commit 2b84f94

File tree

11 files changed

+223
-67
lines changed

11 files changed

+223
-67
lines changed

.github/workflows/e2e.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ jobs:
111111
outputs:
112112
DEFAULT_TESTS: ${{ steps.matrix-conditionals.outputs.DEFAULT_TESTS }}
113113
UPGRADE_TESTS: ${{ steps.matrix-conditionals.outputs.UPGRADE_TESTS }}
114+
UPGRADE_TEST_ZETACLIENT: ${{ steps.matrix-conditionals.outputs.UPGRADE_TEST_ZETACLIENT }}
114115
CONSENSUS_TESTS: ${{ steps.matrix-conditionals.outputs.CONSENSUS_TESTS }}
115116
UPGRADE_LIGHT_TESTS: ${{ steps.matrix-conditionals.outputs.UPGRADE_LIGHT_TESTS }}
116117
UPGRADE_IMPORT_MAINNET_TESTS: ${{ steps.matrix-conditionals.outputs.UPGRADE_IMPORT_MAINNET_TESTS }}
@@ -148,6 +149,7 @@ jobs:
148149
const labels = await getPrLabels(context.payload.pull_request.number);
149150
core.setOutput('DEFAULT_TESTS', true);
150151
core.setOutput('UPGRADE_TESTS', labels.includes('UPGRADE_TESTS'));
152+
core.setOutput('UPGRADE_TEST_ZETACLIENT', labels.includes('UPGRADE_TEST_ZETACLIENT'));
151153
core.setOutput('CONSENSUS_TESTS', labels.includes('CONSENSUS_TESTS'));
152154
core.setOutput('UPGRADE_LIGHT_TESTS', labels.includes('UPGRADE_LIGHT_TESTS'));
153155
core.setOutput('UPGRADE_IMPORT_MAINNET_TESTS', labels.includes('UPGRADE_IMPORT_MAINNET_TESTS'));
@@ -168,6 +170,7 @@ jobs:
168170
// default mergequeue tests
169171
core.setOutput('DEFAULT_TESTS', true);
170172
core.setOutput('UPGRADE_TESTS', true);
173+
core.setOutput('UPGRADE_TEST_ZETACLIENT', true);
171174
core.setOutput('ADMIN_UPGRADE_TESTS', true);
172175
173176
// conditional tests based on PR labels
@@ -184,6 +187,7 @@ jobs:
184187
} else if (context.eventName === 'push' && context.ref.startsWith('refs/heads/release/')) {
185188
core.setOutput('DEFAULT_TESTS', true);
186189
core.setOutput('UPGRADE_TESTS', true);
190+
core.setOutput('UPGRADE_TEST_ZETACLIENT', true);
187191
core.setOutput('UPGRADE_LIGHT_TESTS', true);
188192
core.setOutput('UPGRADE_IMPORT_MAINNET_TESTS', true);
189193
core.setOutput('ADMIN_TESTS', true);
@@ -197,6 +201,7 @@ jobs:
197201
} else if (context.eventName === 'schedule') {
198202
core.setOutput('DEFAULT_TESTS', true);
199203
core.setOutput('UPGRADE_TESTS', true);
204+
core.setOutput('UPGRADE_TEST_ZETACLIENT', true);
200205
core.setOutput('UPGRADE_LIGHT_TESTS', true);
201206
core.setOutput('UPGRADE_IMPORT_MAINNET_TESTS', true);
202207
core.setOutput('ADMIN_TESTS', true);
@@ -213,6 +218,7 @@ jobs:
213218
const makeTargets = context.payload.inputs['make-targets'].split(',');
214219
core.setOutput('DEFAULT_TESTS', makeTargets.includes('default-test'));
215220
core.setOutput('UPGRADE_TESTS', makeTargets.includes('upgrade-test'));
221+
core.setOutput('UPGRADE_TEST_ZETACLIENT', makeTargets.includes('upgrade-test-zetaclient'));
216222
core.setOutput('UPGRADE_LIGHT_TESTS', makeTargets.includes('upgrade-test-light'));
217223
core.setOutput('UPGRADE_IMPORT_MAINNET_TESTS', makeTargets.includes('upgrade-import-mainnet-test'));
218224
core.setOutput('ADMIN_TESTS', makeTargets.includes('admin-test'));
@@ -248,6 +254,9 @@ jobs:
248254
- make-target: "start-upgrade-test"
249255
runs-on: ubuntu-22.04
250256
run: ${{ needs.matrix-conditionals.outputs.UPGRADE_TESTS == 'true' }}
257+
- make-target: "start-upgrade-test-zetaclient"
258+
runs-on: ubuntu-22.04
259+
run: ${{ needs.matrix-conditionals.outputs.UPGRADE_TEST_ZETACLIENT == 'true' }}
251260
- make-target: "start-upgrade-test-light"
252261
runs-on: ubuntu-22.04
253262
run: ${{ needs.matrix-conditionals.outputs.UPGRADE_LIGHT_TESTS == 'true' }}

Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,26 @@ start-upgrade-test-light: zetanode-upgrade
391391
export USE_ZETAE2E_ANTE=true && \
392392
cd contrib/localnet/ && $(DOCKER_COMPOSE) --profile upgrade -f docker-compose-upgrade.yml up -d
393393

394+
# test zetaclientd-only light upgrade , the test does not wait for the upgrade height , but it is still used to signify that this is a light upgrade[height < 100 == light upgrade]
395+
start-upgrade-test-zetaclient-light: zetanode-upgrade
396+
@echo "--> Starting zetaclientd-only light upgrade test"
397+
export LOCALNET_MODE=upgrade && \
398+
export UPGRADE_HEIGHT=60 && \
399+
export USE_ZETAE2E_ANTE=true && \
400+
export E2E_ARGS="--upgrade-contracts" && \
401+
export UPGRADE_ZETACLIENT_ONLY=true && \
402+
cd contrib/localnet/ && $(DOCKER_COMPOSE) --profile upgrade-zetaclient -f docker-compose-upgrade.yml up -d
403+
404+
# test zetaclientd-only upgrade , the test does not wait for the upgrade height , but it is still used to signify that this is not a light upgrade[height > 100 == regular upgrade]
405+
start-upgrade-test-zetaclient: zetanode-upgrade solana
406+
@echo "--> Starting upgrade test"
407+
export LOCALNET_MODE=upgrade && \
408+
export UPGRADE_HEIGHT=260 && \
409+
export USE_ZETAE2E_ANTE=true && \
410+
export E2E_ARGS="--test-solana --test-sui" && \
411+
export UPGRADE_ZETACLIENT_ONLY=true && \
412+
cd contrib/localnet/ && $(DOCKER_COMPOSE) --profile upgrade-zetaclient --profile solana --profile sui -f docker-compose-upgrade.yml up -d
413+
394414
start-upgrade-test-admin: zetanode-upgrade
395415
@echo "--> Starting admin upgrade test"
396416
export LOCALNET_MODE=upgrade && \

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ by calling `updateAdditionalActionFee` admin function.
5555
* [4158](https://github.com/zeta-chain/node/pull/4158) - have e2e tests interact with pre-deployed example dApp contract
5656
* [4165](https://github.com/zeta-chain/node/pull/4165) - fix Sui flaky depositAndCall e2e test in live networks
5757
* [4177](https://github.com/zeta-chain/node/pull/4177) - add an E2E test to verify depositAndCall with high gas consumption
58+
* [4310](https://github.com/zeta-chain/node/pull/4310) - add zetaclient only upgrade tests
5859

5960
## v36.0.0
6061

cmd/zetaclientd-supervisor/lib.go

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"os"
1010
"path"
1111
"runtime"
12+
"strings"
1213
"time"
1314

1415
upgradetypes "cosmossdk.io/x/upgrade/types"
@@ -23,7 +24,15 @@ import (
2324

2425
const zetaclientdBinaryName = "zetaclientd"
2526

26-
var defaultUpgradesDir = os.ExpandEnv("$HOME/.zetaclientd/upgrades")
27+
var (
28+
zetaclientDirectory = os.ExpandEnv("$HOME/.zetaclientd")
29+
defaultUpgradesDir = path.Join(zetaclientDirectory, "upgrades")
30+
// defaultZetaclientdBinaryPath is the path where the zetaclientd binary is expected to be found,this is the path used for localnet e2e tests
31+
defaultZetaclientdBinaryPath = "/usr/local/bin/zetaclientd"
32+
// zetaclientUpgradeTriggerFile is a file watched by the supervisor to trigger a binary upgrade.This should be used when upgrading zetaclient only.
33+
// This is primarily used for testing on localnet e2e tests.
34+
zetaclientUpgradeTriggerFile = path.Join(zetaclientDirectory, "zetaclientd-upgrade-trigger")
35+
)
2736

2837
func getLogger(cfg config.Config, out io.Writer) zerolog.Logger {
2938
var logger zerolog.Logger
@@ -44,12 +53,13 @@ func getLogger(cfg config.Config, out io.Writer) zerolog.Logger {
4453
}
4554

4655
type zetaclientdSupervisor struct {
47-
zetacoredConn *grpc.ClientConn
48-
reloadSignals chan bool
49-
logger zerolog.Logger
50-
upgradesDir string
51-
upgradePlanName string
52-
enableAutoDownload bool
56+
zetacoredConn *grpc.ClientConn
57+
reloadSignals chan bool
58+
logger zerolog.Logger
59+
upgradesDir string
60+
upgradePlanName string
61+
enableAutoDownload bool
62+
zetaclientdBinaryPath string
5363
}
5464

5565
func newZetaclientdSupervisor(
@@ -66,17 +76,19 @@ func newZetaclientdSupervisor(
6676
return nil, fmt.Errorf("grpc dial: %w", err)
6777
}
6878
return &zetaclientdSupervisor{
69-
zetacoredConn: conn,
70-
logger: logger,
71-
reloadSignals: make(chan bool, 1),
72-
upgradesDir: defaultUpgradesDir,
73-
enableAutoDownload: enableAutoDownload,
79+
zetacoredConn: conn,
80+
logger: logger,
81+
reloadSignals: make(chan bool, 1),
82+
upgradesDir: defaultUpgradesDir,
83+
enableAutoDownload: enableAutoDownload,
84+
zetaclientdBinaryPath: defaultZetaclientdBinaryPath,
7485
}, nil
7586
}
7687

7788
func (s *zetaclientdSupervisor) Start(ctx context.Context) {
7889
go s.watchForVersionChanges(ctx)
7990
go s.handleCoreUpgradePlan(ctx)
91+
go s.handleFileBasedUpgrade(ctx)
8092
}
8193

8294
func (s *zetaclientdSupervisor) WaitForReloadSignal(ctx context.Context) {
@@ -239,3 +251,77 @@ func (s *zetaclientdSupervisor) downloadZetaclientd(ctx context.Context, plan *u
239251
}
240252
return nil
241253
}
254+
255+
// handleFileBasedUpgrade watches for the trigger file to be created
256+
// Once created the function updates the zetaclient binary using the URL in the file and triggers a restart
257+
// This is currently only used for local testing and the trigger file is created by the start-zetae2e.sh script
258+
func (s *zetaclientdSupervisor) handleFileBasedUpgrade(ctx context.Context) {
259+
for {
260+
select {
261+
case <-time.After(time.Second):
262+
case <-ctx.Done():
263+
return
264+
}
265+
266+
if _, err := os.Stat(zetaclientUpgradeTriggerFile); err != nil {
267+
continue
268+
}
269+
270+
s.logger.Info().Msg("detected file-based upgrade trigger")
271+
272+
//#nosec G304 used for testing only
273+
binURLBytes, err := os.ReadFile(zetaclientUpgradeTriggerFile)
274+
if err != nil {
275+
panic(fmt.Sprintf("read trigger file: %v", err))
276+
}
277+
binURL := strings.TrimSpace(string(binURLBytes))
278+
if binURL == "" {
279+
panic("empty download URL in trigger file")
280+
}
281+
282+
tempDir := os.TempDir()
283+
err = s.downloadZetaclientdToPath(ctx, tempDir, binURL)
284+
if err != nil {
285+
errRemove := os.Remove(tempDir)
286+
if errRemove != nil {
287+
s.logger.Error().Err(errRemove).Msg("remove temp dir after failed download")
288+
}
289+
panic(fmt.Sprintf("download zetaclientd: %v", err))
290+
}
291+
292+
err = os.Rename(tempDir, s.zetaclientdBinaryPath)
293+
if err != nil {
294+
panic(fmt.Sprintf("rename binary into place: %v", err))
295+
}
296+
297+
err = os.Remove(zetaclientUpgradeTriggerFile)
298+
if err != nil {
299+
panic(fmt.Sprintf("remove trigger file: %v", err))
300+
}
301+
302+
s.reloadSignals <- true
303+
s.logger.Info().Msg("zetaclientd binary updated and restart triggered")
304+
}
305+
}
306+
307+
// downloadZetaclientdToPath downloads the zetaclientd binary to the specified path
308+
func (s *zetaclientdSupervisor) downloadZetaclientdToPath(ctx context.Context, targetPath string, binURL string) error {
309+
s.logger.Info().Msgf("downloading zetaclientd to %s from %s", targetPath, binURL)
310+
311+
err := getter.GetFile(targetPath, binURL, getter.WithContext(ctx), getter.WithUmask(0o750))
312+
if err != nil {
313+
return fmt.Errorf("get file %s: %w", binURL, err)
314+
}
315+
316+
info, err := os.Stat(targetPath)
317+
if err != nil {
318+
return fmt.Errorf("stat binary: %w", err)
319+
}
320+
newMode := info.Mode().Perm() | 0o111
321+
err = os.Chmod(targetPath, newMode)
322+
if err != nil {
323+
return fmt.Errorf("chmod %s: %w", targetPath, err)
324+
}
325+
326+
return nil
327+
}

cmd/zetae2e/local/local.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,9 +606,14 @@ func localE2ETest(cmd *cobra.Command, _ []string) {
606606
os.Exit(1)
607607
}
608608
}
609-
// https://github.com/zeta-chain/node/issues/4038
609+
610610
// TODO : enable sui gateway upgrade tests to be run multiple times
611+
// https://github.com/zeta-chain/node/issues/4038
612+
// https://github.com/zeta-chain/node/issues/4315
611613
runSuiGatewayUpgradeTests := func() bool {
614+
if deployerRunner.IsRunningZetaclientOnlyUpgrade() {
615+
return false
616+
}
612617
// do not if we are running and upgrade and this is the second run
613618
if deployerRunner.IsRunningUpgrade() && semver.Major(deployerRunner.GetZetacoredVersion()) == "v0" {
614619
return false

contrib/localnet/docker-compose.yml

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ services:
326326
- E2E_ARGS=${E2E_ARGS-}
327327
- UPGRADE_HEIGHT=${UPGRADE_HEIGHT-}
328328
- USE_ZETAE2E_ANTE=${USE_ZETAE2E_ANTE-}
329+
- UPGRADE_ZETACLIENT_ONLY=${UPGRADE_ZETACLIENT_ONLY-}
329330
- CI=${CI-}
330331
volumes:
331332
- ssh:/root/.ssh
@@ -336,6 +337,7 @@ services:
336337
hostname: upgrade-host
337338
profiles:
338339
- upgrade
340+
- upgrade-zetaclient
339341
- all
340342
entrypoint: ["/root/start-upgrade-host.sh"]
341343
networks:
@@ -345,24 +347,24 @@ services:
345347
- ssh:/root/.ssh
346348

347349
upgrade-orchestrator:
348-
# must run from old node for api compatibility
349-
image: zetanode:old
350-
container_name: upgrade-orchestrator
351-
hostname: upgrade-orchestrator
352-
profiles:
353-
- upgrade
354-
- all
355-
entrypoint: ["/root/start-upgrade-orchestrator.sh"]
356-
networks:
357-
mynetwork:
358-
ipv4_address: 172.20.0.251
359-
depends_on:
360-
- zetacore0
361-
- upgrade-host
362-
environment:
363-
- UPGRADE_HEIGHT=${UPGRADE_HEIGHT-}
364-
volumes:
365-
- ssh:/root/.ssh
350+
# must run from old node for api compatibility
351+
image: zetanode:old
352+
container_name: upgrade-orchestrator
353+
hostname: upgrade-orchestrator
354+
profiles:
355+
- upgrade
356+
- all
357+
entrypoint: ["/root/start-upgrade-orchestrator.sh"]
358+
networks:
359+
mynetwork:
360+
ipv4_address: 172.20.0.251
361+
depends_on:
362+
- zetacore0
363+
- upgrade-host
364+
environment:
365+
- UPGRADE_HEIGHT=${UPGRADE_HEIGHT-}
366+
volumes:
367+
- ssh:/root/.ssh
366368

367369
grafana:
368370
image: ghcr.io/zeta-chain/grafana-grafana:11.2.0

0 commit comments

Comments
 (0)