github.com/Oyster-zx/tendermint@v0.34.24-fork/test/e2e/tests/e2e_test.go (about) 1 package e2e_test 2 3 import ( 4 "context" 5 "os" 6 "path/filepath" 7 "sync" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 12 rpchttp "github.com/tendermint/tendermint/rpc/client/http" 13 rpctypes "github.com/tendermint/tendermint/rpc/core/types" 14 e2e "github.com/tendermint/tendermint/test/e2e/pkg" 15 "github.com/tendermint/tendermint/types" 16 ) 17 18 func init() { 19 // This can be used to manually specify a testnet manifest and/or node to 20 // run tests against. The testnet must have been started by the runner first. 21 // os.Setenv("E2E_MANIFEST", "networks/ci.toml") 22 // os.Setenv("E2E_NODE", "validator01") 23 } 24 25 var ( 26 ctx = context.Background() 27 testnetCache = map[string]e2e.Testnet{} 28 testnetCacheMtx = sync.Mutex{} 29 blocksCache = map[string][]*types.Block{} 30 blocksCacheMtx = sync.Mutex{} 31 ) 32 33 // testNode runs tests for testnet nodes. The callback function is given a 34 // single node to test, running as a subtest in parallel with other subtests. 35 // 36 // The testnet manifest must be given as the envvar E2E_MANIFEST. If not set, 37 // these tests are skipped so that they're not picked up during normal unit 38 // test runs. If E2E_NODE is also set, only the specified node is tested, 39 // otherwise all nodes are tested. 40 func testNode(t *testing.T, testFunc func(*testing.T, e2e.Node)) { 41 t.Helper() 42 43 testnet := loadTestnet(t) 44 nodes := testnet.Nodes 45 46 if name := os.Getenv("E2E_NODE"); name != "" { 47 node := testnet.LookupNode(name) 48 require.NotNil(t, node, "node %q not found in testnet %q", name, testnet.Name) 49 nodes = []*e2e.Node{node} 50 } 51 52 for _, node := range nodes { 53 if node.Stateless() { 54 continue 55 } 56 57 node := *node 58 t.Run(node.Name, func(t *testing.T) { 59 t.Parallel() 60 testFunc(t, node) 61 }) 62 } 63 } 64 65 // loadTestnet loads the testnet based on the E2E_MANIFEST envvar. 66 func loadTestnet(t *testing.T) e2e.Testnet { 67 t.Helper() 68 69 manifestFile := os.Getenv("E2E_MANIFEST") 70 if manifestFile == "" { 71 t.Skip("E2E_MANIFEST not set, not an end-to-end test run") 72 } 73 if !filepath.IsAbs(manifestFile) { 74 manifestFile = filepath.Join("..", manifestFile) 75 } 76 77 testnetCacheMtx.Lock() 78 defer testnetCacheMtx.Unlock() 79 if testnet, ok := testnetCache[manifestFile]; ok { 80 return testnet 81 } 82 m, err := e2e.LoadManifest(manifestFile) 83 require.NoError(t, err) 84 ifd, err := e2e.NewDockerInfrastructureData(m) 85 require.NoError(t, err) 86 87 testnet, err := e2e.LoadTestnet(m, manifestFile, ifd) 88 require.NoError(t, err) 89 testnetCache[manifestFile] = *testnet 90 return *testnet 91 } 92 93 // fetchBlockChain fetches a complete, up-to-date block history from 94 // the freshest testnet archive node. 95 func fetchBlockChain(t *testing.T) []*types.Block { 96 t.Helper() 97 98 testnet := loadTestnet(t) 99 100 // Find the freshest archive node 101 var ( 102 client *rpchttp.HTTP 103 status *rpctypes.ResultStatus 104 ) 105 for _, node := range testnet.ArchiveNodes() { 106 c, err := node.Client() 107 require.NoError(t, err) 108 s, err := c.Status(ctx) 109 require.NoError(t, err) 110 if status == nil || s.SyncInfo.LatestBlockHeight > status.SyncInfo.LatestBlockHeight { 111 client = c 112 status = s 113 } 114 } 115 require.NotNil(t, client, "couldn't find an archive node") 116 117 // Fetch blocks. Look for existing block history in the block cache, and 118 // extend it with any new blocks that have been produced. 119 blocksCacheMtx.Lock() 120 defer blocksCacheMtx.Unlock() 121 122 from := status.SyncInfo.EarliestBlockHeight 123 to := status.SyncInfo.LatestBlockHeight 124 blocks, ok := blocksCache[testnet.Name] 125 if !ok { 126 blocks = make([]*types.Block, 0, to-from+1) 127 } 128 if len(blocks) > 0 { 129 from = blocks[len(blocks)-1].Height + 1 130 } 131 132 for h := from; h <= to; h++ { 133 resp, err := client.Block(ctx, &(h)) 134 require.NoError(t, err) 135 require.NotNil(t, resp.Block) 136 require.Equal(t, h, resp.Block.Height, "unexpected block height %v", resp.Block.Height) 137 blocks = append(blocks, resp.Block) 138 } 139 require.NotEmpty(t, blocks, "blockchain does not contain any blocks") 140 blocksCache[testnet.Name] = blocks 141 142 return blocks 143 }