mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-05 01:44:16 +08:00
🎁 Sync 2026-10-18 22:41:16
This commit is contained in:
1 parent
3eca35a513
commit
3159b4f938
88 files changed
+5597
-1051
No files matched your search
@@ -37,3 +37,15 @@ mtwifi/mt_dbdc/ralink radios. It does not start a repeating scan poll or stop
|
||||
LuCI's global poller. The refresh button is enabled immediately on completion or failure;
|
||||
requests are coalesced per radio and serialized across radios. Run
|
||||
`node modules/luci-mod-status/tests/channel-analysis.js` from the LuCI root.
|
||||
|
||||
Run `node modules/luci-mod-status/tests/overview-async.js` to check that a
|
||||
pending wireless query does not delay other overview cards or their next
|
||||
refresh, duplicate itself, or prevent retry after failure. Run
|
||||
`node modules/luci-mod-status/tests/wifi-disabled.js` for configured QCA and
|
||||
MediaTek VIF selection, disabled interfaces and mixed-backend handling.
|
||||
|
||||
Run `node modules/luci-mod-status/tests/mount-points.js` to verify that the
|
||||
homepage's root-only storage query never calls statvfs on unrelated mounts,
|
||||
while existing callers without the option still receive the complete list.
|
||||
Cold-boot validation should keep a FAT USB volume mounted: its initial free-space
|
||||
scan must not delay the overview's system, memory or storage cards.
|
||||
@@ -0,0 +1,25 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const source = fs.readFileSync(path.join(__dirname, '../../luci-base/root/usr/share/rpcd/ucode/luci'), 'utf8');
|
||||
const method = source.slice(source.indexOf('\tgetMountPoints: {'), source.indexOf('\tgetRealtimeStats: {'));
|
||||
let visited = [], closed = false;
|
||||
const lines = ['/dev/root /rom squashfs ro 0 0', '/dev/ubi0_5 /overlay ubifs rw 0 0',
|
||||
'overlayfs:/overlay / overlay rw 0 0', '/dev/sda1 /mnt/USB\\040Disk vfat rw 0 0'];
|
||||
const api = new Function('open', 'split', 'replace', 'chr', 'int', 'statvfs', 'length', 'push',
|
||||
'return ({' + method + '}).getMountPoints;')(
|
||||
() => { let i = 0; return {read: () => lines[i++] || '', close: () => {closed = true;}}; },
|
||||
(s, sep) => s.split(sep), (s, re, fn) => s.replace(re, fn), String.fromCharCode, parseInt,
|
||||
mount => {visited.push(mount); return {blocks: 100, bsize: 4096, bavail: 20, bfree: 25};},
|
||||
s => s.length, (a, v) => a.push(v));
|
||||
const roots = api.call({args: {root_only: true}}).result;
|
||||
assert.deepEqual(visited, ['/overlay', '/'], 'overview must not stat unrelated filesystems');
|
||||
assert.deepEqual(roots.map(m => m.mount), visited);
|
||||
assert.equal(roots[0].size, 409600);
|
||||
assert(closed);
|
||||
visited = []; closed = false;
|
||||
const all = api.call({args: {}}).result;
|
||||
assert.deepEqual(visited, ['/rom', '/overlay', '/', '/mnt/USB Disk']);
|
||||
assert.equal(all.length, 4, 'existing callers must retain all mounts');
|
||||
assert(closed);
|
||||
console.log('Root-only storage query and backward-compatible full mount listing passed');
|
||||
@@ -0,0 +1,29 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const source = fs.readFileSync(path.join(__dirname, '../htdocs/luci-static/resources/view/status/index.js'), 'utf8');
|
||||
const view = new Function('view', 'network', 'L', source)(
|
||||
{extend: o => o}, {flushCache: () => Promise.resolve()},
|
||||
{bind: (fn, ctx, ...args) => fn.bind(ctx, ...args)});
|
||||
(async () => {
|
||||
let release, queries = 0;
|
||||
const results = [];
|
||||
const slow = {deferFirstLoad: true, load: () => { queries++; return new Promise(r => {release = r;}); }};
|
||||
const fast = {load: () => Promise.resolve('system ready')};
|
||||
const container = {hasAttribute: () => true};
|
||||
view.applyIncludeResult = (include, el, result) => results.push(result);
|
||||
await view.poll_status([slow, fast], [container, container], false);
|
||||
assert.deepEqual(results, ['system ready'], 'slow wireless must not block system rendering');
|
||||
await view.poll_status([slow, fast], [container, container], false);
|
||||
assert.equal(queries, 1, 'polls must not duplicate an outstanding wireless query');
|
||||
assert.equal(results.length, 2, 'system must continue refreshing while wireless is pending');
|
||||
release('wireless ready');
|
||||
await slow._pendingLoad;
|
||||
assert.equal(results[2], 'wireless ready');
|
||||
assert.equal(slow._pendingLoad, null);
|
||||
slow.load = () => Promise.reject(new Error('radio not ready'));
|
||||
await view.poll_status([slow, fast], [container, container], false);
|
||||
await slow._pendingLoad;
|
||||
assert.equal(slow._pendingLoad, null, 'failed wireless query must be retried on a later poll');
|
||||
console.log('Overview asynchronous rendering, in-flight coalescing and failure retry passed');
|
||||
})().catch(e => {console.error(e); process.exit(1);});
|
||||
@@ -61,5 +61,26 @@ function networks() { return uci.sections('wireless', 'wifi-iface').map(s => ({
|
||||
config.wifi0.disabled = '0';
|
||||
resolver = await view.loadIwinfoResolver(radios(), networks());
|
||||
assert.deepEqual(resolver.queryTargets, ['radio0'], 'mixed setups must not probe bare QCA radios');
|
||||
for (const type of ['mtwifi', 'mt_dbdc', 'mtdbdc', 'ralink']) {
|
||||
config = {
|
||||
ra: {'.type':'wifi-device', type}, rai: {'.type':'wifi-device', type},
|
||||
ra0: {'.type':'wifi-iface', device:'ra', ifname:'ra0'},
|
||||
cfg5g: {'.type':'wifi-iface', device:'rai', ifname:'rai0'},
|
||||
rai1: {'.type':'wifi-iface', device:'rai', disabled:'1'}
|
||||
};
|
||||
calls = [];
|
||||
resolver = await view.loadIwinfoResolver(radios(), networks());
|
||||
assert.deepEqual(resolver.queryTargets, ['ra0', 'rai0']);
|
||||
assert.equal(resolver.aliasMap.cfg5g, 'rai0');
|
||||
view.iwinfoResolver = resolver;
|
||||
await view.loadIwinfoInfoMap(resolver);
|
||||
for (const net of networks()) await view.getAssocListForNetwork(net);
|
||||
assert.deepEqual(calls, [['info','ra0'], ['info','rai0'], ['assoclist','ra0'], ['assoclist','rai0']],
|
||||
type + ': query only enabled real VIFs, without enumeration or synthetic netids');
|
||||
delete config.ra0.ifname;
|
||||
config.cfg5g.disabled = '1';
|
||||
resolver = await view.loadIwinfoResolver(radios(), networks());
|
||||
assert.deepEqual(resolver.queryTargets, ['ra0'], 'legacy section name is a valid VIF');
|
||||
}
|
||||
console.log('Wi-Fi status: disabled radios/VAPs, active VAP, custom ifname, missing VAP and mixed backends passed');
|
||||
})().catch(e => {console.error(e); process.exit(1);});
|
||||
Reference in new issue
Block a user