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