diff options
Diffstat (limited to 'test/test_data.lua')
| -rw-r--r-- | test/test_data.lua | 263 |
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 |
