Update Harbor client and gateway integration workflows
Build and Deploy Gateway / build-and-push (push) Failing after 14s
Build and Deploy Gateway / deploy (push) Has been skipped

This commit is contained in:
2026-08-19 18:16:10 +03:00
parent 416b2b294a
commit daec12e013
63 changed files with 5016 additions and 108 deletions
+66 -1
View File
@@ -8,7 +8,13 @@ process.env.APP_MODE = 'gateway';
process.env.DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'vpn-proxy-gateway-test-'));
process.env.SING_BOX_CACHE = path.join(process.env.DATA_DIR, 'cache.db');
const { buildGatewayConfig } = await import(`../../dist/server/singbox.js?gateway=${Date.now()}`);
const {
buildDualChannelGatewayConfig,
buildGatewayConfig,
dualChannelConfigMatchesApplied,
fingerprintConfiguredOutbound,
fingerprintSelectedOutbound,
} = await import(`../../dist/server/singbox.js?gateway=${Date.now()}`);
const subscriptionConfig = {
outbounds: [{
@@ -59,3 +65,62 @@ test('gateway preserves mixed user-rule order and dynamic VPN target', () => {
assert.deepEqual(config.experimental.clash_api, { external_controller: '127.0.0.1:19090' });
assert.equal(config.route.final, 'test-vpn');
});
test('gateway dual-channel config fixes probes to role tags and keeps inbound connections', () => {
const reserveConfig = structuredClone(subscriptionConfig);
reserveConfig.outbounds[0].tag = 'same-provider-tag';
const primaryConfig = structuredClone(subscriptionConfig);
primaryConfig.outbounds[0].tag = 'same-provider-tag';
const config = buildDualChannelGatewayConfig({
primary: { subscriptionConfig: primaryConfig, selectedServerId: 'same-provider-tag' },
reserve: { subscriptionConfig: reserveConfig, selectedServerId: 'same-provider-tag' },
}, {
routeRules: [{ type: 'domain', value: 'api.example.com', enabled: true, outbound: 'vpn' }],
});
assert.deepEqual(config.outbounds.map(({ tag }) => tag), [
'channel-primary', 'channel-reserve', 'channel-selector', 'direct',
]);
assert.deepEqual(config.outbounds[2], {
type: 'selector',
tag: 'channel-selector',
outbounds: ['channel-primary', 'channel-reserve'],
default: 'channel-primary',
interrupt_exist_connections: false,
});
assert.deepEqual(config.route.rules.slice(1, 5), [
{ inbound: ['diagnostics-primary-in'], outbound: 'channel-primary' },
{ inbound: ['diagnostics-reserve-in'], outbound: 'channel-reserve' },
{ inbound: ['diagnostics-vpn-in'], outbound: 'channel-selector' },
{ domain: ['api.example.com'], outbound: 'channel-selector' },
]);
assert.equal(config.route.final, 'channel-selector');
const restoredReserve = buildDualChannelGatewayConfig({
primary: { subscriptionConfig: primaryConfig, selectedServerId: 'same-provider-tag' },
reserve: { subscriptionConfig: reserveConfig, selectedServerId: 'same-provider-tag' },
}, { defaultRole: 'reserve' });
assert.equal(restoredReserve.outbounds[2].default, 'channel-reserve');
});
test('cached dual-channel outbounds must match the applied provider fingerprints', () => {
const config = buildDualChannelGatewayConfig({
primary: { subscriptionConfig, selectedServerId: 'test-vpn' },
reserve: { subscriptionConfig, selectedServerId: 'test-vpn' },
});
const expected = fingerprintSelectedOutbound(subscriptionConfig, 'test-vpn');
const applied = {
primary: { profileId: 'primary', serverId: 'test-vpn' },
reserve: { profileId: 'reserve', serverId: 'test-vpn' },
primaryConfigFingerprint: expected,
reserveConfigFingerprint: expected,
};
assert.equal(dualChannelConfigMatchesApplied(config, applied, 'primary'), true);
assert.equal(dualChannelConfigMatchesApplied(config, applied, 'reserve'), false);
assert.equal(fingerprintConfiguredOutbound(config.outbounds[0], 'test-vpn'), expected);
config.outbounds[0].uuid = '11111111-1111-4111-8111-111111111111';
assert.notEqual(fingerprintConfiguredOutbound(config.outbounds[0], 'test-vpn'), expected);
assert.equal(dualChannelConfigMatchesApplied(config, applied, 'primary'), false);
config.outbounds[0].uuid = subscriptionConfig.outbounds[0].uuid;
config.outbounds[2].outbounds = ['channel-primary'];
assert.equal(dualChannelConfigMatchesApplied(config, applied, 'primary'), false);
});