Unverified Commit eef7a331 authored by Shihao Xia's avatar Shihao Xia Committed by GitHub

core, miner, rpc, eth: fix goroutine leaks in tests (#24211)

* fix blocking and non-blocking issues

* core: revert change in blockchain.go
Co-authored-by: 's avatarMartin Holst Swende <martin@swende.se>
parent ae45c97d
...@@ -1779,6 +1779,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) { ...@@ -1779,6 +1779,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
SnapshotLimit: 0, // Disable snapshot by default SnapshotLimit: 0, // Disable snapshot by default
} }
) )
defer engine.Close()
if snapshots { if snapshots {
config.SnapshotLimit = 256 config.SnapshotLimit = 256
config.SnapshotWait = true config.SnapshotWait = true
...@@ -1836,25 +1837,25 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) { ...@@ -1836,25 +1837,25 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
} }
defer db.Close() defer db.Close()
chain, err = NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil) newChain, err := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
if err != nil { if err != nil {
t.Fatalf("Failed to recreate chain: %v", err) t.Fatalf("Failed to recreate chain: %v", err)
} }
defer chain.Stop() defer newChain.Stop()
// Iterate over all the remaining blocks and ensure there are no gaps // Iterate over all the remaining blocks and ensure there are no gaps
verifyNoGaps(t, chain, true, canonblocks) verifyNoGaps(t, newChain, true, canonblocks)
verifyNoGaps(t, chain, false, sideblocks) verifyNoGaps(t, newChain, false, sideblocks)
verifyCutoff(t, chain, true, canonblocks, tt.expCanonicalBlocks) verifyCutoff(t, newChain, true, canonblocks, tt.expCanonicalBlocks)
verifyCutoff(t, chain, false, sideblocks, tt.expSidechainBlocks) verifyCutoff(t, newChain, false, sideblocks, tt.expSidechainBlocks)
if head := chain.CurrentHeader(); head.Number.Uint64() != tt.expHeadHeader { if head := newChain.CurrentHeader(); head.Number.Uint64() != tt.expHeadHeader {
t.Errorf("Head header mismatch: have %d, want %d", head.Number, tt.expHeadHeader) t.Errorf("Head header mismatch: have %d, want %d", head.Number, tt.expHeadHeader)
} }
if head := chain.CurrentFastBlock(); head.NumberU64() != tt.expHeadFastBlock { if head := newChain.CurrentFastBlock(); head.NumberU64() != tt.expHeadFastBlock {
t.Errorf("Head fast block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadFastBlock) t.Errorf("Head fast block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadFastBlock)
} }
if head := chain.CurrentBlock(); head.NumberU64() != tt.expHeadBlock { if head := newChain.CurrentBlock(); head.NumberU64() != tt.expHeadBlock {
t.Errorf("Head block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadBlock) t.Errorf("Head block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadBlock)
} }
if frozen, err := db.(freezer).Ancients(); err != nil { if frozen, err := db.(freezer).Ancients(); err != nil {
......
...@@ -364,6 +364,7 @@ func testSequentialAnnouncements(t *testing.T, light bool) { ...@@ -364,6 +364,7 @@ func testSequentialAnnouncements(t *testing.T, light bool) {
hashes, blocks := makeChain(targetBlocks, 0, genesis) hashes, blocks := makeChain(targetBlocks, 0, genesis)
tester := newTester(light) tester := newTester(light)
defer tester.fetcher.Stop()
headerFetcher := tester.makeHeaderFetcher("valid", blocks, -gatherSlack) headerFetcher := tester.makeHeaderFetcher("valid", blocks, -gatherSlack)
bodyFetcher := tester.makeBodyFetcher("valid", blocks, 0) bodyFetcher := tester.makeBodyFetcher("valid", blocks, 0)
...@@ -743,7 +744,7 @@ func testInvalidNumberAnnouncement(t *testing.T, light bool) { ...@@ -743,7 +744,7 @@ func testInvalidNumberAnnouncement(t *testing.T, light bool) {
badBodyFetcher := tester.makeBodyFetcher("bad", blocks, 0) badBodyFetcher := tester.makeBodyFetcher("bad", blocks, 0)
imported := make(chan interface{}) imported := make(chan interface{})
announced := make(chan interface{}) announced := make(chan interface{}, 2)
tester.fetcher.importedHook = func(header *types.Header, block *types.Block) { tester.fetcher.importedHook = func(header *types.Header, block *types.Block) {
if light { if light {
if header == nil { if header == nil {
...@@ -806,6 +807,7 @@ func TestEmptyBlockShortCircuit(t *testing.T) { ...@@ -806,6 +807,7 @@ func TestEmptyBlockShortCircuit(t *testing.T) {
hashes, blocks := makeChain(32, 0, genesis) hashes, blocks := makeChain(32, 0, genesis)
tester := newTester(false) tester := newTester(false)
defer tester.fetcher.Stop()
headerFetcher := tester.makeHeaderFetcher("valid", blocks, -gatherSlack) headerFetcher := tester.makeHeaderFetcher("valid", blocks, -gatherSlack)
bodyFetcher := tester.makeBodyFetcher("valid", blocks, 0) bodyFetcher := tester.makeBodyFetcher("valid", blocks, 0)
......
...@@ -48,6 +48,7 @@ func TestBuildSchema(t *testing.T) { ...@@ -48,6 +48,7 @@ func TestBuildSchema(t *testing.T) {
conf := node.DefaultConfig conf := node.DefaultConfig
conf.DataDir = ddir conf.DataDir = ddir
stack, err := node.New(&conf) stack, err := node.New(&conf)
defer stack.Close()
if err != nil { if err != nil {
t.Fatalf("could not create new node: %v", err) t.Fatalf("could not create new node: %v", err)
} }
......
...@@ -83,20 +83,20 @@ func TestNatto(t *testing.T) { ...@@ -83,20 +83,20 @@ func TestNatto(t *testing.T) {
err := jsre.Exec("test.js") err := jsre.Exec("test.js")
if err != nil { if err != nil {
t.Errorf("expected no error, got %v", err) t.Fatalf("expected no error, got %v", err)
} }
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
val, err := jsre.Run("msg") val, err := jsre.Run("msg")
if err != nil { if err != nil {
t.Errorf("expected no error, got %v", err) t.Fatalf("expected no error, got %v", err)
} }
if val.ExportType().Kind() != reflect.String { if val.ExportType().Kind() != reflect.String {
t.Errorf("expected string value, got %v", val) t.Fatalf("expected string value, got %v", val)
} }
exp := "testMsg" exp := "testMsg"
got := val.ToString().String() got := val.ToString().String()
if exp != got { if exp != got {
t.Errorf("expected '%v', got '%v'", exp, got) t.Fatalf("expected '%v', got '%v'", exp, got)
} }
jsre.Stop(false) jsre.Stop(false)
} }
......
...@@ -80,7 +80,8 @@ func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) ...@@ -80,7 +80,8 @@ func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent)
} }
func TestMiner(t *testing.T) { func TestMiner(t *testing.T) {
miner, mux := createMiner(t) miner, mux, cleanup := createMiner(t)
defer cleanup(false)
miner.Start(common.HexToAddress("0x12345")) miner.Start(common.HexToAddress("0x12345"))
waitForMiningState(t, miner, true) waitForMiningState(t, miner, true)
// Start the downloader // Start the downloader
...@@ -107,7 +108,8 @@ func TestMiner(t *testing.T) { ...@@ -107,7 +108,8 @@ func TestMiner(t *testing.T) {
// An initial FailedEvent should allow mining to stop on a subsequent // An initial FailedEvent should allow mining to stop on a subsequent
// downloader StartEvent. // downloader StartEvent.
func TestMinerDownloaderFirstFails(t *testing.T) { func TestMinerDownloaderFirstFails(t *testing.T) {
miner, mux := createMiner(t) miner, mux, cleanup := createMiner(t)
defer cleanup(false)
miner.Start(common.HexToAddress("0x12345")) miner.Start(common.HexToAddress("0x12345"))
waitForMiningState(t, miner, true) waitForMiningState(t, miner, true)
// Start the downloader // Start the downloader
...@@ -138,8 +140,8 @@ func TestMinerDownloaderFirstFails(t *testing.T) { ...@@ -138,8 +140,8 @@ func TestMinerDownloaderFirstFails(t *testing.T) {
} }
func TestMinerStartStopAfterDownloaderEvents(t *testing.T) { func TestMinerStartStopAfterDownloaderEvents(t *testing.T) {
miner, mux := createMiner(t) miner, mux, cleanup := createMiner(t)
defer cleanup(false)
miner.Start(common.HexToAddress("0x12345")) miner.Start(common.HexToAddress("0x12345"))
waitForMiningState(t, miner, true) waitForMiningState(t, miner, true)
// Start the downloader // Start the downloader
...@@ -161,7 +163,8 @@ func TestMinerStartStopAfterDownloaderEvents(t *testing.T) { ...@@ -161,7 +163,8 @@ func TestMinerStartStopAfterDownloaderEvents(t *testing.T) {
} }
func TestStartWhileDownload(t *testing.T) { func TestStartWhileDownload(t *testing.T) {
miner, mux := createMiner(t) miner, mux, cleanup := createMiner(t)
defer cleanup(false)
waitForMiningState(t, miner, false) waitForMiningState(t, miner, false)
miner.Start(common.HexToAddress("0x12345")) miner.Start(common.HexToAddress("0x12345"))
waitForMiningState(t, miner, true) waitForMiningState(t, miner, true)
...@@ -174,16 +177,19 @@ func TestStartWhileDownload(t *testing.T) { ...@@ -174,16 +177,19 @@ func TestStartWhileDownload(t *testing.T) {
} }
func TestStartStopMiner(t *testing.T) { func TestStartStopMiner(t *testing.T) {
miner, _ := createMiner(t) miner, _, cleanup := createMiner(t)
defer cleanup(false)
waitForMiningState(t, miner, false) waitForMiningState(t, miner, false)
miner.Start(common.HexToAddress("0x12345")) miner.Start(common.HexToAddress("0x12345"))
waitForMiningState(t, miner, true) waitForMiningState(t, miner, true)
miner.Stop() miner.Stop()
waitForMiningState(t, miner, false) waitForMiningState(t, miner, false)
} }
func TestCloseMiner(t *testing.T) { func TestCloseMiner(t *testing.T) {
miner, _ := createMiner(t) miner, _, cleanup := createMiner(t)
defer cleanup(true)
waitForMiningState(t, miner, false) waitForMiningState(t, miner, false)
miner.Start(common.HexToAddress("0x12345")) miner.Start(common.HexToAddress("0x12345"))
waitForMiningState(t, miner, true) waitForMiningState(t, miner, true)
...@@ -195,7 +201,8 @@ func TestCloseMiner(t *testing.T) { ...@@ -195,7 +201,8 @@ func TestCloseMiner(t *testing.T) {
// TestMinerSetEtherbase checks that etherbase becomes set even if mining isn't // TestMinerSetEtherbase checks that etherbase becomes set even if mining isn't
// possible at the moment // possible at the moment
func TestMinerSetEtherbase(t *testing.T) { func TestMinerSetEtherbase(t *testing.T) {
miner, mux := createMiner(t) miner, mux, cleanup := createMiner(t)
defer cleanup(false)
// Start with a 'bad' mining address // Start with a 'bad' mining address
miner.Start(common.HexToAddress("0xdead")) miner.Start(common.HexToAddress("0xdead"))
waitForMiningState(t, miner, true) waitForMiningState(t, miner, true)
...@@ -230,7 +237,7 @@ func waitForMiningState(t *testing.T, m *Miner, mining bool) { ...@@ -230,7 +237,7 @@ func waitForMiningState(t *testing.T, m *Miner, mining bool) {
t.Fatalf("Mining() == %t, want %t", state, mining) t.Fatalf("Mining() == %t, want %t", state, mining)
} }
func createMiner(t *testing.T) (*Miner, *event.TypeMux) { func createMiner(t *testing.T) (*Miner, *event.TypeMux, func(skipMiner bool)) {
// Create Ethash config // Create Ethash config
config := Config{ config := Config{
Etherbase: common.HexToAddress("123456789"), Etherbase: common.HexToAddress("123456789"),
...@@ -259,5 +266,14 @@ func createMiner(t *testing.T) (*Miner, *event.TypeMux) { ...@@ -259,5 +266,14 @@ func createMiner(t *testing.T) (*Miner, *event.TypeMux) {
// Create event Mux // Create event Mux
mux := new(event.TypeMux) mux := new(event.TypeMux)
// Create Miner // Create Miner
return New(backend, &config, chainConfig, mux, engine, nil, merger), mux miner := New(backend, &config, chainConfig, mux, engine, nil, merger)
cleanup := func(skipMiner bool) {
bc.Stop()
engine.Close()
pool.Stop()
if !skipMiner {
miner.Close()
}
}
return miner, mux, cleanup
} }
...@@ -382,7 +382,7 @@ func testRegenerateMiningBlock(t *testing.T, chainConfig *params.ChainConfig, en ...@@ -382,7 +382,7 @@ func testRegenerateMiningBlock(t *testing.T, chainConfig *params.ChainConfig, en
w, b := newTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0) w, b := newTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0)
defer w.close() defer w.close()
var taskCh = make(chan struct{}) var taskCh = make(chan struct{}, 3)
taskIndex := 0 taskIndex := 0
w.newTaskHook = func(task *task) { w.newTaskHook = func(task *task) {
......
...@@ -393,7 +393,7 @@ func TestLifecycleTerminationGuarantee(t *testing.T) { ...@@ -393,7 +393,7 @@ func TestLifecycleTerminationGuarantee(t *testing.T) {
// on the given prefix // on the given prefix
func TestRegisterHandler_Successful(t *testing.T) { func TestRegisterHandler_Successful(t *testing.T) {
node := createNode(t, 7878, 7979) node := createNode(t, 7878, 7979)
defer node.Close()
// create and mount handler // create and mount handler
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("success")) w.Write([]byte("success"))
......
...@@ -615,6 +615,7 @@ func TestClientReconnect(t *testing.T) { ...@@ -615,6 +615,7 @@ func TestClientReconnect(t *testing.T) {
// Start a server and corresponding client. // Start a server and corresponding client.
s1, l1 := startServer("127.0.0.1:0") s1, l1 := startServer("127.0.0.1:0")
client, err := DialContext(ctx, "ws://"+l1.Addr().String()) client, err := DialContext(ctx, "ws://"+l1.Addr().String())
defer client.Close()
if err != nil { if err != nil {
t.Fatal("can't dial", err) t.Fatal("can't dial", err)
} }
......
...@@ -256,6 +256,9 @@ func TestSignTx(t *testing.T) { ...@@ -256,6 +256,9 @@ func TestSignTx(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if len(list) == 0 {
t.Fatal("Unexpected empty list")
}
a := common.NewMixedcaseAddress(list[0]) a := common.NewMixedcaseAddress(list[0])
methodSig := "test(uint)" methodSig := "test(uint)"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment