From 5e0b1709b7710b1117446c174fa5a5a1a0ea2c52 Mon Sep 17 00:00:00 2001 From: Francisco Moura Date: Thu, 29 Feb 2024 15:49:28 -0300 Subject: [PATCH] feat: Add Echo App Input end-to-end tests --- cmd/cartesi-rollups-cli/root/deps/deps.go | 2 + cmd/cartesi-rollups-cli/root/send/send.go | 3 + end-to-end-tests/echo_input_test.go | 141 +++++++++++++++++++++- internal/deps/deps.go | 27 +++-- 4 files changed, 164 insertions(+), 9 deletions(-) diff --git a/cmd/cartesi-rollups-cli/root/deps/deps.go b/cmd/cartesi-rollups-cli/root/deps/deps.go index 94b0d92b5..f71051940 100644 --- a/cmd/cartesi-rollups-cli/root/deps/deps.go +++ b/cmd/cartesi-rollups-cli/root/deps/deps.go @@ -49,6 +49,8 @@ func init() { func run(cmd *cobra.Command, args []string) { + config.InitLogFromEnv() + ctx, cancel := signal.NotifyContext(cmd.Context(), syscall.SIGINT, syscall.SIGTERM) defer cancel() diff --git a/cmd/cartesi-rollups-cli/root/send/send.go b/cmd/cartesi-rollups-cli/root/send/send.go index 22e3a1767..ea3e0809a 100644 --- a/cmd/cartesi-rollups-cli/root/send/send.go +++ b/cmd/cartesi-rollups-cli/root/send/send.go @@ -50,6 +50,9 @@ func init() { } func run(cmd *cobra.Command, args []string) { + + config.InitLogFromEnv() + payload, err := hexutil.Decode(hexPayload) cobra.CheckErr(err) diff --git a/end-to-end-tests/echo_input_test.go b/end-to-end-tests/echo_input_test.go index 46ba78d0e..a8bbcc079 100644 --- a/end-to-end-tests/echo_input_test.go +++ b/end-to-end-tests/echo_input_test.go @@ -4,28 +4,167 @@ package endtoendtests import ( + "context" + "io/ioutil" + "os" "testing" + "time" + "github.com/Khan/genqlient/graphql" + "github.com/cartesi/rollups-node/internal/config" + "github.com/cartesi/rollups-node/internal/deps" + "github.com/cartesi/rollups-node/internal/machine" + "github.com/cartesi/rollups-node/internal/node" + "github.com/cartesi/rollups-node/internal/services" + "github.com/cartesi/rollups-node/pkg/addresses" + "github.com/cartesi/rollups-node/pkg/ethutil" + "github.com/cartesi/rollups-node/pkg/readerclient" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" ) type EchoInputTestSuite struct { suite.Suite + containers *deps.DepsContainers + cancel context.CancelFunc + tempDir string } func (s *EchoInputTestSuite) SetupSuite() { - //run services + //Create machine snapshot + tempDir, err := ioutil.TempDir("", "machine-snapshot") + assert.NoError(s.T(), err) + machine.Save("cartesi/rollups-node-snapshot:devel", tempDir, "test-echo-app") + + //run deps + ctx := context.Background() + var depsConfig = deps.NewDefaultDepsConfig() + depsContainers, err := deps.Run(ctx, *depsConfig) + assert.NoError(s.T(), err) + + config.InfoLogger.Println("All Deps are up!!") + time.Sleep(2 * time.Second) + + // Run Node Service + nodeConfig := config.NewNodeConfigFromEnv() + + postgressEndpoint := "postgres://postgres:password@localhost:5432/postgres" + chainId := 31337 + appAddress := "0x7FFdf694A877067DE99462A7243b29972D19cf72" + var inputBoxBlockNumber int64 = 20 + wsEnpoint := "ws://localhost:8545" + httpEnpoint := "http://localhost:8545" + historyAddress := "0x325272217ae6815b494bF38cED004c5Eb8a7CdA7" + authrorityAddress := "0x58c93F83fb3304730C95aad2E360cdb88b782010" + inputBoxAddress := "0x59b22D57D4f067708AB0c00552767405926dc768" + appDeployBlockNumber := "20" + blockChainFinalityOffset := 1 + httpAddress := "0.0.0.0" + + cartesiEpochDuration, err := time.ParseDuration("120s") + require.NoError(s.T(), err) + + nodeConfig.SetCartesiPostgresEndpoint(&postgressEndpoint) + nodeConfig.SetCartesiBlockchainId(&chainId) + nodeConfig.SetCartesiContractsApplicationAddress(&appAddress) + nodeConfig.SetCartesiContractsInputBoxDeploymentBlockNumber(&inputBoxBlockNumber) + nodeConfig.SetCartesiBlockchainWsEndpoint(&wsEnpoint) + nodeConfig.SetCartesiBlockchainHttpEndpoint(&httpEnpoint) + nodeConfig.SetCartesiContractsHistoryAddress(&historyAddress) + nodeConfig.SetCartesiContractsAuthorityAddress(&authrorityAddress) + nodeConfig.SetCartesiContractsInputBoxAddress(&inputBoxAddress) + nodeConfig.SetCartesiSnapshotDir(&tempDir) + nodeConfig.SetCartesiContractsApplicationDeploymentBlockNumber(&appDeployBlockNumber) + nodeConfig.SetCartesiBlockchainFinalityOffset(&blockChainFinalityOffset) + nodeConfig.SetCartesiHttpAddress(&httpAddress) + nodeConfig.SetCartesiEpochDuration(&cartesiEpochDuration) + + nodeServices := node.NewNodeServices(nodeConfig) + supervisor := services.SupervisorService{ + Name: "rollups-node-tests", + Services: nodeServices, + } + + ctx, cancel := context.WithCancel(ctx) + ready := make(chan struct{}, 1) + supervisorErr := make(chan error, 1) + go func() { + err := supervisor.Start(ctx, ready) + if err != nil { + supervisorErr <- err + } + }() + + select { + case err := <-supervisorErr: + require.NoError(s.T(), err) + case <-ready: + config.InfoLogger.Println("All services are up!!") + break + } + + //Configure Suite for tear down + s.containers = depsContainers + s.tempDir = tempDir + s.cancel = cancel + } func (s *EchoInputTestSuite) TearDownSuite() { + //Stop Node services + s.cancel() + + //Remove machine snpshot + os.RemoveAll(s.tempDir) + + //Terminate deps + ctx := context.Background() + err := deps.Terminate(ctx, s.containers) + require.NoError(s.T(), err) + } func (s *EchoInputTestSuite) SetupTest() { } +func (s *EchoInputTestSuite) TestSendInput() { + + // Send Input + ctx := context.Background() + client, err := ethclient.DialContext(ctx, "http://localhost:8545") + require.NoError(s.T(), err) + signer, err := ethutil.NewMnemonicSigner(ctx, client, ethutil.FoundryMnemonic, 0) + require.NoError(s.T(), err) + + book := addresses.GetTestBook() + + inputIndex, err := ethutil.AddInput(ctx, client, book, signer, []byte("0xDEADBEEF")) + require.NoError(s.T(), err) + + config.InfoLogger.Printf("Input index : %v", inputIndex) + require.EqualValues(s.T(), 0, inputIndex, "The input index should be 0") + + //Check Input if input is Processed + graphQlClient := graphql.NewClient("http://localhost:10000/graphql", nil) + + var resp *readerclient.Input + for resp, err = readerclient.GetInput(ctx, graphQlClient, inputIndex); err != nil; { + config.InfoLogger.Println("Waiting for Input...") + config.InfoLogger.Printf("Error : %v \n", err) + time.Sleep(2 * time.Second) + + } + require.NoError(s.T(), err) + + config.InfoLogger.Printf("Response %v \n", resp) +} + func TestEchoInput(t *testing.T) { + config.InitLogFromEnv() suite.Run(t, new(EchoInputTestSuite)) } diff --git a/internal/deps/deps.go b/internal/deps/deps.go index 746286a7c..d742f9807 100644 --- a/internal/deps/deps.go +++ b/internal/deps/deps.go @@ -61,12 +61,19 @@ func (debug debugLogging) Printf(format string, v ...interface{}) { } func createHook(containerName string, - waitGroup *sync.WaitGroup) []testcontainers.ContainerLifecycleHooks { + finishedWaitGroup *sync.WaitGroup, + startedWaitGroup *sync.WaitGroup) []testcontainers.ContainerLifecycleHooks { return []testcontainers.ContainerLifecycleHooks{ { + PostStarts: []testcontainers.ContainerHook{ + func(ctx context.Context, container testcontainers.Container) error { + startedWaitGroup.Done() + return nil + }, + }, PostTerminates: []testcontainers.ContainerHook{ func(ctx context.Context, container testcontainers.Container) error { - waitGroup.Done() + finishedWaitGroup.Done() return nil }, }, @@ -80,13 +87,15 @@ func createHook(containerName string, // terminate the containers using the Terminate method func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { nolog := debugLogging{} - var waitGroup sync.WaitGroup + var finishedWaitGroup sync.WaitGroup + var startedWaitGroup sync.WaitGroup // wait strategy copied from testcontainers docs postgresWaitStrategy := wait.ForLog("database system is ready to accept connections"). WithOccurrence(numPostgresCheckReadyAttempts). WithPollInterval(pollInterval) + startedWaitGroup.Add(1) postgresReq := testcontainers.ContainerRequest{ Image: depsConfig.PostgresDockerImage, ExposedPorts: []string{strings.Join([]string{ @@ -96,7 +105,7 @@ func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { Env: map[string]string{ "POSTGRES_PASSWORD": depsConfig.PostgresPassword, }, - LifecycleHooks: createHook("rollups-node-dep-postgres", &waitGroup), + LifecycleHooks: createHook("rollups-node-dep-postgres", &finishedWaitGroup, &startedWaitGroup), } postgres, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ @@ -108,8 +117,9 @@ func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { if err != nil { return nil, err } - waitGroup.Add(1) + finishedWaitGroup.Add(1) + startedWaitGroup.Add(1) devNetReq := testcontainers.ContainerRequest{ Image: depsConfig.DevnetDockerImage, ExposedPorts: []string{strings.Join([]string{depsConfig.DevnetPort, ":8545/tcp"}, "")}, @@ -118,7 +128,7 @@ func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { Env: map[string]string{ "ANVIL_IP_ADDR": "0.0.0.0", }, - LifecycleHooks: createHook("rollups-node-dep-devnet", &waitGroup), + LifecycleHooks: createHook("rollups-node-dep-devnet", &finishedWaitGroup, &startedWaitGroup), } devnet, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ @@ -130,11 +140,12 @@ func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { return nil, err } - waitGroup.Add(1) + finishedWaitGroup.Add(1) containers := []testcontainers.Container{postgres, devnet} - return &DepsContainers{containers, &waitGroup}, nil + startedWaitGroup.Wait() + return &DepsContainers{containers, &finishedWaitGroup}, nil } // Terminate terminates all dependencies containers. This method waits for all the containers