Skip to content
This repository has been archived by the owner on Sep 23, 2024. It is now read-only.

Introduce unit tests and corresponding GH workflow #19

Merged
merged 16 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/e2e.yaml → .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ on: # yamllint disable-line rule:truthy

jobs:
execution:
name: "Execution"
runs-on: ubuntu-latest
env:
CI_VERBOSE: true
Expand Down
38 changes: 38 additions & 0 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Unit Tests
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
workflow_call:
outputs:
workflow_output:
description: "Unit tests output"
value: ${{ jobs.go_test.outputs.test_output_failure }}

jobs:
go_test:
name: Execution
runs-on: ubuntu-latest
outputs:
test_output_failure: ${{ steps.run_tests_failure.outputs.test_output }}
steps:
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: 1.21.x

- name: Checkout Code
uses: actions/checkout@v3
with:
submodules: recursive
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis

- name: Run Go Test
run: make unit-tests

- name: Run Go Test Failed
if: failure()
id: run_tests_failure
run: echo "test_output=false" >> $GITHUB_OUTPUT
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
dist
docker/data
docker/data
coverage.out
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ stop-docker: check-docker
destroy-docker: check-docker
install-linter: check-go check-curl
lint: check-go
unit-tests: check-go
e2e-tests: check-go

ARCH := $(shell uname -m)

Expand Down Expand Up @@ -104,3 +106,7 @@ help: ## Prints the help
.PHONY: e2e-tests
e2e-tests: ## Runs E2E tests
go test -v -timeout=30m github.com/0xPolygon/beethoven/test

.PHONY: unit-tests
unit-tests: ## Runs unit tests
go test -v -timeout=5m -race -shuffle=on -coverprofile coverage.out `go list ./... | grep -v test`
2 changes: 1 addition & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
"github.com/0xPolygon/beethoven/config"
"github.com/0xPolygon/beethoven/db"
"github.com/0xPolygon/beethoven/etherman"
"github.com/0xPolygon/beethoven/pkg/network"
"github.com/0xPolygon/beethoven/network"
"github.com/0xPolygon/beethoven/rpc"
)

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/ethereum/go-ethereum v1.12.0
github.com/gobuffalo/packr/v2 v2.8.3
github.com/jackc/pgx/v4 v4.18.1
github.com/jackc/pgconn v1.14.1
github.com/mitchellh/mapstructure v1.5.0
github.com/prometheus/client_golang v1.17.0
github.com/rubenv/sql-migrate v1.5.2
Expand Down Expand Up @@ -64,7 +65,6 @@ require (
github.com/iden3/go-iden3-crypto v0.0.15 // indirect
github.com/invopop/jsonschema v0.7.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.14.1 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
Expand Down
File renamed without changes.
59 changes: 59 additions & 0 deletions network/network_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package network

import (
"fmt"
"net"
"testing"

"github.com/stretchr/testify/require"
)

func TestResolveAddr(t *testing.T) {
t.Parallel()

tcpAddrBuilder := func(t *testing.T, address string) *net.TCPAddr {
tcpAddr, err := net.ResolveTCPAddr("", address)
require.NoError(t, err)

return tcpAddr
}

cases := []struct {
name string
address string
defaultIP string
errMsg string
}{
{
name: "incorrect address",
address: "Foo Bar",
errMsg: "failed to parse addr",
},
{
name: "only port provided",
address: ":8080",
defaultIP: "127.0.0.1",
},
{
name: "both address and port provided",
address: "0.0.0.0:9000",
defaultIP: "",
},
}

for _, c := range cases {
c := c
t.Run(c.name, func(t *testing.T) {
t.Parallel()

ipAddr, err := ResolveAddr(c.address, c.defaultIP)
if c.errMsg != "" {
require.ErrorContains(t, err, c.errMsg)
} else {
require.NoError(t, err)
expectedIPAddr := tcpAddrBuilder(t, fmt.Sprintf("%s%s", c.defaultIP, c.address))
require.Equal(t, expectedIPAddr, ipAddr)
}
})
}
}
4 changes: 4 additions & 0 deletions rpc/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ type EthTxManager interface {
type ZkEVMClientInterface interface {
BatchByNumber(ctx context.Context, number *big.Int) (*types.Batch, error)
}

type ZkEVMClientClientCreator interface {
NewClient(rpc string) ZkEVMClientInterface
}
52 changes: 33 additions & 19 deletions rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,22 @@ const (

type FullNodeRPCs map[common.Address]string

var _ ZkEVMClientClientCreator = (*zkEVMClientCreator)(nil)

type zkEVMClientCreator struct{}

func (zc *zkEVMClientCreator) NewClient(rpc string) ZkEVMClientInterface {
return client.NewClient(rpc)
}

// InteropEndpoints contains implementations for the "interop" RPC endpoints
type InteropEndpoints struct {
db DBInterface
etherman EthermanInterface
interopAdminAddr common.Address
fullNodeRPCs FullNodeRPCs
ethTxManager EthTxManager
db DBInterface
etherman EthermanInterface
interopAdminAddr common.Address
fullNodeRPCs FullNodeRPCs
ethTxManager EthTxManager
zkEVMClientCreator ZkEVMClientClientCreator
}

// NewInteropEndpoints returns InteropEndpoints
Expand All @@ -39,11 +48,12 @@ func NewInteropEndpoints(
ethTxManager EthTxManager,
) *InteropEndpoints {
return &InteropEndpoints{
db: db,
interopAdminAddr: interopAdminAddr,
etherman: etherman,
fullNodeRPCs: fullNodeRPCs,
ethTxManager: ethTxManager,
db: db,
interopAdminAddr: interopAdminAddr,
etherman: etherman,
fullNodeRPCs: fullNodeRPCs,
ethTxManager: ethTxManager,
zkEVMClientCreator: &zkEVMClientCreator{},
}
}

Expand Down Expand Up @@ -92,7 +102,7 @@ func (i *InteropEndpoints) SendTx(signedTx tx.SignedTx) (interface{}, types.Erro
// Check expected root vs root from the managed full node
// TODO: go stateless, depends on https://github.com/0xPolygonHermez/zkevm-prover/issues/581
// when this happens we should go async from here, since processing all the batches could take a lot of time
zkEVMClient := client.NewClient(i.fullNodeRPCs[signedTx.Tx.L1Contract])
zkEVMClient := i.zkEVMClientCreator.NewClient(i.fullNodeRPCs[signedTx.Tx.L1Contract])
batch, err := zkEVMClient.BatchByNumber(
ctx,
big.NewInt(int64(signedTx.Tx.NewVerifiedBatch)),
Expand All @@ -103,7 +113,7 @@ func (i *InteropEndpoints) SendTx(signedTx tx.SignedTx) (interface{}, types.Erro

if batch.StateRoot != signedTx.Tx.ZKP.NewStateRoot || batch.LocalExitRoot != signedTx.Tx.ZKP.NewLocalExitRoot {
return "0x0", types.NewRPCError(types.DefaultErrorCode, fmt.Sprintf(
"Missmatch detected, expected local exit root: %s actual: %s. expected state root: %s actual: %s",
"Mismatch detected, expected local exit root: %s actual: %s. expected state root: %s actual: %s",
signedTx.Tx.ZKP.NewLocalExitRoot.Hex(),
batch.LocalExitRoot.Hex(),
signedTx.Tx.ZKP.NewStateRoot.Hex(),
Expand Down Expand Up @@ -135,22 +145,26 @@ func (i *InteropEndpoints) GetTxStatus(hash common.Hash) (result interface{}, er
dbTx, innerErr := i.db.BeginStateTransaction(ctx)
if innerErr != nil {
result = "0x0"
err = types.NewRPCError(types.DefaultErrorCode, fmt.Sprintf("failed to begin dbTx, error: %s", err))
}
err = types.NewRPCError(types.DefaultErrorCode, fmt.Sprintf("failed to begin dbTx, error: %s", innerErr))

res, innerErr := i.ethTxManager.Result(ctx, ethTxManOwner, hash.Hex(), dbTx)
if innerErr != nil {
result = "0x0"
err = types.NewRPCError(types.DefaultErrorCode, fmt.Sprintf("failed to get tx, error: %s", err))
return
}

defer func() {
if innerErr := dbTx.Rollback(ctx); innerErr != nil {
result = "0x0"
err = types.NewRPCError(types.DefaultErrorCode, fmt.Sprintf("failed to rollback dbTx, error: %s", err))
err = types.NewRPCError(types.DefaultErrorCode, fmt.Sprintf("failed to rollback dbTx, error: %s", innerErr))
}
}()

res, innerErr := i.ethTxManager.Result(ctx, ethTxManOwner, hash.Hex(), dbTx)
if innerErr != nil {
result = "0x0"
err = types.NewRPCError(types.DefaultErrorCode, fmt.Sprintf("failed to get tx, error: %s", innerErr))

return
}

result = res.Status.String()

return result, err
Expand Down
Loading