github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/cmd/devp2p/internal/ethtest/suite_test.go (about)

     1  // Copyright 2021 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // go-ethereum is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package ethtest
    18  
    19  import (
    20  	crand "crypto/rand"
    21  	"fmt"
    22  	"os"
    23  	"path/filepath"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/ethereum/go-ethereum/common"
    28  	"github.com/ethereum/go-ethereum/common/hexutil"
    29  	"github.com/ethereum/go-ethereum/eth"
    30  	"github.com/ethereum/go-ethereum/eth/catalyst"
    31  	"github.com/ethereum/go-ethereum/eth/ethconfig"
    32  	"github.com/ethereum/go-ethereum/internal/utesting"
    33  	"github.com/ethereum/go-ethereum/node"
    34  	"github.com/ethereum/go-ethereum/p2p"
    35  )
    36  
    37  func makeJWTSecret() (string, [32]byte, error) {
    38  	var secret [32]byte
    39  	if _, err := crand.Read(secret[:]); err != nil {
    40  		return "", secret, fmt.Errorf("failed to create jwt secret: %v", err)
    41  	}
    42  	jwtPath := filepath.Join(os.TempDir(), "jwt_secret")
    43  	if err := os.WriteFile(jwtPath, []byte(hexutil.Encode(secret[:])), 0600); err != nil {
    44  		return "", secret, fmt.Errorf("failed to prepare jwt secret file: %v", err)
    45  	}
    46  	return jwtPath, secret, nil
    47  }
    48  
    49  func TestEthSuite(t *testing.T) {
    50  	jwtPath, secret, err := makeJWTSecret()
    51  	if err != nil {
    52  		t.Fatalf("could not make jwt secret: %v", err)
    53  	}
    54  	geth, err := runGeth("./testdata", jwtPath)
    55  	if err != nil {
    56  		t.Fatalf("could not run geth: %v", err)
    57  	}
    58  	defer geth.Close()
    59  
    60  	suite, err := NewSuite(geth.Server().Self(), "./testdata", geth.HTTPAuthEndpoint(), common.Bytes2Hex(secret[:]))
    61  	if err != nil {
    62  		t.Fatalf("could not create new test suite: %v", err)
    63  	}
    64  	for _, test := range suite.EthTests() {
    65  		t.Run(test.Name, func(t *testing.T) {
    66  			if test.Slow && testing.Short() {
    67  				t.Skipf("%s: skipping in -short mode", test.Name)
    68  			}
    69  			result := utesting.RunTests([]utesting.Test{{Name: test.Name, Fn: test.Fn}}, os.Stdout)
    70  			if result[0].Failed {
    71  				t.Fatal()
    72  			}
    73  		})
    74  	}
    75  }
    76  
    77  func TestSnapSuite(t *testing.T) {
    78  	jwtPath, secret, err := makeJWTSecret()
    79  	if err != nil {
    80  		t.Fatalf("could not make jwt secret: %v", err)
    81  	}
    82  	geth, err := runGeth("./testdata", jwtPath)
    83  	if err != nil {
    84  		t.Fatalf("could not run geth: %v", err)
    85  	}
    86  	defer geth.Close()
    87  
    88  	suite, err := NewSuite(geth.Server().Self(), "./testdata", geth.HTTPAuthEndpoint(), common.Bytes2Hex(secret[:]))
    89  	if err != nil {
    90  		t.Fatalf("could not create new test suite: %v", err)
    91  	}
    92  	for _, test := range suite.SnapTests() {
    93  		t.Run(test.Name, func(t *testing.T) {
    94  			result := utesting.RunTests([]utesting.Test{{Name: test.Name, Fn: test.Fn}}, os.Stdout)
    95  			if result[0].Failed {
    96  				t.Fatal()
    97  			}
    98  		})
    99  	}
   100  }
   101  
   102  // runGeth creates and starts a geth node
   103  func runGeth(dir string, jwtPath string) (*node.Node, error) {
   104  	stack, err := node.New(&node.Config{
   105  		AuthAddr: "127.0.0.1",
   106  		AuthPort: 0,
   107  		P2P: p2p.Config{
   108  			ListenAddr:  "127.0.0.1:0",
   109  			NoDiscovery: true,
   110  			MaxPeers:    10, // in case a test requires multiple connections, can be changed in the future
   111  			NoDial:      true,
   112  		},
   113  		JWTSecret: jwtPath,
   114  	})
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  
   119  	err = setupGeth(stack, dir)
   120  	if err != nil {
   121  		stack.Close()
   122  		return nil, err
   123  	}
   124  	if err = stack.Start(); err != nil {
   125  		stack.Close()
   126  		return nil, err
   127  	}
   128  	return stack, nil
   129  }
   130  
   131  func setupGeth(stack *node.Node, dir string) error {
   132  	chain, err := NewChain(dir)
   133  	if err != nil {
   134  		return err
   135  	}
   136  	backend, err := eth.New(stack, &ethconfig.Config{
   137  		Genesis:        &chain.genesis,
   138  		NetworkId:      chain.genesis.Config.ChainID.Uint64(), // 19763
   139  		DatabaseCache:  10,
   140  		TrieCleanCache: 10,
   141  		TrieDirtyCache: 16,
   142  		TrieTimeout:    60 * time.Minute,
   143  		SnapshotCache:  10,
   144  	})
   145  	if err != nil {
   146  		return err
   147  	}
   148  	if err := catalyst.Register(stack, backend); err != nil {
   149  		return fmt.Errorf("failed to register catalyst service: %v", err)
   150  	}
   151  	_, err = backend.BlockChain().InsertChain(chain.blocks[1:])
   152  	return err
   153  }