aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_data.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_data.lua')
-rw-r--r--test/test_data.lua263
1 files changed, 0 insertions, 263 deletions
diff --git a/test/test_data.lua b/test/test_data.lua
index 549ce40..37a302e 100644
--- a/test/test_data.lua
+++ b/test/test_data.lua
@@ -20,141 +20,7 @@ local function read(path)
return s
end
--- cpu_times: total and idle jiffies from the aggregate "cpu " line.
-local total, idle = data.cpu_times(read('test/fixtures/proc_stat'))
--- 209094+2199+135469+11604898+24408+0+946 = 11977014
-assert(total == 11977014, 'cpu total, got ' .. tostring(total))
--- idle field is the 4th value, 11604898; iowait (24408) counts as idle too
-assert(idle == 11629306, 'cpu idle, got ' .. tostring(idle))
-
--- mem_info: values in kB, as the file gives them.
-local mem = data.mem_info(read('test/fixtures/proc_meminfo'))
-assert(mem.total == 31943076, 'mem total, got ' .. tostring(mem.total))
-assert(mem.available == 25627088, 'mem available, got ' .. tostring(mem.available))
--- used is total minus available, which is what a user means by "used"
-assert(mem.used == 6315988, 'mem used, got ' .. tostring(mem.used))
-
--- millidegrees: hwmon temp*_input is millidegrees C, rounded to whole degrees.
-assert(data.millidegrees(read('test/fixtures/temp1_input')) == 53,
- 'temp, got ' .. tostring(data.millidegrees(read('test/fixtures/temp1_input'))))
--- A missing or unreadable sensor must yield nil, not an error and not 0:
--- 0 degrees is a plausible reading and would be indistinguishable from failure.
-assert(data.millidegrees(nil) == nil, 'nil input must give nil')
-assert(data.millidegrees('') == nil, 'empty input must give nil')
-assert(data.millidegrees('garbage') == nil, 'unparseable input must give nil')
-
--- CPU load is a delta between two samples, so the counter holds state.
--- The first call has no previous sample and must report nil, not a number:
--- any number it invented would be wrong, and 100% on startup looks like a
--- real spike.
-local c = data.new_cpu_counter()
-assert(c:sample(1000, 900) == nil, 'first sample must give nil')
-
--- Second sample: 100 more total jiffies, 50 of them idle, so 50% busy.
--- Held in a local first: calling sample() again inside the assert message would
--- advance the counter a third time.
-local busy = c:sample(1100, 950)
-assert(busy == 50.0, 'second sample, got ' .. tostring(busy))
-
--- A counter that did not advance means no elapsed time, not 0% load.
-local c2 = data.new_cpu_counter()
-c2:sample(1000, 900)
-assert(c2:sample(1000, 900) == nil, 'zero delta must give nil, not a division by zero')
-
--- === Per-core CPU =========================================================
--- The aggregate line answers "how busy is the machine"; the equaliser needs
--- one entry per core. Both come from the same file, so they are parsed by the
--- same rules and differ only in which lines they read.
-local percore = read('test/fixtures/proc_stat_percore')
-local cores = data.per_cpu_times(percore)
-assert(#cores == 4, 'one entry per cpuN line, got ' .. tostring(#cores))
-
--- cpu0: 6441+24+3225+1056496+1932+0+760 = 1068878 total, idle+iowait = 1058428
-assert(cores[1].total == 1068878, 'core 0 total, got ' .. tostring(cores[1].total))
-assert(cores[1].idle == 1058428, 'core 0 idle, got ' .. tostring(cores[1].idle))
-
--- Ordering matters: bar N must be core N, so the list follows the file.
-assert(cores[2].total == 1066406, 'core 1 total, got ' .. tostring(cores[2].total))
-
--- The aggregate 'cpu ' line must NOT be counted as a core: it would draw a
--- bar for the aggregate line showing the average, which looks like a real core.
-for i, c in ipairs(cores) do
- assert(c.total < 2000000, 'entry ' .. i .. ' looks like the aggregate line')
-end
-
--- A counter per core is just another instance, which is why new_cpu_counter
--- holds its own previous sample rather than using a module-level one.
-local c0 = data.new_cpu_counter()
-assert(c0:sample(cores[1].total, cores[1].idle) == nil, 'first sample is nil')
-local busy = c0:sample(cores[1].total + 100, cores[1].idle + 25)
-assert(busy == 75.0, 'second sample 75%, got ' .. tostring(busy))
-
--- Malformed input yields an empty list, never an error: a raise here is a
--- blank dashboard.
-assert(#data.per_cpu_times('') == 0, 'empty input gives an empty list')
-assert(#data.per_cpu_times('garbage\nlines\n') == 0, 'garbage gives an empty list')
-assert(#data.per_cpu_times(nil) == 0, 'nil gives an empty list')
--- A truncated line (fewer than the 5 fields the maths needs) is skipped
--- rather than producing a nonsense total.
-assert(#data.per_cpu_times('cpu0 1 2\n') == 0, 'a short line is skipped')
-
-- === Cache files ==========================================================
--- df -P guarantees one line per mount with the mountpoint LAST, which is why
--- the parser takes the last field rather than the sixth: an NFS device is
--- 'server:/export' and a device name can carry surprises, but the mountpoint
--- is always at the end.
-local fs = data.df_parse(read('test/fixtures/df_output'))
-assert(#fs == 6, 'one entry per mount, got ' .. tostring(#fs))
-assert(fs[1].mount == '/', 'first mount, got ' .. tostring(fs[1].mount))
-assert(fs[1].pct == 84, 'root percent, got ' .. tostring(fs[1].pct))
-assert(fs[1].size == 263174213632, 'root size in bytes, got ' .. tostring(fs[1].size))
-assert(fs[1].used == 208111570944, 'root used, got ' .. tostring(fs[1].used))
-
--- Available is READ, never derived as size - used: the two differ by the
--- root-reserved blocks, about 5%, which on this root is some 13GB that exists
--- but cannot be used. A card claiming that space is free would be lying.
-assert(fs[1].avail == 41746907136, 'root available, got ' .. tostring(fs[1].avail))
-assert(fs[1].size - fs[1].used ~= fs[1].avail,
- 'the fixture must exercise the reserved-block gap, or this assertion proves nothing')
-
--- fs[3] is /dev/sda1: a device name ENDING IN A DIGIT, next to a numeric
--- column. A parser counting fields from the left, or matching digits without
--- anchoring, reads the partition number as a size.
-assert(fs[3].mount == '/data', 'sda1 mount, got ' .. tostring(fs[3].mount))
-assert(fs[3].dev == '/dev/sda1', 'sda1 device, got ' .. tostring(fs[3].dev))
-assert(fs[3].size == 983350091776, 'sda1 size, got ' .. tostring(fs[3].size))
-assert(fs[3].used == 547869650944, 'sda1 used, got ' .. tostring(fs[3].used))
-assert(fs[3].avail == 385453473792, 'sda1 available, got ' .. tostring(fs[3].avail))
-assert(fs[3].pct == 59, 'sda1 percent, got ' .. tostring(fs[3].pct))
-assert(fs[3].host == nil, 'a local device has no host')
-
--- A full filesystem reports zero available, which is a real reading.
-assert(fs[6].avail == 0, 'a full mount has 0 available, got ' .. tostring(fs[6].avail))
-
--- The NFS rows are the reason the last field matters: a colon in the device
--- would break a parser splitting on punctuation.
-assert(fs[4].mount == '/mnt/nfs/Library', 'nfs mount, got ' .. tostring(fs[4].mount))
-assert(fs[4].pct == 79, 'nfs percent, got ' .. tostring(fs[4].pct))
-
--- The device field carries the server, which is what lets the disks card
--- label the two shares without an address hardcoded in the repo.
-assert(fs[4].host == 'server-a', 'nfs host, got ' .. tostring(fs[4].host))
-assert(fs[1].host == nil, 'a local device has no host, got ' .. tostring(fs[1].host))
-
--- A full filesystem is a real state, not an error.
-assert(fs[6].pct == 100, 'a full mount reads 100, got ' .. tostring(fs[6].pct))
-
--- The header line must not become a row.
-for _, e in ipairs(fs) do
- assert(e.mount ~= 'on' and e.mount ~= 'Mounted', 'the header leaked in as a row')
-end
-
-assert(#data.df_parse('') == 0, 'empty input gives an empty list')
-assert(#data.df_parse(nil) == 0, 'nil gives an empty list')
--- A header with no rows is what a failed df produces.
-assert(#data.df_parse('Filesystem 1-blocks Used Available Capacity Mounted on\n') == 0,
- 'a header alone gives an empty list')
-
-- du -sh: total first, then children largest-first. The suffixes must be
-- converted, not string-sorted: '1.1G' outranks '245M' numerically and loses
-- to it alphabetically.
@@ -199,46 +65,6 @@ assert(cut == string.rep('\u{00E9}', 9) .. '\u{2026}',
assert(card.truncate(nil, 10) == '', 'nil truncates to empty')
assert(card.truncate('abc', 0) == '', 'a zero limit gives empty')
--- === Network rate =========================================================
--- Interface byte counters are cumulative, so a rate is a delta over elapsed
--- time. The first call has no previous sample and must report nil: any number
--- it invented would be wrong, and a spike at startup looks real.
-local r = data.new_rate_counter()
-assert(r:sample(1000, 100) == nil, 'first sample must give nil')
-
--- 2048 bytes over 2 seconds is 1024 B/s.
-local rate = r:sample(3048, 102)
-assert(rate == 1024, 'second sample, got ' .. tostring(rate))
-
--- A counter that went backwards means a wrap or an interface reset. It must
--- clamp to zero, never produce the huge positive an unsigned wrap implies:
--- one bogus sample poisons the shared autoscale for the whole window.
-local r2 = data.new_rate_counter()
-r2:sample(5000, 100)
-assert(r2:sample(10, 102) == 0, 'a counter reset must give 0')
-
--- Two samples inside the same clock second. os.time() has whole-second
--- resolution against a 2s draw interval, so this happens in normal operation
--- and must not divide by zero.
-local r3 = data.new_rate_counter()
-r3:sample(1000, 500)
-local same_second = r3:sample(2000, 500)
-assert(same_second ~= nil and same_second >= 0,
- 'a zero time delta must fall back to the draw interval, got ' .. tostring(same_second))
-
--- A missing interface reads nil, which must propagate rather than raise.
-local r4 = data.new_rate_counter()
-assert(r4:sample(nil, 100) == nil, 'a nil byte count gives nil')
-
--- The fallback interval is a constructor argument, and the widget passes
--- conky's real update_interval rather than letting it default. That is the
--- path that ships, so it is the path that gets a test: at a 5s interval the
--- same 2048 bytes must read as 409.6 B/s, not 1024.
-local r5 = data.new_rate_counter(5)
-r5:sample(1000, 100)
-assert(r5:sample(3048, 100) == 2048 / 5,
- 'an explicit fallback interval must be used, got ' .. tostring(r5:sample(3048, 100)))
-
-- === kv_parse =============================================================
-- The slackware sampler writes 'key value' lines. The format is deliberately
-- dumber than the data: epochs stay integers rather than becoming formatted
@@ -260,68 +86,6 @@ assert(type(data.kv_parse('')) == 'table', 'empty input gives a table')
assert(type(data.kv_parse(nil)) == 'table', 'nil gives a table')
assert(data.kv_parse('keyonly\n').keyonly == nil, 'a line with no value is skipped')
--- === Hardware identification ==============================================
--- Both strings are constant for the machine's life, so the widget memoizes
--- them. What is tested here is the stripping, which must be a rule rather
--- than a special case for one host: the Intel fixture exists to prove it.
-assert(data.cpu_model(read('test/fixtures/proc_cpuinfo')) == 'Ryzen 7 9700X',
- 'amd cpu, got ' .. tostring(data.cpu_model(read('test/fixtures/proc_cpuinfo'))))
-assert(data.cpu_model(read('test/fixtures/proc_cpuinfo_intel')) == 'Core i7-8700K',
- 'intel cpu, got ' .. tostring(data.cpu_model(read('test/fixtures/proc_cpuinfo_intel'))))
-
--- Unparseable input yields nil, so the card shows nothing rather than a
--- half-stripped string.
-assert(data.cpu_model('') == nil, 'empty cpuinfo gives nil')
-assert(data.cpu_model(nil) == nil, 'nil cpuinfo gives nil')
-assert(data.cpu_model('processor\t: 0\n') == nil, 'cpuinfo with no model name gives nil')
-
--- The board is two sysfs files joined, with the vendor's corporate suffix
--- dropped: it is boilerplate on every board and costs a third of the row.
-assert(data.board_name('Gigabyte Technology Co., Ltd.\n', 'X870 EAGLE WIFI7\n')
- == 'Gigabyte X870 EAGLE WIFI7',
- 'board, got ' .. tostring(data.board_name('Gigabyte Technology Co., Ltd.\n', 'X870 EAGLE WIFI7\n')))
-assert(data.board_name('ASUSTeK COMPUTER INC.\n', 'PRIME B650-PLUS\n')
- == 'ASUSTeK PRIME B650-PLUS',
- 'asus board, got ' .. tostring(data.board_name('ASUSTeK COMPUTER INC.\n', 'PRIME B650-PLUS\n')))
-
--- A machine that reports one and not the other shows what it has.
-assert(data.board_name(nil, 'X870 EAGLE WIFI7\n') == 'X870 EAGLE WIFI7',
- 'name alone, got ' .. tostring(data.board_name(nil, 'X870 EAGLE WIFI7\n')))
-assert(data.board_name('Gigabyte\n', nil) == 'Gigabyte', 'vendor alone')
-assert(data.board_name(nil, nil) == nil, 'neither gives nil')
-
--- A virtual machine reports placeholder DMI strings. Showing 'To be filled by
--- O.E.M.' as the motherboard is worse than showing nothing.
-assert(data.board_name('To Be Filled By O.E.M.\n', 'To Be Filled By O.E.M.\n') == nil,
- 'placeholder DMI gives nil')
-
--- Three Intel forms the single fixture does not cover. The first fixture
--- happens to carry a literal 'CPU' before the clock, so a pattern requiring
--- that token passes the fixture and still leaves '@ 2.40GHz' on the card for
--- every other Intel part. These exist so the stripping stays a rule.
-assert(data.cpu_model('model name\t: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz\n')
- == 'Xeon E5-2680 v4',
- 'xeon, got ' .. tostring(data.cpu_model('model name\t: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz\n')))
-assert(data.cpu_model('model name\t: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz\n')
- == 'Core i7-1165G7',
- 'tiger lake, got ' .. tostring(data.cpu_model('model name\t: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz\n')))
-assert(data.cpu_model('model name\t: AMD Ryzen 9 7950X3D 16-Core Processor\n')
- == 'Ryzen 9 7950X3D',
- 'x3d, got ' .. tostring(data.cpu_model('model name\t: AMD Ryzen 9 7950X3D 16-Core Processor\n')))
-
--- === Interface address ====================================================
--- The fixture uses TEST-NET-1 (192.0.2.0/24, RFC 5737). This repository is
--- public: no real LAN address belongs in it, and no test may assert one.
-local addr = data.iface_addr_parse(read('test/fixtures/ip_addr'))
-assert(addr == '192.0.2.15', 'lan address, got ' .. tostring(addr))
-
--- A down interface has no inet line. nil, so the card shows '--' rather than
--- a stale or invented address.
-assert(data.iface_addr_parse('5: br0: <BROADCAST,MULTICAST> mtu 1500 state DOWN\n') == nil,
- 'a down interface gives nil')
-assert(data.iface_addr_parse('') == nil, 'empty gives nil')
-assert(data.iface_addr_parse(nil) == nil, 'nil gives nil')
-
-- === Calendar =============================================================
-- The fixture uses generic event titles. This repository is public: a real
-- appointment names a real person or a real appointment, and neither belongs
@@ -479,33 +243,6 @@ assert(up.upgrade == 3 and up.bump == 1 and up.current == 46 and up.missing == 1
'updates summary')
assert(data.nvtable_parse('') == nil, 'updates: empty cache is nil')
--- drm_vram_parse: xe clients counted once across their fds, other drivers
--- skipped, units honoured.
-local fdinfo = table.concat({
- '/proc/1/fdinfo/5:drm-driver:\txe',
- '/proc/1/fdinfo/5:drm-client-id:\t7',
- '/proc/1/fdinfo/5:drm-resident-vram0:\t1024 KiB',
- '/proc/1/fdinfo/6:drm-driver:\txe',
- '/proc/1/fdinfo/6:drm-client-id:\t7',
- '/proc/1/fdinfo/6:drm-resident-vram0:\t1024 KiB',
- '/proc/2/fdinfo/9:drm-driver:\txe',
- '/proc/2/fdinfo/9:drm-client-id:\t8',
- '/proc/2/fdinfo/9:drm-resident-vram0:\t2 MiB',
- '/proc/3/fdinfo/4:drm-driver:\tamdgpu',
- '/proc/3/fdinfo/4:drm-client-id:\t9',
- '/proc/3/fdinfo/4:drm-resident-vram0:\t5 GiB',
-}, '\n')
-assert(data.drm_vram_parse(fdinfo) == 3 * 1024 ^ 2,
- 'drm vram: got ' .. tostring(data.drm_vram_parse(fdinfo)))
-assert(data.drm_vram_parse('') == nil, 'drm vram: no clients is nil')
-
--- new_gate: opens at most once per interval on the clock it is given.
-local gate = data.new_gate(1.9)
-assert(gate(100.0) == true, 'gate: first call opens')
-assert(gate(100.5) == false, 'gate: closed inside the interval')
-assert(gate(101.95) == true, 'gate: opens after it')
-assert(gate(102.0) == false, 'gate: interval restarts from the last open')
-
-- Emoji fall back to card.FONT_EMOJI: the toy API has no per-glyph fallback,
-- so without the run split "x🦷" measured a tofu box in Noto Sans.
do