github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/cmd/objecttool/testBandwidth.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io" 6 "math/rand" 7 "os" 8 "time" 9 10 "github.com/Cloud-Foundations/Dominator/lib/format" 11 "github.com/Cloud-Foundations/Dominator/lib/log" 12 "github.com/Cloud-Foundations/Dominator/lib/srpc" 13 proto "github.com/Cloud-Foundations/Dominator/proto/objectserver" 14 ) 15 16 func testBandwidthFromServerSubcommand(args []string, 17 logger log.DebugLogger) error { 18 if err := testBandwidthFromServer(); err != nil { 19 return fmt.Errorf("Error testing bandwidth: %s", err) 20 } 21 return nil 22 } 23 24 func testBandwidthToServerSubcommand(args []string, 25 logger log.DebugLogger) error { 26 if err := testBandwidthToServer(); err != nil { 27 return fmt.Errorf("Error testing bandwidth: %s", err) 28 } 29 return nil 30 } 31 32 func testBandwidthFromServer() error { 33 client, err := srpc.DialHTTP("tcp", fmt.Sprintf("%s:%d", 34 *objectServerHostname, *objectServerPortNum), 0) 35 if err != nil { 36 return err 37 } 38 defer client.Close() 39 conn, err := client.Call("ObjectServer.TestBandwidth") 40 if err != nil { 41 return err 42 } 43 defer conn.Close() 44 request := proto.TestBandwidthRequest{ 45 Duration: *testDuration, 46 ChunkSize: *chunkSize, 47 } 48 if err := conn.Encode(&request); err != nil { 49 return err 50 } 51 if err := conn.Flush(); err != nil { 52 return nil 53 } 54 buffer := make([]byte, *chunkSize+1) 55 startTime := time.Now() 56 var totalBytes uint64 57 for { 58 if _, err := io.ReadAtLeast(conn, buffer, len(buffer)); err != nil { 59 return err 60 } 61 totalBytes += uint64(len(buffer)) 62 if buffer[len(buffer)-1] == 0 { 63 break 64 } 65 } 66 localDuration := time.Since(startTime) 67 var response proto.TestBandwidthResponse 68 if err := conn.Decode(&response); err != nil { 69 return err 70 } 71 localSpeed := totalBytes / uint64(localDuration.Seconds()) 72 serverSpeed := totalBytes / uint64(response.ServerDuration.Seconds()) 73 fmt.Fprintf(os.Stderr, 74 "Received %s from server in %s (%s/s), at server: %s (%s/s)\n", 75 format.FormatBytes(totalBytes), 76 format.Duration(localDuration), format.FormatBytes(localSpeed), 77 format.Duration(response.ServerDuration), 78 format.FormatBytes(serverSpeed)) 79 return nil 80 } 81 82 func testBandwidthToServer() error { 83 client, err := srpc.DialHTTP("tcp", fmt.Sprintf("%s:%d", 84 *objectServerHostname, *objectServerPortNum), 0) 85 if err != nil { 86 return err 87 } 88 defer client.Close() 89 conn, err := client.Call("ObjectServer.TestBandwidth") 90 if err != nil { 91 return err 92 } 93 defer conn.Close() 94 request := proto.TestBandwidthRequest{ 95 Duration: *testDuration, 96 ChunkSize: *chunkSize, 97 SendToServer: true, 98 } 99 if err := conn.Encode(&request); err != nil { 100 return err 101 } 102 if err := conn.Flush(); err != nil { 103 return nil 104 } 105 buffer := make([]byte, *chunkSize+1) 106 rand.Read(buffer[:request.ChunkSize]) 107 var totalBytes uint64 108 startTime := time.Now() 109 stopTime := startTime.Add(request.Duration) 110 buffer[len(buffer)-1] = 1 111 for time.Until(stopTime) > 0 { 112 if _, err := conn.Write(buffer); err != nil { 113 return err 114 } 115 totalBytes += uint64(len(buffer)) 116 } 117 buffer[len(buffer)-1] = 0 118 if _, err := conn.Write(buffer); err != nil { 119 return err 120 } 121 totalBytes += uint64(len(buffer)) 122 if err := conn.Flush(); err != nil { 123 return nil 124 } 125 localDuration := time.Since(startTime) 126 var response proto.TestBandwidthResponse 127 if err := conn.Decode(&response); err != nil { 128 return err 129 } 130 localSpeed := totalBytes / uint64(localDuration.Seconds()) 131 serverSpeed := totalBytes / uint64(response.ServerDuration.Seconds()) 132 fmt.Fprintf(os.Stderr, 133 "Sent %s to server in %s (%s/s), at server: %s (%s/s)\n", 134 format.FormatBytes(totalBytes), 135 format.Duration(localDuration), format.FormatBytes(localSpeed), 136 format.Duration(response.ServerDuration), 137 format.FormatBytes(serverSpeed)) 138 return nil 139 }