github.com/Cloud-Foundations/Dominator@v0.3.4/cmd/imagetool/testDownloadSpeed.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/ioutil"
     7  	"time"
     8  
     9  	imgclient "github.com/Cloud-Foundations/Dominator/imageserver/client"
    10  	"github.com/Cloud-Foundations/Dominator/lib/filesystem"
    11  	"github.com/Cloud-Foundations/Dominator/lib/format"
    12  	"github.com/Cloud-Foundations/Dominator/lib/hash"
    13  	"github.com/Cloud-Foundations/Dominator/lib/log"
    14  	"github.com/Cloud-Foundations/Dominator/lib/objectserver"
    15  )
    16  
    17  func testDownloadSpeedSubcommand(args []string, logger log.DebugLogger) error {
    18  	if err := testDownloadSpeed(args[0], logger); err != nil {
    19  		return fmt.Errorf("error testing download speed: %s", err)
    20  	}
    21  	return nil
    22  }
    23  
    24  func testDownloadSpeed(imageName string, logger log.Logger) error {
    25  	imageSClient, objClient := getClients()
    26  	isDir, err := imgclient.CheckDirectory(imageSClient, imageName)
    27  	if err != nil {
    28  		return err
    29  	}
    30  	if isDir {
    31  		name, err := imgclient.FindLatestImage(imageSClient, imageName, false)
    32  		if err != nil {
    33  			return err
    34  		} else {
    35  			imageName = name
    36  		}
    37  	}
    38  	startTime := time.Now()
    39  	img, err := getTypedImage(imageName)
    40  	if err != nil {
    41  		return err
    42  	}
    43  	finishedTime := time.Now()
    44  	logger.Printf("downloaded image metadata in %s\n",
    45  		format.Duration(finishedTime.Sub(startTime)))
    46  	hashes := make([]hash.Hash, 0, len(img.FileSystem.InodeTable))
    47  	for _, inode := range img.FileSystem.InodeTable {
    48  		if inode, ok := inode.(*filesystem.RegularInode); ok {
    49  			if inode.Size > 0 {
    50  				hashes = append(hashes, inode.Hash)
    51  			}
    52  		}
    53  	}
    54  	startTime = time.Now()
    55  	objectsReader, err := objClient.GetObjects(hashes)
    56  	if err != nil {
    57  		return err
    58  	}
    59  	defer objectsReader.Close()
    60  	var totalBytes uint64
    61  	buffer := make([]byte, 32<<10)
    62  	for range hashes {
    63  		if length, err := readOneObject(objectsReader, buffer); err != nil {
    64  			return err
    65  		} else {
    66  			totalBytes += length
    67  		}
    68  	}
    69  	finishedTime = time.Now()
    70  	downloadTime := finishedTime.Sub(startTime)
    71  	downloadSpeed := float64(totalBytes) / downloadTime.Seconds()
    72  	logger.Printf("downloaded %s (%d objects) in %s (%s/s)\n",
    73  		format.FormatBytes(totalBytes), len(hashes),
    74  		format.Duration(downloadTime),
    75  		format.FormatBytes(uint64(downloadSpeed)))
    76  	return nil
    77  }
    78  
    79  func readOneObject(objectsReader objectserver.ObjectsReader,
    80  	buffer []byte) (uint64, error) {
    81  	_, reader, err := objectsReader.NextObject()
    82  	if err != nil {
    83  		return 0, err
    84  	}
    85  	defer reader.Close()
    86  	nCopied, err := io.CopyBuffer(ioutil.Discard, reader, buffer)
    87  	return uint64(nCopied), err
    88  }