mirror of
https://github.com/nicolargo/glances.git
synced 2026-09-15 06:40:25 -04:00
The reference configuration documents the boundary for both plugins that
use the feature:
# Set hide_threshold_bytes to an integer value to automatically hide
# interface with traffic less or equal than this value
#hide_threshold_bytes=0
"less or equal than this value", with a documented default of 0, means a
rate of exactly 0 is hidden. The comparison un-hid on `>=` instead, so at
the default threshold every zero rate satisfied `0 >= 0` and the row came
straight back.
The first refresh still hides, because it has no previous view to carry
forward and falls into the `else` branch. From the second refresh on,
nothing was ever hidden again -- which is why `hide_zero=True` looked like
it worked for one frame and then stopped.
This restores the behaviour that `i[field] != 0` had before the threshold
option was introduced, and honours a non-zero threshold the way the
configuration file describes it.
Tests pin the boundary rather than any rendered message: the views dict
keeps every key either way, only `hidden` moves.
165 lines
5.7 KiB
Python
165 lines
5.7 KiB
Python
#!/usr/bin/env python
|
|
#
|
|
# Glances - An eye on your system
|
|
#
|
|
# SPDX-FileCopyrightText: 2026 Nicolas Hennion <nicolas@nicolargo.com>
|
|
#
|
|
# SPDX-License-Identifier: LGPL-3.0-only
|
|
#
|
|
|
|
"""hide_zero hides a stat that has never moved.
|
|
|
|
The reference configuration states the boundary for both plugins that use the
|
|
feature: "Set hide_threshold_bytes to an integer value to automatically hide
|
|
interface with traffic less or equal than this value". With the documented
|
|
default of 0, a rate of exactly 0 is therefore hidden.
|
|
|
|
This is invisible when it breaks: the views dict still has every key, the rows
|
|
just come back. So the tests below pin the boundary itself rather than any
|
|
message drawn from it.
|
|
"""
|
|
|
|
import os
|
|
|
|
import pytest
|
|
|
|
from glances.config import Config
|
|
from glances.plugins.diskio import DiskioPlugin
|
|
from glances.plugins.network import NetworkPlugin
|
|
|
|
RECV = 'bytes_recv_rate_per_sec'
|
|
SENT = 'bytes_sent_rate_per_sec'
|
|
READ = 'read_bytes_rate_per_sec'
|
|
WRITE = 'write_bytes_rate_per_sec'
|
|
|
|
|
|
def make_config(tmp_path, section, extra=''):
|
|
config_file = tmp_path / 'glances.conf'
|
|
config_file.write_text(f'[{section}]\nhide_zero=True\n{extra}', encoding='utf-8')
|
|
return Config(config_dir=os.fspath(config_file))
|
|
|
|
|
|
@pytest.fixture
|
|
def network(tmp_path):
|
|
return NetworkPlugin(args=None, config=make_config(tmp_path, 'network'))
|
|
|
|
|
|
@pytest.fixture
|
|
def diskio(tmp_path):
|
|
return DiskioPlugin(args=None, config=make_config(tmp_path, 'diskio'))
|
|
|
|
|
|
def interface(recv_rate, sent_rate, name='eth0'):
|
|
return {
|
|
'interface_name': name,
|
|
'key': 'interface_name',
|
|
'alias': None,
|
|
'is_up': True,
|
|
'speed': 0,
|
|
'time_since_update': 1.0,
|
|
'bytes_recv': 0,
|
|
'bytes_sent': 0,
|
|
'bytes_all': 0,
|
|
RECV: recv_rate,
|
|
SENT: sent_rate,
|
|
'bytes_all_rate_per_sec': recv_rate + sent_rate,
|
|
}
|
|
|
|
|
|
def disk(read_rate, write_rate, name='sda'):
|
|
return {
|
|
'disk_name': name,
|
|
'key': 'disk_name',
|
|
'time_since_update': 1.0,
|
|
'read_count': 0,
|
|
'write_count': 0,
|
|
'read_bytes': 0,
|
|
'write_bytes': 0,
|
|
READ: read_rate,
|
|
WRITE: write_rate,
|
|
'read_count_rate_per_sec': 0,
|
|
'write_count_rate_per_sec': 0,
|
|
'read_latency': 0,
|
|
'write_latency': 0,
|
|
}
|
|
|
|
|
|
def sample(plugin, stats):
|
|
"""Feed one refresh and return the views for the single row."""
|
|
plugin.stats = [stats]
|
|
plugin.update_views()
|
|
return plugin.views[stats[plugin.get_key()]]
|
|
|
|
|
|
class TestHideZeroStaysHidden:
|
|
"""A stat that has never been different from 0 keeps hiding."""
|
|
|
|
def test_an_idle_interface_stays_hidden_across_refreshes(self, network):
|
|
# The first refresh has no previous view to carry forward and hides by
|
|
# construction; the regression only shows from the second one on.
|
|
assert sample(network, interface(0, 0))[RECV]['hidden'] is True
|
|
|
|
for refresh in range(2, 5):
|
|
views = sample(network, interface(0, 0))
|
|
assert views[RECV]['hidden'] is True, f'recv came back on refresh {refresh}'
|
|
assert views[SENT]['hidden'] is True, f'sent came back on refresh {refresh}'
|
|
|
|
def test_an_idle_disk_stays_hidden_across_refreshes(self, diskio):
|
|
assert sample(diskio, disk(0, 0))[READ]['hidden'] is True
|
|
|
|
for refresh in range(2, 5):
|
|
views = sample(diskio, disk(0, 0))
|
|
assert views[READ]['hidden'] is True, f'read came back on refresh {refresh}'
|
|
assert views[WRITE]['hidden'] is True, f'write came back on refresh {refresh}'
|
|
|
|
|
|
class TestHideZeroRevealsTraffic:
|
|
"""...and any traffic at all reveals it, permanently."""
|
|
|
|
def test_traffic_reveals_the_field_and_it_does_not_hide_again(self, network):
|
|
sample(network, interface(0, 0))
|
|
views = sample(network, interface(0, 51200))
|
|
assert views[SENT]['hidden'] is False, 'a transmitting interface must be shown'
|
|
|
|
# "never been != 0" is a memory, not a snapshot: going quiet again does
|
|
# not re-hide the field.
|
|
views = sample(network, interface(0, 0))
|
|
assert views[SENT]['hidden'] is False, 'an interface that has transmitted must stay shown'
|
|
|
|
def test_one_byte_per_second_is_traffic(self, network):
|
|
sample(network, interface(0, 0))
|
|
assert sample(network, interface(1, 0))[RECV]['hidden'] is False
|
|
|
|
|
|
class TestHideThresholdBytes:
|
|
"""The threshold is the boundary the configuration file documents."""
|
|
|
|
def test_a_rate_equal_to_the_threshold_is_hidden(self, tmp_path):
|
|
plugin = DiskioPlugin(args=None, config=make_config(tmp_path, 'diskio', 'hide_threshold_bytes=1024\n'))
|
|
assert plugin.hide_threshold_bytes == 1024
|
|
|
|
sample(plugin, disk(0, 0))
|
|
views = sample(plugin, disk(1024, 1024))
|
|
assert views[READ]['hidden'] is True, 'a rate equal to the threshold is "less or equal than"'
|
|
assert views[WRITE]['hidden'] is True
|
|
|
|
def test_a_rate_above_the_threshold_is_shown(self, tmp_path):
|
|
plugin = DiskioPlugin(args=None, config=make_config(tmp_path, 'diskio', 'hide_threshold_bytes=1024\n'))
|
|
|
|
sample(plugin, disk(0, 0))
|
|
assert sample(plugin, disk(1025, 0))[READ]['hidden'] is False
|
|
|
|
|
|
class TestHideZeroDisabled:
|
|
"""Nothing is hidden when the feature is off, whatever the rates are."""
|
|
|
|
def test_hide_zero_false_never_hides(self, tmp_path):
|
|
config_file = tmp_path / 'glances.conf'
|
|
config_file.write_text('[network]\nhide_zero=False\n', encoding='utf-8')
|
|
plugin = NetworkPlugin(args=None, config=Config(config_dir=os.fspath(config_file)))
|
|
|
|
for _ in range(3):
|
|
views = sample(plugin, interface(0, 0))
|
|
assert views[RECV]['hidden'] is False
|
|
assert views[SENT]['hidden'] is False
|