Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions tests/fixtures/awf-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface AwfOptions {
noRateLimit?: boolean; // Disable rate limiting
envAll?: boolean; // Pass all host environment variables to container (--env-all)
cliEnv?: Record<string, string>; // Explicit -e KEY=VALUE flags passed to AWF CLI
skipPull?: boolean; // Use local images without pulling from registry (--skip-pull)
}

export interface AwfResult {
Expand Down Expand Up @@ -76,6 +77,10 @@ export class AwfRunner {
args.push('--build-local');
}

if (options.skipPull) {
args.push('--skip-pull');
}

if (options.imageRegistry) {
args.push('--image-registry', options.imageRegistry);
}
Expand Down Expand Up @@ -256,6 +261,10 @@ export class AwfRunner {
args.push('--build-local');
}

if (options.skipPull) {
args.push('--skip-pull');
}

if (options.imageRegistry) {
args.push('--image-registry', options.imageRegistry);
}
Expand Down
87 changes: 87 additions & 0 deletions tests/integration/skip-pull.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Skip Pull Flag Tests
*
* These tests verify the --skip-pull flag behavior:
* - Success when images are pre-downloaded (uses --build-local first to ensure images exist)
* - Error when images are not available locally
* - Rejection of --skip-pull with --build-local (incompatible flags)
*/

/// <reference path="../jest-custom-matchers.d.ts" />

import { describe, test, expect, beforeAll, afterAll } from '@jest/globals';
import { createRunner, AwfRunner } from '../fixtures/awf-runner';
import { cleanup } from '../fixtures/cleanup';

describe('Skip Pull Flag', () => {
let runner: AwfRunner;

beforeAll(async () => {
await cleanup(false);
runner = createRunner();
});

afterAll(async () => {
await cleanup(false);
});

test('should succeed with --skip-pull when images are pre-downloaded', async () => {
// First, ensure images exist locally by building them
const buildResult = await runner.runWithSudo(
'echo "images built"',
{
allowDomains: ['github.com'],
buildLocal: true,
logLevel: 'debug',
timeout: 120000,
}
);
Comment on lines +29 to +38
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The “pre-download” step uses buildLocal: true, but --build-local builds Compose services without an image: name (Compose auto-names them), while the subsequent --skip-pull run uses GHCR image: ${registry}/…:${tag}. This means the first run does not actually populate the local cache for the images that --skip-pull will try to start, so this test can fail even though the intent is to validate cached-pull behavior.

To make this deterministic, prime the cache by running once with the same GHCR image settings (i.e., without --skip-pull and without --build-local) or explicitly docker pull the expected ${registry}/{squid,agent,api-proxy}:<tag> images before running with --skip-pull.

Suggested change
// First, ensure images exist locally by building them
const buildResult = await runner.runWithSudo(
'echo "images built"',
{
allowDomains: ['github.com'],
buildLocal: true,
logLevel: 'debug',
timeout: 120000,
}
);
// First, ensure images exist locally by running once without --skip-pull or --build-local
const buildResult = await runner.runWithSudo(
'echo "images built"',
{
allowDomains: ['github.com'],
logLevel: 'debug',
timeout: 120000,
}
);

Copilot uses AI. Check for mistakes.
expect(buildResult).toSucceed();

// Now run with --skip-pull, which should use the locally available images
const result = await runner.runWithSudo(
'echo "skip-pull works"',
{
allowDomains: ['github.com'],
skipPull: true,
logLevel: 'debug',
timeout: 60000,
}
);

expect(result).toSucceed();
expect(result.stdout).toContain('skip-pull works');
}, 240000);

test('should fail with --skip-pull when images are not available locally', async () => {
// Use a non-existent image tag so Docker cannot find it locally
const result = await runner.runWithSudo(
'echo "should not reach here"',
{
allowDomains: ['github.com'],
skipPull: true,
imageTag: 'nonexistent-tag-xyz-999',
logLevel: 'debug',
timeout: 60000,
}
);

expect(result).toFail();
}, 120000);

test('should reject --skip-pull with --build-local', async () => {
const result = await runner.runWithSudo(
'echo "should not reach here"',
{
allowDomains: ['github.com'],
skipPull: true,
buildLocal: true,
logLevel: 'debug',
timeout: 30000,
}
);

expect(result).toFail();
expect(result.stderr).toContain('--skip-pull cannot be used with --build-local');
}, 60000);
});
Loading