mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-15 00:17:09 +00:00
fix(image-analysis): harden runtime and provisioning
This commit is contained in:
1 parent
6d1c895721
commit
77b488f8b1
21 files changed
+811
-169
No files matched your search
@@ -0,0 +1,61 @@
|
||||
import { describe, expect, it } from 'bun:test';
|
||||
import { resolveImageAnalysisRuntimeConnection } from '../../../../src/utils/hooks';
|
||||
|
||||
describe('resolveImageAnalysisRuntimeConnection', () => {
|
||||
it('returns a direct local runtime connection for local CLIProxy targets', () => {
|
||||
const connection = resolveImageAnalysisRuntimeConnection({
|
||||
proxyTarget: {
|
||||
host: '127.0.0.1',
|
||||
port: 8317,
|
||||
protocol: 'http',
|
||||
isRemote: false,
|
||||
},
|
||||
});
|
||||
|
||||
expect(connection.baseUrl).toBe('http://127.0.0.1:8317');
|
||||
expect(connection.allowSelfSigned).toBe(false);
|
||||
expect(connection.proxyTarget.isRemote).toBe(false);
|
||||
});
|
||||
|
||||
it('returns the remote runtime base URL and TLS flag for self-signed targets', () => {
|
||||
const connection = resolveImageAnalysisRuntimeConnection({
|
||||
proxyTarget: {
|
||||
host: 'remote.example.com',
|
||||
port: 9443,
|
||||
protocol: 'https',
|
||||
authToken: 'remote-token',
|
||||
allowSelfSigned: true,
|
||||
isRemote: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(connection.baseUrl).toBe('https://remote.example.com:9443');
|
||||
expect(connection.apiKey).toBe('remote-token');
|
||||
expect(connection.allowSelfSigned).toBe(true);
|
||||
expect(connection.proxyTarget.isRemote).toBe(true);
|
||||
});
|
||||
|
||||
it('prefers the local tunnel when one is active for a remote target', () => {
|
||||
const connection = resolveImageAnalysisRuntimeConnection({
|
||||
proxyTarget: {
|
||||
host: 'remote.example.com',
|
||||
port: 9443,
|
||||
protocol: 'https',
|
||||
authToken: 'remote-token',
|
||||
allowSelfSigned: true,
|
||||
isRemote: true,
|
||||
},
|
||||
tunnelPort: 9911,
|
||||
});
|
||||
|
||||
expect(connection.baseUrl).toBe('http://127.0.0.1:9911');
|
||||
expect(connection.apiKey).toBe('remote-token');
|
||||
expect(connection.allowSelfSigned).toBe(false);
|
||||
expect(connection.proxyTarget).toMatchObject({
|
||||
host: '127.0.0.1',
|
||||
port: 9911,
|
||||
protocol: 'http',
|
||||
isRemote: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -38,6 +38,7 @@ function createStatus(overrides: Partial<ImageAnalysisStatus> = {}): ImageAnalys
|
||||
describe('image-analysis-runtime-status', () => {
|
||||
it('falls back to native read when provider auth is missing', async () => {
|
||||
const status = await hydrateImageAnalysisRuntimeStatus(createStatus(), {
|
||||
checkRemoteProxy: async () => ({ reachable: false, error: 'not-used' }),
|
||||
getProxyTarget: () => ({
|
||||
host: '127.0.0.1',
|
||||
port: 8317,
|
||||
@@ -63,6 +64,7 @@ describe('image-analysis-runtime-status', () => {
|
||||
|
||||
it('marks an idle local proxy as launchable when auth is ready', async () => {
|
||||
const status = await hydrateImageAnalysisRuntimeStatus(createStatus(), {
|
||||
checkRemoteProxy: async () => ({ reachable: false, error: 'not-used' }),
|
||||
getProxyTarget: () => ({
|
||||
host: '127.0.0.1',
|
||||
port: 8317,
|
||||
@@ -107,7 +109,10 @@ describe('image-analysis-runtime-status', () => {
|
||||
source: 'remote',
|
||||
},
|
||||
],
|
||||
isCliproxyRunning: async () => false,
|
||||
checkRemoteProxy: async () => ({
|
||||
reachable: false,
|
||||
error: 'Remote CLIProxy target remote.example:443 is unreachable.',
|
||||
}),
|
||||
});
|
||||
|
||||
expect(status.authReadiness).toBe('ready');
|
||||
@@ -123,6 +128,7 @@ describe('image-analysis-runtime-status', () => {
|
||||
reason: 'Profile hook is missing from the persisted settings file.',
|
||||
}),
|
||||
{
|
||||
checkRemoteProxy: async () => ({ reachable: false, error: 'not-used' }),
|
||||
getProxyTarget: () => ({
|
||||
host: '127.0.0.1',
|
||||
port: 8317,
|
||||
@@ -147,4 +153,38 @@ describe('image-analysis-runtime-status', () => {
|
||||
expect(status.effectiveRuntimeMode).toBe('cliproxy-image-analysis');
|
||||
expect(status.effectiveRuntimeReason).toContain('Profile hook is missing');
|
||||
});
|
||||
|
||||
it('marks a reachable remote proxy as remote instead of inspecting local 8317', async () => {
|
||||
const status = await hydrateImageAnalysisRuntimeStatus(createStatus(), {
|
||||
getProxyTarget: () => ({
|
||||
host: 'remote.example',
|
||||
port: 443,
|
||||
protocol: 'https',
|
||||
authToken: 'token',
|
||||
managementKey: 'secret',
|
||||
allowSelfSigned: true,
|
||||
isRemote: true,
|
||||
}),
|
||||
fetchRemoteAuthStatus: async () => [
|
||||
{
|
||||
provider: 'ghcp',
|
||||
displayName: 'GitHub Copilot (OAuth)',
|
||||
authenticated: true,
|
||||
tokenFiles: 1,
|
||||
accounts: [],
|
||||
defaultAccount: null,
|
||||
source: 'remote',
|
||||
},
|
||||
],
|
||||
checkRemoteProxy: async () => ({
|
||||
reachable: true,
|
||||
latencyMs: 42,
|
||||
}),
|
||||
isCliproxyRunning: async () => false,
|
||||
});
|
||||
|
||||
expect(status.proxyReadiness).toBe('remote');
|
||||
expect(status.proxyReason).toContain('remote.example:443');
|
||||
expect(status.effectiveRuntimeMode).toBe('cliproxy-image-analysis');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user