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: Martin Holst Swende <martin@swende.se>
This commit is contained in:
		
							parent
							
								
									ae45c97d3d
								
							
						
					
					
						commit
						eef7a33135
					
				| @ -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) { | |||||||
| 	} | 	} | ||||||
| 	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) { | |||||||
| 	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) { | |||||||
| 	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) { | |||||||
| 	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) { | |||||||
| 	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) { | |||||||
| 
 | 
 | ||||||
| 	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) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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) { | |||||||
| // 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) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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) { | |||||||
| // 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) { | |||||||
| 	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) { | |||||||
| 	// 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 | |||||||
| 	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) { | |||||||
| // 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) { | |||||||
| 	// 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) { | |||||||
| 	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)" | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user