mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 04:18:05 +00:00
ci: add fast test budget warning
This commit is contained in:
@@ -95,6 +95,7 @@ jobs:
|
||||
needs: [build]
|
||||
env:
|
||||
BUN_INSTALL_CACHE_DIR: ${{ github.workspace }}/.bun/install/cache
|
||||
FAST_TEST_BUDGET_SECONDS: '90'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
@@ -125,8 +126,32 @@ jobs:
|
||||
name: dist
|
||||
path: dist/
|
||||
|
||||
- name: Test
|
||||
run: bun run test:all
|
||||
- name: Test fast bucket with perf budget
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
start_epoch=$(date +%s)
|
||||
bun run test:fast
|
||||
end_epoch=$(date +%s)
|
||||
elapsed_seconds=$((end_epoch - start_epoch))
|
||||
|
||||
{
|
||||
echo "### test:fast perf budget"
|
||||
echo ""
|
||||
echo "- Elapsed: ${elapsed_seconds}s"
|
||||
echo "- Budget: ${FAST_TEST_BUDGET_SECONDS}s"
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
if (( elapsed_seconds > FAST_TEST_BUDGET_SECONDS )); then
|
||||
echo "::warning::test:fast took ${elapsed_seconds}s (budget ${FAST_TEST_BUDGET_SECONDS}s) - check for undeclared slow tests in scripts/run-test-bucket.js"
|
||||
echo "- Result: warning emitted. Check for undeclared slow tests in scripts/run-test-bucket.js." >> "$GITHUB_STEP_SUMMARY"
|
||||
else
|
||||
echo "- Result: within budget." >> "$GITHUB_STEP_SUMMARY"
|
||||
fi
|
||||
|
||||
- name: Test slow bucket
|
||||
run: bun run test:slow
|
||||
|
||||
- name: Test CLI e2e
|
||||
env:
|
||||
|
||||
@@ -256,12 +256,12 @@ describe('openai proxy daemon lifecycle', () => {
|
||||
}, 35000);
|
||||
|
||||
it('fails when an explicit port is already occupied', async () => {
|
||||
const occupiedPort = await getPort();
|
||||
const server = Bun.serve({
|
||||
port: occupiedPort,
|
||||
port: 0,
|
||||
hostname: '127.0.0.1',
|
||||
fetch: () => new Response('busy'),
|
||||
});
|
||||
const occupiedPort = server.port;
|
||||
|
||||
try {
|
||||
const settingsPath = path.join(tempDir, 'occupied-explicit.settings.json');
|
||||
@@ -298,12 +298,12 @@ describe('openai proxy daemon lifecycle', () => {
|
||||
});
|
||||
|
||||
it('fails when a configured profile port is already occupied', async () => {
|
||||
const occupiedPort = await getPort();
|
||||
const server = Bun.serve({
|
||||
port: occupiedPort,
|
||||
port: 0,
|
||||
hostname: '127.0.0.1',
|
||||
fetch: () => new Response('busy'),
|
||||
});
|
||||
const occupiedPort = server.port;
|
||||
|
||||
try {
|
||||
mutateUnifiedConfig((config) => {
|
||||
@@ -347,12 +347,12 @@ describe('openai proxy daemon lifecycle', () => {
|
||||
});
|
||||
|
||||
it('falls back when a configured shared proxy.port is occupied', async () => {
|
||||
const occupiedPort = await getPort();
|
||||
const server = Bun.serve({
|
||||
port: occupiedPort,
|
||||
port: 0,
|
||||
hostname: '127.0.0.1',
|
||||
fetch: () => new Response('busy'),
|
||||
});
|
||||
const occupiedPort = server.port;
|
||||
|
||||
try {
|
||||
mutateUnifiedConfig((config) => {
|
||||
@@ -396,12 +396,12 @@ describe('openai proxy daemon lifecycle', () => {
|
||||
|
||||
it('keeps the existing proxy running if replacement startup fails', async () => {
|
||||
const firstPort = await getPort();
|
||||
const occupiedPort = await getPort();
|
||||
const busyServer = Bun.serve({
|
||||
port: occupiedPort,
|
||||
port: 0,
|
||||
hostname: '127.0.0.1',
|
||||
fetch: () => new Response('busy'),
|
||||
});
|
||||
const occupiedPort = busyServer.port;
|
||||
|
||||
try {
|
||||
const settingsPath = path.join(tempDir, 'rollback.settings.json');
|
||||
|
||||
@@ -27,7 +27,12 @@ describe('push ci workflow', () => {
|
||||
expect(workflow).toContain("cmd: 'bun run lint'");
|
||||
expect(workflow).toContain("cmd: 'bun run format:check'");
|
||||
expect(workflow).toContain('run: bun run build:all');
|
||||
expect(workflow).toContain('run: bun run test:all');
|
||||
expect(workflow).toContain("FAST_TEST_BUDGET_SECONDS: '90'");
|
||||
expect(workflow).toContain('name: Test fast bucket with perf budget');
|
||||
expect(workflow).toContain('bun run test:fast');
|
||||
expect(workflow).toContain('::warning::test:fast took ${elapsed_seconds}s');
|
||||
expect(workflow).toContain('scripts/run-test-bucket.js');
|
||||
expect(workflow).toContain('run: bun run test:slow');
|
||||
expect(workflow).toContain("CCS_E2E_SKIP_BUILD: '1'");
|
||||
expect(workflow).toContain('run: bun run test:e2e');
|
||||
});
|
||||
|
||||
@@ -165,6 +165,7 @@ let stripAnthropicRoutingEnv: typeof import('../../../src/utils/shell-executor')
|
||||
let stripClaudeCodeEnv: typeof import('../../../src/utils/shell-executor').stripClaudeCodeEnv;
|
||||
let HeadlessExecutor: typeof import('../../../src/delegation/headless-executor').HeadlessExecutor;
|
||||
let SharedManager: typeof import('../../../src/management/shared-manager').default;
|
||||
let stopOpenAICompatProxy: typeof import('../../../src/proxy/proxy-daemon').stopOpenAICompatProxy;
|
||||
|
||||
beforeAll(async () => {
|
||||
registerChildProcessMock();
|
||||
@@ -179,6 +180,9 @@ beforeAll(async () => {
|
||||
|
||||
const headless = await import('../../../src/delegation/headless-executor');
|
||||
HeadlessExecutor = headless.HeadlessExecutor;
|
||||
|
||||
const proxyDaemon = await import('../../../src/proxy/proxy-daemon');
|
||||
stopOpenAICompatProxy = proxyDaemon.stopOpenAICompatProxy;
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
@@ -208,7 +212,14 @@ describe('CLAUDECODE environment stripping', () => {
|
||||
baselineSighupListeners = process.listeners('SIGHUP');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
afterEach(async () => {
|
||||
const tempCcsHome = process.env.CCS_HOME?.startsWith(os.tmpdir())
|
||||
? process.env.CCS_HOME
|
||||
: undefined;
|
||||
if (tempCcsHome) {
|
||||
await stopOpenAICompatProxy();
|
||||
}
|
||||
|
||||
Object.defineProperty(process, 'platform', { value: originalPlatform });
|
||||
delete process.env.CLAUDECODE;
|
||||
delete process.env.claudecode;
|
||||
@@ -253,6 +264,10 @@ describe('CLAUDECODE environment stripping', () => {
|
||||
process.removeListener('SIGHUP', listener as (...args: unknown[]) => void);
|
||||
}
|
||||
}
|
||||
|
||||
if (tempCcsHome) {
|
||||
fs.rmSync(tempCcsHome, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it('stripClaudeCodeEnv removes CLAUDECODE case-insensitively', () => {
|
||||
|
||||
Reference in New Issue
Block a user