mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-01 16:44:23 +08:00
This commit is contained in:
1 parent
c7bafc635d
commit
c71da84035
264 files changed
+8169
-3944
No files matched your search
@@ -5,7 +5,6 @@ let values = {
|
||||
debug: '0',
|
||||
download_retry: '3',
|
||||
statistics_enabled: '1',
|
||||
license_key: 'abcd1234wxyz',
|
||||
device_vendor: 'Junatum',
|
||||
device_model: 'Test Router',
|
||||
device_arch: 'aarch64',
|
||||
@@ -33,12 +32,6 @@ function to_int(v, def) {
|
||||
return type(n) == 'int' ? n : def;
|
||||
}
|
||||
|
||||
function mask_secret(v) {
|
||||
let s = sprintf('%s', v || '');
|
||||
if (!length(s)) return '';
|
||||
if (length(s) <= 8) return '********';
|
||||
return sprintf('%s...%s', substr(s, 0, 4), substr(s, length(s) - 4));
|
||||
}
|
||||
|
||||
function api_error(code, message, field) {
|
||||
let error = { code: code, message: message };
|
||||
@@ -71,7 +64,6 @@ return {
|
||||
cfg: function(name, def) { return values[name] == null ? def : values[name]; },
|
||||
to_bool: to_bool,
|
||||
to_int: to_int,
|
||||
mask_secret: mask_secret,
|
||||
api_error: api_error,
|
||||
uci_commit_option: uci_commit_option,
|
||||
bool_uci: function(v) { return v ? '1' : '0'; }
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
let state = {
|
||||
license_key: 'existing-license-key',
|
||||
commits: 0,
|
||||
deletes: 0
|
||||
};
|
||||
|
||||
function trim(s) {
|
||||
return replace(s, /^[\r\n\t ]+|[\r\n\t ]+$/g, '');
|
||||
}
|
||||
|
||||
function mask_secret(v) {
|
||||
let s = sprintf('%s', v || '');
|
||||
if (!length(s)) return '';
|
||||
if (length(s) <= 8) return '********';
|
||||
return sprintf('%s...%s', substr(s, 0, 4), substr(s, length(s) - 4));
|
||||
}
|
||||
|
||||
function api_error(code, message, field) {
|
||||
let error = { code: code, message: message };
|
||||
if (field) error.field = field;
|
||||
return { ok: false, error: error };
|
||||
}
|
||||
|
||||
return {
|
||||
state: state,
|
||||
reload_uci: function() { return true; },
|
||||
cfg: function(name, def) { return name == 'license_key' ? state.license_key : def; },
|
||||
trim: trim,
|
||||
mask_secret: mask_secret,
|
||||
api_error: api_error,
|
||||
uci_commit_option: function(name, value) {
|
||||
state.license_key = value;
|
||||
state.commits++;
|
||||
return true;
|
||||
},
|
||||
uci_delete_option: function(name) {
|
||||
state.license_key = '';
|
||||
state.deletes++;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
let state = { refresh_count: 0, statistics_reset_count: 0, accepted: true, reason: '' };
|
||||
|
||||
return {
|
||||
state: state,
|
||||
reset_statistics_upload_state: function() {
|
||||
state.statistics_reset_count++;
|
||||
},
|
||||
start_refresh_async: function() {
|
||||
state.refresh_count++;
|
||||
return { accepted: state.accepted, reason: state.reason };
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
let ubus = require('ubus');
|
||||
let state = { calls: [], timeout: false };
|
||||
|
||||
function popen(command, mode) {
|
||||
push(state.calls, command);
|
||||
if (state.timeout) return null;
|
||||
let name = match(command, /\"name\":\"([^\"]+)\"/);
|
||||
let service_name = name ? name[1] : null;
|
||||
let instance = service_name ? ubus.state.services[service_name] : null;
|
||||
let response = {};
|
||||
if (instance != null) response[service_name] = instance;
|
||||
return {
|
||||
read: function() { return sprintf('%J', response); },
|
||||
close: function() { return true; }
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
state: state,
|
||||
popen: popen,
|
||||
unlink: function() { return true; }
|
||||
};
|
||||
@@ -1,6 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
service_status: function() {
|
||||
return { state: 'running', running: true, lookup_ok: true, instances: { statistics: { running: true } } };
|
||||
},
|
||||
service_instance_running: function(name, instance) {
|
||||
return name == 'safeshield' && instance == 'statistics';
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ let config = {
|
||||
require_wan: '1',
|
||||
refresh_interval_s: '28800',
|
||||
boot_start_delay_s: '30',
|
||||
license_key: 'abcd1234wxyz',
|
||||
apply_local_overrides: '1',
|
||||
device_vendor: 'Junatum',
|
||||
device_model: 'Test Router',
|
||||
@@ -41,8 +40,8 @@ let state = {
|
||||
health_dns_runtime: '1',
|
||||
blocklist_installed: '1',
|
||||
blocklist_file_size_kb: '2048',
|
||||
license_plan: 'pro',
|
||||
license_status: 'active'
|
||||
entitlement_plan: 'pro',
|
||||
entitlement_status: 'active'
|
||||
},
|
||||
warnings: [],
|
||||
errors: []
|
||||
@@ -67,12 +66,6 @@ function to_int(v, def) {
|
||||
return type(n) == 'int' ? n : def;
|
||||
}
|
||||
|
||||
function mask_secret(v) {
|
||||
let s = sprintf('%s', v || '');
|
||||
if (!length(s)) return '';
|
||||
if (length(s) <= 8) return '********';
|
||||
return sprintf('%s...%s', substr(s, 0, 4), substr(s, length(s) - 4));
|
||||
}
|
||||
|
||||
return {
|
||||
PKG_NAME: 'safeshield',
|
||||
@@ -93,6 +86,5 @@ return {
|
||||
file_size_kb: function() { return 0; },
|
||||
to_bool: to_bool,
|
||||
to_optional_bool: to_optional_bool,
|
||||
to_int: to_int,
|
||||
mask_secret: mask_secret
|
||||
to_int: to_int
|
||||
};
|
||||
@@ -1,9 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
let state = { service_running: true, dnsmasq_running: true };
|
||||
|
||||
let state = { service_running: true, dnsmasq_running: true, lookup_ok: true };
|
||||
return {
|
||||
state: state,
|
||||
service_status: function(name) {
|
||||
let running = name == 'dnsmasq' ? state.dnsmasq_running : state.service_running;
|
||||
return { running: running && state.lookup_ok, state: !state.lookup_ok ? 'unknown' : (running ? 'running' : 'stopped'), lookup_ok: state.lookup_ok };
|
||||
},
|
||||
service_running: function() { return state.service_running; },
|
||||
dnsmasq_running: function() { return state.dnsmasq_running; }
|
||||
};
|
||||
@@ -8,8 +8,6 @@ let built = config.build();
|
||||
assert(built.schema.name == 'safeshield.config', 'config schema name is preserved');
|
||||
assert(built.values.enabled == false, 'disabled state is normalized to boolean');
|
||||
assert(built.values.download_retry == 3, 'integer options are normalized');
|
||||
assert(built.license.configured == true, 'configured license is reported');
|
||||
assert(built.license.key_masked == 'abcd...wxyz', 'license key is masked');
|
||||
assert(built.device.memory_mb == 256, 'device memory is normalized to integer');
|
||||
|
||||
let invalid_values = config.update({ args: { values: 'not-an-object' } });
|
||||
@@ -27,8 +25,8 @@ assert(unknown.ok == false && unknown.error.code == 'unknown_option', 'unknown o
|
||||
let dedicated = config.update({ args: { values: { enabled: true } } });
|
||||
assert(dedicated.ok == false && dedicated.error.code == 'dedicated_method_required', 'enabled requires dedicated method');
|
||||
|
||||
let dedicated_license = config.update({ args: { values: { license_key: 'new-key' } } });
|
||||
assert(dedicated_license.ok == false && dedicated_license.error.code == 'dedicated_method_required', 'license_key requires dedicated method');
|
||||
let retired_license_key = config.update({ args: { values: { license_key: 'new-key' } } });
|
||||
assert(retired_license_key.ok == false && retired_license_key.error.code == 'unknown_option', 'retired license_key is not a writable option');
|
||||
|
||||
runtime.state.last_action = '';
|
||||
let statistics = config.update({ args: { values: { statistics_enabled: false } } });
|
||||
|
||||
@@ -22,9 +22,6 @@ assert(core.to_int('42', 7) == 42, 'to_int converts numeric strings');
|
||||
assert(core.to_int('', 7) == 7, 'to_int uses default for empty values');
|
||||
assert(core.to_int(null, 7) == 7, 'to_int uses default for null');
|
||||
|
||||
assert(core.mask_secret('') == '', 'mask_secret keeps empty secrets empty');
|
||||
assert(core.mask_secret('short') == '********', 'mask_secret fully masks short secrets');
|
||||
assert(core.mask_secret('abcd1234wxyz') == 'abcd...wxyz', 'mask_secret partially masks long secrets');
|
||||
|
||||
let error = core.api_error('invalid_value', 'Invalid value', 'field_name');
|
||||
assert(error.ok == false, 'api_error marks response as failed');
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
let core = require('core');
|
||||
let runtime = require('runtime');
|
||||
let license = require('license');
|
||||
|
||||
let current = license.get();
|
||||
assert(current.ok == true && current.license.key == 'existing-license-key', 'license_get returns current key');
|
||||
|
||||
let missing = license.update({ args: {} });
|
||||
assert(missing.ok == false && missing.error.code == 'missing_argument', 'license_update requires license_key');
|
||||
|
||||
let multiline = license.update({ args: { license_key: 'line1\nline2' } });
|
||||
assert(multiline.ok == false && multiline.error.code == 'invalid_license_key', 'license_update rejects line breaks');
|
||||
|
||||
let oversized_key = '';
|
||||
for (let i = 0; i < 513; i++) oversized_key += 'x';
|
||||
let too_long = license.update({ args: { license_key: oversized_key } });
|
||||
assert(too_long.ok == false && too_long.error.code == 'invalid_license_key', 'license_update rejects keys longer than 512 characters');
|
||||
|
||||
runtime.state.refresh_count = 0;
|
||||
runtime.state.statistics_reset_count = 0;
|
||||
let updated = license.update({ args: { license_key: ' new-license-key ' } });
|
||||
assert(updated.ok == true && updated.changed == true, 'license_update accepts a new key');
|
||||
assert(core.state.license_key == 'new-license-key', 'license_update trims key before saving');
|
||||
assert(updated.license.key_masked == 'new-...-key', 'license_update masks saved key');
|
||||
assert(runtime.state.refresh_count == 1, 'license_update requests refresh after change');
|
||||
assert(runtime.state.statistics_reset_count == 1, 'license_update resets statistics upload entitlement after change');
|
||||
|
||||
runtime.state.refresh_count = 0;
|
||||
runtime.state.statistics_reset_count = 0;
|
||||
let unchanged = license.update({ args: { license_key: 'new-license-key' } });
|
||||
assert(unchanged.ok == true && unchanged.changed == false, 'unchanged license does not write');
|
||||
assert(runtime.state.refresh_count == 0, 'unchanged license does not refresh');
|
||||
assert(runtime.state.statistics_reset_count == 0, 'unchanged license keeps statistics upload entitlement');
|
||||
|
||||
runtime.state.statistics_reset_count = 0;
|
||||
let cleared = license.update({ args: { license_key: '' } });
|
||||
assert(cleared.ok == true && cleared.changed == true, 'empty license clears configured key');
|
||||
assert(core.state.license_key == '' && core.state.deletes == 1, 'empty license uses delete helper');
|
||||
assert(cleared.license.configured == false, 'cleared license is reported unconfigured');
|
||||
assert(runtime.state.statistics_reset_count == 1, 'clearing the license resets statistics upload entitlement');
|
||||
|
||||
print('ucode license tests: ok\n');
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
let core = require('core');
|
||||
let ubus = require('ubus');
|
||||
let fs = require('fs');
|
||||
let runtime = require('runtime');
|
||||
|
||||
ubus.state.services.safeshield = {
|
||||
@@ -10,6 +11,7 @@ ubus.state.services.safeshield = {
|
||||
stopped: { running: false }
|
||||
}
|
||||
};
|
||||
assert(runtime.service_status('safeshield', false).state == 'running', 'runtime distinguishes running services');
|
||||
assert(runtime.service_running('safeshield') == true, 'service_running accepts any running instance');
|
||||
assert(runtime.service_instance_running('safeshield', 'refreshd') == true, 'service_instance_running finds a running instance');
|
||||
assert(runtime.service_instance_running('safeshield', 'stopped') == false, 'service_instance_running preserves stopped state');
|
||||
@@ -20,6 +22,18 @@ ubus.state.services.dnsmasq = { instances: { main: { running: true } } };
|
||||
assert(runtime.dnsmasq_running() == true, 'dnsmasq_running accepts a running dnsmasq instance');
|
||||
ubus.state.services.dnsmasq.instances.main.running = false;
|
||||
assert(runtime.dnsmasq_running() == false, 'dnsmasq_running rejects stopped dnsmasq instances');
|
||||
assert(length(fs.state.calls) == 6, 'supported service checks use a separate bounded ubus client while unsupported names are rejected locally');
|
||||
for (let call in fs.state.calls) {
|
||||
assert(index(call, 'ubus -t 2 call service list') >= 0, 'service lookup uses ubus built-in timeout without an external timeout binary');
|
||||
}
|
||||
fs.state.timeout = true;
|
||||
assert(runtime.service_running('safeshield') == false, 'failed or timed out service lookup fails closed');
|
||||
assert(runtime.service_status('safeshield', true).state == 'unknown', 'lookup failure is exposed as unknown');
|
||||
fs.state.timeout = false;
|
||||
let calls_before = length(fs.state.calls);
|
||||
assert(runtime.service_status('safeshield', true).lookup_ok == true, 'failed lookups are not cached');
|
||||
assert(runtime.service_status('safeshield', true).lookup_ok == true, 'successful lookup can be reused briefly');
|
||||
assert(length(fs.state.calls) == calls_before + 1, 'repeated successful lookups share the cached result');
|
||||
|
||||
let action = runtime.run_service_action('status', 1000);
|
||||
assert(action.ok == true && action.rc == 0, 'run_service_action reports successful service commands');
|
||||
|
||||
@@ -5,6 +5,7 @@ let statistics = require('statistics');
|
||||
let result = statistics.build();
|
||||
assert(result.schema.name == 'safeshield.statistics' && result.schema.version == 3, 'statistics schema is preserved');
|
||||
assert(result.enabled == true && result.effective_enabled == true && result.available == true, 'configured and effective statistics availability are reported');
|
||||
assert(result.collector_state == 'running' && result.collector_lookup_ok == true, 'collector lookup detail is exposed');
|
||||
assert(result.collector_running == true, 'statistics collector state is reported');
|
||||
assert(result.snapshot_interval_s == 30 && result.effective_snapshot_interval_s == 30 && result.retention_hours == 24, 'statistics config values are normalized');
|
||||
assert(result.generation_id == 'generation-test', 'statistics generation is preserved');
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
let core = require('core');
|
||||
let runtime = require('runtime');
|
||||
let status = require('status');
|
||||
|
||||
let ready = status.build();
|
||||
assert(ready.runtime.refreshd_state == 'running' && ready.runtime.dnsmasq_state == 'running' && ready.runtime.refreshd_lookup_ok == true, 'healthy status includes successful procd lookup details');
|
||||
runtime.state.lookup_ok = false;
|
||||
let unknown = status.build();
|
||||
assert(unknown.runtime.refreshd_state == 'unknown' && unknown.runtime.refreshd_lookup_ok == false && unknown.active == false, 'unknown service lookups do not claim running');
|
||||
runtime.state.lookup_ok = true;
|
||||
assert(ready.status == 'ready', 'status preserves ready state');
|
||||
assert(ready.summary.label == 'Ready' && ready.summary.severity == 'info', 'ready summary is generated');
|
||||
assert(index(ready.summary.message, '42000 rules active') >= 0, 'ready summary includes active rule count');
|
||||
@@ -11,7 +17,8 @@ assert(ready.artifact.source_count == 2, 'status reports artifact source count')
|
||||
assert(ready.artifact.block_source_count == 1 && ready.artifact.allow_source_count == 1, 'status reports artifact action counts');
|
||||
assert(ready.sources.items[0].last_result == 'ok', 'healthy API source is reported ok');
|
||||
assert(ready.blocklist.installed == true && ready.blocklist.file_size_kb == 2048, 'blocklist state is normalized');
|
||||
assert(ready.license.configured == true && ready.license.key_masked == 'abcd...wxyz', 'license state is masked');
|
||||
assert(ready.entitlement.plan == 'pro' && ready.entitlement.status == 'active', 'Hub entitlement is exposed under the entitlement field');
|
||||
assert(ready.license == null, 'status does not expose the retired license status field');
|
||||
assert(ready.device.device_code == 'xiaomi-ax3000t', 'status exposes the canonical device code');
|
||||
assert(ready.device.device_code_source == 'smartsafehub_firmware', 'status exposes the device code source');
|
||||
assert(ready.health.overall == 'ok', 'healthy ready state reports overall ok');
|
||||
|
||||
Reference in new issue
Block a user