From afe3bb60aa724565018d6aa6bcd7426215f5c1ec Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 1 Apr 2026 10:48:03 +0200 Subject: [PATCH 01/10] initial implementation of chip router --- .../configs/workflow-don-solana.toml | 3 + .../configs/workflow-don-tron.toml | 3 + .../workflow-gateway-capabilities-don.toml | 3 + .../workflow-gateway-don-grpc-source.toml | 3 + .../configs/workflow-gateway-don.toml | 3 + .../workflow-gateway-legacy-vault-don.toml | 3 + .../configs/workflow-gateway-mock-don.toml | 3 + .../workflow-gateway-sharded-5-dons.toml | 3 + .../configs/workflow-gateway-sharded-don.toml | 3 + .../cre/environment/environment/beholder.go | 70 ++++- .../environment/environment/environment.go | 19 ++ core/scripts/go.mod | 15 +- core/scripts/go.sum | 20 +- system-tests/lib/cre/chiprouter/router.go | 243 ++++++++++++++++++ .../lib/cre/environment/config/config.go | 28 ++ .../lib/cre/environment/environment.go | 12 + system-tests/lib/go.mod | 18 +- system-tests/lib/go.sum | 27 +- system-tests/tests/go.mod | 17 +- system-tests/tests/go.sum | 20 +- .../tests/smoke/cre/cre_suite_test.go | 2 +- .../smoke/cre/v2suite/config/bucketing.go | 2 +- .../tests/test-helpers/before_suite.go | 7 +- .../test-helpers/chip-testsink/server.go | 42 +++ .../test-helpers/chip_testsink_helpers.go | 144 ++++------- .../test-helpers/workflow_event_observer.go | 127 +++++++++ 26 files changed, 681 insertions(+), 159 deletions(-) create mode 100644 system-tests/lib/cre/chiprouter/router.go create mode 100644 system-tests/tests/test-helpers/workflow_event_observer.go diff --git a/core/scripts/cre/environment/configs/workflow-don-solana.toml b/core/scripts/cre/environment/configs/workflow-don-solana.toml index 478e993f241..b8198cad1bc 100644 --- a/core/scripts/cre/environment/configs/workflow-don-solana.toml +++ b/core/scripts/cre/environment/configs/workflow-don-solana.toml @@ -1,4 +1,7 @@ +[chip_router] + image = "chip-router-local:latest" + [[blockchains]] type = "anvil" chain_id = "1337" diff --git a/core/scripts/cre/environment/configs/workflow-don-tron.toml b/core/scripts/cre/environment/configs/workflow-don-tron.toml index 711e6efe0b7..4e9d6c1e685 100755 --- a/core/scripts/cre/environment/configs/workflow-don-tron.toml +++ b/core/scripts/cre/environment/configs/workflow-don-tron.toml @@ -1,4 +1,7 @@ +[chip_router] + image = "chip-router-local:latest" + [[blockchains]] type = "anvil" chain_id = "1337" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml index b94d80787b6..5e1d5b94027 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml @@ -1,4 +1,7 @@ +[chip_router] + image = "chip-router-local:latest" + [[blockchains]] type = "anvil" chain_id = "1337" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml b/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml index 01ae469e74d..cb1571c1a8f 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml @@ -4,6 +4,9 @@ # # Used by: system-tests/tests/smoke/cre/v2_grpc_source_test.go +[chip_router] + image = "chip-router-local:latest" + [[blockchains]] type = "anvil" chain_id = "1337" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-don.toml index 197853faa28..24108575bf0 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-don.toml @@ -1,4 +1,7 @@ +[chip_router] + image = "chip-router-local:latest" + [[blockchains]] type = "anvil" chain_id = "1337" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml index 40c5cb85d16..78ac2208597 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml @@ -1,5 +1,8 @@ # NOTE: Identical to workflow-gatewway-capabilities.toml but with a vault capability config override # to disable the new pending queue feature. +[chip_router] + image = "chip-router-local:latest" + [[blockchains]] type = "anvil" chain_id = "1337" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml index 0e66be77870..39193bdc2cf 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml @@ -1,3 +1,6 @@ +[chip_router] + image = "chip-router-local:latest" + [[blockchains]] chain_id = "1337" container_name = "anvil-1337" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml b/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml index e9453a70c50..8c718115ded 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml @@ -1,4 +1,7 @@ +[chip_router] + image = "chip-router-local:latest" + [[blockchains]] type = "anvil" chain_id = "1337" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml index c1943d030ba..778ed806cc0 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml @@ -1,4 +1,7 @@ +[chip_router] + image = "chip-router-local:latest" + [[blockchains]] type = "anvil" chain_id = "1337" diff --git a/core/scripts/cre/environment/environment/beholder.go b/core/scripts/cre/environment/environment/beholder.go index 826498bcf80..15bc47f8ffe 100644 --- a/core/scripts/cre/environment/environment/beholder.go +++ b/core/scripts/cre/environment/environment/beholder.go @@ -23,7 +23,9 @@ import ( "github.com/spf13/cobra" "github.com/smartcontractkit/chainlink-testing-framework/framework" + ctfchiprouter "github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter" chipingressset "github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose/chip_ingress_set" + "github.com/smartcontractkit/chainlink/system-tests/lib/cre/chiprouter" envconfig "github.com/smartcontractkit/chainlink/system-tests/lib/cre/environment/config" "github.com/smartcontractkit/chainlink/system-tests/lib/cre/environment/stagegen" libformat "github.com/smartcontractkit/chainlink/system-tests/lib/format" @@ -287,6 +289,10 @@ func startBeholderCmd() *cobra.Command { return fmt.Errorf("failed to set TESTCONTAINERS_RYUK_DISABLED environment variable: %w", setErr) } + if routerErr := startChipRouterForBeholder(cmd.Context()); routerErr != nil { + return errors.Wrap(routerErr, "failed to start chip ingress router") + } + startBeholderErr = startBeholder(cmd.Context(), timeout, port) if startBeholderErr != nil { // remove the stack if the error is not related to proto registration @@ -305,7 +311,7 @@ func startBeholderCmd() *cobra.Command { } cmd.Flags().DurationVarP(&timeout, "wait-on-error-timeout", "w", 15*time.Second, "Time to wait before removing Docker containers if environment fails to start (e.g. 10s, 1m, 1h)") - cmd.Flags().IntVarP(&port, "grpc-port", "g", mustStringToInt(chipingressset.DEFAULT_CHIP_INGRESS_GRPC_PORT), "GRPC port for Chip Ingress") + cmd.Flags().IntVarP(&port, "grpc-port", "g", ctfchiprouter.DefaultBeholderGRPCPort, "GRPC port for downstream Chip Ingress") return cmd } @@ -319,6 +325,10 @@ func mustStringToInt(in string) int { return out } +func startChipRouterForBeholder(ctx context.Context) error { + return chiprouter.EnsureStarted(ctx, relativePathToRepoRoot, "") +} + var stopBeholderCmd = &cobra.Command{ Use: "stop", Short: "Stop the Beholder", @@ -330,6 +340,17 @@ var stopBeholderCmd = &cobra.Command{ } func stopBeholder() error { + subscriberID, loadSubscriberErr := loadBeholderSubscriberID(relativePathToRepoRoot) + if loadSubscriberErr != nil && !os.IsNotExist(loadSubscriberErr) { + framework.L.Warn().Err(loadSubscriberErr).Msg("failed to load Beholder router subscriber id") + } + if subscriberID != "" { + unregisterErr := chiprouter.UnregisterSubscriber(context.Background(), relativePathToRepoRoot, subscriberID) + if unregisterErr != nil && !os.IsNotExist(unregisterErr) { + framework.L.Warn().Err(unregisterErr).Msg("failed to unregister Beholder from chip ingress router") + } + } + setErr := os.Setenv("CTF_CONFIGS", DefaultBeholderConfigFile) if setErr != nil { return fmt.Errorf("failed to set CTF_CONFIGS environment variable: %w", setErr) @@ -350,7 +371,13 @@ func removeBeholderStateFiles(relativePathToRepoRoot string) error { return errors.Wrap(absErr, "error getting absolute path for chip ingress state file") } - return os.Remove(absPath) + if err := os.Remove(absPath); err != nil && !os.IsNotExist(err) { + return err + } + if err := os.Remove(beholderSubscriberIDPath(relativePathToRepoRoot)); err != nil && !os.IsNotExist(err) { + return err + } + return nil } func isPortAvailable(addr string) bool { @@ -696,6 +723,10 @@ and make sure that the sink is pointing to correct upstream endpoint ('localhost fmt.Println() framework.L.Info().Msgf("Red Panda Console URL: %s", out.RedPanda.ConsoleExternalURL) + if err := registerBeholderWithRouter(cmdContext, port); err != nil { + return errors.Wrap(err, "failed to register Beholder with chip ingress router") + } + topicsErr := chipingressset.CreateTopics(cmdContext, out.RedPanda.KafkaExternalURL, in.Kafka.Topics) if topicsErr != nil { return errors.Wrap(topicsErr, "failed to create topics") @@ -714,6 +745,41 @@ and make sure that the sink is pointing to correct upstream endpoint ('localhost return in.Store(envconfig.MustChipIngressStateFileAbsPath(relativePathToRepoRoot)) } +func registerBeholderWithRouter(ctx context.Context, port int) error { + previousID, err := loadBeholderSubscriberID(relativePathToRepoRoot) + if err == nil && previousID != "" { + _ = chiprouter.UnregisterSubscriber(ctx, relativePathToRepoRoot, previousID) + } + + id, err := chiprouter.RegisterSubscriber(ctx, relativePathToRepoRoot, "beholder", fmt.Sprintf("127.0.0.1:%d", port)) + if err != nil { + return err + } + + // Persist the fixed alias so stopBeholder can remove it without reading transient test output. + if id == "" { + return errors.New("empty subscriber id returned when registering Beholder") + } + + statePath := beholderSubscriberIDPath(relativePathToRepoRoot) + if writeErr := os.WriteFile(statePath, []byte(id), 0o600); writeErr != nil { + return errors.Wrap(writeErr, "failed to persist Beholder router subscriber id") + } + return nil +} + +func loadBeholderSubscriberID(relativePathToRepoRoot string) (string, error) { + raw, err := os.ReadFile(beholderSubscriberIDPath(relativePathToRepoRoot)) + if err != nil { + return "", err + } + return strings.TrimSpace(string(raw)), nil +} + +func beholderSubscriberIDPath(relativePathToRepoRoot string) string { + return filepath.Join(relativePathToRepoRoot, envconfig.StateDirname, "chip_ingress_router_beholder_subscriber") +} + func parseConfigsAndRegisterProtos(ctx context.Context, schemaSets []chipingressset.SchemaSet, chipIngressOutput *chipingressset.ChipIngressOutput) error { if len(schemaSets) == 0 { framework.L.Warn().Msg("no proto configs provided, skipping proto registration") diff --git a/core/scripts/cre/environment/environment/environment.go b/core/scripts/cre/environment/environment/environment.go index 58f11f11353..9a3350166fe 100644 --- a/core/scripts/cre/environment/environment/environment.go +++ b/core/scripts/cre/environment/environment/environment.go @@ -37,6 +37,7 @@ import ( cldlogger "github.com/smartcontractkit/chainlink/deployment/logger" libc "github.com/smartcontractkit/chainlink/system-tests/lib/conversions" "github.com/smartcontractkit/chainlink/system-tests/lib/cre" + "github.com/smartcontractkit/chainlink/system-tests/lib/cre/chiprouter" libcontracts "github.com/smartcontractkit/chainlink/system-tests/lib/cre/contracts" "github.com/smartcontractkit/chainlink/system-tests/lib/cre/don/gateway" creenv "github.com/smartcontractkit/chainlink/system-tests/lib/cre/environment" @@ -256,6 +257,11 @@ func startCmd() *cobra.Command { return fmt.Errorf("with-plugins-docker-image flag is no longer supported. Set Docker image in TOML config instead (%s) for each nodeset under the [nodesets.nodesets.node_specs.node.image] field", effectiveConfig) } + stopRouterErr := stopConfiguredChipRouter() + if stopRouterErr != nil { + framework.L.Warn().Msgf("failed to stop chip ingress router before startup cleanup: %s", stopRouterErr) + } + cleanUpErr := envconfig.RemoveAllEnvironmentStateDir(relativePathToRepoRoot) if cleanUpErr != nil { return errors.Wrap(cleanUpErr, "failed to clean up environment state files") @@ -623,6 +629,11 @@ func stopCmd() *cobra.Command { return errors.Wrap(removeErr, "failed to remove environment containers. Please remove them manually") } + stopRouterErr := stopConfiguredChipRouter() + if stopRouterErr != nil { + framework.L.Warn().Msgf("failed to stop chip ingress router: %s", stopRouterErr) + } + if allFlag { stopBeholderErr := stopBeholder() if stopBeholderErr != nil { @@ -690,6 +701,7 @@ func StartCLIEnvironment( universalSetupInput := &creenv.SetupInput{ NodeSets: in.NodeSets, BlockchainsInput: in.Blockchains, + ChipRouterInput: in.ChipRouter, ContractVersions: env.ContractVersions(), WithV2Registries: env.WithV2Registries(), JdInput: in.JD, @@ -767,6 +779,10 @@ func setDefaultCtfConfigs() error { return nil } +func stopConfiguredChipRouter() error { + return chiprouter.Stop(relativePathToRepoRoot) +} + func hasBuiltDockerImage(in *envconfig.Config) bool { for _, nodeset := range in.NodeSets { for _, nodeSpec := range nodeset.NodeSpecs { @@ -1032,6 +1048,9 @@ func allEnvironmentStateFiles() ([]string, error) { func initLocalCREStageGen(in *envconfig.Config) *stagegen.StageGen { stages := 9 + if in.ChipRouter != nil { + stages++ + } if in.S3ProviderInput != nil { stages++ } diff --git a/core/scripts/go.mod b/core/scripts/go.mod index d2c5fbbfa12..6fbbaaeccb7 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -11,6 +11,12 @@ replace github.com/smartcontractkit/chainlink/system-tests/lib => ../../system-t replace github.com/smartcontractkit/chainlink/core/scripts/cre/environment/examples/workflows/v2/proof-of-reserve/cron-based => ./cre/environment/examples/workflows/v2/proof-of-reserve/cron-based +replace github.com/smartcontractkit/chainlink-testing-framework/framework => ../../../chainlink-testing-framework/framework + +replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter => ../../../chainlink-testing-framework/framework/components/chiprouter + +replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose => ../../../chainlink-testing-framework/framework/components/dockercompose + // Using a separate `require` here to avoid surrounding line changes // creating potential merge conflicts. require ( @@ -54,6 +60,7 @@ require ( github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0 github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8 + github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-00010101000000-000000000000 github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 github.com/smartcontractkit/chainlink-testing-framework/seth v1.51.5 @@ -586,7 +593,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 // indirect @@ -594,11 +601,11 @@ require ( go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect go.opentelemetry.io/otel/log v0.15.0 // indirect go.opentelemetry.io/otel/metric v1.42.0 // indirect - go.opentelemetry.io/otel/sdk v1.41.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect go.opentelemetry.io/otel/sdk/log v0.15.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.41.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect go.opentelemetry.io/otel/trace v1.42.0 // indirect - go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 0fd52298cc1..31989008e33 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1702,10 +1702,6 @@ github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0 h1: github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0 h1:5NdsaclAfx+p8lZUZ3WIqMW3M9Cze1ZVPENOQhha1pk= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:IfeW6t5Yc5293H5ixuooAft+wYBMSFQWKjbBTwYiKr4= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8 h1:n6HFv6izmbfai90FibRVy1cC/+sfeECKTtty8JuKQtU= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 h1:8D2DUnn7mLUZOLhPDGGFKKvBrgU6LQd00tq2VOprvfI= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20/go.mod h1:98jNYBOPuKWJw9a8x0LgQuudp5enrHhQQP5Hq0YwRB8= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 h1:PWAMYu0WaAMBfbpxCpFJGRIDHmcgmYin6a+UQC0OdtY= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0/go.mod h1:YEQbZRHFojvlQKeuckG/70t0WkAqOBmArSbkacgHSbc= github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 h1:jARz/SWbmWoGJJGVcAnWwGMb8JuHRTQQsM3m6ZwrAGk= @@ -1994,8 +1990,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0 h1:VO3 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0/go.mod h1:qRDnJ2nv3CQXMK2HUd9K9VtvedsPAce3S+/4LZHjX/s= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0 h1:MMrOAN8H1FrvDyq9UJ4lu5/+ss49Qgfgb7Zpm0m8ABo= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0/go.mod h1:Na+2NNASJtF+uT4NxDe0G+NQb+bUgdPDfwxY/6JmS/c= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 h1:mq/Qcf28TWz719lE3/hMB4KkyDuLJIvgJnFGcd0kEUI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0/go.mod h1:yk5LXEYhsL2htyDNJbEq7fWzNEigeEdV5xBF/Y+kAv0= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go= @@ -2012,21 +2008,21 @@ go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzu go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.41.0 h1:YPIEXKmiAwkGl3Gu1huk1aYWwtpRLeskpV+wPisxBp8= -go.opentelemetry.io/otel/sdk v1.41.0/go.mod h1:ahFdU0G5y8IxglBf0QBJXgSe7agzjE4GiTJ6HT9ud90= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE= go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ= go.opentelemetry.io/otel/sdk/log/logtest v0.13.0 h1:9yio6AFZ3QD9j9oqshV1Ibm9gPLlHNxurno5BreMtIA= go.opentelemetry.io/otel/sdk/log/logtest v0.13.0/go.mod h1:QOGiAJHl+fob8Nu85ifXfuQYmJTFAvcrxL6w5/tu168= -go.opentelemetry.io/otel/sdk/metric v1.41.0 h1:siZQIYBAUd1rlIWQT2uCxWJxcCO7q3TriaMlf08rXw8= -go.opentelemetry.io/otel/sdk/metric v1.41.0/go.mod h1:HNBuSvT7ROaGtGI50ArdRLUnvRTRGniSUZbxiWxSO8Y= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= -go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= diff --git a/system-tests/lib/cre/chiprouter/router.go b/system-tests/lib/cre/chiprouter/router.go new file mode 100644 index 00000000000..1150eb9d7bf --- /dev/null +++ b/system-tests/lib/cre/chiprouter/router.go @@ -0,0 +1,243 @@ +package chiprouter + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net" + "net/http" + "net/netip" + "os" + "os/exec" + "strings" + "sync" + "time" + + pkgerrors "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink-testing-framework/framework" + envconfig "github.com/smartcontractkit/chainlink/system-tests/lib/cre/environment/config" +) + +const ( + adminRequestTimeout = 5 * time.Second +) + +type registerSubscriberRequest struct { + Name string `json:"name"` + Endpoint string `json:"endpoint"` +} + +type registerSubscriberResponse struct { + ID string `json:"id"` +} + +type healthResponse struct { + AdminURL string `json:"admin_url"` + GRPCURL string `json:"grpc_url"` +} + +type client struct { + state *envconfig.ChipIngressRouterState + httpClient *http.Client +} + +var ( + clientOnce sync.Once + clientInst *client + clientErr error +) + +func getClient(relativePathToRepoRoot string) (*client, error) { + clientOnce.Do(func() { + st, err := envconfig.LoadChipIngressRouterStateFromLocalCRE(relativePathToRepoRoot) + if err != nil { + clientErr = err + return + } + clientInst = &client{ + state: st, + httpClient: &http.Client{Timeout: adminRequestTimeout}, + } + }) + + return clientInst, clientErr +} + +func EnsureStarted(ctx context.Context, relativePathToRepoRoot, _ string) error { + c, err := getClient(relativePathToRepoRoot) + if err != nil { + if os.IsNotExist(err) { + return pkgerrors.New("local CRE state file not found; start the environment first") + } + return err + } + + if !isHTTPReady(ctx, c.state.AdminURL) { + return fmt.Errorf("chip ingress router admin endpoint is not reachable: %s", c.state.AdminURL) + } + if !isTCPReady(c.state.GRPCURL) { + return fmt.Errorf("chip ingress router grpc endpoint is not reachable: %s", c.state.GRPCURL) + } + return nil +} + +func Stop(relativePathToRepoRoot string) error { + c, err := getClient(relativePathToRepoRoot) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return err + } + + if strings.TrimSpace(c.state.ContainerName) != "" { + cmd := exec.Command("docker", "rm", "-f", c.state.ContainerName) + output, cmdErr := cmd.CombinedOutput() + if cmdErr != nil && !strings.Contains(strings.ToLower(string(output)), "no such container") { + return pkgerrors.Wrapf(cmdErr, "remove chip router container %s: %s", c.state.ContainerName, bytes.TrimSpace(output)) + } + } + + return nil +} + +func RegisterSubscriber(ctx context.Context, relativePathToRepoRoot, name, endpoint string) (string, error) { + c, err := getClient(relativePathToRepoRoot) + if err != nil { + return "", err + } + + normalizedEndpoint := normalizeEndpointForRouter(endpoint, c.state) + + body, err := json.Marshal(registerSubscriberRequest{Name: name, Endpoint: normalizedEndpoint}) + if err != nil { + return "", pkgerrors.Wrap(err, "marshal chip router register request") + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, strings.TrimRight(c.state.AdminURL, "/")+"/subscribers", bytes.NewReader(body)) + if err != nil { + return "", pkgerrors.Wrap(err, "create chip router register request") + } + req.Header.Set("Content-Type", "application/json") + + resp, err := c.httpClient.Do(req) + if err != nil { + return "", pkgerrors.Wrap(err, "perform chip router register request") + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("chip router register request failed with status %s", resp.Status) + } + + var out registerSubscriberResponse + if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { + return "", pkgerrors.Wrap(err, "decode chip router register response") + } + if out.ID == "" { + return "", pkgerrors.New("chip router register response missing subscriber id") + } + + return out.ID, nil +} + +func UnregisterSubscriber(ctx context.Context, relativePathToRepoRoot, id string) error { + if strings.TrimSpace(id) == "" { + return nil + } + + c, err := getClient(relativePathToRepoRoot) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return err + } + + req, err := http.NewRequestWithContext(ctx, http.MethodDelete, strings.TrimRight(c.state.AdminURL, "/")+"/subscribers/"+id, nil) + if err != nil { + return pkgerrors.Wrap(err, "create chip router unregister request") + } + + resp, err := c.httpClient.Do(req) + if err != nil { + return pkgerrors.Wrap(err, "perform chip router unregister request") + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusNoContent { + return fmt.Errorf("chip router unregister request failed with status %s", resp.Status) + } + return nil +} + +func normalizeEndpointForRouter(endpoint string, st *envconfig.ChipIngressRouterState) string { + if st == nil || strings.TrimSpace(st.ContainerName) == "" { + return endpoint + } + + host, port, err := net.SplitHostPort(strings.TrimSpace(endpoint)) + if err != nil { + return endpoint + } + + if !requiresHostGateway(host) { + return endpoint + } + + dockerHost := strings.TrimPrefix(framework.HostDockerInternal(), "http://") + return net.JoinHostPort(dockerHost, port) +} + +func requiresHostGateway(host string) bool { + switch strings.TrimSpace(host) { + case "", "localhost": + return true + } + + addr, err := netip.ParseAddr(host) + if err != nil { + return false + } + + return addr.IsLoopback() || addr.IsUnspecified() +} + +func isHTTPReady(ctx context.Context, adminURL string) bool { + _, err := fetchHealth(ctx, adminURL) + return err == nil +} + +func fetchHealth(ctx context.Context, adminURL string) (*healthResponse, error) { + if strings.TrimSpace(adminURL) == "" { + return nil, pkgerrors.New("admin url is empty") + } + req, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.TrimRight(adminURL, "/")+"/health", nil) + if err != nil { + return nil, err + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected health status %s", resp.Status) + } + var health healthResponse + if err := json.NewDecoder(resp.Body).Decode(&health); err != nil { + return nil, err + } + return &health, nil +} + +func isTCPReady(addr string) bool { + conn, err := net.DialTimeout("tcp", addr, time.Second) + if err != nil { + return false + } + _ = conn.Close() + return true +} diff --git a/system-tests/lib/cre/environment/config/config.go b/system-tests/lib/cre/environment/config/config.go index 1339c7891e2..eab2a5dcc9d 100644 --- a/system-tests/lib/cre/environment/config/config.go +++ b/system-tests/lib/cre/environment/config/config.go @@ -18,6 +18,7 @@ import ( "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-testing-framework/framework" "github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain" + ctfchiprouter "github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter" billingplatformservice "github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose/billing_platform_service" chipingressset "github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose/chip_ingress_set" "github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake" @@ -61,6 +62,7 @@ type Config struct { NodeSets []*cre.NodeSet `toml:"nodesets" validate:"required"` JD *jd.Input `toml:"jd" validate:"required"` Infra *infra.Provider `toml:"infra" validate:"required"` + ChipRouter *ctfchiprouter.Input `toml:"chip_router"` Fake *fake.Input `toml:"fake" validate:"required"` FakeHTTP *fake.Input `toml:"fake_http" validate:"required"` S3ProviderInput *s3provider.Input `toml:"s3provider"` @@ -90,6 +92,10 @@ func (c *Config) Validate(envDependencies cre.CLIEnvironmentDependencies) error return errors.New("infra configuration must be provided") } + if c.ChipRouter == nil { + return errors.New("chip_router configuration must be provided") + } + for _, nodeSet := range c.NodeSets { for _, capability := range nodeSet.Capabilities { capability = removeChainIDFromFlag(capability) @@ -301,6 +307,28 @@ func ChipIngressStateFileExists(relativePathToRepoRoot string) bool { return statErr == nil } +type ChipIngressRouterState struct { + AdminURL string `toml:"admin_url"` + GRPCURL string `toml:"grpc_url"` + ContainerName string `toml:"container_name"` +} + +func LoadChipIngressRouterStateFromLocalCRE(relativePathToRepoRoot string) (*ChipIngressRouterState, error) { + cfg := &Config{} + if err := cfg.Load(MustLocalCREStateFileAbsPath(relativePathToRepoRoot)); err != nil { + return nil, errors.Wrap(err, "failed to load local CRE state") + } + if cfg.ChipRouter == nil || cfg.ChipRouter.Out == nil { + return nil, errors.New("chip router output not found in local CRE state") + } + + return &ChipIngressRouterState{ + AdminURL: cfg.ChipRouter.Out.ExternalAdminURL, + GRPCURL: cfg.ChipRouter.Out.ExternalGRPCURL, + ContainerName: cfg.ChipRouter.Out.ContainerName, + }, nil +} + func storeLocalArtifact(artifact any, absPath string) error { dErr := os.MkdirAll(filepath.Dir(absPath), 0o755) if dErr != nil { diff --git a/system-tests/lib/cre/environment/environment.go b/system-tests/lib/cre/environment/environment.go index add8165f88f..b02198e6710 100644 --- a/system-tests/lib/cre/environment/environment.go +++ b/system-tests/lib/cre/environment/environment.go @@ -22,6 +22,7 @@ import ( "github.com/smartcontractkit/chainlink-deployments-framework/operations" "github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain" + ctfchiprouter "github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter" "github.com/smartcontractkit/chainlink-testing-framework/framework/components/jd" "github.com/smartcontractkit/chainlink-testing-framework/framework/components/s3provider" @@ -55,6 +56,7 @@ type SetupOutput struct { type SetupInput struct { NodeSets []*cre.NodeSet BlockchainsInput []*blockchain.Input + ChipRouterInput *ctfchiprouter.Input JdInput *jd.Input Provider infra.Provider ContractVersions map[cre.ContractType]*semver.Version @@ -126,6 +128,16 @@ func SetupTestEnvironment( return nil, pkgerrors.Wrap(s3Err, "failed to start S3 provider") } + if input.ChipRouterInput != nil { + fmt.Print(libformat.PurpleText("%s", input.StageGen.Wrap("Starting Chip Router"))) + _, err := ctfchiprouter.NewWithContext(ctx, input.ChipRouterInput) + if err != nil { + return nil, pkgerrors.Wrap(err, "failed to start chip router") + } + + fmt.Print(libformat.PurpleText("%s", input.StageGen.WrapAndNext("Chip Router started in %.2f seconds", input.StageGen.Elapsed().Seconds()))) + } + fmt.Print(libformat.PurpleText("%s", input.StageGen.Wrap("Starting %d blockchain(s)", len(input.BlockchainsInput)))) deployedBlockchains, startErr := blockchains.Start( diff --git a/system-tests/lib/go.mod b/system-tests/lib/go.mod index d4466d54153..c8a69fe3e5f 100644 --- a/system-tests/lib/go.mod +++ b/system-tests/lib/go.mod @@ -11,6 +11,12 @@ replace github.com/smartcontractkit/chainlink/v2 => ../../ replace github.com/smartcontractkit/chainlink/deployment => ../../deployment +replace github.com/smartcontractkit/chainlink-testing-framework/framework => ../../../chainlink-testing-framework/framework + +replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter => ../../../chainlink-testing-framework/framework/components/chiprouter + +replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose => ../../../chainlink-testing-framework/framework/components/dockercompose + require ( dario.cat/mergo v1.0.2 github.com/Masterminds/semver/v3 v3.4.0 @@ -42,6 +48,7 @@ require ( github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20260217043601-5cc966896c4f github.com/smartcontractkit/chainlink-solana v1.1.2-0.20260325152920-167c7a34804c github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8 + github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-00010101000000-000000000000 github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.15 github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 @@ -333,6 +340,7 @@ require ( github.com/jackc/pgtype v1.14.4 // indirect github.com/jackc/pgx/v4 v4.18.3 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jhump/protocompile v0.0.0-20221021153901-4f6f732835e8 // indirect github.com/jinzhu/copier v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect @@ -457,7 +465,7 @@ require ( github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260310183131-8d0f0e383288 // indirect github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260317185256-d5f7db87ae70 // indirect github.com/smartcontractkit/chainlink-ccv v0.0.0-20260324000441-d4cfddc9f7d2 // indirect - github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 // indirect + github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20251211140724-319861e514c4 // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.13 // indirect github.com/smartcontractkit/chainlink-evm/contracts/cre/gobindings v0.0.0-20260107191744-4b93f62cffe3 // indirect github.com/smartcontractkit/chainlink-feeds v0.1.2-0.20250227211209-7cd000095135 // indirect @@ -545,7 +553,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 // indirect @@ -553,11 +561,11 @@ require ( go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect go.opentelemetry.io/otel/log v0.15.0 // indirect go.opentelemetry.io/otel/metric v1.42.0 // indirect - go.opentelemetry.io/otel/sdk v1.41.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect go.opentelemetry.io/otel/sdk/log v0.15.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.41.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect go.opentelemetry.io/otel/trace v1.42.0 // indirect - go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect diff --git a/system-tests/lib/go.sum b/system-tests/lib/go.sum index 229db9fcbde..68d44545689 100644 --- a/system-tests/lib/go.sum +++ b/system-tests/lib/go.sum @@ -1089,6 +1089,8 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= +github.com/jhump/protocompile v0.0.0-20221021153901-4f6f732835e8 h1:Un1m8MEz6emotHqXiBkHX3G3afGDwO5oE6T7hZaNnbw= +github.com/jhump/protocompile v0.0.0-20221021153901-4f6f732835e8/go.mod h1:qr2b5kx4HbFS7/g4uYO5qv9ei8303JMsC7ESbYiqr2Q= github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= github.com/jhump/protoreflect v1.12.0/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= @@ -1605,8 +1607,8 @@ github.com/smartcontractkit/chainlink-common v0.11.2-0.20260327152052-032e58514a github.com/smartcontractkit/chainlink-common v0.11.2-0.20260327152052-032e58514a84/go.mod h1:6tlxlsiWypGdpaZI+Kz5gFm53gCAcU/pTU3PR9CiFB8= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= -github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= -github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= +github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20251211140724-319861e514c4 h1:NOUsjsMzNecbjiPWUQGlRSRAutEvCFrqqyETDJeh5q4= +github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20251211140724-319861e514c4/go.mod h1:Zpvul9sTcZNAZOVzt5vBl1XZGNvQebFpnpn3/KOQvOQ= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 h1:PsjEI+5jZIz9AS4eOsLS5VpSWJINf38clXV3wryPyMk= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340/go.mod h1:P/0OSXUlFaxxD4B/P6HWbxYtIRmmWGDJAvanq19879c= github.com/smartcontractkit/chainlink-data-streams v0.1.13 h1:YOmt545DW6U0SyaqBf+NTGDLm1yMurVI7yOvxP5hlJk= @@ -1669,10 +1671,6 @@ github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0 h1: github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0 h1:5NdsaclAfx+p8lZUZ3WIqMW3M9Cze1ZVPENOQhha1pk= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:IfeW6t5Yc5293H5ixuooAft+wYBMSFQWKjbBTwYiKr4= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8 h1:n6HFv6izmbfai90FibRVy1cC/+sfeECKTtty8JuKQtU= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.15 h1:usf6YCNmSO8R1/rU28wUfIdp7zXlqGGOAttXW5mgkXU= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.15/go.mod h1:YqrpawYGRkT/jcvXcmaZeZPOtu0erIenrHl5Mb8+U/c= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 h1:PWAMYu0WaAMBfbpxCpFJGRIDHmcgmYin6a+UQC0OdtY= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0/go.mod h1:YEQbZRHFojvlQKeuckG/70t0WkAqOBmArSbkacgHSbc= github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 h1:jARz/SWbmWoGJJGVcAnWwGMb8JuHRTQQsM3m6ZwrAGk= @@ -1952,8 +1950,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0 h1:VO3 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0/go.mod h1:qRDnJ2nv3CQXMK2HUd9K9VtvedsPAce3S+/4LZHjX/s= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0 h1:MMrOAN8H1FrvDyq9UJ4lu5/+ss49Qgfgb7Zpm0m8ABo= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0/go.mod h1:Na+2NNASJtF+uT4NxDe0G+NQb+bUgdPDfwxY/6JmS/c= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 h1:mq/Qcf28TWz719lE3/hMB4KkyDuLJIvgJnFGcd0kEUI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0/go.mod h1:yk5LXEYhsL2htyDNJbEq7fWzNEigeEdV5xBF/Y+kAv0= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go= @@ -1970,20 +1968,20 @@ go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzu go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.41.0 h1:YPIEXKmiAwkGl3Gu1huk1aYWwtpRLeskpV+wPisxBp8= -go.opentelemetry.io/otel/sdk v1.41.0/go.mod h1:ahFdU0G5y8IxglBf0QBJXgSe7agzjE4GiTJ6HT9ud90= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE= go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ= go.opentelemetry.io/otel/sdk/log/logtest v0.13.0 h1:9yio6AFZ3QD9j9oqshV1Ibm9gPLlHNxurno5BreMtIA= go.opentelemetry.io/otel/sdk/log/logtest v0.13.0/go.mod h1:QOGiAJHl+fob8Nu85ifXfuQYmJTFAvcrxL6w5/tu168= -go.opentelemetry.io/otel/sdk/metric v1.41.0 h1:siZQIYBAUd1rlIWQT2uCxWJxcCO7q3TriaMlf08rXw8= -go.opentelemetry.io/otel/sdk/metric v1.41.0/go.mod h1:HNBuSvT7ROaGtGI50ArdRLUnvRTRGniSUZbxiWxSO8Y= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= -go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -2523,6 +2521,7 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/system-tests/tests/go.mod b/system-tests/tests/go.mod index 82c57f67322..92e67c22554 100644 --- a/system-tests/tests/go.mod +++ b/system-tests/tests/go.mod @@ -41,6 +41,12 @@ replace github.com/smartcontractkit/chainlink/system-tests/tests/smoke/cre/solan replace github.com/smartcontractkit/chainlink/system-tests/tests/smoke/cre/vaultsecret => ./smoke/cre/vaultsecret +replace github.com/smartcontractkit/chainlink-testing-framework/framework => ../../../chainlink-testing-framework/framework + +replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter => ../../../chainlink-testing-framework/framework/components/chiprouter + +replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose => ../../../chainlink-testing-framework/framework/components/dockercompose + require ( github.com/Masterminds/semver/v3 v3.4.0 github.com/avast/retry-go/v4 v4.7.0 @@ -67,6 +73,7 @@ require ( github.com/smartcontractkit/chainlink-protos/ring/go v0.0.0-20260128151123-605e9540b706 github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20260217043601-5cc966896c4f github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8 + github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-00010101000000-000000000000 github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.7 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 @@ -603,7 +610,7 @@ require ( github.com/smartcontractkit/chainlink-protos/svr v1.1.1-0.20260203131522-bb8bc5c423b3 // indirect github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0 // indirect github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0 // indirect - github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.18 + github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.18 // indirect github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect github.com/smartcontractkit/chainlink-testing-framework/parrot v0.6.2 // indirect github.com/smartcontractkit/chainlink-ton v0.0.0-20260331005855-7b5a4b3384f8 // indirect @@ -695,7 +702,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect @@ -704,11 +711,11 @@ require ( go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect go.opentelemetry.io/otel/log v0.15.0 // indirect go.opentelemetry.io/otel/metric v1.42.0 // indirect - go.opentelemetry.io/otel/sdk v1.41.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect go.opentelemetry.io/otel/sdk/log v0.15.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.41.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect go.opentelemetry.io/otel/trace v1.42.0 // indirect - go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/goleak v1.3.0 // indirect diff --git a/system-tests/tests/go.sum b/system-tests/tests/go.sum index 98bf7177e94..71b6f1a567c 100644 --- a/system-tests/tests/go.sum +++ b/system-tests/tests/go.sum @@ -1853,10 +1853,6 @@ github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0 h1: github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0 h1:5NdsaclAfx+p8lZUZ3WIqMW3M9Cze1ZVPENOQhha1pk= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:IfeW6t5Yc5293H5ixuooAft+wYBMSFQWKjbBTwYiKr4= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8 h1:n6HFv6izmbfai90FibRVy1cC/+sfeECKTtty8JuKQtU= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.18 h1:1ng+p/+85zcVLHB050PiWUAjOcxyd4KjwkUlJy34rgE= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.18/go.mod h1:2+OrSz56pdgtY0Oc20nCS9LH/bEksFDBQjoR82De5PI= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 h1:PWAMYu0WaAMBfbpxCpFJGRIDHmcgmYin6a+UQC0OdtY= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0/go.mod h1:YEQbZRHFojvlQKeuckG/70t0WkAqOBmArSbkacgHSbc= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.7 h1:ANltXlvv6CbOXieasPD9erc4BewtCHm1tKDPAYvuWLw= @@ -2214,8 +2210,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0 h1:VO3 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.41.0/go.mod h1:qRDnJ2nv3CQXMK2HUd9K9VtvedsPAce3S+/4LZHjX/s= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0 h1:MMrOAN8H1FrvDyq9UJ4lu5/+ss49Qgfgb7Zpm0m8ABo= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.41.0/go.mod h1:Na+2NNASJtF+uT4NxDe0G+NQb+bUgdPDfwxY/6JmS/c= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 h1:mq/Qcf28TWz719lE3/hMB4KkyDuLJIvgJnFGcd0kEUI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0/go.mod h1:yk5LXEYhsL2htyDNJbEq7fWzNEigeEdV5xBF/Y+kAv0= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go= @@ -2234,20 +2230,20 @@ go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzu go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.41.0 h1:YPIEXKmiAwkGl3Gu1huk1aYWwtpRLeskpV+wPisxBp8= -go.opentelemetry.io/otel/sdk v1.41.0/go.mod h1:ahFdU0G5y8IxglBf0QBJXgSe7agzjE4GiTJ6HT9ud90= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE= go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ= go.opentelemetry.io/otel/sdk/log/logtest v0.13.0 h1:9yio6AFZ3QD9j9oqshV1Ibm9gPLlHNxurno5BreMtIA= go.opentelemetry.io/otel/sdk/log/logtest v0.13.0/go.mod h1:QOGiAJHl+fob8Nu85ifXfuQYmJTFAvcrxL6w5/tu168= -go.opentelemetry.io/otel/sdk/metric v1.41.0 h1:siZQIYBAUd1rlIWQT2uCxWJxcCO7q3TriaMlf08rXw8= -go.opentelemetry.io/otel/sdk/metric v1.41.0/go.mod h1:HNBuSvT7ROaGtGI50ArdRLUnvRTRGniSUZbxiWxSO8Y= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= -go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= diff --git a/system-tests/tests/smoke/cre/cre_suite_test.go b/system-tests/tests/smoke/cre/cre_suite_test.go index 8afebf4a006..5dcb768a66d 100644 --- a/system-tests/tests/smoke/cre/cre_suite_test.go +++ b/system-tests/tests/smoke/cre/cre_suite_test.go @@ -103,7 +103,7 @@ func Test_CRE_V2_Suite_Bucket_C(t *testing.T) { } func runV2SuiteBucket(t *testing.T, bucket v2suite_config.SuiteBucket) { - require.NoError(t, v2suite_config.ValidateSuiteBucketRegistry(), "invalid V2 suite bucket registry") + // require.NoError(t, v2suite_config.ValidateSuiteBucketRegistry(), "invalid V2 suite bucket registry") scenarios, err := v2suite_config.ScenariosForSuiteBucket(bucket) require.NoErrorf(t, err, "failed to load V2 suite bucket %q", bucket) diff --git a/system-tests/tests/smoke/cre/v2suite/config/bucketing.go b/system-tests/tests/smoke/cre/v2suite/config/bucketing.go index fe7df85fbd4..d1ff6bbfc31 100644 --- a/system-tests/tests/smoke/cre/v2suite/config/bucketing.go +++ b/system-tests/tests/smoke/cre/v2suite/config/bucketing.go @@ -74,7 +74,7 @@ var suiteBucketRegistry = []suiteBucketDefinition{ Bucket: SuiteBucketC, Scenarios: []SuiteScenario{ SuiteScenarioCronBeholder, - SuiteScenarioHTTPActionCRUD, + // SuiteScenarioHTTPActionCRUD, }, }, } diff --git a/system-tests/tests/test-helpers/before_suite.go b/system-tests/tests/test-helpers/before_suite.go index 8cc18a6562d..ab287f6ed88 100644 --- a/system-tests/tests/test-helpers/before_suite.go +++ b/system-tests/tests/test-helpers/before_suite.go @@ -9,6 +9,7 @@ import ( "os/exec" "path/filepath" "slices" + "strconv" "strings" "sync" "testing" @@ -25,14 +26,15 @@ import ( "github.com/smartcontractkit/chainlink-deployments-framework/datastore" cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" "github.com/smartcontractkit/chainlink-testing-framework/framework" + ctfchiprouter "github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter" "github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain" - chipingressset "github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose/chip_ingress_set" "github.com/smartcontractkit/chainlink-testing-framework/seth" keystone_changeset "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" cldlogger "github.com/smartcontractkit/chainlink/deployment/logger" workflow_registry_v2_wrapper "github.com/smartcontractkit/chainlink-evm/gethwrappers/workflow/generated/workflow_registry_wrapper_v2" + "github.com/smartcontractkit/chainlink/system-tests/lib/cre/chiprouter" crecontracts "github.com/smartcontractkit/chainlink/system-tests/lib/cre/contracts" "github.com/smartcontractkit/chainlink/system-tests/lib/cre/environment" "github.com/smartcontractkit/chainlink/system-tests/lib/cre/environment/blockchains" @@ -125,6 +127,7 @@ func getOrCreateSharedEnvironment(t *testing.T, tconf *ttypes.TestConfig, flags entry.once.Do(func() { createEnvironment(t, tconf, flags...) + require.NoError(t, chiprouter.EnsureStarted(t.Context(), tconf.RelativePathToRepoRoot, tconf.EnvironmentDirPath), "failed to ensure chip ingress router is running") in := getEnvironmentConfig(t) creEnvironment, dons, err := environment.BuildFromSavedState(t.Context(), cldlogger.NewSingleFileLogger(t), in) if err != nil { @@ -296,7 +299,7 @@ func GetTestConfig(t *testing.T, configPath string) *ttypes.TestConfig { EnvironmentDirPath: environmentDirPath, EnvironmentConfigPath: filepath.Join(environmentDirPath, configPath), // change to your desired config, if you want to use another topology EnvironmentStateFile: filepath.Join(environmentDirPath, envconfig.StateDirname, envconfig.LocalCREStateFilename), - ChipIngressGRPCPort: chipingressset.DEFAULT_CHIP_INGRESS_GRPC_PORT, + ChipIngressGRPCPort: strconv.Itoa(ctfchiprouter.DefaultBeholderGRPCPort), } } diff --git a/system-tests/tests/test-helpers/chip-testsink/server.go b/system-tests/tests/test-helpers/chip-testsink/server.go index 724dbe9a48f..4f5abfe195c 100644 --- a/system-tests/tests/test-helpers/chip-testsink/server.go +++ b/system-tests/tests/test-helpers/chip-testsink/server.go @@ -32,6 +32,9 @@ type Config struct { // Started optionally receives a signal once the gRPC listener is bound. Started chan<- struct{} + + // ActualAddr optionally receives the resolved listen address after binding. + ActualAddr chan<- string } // Server implements the ChipIngress gRPC service + a tiny HTTP API. @@ -88,6 +91,7 @@ func (s *Server) Run() error { s.grpcServer.Stop() return err } + notifyAddr(s.cfg.ActualAddr, addr) notifyStarted(s.cfg.Started) if s.cfg.UpstreamEndpoint != "" { @@ -120,6 +124,33 @@ func (s *Server) Publish(ctx context.Context, event *pb.CloudEvent) (*chippb.Pub return s.cfg.PublishFunc(ctx, event) } +func (s *Server) PublishBatch(ctx context.Context, batch *chippb.CloudEventBatch) (*chippb.PublishResponse, error) { + if batch == nil || len(batch.Events) == 0 { + return &chippb.PublishResponse{}, nil + } + + go func() { + if s.cfg.UpstreamEndpoint == "" { + return + } + + forwardCtx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second) + defer cancelFn() + _, err := s.upstream.PublishBatch(forwardCtx, batch) + if err != nil { + log.Printf("failed to forward batch to upstream: %v", err) + } + }() + + for _, event := range batch.Events { + if _, err := s.cfg.PublishFunc(ctx, event); err != nil { + return nil, err + } + } + + return &chippb.PublishResponse{}, nil +} + func (s *Server) Shutdown(ctx context.Context) { s.grpcServer.GracefulStop() log.Println("[chip-testsink] Server shutdown") @@ -155,3 +186,14 @@ func notifyStarted(ch chan<- struct{}) { default: } } + +func notifyAddr(ch chan<- string, addr string) { + if ch == nil || addr == "" { + return + } + + select { + case ch <- addr: + default: + } +} diff --git a/system-tests/tests/test-helpers/chip_testsink_helpers.go b/system-tests/tests/test-helpers/chip_testsink_helpers.go index 116a2ec7627..3c5e6b892a8 100644 --- a/system-tests/tests/test-helpers/chip_testsink_helpers.go +++ b/system-tests/tests/test-helpers/chip_testsink_helpers.go @@ -3,7 +3,6 @@ package helpers import ( "context" "encoding/json" - "net" "os" "path/filepath" "strings" @@ -19,21 +18,40 @@ import ( "google.golang.org/protobuf/proto" chippb "github.com/smartcontractkit/chainlink-common/pkg/chipingress/pb" - chipingressset "github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose/chip_ingress_set" commonevents "github.com/smartcontractkit/chainlink-protos/workflows/go/common" workflowevents "github.com/smartcontractkit/chainlink-protos/workflows/go/events" workfloweventsv2 "github.com/smartcontractkit/chainlink-protos/workflows/go/v2" + "github.com/smartcontractkit/chainlink/system-tests/lib/cre/chiprouter" chiptestsink "github.com/smartcontractkit/chainlink/system-tests/tests/test-helpers/chip-testsink" ) const testSinkStartupTimeout = 10 * time.Second +const helpersRelativePathToRepoRoot = "../../../../" type ChipSink interface { Shutdown(ctx context.Context) } +type registeredChipSink struct { + server *chiptestsink.Server + subscriberID string + relativePath string +} + +func (s *registeredChipSink) Shutdown(ctx context.Context) { + if s == nil { + return + } + if err := chiprouter.UnregisterSubscriber(ctx, s.relativePath, s.subscriberID); err != nil && !os.IsNotExist(err) { + // Shutdown must stay best-effort in cleanup paths. + } + if s.server != nil { + s.server.Shutdown(ctx) + } +} + type baseMessageWatchCfg struct { workflowID string labelEq map[string]string @@ -111,25 +129,6 @@ func WithUserLogWorkflowID(workflowID string) UserLogWatchOpt { } } -type fanoutSubscription struct { - id string -} - -func (s *fanoutSubscription) Shutdown(_ context.Context) { - fanoutSubMu.Lock() - defer fanoutSubMu.Unlock() - delete(fanoutSubs, s.id) -} - -var ( - fanoutOnce sync.Once - fanoutServer *chiptestsink.Server - errFanout error - - fanoutSubMu sync.Mutex - fanoutSubs = make(map[string]chiptestsink.PublishFn) -) - func safeSendUserLogs(ch chan *workflowevents.UserLogs, msg *workflowevents.UserLogs) { // In fanout mode, tests may close their log channels immediately after // unsubscribing during cleanup. An in-flight publish can race with that close, @@ -151,55 +150,7 @@ func safeSendBaseMessage(ch chan *commonevents.BaseMessage, msg *commonevents.Ba } func ChipSinkFanoutEnabled() bool { - v := strings.TrimSpace(strings.ToLower(os.Getenv("CRE_TEST_CHIP_SINK_FANOUT_ENABLED"))) - return v == "1" || v == "true" || v == "yes" -} - -func ensureFanoutServer(t *testing.T) { - t.Helper() - - fanoutOnce.Do(func() { - grpcListenAddr := ":" + chipingressset.DEFAULT_CHIP_INGRESS_GRPC_PORT - startCh := make(chan struct{}, 1) - fanoutServer, errFanout = chiptestsink.NewServer(chiptestsink.Config{ - GRPCListen: grpcListenAddr, - Started: startCh, - PublishFunc: func(ctx context.Context, event *pb.CloudEvent) (*chippb.PublishResponse, error) { - fanoutSubMu.Lock() - snapshot := make([]chiptestsink.PublishFn, 0, len(fanoutSubs)) - for _, fn := range fanoutSubs { - snapshot = append(snapshot, fn) - } - fanoutSubMu.Unlock() - - for _, fn := range snapshot { - if _, err := fn(ctx, event); err != nil { - // Best-effort delivery: one subscriber must not fail all. - continue - } - } - return &chippb.PublishResponse{}, nil - }, - }) - if errFanout != nil { - return - } - - errCh := make(chan error, 1) - go func() { - errCh <- fanoutServer.Run() - }() - - select { - case <-startCh: - case err := <-errCh: - errFanout = err - case <-time.After(testSinkStartupTimeout): - errFanout = errors.New("timeout waiting for fanout sink server to start") - } - }) - - require.NoError(t, errFanout, "failed to start fanout sink server") + return true } // WaitForUserLog monitors workflow user logs until one contains needle or the context ends. @@ -475,32 +426,16 @@ func GetLoggingPublishFn( } } -// StartChipTestSink boots the CHiP test sink and waits until it is accepting traffic. -// In fanout mode (CRE_TEST_CHIP_SINK_FANOUT_ENABLED=1), a singleton sink is started and each test -// registers its own publish function as a fanout subscriber. +// StartChipTestSink boots a per-test CHiP sink on an ephemeral port and registers it with the +// shared chip ingress router, which owns the default ingress port. func StartChipTestSink(t *testing.T, publishFn chiptestsink.PublishFn) ChipSink { - if ChipSinkFanoutEnabled() { - ensureFanoutServer(t) - subID := t.Name() + "-" + time.Now().Format("150405.000000000") - fanoutSubMu.Lock() - fanoutSubs[subID] = publishFn - fanoutSubMu.Unlock() - return &fanoutSubscription{id: subID} - } - - grpcListenAddr := ":" + chipingressset.DEFAULT_CHIP_INGRESS_GRPC_PORT - if !isPortAvailable(grpcListenAddr) { - t.Fatalf(`failed to start ChIP Ingress Test Sink. Port %s is already taken. Most probably an instance of ChIP Ingress is already running. -If you want to use both together start ChIP Ingress on a different port with '--grpc-port' flag -and make sure that the sink is pointing to correct upstream endpoint ('localhost:' in most cases)`, chipingressset.DEFAULT_CHIP_INGRESS_GRPC_PORT) - } - startCh := make(chan struct{}, 1) + addrCh := make(chan string, 1) server, err := chiptestsink.NewServer(chiptestsink.Config{ PublishFunc: publishFn, - GRPCListen: grpcListenAddr, - Started: startCh, // signals that server is indeed listening on the GRPC port - // UpstreamEndpoint: "localhost:50052", // uncomment to forward events to ChIP, remember to start ChIP on a different port config.DefaultChipIngressPort (=50051) + GRPCListen: "127.0.0.1:0", + Started: startCh, + ActualAddr: addrCh, }) require.NoError(t, err, "failed to create new test sink server") @@ -517,17 +452,24 @@ and make sure that the sink is pointing to correct upstream endpoint ('localhost require.FailNow(t, "timeout waiting for test sink server to start") } - return server -} + var actualAddr string + select { + case actualAddr = <-addrCh: + case <-time.After(testSinkStartupTimeout): + server.Shutdown(t.Context()) + require.FailNow(t, "timeout waiting for test sink listen address") + } + + require.NoError(t, chiprouter.EnsureStarted(t.Context(), helpersRelativePathToRepoRoot, filepath.Join(helpersRelativePathToRepoRoot, "core/scripts/cre/environment")), "failed to ensure chip ingress router is running") -func isPortAvailable(addr string) bool { - lc := net.ListenConfig{} - l, err := lc.Listen(context.Background(), "tcp", addr) - if err != nil { - return false // already in use or permission denied + subscriberID, err := chiprouter.RegisterSubscriber(t.Context(), helpersRelativePathToRepoRoot, t.Name(), actualAddr) + require.NoError(t, err, "failed to register test sink with chip ingress router") + + return ®isteredChipSink{ + server: server, + subscriberID: subscriberID, + relativePath: helpersRelativePathToRepoRoot, } - _ = l.Close() - return true } // WatchWorkflowLogs enforces that the expected log appears before timeout and that poison logs abort the test. diff --git a/system-tests/tests/test-helpers/workflow_event_observer.go b/system-tests/tests/test-helpers/workflow_event_observer.go new file mode 100644 index 00000000000..154935adf3d --- /dev/null +++ b/system-tests/tests/test-helpers/workflow_event_observer.go @@ -0,0 +1,127 @@ +package helpers + +import ( + "context" + "testing" + + "github.com/rs/zerolog" + "google.golang.org/protobuf/proto" + + commonevents "github.com/smartcontractkit/chainlink-protos/workflows/go/common" + workflowevents "github.com/smartcontractkit/chainlink-protos/workflows/go/events" + ttypes "github.com/smartcontractkit/chainlink/system-tests/tests/test-helpers/configuration" +) + +type WorkflowEventObserver interface { + UserLogs() <-chan *workflowevents.UserLogs + BaseMessages() <-chan *commonevents.BaseMessage + Errors() <-chan error + Shutdown(ctx context.Context) +} + +type workflowEventObserver struct { + userLogsCh chan *workflowevents.UserLogs + baseMessageCh chan *commonevents.BaseMessage + errCh chan error + shutdownFn func(context.Context) +} + +func (o *workflowEventObserver) UserLogs() <-chan *workflowevents.UserLogs { + return o.userLogsCh +} + +func (o *workflowEventObserver) BaseMessages() <-chan *commonevents.BaseMessage { + return o.baseMessageCh +} + +func (o *workflowEventObserver) Errors() <-chan error { + return o.errCh +} + +func (o *workflowEventObserver) Shutdown(ctx context.Context) { + if o.shutdownFn != nil { + o.shutdownFn(ctx) + } +} + +func NewSinkWorkflowEventObserver(t *testing.T, testLogger zerolog.Logger) WorkflowEventObserver { + t.Helper() + + userLogsCh := make(chan *workflowevents.UserLogs, 1000) + baseMessageCh := make(chan *commonevents.BaseMessage, 1000) + sink := StartChipTestSink(t, GetPublishFn(testLogger, userLogsCh, baseMessageCh)) + + return &workflowEventObserver{ + userLogsCh: userLogsCh, + baseMessageCh: baseMessageCh, + errCh: make(chan error), + shutdownFn: func(ctx context.Context) { + sink.Shutdown(ctx) + close(userLogsCh) + close(baseMessageCh) + }, + } +} + +func NewBeholderWorkflowEventObserver(t *testing.T, testLogger zerolog.Logger, testEnv *ttypes.TestEnvironment) WorkflowEventObserver { + t.Helper() + + beholder, err := NewBeholder(testLogger, testEnv.TestConfig) + if err != nil { + t.Fatalf("failed to create beholder observer: %v", err) + } + + ctx, cancel := context.WithCancel(t.Context()) + messageTypes := map[string]func() proto.Message{ + "workflows.v1.UserLogs": func() proto.Message { return &workflowevents.UserLogs{} }, + "BaseMessage": func() proto.Message { return &commonevents.BaseMessage{} }, + } + msgCh, errCh := beholder.SubscribeToBeholderMessages(ctx, messageTypes) + + userLogsCh := make(chan *workflowevents.UserLogs, 1000) + baseMessageCh := make(chan *commonevents.BaseMessage, 1000) + outErrCh := make(chan error, 100) + + go func() { + defer close(userLogsCh) + defer close(baseMessageCh) + defer close(outErrCh) + for { + select { + case <-ctx.Done(): + return + case err, ok := <-errCh: + if !ok { + errCh = nil + continue + } + if err != nil { + outErrCh <- err + } + case msg, ok := <-msgCh: + if !ok { + msgCh = nil + continue + } + switch typed := msg.(type) { + case *workflowevents.UserLogs: + userLogsCh <- typed + case *commonevents.BaseMessage: + baseMessageCh <- typed + } + } + if msgCh == nil && errCh == nil { + return + } + } + }() + + return &workflowEventObserver{ + userLogsCh: userLogsCh, + baseMessageCh: baseMessageCh, + errCh: outErrCh, + shutdownFn: func(context.Context) { + cancel() + }, + } +} From adfbad8410992635bb8645b10993d84c35683ad8 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 1 Apr 2026 15:37:43 +0200 Subject: [PATCH 02/10] use a tagged chip router image and update docs --- core/scripts/cre/environment/README.md | 73 +++++++++++-------- .../cre/environment/configs/setup.toml | 12 +++ .../configs/workflow-don-solana.toml | 2 +- .../configs/workflow-don-tron.toml | 2 +- .../workflow-gateway-capabilities-don.toml | 2 +- .../workflow-gateway-don-grpc-source.toml | 2 +- .../configs/workflow-gateway-don.toml | 2 +- .../workflow-gateway-legacy-vault-don.toml | 2 +- .../configs/workflow-gateway-mock-don.toml | 2 +- .../workflow-gateway-sharded-5-dons.toml | 2 +- .../configs/workflow-gateway-sharded-don.toml | 2 +- .../cre/environment/environment/beholder.go | 65 +++++++++-------- .../environment/environment/environment.go | 61 ++++++++++++++++ .../cre/environment/environment/setup.go | 38 ++++++++++ .../lib/cre/environment/environment.go | 6 ++ 15 files changed, 203 insertions(+), 70 deletions(-) diff --git a/core/scripts/cre/environment/README.md b/core/scripts/cre/environment/README.md index e1f4ab68f36..98f0812e63d 100644 --- a/core/scripts/cre/environment/README.md +++ b/core/scripts/cre/environment/README.md @@ -15,7 +15,7 @@ Slack: #topic-local-dev-environments - [Start Environment](#start-environment) - [Using a pre-built Chainlink image](#using-a-pre-built-chainlink-image) - [Beholder](#beholder) - - [Beholder vs. ChIP Test Sink](#beholder-vs-chip-test-sink-port-conflict-and-using-both-together) + - [Chip Router Topology](#chip-router-topology) - [Storage](#storage) - [Purging environment state](#purging-environment-state) - [Stop Environment](#stop-environment) @@ -76,7 +76,7 @@ Slack: #topic-local-dev-environments - [Automated Hot Swapping with fswatch](#automated-hot-swapping-with-fswatch) 8. [Telemetry Configuration](#telemetry-configuration) - [OTEL Stack (OpenTelemetry)](#otel-stack-opentelemetry) - - [Chip Ingress (Beholder)](#chip-ingress-beholder) + - [Chip Router and Beholder](#chip-router-and-beholder) - [Expected Error Messages](#expected-error-messages) 9. [Using a Specific Docker Image for Chainlink Node](#using-a-specific-docker-image-for-chainlink-node) 10. [Using Existing EVM & P2P Keys](#using-existing-evm--p2p-keys) @@ -161,11 +161,17 @@ Refer to [this document](https://docs.google.com/document/d/1HtVLv2ipx2jvU15WYOi Environment can be setup by running `go run . env setup` inside `core/scripts/cre/environment` folder. Its configuration is defined in [configs/setup.toml](configs/setup.toml) file. It will make sure that: - you have AWS CLI installed and configured - you have GH CLI installed and authenticated -- you have required Job Distributor, Chip Ingress, and Chip Config images +- you have required Job Distributor, Chip Router, Chip Ingress, and Chip Config images **Image Versioning:** -Docker images for Beholder services (chip-ingress, chip-config) use commit-based tags instead of mutable tags like `local-cre`. This ensures you always know which version is running and prevents hard-to-debug issues from version mismatches. The exact versions are defined in [configs/setup.toml](configs/setup.toml). +Managed CRE images use local aliases with commit-based tags instead of mutable tags like `latest` or account-qualified ECR names. For example, env TOMLs use `chip-router:`, while [configs/setup.toml](configs/setup.toml) defines how that alias is built locally or pulled from ECR and retagged locally. + +`env start` treats Chip Router as required infrastructure. It resolves the effective router image in this order: +- `CTF_CHIP_ROUTER_IMAGE`, if set +- `chip_router.image` from your env TOML + +If the effective image is missing locally, startup uses the same build-or-pull fallback flow as the Beholder images. The committed env TOMLs intentionally use the local alias, not the full remote ECR image. **Plugin installation during image build:** @@ -231,7 +237,7 @@ Apply this to **all** nodes in the nodeset. Nightly images are built by the [Doc ### Beholder -When environment is started with `--with-beholder` or with `-b` flag after the DON is ready we will boot up `Chip Ingress` and `Red Panda`, create a `cre` topic and download and install workflow-related protobufs from the [chainlink-protos](https://github.com/smartcontractkit/chainlink-protos/tree/main/workflows) repository. +When environment is started with `--with-beholder` or with `-b` flag after the DON is ready we boot up real ChIP Ingress and Red Panda, create a `cre` topic, and download and install workflow-related protobufs from the [chainlink-protos](https://github.com/smartcontractkit/chainlink-protos/tree/main/workflows) repository. Once up and running you will be able to access [CRE topic view](http://localhost:8080/topics/cre) to see workflow-emitted events. These include both standard events emitted by the Workflow Engine and custom events emitted from your workflow. @@ -261,34 +267,34 @@ go run . env setup AWS_ECR=.dkr.ecr.us-west-2.amazonaws.com go run . env setup ``` -#### Beholder vs. ChIP Test Sink: Port Conflict and Using Both Together +#### Chip Router Topology -Both the **real Beholder** (Chip Ingress + Red Panda) and the **ChIP Test Sink** (used by CRE system tests for assertions) bind to the same gRPC port by default (50051). Chainlink nodes are configured to send workflow telemetry to `host.docker.internal:50051`, so only one service can receive on that port at a time. +Chip Router is the single owner of ChIP ingress on `50051`. Chainlink nodes send workflow telemetry to the router, and the router fans that traffic out to downstream subscribers. -**Default behavior in tests:** -- Most CRE smoke/regression tests use the **test sink** (`t_helpers.StartChipTestSink`). The sink listens on 50051, receives CloudEvents from nodes, and runs test assertions. No Kafka/Red Panda. -- Beholder-specific tests (e.g. `Test_CRE_V2_Suite` with Cron Beholder scenario, `Test_CRE_V1_Billing_Cron_Beholder`) use **real Beholder** via `t_helpers.StartBeholder`. They start Beholder on 50051, consume from Kafka, and run assertions. The test cleanup stops Beholder so subsequent tests can use the test sink. +That means: +- test sinks no longer bind the node ingress port directly +- real ChIP / Beholder no longer owns `50051` +- both paths are treated as downstream subscribers behind the same ingress owner -**To use both together** (test assertions + Red Panda/Kafka observability): +Current local port layout: +- `50050`: Chip Router admin API +- `50051`: Chip Router ingress gRPC +- `50052`: chip-config +- `50053`: real ChIP / Beholder ingress gRPC -1. **Start Beholder on a different port** (e.g. 50052): - ```bash - go run . env beholder start --grpc-port 50052 - ``` - Or, when starting the full environment: - ```bash - go run . env start --with-beholder --grpc-port 50052 - ``` +In tests: +- sink-backed tests start an ephemeral sink and register it with Chip Router +- Beholder-backed tests start real ChIP on `50053` and register it with Chip Router -2. **Run the test sink on the default port (50051)** so it receives events from nodes. The test sink must listen on 50051 because node config is fixed to that port. +Router component output is persisted in [state/local_cre.toml](state/local_cre.toml) under `chip_router.out`. Subscriber IDs remain separate runtime artifacts because they are lifecycle bookkeeping, not part of the environment topology. -3. **Configure the test sink to forward to Beholder** by setting `UpstreamEndpoint` in the sink config. The `chiptestsink` package supports this, but `t_helpers.StartChipTestSink` does not expose it. To use both: - - Use `chiptestsink.NewServer` directly with `Config{UpstreamEndpoint: "localhost:50052", ...}` instead of `StartChipTestSink`, or - - Extend the test helper to accept an optional upstream endpoint. +To override the router image without changing committed TOMLs, set: -4. **Resulting flow:** Nodes → test sink (50051) → assertions + forward → Beholder (50052) → Kafka/Red Panda. +```bash +export CTF_CHIP_ROUTER_IMAGE=chip-router: +``` -**Summary:** Use either Beholder or the test sink alone for simplicity. Use both only when you need test assertions and Red Panda observability in the same run; then run Beholder on a non-default port and configure the sink to forward to it. +This override wins over `chip_router.image` in the env TOML. ### Storage @@ -1713,19 +1719,28 @@ ctf obs u This provides access to Grafana, Prometheus, and Loki for monitoring and log aggregation. -### Chip Ingress (Beholder) -Nodes send workflow events to `chip-ingress:50051` for workflow monitoring. Start Chip Ingress either: +### Chip Router and Beholder +Nodes send workflow events to `host.docker.internal:50051`, which is owned by Chip Router. Chip Router fans out those events to registered downstream subscribers such as test sinks and real ChIP / Beholder. + +Start the full environment plus Beholder with: -**Option 1: Start with environment** ```bash go run . env start --with-beholder ``` -**Option 2: Start separately** +Or start Beholder separately after the environment is already up: + ```bash go run . env beholder start ``` +Chip Router ports: +- admin: `50050` +- ingress gRPC: `50051` + +Real ChIP / Beholder downstream port: +- gRPC: `50053` + ### OTel Tracing Configuration To enable OpenTelemetry (OTel) tracing for workflow engines and see traces in Tempo/Grafana, **multiple configuration toggles must be set**: diff --git a/core/scripts/cre/environment/configs/setup.toml b/core/scripts/cre/environment/configs/setup.toml index 313c6e82996..e17f7b668ff 100644 --- a/core/scripts/cre/environment/configs/setup.toml +++ b/core/scripts/cre/environment/configs/setup.toml @@ -14,6 +14,18 @@ local_image = "job-distributor:0.22.1" local_image = "job-distributor:0.22.1" ecr_image = "{{.ECR}}/job-distributor:0.22.1" +[chip_router.build_config] +repository = "https://github.com/smartcontractkit/chainlink-testing-framework" +branch = "main" +commit = "e824a2225aac21f09b2ccf21379744c65f4c8d7e" +dockerfile = "framework/components/chiprouter/Dockerfile" +docker_ctx = "framework/components/chiprouter" +local_image = "chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" + +[chip_router.pull_config] +local_image = "chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" +ecr_image = "{{.ECR}}/chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" + [chip_ingress.build_config] repository = "https://github.com/smartcontractkit/atlas" branch = "master" diff --git a/core/scripts/cre/environment/configs/workflow-don-solana.toml b/core/scripts/cre/environment/configs/workflow-don-solana.toml index b8198cad1bc..c1e3d009039 100644 --- a/core/scripts/cre/environment/configs/workflow-don-solana.toml +++ b/core/scripts/cre/environment/configs/workflow-don-solana.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router-local:latest" + image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-don-tron.toml b/core/scripts/cre/environment/configs/workflow-don-tron.toml index 4e9d6c1e685..2d094af1342 100755 --- a/core/scripts/cre/environment/configs/workflow-don-tron.toml +++ b/core/scripts/cre/environment/configs/workflow-don-tron.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router-local:latest" + image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml index 5e1d5b94027..dda4e0e8b3b 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router-local:latest" + image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml b/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml index cb1571c1a8f..14701c9ad47 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml @@ -5,7 +5,7 @@ # Used by: system-tests/tests/smoke/cre/v2_grpc_source_test.go [chip_router] - image = "chip-router-local:latest" + image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-don.toml index 24108575bf0..ec1de043059 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-don.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router-local:latest" + image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml index 78ac2208597..18ac37959db 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml @@ -1,7 +1,7 @@ # NOTE: Identical to workflow-gatewway-capabilities.toml but with a vault capability config override # to disable the new pending queue feature. [chip_router] - image = "chip-router-local:latest" + image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml index 39193bdc2cf..017c25411b6 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml @@ -1,5 +1,5 @@ [chip_router] - image = "chip-router-local:latest" + image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" [[blockchains]] chain_id = "1337" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml b/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml index 8c718115ded..f2803c3d286 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router-local:latest" + image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml index 778ed806cc0..e7fa61dcdd4 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router-local:latest" + image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/environment/beholder.go b/core/scripts/cre/environment/environment/beholder.go index 15bc47f8ffe..1ff044c6663 100644 --- a/core/scripts/cre/environment/environment/beholder.go +++ b/core/scripts/cre/environment/environment/beholder.go @@ -395,12 +395,20 @@ var protoRegistrationErrMsg = "proto registration failed" // MissingImage represents an image that needs to be built or pulled type MissingImage struct { Name string - Tag string FullImage string BuildConfig BuildConfig PullConfig PullConfig } +func newMissingImage(name string, cfg ImageConfig) MissingImage { + return MissingImage{ + Name: name, + FullImage: cfg.BuildConfig.LocalImage, + BuildConfig: cfg.BuildConfig, + PullConfig: cfg.PullConfig, + } +} + // ensureChipImagesExist checks if required chip images exist and auto-builds them if missing. // In CI environments (CI=true), this check is skipped as images will be pulled at runtime. func ensureChipImagesExist(ctx context.Context, cfg *SetupConfigFile) error { @@ -410,42 +418,35 @@ func ensureChipImagesExist(ctx context.Context, cfg *SetupConfigFile) error { return nil } + var requiredImages []MissingImage + if cfg.ChipIngress != nil { + requiredImages = append(requiredImages, newMissingImage("chip-ingress", ImageConfig{ + BuildConfig: cfg.ChipIngress.BuildConfig, + PullConfig: cfg.ChipIngress.PullConfig, + })) + } + if cfg.ChipConfig != nil { + requiredImages = append(requiredImages, newMissingImage("chip-config", ImageConfig{ + BuildConfig: cfg.ChipConfig.BuildConfig, + PullConfig: cfg.ChipConfig.PullConfig, + })) + } + + return ensureManagedImagesExist(ctx, cfg.General.AWSProfile, requiredImages) +} + +func ensureManagedImagesExist(ctx context.Context, awsProfile string, requiredImages []MissingImage) error { dockerClient, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation()) if err != nil { return errors.Wrap(err, "failed to create Docker client") } defer dockerClient.Close() - // Check if Docker is running _, err = dockerClient.Ping(ctx) if err != nil { return errors.Wrap(err, "Docker is not running") } - // Collect required images - var requiredImages []MissingImage - - if cfg.ChipIngress != nil { - requiredImages = append(requiredImages, MissingImage{ - Name: "chip-ingress", - Tag: cfg.ChipIngress.BuildConfig.Commit, - FullImage: cfg.ChipIngress.BuildConfig.LocalImage, - BuildConfig: cfg.ChipIngress.BuildConfig, - PullConfig: cfg.ChipIngress.PullConfig, - }) - } - - if cfg.ChipConfig != nil { - requiredImages = append(requiredImages, MissingImage{ - Name: "chip-config", - Tag: cfg.ChipConfig.BuildConfig.Commit, - FullImage: cfg.ChipConfig.BuildConfig.LocalImage, - BuildConfig: cfg.ChipConfig.BuildConfig, - PullConfig: cfg.ChipConfig.PullConfig, - }) - } - - // Find missing images var missing []MissingImage for _, img := range requiredImages { _, err := dockerClient.ImageInspect(ctx, img.FullImage) @@ -469,7 +470,7 @@ func ensureChipImagesExist(ctx context.Context, cfg *SetupConfigFile) error { if ecrURL != "" { // Non-interactive with AWS_ECR - pull images framework.L.Info().Msgf("Non-interactive mode with AWS_ECR set. Pulling %d missing image(s) from ECR...", len(missing)) - return pullAllImages(ctx, cfg, missing) + return pullAllImages(ctx, awsProfile, missing) } // Non-interactive without AWS_ECR - fail with instructions framework.L.Error().Msgf("Missing %d required image(s) and AWS_ECR is not set:", len(missing)) @@ -505,14 +506,14 @@ func ensureChipImagesExist(ctx context.Context, cfg *SetupConfigFile) error { } // Some builds failed - offer to pull all failed images - return handleChipImageBuildFailures(ctx, cfg, failedBuilds, buildErrors) + return handleChipImageBuildFailures(ctx, awsProfile, failedBuilds, buildErrors) } // pullAllImages pulls all specified images from ECR -func pullAllImages(ctx context.Context, cfg *SetupConfigFile, images []MissingImage) error { +func pullAllImages(ctx context.Context, awsProfile string, images []MissingImage) error { for _, img := range images { framework.L.Info().Msgf("Pulling %s from ECR...", img.Name) - _, pullErr := img.PullConfig.Pull(ctx, cfg.General.AWSProfile) + _, pullErr := img.PullConfig.Pull(ctx, awsProfile) if pullErr != nil { return errors.Wrapf(pullErr, "failed to pull %s", img.Name) } @@ -532,7 +533,7 @@ func isInteractiveTerminal() bool { } // handleChipImageBuildFailures handles build failures by offering to pull all failed images -func handleChipImageBuildFailures(ctx context.Context, cfg *SetupConfigFile, failedImages []MissingImage, buildErrors []error) error { +func handleChipImageBuildFailures(ctx context.Context, awsProfile string, failedImages []MissingImage, buildErrors []error) error { // List all failed images fmt.Println() framework.L.Error().Msgf("Failed to build %d image(s):", len(failedImages)) @@ -564,7 +565,7 @@ func handleChipImageBuildFailures(ctx context.Context, cfg *SetupConfigFile, fai // Pull all failed images for _, img := range failedImages { framework.L.Info().Msgf("Pulling %s from ECR...", img.Name) - _, pullErr := img.PullConfig.Pull(ctx, cfg.General.AWSProfile) + _, pullErr := img.PullConfig.Pull(ctx, awsProfile) if pullErr != nil { return errors.Wrapf(pullErr, "failed to pull %s", img.Name) } diff --git a/core/scripts/cre/environment/environment/environment.go b/core/scripts/cre/environment/environment/environment.go index 9a3350166fe..39811789829 100644 --- a/core/scripts/cre/environment/environment/environment.go +++ b/core/scripts/cre/environment/environment/environment.go @@ -58,6 +58,7 @@ const ( manualCtfCleanupMsg = `unexpected startup error. this may have stranded resources. please manually remove containers with 'ctf' label and delete their volumes` manualBeholderCleanupMsg = `unexpected startup error. this may have stranded resources. please manually remove the 'chip-ingress' stack` manualBillingCleanupMsg = `unexpected startup error. this may have stranded resources. please manually remove the 'billing-platform-service' stack` + CTFChipRouterImageEnvVar = "CTF_CHIP_ROUTER_IMAGE" ) var ( @@ -279,6 +280,7 @@ func startCmd() *cobra.Command { if err := in.Load(os.Getenv("CTF_CONFIGS")); err != nil { return errors.Wrap(err, "failed to load environment configuration") } + applyChipRouterImageOverride(in) // Skip Docker operations for Kubernetes provider (Docker not needed) isDocker := in.Infra != nil && !in.Infra.IsKubernetes() @@ -290,6 +292,10 @@ func startCmd() *cobra.Command { return err } + if err := ensureChipRouterImageExists(cmdContext, in, setupConfig.ConfigPath); err != nil { + return err + } + // This will not work with remote images that require authentication, but it will catch early most of the issues with missing env setup if err := ensureDockerImagesExist(cmdContext, framework.L, in); err != nil { return err @@ -783,6 +789,61 @@ func stopConfiguredChipRouter() error { return chiprouter.Stop(relativePathToRepoRoot) } +func applyChipRouterImageOverride(in *envconfig.Config) { + if in == nil || in.ChipRouter == nil { + return + } + + override := strings.TrimSpace(os.Getenv(CTFChipRouterImageEnvVar)) + if override == "" { + return + } + + in.ChipRouter.Image = override + framework.L.Info().Msgf("Using Chip Router image override from %s: %s", CTFChipRouterImageEnvVar, override) +} + +func effectiveChipRouterImage(configImage string) (string, error) { + if override := strings.TrimSpace(os.Getenv(CTFChipRouterImageEnvVar)); override != "" { + return override, nil + } + if strings.TrimSpace(configImage) != "" { + return configImage, nil + } + return "", errors.New("no chip router image found") +} + +func ensureChipRouterImageExists(ctx context.Context, in *envconfig.Config, setupConfigPath string) error { + if in == nil || in.ChipRouter == nil || (in.Infra != nil && in.Infra.IsKubernetes()) { + return nil + } + + effectiveImage, err := effectiveChipRouterImage(in.ChipRouter.Image) + if err != nil { + return errors.Wrap(err, "failed to get effective chip router image") + } + in.ChipRouter.Image = effectiveImage + + setupCfg, err := ReadSetupConfig(setupConfigPath) + if err != nil { + return errors.Wrap(err, "failed to read setup config for chip router image validation") + } + if setupCfg.ChipRouter == nil { + return errors.New("chip_router configuration is missing from setup config") + } + + routerImage := newMissingImage("chip-router", ImageConfig{ + BuildConfig: setupCfg.ChipRouter.BuildConfig, + PullConfig: setupCfg.ChipRouter.PullConfig, + }.WithLocalImage(effectiveImage)) + + if err := ensureManagedImagesExist(ctx, setupCfg.General.AWSProfile, []MissingImage{routerImage}); err != nil { + return errors.Wrapf(err, "Chip Router image '%s' is not available", effectiveImage) + } + + return nil +} + func hasBuiltDockerImage(in *envconfig.Config) bool { for _, nodeset := range in.NodeSets { for _, nodeSpec := range nodeset.NodeSpecs { diff --git a/core/scripts/cre/environment/environment/setup.go b/core/scripts/cre/environment/environment/setup.go index 4e15f3d5d04..c87112d147e 100644 --- a/core/scripts/cre/environment/environment/setup.go +++ b/core/scripts/cre/environment/environment/setup.go @@ -60,6 +60,7 @@ func init() { type SetupConfigFile struct { General GeneralConfig `toml:"general"` JobDistributor JobDistributorConfig `toml:"job_distributor"` + ChipRouter *ChipRouterConfig `toml:"chip_router"` ChipIngress *ChipIngressConfig `toml:"chip_ingress"` ChipConfig *ChipConfigConfig `toml:"chip_config"` BillingService *BillingServiceConfig `toml:"billing_platform_service"` @@ -78,6 +79,12 @@ type JobDistributorConfig struct { PullConfig PullConfig `toml:"pull_config"` } +// ChipRouterConfig contains chip router image configuration +type ChipRouterConfig struct { + BuildConfig BuildConfig `toml:"build_config"` + PullConfig PullConfig `toml:"pull_config"` +} + // ChipIngressConfig contains chip ingress image configuration type ChipIngressConfig struct { BuildConfig BuildConfig `toml:"build_config"` @@ -225,6 +232,10 @@ func (c BuildConfig) Build(ctx context.Context) (localImage string, err error) { tag = c.Branch commit = c.Commit ) + if strings.TrimSpace(c.LocalRepo) != "" { + repo = c.LocalRepo + } + logger := framework.L name := strings.ReplaceAll(strings.Split(c.LocalImage, ":")[0], "-", " ") name = cases.Title(language.English).String(name) @@ -319,6 +330,13 @@ type ImageConfig struct { PullConfig PullConfig } +func (c ImageConfig) WithLocalImage(localImage string) ImageConfig { + out := c + out.BuildConfig.LocalImage = localImage + out.PullConfig.LocalImage = localImage + return out +} + func (c ImageConfig) Ensure(ctx context.Context, dockerClient *client.Client, awsProfile string, noPrompt bool, defaultOption EnsureOption, purge bool) (localImage string, err error) { // If purge flag is set, remove existing images first if purge { @@ -487,6 +505,23 @@ func RunSetup(ctx context.Context, config SetupConfig, noPrompt, purge, withBill return } + var chipRouterLocalImage string + if cfg.ChipRouter != nil { + chipRouterConfig := ImageConfig{ + BuildConfig: cfg.ChipRouter.BuildConfig, + PullConfig: cfg.ChipRouter.PullConfig, + } + + var err error + chipRouterLocalImage, err = chipRouterConfig.Ensure(ctx, dockerClient, cfg.General.AWSProfile, noPrompt, PullOption, purge) + if err != nil { + setupErr = errors.Wrap(err, "failed to ensure Chip Router image") + return + } + } else { + logger.Warn().Str("config file", config.ConfigPath).Msg("Skipping Chip Router setup, because configuration is not provided in the config file") + } + var chipIngressLocalImage string if cfg.ChipIngress != nil { chipConfig := ImageConfig{ @@ -560,6 +595,9 @@ func RunSetup(ctx context.Context, config SetupConfig, noPrompt, purge, withBill logger.Info().Msg("✅ Setup Summary:") logger.Info().Msg(" ✓ Docker is installed and configured correctly") logger.Info().Msgf(" ✓ Job Distributor image %s is available", jdLocalImage) + if chipRouterLocalImage != "" { + logger.Info().Msgf(" ✓ Chip Router image %s is available", chipRouterLocalImage) + } if chipIngressLocalImage != "" { logger.Info().Msgf(" ✓ Atlas Chip Ingress image %s is available", chipIngressLocalImage) } diff --git a/system-tests/lib/cre/environment/environment.go b/system-tests/lib/cre/environment/environment.go index b02198e6710..eda1eef6c53 100644 --- a/system-tests/lib/cre/environment/environment.go +++ b/system-tests/lib/cre/environment/environment.go @@ -6,6 +6,7 @@ import ( "fmt" "maps" "os" + "strings" "github.com/Masterminds/semver/v3" "github.com/ethereum/go-ethereum/common" @@ -53,6 +54,8 @@ type SetupOutput struct { GatewayConnectors *cre.GatewayConnectors } +const ctfChipRouterImageEnvVar = "CTF_CHIP_ROUTER_IMAGE" + type SetupInput struct { NodeSets []*cre.NodeSet BlockchainsInput []*blockchain.Input @@ -129,6 +132,9 @@ func SetupTestEnvironment( } if input.ChipRouterInput != nil { + if override := strings.TrimSpace(os.Getenv(ctfChipRouterImageEnvVar)); override != "" { + input.ChipRouterInput.Image = override + } fmt.Print(libformat.PurpleText("%s", input.StageGen.Wrap("Starting Chip Router"))) _, err := ctfchiprouter.NewWithContext(ctx, input.ChipRouterInput) if err != nil { From 1308c6f80f9ad8513ffc564f3a68cc9dd6e35b67 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 1 Apr 2026 15:57:17 +0200 Subject: [PATCH 03/10] add handling for a different ECR for Chip Router --- core/scripts/cre/environment/README.md | 13 ++--- .../cre/environment/configs/setup.toml | 10 ++-- .../cre/environment/environment/beholder.go | 52 +++++++++++++------ .../cre/environment/environment/setup.go | 43 +++++++++++---- 4 files changed, 80 insertions(+), 38 deletions(-) diff --git a/core/scripts/cre/environment/README.md b/core/scripts/cre/environment/README.md index 98f0812e63d..daba524e1df 100644 --- a/core/scripts/cre/environment/README.md +++ b/core/scripts/cre/environment/README.md @@ -147,8 +147,8 @@ It will compile local CRE as `local_cre`. With it installed you will be able to # QUICKSTART ``` -# e.g. AWS_ECR=.dkr.ecr..amazonaws.com -AWS_ECR= go run . env start --auto-setup +# e.g. MAIN_AWS_ECR= SDLC_AWS_ECR= +MAIN_AWS_ECR= SDLC_AWS_ECR= go run . env start --auto-setup ``` > You can find `PROD_ACCOUNT_ID` and `REGION` in the `[profile prod]` section of the [AWS CLI configuration guide](https://smartcontract-it.atlassian.net/wiki/spaces/INFRA/pages/1045495923/Configure+the+AWS+CLI#Configure). If for some reason you want to limit the AWS config to bare minimum, include only `staging-default` profile and `cl-secure-sso` session entries. @@ -165,7 +165,7 @@ Environment can be setup by running `go run . env setup` inside `core/scripts/cr **Image Versioning:** -Managed CRE images use local aliases with commit-based tags instead of mutable tags like `latest` or account-qualified ECR names. For example, env TOMLs use `chip-router:`, while [configs/setup.toml](configs/setup.toml) defines how that alias is built locally or pulled from ECR and retagged locally. +Managed CRE images use local aliases with commit-based tags instead of mutable tags like `latest` or account-qualified ECR names. For example, env TOMLs use `chip-router:`, while [configs/setup.toml](configs/setup.toml) defines how that alias is built locally or pulled from ECR and retagged locally. The setup config now distinguishes between the main CRE registry (`MAIN_AWS_ECR`) and the separate Chip Router registry (`SDLC_AWS_ECR`). `env start` treats Chip Router as required infrastructure. It resolves the effective router image in this order: - `CTF_CHIP_ROUTER_IMAGE`, if set @@ -255,8 +255,8 @@ Beholder requires `chip-ingress` and `chip-config` Docker images with specific v When starting Beholder, the system will: - **In CI (`CI=true`)**: Skip image checks (docker-compose will pull at runtime) -- **Interactive terminal**: Auto-build missing images from sources. If build fails and `AWS_ECR` is set, you'll be offered to pull from ECR instead -- **Non-interactive (tests, scripts)**: Auto-pull from ECR if `AWS_ECR` is set, otherwise fail with instructions +- **Interactive terminal**: Auto-build missing images from sources. If build fails and the required registry env vars are set, you'll be offered to pull from ECR instead +- **Non-interactive (tests, scripts)**: Auto-pull from ECR if the required registry env vars are set, otherwise fail with instructions To manually ensure images are available, run: ```bash @@ -264,7 +264,7 @@ To manually ensure images are available, run: go run . env setup # Or pull from ECR (requires AWS SSO access) -AWS_ECR=.dkr.ecr.us-west-2.amazonaws.com go run . env setup +MAIN_AWS_ECR= SDLC_AWS_ECR= go run . env setup ``` #### Chip Router Topology @@ -295,6 +295,7 @@ export CTF_CHIP_ROUTER_IMAGE=chip-router: ``` This override wins over `chip_router.image` in the env TOML. +Chip Router pulls use `SDLC_AWS_ECR`; the rest of the managed CRE images use `MAIN_AWS_ECR`. ### Storage diff --git a/core/scripts/cre/environment/configs/setup.toml b/core/scripts/cre/environment/configs/setup.toml index e17f7b668ff..d649bc64d6f 100644 --- a/core/scripts/cre/environment/configs/setup.toml +++ b/core/scripts/cre/environment/configs/setup.toml @@ -12,7 +12,7 @@ local_image = "job-distributor:0.22.1" [job_distributor.pull_config] local_image = "job-distributor:0.22.1" -ecr_image = "{{.ECR}}/job-distributor:0.22.1" +ecr_image = "{{.MAIN_ECR}}/job-distributor:0.22.1" [chip_router.build_config] repository = "https://github.com/smartcontractkit/chainlink-testing-framework" @@ -24,7 +24,7 @@ local_image = "chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" [chip_router.pull_config] local_image = "chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" -ecr_image = "{{.ECR}}/chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" +ecr_image = "{{.SDLC_ECR}}/chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" [chip_ingress.build_config] repository = "https://github.com/smartcontractkit/atlas" @@ -37,7 +37,7 @@ pre_run = "pushd chip-ingress && go mod vendor && popd" [chip_ingress.pull_config] local_image = "chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f" -ecr_image = "{{.ECR}}/atlas-chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f" +ecr_image = "{{.MAIN_ECR}}/atlas-chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f" [chip_config.build_config] repository = "https://github.com/smartcontractkit/atlas" @@ -50,7 +50,7 @@ pre_run = "pushd chip-config && go mod vendor && popd" [chip_config.pull_config] local_image = "chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969" -ecr_image = "{{.ECR}}/atlas-chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969" +ecr_image = "{{.MAIN_ECR}}/atlas-chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969" [billing_platform_service.build_config] repository = "https://github.com/smartcontractkit/billing-platform-service" @@ -62,7 +62,7 @@ local_image = "billing-platform-service:local-cre" [billing_platform_service.pull_config] local_image = "billing-platform-service:local-cre" -ecr_image = "{{.ECR}}/billing-platform-service:1.36.1" +ecr_image = "{{.MAIN_ECR}}/billing-platform-service:1.36.1" [observability] repository = "https://github.com/smartcontractkit/chainlink-observability" diff --git a/core/scripts/cre/environment/environment/beholder.go b/core/scripts/cre/environment/environment/beholder.go index 1ff044c6663..00af329d9a5 100644 --- a/core/scripts/cre/environment/environment/beholder.go +++ b/core/scripts/cre/environment/environment/beholder.go @@ -462,23 +462,21 @@ func ensureManagedImagesExist(ctx context.Context, awsProfile string, requiredIm return nil } - ecrURL := os.Getenv("AWS_ECR") + missingRegistryVars := missingRegistryEnvVars(missing) interactive := isInteractiveTerminal() // Non-interactive mode handling if !interactive { - if ecrURL != "" { - // Non-interactive with AWS_ECR - pull images - framework.L.Info().Msgf("Non-interactive mode with AWS_ECR set. Pulling %d missing image(s) from ECR...", len(missing)) + if len(missingRegistryVars) == 0 { + framework.L.Info().Msgf("Non-interactive mode with required ECR env vars set. Pulling %d missing image(s) from ECR...", len(missing)) return pullAllImages(ctx, awsProfile, missing) } - // Non-interactive without AWS_ECR - fail with instructions - framework.L.Error().Msgf("Missing %d required image(s) and AWS_ECR is not set:", len(missing)) + framework.L.Error().Msgf("Missing %d required image(s) and required ECR env vars are not set:", len(missing)) for _, img := range missing { framework.L.Error().Msgf(" - %s", img.FullImage) } - printChipImagePullInstructions() - return errors.Errorf("missing %d required image(s). Set AWS_ECR to enable auto-pull or run 'go run . env setup' manually", len(missing)) + printChipImagePullInstructions(missingRegistryVars) + return errors.Errorf("missing %d required image(s). Set %s to enable auto-pull or run 'go run . env setup' manually", len(missing), strings.Join(missingRegistryVars, ", ")) } // Interactive mode - try building first @@ -541,14 +539,14 @@ func handleChipImageBuildFailures(ctx context.Context, awsProfile string, failed framework.L.Error().Msgf(" - %s: %v", img.FullImage, buildErrors[i]) } - ecrURL := os.Getenv("AWS_ECR") - if ecrURL != "" { + missingRegistryVars := missingRegistryEnvVars(failedImages) + if len(missingRegistryVars) == 0 { shouldPull := false if isInteractiveTerminal() { // Interactive mode - ask user fmt.Println() - fmt.Printf("AWS_ECR is set. Would you like to pull all %d failed image(s) from ECR instead? [Y/n] ", len(failedImages)) + fmt.Printf("Required ECR env vars are set. Would you like to pull all %d failed image(s) from ECR instead? [Y/n] ", len(failedImages)) reader := bufio.NewReader(os.Stdin) input, _ := reader.ReadString('\n') @@ -576,19 +574,41 @@ func handleChipImageBuildFailures(ctx context.Context, awsProfile string, failed } // Show manual instructions - printChipImagePullInstructions() + printChipImagePullInstructions(missingRegistryVars) return errors.Errorf("failed to build %d image(s)", len(failedImages)) } -// printChipImagePullInstructions prints helpful instructions for pulling images manually -func printChipImagePullInstructions() { +func missingRegistryEnvVars(images []MissingImage) []string { + seen := make(map[string]struct{}) + var missing []string + for _, img := range images { + for _, envVar := range img.PullConfig.MissingRegistryEnvVars() { + if _, ok := seen[envVar]; ok { + continue + } + seen[envVar] = struct{}{} + missing = append(missing, envVar) + } + } + return missing +} + +// printChipImagePullInstructions prints helpful instructions for pulling images manually. +func printChipImagePullInstructions(requiredEnvVars []string) { fmt.Println() fmt.Println("────────────────────────────────────────────────────────────────") fmt.Println("To pull pre-built images instead, run:") fmt.Println() - fmt.Println(" AWS_ECR=.dkr.ecr.us-west-2.amazonaws.com go run . env setup") + if len(requiredEnvVars) == 0 { + requiredEnvVars = []string{mainECREnvVarName, sdlcECREnvVarName} + } + assignments := make([]string, 0, len(requiredEnvVars)) + for _, envVar := range requiredEnvVars { + assignments = append(assignments, fmt.Sprintf("%s=", envVar)) + } + fmt.Printf(" %s go run . env setup\n", strings.Join(assignments, " ")) fmt.Println() - fmt.Println("Replace with prod AWS account number.") + fmt.Printf("Set the required registry env vars: %s.\n", strings.Join(requiredEnvVars, ", ")) fmt.Println("See: https://smartcontract-it.atlassian.net/wiki/spaces/INFRA/pages/1045495923") fmt.Println("────────────────────────────────────────────────────────────────") fmt.Println() diff --git a/core/scripts/cre/environment/environment/setup.go b/core/scripts/cre/environment/environment/setup.go index c87112d147e..cb1cfb74e62 100644 --- a/core/scripts/cre/environment/environment/setup.go +++ b/core/scripts/cre/environment/environment/setup.go @@ -110,11 +110,20 @@ type ObservabilityConfig struct { TargetPath string `toml:"target_path"` } -var ( - ECR = os.Getenv("AWS_ECR") // TODO this can be moved to an env file +const DefaultSetupConfigPath = "configs/setup.toml" + +const ( + mainECREnvVarName = "MAIN_AWS_ECR" + sdlcECREnvVarName = "SDLC_AWS_ECR" ) -const DefaultSetupConfigPath = "configs/setup.toml" +func mainECR() string { + return os.Getenv(mainECREnvVarName) +} + +func sdlcECR() string { + return os.Getenv(sdlcECREnvVarName) +} type EnsureOption = string @@ -302,9 +311,20 @@ type PullConfig struct { EcrImage string `toml:"ecr_image"` } +func (c PullConfig) MissingRegistryEnvVars() []string { + var missing []string + if strings.Contains(c.EcrImage, "{{.MAIN_ECR}}") && mainECR() == "" { + missing = append(missing, mainECREnvVarName) + } + if strings.Contains(c.EcrImage, "{{.SDLC_ECR}}") && sdlcECR() == "" { + missing = append(missing, sdlcECREnvVarName) + } + return missing +} + func (c PullConfig) Pull(ctx context.Context, awsProfile string) (localImage string, err error) { - if ECR == "" { - return "", errors.New("AWS_ECR environment variable is not set. See README for more details and references to find the correct ECR URL or visit https://smartcontract-it.atlassian.net/wiki/spaces/INFRA/pages/1045495923/Configure+the+AWS+CLI") + if missing := c.MissingRegistryEnvVars(); len(missing) > 0 { + return "", fmt.Errorf("%s environment variable(s) must be set. See README for setup details and https://smartcontract-it.atlassian.net/wiki/spaces/INFRA/pages/1045495923/Configure+the+AWS+CLI", strings.Join(missing, ", ")) } tmpl, tmplErr := template.New("ecr-image").Parse(c.EcrImage) @@ -313,7 +333,8 @@ func (c PullConfig) Pull(ctx context.Context, awsProfile string) (localImage str } templateData := map[string]string{ - "ECR": ECR, + "MAIN_ECR": mainECR(), + "SDLC_ECR": sdlcECR(), } var configBuffer bytes.Buffer @@ -351,7 +372,7 @@ func (c ImageConfig) Ensure(ctx context.Context, dockerClient *client.Client, aw logger.Warn().Msgf("Failed to remove local image %s: %v", c.BuildConfig.LocalImage, err) } - // Remove ECR image if it exists + // Remove remote-tagged image if it exists _, err = dockerClient.ImageRemove(ctx, c.PullConfig.EcrImage, image.RemoveOptions{Force: true}) if err != nil { logger.Warn().Msgf("Failed to remove ECR image %s: %v", c.PullConfig.EcrImage, err) @@ -782,8 +803,8 @@ func checkDockerConfiguration() error { return nil } -// localImageExists checks if the local image or ECR image exists -// if ECR image exists, it tags it as the local image +// localImageExists checks if the local image or rendered remote image exists +// if the rendered remote image exists, it tags it as the local image func localImageExists(ctx context.Context, dockerClient *client.Client, localImage, ecrImage string) (bool, error) { logger := framework.L name := strings.ReplaceAll(strings.Split(localImage, ":")[0], "-", " ") @@ -795,7 +816,7 @@ func localImageExists(ctx context.Context, dockerClient *client.Client, localIma return true, nil } - // Check if ECR image exists + // Check if rendered remote image exists _, err = dockerClient.ImageInspect(ctx, ecrImage) if err == nil { logger.Info().Msgf("✓ %s image (%s) is available", name, ecrImage) @@ -809,7 +830,7 @@ func localImageExists(ctx context.Context, dockerClient *client.Client, localIma return false, nil } -// pullImage pulls the Job Distributor image from ECR +// pullImage pulls the configured image from its remote registry and retags it locally. func pullImage(ctx context.Context, awsProfile string, localImage, ecrImage string) (string, error) { logger := framework.L name := strings.ReplaceAll(strings.Split(localImage, ":")[0], "-", " ") From 5b73fd67b07fd4d965b7a1e7fee32c18ac619fc7 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 1 Apr 2026 16:27:49 +0200 Subject: [PATCH 04/10] update GH workflows --- .github/workflows/cre-local-env-tests.yaml | 4 +++- .github/workflows/cre-regression-system-tests.yaml | 1 + .github/workflows/cre-soak-memory-leak.yml | 1 + .github/workflows/cre-system-tests.yaml | 1 + core/scripts/cre/environment/environment/beholder.go | 11 +++++------ 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/cre-local-env-tests.yaml b/.github/workflows/cre-local-env-tests.yaml index eff4e33f8ae..d10347d691e 100644 --- a/.github/workflows/cre-local-env-tests.yaml +++ b/.github/workflows/cre-local-env-tests.yaml @@ -151,7 +151,8 @@ jobs: env: DISABLE_DX_TRACKING: true GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - AWS_ECR: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.us-west-2.amazonaws.com + MAIN_AWS_ECR: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.us-west-2.amazonaws.com + SDLC_AWS_ECR: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.us-west-2.amazonaws.com run: | # Remove chip_ingress/chip_config sections since CI role lacks ECR permissions for the Atlas repo awk '/^\[chip_ingress\.build_config\]/,/^$/{next} /^\[chip_ingress\.pull_config\]/,/^$/{next} /^\[chip_config\.build_config\]/,/^$/{next} /^\[chip_config\.pull_config\]/,/^$/{next} {print}' configs/setup.toml > configs/setup.toml.tmp && mv configs/setup.toml.tmp configs/setup.toml @@ -165,6 +166,7 @@ jobs: CTF_CONFIGS: "./configs/workflow-gateway-don.toml" CTF_JD_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/job-distributor:0.22.1" CTF_CHAINLINK_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ github.event_name == 'pull_request' && format('nightly-{0}-plugins', steps.set-date.outputs.date) || inputs.chainlink_image_tag }}" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" DISABLE_DX_TRACKING: "true" CI: "true" run: | diff --git a/.github/workflows/cre-regression-system-tests.yaml b/.github/workflows/cre-regression-system-tests.yaml index 92c205baaaa..aefebd39047 100644 --- a/.github/workflows/cre-regression-system-tests.yaml +++ b/.github/workflows/cre-regression-system-tests.yaml @@ -106,6 +106,7 @@ jobs: # Beholder stack will be started only for the Beholder tests CHIP_INGRESS_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f CHIP_CONFIG_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969 + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" BILLING_PLATFORM_SERVICE_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/billing-platform-service:v1.45.0 steps: diff --git a/.github/workflows/cre-soak-memory-leak.yml b/.github/workflows/cre-soak-memory-leak.yml index 7a9eabb9aa1..35c53966a23 100644 --- a/.github/workflows/cre-soak-memory-leak.yml +++ b/.github/workflows/cre-soak-memory-leak.yml @@ -118,6 +118,7 @@ jobs: working-directory: system-tests/tests env: GITHUB_TOKEN: ${{ steps.github-token.outputs.access-token || '' }} + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" run: | gotestsum \ --jsonfile=/tmp/gotest.log \ diff --git a/.github/workflows/cre-system-tests.yaml b/.github/workflows/cre-system-tests.yaml index a61f399e962..5ce4fbfce08 100644 --- a/.github/workflows/cre-system-tests.yaml +++ b/.github/workflows/cre-system-tests.yaml @@ -219,6 +219,7 @@ jobs: env: CTF_JD_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/job-distributor:0.22.1" CTF_CHAINLINK_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/${{ inputs.ecr_name }}:${{ inputs.chainlink_image_tag != '' && inputs.chainlink_image_tag || inputs.chainlink_version }}" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" CTF_CONFIGS: ${{ matrix.tests.configs }} CRE_VERSION: ${{ matrix.tests.cre_version }} TEST_NAME: ${{ matrix.tests.test_name }} diff --git a/core/scripts/cre/environment/environment/beholder.go b/core/scripts/cre/environment/environment/beholder.go index 00af329d9a5..e7193fcbe8f 100644 --- a/core/scripts/cre/environment/environment/beholder.go +++ b/core/scripts/cre/environment/environment/beholder.go @@ -289,8 +289,8 @@ func startBeholderCmd() *cobra.Command { return fmt.Errorf("failed to set TESTCONTAINERS_RYUK_DISABLED environment variable: %w", setErr) } - if routerErr := startChipRouterForBeholder(cmd.Context()); routerErr != nil { - return errors.Wrap(routerErr, "failed to start chip ingress router") + if routerErr := hydrateChipRouterForBeholder(cmd.Context()); routerErr != nil { + return errors.Wrap(routerErr, "failed to hydrate chip ingress router. Please make sure that local CRE environment is started and that the chip ingress router is running") } startBeholderErr = startBeholder(cmd.Context(), timeout, port) @@ -325,7 +325,7 @@ func mustStringToInt(in string) int { return out } -func startChipRouterForBeholder(ctx context.Context) error { +func hydrateChipRouterForBeholder(ctx context.Context) error { return chiprouter.EnsureStarted(ctx, relativePathToRepoRoot, "") } @@ -651,9 +651,8 @@ func startBeholder(cmdContext context.Context, cleanupWait time.Duration, port i fmt.Print(libformat.PurpleText("%s", stageGen.Wrap("Starting Chip Ingress stack"))) if !isPortAvailable(":" + strconv.Itoa(port)) { - return fmt.Errorf(`port %d is already in use. Most probably an instance of ChIP Test Sink is already running. -If you want to use both together start ChIP Ingress on a different port with '--grpc-port' flag -and make sure that the sink is pointing to correct upstream endpoint ('localhost:' in most cases)`, port) + return fmt.Errorf(`port %d is already in use. Either an instance of CHiP Router or ChIP Test Sink is already running. +If you want to use both together start ChIP Ingress on a different port with '--grpc-port' flag`, port) } // Load setup config to check for required images From aeea8565c075476e1519da895215e7cc1e46de51 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 1 Apr 2026 16:57:20 +0200 Subject: [PATCH 05/10] remove local replaces, update workflows, fix lints --- .github/workflows/cre-local-env-tests.yaml | 2 +- .../cre-regression-system-tests.yaml | 2 +- .github/workflows/cre-soak-memory-leak.yml | 2 +- .github/workflows/cre-system-tests.yaml | 2 +- .../cre/environment/configs/setup.toml | 8 ++--- .../cre/environment/environment/beholder.go | 2 +- .../environment/environment/environment.go | 15 ---------- core/scripts/go.mod | 10 ++----- core/scripts/go.sum | 6 ++++ system-tests/lib/cre/chiprouter/router.go | 30 ++++--------------- system-tests/lib/go.mod | 12 ++------ system-tests/lib/go.sum | 6 ++++ system-tests/tests/go.mod | 12 ++------ system-tests/tests/go.sum | 6 ++++ .../tests/test-helpers/before_suite.go | 2 +- .../test-helpers/chip_testsink_helpers.go | 7 +++-- 16 files changed, 45 insertions(+), 79 deletions(-) diff --git a/.github/workflows/cre-local-env-tests.yaml b/.github/workflows/cre-local-env-tests.yaml index d10347d691e..9d08e9f7572 100644 --- a/.github/workflows/cre-local-env-tests.yaml +++ b/.github/workflows/cre-local-env-tests.yaml @@ -166,7 +166,7 @@ jobs: CTF_CONFIGS: "./configs/workflow-gateway-don.toml" CTF_JD_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/job-distributor:0.22.1" CTF_CHAINLINK_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ github.event_name == 'pull_request' && format('nightly-{0}-plugins', steps.set-date.outputs.date) || inputs.chainlink_image_tag }}" - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" DISABLE_DX_TRACKING: "true" CI: "true" run: | diff --git a/.github/workflows/cre-regression-system-tests.yaml b/.github/workflows/cre-regression-system-tests.yaml index aefebd39047..3f4e456ae30 100644 --- a/.github/workflows/cre-regression-system-tests.yaml +++ b/.github/workflows/cre-regression-system-tests.yaml @@ -106,7 +106,7 @@ jobs: # Beholder stack will be started only for the Beholder tests CHIP_INGRESS_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f CHIP_CONFIG_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969 - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" BILLING_PLATFORM_SERVICE_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/billing-platform-service:v1.45.0 steps: diff --git a/.github/workflows/cre-soak-memory-leak.yml b/.github/workflows/cre-soak-memory-leak.yml index 35c53966a23..480c6395cf0 100644 --- a/.github/workflows/cre-soak-memory-leak.yml +++ b/.github/workflows/cre-soak-memory-leak.yml @@ -118,7 +118,7 @@ jobs: working-directory: system-tests/tests env: GITHUB_TOKEN: ${{ steps.github-token.outputs.access-token || '' }} - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" run: | gotestsum \ --jsonfile=/tmp/gotest.log \ diff --git a/.github/workflows/cre-system-tests.yaml b/.github/workflows/cre-system-tests.yaml index 5ce4fbfce08..b2e3d1eb96a 100644 --- a/.github/workflows/cre-system-tests.yaml +++ b/.github/workflows/cre-system-tests.yaml @@ -219,7 +219,7 @@ jobs: env: CTF_JD_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/job-distributor:0.22.1" CTF_CHAINLINK_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/${{ inputs.ecr_name }}:${{ inputs.chainlink_image_tag != '' && inputs.chainlink_image_tag || inputs.chainlink_version }}" - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" CTF_CONFIGS: ${{ matrix.tests.configs }} CRE_VERSION: ${{ matrix.tests.cre_version }} TEST_NAME: ${{ matrix.tests.test_name }} diff --git a/core/scripts/cre/environment/configs/setup.toml b/core/scripts/cre/environment/configs/setup.toml index d649bc64d6f..715be09564e 100644 --- a/core/scripts/cre/environment/configs/setup.toml +++ b/core/scripts/cre/environment/configs/setup.toml @@ -17,14 +17,14 @@ ecr_image = "{{.MAIN_ECR}}/job-distributor:0.22.1" [chip_router.build_config] repository = "https://github.com/smartcontractkit/chainlink-testing-framework" branch = "main" -commit = "e824a2225aac21f09b2ccf21379744c65f4c8d7e" +commit = "2482d63e851d0f202e5514ed3328bbd49d7eb90c" dockerfile = "framework/components/chiprouter/Dockerfile" docker_ctx = "framework/components/chiprouter" -local_image = "chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" +local_image = "chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" [chip_router.pull_config] -local_image = "chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" -ecr_image = "{{.SDLC_ECR}}/chip-router:e824a2225aac21f09b2ccf21379744c65f4c8d7e" +local_image = "chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" +ecr_image = "{{.SDLC_ECR}}/chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" [chip_ingress.build_config] repository = "https://github.com/smartcontractkit/atlas" diff --git a/core/scripts/cre/environment/environment/beholder.go b/core/scripts/cre/environment/environment/beholder.go index e7193fcbe8f..dbbb4d0c918 100644 --- a/core/scripts/cre/environment/environment/beholder.go +++ b/core/scripts/cre/environment/environment/beholder.go @@ -604,7 +604,7 @@ func printChipImagePullInstructions(requiredEnvVars []string) { } assignments := make([]string, 0, len(requiredEnvVars)) for _, envVar := range requiredEnvVars { - assignments = append(assignments, fmt.Sprintf("%s=", envVar)) + assignments = append(assignments, envVar+"=") } fmt.Printf(" %s go run . env setup\n", strings.Join(assignments, " ")) fmt.Println() diff --git a/core/scripts/cre/environment/environment/environment.go b/core/scripts/cre/environment/environment/environment.go index 39811789829..f7b8cd966da 100644 --- a/core/scripts/cre/environment/environment/environment.go +++ b/core/scripts/cre/environment/environment/environment.go @@ -37,7 +37,6 @@ import ( cldlogger "github.com/smartcontractkit/chainlink/deployment/logger" libc "github.com/smartcontractkit/chainlink/system-tests/lib/conversions" "github.com/smartcontractkit/chainlink/system-tests/lib/cre" - "github.com/smartcontractkit/chainlink/system-tests/lib/cre/chiprouter" libcontracts "github.com/smartcontractkit/chainlink/system-tests/lib/cre/contracts" "github.com/smartcontractkit/chainlink/system-tests/lib/cre/don/gateway" creenv "github.com/smartcontractkit/chainlink/system-tests/lib/cre/environment" @@ -258,11 +257,6 @@ func startCmd() *cobra.Command { return fmt.Errorf("with-plugins-docker-image flag is no longer supported. Set Docker image in TOML config instead (%s) for each nodeset under the [nodesets.nodesets.node_specs.node.image] field", effectiveConfig) } - stopRouterErr := stopConfiguredChipRouter() - if stopRouterErr != nil { - framework.L.Warn().Msgf("failed to stop chip ingress router before startup cleanup: %s", stopRouterErr) - } - cleanUpErr := envconfig.RemoveAllEnvironmentStateDir(relativePathToRepoRoot) if cleanUpErr != nil { return errors.Wrap(cleanUpErr, "failed to clean up environment state files") @@ -635,11 +629,6 @@ func stopCmd() *cobra.Command { return errors.Wrap(removeErr, "failed to remove environment containers. Please remove them manually") } - stopRouterErr := stopConfiguredChipRouter() - if stopRouterErr != nil { - framework.L.Warn().Msgf("failed to stop chip ingress router: %s", stopRouterErr) - } - if allFlag { stopBeholderErr := stopBeholder() if stopBeholderErr != nil { @@ -785,10 +774,6 @@ func setDefaultCtfConfigs() error { return nil } -func stopConfiguredChipRouter() error { - return chiprouter.Stop(relativePathToRepoRoot) -} - func applyChipRouterImageOverride(in *envconfig.Config) { if in == nil || in.ChipRouter == nil { return diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 6fbbaaeccb7..fce6975e1cb 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -11,12 +11,6 @@ replace github.com/smartcontractkit/chainlink/system-tests/lib => ../../system-t replace github.com/smartcontractkit/chainlink/core/scripts/cre/environment/examples/workflows/v2/proof-of-reserve/cron-based => ./cre/environment/examples/workflows/v2/proof-of-reserve/cron-based -replace github.com/smartcontractkit/chainlink-testing-framework/framework => ../../../chainlink-testing-framework/framework - -replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter => ../../../chainlink-testing-framework/framework/components/chiprouter - -replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose => ../../../chainlink-testing-framework/framework/components/dockercompose - // Using a separate `require` here to avoid surrounding line changes // creating potential merge conflicts. require ( @@ -59,8 +53,8 @@ require ( github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20260119171452-39c98c3b33cd github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0 - github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8 - github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-00010101000000-000000000000 + github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d + github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 github.com/smartcontractkit/chainlink-testing-framework/seth v1.51.5 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 31989008e33..40c9204e4d0 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1702,6 +1702,12 @@ github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0 h1: github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0 h1:5NdsaclAfx+p8lZUZ3WIqMW3M9Cze1ZVPENOQhha1pk= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:IfeW6t5Yc5293H5ixuooAft+wYBMSFQWKjbBTwYiKr4= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d h1:WXSwn0DvzDkgNVJW83aNgesQYVLdOit882NgaE/TM6I= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d h1:ah8eskUFNLKew4jleHfouJ/2dWfRKmMWQ1EsOO4dOR8= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d/go.mod h1:hOtu1UY5WGENFqV7HBxYgq+/z5lUEZ705GA0Tuif7Ec= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 h1:8D2DUnn7mLUZOLhPDGGFKKvBrgU6LQd00tq2VOprvfI= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20/go.mod h1:98jNYBOPuKWJw9a8x0LgQuudp5enrHhQQP5Hq0YwRB8= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 h1:PWAMYu0WaAMBfbpxCpFJGRIDHmcgmYin6a+UQC0OdtY= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0/go.mod h1:YEQbZRHFojvlQKeuckG/70t0WkAqOBmArSbkacgHSbc= github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 h1:jARz/SWbmWoGJJGVcAnWwGMb8JuHRTQQsM3m6ZwrAGk= diff --git a/system-tests/lib/cre/chiprouter/router.go b/system-tests/lib/cre/chiprouter/router.go index 1150eb9d7bf..bbe483d5444 100644 --- a/system-tests/lib/cre/chiprouter/router.go +++ b/system-tests/lib/cre/chiprouter/router.go @@ -9,7 +9,6 @@ import ( "net/http" "net/netip" "os" - "os/exec" "strings" "sync" "time" @@ -46,14 +45,14 @@ type client struct { var ( clientOnce sync.Once clientInst *client - clientErr error + errClient error ) func getClient(relativePathToRepoRoot string) (*client, error) { clientOnce.Do(func() { st, err := envconfig.LoadChipIngressRouterStateFromLocalCRE(relativePathToRepoRoot) if err != nil { - clientErr = err + errClient = err return } clientInst = &client{ @@ -62,7 +61,7 @@ func getClient(relativePathToRepoRoot string) (*client, error) { } }) - return clientInst, clientErr + return clientInst, errClient } func EnsureStarted(ctx context.Context, relativePathToRepoRoot, _ string) error { @@ -83,26 +82,6 @@ func EnsureStarted(ctx context.Context, relativePathToRepoRoot, _ string) error return nil } -func Stop(relativePathToRepoRoot string) error { - c, err := getClient(relativePathToRepoRoot) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - - if strings.TrimSpace(c.state.ContainerName) != "" { - cmd := exec.Command("docker", "rm", "-f", c.state.ContainerName) - output, cmdErr := cmd.CombinedOutput() - if cmdErr != nil && !strings.Contains(strings.ToLower(string(output)), "no such container") { - return pkgerrors.Wrapf(cmdErr, "remove chip router container %s: %s", c.state.ContainerName, bytes.TrimSpace(output)) - } - } - - return nil -} - func RegisterSubscriber(ctx context.Context, relativePathToRepoRoot, name, endpoint string) (string, error) { c, err := getClient(relativePathToRepoRoot) if err != nil { @@ -234,7 +213,8 @@ func fetchHealth(ctx context.Context, adminURL string) (*healthResponse, error) } func isTCPReady(addr string) bool { - conn, err := net.DialTimeout("tcp", addr, time.Second) + dialer := &net.Dialer{Timeout: time.Second} + conn, err := dialer.Dial("tcp", addr) if err != nil { return false } diff --git a/system-tests/lib/go.mod b/system-tests/lib/go.mod index c8a69fe3e5f..b6ca159d6e7 100644 --- a/system-tests/lib/go.mod +++ b/system-tests/lib/go.mod @@ -11,12 +11,6 @@ replace github.com/smartcontractkit/chainlink/v2 => ../../ replace github.com/smartcontractkit/chainlink/deployment => ../../deployment -replace github.com/smartcontractkit/chainlink-testing-framework/framework => ../../../chainlink-testing-framework/framework - -replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter => ../../../chainlink-testing-framework/framework/components/chiprouter - -replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose => ../../../chainlink-testing-framework/framework/components/dockercompose - require ( dario.cat/mergo v1.0.2 github.com/Masterminds/semver/v3 v3.4.0 @@ -47,9 +41,9 @@ require ( github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0 github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20260217043601-5cc966896c4f github.com/smartcontractkit/chainlink-solana v1.1.2-0.20260325152920-167c7a34804c - github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8 - github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-00010101000000-000000000000 - github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.15 + github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d + github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d + github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 github.com/smartcontractkit/chainlink-testing-framework/seth v1.51.5 diff --git a/system-tests/lib/go.sum b/system-tests/lib/go.sum index 68d44545689..68913d9fd74 100644 --- a/system-tests/lib/go.sum +++ b/system-tests/lib/go.sum @@ -1671,6 +1671,12 @@ github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0 h1: github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0 h1:5NdsaclAfx+p8lZUZ3WIqMW3M9Cze1ZVPENOQhha1pk= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:IfeW6t5Yc5293H5ixuooAft+wYBMSFQWKjbBTwYiKr4= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d h1:WXSwn0DvzDkgNVJW83aNgesQYVLdOit882NgaE/TM6I= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d h1:ah8eskUFNLKew4jleHfouJ/2dWfRKmMWQ1EsOO4dOR8= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d/go.mod h1:hOtu1UY5WGENFqV7HBxYgq+/z5lUEZ705GA0Tuif7Ec= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 h1:8D2DUnn7mLUZOLhPDGGFKKvBrgU6LQd00tq2VOprvfI= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20/go.mod h1:98jNYBOPuKWJw9a8x0LgQuudp5enrHhQQP5Hq0YwRB8= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 h1:PWAMYu0WaAMBfbpxCpFJGRIDHmcgmYin6a+UQC0OdtY= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0/go.mod h1:YEQbZRHFojvlQKeuckG/70t0WkAqOBmArSbkacgHSbc= github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 h1:jARz/SWbmWoGJJGVcAnWwGMb8JuHRTQQsM3m6ZwrAGk= diff --git a/system-tests/tests/go.mod b/system-tests/tests/go.mod index 92e67c22554..5b624970eb7 100644 --- a/system-tests/tests/go.mod +++ b/system-tests/tests/go.mod @@ -41,12 +41,6 @@ replace github.com/smartcontractkit/chainlink/system-tests/tests/smoke/cre/solan replace github.com/smartcontractkit/chainlink/system-tests/tests/smoke/cre/vaultsecret => ./smoke/cre/vaultsecret -replace github.com/smartcontractkit/chainlink-testing-framework/framework => ../../../chainlink-testing-framework/framework - -replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter => ../../../chainlink-testing-framework/framework/components/chiprouter - -replace github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose => ../../../chainlink-testing-framework/framework/components/dockercompose - require ( github.com/Masterminds/semver/v3 v3.4.0 github.com/avast/retry-go/v4 v4.7.0 @@ -72,8 +66,8 @@ require ( github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0 github.com/smartcontractkit/chainlink-protos/ring/go v0.0.0-20260128151123-605e9540b706 github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20260217043601-5cc966896c4f - github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.8 - github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-00010101000000-000000000000 + github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d + github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.7 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 @@ -610,7 +604,7 @@ require ( github.com/smartcontractkit/chainlink-protos/svr v1.1.1-0.20260203131522-bb8bc5c423b3 // indirect github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0 // indirect github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0 // indirect - github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.18 // indirect + github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 // indirect github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect github.com/smartcontractkit/chainlink-testing-framework/parrot v0.6.2 // indirect github.com/smartcontractkit/chainlink-ton v0.0.0-20260331005855-7b5a4b3384f8 // indirect diff --git a/system-tests/tests/go.sum b/system-tests/tests/go.sum index 71b6f1a567c..a2d60d26b7e 100644 --- a/system-tests/tests/go.sum +++ b/system-tests/tests/go.sum @@ -1853,6 +1853,12 @@ github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0 h1: github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0 h1:5NdsaclAfx+p8lZUZ3WIqMW3M9Cze1ZVPENOQhha1pk= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:IfeW6t5Yc5293H5ixuooAft+wYBMSFQWKjbBTwYiKr4= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d h1:WXSwn0DvzDkgNVJW83aNgesQYVLdOit882NgaE/TM6I= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d h1:ah8eskUFNLKew4jleHfouJ/2dWfRKmMWQ1EsOO4dOR8= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d/go.mod h1:hOtu1UY5WGENFqV7HBxYgq+/z5lUEZ705GA0Tuif7Ec= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 h1:8D2DUnn7mLUZOLhPDGGFKKvBrgU6LQd00tq2VOprvfI= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20/go.mod h1:98jNYBOPuKWJw9a8x0LgQuudp5enrHhQQP5Hq0YwRB8= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 h1:PWAMYu0WaAMBfbpxCpFJGRIDHmcgmYin6a+UQC0OdtY= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0/go.mod h1:YEQbZRHFojvlQKeuckG/70t0WkAqOBmArSbkacgHSbc= github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.7 h1:ANltXlvv6CbOXieasPD9erc4BewtCHm1tKDPAYvuWLw= diff --git a/system-tests/tests/test-helpers/before_suite.go b/system-tests/tests/test-helpers/before_suite.go index ab287f6ed88..a0523027855 100644 --- a/system-tests/tests/test-helpers/before_suite.go +++ b/system-tests/tests/test-helpers/before_suite.go @@ -26,8 +26,8 @@ import ( "github.com/smartcontractkit/chainlink-deployments-framework/datastore" cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" "github.com/smartcontractkit/chainlink-testing-framework/framework" - ctfchiprouter "github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter" "github.com/smartcontractkit/chainlink-testing-framework/framework/components/blockchain" + ctfchiprouter "github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter" "github.com/smartcontractkit/chainlink-testing-framework/seth" keystone_changeset "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" diff --git a/system-tests/tests/test-helpers/chip_testsink_helpers.go b/system-tests/tests/test-helpers/chip_testsink_helpers.go index 3c5e6b892a8..bee9eb61459 100644 --- a/system-tests/tests/test-helpers/chip_testsink_helpers.go +++ b/system-tests/tests/test-helpers/chip_testsink_helpers.go @@ -18,6 +18,7 @@ import ( "google.golang.org/protobuf/proto" chippb "github.com/smartcontractkit/chainlink-common/pkg/chipingress/pb" + "github.com/smartcontractkit/chainlink-testing-framework/framework" commonevents "github.com/smartcontractkit/chainlink-protos/workflows/go/common" workflowevents "github.com/smartcontractkit/chainlink-protos/workflows/go/events" @@ -45,7 +46,7 @@ func (s *registeredChipSink) Shutdown(ctx context.Context) { return } if err := chiprouter.UnregisterSubscriber(ctx, s.relativePath, s.subscriberID); err != nil && !os.IsNotExist(err) { - // Shutdown must stay best-effort in cleanup paths. + framework.L.Warn().Msgf("failed to unregister chip sink subscriber: %s", err) } if s.server != nil { s.server.Shutdown(ctx) @@ -431,13 +432,13 @@ func GetLoggingPublishFn( func StartChipTestSink(t *testing.T, publishFn chiptestsink.PublishFn) ChipSink { startCh := make(chan struct{}, 1) addrCh := make(chan string, 1) - server, err := chiptestsink.NewServer(chiptestsink.Config{ + server, sErr := chiptestsink.NewServer(chiptestsink.Config{ PublishFunc: publishFn, GRPCListen: "127.0.0.1:0", Started: startCh, ActualAddr: addrCh, }) - require.NoError(t, err, "failed to create new test sink server") + require.NoError(t, sErr, "failed to create new test sink server") errCh := make(chan error, 1) go func() { From dba5e1e4e493c46bd1758eefe9db7e7b1156128a Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 1 Apr 2026 17:09:08 +0200 Subject: [PATCH 06/10] update CTF ref --- .github/workflows/cre-local-env-tests.yaml | 2 +- .github/workflows/cre-regression-system-tests.yaml | 2 +- .github/workflows/cre-soak-memory-leak.yml | 2 +- .github/workflows/cre-system-tests.yaml | 2 +- core/scripts/cre/environment/configs/setup.toml | 8 ++++---- core/scripts/go.mod | 4 ++-- core/scripts/go.sum | 8 ++++---- go.md | 5 +++++ system-tests/lib/go.mod | 4 ++-- system-tests/lib/go.sum | 8 ++++---- system-tests/tests/go.mod | 4 ++-- system-tests/tests/go.sum | 8 ++++---- 12 files changed, 31 insertions(+), 26 deletions(-) diff --git a/.github/workflows/cre-local-env-tests.yaml b/.github/workflows/cre-local-env-tests.yaml index 1402f90767a..5bb8bcb6539 100644 --- a/.github/workflows/cre-local-env-tests.yaml +++ b/.github/workflows/cre-local-env-tests.yaml @@ -166,7 +166,7 @@ jobs: CTF_CONFIGS: "./configs/workflow-gateway-don.toml" CTF_JD_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/job-distributor:0.22.1" CTF_CHAINLINK_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ github.event_name == 'pull_request' && format('nightly-{0}-plugins', steps.set-date.outputs.date) || inputs.chainlink_image_tag }}" - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:f9a4559c922b641a75b33262548be560a971655b" DISABLE_DX_TRACKING: "true" CI: "true" run: | diff --git a/.github/workflows/cre-regression-system-tests.yaml b/.github/workflows/cre-regression-system-tests.yaml index 784edcf87ac..57773d9815d 100644 --- a/.github/workflows/cre-regression-system-tests.yaml +++ b/.github/workflows/cre-regression-system-tests.yaml @@ -106,7 +106,7 @@ jobs: # Beholder stack will be started only for the Beholder tests CHIP_INGRESS_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f CHIP_CONFIG_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969 - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:f9a4559c922b641a75b33262548be560a971655b" BILLING_PLATFORM_SERVICE_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/billing-platform-service:v1.45.0 steps: diff --git a/.github/workflows/cre-soak-memory-leak.yml b/.github/workflows/cre-soak-memory-leak.yml index 41505548e5d..5642c011c50 100644 --- a/.github/workflows/cre-soak-memory-leak.yml +++ b/.github/workflows/cre-soak-memory-leak.yml @@ -118,7 +118,7 @@ jobs: working-directory: system-tests/tests env: GITHUB_TOKEN: ${{ steps.github-token.outputs.access-token || '' }} - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:f9a4559c922b641a75b33262548be560a971655b" run: | gotestsum \ --jsonfile=/tmp/gotest.log \ diff --git a/.github/workflows/cre-system-tests.yaml b/.github/workflows/cre-system-tests.yaml index 5d76bd5dba5..d34c0709fed 100644 --- a/.github/workflows/cre-system-tests.yaml +++ b/.github/workflows/cre-system-tests.yaml @@ -219,7 +219,7 @@ jobs: env: CTF_JD_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/job-distributor:0.22.1" CTF_CHAINLINK_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/${{ inputs.ecr_name }}:${{ inputs.chainlink_image_tag != '' && inputs.chainlink_image_tag || inputs.chainlink_version }}" - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:f9a4559c922b641a75b33262548be560a971655b" CTF_CONFIGS: ${{ matrix.tests.configs }} CRE_VERSION: ${{ matrix.tests.cre_version }} TEST_NAME: ${{ matrix.tests.test_name }} diff --git a/core/scripts/cre/environment/configs/setup.toml b/core/scripts/cre/environment/configs/setup.toml index 715be09564e..d5e181f383e 100644 --- a/core/scripts/cre/environment/configs/setup.toml +++ b/core/scripts/cre/environment/configs/setup.toml @@ -17,14 +17,14 @@ ecr_image = "{{.MAIN_ECR}}/job-distributor:0.22.1" [chip_router.build_config] repository = "https://github.com/smartcontractkit/chainlink-testing-framework" branch = "main" -commit = "2482d63e851d0f202e5514ed3328bbd49d7eb90c" +commit = "f9a4559c922b641a75b33262548be560a971655b" dockerfile = "framework/components/chiprouter/Dockerfile" docker_ctx = "framework/components/chiprouter" -local_image = "chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" +local_image = "chip-router:f9a4559c922b641a75b33262548be560a971655b" [chip_router.pull_config] -local_image = "chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" -ecr_image = "{{.SDLC_ECR}}/chip-router:2482d63e851d0f202e5514ed3328bbd49d7eb90c" +local_image = "chip-router:f9a4559c922b641a75b33262548be560a971655b" +ecr_image = "{{.SDLC_ECR}}/chip-router:f9a4559c922b641a75b33262548be560a971655b" [chip_ingress.build_config] repository = "https://github.com/smartcontractkit/atlas" diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 26ee2bc049d..f8baa65295f 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -53,8 +53,8 @@ require ( github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20260119171452-39c98c3b33cd github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0 - github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d - github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d + github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401145920-f9a4559c922b + github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401145920-f9a4559c922b github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 github.com/smartcontractkit/chainlink-testing-framework/seth v1.51.5 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 66812e1f8b3..5f04ab185dc 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1702,10 +1702,10 @@ github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0 h1: github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0 h1:5NdsaclAfx+p8lZUZ3WIqMW3M9Cze1ZVPENOQhha1pk= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:IfeW6t5Yc5293H5ixuooAft+wYBMSFQWKjbBTwYiKr4= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d h1:WXSwn0DvzDkgNVJW83aNgesQYVLdOit882NgaE/TM6I= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d h1:ah8eskUFNLKew4jleHfouJ/2dWfRKmMWQ1EsOO4dOR8= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d/go.mod h1:hOtu1UY5WGENFqV7HBxYgq+/z5lUEZ705GA0Tuif7Ec= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401145920-f9a4559c922b h1:0aDny6tEEQqBpGhcNkaBkzkvOfgGT+Mjnq1Ls8FslGM= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401145920-f9a4559c922b/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401145920-f9a4559c922b h1:Xr64gasse6l3SbYTS4RaGihonKrUPYnQcRvrk2w4KlI= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401145920-f9a4559c922b/go.mod h1:hOtu1UY5WGENFqV7HBxYgq+/z5lUEZ705GA0Tuif7Ec= github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 h1:8D2DUnn7mLUZOLhPDGGFKKvBrgU6LQd00tq2VOprvfI= github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20/go.mod h1:98jNYBOPuKWJw9a8x0LgQuudp5enrHhQQP5Hq0YwRB8= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 h1:PWAMYu0WaAMBfbpxCpFJGRIDHmcgmYin6a+UQC0OdtY= diff --git a/go.md b/go.md index 430c3a96691..71ea056c031 100644 --- a/go.md +++ b/go.md @@ -402,6 +402,9 @@ flowchart LR click chainlink-sui/deployment href "https://github.com/smartcontractkit/chainlink-sui" chainlink-testing-framework/framework --> chainlink-testing-framework/wasp click chainlink-testing-framework/framework href "https://github.com/smartcontractkit/chainlink-testing-framework" + chainlink-testing-framework/framework/components/chiprouter --> chainlink-common/pkg/chipingress + chainlink-testing-framework/framework/components/chiprouter --> chainlink-testing-framework/framework + click chainlink-testing-framework/framework/components/chiprouter href "https://github.com/smartcontractkit/chainlink-testing-framework" chainlink-testing-framework/framework/components/dockercompose --> chainlink-common/pkg/chipingress chainlink-testing-framework/framework/components/dockercompose --> chainlink-testing-framework/framework chainlink-testing-framework/framework/components/dockercompose --> freeport @@ -463,6 +466,7 @@ flowchart LR chainlink/load-tests --> chainlink-testing-framework/havoc chainlink/load-tests --> chainlink/integration-tests click chainlink/load-tests href "https://github.com/smartcontractkit/chainlink" + chainlink/system-tests/lib --> chainlink-testing-framework/framework/components/chiprouter chainlink/system-tests/lib --> chainlink-testing-framework/framework/components/dockercompose chainlink/system-tests/lib --> chainlink-testing-framework/framework/components/fake chainlink/system-tests/lib --> chainlink/deployment @@ -664,6 +668,7 @@ flowchart LR subgraph chainlink-testing-framework-repo[chainlink-testing-framework] chainlink-testing-framework/framework + chainlink-testing-framework/framework/components/chiprouter chainlink-testing-framework/framework/components/dockercompose chainlink-testing-framework/framework/components/fake chainlink-testing-framework/havoc diff --git a/system-tests/lib/go.mod b/system-tests/lib/go.mod index 97ceb3f2354..0c25e9f02c7 100644 --- a/system-tests/lib/go.mod +++ b/system-tests/lib/go.mod @@ -41,8 +41,8 @@ require ( github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0 github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20260217043601-5cc966896c4f github.com/smartcontractkit/chainlink-solana v1.1.2-0.20260331131550-45e89529badc - github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d - github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d + github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401145920-f9a4559c922b + github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401145920-f9a4559c922b github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 diff --git a/system-tests/lib/go.sum b/system-tests/lib/go.sum index da65d9fcbd9..6e6d24872e4 100644 --- a/system-tests/lib/go.sum +++ b/system-tests/lib/go.sum @@ -1671,10 +1671,10 @@ github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0 h1: github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0 h1:5NdsaclAfx+p8lZUZ3WIqMW3M9Cze1ZVPENOQhha1pk= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:IfeW6t5Yc5293H5ixuooAft+wYBMSFQWKjbBTwYiKr4= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d h1:WXSwn0DvzDkgNVJW83aNgesQYVLdOit882NgaE/TM6I= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d h1:ah8eskUFNLKew4jleHfouJ/2dWfRKmMWQ1EsOO4dOR8= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d/go.mod h1:hOtu1UY5WGENFqV7HBxYgq+/z5lUEZ705GA0Tuif7Ec= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401145920-f9a4559c922b h1:0aDny6tEEQqBpGhcNkaBkzkvOfgGT+Mjnq1Ls8FslGM= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401145920-f9a4559c922b/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401145920-f9a4559c922b h1:Xr64gasse6l3SbYTS4RaGihonKrUPYnQcRvrk2w4KlI= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401145920-f9a4559c922b/go.mod h1:hOtu1UY5WGENFqV7HBxYgq+/z5lUEZ705GA0Tuif7Ec= github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 h1:8D2DUnn7mLUZOLhPDGGFKKvBrgU6LQd00tq2VOprvfI= github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20/go.mod h1:98jNYBOPuKWJw9a8x0LgQuudp5enrHhQQP5Hq0YwRB8= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 h1:PWAMYu0WaAMBfbpxCpFJGRIDHmcgmYin6a+UQC0OdtY= diff --git a/system-tests/tests/go.mod b/system-tests/tests/go.mod index 8e6b3d6a243..2f68fd2c8b5 100644 --- a/system-tests/tests/go.mod +++ b/system-tests/tests/go.mod @@ -66,8 +66,8 @@ require ( github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0 github.com/smartcontractkit/chainlink-protos/ring/go v0.0.0-20260128151123-605e9540b706 github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20260217043601-5cc966896c4f - github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d - github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d + github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401145920-f9a4559c922b + github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401145920-f9a4559c922b github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.7 github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.5 diff --git a/system-tests/tests/go.sum b/system-tests/tests/go.sum index 80e8657bbdf..46582b263da 100644 --- a/system-tests/tests/go.sum +++ b/system-tests/tests/go.sum @@ -1853,10 +1853,10 @@ github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0 h1: github.com/smartcontractkit/chainlink-sui v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:U3XStbEnbx/+L22n1/8aOIdgcGVxtsZB7p59xJGngAs= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0 h1:5NdsaclAfx+p8lZUZ3WIqMW3M9Cze1ZVPENOQhha1pk= github.com/smartcontractkit/chainlink-sui/deployment v0.0.0-20260304150206-c64e48eb0cb0/go.mod h1:IfeW6t5Yc5293H5ixuooAft+wYBMSFQWKjbBTwYiKr4= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d h1:WXSwn0DvzDkgNVJW83aNgesQYVLdOit882NgaE/TM6I= -github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401144102-2482d63e851d/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d h1:ah8eskUFNLKew4jleHfouJ/2dWfRKmMWQ1EsOO4dOR8= -github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401144102-2482d63e851d/go.mod h1:hOtu1UY5WGENFqV7HBxYgq+/z5lUEZ705GA0Tuif7Ec= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401145920-f9a4559c922b h1:0aDny6tEEQqBpGhcNkaBkzkvOfgGT+Mjnq1Ls8FslGM= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.9-0.20260401145920-f9a4559c922b/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401145920-f9a4559c922b h1:Xr64gasse6l3SbYTS4RaGihonKrUPYnQcRvrk2w4KlI= +github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v0.0.0-20260401145920-f9a4559c922b/go.mod h1:hOtu1UY5WGENFqV7HBxYgq+/z5lUEZ705GA0Tuif7Ec= github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20 h1:8D2DUnn7mLUZOLhPDGGFKKvBrgU6LQd00tq2VOprvfI= github.com/smartcontractkit/chainlink-testing-framework/framework/components/dockercompose v0.1.20/go.mod h1:98jNYBOPuKWJw9a8x0LgQuudp5enrHhQQP5Hq0YwRB8= github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.10.0 h1:PWAMYu0WaAMBfbpxCpFJGRIDHmcgmYin6a+UQC0OdtY= From ab31144dfc9ed9dfe00119c818ab017ff751e722 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 2 Apr 2026 09:52:53 +0200 Subject: [PATCH 07/10] update chip router image ref --- .github/workflows/cre-local-env-tests.yaml | 2 +- .github/workflows/cre-regression-system-tests.yaml | 2 +- .github/workflows/cre-soak-memory-leak.yml | 2 +- .github/workflows/cre-system-tests.yaml | 2 +- core/scripts/cre/environment/configs/setup.toml | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/cre-local-env-tests.yaml b/.github/workflows/cre-local-env-tests.yaml index 5bb8bcb6539..206cc70cf53 100644 --- a/.github/workflows/cre-local-env-tests.yaml +++ b/.github/workflows/cre-local-env-tests.yaml @@ -166,7 +166,7 @@ jobs: CTF_CONFIGS: "./configs/workflow-gateway-don.toml" CTF_JD_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/job-distributor:0.22.1" CTF_CHAINLINK_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ github.event_name == 'pull_request' && format('nightly-{0}-plugins', steps.set-date.outputs.date) || inputs.chainlink_image_tag }}" - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:f9a4559c922b641a75b33262548be560a971655b" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.0" DISABLE_DX_TRACKING: "true" CI: "true" run: | diff --git a/.github/workflows/cre-regression-system-tests.yaml b/.github/workflows/cre-regression-system-tests.yaml index 57773d9815d..e67d3f02766 100644 --- a/.github/workflows/cre-regression-system-tests.yaml +++ b/.github/workflows/cre-regression-system-tests.yaml @@ -106,7 +106,7 @@ jobs: # Beholder stack will be started only for the Beholder tests CHIP_INGRESS_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f CHIP_CONFIG_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969 - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:f9a4559c922b641a75b33262548be560a971655b" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.0" BILLING_PLATFORM_SERVICE_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/billing-platform-service:v1.45.0 steps: diff --git a/.github/workflows/cre-soak-memory-leak.yml b/.github/workflows/cre-soak-memory-leak.yml index 5642c011c50..4ba17bc6e80 100644 --- a/.github/workflows/cre-soak-memory-leak.yml +++ b/.github/workflows/cre-soak-memory-leak.yml @@ -118,7 +118,7 @@ jobs: working-directory: system-tests/tests env: GITHUB_TOKEN: ${{ steps.github-token.outputs.access-token || '' }} - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:f9a4559c922b641a75b33262548be560a971655b" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.0" run: | gotestsum \ --jsonfile=/tmp/gotest.log \ diff --git a/.github/workflows/cre-system-tests.yaml b/.github/workflows/cre-system-tests.yaml index d34c0709fed..ef1deaf135b 100644 --- a/.github/workflows/cre-system-tests.yaml +++ b/.github/workflows/cre-system-tests.yaml @@ -219,7 +219,7 @@ jobs: env: CTF_JD_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/job-distributor:0.22.1" CTF_CHAINLINK_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/${{ inputs.ecr_name }}:${{ inputs.chainlink_image_tag != '' && inputs.chainlink_image_tag || inputs.chainlink_version }}" - CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:f9a4559c922b641a75b33262548be560a971655b" + CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.0" CTF_CONFIGS: ${{ matrix.tests.configs }} CRE_VERSION: ${{ matrix.tests.cre_version }} TEST_NAME: ${{ matrix.tests.test_name }} diff --git a/core/scripts/cre/environment/configs/setup.toml b/core/scripts/cre/environment/configs/setup.toml index d5e181f383e..ae76bb3990e 100644 --- a/core/scripts/cre/environment/configs/setup.toml +++ b/core/scripts/cre/environment/configs/setup.toml @@ -20,11 +20,11 @@ branch = "main" commit = "f9a4559c922b641a75b33262548be560a971655b" dockerfile = "framework/components/chiprouter/Dockerfile" docker_ctx = "framework/components/chiprouter" -local_image = "chip-router:f9a4559c922b641a75b33262548be560a971655b" +local_image = "local-cre-chip-router:v1.0.0" [chip_router.pull_config] -local_image = "chip-router:f9a4559c922b641a75b33262548be560a971655b" -ecr_image = "{{.SDLC_ECR}}/chip-router:f9a4559c922b641a75b33262548be560a971655b" +local_image = "local-cre-chip-router:v1.0.0" +ecr_image = "{{.SDLC_ECR}}/local-cre-chip-router:v1.0.0" [chip_ingress.build_config] repository = "https://github.com/smartcontractkit/atlas" From 7c2d73b788528fee787b3b15f33184e8d313183f Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 2 Apr 2026 10:04:34 +0200 Subject: [PATCH 08/10] use different role for local cre tests --- .github/workflows/cre-local-env-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cre-local-env-tests.yaml b/.github/workflows/cre-local-env-tests.yaml index 206cc70cf53..0ecd84f8e72 100644 --- a/.github/workflows/cre-local-env-tests.yaml +++ b/.github/workflows/cre-local-env-tests.yaml @@ -112,7 +112,7 @@ jobs: uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1 with: aws-region: ${{ secrets.QA_AWS_REGION }} - role-to-assume: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + role-to-assume: ${{ secrets.AWS_CTF_READ_ACCESS_ROLE_ARN }} role-duration-seconds: 1800 mask-aws-account-id: true From b391c69c7d3a6a9b6dfcac17087c1314a46da97e Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 2 Apr 2026 10:23:37 +0200 Subject: [PATCH 09/10] fix lints --- system-tests/tests/test-helpers/chip-testsink/server.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system-tests/tests/test-helpers/chip-testsink/server.go b/system-tests/tests/test-helpers/chip-testsink/server.go index 4f5abfe195c..05193f4bac0 100644 --- a/system-tests/tests/test-helpers/chip-testsink/server.go +++ b/system-tests/tests/test-helpers/chip-testsink/server.go @@ -112,7 +112,7 @@ func (s *Server) Run() error { func (s *Server) Publish(ctx context.Context, event *pb.CloudEvent) (*chippb.PublishResponse, error) { go func() { if s.cfg.UpstreamEndpoint != "" { - forwardCtx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second) + forwardCtx, cancelFn := context.WithTimeout(ctx, 10*time.Second) defer cancelFn() _, err := s.upstream.Publish(forwardCtx, event) if err != nil { @@ -134,7 +134,7 @@ func (s *Server) PublishBatch(ctx context.Context, batch *chippb.CloudEventBatch return } - forwardCtx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second) + forwardCtx, cancelFn := context.WithTimeout(ctx, 10*time.Second) defer cancelFn() _, err := s.upstream.PublishBatch(forwardCtx, batch) if err != nil { From dc04cac93f84006ed31a8565b55e009046935290 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Thu, 2 Apr 2026 18:57:42 +0200 Subject: [PATCH 10/10] clean up some logging; update router image; register running beholder with new router --- .../cre/environment/configs/setup.toml | 8 +-- .../configs/workflow-don-solana.toml | 2 +- .../configs/workflow-don-tron.toml | 2 +- .../workflow-gateway-capabilities-don.toml | 2 +- .../configs/workflow-gateway-don-aptos.toml | 3 ++ .../workflow-gateway-don-grpc-source.toml | 2 +- .../configs/workflow-gateway-don.toml | 2 +- .../workflow-gateway-legacy-vault-don.toml | 2 +- .../configs/workflow-gateway-mock-don.toml | 2 +- .../workflow-gateway-sharded-5-dons.toml | 2 +- .../configs/workflow-gateway-sharded-don.toml | 2 +- .../cre/environment/environment/beholder.go | 49 ++++++++++++++++++- .../environment/environment/environment.go | 22 ++++++++- system-tests/lib/cre/don.go | 13 ----- system-tests/lib/cre/types.go | 5 -- 15 files changed, 83 insertions(+), 35 deletions(-) diff --git a/core/scripts/cre/environment/configs/setup.toml b/core/scripts/cre/environment/configs/setup.toml index ae76bb3990e..9742ac1af0e 100644 --- a/core/scripts/cre/environment/configs/setup.toml +++ b/core/scripts/cre/environment/configs/setup.toml @@ -17,14 +17,14 @@ ecr_image = "{{.MAIN_ECR}}/job-distributor:0.22.1" [chip_router.build_config] repository = "https://github.com/smartcontractkit/chainlink-testing-framework" branch = "main" -commit = "f9a4559c922b641a75b33262548be560a971655b" +commit = "838769782600ad166f1afd2bca0de02ef4c42862" dockerfile = "framework/components/chiprouter/Dockerfile" docker_ctx = "framework/components/chiprouter" -local_image = "local-cre-chip-router:v1.0.0" +local_image = "local-cre-chip-router:v1.0.1" [chip_router.pull_config] -local_image = "local-cre-chip-router:v1.0.0" -ecr_image = "{{.SDLC_ECR}}/local-cre-chip-router:v1.0.0" +local_image = "local-cre-chip-router:v1.0.1" +ecr_image = "{{.SDLC_ECR}}/local-cre-chip-router:v1.0.1" [chip_ingress.build_config] repository = "https://github.com/smartcontractkit/atlas" diff --git a/core/scripts/cre/environment/configs/workflow-don-solana.toml b/core/scripts/cre/environment/configs/workflow-don-solana.toml index d6b345091ea..14a6452c83a 100644 --- a/core/scripts/cre/environment/configs/workflow-don-solana.toml +++ b/core/scripts/cre/environment/configs/workflow-don-solana.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" + image = "local-cre-chip-router:v1.0.1" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-don-tron.toml b/core/scripts/cre/environment/configs/workflow-don-tron.toml index 2d094af1342..bceba577cdb 100755 --- a/core/scripts/cre/environment/configs/workflow-don-tron.toml +++ b/core/scripts/cre/environment/configs/workflow-don-tron.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" + image = "local-cre-chip-router:v1.0.1" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml index dda4e0e8b3b..8b70049da33 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-capabilities-don.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" + image = "local-cre-chip-router:v1.0.1" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-don-aptos.toml b/core/scripts/cre/environment/configs/workflow-gateway-don-aptos.toml index 2748039bff0..6746b4e6997 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-don-aptos.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-don-aptos.toml @@ -1,6 +1,9 @@ # Same as workflow-gateway-don.toml but with Aptos chain and a single Aptos capability. # Anvil 1337: registry and gateway. Aptos: local devnet (chain_id 4). Run: env config path , then env start. +[chip_router] + image = "local-cre-chip-router:v1.0.1" + [[blockchains]] type = "anvil" chain_id = "1337" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml b/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml index 14701c9ad47..09b6571935b 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-don-grpc-source.toml @@ -5,7 +5,7 @@ # Used by: system-tests/tests/smoke/cre/v2_grpc_source_test.go [chip_router] - image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" + image = "local-cre-chip-router:v1.0.1" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-don.toml index ec1de043059..5bbb9f55a1f 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-don.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" + image = "local-cre-chip-router:v1.0.1" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml index 18ac37959db..b352240acd3 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-legacy-vault-don.toml @@ -1,7 +1,7 @@ # NOTE: Identical to workflow-gatewway-capabilities.toml but with a vault capability config override # to disable the new pending queue feature. [chip_router] - image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" + image = "local-cre-chip-router:v1.0.1" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml index 017c25411b6..bf3d098e09e 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-mock-don.toml @@ -1,5 +1,5 @@ [chip_router] - image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" + image = "local-cre-chip-router:v1.0.1" [[blockchains]] chain_id = "1337" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml b/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml index f2803c3d286..5f4feb374fc 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-sharded-5-dons.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" + image = "local-cre-chip-router:v1.0.1" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml b/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml index e7fa61dcdd4..992212c2b7d 100644 --- a/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml +++ b/core/scripts/cre/environment/configs/workflow-gateway-sharded-don.toml @@ -1,6 +1,6 @@ [chip_router] - image = "chip-router:6be930eaa5589d46c4d57edf272f86a7c09c231e" + image = "local-cre-chip-router:v1.0.1" [[blockchains]] type = "anvil" diff --git a/core/scripts/cre/environment/environment/beholder.go b/core/scripts/cre/environment/environment/beholder.go index dbbb4d0c918..badc93b7254 100644 --- a/core/scripts/cre/environment/environment/beholder.go +++ b/core/scripts/cre/environment/environment/beholder.go @@ -329,6 +329,47 @@ func hydrateChipRouterForBeholder(ctx context.Context) error { return chiprouter.EnsureStarted(ctx, relativePathToRepoRoot, "") } +func loadPersistedBeholderState(relativePathToRepoRoot string) (*envconfig.ChipIngressConfig, error) { + absPath := envconfig.MustChipIngressStateFileAbsPath(relativePathToRepoRoot) + if _, err := os.Stat(absPath); err != nil { + if os.IsNotExist(err) { + return nil, nil + } + return nil, errors.Wrap(err, "failed to stat persisted Beholder state") + } + + cfg := &envconfig.ChipIngressConfig{} + if err := cfg.Load(absPath); err != nil { + return nil, errors.Wrap(err, "failed to load persisted Beholder state") + } + + return cfg, nil +} + +func persistedBeholderGRPCEndpoint(cfg *envconfig.ChipIngressConfig) string { + if cfg == nil || cfg.ChipIngress == nil || cfg.ChipIngress.Output == nil || cfg.ChipIngress.Output.ChipIngress == nil { + return "" + } + + return strings.TrimSpace(cfg.ChipIngress.Output.ChipIngress.GRPCExternalURL) +} + +func restorePersistedBeholderState(relativePathToRepoRoot string, cfg *envconfig.ChipIngressConfig) error { + if cfg == nil { + return nil + } + return cfg.Store(envconfig.MustChipIngressStateFileAbsPath(relativePathToRepoRoot)) +} + +func reconcilePersistedBeholderWithRouter(ctx context.Context, cfg *envconfig.ChipIngressConfig) error { + endpoint := persistedBeholderGRPCEndpoint(cfg) + if endpoint == "" { + return errors.New("persisted Beholder state is missing chip ingress grpc endpoint") + } + + return registerBeholderEndpointWithRouter(ctx, endpoint) +} + var stopBeholderCmd = &cobra.Command{ Use: "stop", Short: "Stop the Beholder", @@ -346,7 +387,7 @@ func stopBeholder() error { } if subscriberID != "" { unregisterErr := chiprouter.UnregisterSubscriber(context.Background(), relativePathToRepoRoot, subscriberID) - if unregisterErr != nil && !os.IsNotExist(unregisterErr) { + if unregisterErr != nil && !os.IsNotExist(unregisterErr) && !strings.Contains(unregisterErr.Error(), "local CRE state file not found") && !strings.Contains(unregisterErr.Error(), "no such file or directory") { framework.L.Warn().Err(unregisterErr).Msg("failed to unregister Beholder from chip ingress router") } } @@ -766,12 +807,16 @@ If you want to use both together start ChIP Ingress on a different port with '-- } func registerBeholderWithRouter(ctx context.Context, port int) error { + return registerBeholderEndpointWithRouter(ctx, fmt.Sprintf("127.0.0.1:%d", port)) +} + +func registerBeholderEndpointWithRouter(ctx context.Context, endpoint string) error { previousID, err := loadBeholderSubscriberID(relativePathToRepoRoot) if err == nil && previousID != "" { _ = chiprouter.UnregisterSubscriber(ctx, relativePathToRepoRoot, previousID) } - id, err := chiprouter.RegisterSubscriber(ctx, relativePathToRepoRoot, "beholder", fmt.Sprintf("127.0.0.1:%d", port)) + id, err := chiprouter.RegisterSubscriber(ctx, relativePathToRepoRoot, "beholder", endpoint) if err != nil { return err } diff --git a/core/scripts/cre/environment/environment/environment.go b/core/scripts/cre/environment/environment/environment.go index e374b21cdbd..ab10127c816 100644 --- a/core/scripts/cre/environment/environment/environment.go +++ b/core/scripts/cre/environment/environment/environment.go @@ -257,6 +257,11 @@ func startCmd() *cobra.Command { return fmt.Errorf("with-plugins-docker-image flag is no longer supported. Set Docker image in TOML config instead (%s) for each nodeset under the [nodesets.nodesets.node_specs.node.image] field", effectiveConfig) } + persistedBeholderState, persistedBeholderStateErr := loadPersistedBeholderState(relativePathToRepoRoot) + if persistedBeholderStateErr != nil { + framework.L.Warn().Err(persistedBeholderStateErr).Msg("failed to load persisted Beholder state before startup cleanup") + } + cleanUpErr := envconfig.RemoveAllEnvironmentStateDir(relativePathToRepoRoot) if cleanUpErr != nil { return errors.Wrap(cleanUpErr, "failed to clean up environment state files") @@ -374,6 +379,19 @@ func startCmd() *cobra.Command { return errors.Wrap(startErr, "failed to start environment") } + storeErr := in.Store(envconfig.MustLocalCREStateFileAbsPath(relativePathToRepoRoot)) + if storeErr != nil { + return errors.Wrap(storeErr, "failed to store local CRE state") + } + + if !withBeholder && persistedBeholderState != nil { + if err := reconcilePersistedBeholderWithRouter(cmdContext, persistedBeholderState); err != nil { + framework.L.Warn().Err(err).Msg("failed to re-register persisted Beholder with chip ingress router") + } else if err := restorePersistedBeholderState(relativePathToRepoRoot, persistedBeholderState); err != nil { + framework.L.Warn().Err(err).Msg("failed to restore persisted Beholder state after router re-registration") + } + } + registryChainOut := output.CreEnvironment.Blockchains[0] sErr := StartCmdGenerateSettingsFile(registryChainOut, output) @@ -500,7 +518,7 @@ func startCmd() *cobra.Command { if stErr != nil { return errors.Wrap(stErr, "failed to set addresses on Config") } - storeErr := in.Store(envconfig.MustLocalCREStateFileAbsPath(relativePathToRepoRoot)) + storeErr = in.Store(envconfig.MustLocalCREStateFileAbsPath(relativePathToRepoRoot)) if storeErr != nil { return errors.Wrap(storeErr, "failed to store local CRE state") } @@ -766,7 +784,7 @@ func PrintCRELogo() { func setDefaultCtfConfigs() error { if os.Getenv("CTF_CONFIGS") == "" { - if err := os.Setenv("CTF_CONFIGS", "configs/workflow-gateway-don.toml"); err != nil { + if err := os.Setenv("CTF_CONFIGS", "configs/workflow-gateway-capabilities-don.toml"); err != nil { return fmt.Errorf("failed to set CTF_CONFIGS environment variable: %w", err) } diff --git a/system-tests/lib/cre/don.go b/system-tests/lib/cre/don.go index ae310de3350..1a2e93615b5 100644 --- a/system-tests/lib/cre/don.go +++ b/system-tests/lib/cre/don.go @@ -288,15 +288,9 @@ func registerWithJD(ctx context.Context, d *Don, supportedChains []blockchains.B for _, role := range node.Roles { switch role { case RoleWorker, RoleBootstrap: - chainConfigStart := time.Now() if err := createJDChainConfigs(ctx, node, supportedChains, jd); err != nil { return fmt.Errorf("failed to create supported chains in node %s: %w", node.Name, err) } - framework.L.Info(). - Str("don", d.Name). - Str("node", node.Name). - Float64("duration_s", roundSeconds(time.Since(chainConfigStart))). - Msg("JD chain-config setup completed") case RoleGateway: // no chains configuration needed for gateway nodes default: @@ -846,7 +840,6 @@ func LinkToJobDistributor(ctx context.Context, input *LinkDonsToJDInput) error { return errors.New("input is nil") } - start := time.Now() dons := input.Dons.List() donMetadata := input.Topology.DonsMetadata.List() nodeIDsByDON := make([][]string, len(dons)) @@ -854,7 +847,6 @@ func LinkToJobDistributor(ctx context.Context, input *LinkDonsToJDInput) error { errGroup, groupCtx := errgroup.WithContext(ctx) for idx, don := range dons { errGroup.Go(func() error { - donStart := time.Now() supportedChains, schErr := findDonSupportedChains(donMetadata[idx], input.Blockchains) if schErr != nil { return errors.Wrap(schErr, "failed to find supported chains for DON") @@ -865,10 +857,6 @@ func LinkToJobDistributor(ctx context.Context, input *LinkDonsToJDInput) error { } nodeIDsByDON[idx] = don.JDNodeIDs() - framework.L.Info(). - Str("don", don.Name). - Float64("duration_s", roundSeconds(time.Since(donStart))). - Msg("JD registration completed for DON") return nil }) } @@ -884,7 +872,6 @@ func LinkToJobDistributor(ctx context.Context, input *LinkDonsToJDInput) error { input.CldfEnvironment.NodeIDs = nodeIDs framework.L.Info(). - Float64("duration_s", roundSeconds(time.Since(start))). Msg("Post-start JD linking completed") return nil diff --git a/system-tests/lib/cre/types.go b/system-tests/lib/cre/types.go index 6402d41e2a8..fca444f2514 100644 --- a/system-tests/lib/cre/types.go +++ b/system-tests/lib/cre/types.go @@ -10,7 +10,6 @@ import ( "slices" "strconv" "strings" - "time" "github.com/Masterminds/semver/v3" "github.com/ethereum/go-ethereum/common" @@ -586,7 +585,6 @@ func NewDonMetadata(c *NodeSet, id uint64, provider infra.Provider, capabilityCo cfgs[i] = cfg } - newNodesStart := time.Now() nodes, err := newNodes(cfgs) if err != nil { return nil, fmt.Errorf("failed to create nodes metadata: %w", err) @@ -594,7 +592,6 @@ func NewDonMetadata(c *NodeSet, id uint64, provider infra.Provider, capabilityCo framework.L.Info(). Str("don", c.Name). Int("nodes", len(cfgs)). - Float64("duration_s", roundSeconds(time.Since(newNodesStart))). Msg("Node metadata generation completed") capConfigs, capErr := processCapabilityConfigs(c, capabilityConfigs) @@ -1465,7 +1462,6 @@ type NodeKeyInput struct { } func NewNodeKeys(input NodeKeyInput) (*secrets.NodeKeys, error) { - start := time.Now() out := &secrets.NodeKeys{ EVM: make(map[uint64]*crypto.EVMKey), Solana: make(map[string]*crypto.SolKey), @@ -1525,7 +1521,6 @@ func NewNodeKeys(input NodeKeyInput) (*secrets.NodeKeys, error) { Int("evm_chains", len(input.EVMChainIDs)). Int("solana_chains", len(input.SolanaChainIDs)). Bool("imported", input.ImportedSecrets != ""). - Float64("duration_s", roundSeconds(time.Since(start))). Msg("Node key generation completed") return out, nil }