github.com/decred/dcrlnd@v0.7.6/contractcourt/utils_test.go (about)

     1  package contractcourt
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"runtime/pprof"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/decred/dcrlnd/channeldb"
    14  )
    15  
    16  // timeout implements a test level timeout.
    17  func timeout(t *testing.T) func() {
    18  	done := make(chan struct{})
    19  	go func() {
    20  		select {
    21  		case <-time.After(5 * time.Second):
    22  			pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
    23  
    24  			panic("test timeout")
    25  		case <-done:
    26  		}
    27  	}()
    28  
    29  	return func() {
    30  		close(done)
    31  	}
    32  }
    33  
    34  func copyFile(dest, src string) error {
    35  	s, err := os.Open(src)
    36  	if err != nil {
    37  		return err
    38  	}
    39  	defer s.Close()
    40  
    41  	d, err := os.Create(dest)
    42  	if err != nil {
    43  		return err
    44  	}
    45  
    46  	if _, err := io.Copy(d, s); err != nil {
    47  		d.Close()
    48  		return err
    49  	}
    50  
    51  	return d.Close()
    52  }
    53  
    54  // copyChannelState copies the OpenChannel state by copying the database and
    55  // creating a new struct from it. The copied state and a cleanup function are
    56  // returned.
    57  func copyChannelState(state *channeldb.OpenChannel) (
    58  	*channeldb.OpenChannel, func(), error) {
    59  
    60  	// Make a copy of the DB.
    61  	dbFile := filepath.Join(state.Db.GetParentDB().Path(), "channel.db")
    62  	tempDbPath, err := ioutil.TempDir("", "past-state")
    63  	if err != nil {
    64  		return nil, nil, err
    65  	}
    66  
    67  	cleanup := func() {
    68  		os.RemoveAll(tempDbPath)
    69  	}
    70  
    71  	tempDbFile := filepath.Join(tempDbPath, "channel.db")
    72  	err = copyFile(tempDbFile, dbFile)
    73  	if err != nil {
    74  		cleanup()
    75  		return nil, nil, err
    76  	}
    77  
    78  	newDb, err := channeldb.Open(tempDbPath)
    79  	if err != nil {
    80  		cleanup()
    81  		return nil, nil, err
    82  	}
    83  
    84  	chans, err := newDb.ChannelStateDB().FetchAllChannels()
    85  	if err != nil {
    86  		cleanup()
    87  		return nil, nil, err
    88  	}
    89  
    90  	// We only support DBs with a single channel, for now.
    91  	if len(chans) != 1 {
    92  		cleanup()
    93  		return nil, nil, fmt.Errorf("found %d chans in the db",
    94  			len(chans))
    95  	}
    96  
    97  	return chans[0], cleanup, nil
    98  }