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
26 changes: 26 additions & 0 deletions tests/fixtures/awf-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export interface AwfOptions {
allowHostPorts?: string; // Ports or port ranges to allow for host access (e.g., '3000' or '3000-8000')
allowFullFilesystemAccess?: boolean; // Allow full filesystem access (disables selective mounting security)
enableApiProxy?: boolean; // Enable API proxy sidecar for LLM credential management
envAll?: boolean; // Pass all host environment variables to container (--env-all)
cliEnv?: Record<string, string>; // Explicit -e KEY=VALUE flags passed to AWF CLI
}

export interface AwfResult {
Expand Down Expand Up @@ -110,6 +112,18 @@ export class AwfRunner {
args.push('--enable-api-proxy');
}

// Add --env-all flag
if (options.envAll) {
args.push('--env-all');
}

// Add explicit -e KEY=VALUE flags
if (options.cliEnv) {
for (const [key, value] of Object.entries(options.cliEnv)) {
args.push('-e', `${key}=${value}`);
}
}

// Add -- separator before command
args.push('--');

Expand Down Expand Up @@ -264,6 +278,18 @@ export class AwfRunner {
args.push('--enable-api-proxy');
}

// Add --env-all flag
if (options.envAll) {
args.push('--env-all');
}

// Add explicit -e KEY=VALUE flags
if (options.cliEnv) {
for (const [key, value] of Object.entries(options.cliEnv)) {
args.push('-e', `${key}=${value}`);
}
}

// Add -- separator before command
args.push('--');

Expand Down
121 changes: 121 additions & 0 deletions tests/integration/environment-variables.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,125 @@ describe('Environment Variable Handling', () => {
expect(result).toSucceed();
expect(result.stdout).toContain('12345');
}, 120000);

describe('--env-all flag', () => {
test('should pass host environment variables into container', async () => {
const result = await runner.runWithSudo(
'echo $AWF_TEST_CUSTOM_VAR',
{
allowDomains: ['github.com'],
logLevel: 'debug',
timeout: 60000,
envAll: true,
env: {
AWF_TEST_CUSTOM_VAR: 'env_all_works',
},
}
);

expect(result).toSucceed();
expect(result.stdout).toContain('env_all_works');
}, 120000);

test('should set proxy environment variables inside container', async () => {
const result = await runner.runWithSudo(
'bash -c "echo HTTP_PROXY=$HTTP_PROXY && echo HTTPS_PROXY=$HTTPS_PROXY"',
{
allowDomains: ['github.com'],
logLevel: 'debug',
timeout: 60000,
envAll: true,
}
);

expect(result).toSucceed();
expect(result.stdout).toMatch(/HTTP_PROXY=http:\/\/172\.30\.0\.10:3128/);
expect(result.stdout).toMatch(/HTTPS_PROXY=http:\/\/172\.30\.0\.10:3128/);
}, 120000);

test('should set JAVA_TOOL_OPTIONS with JVM proxy properties', async () => {
const result = await runner.runWithSudo(
'bash -c "echo $JAVA_TOOL_OPTIONS"',
{
allowDomains: ['github.com'],
logLevel: 'debug',
timeout: 60000,
envAll: true,
}
);

expect(result).toSucceed();
expect(result.stdout).toContain('-Dhttp.proxyHost=');
expect(result.stdout).toContain('-Dhttp.proxyPort=');
expect(result.stdout).toContain('-Dhttps.proxyHost=');
expect(result.stdout).toContain('-Dhttps.proxyPort=');
}, 120000);

test('should work together with explicit -e flags', async () => {
const result = await runner.runWithSudo(
'bash -c "echo HOST_VAR=$AWF_TEST_HOST_VAR && echo CLI_VAR=$AWF_TEST_CLI_VAR"',
{
allowDomains: ['github.com'],
logLevel: 'debug',
timeout: 60000,
envAll: true,
env: {
AWF_TEST_HOST_VAR: 'from_host',
},
cliEnv: {
AWF_TEST_CLI_VAR: 'from_cli_flag',
},
}
);

expect(result).toSucceed();
expect(result.stdout).toContain('HOST_VAR=from_host');
expect(result.stdout).toContain('CLI_VAR=from_cli_flag');
}, 120000);

test('explicit -e should override --env-all for same variable', async () => {
const result = await runner.runWithSudo(
'echo $AWF_TEST_OVERRIDE_VAR',
{
allowDomains: ['github.com'],
logLevel: 'debug',
timeout: 60000,
envAll: true,
env: {
AWF_TEST_OVERRIDE_VAR: 'original_value',
},
cliEnv: {
AWF_TEST_OVERRIDE_VAR: 'overridden_value',
},
}
);

expect(result).toSucceed();
expect(result.stdout).toContain('overridden_value');
expect(result.stdout).not.toContain('original_value');
}, 120000);

test('should exclude system variables like PATH from passthrough', async () => {
const sentinel = '/tmp/awf-sentinel-path-marker';
const result = await runner.runWithSudo(
'echo $PATH',
{
allowDomains: ['github.com'],
logLevel: 'debug',
timeout: 60000,
envAll: true,
env: {
// Prepend sentinel to host PATH so sudo/node still work
PATH: `${sentinel}:${process.env.PATH}`,
},
}
);

expect(result).toSucceed();
// Container PATH should include its own default entries
expect(result.stdout).toContain('/usr/local/bin');
// Host PATH sentinel must NOT leak into the container
expect(result.stdout).not.toContain(sentinel);
}, 120000);
});
});
Loading