mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(cli): add json output to coder speedtest (#13475)
This commit is contained in:
+58
-11
@@ -6,7 +6,6 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/jedib0t/go-pretty/v6/table"
|
||||
"golang.org/x/xerrors"
|
||||
tsspeedtest "tailscale.com/net/speedtest"
|
||||
"tailscale.com/wgengine/capture"
|
||||
@@ -19,12 +18,51 @@ import (
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
type SpeedtestResult struct {
|
||||
Overall SpeedtestResultInterval `json:"overall"`
|
||||
Intervals []SpeedtestResultInterval `json:"intervals"`
|
||||
}
|
||||
|
||||
type SpeedtestResultInterval struct {
|
||||
StartTimeSeconds float64 `json:"start_time_seconds"`
|
||||
EndTimeSeconds float64 `json:"end_time_seconds"`
|
||||
ThroughputMbits float64 `json:"throughput_mbits"`
|
||||
}
|
||||
|
||||
type speedtestTableItem struct {
|
||||
Interval string `table:"Interval,nosort"`
|
||||
Throughput string `table:"Throughput"`
|
||||
}
|
||||
|
||||
func (r *RootCmd) speedtest() *serpent.Command {
|
||||
var (
|
||||
direct bool
|
||||
duration time.Duration
|
||||
direction string
|
||||
pcapFile string
|
||||
formatter = cliui.NewOutputFormatter(
|
||||
cliui.ChangeFormatterData(cliui.TableFormat([]speedtestTableItem{}, []string{"Interval", "Throughput"}), func(data any) (any, error) {
|
||||
res, ok := data.(SpeedtestResult)
|
||||
if !ok {
|
||||
// This should never happen
|
||||
return "", xerrors.Errorf("expected speedtestResult, got %T", data)
|
||||
}
|
||||
tableRows := make([]any, len(res.Intervals)+2)
|
||||
for i, r := range res.Intervals {
|
||||
tableRows[i] = speedtestTableItem{
|
||||
Interval: fmt.Sprintf("%.2f-%.2f sec", r.StartTimeSeconds, r.EndTimeSeconds),
|
||||
Throughput: fmt.Sprintf("%.4f Mbits/sec", r.ThroughputMbits),
|
||||
}
|
||||
}
|
||||
tableRows[len(res.Intervals)] = cliui.TableSeparator{}
|
||||
tableRows[len(res.Intervals)+1] = speedtestTableItem{
|
||||
Interval: fmt.Sprintf("%.2f-%.2f sec", res.Overall.StartTimeSeconds, res.Overall.EndTimeSeconds),
|
||||
Throughput: fmt.Sprintf("%.4f Mbits/sec", res.Overall.ThroughputMbits),
|
||||
}
|
||||
return tableRows, nil
|
||||
}),
|
||||
cliui.JSONFormat(),
|
||||
)
|
||||
)
|
||||
client := new(codersdk.Client)
|
||||
cmd := &serpent.Command{
|
||||
@@ -124,24 +162,32 @@ func (r *RootCmd) speedtest() *serpent.Command {
|
||||
default:
|
||||
return xerrors.Errorf("invalid direction: %q", direction)
|
||||
}
|
||||
cliui.Infof(inv.Stdout, "Starting a %ds %s test...", int(duration.Seconds()), tsDir)
|
||||
cliui.Infof(inv.Stderr, "Starting a %ds %s test...", int(duration.Seconds()), tsDir)
|
||||
results, err := conn.Speedtest(ctx, tsDir, duration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tableWriter := cliui.Table()
|
||||
tableWriter.AppendHeader(table.Row{"Interval", "Throughput"})
|
||||
var outputResult SpeedtestResult
|
||||
startTime := results[0].IntervalStart
|
||||
for _, r := range results {
|
||||
outputResult.Intervals = make([]SpeedtestResultInterval, len(results)-1)
|
||||
for i, r := range results {
|
||||
interval := SpeedtestResultInterval{
|
||||
StartTimeSeconds: r.IntervalStart.Sub(startTime).Seconds(),
|
||||
EndTimeSeconds: r.IntervalEnd.Sub(startTime).Seconds(),
|
||||
ThroughputMbits: r.MBitsPerSecond(),
|
||||
}
|
||||
if r.Total {
|
||||
tableWriter.AppendSeparator()
|
||||
interval.StartTimeSeconds = 0
|
||||
outputResult.Overall = interval
|
||||
} else {
|
||||
outputResult.Intervals[i] = interval
|
||||
}
|
||||
tableWriter.AppendRow(table.Row{
|
||||
fmt.Sprintf("%.2f-%.2f sec", r.IntervalStart.Sub(startTime).Seconds(), r.IntervalEnd.Sub(startTime).Seconds()),
|
||||
fmt.Sprintf("%.4f Mbits/sec", r.MBitsPerSecond()),
|
||||
})
|
||||
}
|
||||
_, err = fmt.Fprintln(inv.Stdout, tableWriter.Render())
|
||||
out, err := formatter.Format(inv.Context(), outputResult)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprintln(inv.Stdout, out)
|
||||
return err
|
||||
},
|
||||
}
|
||||
@@ -173,5 +219,6 @@ func (r *RootCmd) speedtest() *serpent.Command {
|
||||
Value: serpent.StringOf(&pcapFile),
|
||||
},
|
||||
}
|
||||
formatter.AttachOptions(&cmd.Options)
|
||||
return cmd
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user