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 }