func (tn *TestNode) Upload(lf *LocalFile, dataPieces, parityPieces uint64) (*RemoteFile, error) {
	err := tn.RenterUploadPost(lf.path, "/"+lf.fileName(), dataPieces, parityPieces)
	if err != nil {
		return nil, err
	}
	rf := &RemoteFile{
		siaPath:  lf.fileName(),
		checksum: lf.checksum,
	}
	_, err = tn.FileInfo(rf)
	if err != nil {
		return rf, errors.AddContext(err, "uploaded file is not tracked by the renter")
	}
	return rf, nil
}
Upload uses the node to upload the file.
package siatest
import (
	"fmt"
	"math"
	"path/filepath"
	"reflect"
	"strconv"
	"time"
	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/node/api"
	"github.com/NebulousLabs/errors"
	"github.com/NebulousLabs/fastrand"
)
func (tn *TestNode) DownloadToDisk(rf *RemoteFile, async bool) (*LocalFile, error) {
	fi, err := tn.FileInfo(rf)
	if err != nil {
		return nil, errors.AddContext(err, "failed to retrieve FileInfo")
	}
	fileName := strconv.Itoa(fastrand.Intn(math.MaxInt32))
	dest := filepath.Join(SiaTestingDir, fileName)
	if err := tn.RenterDownloadGet(rf.siaPath, dest, 0, fi.Filesize, async); err != nil {
		return nil, errors.AddContext(err, "failed to download file")
	}
	lf := &LocalFile{
		path:     dest,
		checksum: rf.checksum,
	}
	if async {
		return lf, nil
	}
	if err := lf.checkIntegrity(); err != nil {
		return lf, errors.AddContext(err, "downloaded file's checksum doesn't match")
	}
	return lf, nil
}
func (tn *TestNode) DownloadByStream(rf *RemoteFile) (data []byte, err error) {
	fi, err := tn.FileInfo(rf)
	if err != nil {
		return nil, errors.AddContext(err, "failed to retrieve FileInfo")
	}
	data, err = tn.RenterDownloadHTTPResponseGet(rf.siaPath, 0, fi.Filesize)
	if err == nil && rf.checksum != crypto.HashBytes(data) {
		err = errors.New("downloaded bytes don't match requested data")
	}
	return
}
func (tn *TestNode) Stream(rf *RemoteFile) (data []byte, err error) {
	data, err = tn.RenterStreamGet(rf.siaPath)
	if err == nil && rf.checksum != crypto.HashBytes(data) {
		err = errors.New("downloaded bytes don't match requested data")
	}
	return
}
func (tn *TestNode) StreamPartial(rf *RemoteFile, lf *LocalFile, from, to uint64) (data []byte, err error) {
	data, err = tn.RenterStreamPartialGet(rf.siaPath, from, to)
	if err != nil {
		return
	}
	if uint64(len(data)) != to-from+1 {
		err = fmt.Errorf("length of downloaded data should be %v but was %v",
			to-from+1, len(data))
		return
	}
	if lf != nil {
		var checksum crypto.Hash
		checksum, err = lf.partialChecksum(from, to+1)
		if err != nil {
			err = errors.AddContext(err, "failed to get partial checksum")
			return
		}
		if checksum != crypto.HashBytes(data) {
			err = fmt.Errorf("downloaded bytes don't match requested data %v-%v", from, to)
			return
		}
	}
	return
}
func (tn *TestNode) DownloadInfo(lf *LocalFile, rf *RemoteFile) (*api.DownloadInfo, error) {
	rdq, err := tn.RenterDownloadsGet()
	if err != nil {
		return nil, err
	}
	var di *api.DownloadInfo
	for _, d := range rdq.Downloads {
		if rf.siaPath == d.SiaPath && lf.path == d.Destination {
			di = &d
			break
		}
	}
	if di == nil {
		return nil, errors.New("download info not found")
	}
	if di.Length != di.Filesize {
		err = errors.AddContext(err, "filesize != length")
	}
	if di.Received > di.TotalDataTransferred {
		err = errors.AddContext(err, "received > TotalDataTransferred")
	}
	if di.Completed && di.Received != di.Length {
		err = errors.AddContext(err, "completed == true but received != length")
	}
	return di, err
}
func (tn *TestNode) File(siaPath string) (modules.FileInfo, error) {
	rf, err := tn.RenterFileGet(siaPath)
	if err != nil {
		return rf.File, err
	}
	return rf.File, err
}
func (tn *TestNode) Files() ([]modules.FileInfo, error) {
	rf, err := tn.RenterFilesGet()
	if err != nil {
		return nil, err
	}
	return rf.Files, err
}
func (tn *TestNode) FileInfo(rf *RemoteFile) (modules.FileInfo, error) {
	files, err := tn.Files()
	if err != nil {
		return modules.FileInfo{}, err
	}
	for _, file := range files {
		if file.SiaPath == rf.siaPath {
			return file, nil
		}
	}
	return modules.FileInfo{}, errors.New("file is not tracked by the renter")
}