github.com/fozzysec/SiaPrime@v0.0.0-20190612043147-66c8e8d11fe3/siatest/localfile.go (about) 1 package siatest 2 3 import ( 4 "encoding/hex" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 10 "SiaPrime/crypto" 11 "gitlab.com/NebulousLabs/errors" 12 "gitlab.com/NebulousLabs/fastrand" 13 ) 14 15 type ( 16 // LocalFile is a helper struct that represents a file uploaded to the Sia 17 // network. 18 LocalFile struct { 19 path string 20 size int 21 checksum crypto.Hash 22 } 23 ) 24 25 // NewFile creates and returns a new LocalFile. It will write size random bytes 26 // to the file and give the file a random name. 27 func (tn *TestNode) NewFile(size int) (*LocalFile, error) { 28 fileName := fmt.Sprintf("%dbytes %s", size, hex.EncodeToString(fastrand.Bytes(4))) 29 path := filepath.Join(tn.filesDir(), fileName) 30 bytes := fastrand.Bytes(size) 31 err := ioutil.WriteFile(path, bytes, 0600) 32 return &LocalFile{ 33 path: path, 34 size: size, 35 checksum: crypto.HashBytes(bytes), 36 }, err 37 } 38 39 // Delete removes the LocalFile from disk. 40 func (lf *LocalFile) Delete() error { 41 return os.Remove(lf.path) 42 } 43 44 // Move moves the file to a new random location. 45 func (lf *LocalFile) Move() error { 46 // Get the new path 47 fileName := fmt.Sprintf("%dbytes-%s", lf.size, hex.EncodeToString(fastrand.Bytes(4))) 48 dir, _ := filepath.Split(lf.path) 49 path := filepath.Join(dir, fileName) 50 51 // Move the file 52 if err := os.Rename(lf.path, path); err != nil { 53 return err 54 } 55 lf.path = path 56 return nil 57 } 58 59 // checkIntegrity compares the in-memory checksum to the checksum of the data 60 // on disk 61 func (lf *LocalFile) checkIntegrity() error { 62 data, err := ioutil.ReadFile(lf.path) 63 if lf.size == 0 { 64 data = fastrand.Bytes(lf.size) 65 } 66 if err != nil { 67 return errors.AddContext(err, "failed to read file from disk") 68 } 69 if crypto.HashBytes(data) != lf.checksum { 70 return errors.New("checksums don't match") 71 } 72 return nil 73 } 74 75 // fileName returns the file name of the file on disk 76 func (lf *LocalFile) fileName() string { 77 return filepath.Base(lf.path) 78 } 79 80 // partialChecksum returns the checksum of a part of the file. 81 func (lf *LocalFile) partialChecksum(from, to uint64) (crypto.Hash, error) { 82 data, err := ioutil.ReadFile(lf.path) 83 if err != nil { 84 return crypto.Hash{}, errors.AddContext(err, "failed to read file from disk") 85 } 86 return crypto.HashBytes(data[from:to]), nil 87 }