Skip to content

Commit

Permalink
Merge integration tests folder
Browse files Browse the repository at this point in the history
  • Loading branch information
kalverra committed Jul 8, 2024
1 parent d5ab3e6 commit 24342f9
Show file tree
Hide file tree
Showing 71 changed files with 2,257 additions and 1,306 deletions.
2 changes: 1 addition & 1 deletion integration-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,4 @@ Run soak/ocr_test.go with RPC network chaos by bringing down network to RPC node

```bash
make test_soak_ocr_rpc_down_half_cl_nodes
```
```
68 changes: 1 addition & 67 deletions integration-tests/actions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package actions
import (
"context"
"crypto/ecdsa"
"encoding/json"
"fmt"
"math"
"math/big"
Expand All @@ -13,7 +12,6 @@ import (
"testing"
"time"

"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/pelletier/go-toml/v2"

geth "github.com/ethereum/go-ethereum"
Expand All @@ -26,7 +24,6 @@ import (
"github.com/smartcontractkit/chainlink-testing-framework/logging"
"github.com/smartcontractkit/chainlink-testing-framework/testreporters"
"github.com/smartcontractkit/chainlink-testing-framework/utils/conversions"

"github.com/smartcontractkit/chainlink/integration-tests/contracts"
ethContracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"

Expand Down Expand Up @@ -667,45 +664,6 @@ func ConfigureOCRv2AggregatorContracts(
return nil
}

// ReturnFunds attempts to return all the funds from the chainlink nodes to the network's default address
// all from a remote, k8s style environment
// Remove this once ccip-tests are moved to seth client
func ReturnFunds(lggr zerolog.Logger, chainlinkNodes []*client.ChainlinkK8sClient, blockchainClient blockchain.EVMClient) error {
if blockchainClient == nil {
return fmt.Errorf("blockchain client is nil, unable to return funds from chainlink nodes")
}
lggr.Info().Msg("Attempting to return Chainlink node funds to default network wallets")
if blockchainClient.NetworkSimulated() {
lggr.Info().Str("Network Name", blockchainClient.GetNetworkName()).
Msg("Network is a simulated network. Skipping fund return.")
return nil
}

for _, chainlinkNode := range chainlinkNodes {
fundedKeys, err := chainlinkNode.ExportEVMKeysForChain(blockchainClient.GetChainID().String())
if err != nil {
return err
}
for _, key := range fundedKeys {
keyToDecrypt, err := json.Marshal(key)
if err != nil {
return err
}
// This can take up a good bit of RAM and time. When running on the remote-test-runner, this can lead to OOM
// issues. So we avoid running in parallel; slower, but safer.
decryptedKey, err := keystore.DecryptKey(keyToDecrypt, client.ChainlinkKeyPassword)
if err != nil {
return err
}
err = blockchainClient.ReturnFunds(decryptedKey.PrivateKey)
if err != nil {
lggr.Error().Err(err).Str("Address", fundedKeys[0].Address).Msg("Error returning funds from Chainlink node")
}
}
}
return blockchainClient.WaitForEvents()
}

// TeardownSuite tears down networks/clients and environment and creates a logs folder for failed tests in the
// specified path. Can also accept a testreporter (if one was used) to log further results
func TeardownSuite(
Expand All @@ -716,7 +674,6 @@ func TeardownSuite(
optionalTestReporter testreporters.TestReporter, // Optionally pass in a test reporter to log further metrics
failingLogLevel zapcore.Level, // Examines logs after the test, and fails the test if any Chainlink logs are found at or above provided level
grafnaUrlProvider testreporters.GrafanaURLProvider,
evmClients ...blockchain.EVMClient,
) error {
l := logging.GetTestLogger(t)
if err := testreporters.WriteTeardownLogs(t, env, optionalTestReporter, failingLogLevel, grafnaUrlProvider); err != nil {
Expand All @@ -728,7 +685,7 @@ func TeardownSuite(
l.Warn().Msgf("Error deleting jobs %+v", err)
}

if chainlinkNodes != nil && chainClient != nil {
if chainlinkNodes != nil {
if err := ReturnFundsFromNodes(l, chainClient, contracts.ChainlinkK8sClientToChainlinkNodeWithKeysAndAddress(chainlinkNodes)); err != nil {
// This printed line is required for tests that use real funds to propagate the failure
// out to the system running the test. Do not remove
Expand All @@ -740,29 +697,6 @@ func TeardownSuite(
} else {
l.Info().Msg("Successfully returned funds from chainlink nodes to default network wallets")
}
// The following is needed for tests using EVMClient,
// Remove this once ccip-tests are moved to seth client
for _, c := range evmClients {
if c != nil && chainlinkNodes != nil && len(chainlinkNodes) > 0 {
if err := ReturnFunds(l, chainlinkNodes, c); err != nil {
// This printed line is required for tests that use real funds to propagate the failure
// out to the system running the test. Do not remove
fmt.Println(environment.FAILED_FUND_RETURN)
l.Error().Err(err).Str("Namespace", env.Cfg.Namespace).
Msg("Error attempting to return funds from chainlink nodes to network's default wallet. " +
"Environment is left running so you can try manually!")
}
} else {
l.Info().Msg("Successfully returned funds from chainlink nodes to default network wallets")
}
// nolint
if c != nil {
err := c.Close()
if err != nil {
return err
}
}
}

return env.Shutdown()
}
Expand Down
15 changes: 9 additions & 6 deletions integration-tests/actions/automation_ocr_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,12 @@ func DeployAutoOCRRegistryAndRegistrar(

// DeployConsumers deploys and registers keeper consumers. If ephemeral addresses are enabled, it will deploy and register the consumers from ephemeral addresses, but each upkpeep will be registered with root key address as the admin. Which means
// that functions like setting upkeep configuration, pausing, unpausing, etc. will be done by the root key address. It deploys multicall contract and sends link funds to each deployment address.
func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, linkToken contracts.LinkToken, numberOfUpkeeps int, linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, isLogTrigger bool, isMercury bool) ([]contracts.KeeperConsumer, []*big.Int) {
err := DeployMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep)
require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail")
func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, linkToken contracts.LinkToken, numberOfUpkeeps int, linkFundsForEachUpkeep *big.Int, upkeepGasLimit uint32, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken) ([]contracts.KeeperConsumer, []*big.Int) {
// Fund deployers with LINK, no need to do this for Native token
if !isBillingTokenNative {
err := DeployMultiCallAndFundDeploymentAddresses(chainClient, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep)
require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail")
}

upkeeps := DeployKeeperConsumers(t, chainClient, numberOfUpkeeps, isLogTrigger, isMercury)
require.Equal(t, numberOfUpkeeps, len(upkeeps), "Number of upkeeps should match")
Expand All @@ -285,7 +288,7 @@ func DeployConsumers(t *testing.T, chainClient *seth.Client, registry contracts.
upkeepsAddresses = append(upkeepsAddresses, upkeep.Address())
}
upkeepIds := RegisterUpkeepContracts(
t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, isLogTrigger, isMercury,
t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, isLogTrigger, isMercury, isBillingTokenNative, wethToken,
)
require.Equal(t, numberOfUpkeeps, len(upkeepIds), "Number of upkeepIds should match")
return upkeeps, upkeepIds
Expand Down Expand Up @@ -318,7 +321,7 @@ func DeployPerformanceConsumers(
for _, upkeep := range upkeeps {
upkeepsAddresses = append(upkeepsAddresses, upkeep.Address())
}
upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, false, false)
upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, false, false, false, nil)
return upkeeps, upkeepIds
}

Expand All @@ -344,7 +347,7 @@ func DeployPerformDataCheckerConsumers(
for _, upkeep := range upkeeps {
upkeepsAddresses = append(upkeepsAddresses, upkeep.Address())
}
upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, false, false)
upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfUpkeeps, upkeepsAddresses, false, false, false, nil)
return upkeeps, upkeepIds
}

Expand Down
11 changes: 10 additions & 1 deletion integration-tests/actions/automationv2/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,8 @@ func (a *AutomationTest) SetConfigOnRegistry() error {
} else if a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_3 {
ocrConfig.TypedOnchainConfig23 = a.RegistrySettings.Create23OnchainConfig(a.Registrar.Address(), a.UpkeepPrivilegeManager, a.Registry.ChainModuleAddress(), a.Registry.ReorgProtectionEnabled())
ocrConfig.BillingTokens = []common.Address{
common.HexToAddress(a.LinkToken.Address()), // TODO add more billing tokens
common.HexToAddress(a.LinkToken.Address()),
common.HexToAddress(a.WETHToken.Address()),
}

ocrConfig.BillingConfigs = []i_automation_registry_master_wrapper_2_3.AutomationRegistryBase23BillingConfig{
Expand All @@ -577,6 +578,14 @@ func (a *AutomationTest) SetConfigOnRegistry() error {
FallbackPrice: big.NewInt(1000),
MinSpend: big.NewInt(200),
},
{
GasFeePPB: 100,
FlatFeeMilliCents: big.NewInt(500),
PriceFeed: common.HexToAddress(a.EthUSDFeed.Address()), // ETH/USD feed and LINK/USD feed are the same
Decimals: 18,
FallbackPrice: big.NewInt(1000),
MinSpend: big.NewInt(200),
},
}
}
err = a.Registry.SetConfigTypeSafe(ocrConfig)
Expand Down
113 changes: 69 additions & 44 deletions integration-tests/actions/keeper_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strconv"
"testing"

"github.com/ethereum/go-ethereum/core/types"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/smartcontractkit/seth"
Expand Down Expand Up @@ -115,7 +116,7 @@ func DeployKeeperContracts(
}

registrar := DeployKeeperRegistrar(t, client, registryVersion, linkToken, registrarSettings, registry)
upkeeps, upkeepIds := DeployConsumers(t, client, registry, registrar, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, upkeepGasLimit, false, false)
upkeeps, upkeepIds := DeployConsumers(t, client, registry, registrar, linkToken, numberOfUpkeeps, linkFundsForEachUpkeep, upkeepGasLimit, false, false, false, nil)

return registry, registrar, upkeeps, upkeepIds
}
Expand Down Expand Up @@ -178,7 +179,7 @@ func DeployPerformanceKeeperContracts(
upkeepsAddresses = append(upkeepsAddresses, upkeep.Address())
}

upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, false, false)
upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, false, false, false, nil)

return registry, registrar, upkeeps, upkeepIds
}
Expand Down Expand Up @@ -236,7 +237,7 @@ func DeployPerformDataCheckerContracts(
upkeepsAddresses = append(upkeepsAddresses, upkeep.Address())
}

upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, false, false)
upkeepIds := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfContracts, upkeepsAddresses, false, false, false, nil)

return registry, registrar, upkeeps, upkeepIds
}
Expand All @@ -259,14 +260,14 @@ func DeployKeeperRegistrar(
return registrar
}

func RegisterUpkeepContracts(t *testing.T, client *seth.Client, linkToken contracts.LinkToken, linkFunds *big.Int, upkeepGasLimit uint32, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, numberOfContracts int, upkeepAddresses []string, isLogTrigger bool, isMercury bool) []*big.Int {
func RegisterUpkeepContracts(t *testing.T, client *seth.Client, linkToken contracts.LinkToken, fundsForEachUpkeep *big.Int, upkeepGasLimit uint32, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, numberOfContracts int, upkeepAddresses []string, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken) []*big.Int {
checkData := make([][]byte, 0)
for i := 0; i < numberOfContracts; i++ {
checkData = append(checkData, []byte("0"))
}
return RegisterUpkeepContractsWithCheckData(
t, client, linkToken, linkFunds, upkeepGasLimit, registry, registrar,
numberOfContracts, upkeepAddresses, checkData, isLogTrigger, isMercury)
t, client, linkToken, fundsForEachUpkeep, upkeepGasLimit, registry, registrar,
numberOfContracts, upkeepAddresses, checkData, isLogTrigger, isMercury, isBillingTokenNative, wethToken)
}

type upkeepRegistrationResult struct {
Expand All @@ -284,7 +285,7 @@ type upkeepConfig struct {

type UpkeepId = *big.Int

func RegisterUpkeepContractsWithCheckData(t *testing.T, client *seth.Client, linkToken contracts.LinkToken, linkFunds *big.Int, upkeepGasLimit uint32, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, numberOfContracts int, upkeepAddresses []string, checkData [][]byte, isLogTrigger bool, isMercury bool) []*big.Int {
func RegisterUpkeepContractsWithCheckData(t *testing.T, client *seth.Client, linkToken contracts.LinkToken, fundsForEachUpkeep *big.Int, upkeepGasLimit uint32, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, numberOfContracts int, upkeepAddresses []string, checkData [][]byte, isLogTrigger bool, isMercury bool, isBillingTokenNative bool, wethToken contracts.WETHToken) []*big.Int {
l := logging.GetTestLogger(t)

concurrency, err := GetAndAssertCorrectConcurrency(client, 1)
Expand All @@ -300,45 +301,69 @@ func RegisterUpkeepContractsWithCheckData(t *testing.T, client *seth.Client, lin
var registerUpkeepFn = func(resultCh chan upkeepRegistrationResult, errorCh chan error, executorNum int, config upkeepConfig) {
id := uuid.New().String()
keyNum := executorNum + 1 // key 0 is the root key
var tx *types.Transaction

if isBillingTokenNative {
// register upkeep with native token
tx, err = registrar.RegisterUpkeepFromKey(
keyNum,
fmt.Sprintf("upkeep_%s", id),
[]byte("[email protected]"),
config.address,
upkeepGasLimit,
client.MustGetRootKeyAddress().Hex(), // upkeep Admin
config.data,
fundsForEachUpkeep,
wethToken.Address(),
isLogTrigger,
isMercury,
)
if err != nil {
errorCh <- errors.Wrapf(err, "[id: %s] Failed to register upkeep at %s", id, config.address)
return
}
} else {
// register upkeep with LINK
req, err := registrar.EncodeRegisterRequest(
fmt.Sprintf("upkeep_%s", id),
[]byte("[email protected]"),
config.address,
upkeepGasLimit,
client.MustGetRootKeyAddress().Hex(), // upkeep Admin
config.data,
fundsForEachUpkeep,
0,
client.Addresses[keyNum].Hex(),
isLogTrigger,
isMercury,
linkToken.Address(),
)

if err != nil {
errorCh <- errors.Wrapf(err, "[id: %s] Failed to encode register request for upkeep at %s", id, config.address)
return
}

req, err := registrar.EncodeRegisterRequest(
fmt.Sprintf("upkeep_%s", id),
[]byte("[email protected]"),
config.address,
upkeepGasLimit,
client.MustGetRootKeyAddress().Hex(), // upkeep Admin
config.data,
linkFunds,
0,
client.Addresses[keyNum].Hex(),
isLogTrigger,
isMercury,
linkToken.Address(),
)

if err != nil {
errorCh <- errors.Wrapf(err, "[id: %s] Failed to encode register request for upkeep at %s", id, config.address)
return
}

balance, err := linkToken.BalanceOf(context.Background(), client.Addresses[keyNum].Hex())
if err != nil {
errorCh <- errors.Wrapf(err, "[id: %s]Failed to get LINK balance of %s", id, client.Addresses[keyNum].Hex())
return
}
balance, err := linkToken.BalanceOf(context.Background(), client.Addresses[keyNum].Hex())
if err != nil {
errorCh <- errors.Wrapf(err, "[id: %s]Failed to get LINK balance of %s", id, client.Addresses[keyNum].Hex())
return
}

// not stricly necessary, but helps us to avoid an errorless revert if there is not enough LINK
if balance.Cmp(linkFunds) < 0 {
errorCh <- fmt.Errorf("[id: %s] Not enough LINK balance for %s. Has: %s. Needs: %s", id, client.Addresses[keyNum].Hex(), balance.String(), linkFunds.String())
return
}
// not strictly necessary, but helps us to avoid an errorless revert if there is not enough LINK
if balance.Cmp(fundsForEachUpkeep) < 0 {
errorCh <- fmt.Errorf("[id: %s] Not enough LINK balance for %s. Has: %s. Needs: %s", id, client.Addresses[keyNum].Hex(), balance.String(), fundsForEachUpkeep.String())
return
}

tx, err := linkToken.TransferAndCallFromKey(registrar.Address(), linkFunds, req, keyNum)
if err != nil {
errorCh <- errors.Wrapf(err, "[id: %s] Failed to register upkeep at %s", id, config.address)
return
tx, err = linkToken.TransferAndCallFromKey(registrar.Address(), fundsForEachUpkeep, req, keyNum)
if err != nil {
errorCh <- errors.Wrapf(err, "[id: %s] Failed to register upkeep at %s", id, config.address)
return
}
}

// parse txn to get upkeep ID
receipt, err := client.Client.TransactionReceipt(context.Background(), tx.Hash())
if err != nil {
errorCh <- errors.Wrapf(err, "[id: %s] Failed to get receipt for upkeep at %s and tx hash %s", id, config.address, tx.Hash())
Expand Down Expand Up @@ -405,10 +430,10 @@ func DeployKeeperConsumers(t *testing.T, client *seth.Client, numberOfContracts
// v2.1 only: Conditional based contract with Mercury enabled
keeperConsumerInstance, err = contracts.DeployAutomationStreamsLookupUpkeepConsumerFromKey(client, keyNum, big.NewInt(1000), big.NewInt(5), false, true, false) // 1000 block test range
} else if isLogTrigger {
// v2.1 only: Log triggered based contract without Mercury
// v2.1+: Log triggered based contract without Mercury
keeperConsumerInstance, err = contracts.DeployAutomationLogTriggerConsumerFromKey(client, keyNum, big.NewInt(1000)) // 1000 block test range
} else {
// v2.0 and v2.1: Conditional based contract without Mercury
// v2.0+: Conditional based contract without Mercury
keeperConsumerInstance, err = contracts.DeployUpkeepCounterFromKey(client, keyNum, big.NewInt(999999), big.NewInt(5))
}

Expand Down Expand Up @@ -580,7 +605,7 @@ func RegisterNewUpkeeps(
err = SendLinkFundsToDeploymentAddresses(chainClient, concurrency, numberOfNewUpkeeps, operationsPerAddress, multicallAddress, linkFundsForEachUpkeep, linkToken)
require.NoError(t, err, "Sending link funds to deployment addresses shouldn't fail")

newUpkeepIDs := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfNewUpkeeps, addressesOfNewUpkeeps, false, false)
newUpkeepIDs := RegisterUpkeepContracts(t, chainClient, linkToken, linkFundsForEachUpkeep, upkeepGasLimit, registry, registrar, numberOfNewUpkeeps, addressesOfNewUpkeeps, false, false, false, nil)

return newlyDeployedUpkeeps, newUpkeepIDs
}
Expand Down
1 change: 0 additions & 1 deletion integration-tests/actions/ocr2_helpers_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (

"github.com/smartcontractkit/chainlink-common/pkg/codec"
"github.com/smartcontractkit/chainlink-testing-framework/docker/test_env"

evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types"

"github.com/smartcontractkit/chainlink/v2/core/services/job"
Expand Down
Loading

0 comments on commit 24342f9

Please sign in to comment.