diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-14 22:22:57 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-14 22:22:57 +0200 |
| commit | d0bed33cf41ac4917a9427c98e63351367d71298 (patch) | |
| tree | 9a49a06516aa20dc78a42fa873d6f77a0e411488 | |
| parent | 2265b31a6eeaae8d6aac52e1fa32a33863733192 (diff) | |
Aggregate all net interfaces, remove n hotkey, fix net bar decay bugv0.9.0
Sum RX/TX across all non-lo interfaces instead of picking a single one.
Remove the n hotkey (cycle interface), netint config field, and --netint
flag since they are no longer needed. Fix pre-existing bug where net bars
decayed to zero between collector updates (~19 of 20 frames had target=0,
making bars invisible even during heavy downloads).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| -rw-r--r-- | AGENTS.md | 6 | ||||
| -rw-r--r-- | README.md | 12 | ||||
| -rw-r--r-- | cmd/loadbars/main.go | 8 | ||||
| -rw-r--r-- | internal/config/config.go | 6 | ||||
| -rw-r--r-- | internal/display/display.go | 185 | ||||
| -rw-r--r-- | internal/display/display_test.go | 80 | ||||
| -rw-r--r-- | internal/version/version.go | 2 |
7 files changed, 140 insertions, 159 deletions
@@ -51,15 +51,15 @@ Default when no hosts are given: `localhost`. No SSH required for local use. ## Display and hotkeys - **Display** (`internal/display`): One loop – poll events, snapshot from store, count bars, clear only when layout/size changes, draw CPU then mem then net per host, present. Bar width = `winW / numBars`; no gap between bars (avoids 1px artifacts). -- **Hotkeys:** 1=cores, 2=mem, 3=net, e=extended (peak line), h=help, n=cycle net iface, q=quit, w=write config, a/y=cpu avg, d/c=net avg, arrows=resize. See README “Hotkeys” table. +- **Hotkeys:** 1=cores, 2=mem, 3=net, e=extended (peak line), h=help, q=quit, w=write config, a/y=cpu avg, d/c=net avg, f/v=link scale, arrows=resize. See README "Hotkeys" table. -Network interface: chosen by `netint` config or first non-`lo`; press `n` to cycle. When net is toggled on, stdout prints which interface is used and how to set `netint`/`netlink`. +Network bars aggregate RX/TX across all non-`lo` interfaces per host. Link speed is set via `netlink` config or `--netlink` flag. ## Conventions - Prefer the existing `internal/*` package layout; avoid adding new toplevel Go packages unless necessary. - Version is the single source in `internal/version/version.go`. -- Config keys are lowercase in `~/.loadbarsrc` (e.g. `netint=eth0`, `netlink=gbit`). +- Config keys are lowercase in `~/.loadbarsrc` (e.g. `netlink=gbit`). - No text/font rendering in the SDL window in the current design; keep feedback on stdout unless the user explicitly asks for in-window labels. ## Testing @@ -109,10 +109,9 @@ Press these keys while loadbars is running (see also `h` for a short list on std |-----|--------| | **1** | Toggle CPU cores (one bar per core vs one aggregate bar per host) | | **2** | Toggle memory bars (RAM left, Swap right per host) | -| **3** | Toggle network bars (RX/TX per host); stdout shows which interface is used | +| **3** | Toggle network bars (RX/TX summed across all non-lo interfaces per host) | | **e** | Toggle extended display (1px peak line on CPU bars: max system+user over last samples) | | **h** | Print hotkey list to stdout | -| **n** | Cycle to next network interface (per host); only when net bars are shown | | **q** | Quit | | **w** | Write current settings to ~/.loadbarsrc | | **a** | Increase CPU average samples (affects extended peak history length) | @@ -148,13 +147,9 @@ Press these keys while loadbars is running (see also `h` for a short list on std - `Rxb` = Incoming (received) traffic in %, Color: Light green, normal green if >100% while using low netlink reference. Bar comes from top and is half width. - `Txb` = Outgoing (transmitted) traffic in %, Color: Light green, normal green if >100% while using low netlink reference. Bar comes from bottom and is half width. -When network bar is red: The interface does not exist on the specific remote host. +When network bar is red: No non-loopback interface exists on the specific remote host. -**Choosing the network interface:** By default loadbars uses the first non-loopback interface (e.g. `eth0`, `enp0s3`). If stats never change, you may be watching the wrong interface (e.g. `docker0` with little traffic). Set the interface explicitly: - -- In **~/.loadbarsrc**: `netint=eth0` (use the name from `/proc/net/dev` or `ip link`) -- On the command line: `loadbars --netint eth0 --hosts localhost` -- In-app: press **3** to show net bars (stdout will print which interface is used), then **n** to cycle to the next interface. +**Aggregated interfaces:** Loadbars sums RX/TX across all non-loopback interfaces (e.g. `eth0`, `wlan0`, `enp0s3`) and shows the combined total. Loopback (`lo`) is always excluded. **Link speed** (`netlink`): Used to compute utilization %. Default is `gbit`. Set e.g. `netlink=100mbit` or `netlink=10gbit` in ~/.loadbarsrc or `--netlink 100mbit`. @@ -164,7 +159,6 @@ Loadbars tries to read ~/.loadbarsrc and it's possible to configure any option y ``` showcores=1 # Always show cores on startup -netint=eth0 # Interface for network bars (optional) netlink=gbit # Link speed for utilization % (optional) ``` diff --git a/cmd/loadbars/main.go b/cmd/loadbars/main.go index cd834ab..3d7fe77 100644 --- a/cmd/loadbars/main.go +++ b/cmd/loadbars/main.go @@ -26,7 +26,6 @@ func main() { flag.IntVar(&cfg.MaxWidth, "maxwidth", cfg.MaxWidth, "Set max width") flag.IntVar(&cfg.CPUAverage, "cpuaverage", cfg.CPUAverage, "Num of CPU samples for avg") flag.IntVar(&cfg.NetAverage, "netaverage", cfg.NetAverage, "Num of net samples for avg") - flag.StringVar(&cfg.NetInt, "netint", cfg.NetInt, "Interface to show netstats for") flag.StringVar(&cfg.NetLink, "netlink", cfg.NetLink, "Link speed (mbit, 10mbit, 100mbit, gbit, 10gbit or number)") flag.BoolVar(&cfg.ShowCores, "showcores", cfg.ShowCores, "Toggle core display") flag.BoolVar(&cfg.ShowMem, "showmem", cfg.ShowMem, "Toggle mem display") @@ -119,16 +118,13 @@ Options: --height <n> Window height (default 150) --showcores Show per-CPU bars --showmem Show memory bars - --shownet Show network bars - --netint <iface> Network interface for net bars (e.g. eth0, enp0s3). - Default: first non-lo. Press 'n' in-app to cycle. + --shownet Show network bars (aggregates all non-lo interfaces) --netlink <speed> Link speed for %% (gbit, 10gbit, mbit, 100mbit, or number). Default: gbit. --extended Extended display (peak line) --help This help --version Print version -Config: netint and netlink can be set in ~/.loadbarsrc. Press '3' then see -stdout for which interface is used; press 'n' to cycle. Press 'h' for hotkeys. +Config: netlink can be set in ~/.loadbarsrc. Press 'h' for hotkeys. `, version.Version, constants.CSSHConfFile) } diff --git a/internal/config/config.go b/internal/config/config.go index e523372..0fc80d4 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -23,7 +23,6 @@ type Config struct { Height int MaxWidth int NetAverage int - NetInt string NetLink string ShowCores bool ShowMem bool @@ -104,7 +103,7 @@ func (c *Config) parseReader(f *os.File) error { validKeys := map[string]bool{ "title": true, "barwidth": true, "cpuaverage": true, "extended": true, "hasagent": true, "height": true, "maxwidth": true, "netaverage": true, - "netint": true, "netlink": true, "showcores": true, "showmem": true, + "netlink": true, "showcores": true, "showmem": true, "shownet": true, "sshopts": true, "cluster": true, } scanner := bufio.NewScanner(f) @@ -158,8 +157,6 @@ func (c *Config) set(key, val string) { if n, err := strconv.Atoi(val); err == nil { c.NetAverage = n } - case "netint": - c.NetInt = val case "netlink": c.NetLink = val case "showcores": @@ -198,7 +195,6 @@ func (c *Config) writeTo(f *os.File) error { writeInt("height", c.Height) writeInt("maxwidth", c.MaxWidth) writeInt("netaverage", c.NetAverage) - writeStr("netint", c.NetInt) writeStr("netlink", c.NetLink) writeBool("showcores", c.ShowCores) writeBool("showmem", c.ShowMem) diff --git a/internal/display/display.go b/internal/display/display.go index b5ed092..3b4dd42 100644 --- a/internal/display/display.go +++ b/internal/display/display.go @@ -21,40 +21,35 @@ const smoothFactor = 0.12 // blend toward target each frame; lower = smoother // runState holds mutable state across the display loop (hotkeys, window size, smoothed data). type runState struct { - showCores bool - showMem bool - showNet bool - extended bool - winW int32 - winH int32 - prevCPU map[string]collector.CPULine - smoothedCPU map[string]*[9]float64 - smoothedMem map[string]*struct{ ramUsed, swapUsed float64 } - smoothedNet map[string]*struct{ rxPct, txPct float64 } - prevNet map[string]stats.NetStamp - netIntIndex map[string]int - cycleNetNext bool - printNetInfoOnce bool - peakHistory map[string][]float64 + showCores bool + showMem bool + showNet bool + extended bool + winW int32 + winH int32 + prevCPU map[string]collector.CPULine + smoothedCPU map[string]*[9]float64 + smoothedMem map[string]*struct{ ramUsed, swapUsed float64 } + smoothedNet map[string]*struct{ rxPct, txPct float64 } + prevNet map[string]stats.NetStamp // aggregated (summed) previous net stamp per host + peakHistory map[string][]float64 } // newRunState builds initial run state from config. func newRunState(cfg *config.Config, winW, winH int32) *runState { return &runState{ - showCores: cfg.ShowCores, - showMem: cfg.ShowMem, - showNet: cfg.ShowNet, - extended: cfg.Extended, - winW: winW, - winH: winH, - prevCPU: make(map[string]collector.CPULine), - smoothedCPU: make(map[string]*[9]float64), - smoothedMem: make(map[string]*struct{ ramUsed, swapUsed float64 }), - smoothedNet: make(map[string]*struct{ rxPct, txPct float64 }), - prevNet: make(map[string]stats.NetStamp), - netIntIndex: make(map[string]int), - printNetInfoOnce: cfg.ShowNet, - peakHistory: make(map[string][]float64), + showCores: cfg.ShowCores, + showMem: cfg.ShowMem, + showNet: cfg.ShowNet, + extended: cfg.Extended, + winW: winW, + winH: winH, + prevCPU: make(map[string]collector.CPULine), + smoothedCPU: make(map[string]*[9]float64), + smoothedMem: make(map[string]*struct{ ramUsed, swapUsed float64 }), + smoothedNet: make(map[string]*struct{ rxPct, txPct float64 }), + prevNet: make(map[string]stats.NetStamp), + peakHistory: make(map[string][]float64), } } @@ -152,9 +147,6 @@ func handleKey(sym sdl.Keycode, window *sdl.Window, cfg *config.Config, state *r case sdl.K_3: state.showNet = !state.showNet fmt.Println("==> Toggled show net:", state.showNet) - if state.showNet { - state.printNetInfoOnce = true - } case sdl.K_e: state.extended = !state.extended fmt.Println("==> Toggled extended (peak line):", state.extended) @@ -180,11 +172,6 @@ func handleKey(sym sdl.Keycode, window *sdl.Window, cfg *config.Config, state *r scaleLinkDown(cfg) case sdl.K_h: printHotkeys() - case sdl.K_n: - state.cycleNetNext = true - if state.showNet { - fmt.Println("==> Cycling to next network interface (per host)") - } case sdl.K_w: cfg.ShowCores = state.showCores cfg.ShowMem = state.showMem @@ -223,16 +210,6 @@ func handleKey(sym sdl.Keycode, window *sdl.Window, cfg *config.Config, state *r // drawFrame updates state from snapshot, clears if layout changed, and draws all bars. func drawFrame(renderer *sdl.Renderer, src stats.Source, cfg *config.Config, state *runState) { snap := src.Snapshot() - if state.cycleNetNext { - for _, host := range sortedHosts(snap) { - state.netIntIndex[host]++ - } - state.cycleNetNext = false - } - if state.printNetInfoOnce && state.showNet { - state.printNetInfoOnce = false - printNetInterfaceHelp(snap, cfg, state.netIntIndex) - } numBars := countBars(snap, state.showCores, state.showMem, state.showNet) barWidth := state.winW / int32(numBars) if barWidth < 1 { @@ -314,7 +291,7 @@ func drawHostBars(renderer *sdl.Renderer, h *stats.HostStats, host string, cfg * if state.smoothedNet[host] == nil { state.smoothedNet[host] = &struct{ rxPct, txPct float64 }{} } - state.prevNet[host] = drawNetBarSmoothed(renderer, h, cfg, state.smoothedNet[host], state.prevNet[host], state.netIntIndex, host, smoothFactor, barWidth, x, winH) + state.prevNet[host] = drawNetBarSmoothed(renderer, h, cfg, state.smoothedNet[host], state.prevNet[host], smoothFactor, barWidth, x, winH) } } @@ -526,35 +503,9 @@ func drawMemBarSmoothed(renderer *sdl.Renderer, h *stats.HostStats, smoothed *st } func printHotkeys() { - fmt.Println("=> Hotkeys: 1=cores 2=mem 3=net e=extended h=help n=next net q=quit w=write config a/y=cpu avg d/c=net avg f/v=link scale arrows=resize") + fmt.Println("=> Hotkeys: 1=cores 2=mem 3=net e=extended h=help q=quit w=write config a/y=cpu avg d/c=net avg f/v=link scale arrows=resize") } -// printNetInterfaceHelp prints which interface is used per host and how to set netint (when net view is toggled on). -func printNetInterfaceHelp(snap map[string]*stats.HostStats, cfg *config.Config, netIntIndex map[string]int) { - for _, host := range sortedHosts(snap) { - h := snap[host] - if h == nil || h.Net == nil || len(h.Net) == 0 { - fmt.Printf("Net: %s => (no interfaces yet, wait for data)\n", host) - continue - } - iface := chooseNetIface(h, cfg, host, netIntIndex) - all := make([]string, 0, len(h.Net)) - for name := range h.Net { - all = append(all, name) - } - sort.Strings(all) - if iface == "" { - fmt.Printf("Net: %s => (no non-lo interface; seen: %s)\n", host, strings.Join(all, ", ")) - continue - } - hint := "set netint=IFACE in ~/.loadbarsrc or --netint IFACE" - if cfg.NetInt != "" { - hint = "using netint=" + cfg.NetInt + " from config" - } - fmt.Printf("Net: %s => %s (all: %s). %s\n", host, iface, strings.Join(all, ", "), hint) - } - fmt.Println("=> Link speed: netlink=" + cfg.NetLink + " (gbit/mbit/10mbit/100mbit/10gbit or number). Change in ~/.loadbarsrc or --netlink") -} // netLinkBytesPerSec returns link speed in bytes/sec from cfg.NetLink (e.g. "gbit", "10gbit", "100mbit", or numeric mbit). @@ -616,58 +567,54 @@ func netLinkBytesPerSec(cfg *config.Config) int64 { return int64(constants.BytesGbit) } -// chooseNetIface returns the interface name to use for this host: cfg.NetInt if set and present, else first non-lo, cycling with n key. -func chooseNetIface(h *stats.HostStats, cfg *config.Config, host string, netIntIndex map[string]int) string { - if h.Net == nil || len(h.Net) == 0 { - return "" - } - if cfg.NetInt != "" { - if _, ok := h.Net[cfg.NetInt]; ok { - return cfg.NetInt - } +// sumNonLoNet aggregates RX (B) and TX (Tb) bytes across all non-lo interfaces, +// using the latest timestamp from any interface. +func sumNonLoNet(h *stats.HostStats) (sum stats.NetStamp, hasIface bool) { + if h.Net == nil { + return sum, false } - names := make([]string, 0, len(h.Net)) - for iface := range h.Net { + for iface, ns := range h.Net { if iface == "lo" { continue } - names = append(names, iface) - } - sort.Strings(names) - if len(names) == 0 { - return "" - } - idx := netIntIndex[host] % len(names) - if idx < 0 { - idx += len(names) + hasIface = true + sum.B += ns.B + sum.Tb += ns.Tb + if ns.Stamp > sum.Stamp { + sum.Stamp = ns.Stamp + } } - return names[idx] + return sum, hasIface } -func drawNetBarSmoothed(renderer *sdl.Renderer, h *stats.HostStats, cfg *config.Config, smoothed *struct{ rxPct, txPct float64 }, prev stats.NetStamp, netIntIndex map[string]int, host string, factor float64, barW int32, x *int32, winH int32) stats.NetStamp { +// drawNetBarSmoothed sums RX/TX across all non-lo interfaces, computes utilization +// vs link speed, smooths toward target, and draws one net bar (RX left from top, TX right from bottom). +// Smoothed values and prevNet are only updated when new collector data arrives +// (cur.Stamp > prev.Stamp), so the bar holds steady between collector cycles +// instead of decaying toward zero on frames with no new data. +func drawNetBarSmoothed(renderer *sdl.Renderer, h *stats.HostStats, cfg *config.Config, smoothed *struct{ rxPct, txPct float64 }, prev stats.NetStamp, factor float64, barW int32, x *int32, winH int32) stats.NetStamp { defer func() { *x += barW }() // Clear this slot so we never leave previous (e.g. CPU/mem) content visible renderer.SetDrawColor(constants.Black.R, constants.Black.G, constants.Black.B, 255) renderer.FillRect(&sdl.Rect{X: *x, Y: 0, W: barW, H: winH}) - iface := chooseNetIface(h, cfg, host, netIntIndex) - if iface == "" { - renderer.SetDrawColor(constants.Red.R, constants.Red.G, constants.Red.B, 255) - renderer.FillRect(&sdl.Rect{X: *x, Y: 0, W: barW, H: winH}) - return prev - } - cur, ok := h.Net[iface] - if !ok { + cur, hasIface := sumNonLoNet(h) + if !hasIface { + // No non-lo interface: show red bar renderer.SetDrawColor(constants.Red.R, constants.Red.G, constants.Red.B, 255) renderer.FillRect(&sdl.Rect{X: *x, Y: 0, W: barW, H: winH}) return prev } - linkBps := netLinkBytesPerSec(cfg) - if linkBps <= 0 { - linkBps = int64(constants.BytesGbit) - } - var targetRx, targetTx float64 - if prev.Stamp > 0 && cur.Stamp > prev.Stamp { - dt := float64(cur.Stamp-prev.Stamp) / 1e9 + // Only recompute and smooth when the collector has provided new data. + // The collector updates net stamps every ~2.8s, but drawFrame runs every + // ~0.14s. Without this guard, the 19 intermediate frames would set + // target to 0 (no delta) and smooth the bar toward zero, making real + // traffic invisible. + if cur.Stamp > prev.Stamp && prev.Stamp > 0 { + linkBps := netLinkBytesPerSec(cfg) + if linkBps <= 0 { + linkBps = int64(constants.BytesGbit) + } + dt := cur.Stamp - prev.Stamp if dt > 0 { deltaB := cur.B - prev.B deltaTb := cur.Tb - prev.Tb @@ -677,12 +624,16 @@ func drawNetBarSmoothed(renderer *sdl.Renderer, h *stats.HostStats, cfg *config. if deltaTb < 0 { deltaTb = 0 } - targetRx = 100 * float64(deltaB) / (float64(linkBps) * dt) - targetTx = 100 * float64(deltaTb) / (float64(linkBps) * dt) + targetRx := 100 * float64(deltaB) / (float64(linkBps) * dt) + targetTx := 100 * float64(deltaTb) / (float64(linkBps) * dt) + smoothed.rxPct += (targetRx - smoothed.rxPct) * factor + smoothed.txPct += (targetTx - smoothed.txPct) * factor } + prev = cur // only advance prev when we consumed new data + } else if prev.Stamp == 0 { + // First sample: record it but don't draw yet (no delta available) + prev = cur } - smoothed.rxPct += (targetRx - smoothed.rxPct) * factor - smoothed.txPct += (targetTx - smoothed.txPct) * factor halfW := barW / 2 barH := float64(winH) / 100.0 @@ -712,5 +663,5 @@ func drawNetBarSmoothed(renderer *sdl.Renderer, h *stats.HostStats, cfg *config. renderer.SetDrawColor(constants.Black.R, constants.Black.G, constants.Black.B, 255) renderer.FillRect(&sdl.Rect{X: *x + halfW, Y: 0, W: halfW, H: winH - txH}) } - return cur + return prev } diff --git a/internal/display/display_test.go b/internal/display/display_test.go index 841b1d4..94068f6 100644 --- a/internal/display/display_test.go +++ b/internal/display/display_test.go @@ -278,7 +278,7 @@ func TestNetBar_RxTx(t *testing.T) { "cpu": {User: 100, System: 100, Idle: 800}, }, Net: map[string]stats.NetStamp{ - "eth0": {B: 12500000, Tb: 6250000, Stamp: 2e9}, // current sample + "eth0": {B: 12500000, Tb: 6250000, Stamp: 2.0}, // current sample }, }, }, @@ -288,7 +288,7 @@ func TestNetBar_RxTx(t *testing.T) { state.prevCPU["host1;cpu"] = collector.CPULine{} // Pre-populate prevNet so delta calculation works: // RX: delta=12500000 bytes in 1s = 10% of gbit, TX: 6250000 = 5% of gbit - state.prevNet["host1"] = stats.NetStamp{B: 0, Tb: 0, Stamp: 1e9} + state.prevNet["host1"] = stats.NetStamp{B: 0, Tb: 0, Stamp: 1.0} // Pre-populate smoothed net so first frame is near target state.smoothedNet["host1"] = &struct{ rxPct, txPct float64 }{ rxPct: 10, txPct: 5, @@ -307,6 +307,60 @@ func TestNetBar_RxTx(t *testing.T) { assertPixelColor(t, surface, 85, 10, constants.Black, tol, "TX free area") } +func TestNetBar_AggregatesAllInterfaces(t *testing.T) { + const w, h int32 = 100, 100 + + renderer, surface, err := createTestRenderer(w, h) + if err != nil { + t.Fatal(err) + } + defer renderer.Destroy() + defer surface.Free() + + cfg := defaultTestConfig() + cfg.ShowCores = false + cfg.ShowMem = false + cfg.ShowNet = true + cfg.NetLink = "gbit" + + // Two non-lo interfaces: combined RX = 12500000+12500000 = 25000000 → 20% of gbit + src := &mockSource{ + data: map[string]*stats.HostStats{ + "host1": { + CPU: map[string]collector.CPULine{ + "cpu": {User: 100, System: 100, Idle: 800}, + }, + Net: map[string]stats.NetStamp{ + "eth0": {B: 12500000, Tb: 6250000, Stamp: 2.0}, + "wlan0": {B: 12500000, Tb: 6250000, Stamp: 2.0}, + "lo": {B: 99999999, Tb: 99999999, Stamp: 2.0}, // lo must be excluded + }, + }, + }, + } + + state := newRunState(cfg, w, h) + state.prevCPU["host1;cpu"] = collector.CPULine{} + // Previous aggregated stamp: all zeros at t=1 + state.prevNet["host1"] = stats.NetStamp{B: 0, Tb: 0, Stamp: 1.0} + // Pre-populate smoothed to 20% RX, 10% TX (the expected combined values) + state.smoothedNet["host1"] = &struct{ rxPct, txPct float64 }{ + rxPct: 20, txPct: 10, + } + + drawFrame(renderer, src, cfg, state) + + const tol = 5 + // Net bar: 1 CPU + 1 net = 2 bars, each 50px. Net bar at x=50, halfW=25 + // Left half (RX from top): 20% = 20px of LightGreen from top + assertPixelColor(t, surface, 60, 5, constants.LightGreen, tol, "aggregated RX at top") + assertPixelColor(t, surface, 60, 45, constants.Black, tol, "RX free area") + + // Right half (TX from bottom): 10% = 10px of LightGreen from bottom + assertPixelColor(t, surface, 85, 98, constants.LightGreen, tol, "aggregated TX at bottom") + assertPixelColor(t, surface, 85, 10, constants.Black, tol, "TX free area") +} + func TestMultiHost_BarCount(t *testing.T) { const w, h int32 = 600, 100 @@ -332,12 +386,12 @@ func TestMultiHost_BarCount(t *testing.T) { "alpha": { CPU: map[string]collector.CPULine{"cpu": alphaCur}, Mem: map[string]int64{"MemTotal": 100, "MemFree": 50, "SwapTotal": 0, "SwapFree": 0}, - Net: map[string]stats.NetStamp{"eth0": {B: 0, Tb: 0, Stamp: 1e9}}, + Net: map[string]stats.NetStamp{"eth0": {B: 0, Tb: 0, Stamp: 1.0}}, }, "beta": { CPU: map[string]collector.CPULine{"cpu": betaCur}, Mem: map[string]int64{"MemTotal": 100, "MemFree": 50, "SwapTotal": 0, "SwapFree": 0}, - Net: map[string]stats.NetStamp{"eth0": {B: 0, Tb: 0, Stamp: 1e9}}, + Net: map[string]stats.NetStamp{"eth0": {B: 0, Tb: 0, Stamp: 1.0}}, }, }, } @@ -443,7 +497,7 @@ func TestNetBar_NoInterface(t *testing.T) { "cpu": {User: 100, System: 100, Idle: 800}, }, Net: map[string]stats.NetStamp{ - "lo": {B: 0, Tb: 0, Stamp: 1e9}, // only loopback + "lo": {B: 0, Tb: 0, Stamp: 1.0}, // only loopback }, }, }, @@ -573,8 +627,8 @@ func newHotkeyTestEnv(t *testing.T, showCores, showMem, showNet bool) ( "SwapFree": 600, }, Net: map[string]stats.NetStamp{ - "eth0": {B: 12500000, Tb: 6250000, Stamp: 2e9}, - "wlan0": {B: 1000000, Tb: 500000, Stamp: 2e9}, + "eth0": {B: 12500000, Tb: 6250000, Stamp: 2.0}, + "wlan0": {B: 1000000, Tb: 500000, Stamp: 2.0}, }, }, }, @@ -584,7 +638,7 @@ func newHotkeyTestEnv(t *testing.T, showCores, showMem, showNet bool) ( state.prevCPU["host1;cpu"] = prev state.prevCPU["host1;cpu0"] = prev0 state.prevCPU["host1;cpu1"] = prev1 - state.prevNet["host1"] = stats.NetStamp{B: 0, Tb: 0, Stamp: 1e9} + state.prevNet["host1"] = stats.NetStamp{B: 0, Tb: 0, Stamp: 1.0} state.smoothedNet["host1"] = &struct{ rxPct, txPct float64 }{ rxPct: 10, txPct: 5, } @@ -755,16 +809,6 @@ func TestHandleKey_NetAverage(t *testing.T) { } } -func TestHandleKey_CycleNet(t *testing.T) { - cfg := defaultTestConfig() - state := newRunState(cfg, 200, 100) - - handleKey(sdl.K_n, nil, cfg, state) - if !state.cycleNetNext { - t.Error("expected cycleNetNext=true after pressing 'n'") - } -} - func TestHandleKey_WriteConfig(t *testing.T) { // Set HOME to a temp dir so we don't touch real ~/.loadbarsrc tmpDir := t.TempDir() diff --git a/internal/version/version.go b/internal/version/version.go index 2b4ace2..209fae7 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -1,4 +1,4 @@ package version // Version is the application version (set at build time or here for development). -const Version = "0.8.4" +const Version = "0.9.0" |
