Skip to content

Commit ed48249

Browse files
authored
chore: additional e2e tests for gatewayconfig + network config (#709)
1 parent 1807d59 commit ed48249

1 file changed

Lines changed: 170 additions & 0 deletions

File tree

tests/smoketests/object-oriented/gateway-config.test.ts

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,4 +711,174 @@ describe('smoketest: object-oriented gateway config', () => {
711711
});
712712
},
713713
);
714+
715+
// Tests for gateway config with network policy interactions
716+
// Uses a shared devbox setup similar to 'comprehensive gateway proxying tests'
717+
//
718+
// KNOWN LIMITATION: As of this writing, gateway URLs (e.g., gateway.runloop.pro)
719+
// are not accessible from devboxes that have network policies applied, even with
720+
// allow_all: true. The gateway service runs on internal infrastructure and network
721+
// policies may not properly whitelist access to it. The setup tests below verify
722+
// that devboxes can be created with both gateway configs and network policies,
723+
// and that the configuration is properly applied. The actual gateway request tests
724+
// are skipped until the backend infrastructure supports this combination.
725+
(process.env['RUN_SMOKETESTS'] ? describe : describe.skip)(
726+
'gateway config with network policy',
727+
() => {
728+
let devbox: Devbox | undefined;
729+
let gatewayConfig: GatewayConfig | undefined;
730+
let networkPolicy: NetworkPolicy | undefined;
731+
const testSecretName = uniqueName('gw-np-test-secret');
732+
let gatewayUrl: string;
733+
let gatewayToken: string;
734+
735+
beforeAll(async () => {
736+
const runloopApiKey = process.env['RUNLOOP_API_KEY'];
737+
expect(runloopApiKey).toBeTruthy();
738+
const baseUrl = process.env['RUNLOOP_BASE_URL'] || 'https://api.runloop.ai';
739+
740+
// Create network policy with allow_all for this test suite
741+
networkPolicy = await sdk.networkPolicy.create({
742+
name: uniqueName('gw-np-test-policy'),
743+
allow_all: true,
744+
description: 'Network policy for gateway + network policy tests',
745+
});
746+
747+
// Create secret for gateway auth
748+
await sdk.api.secrets.create({
749+
name: testSecretName,
750+
value: runloopApiKey!,
751+
});
752+
753+
// Create gateway config
754+
gatewayConfig = await sdk.gatewayConfig.create({
755+
name: uniqueName('gw-np-test-gateway'),
756+
endpoint: baseUrl,
757+
auth_mechanism: { type: 'bearer' },
758+
});
759+
760+
// Create devbox with both gateway and network policy
761+
devbox = await sdk.devbox.create({
762+
name: uniqueName('gw-np-test-devbox'),
763+
launch_parameters: {
764+
resource_size_request: 'X_SMALL',
765+
keep_alive_time_seconds: 300,
766+
network_policy_id: networkPolicy.id,
767+
},
768+
gateways: {
769+
RUNLOOP: {
770+
gateway: gatewayConfig.id,
771+
secret: testSecretName,
772+
},
773+
},
774+
});
775+
776+
// Get gateway URL and token
777+
const urlResult = await devbox.cmd.exec('echo $RUNLOOP_URL');
778+
gatewayUrl = (await urlResult.stdout()).trim();
779+
780+
const tokenResult = await devbox.cmd.exec('echo $RUNLOOP');
781+
gatewayToken = (await tokenResult.stdout()).trim();
782+
783+
expect(gatewayUrl).toBeTruthy();
784+
expect(gatewayToken.startsWith('gws_')).toBe(true);
785+
}, MEDIUM_TIMEOUT);
786+
787+
afterAll(async () => {
788+
if (devbox) {
789+
try {
790+
await devbox.shutdown();
791+
} catch {
792+
// Ignore
793+
}
794+
}
795+
await cleanUpGatewayConfig(gatewayConfig);
796+
await cleanUpPolicy(networkPolicy);
797+
try {
798+
await sdk.api.secrets.delete(testSecretName);
799+
} catch {
800+
// Ignore
801+
}
802+
});
803+
804+
test('devbox with network policy and gateway can be created', async () => {
805+
expect(devbox).toBeDefined();
806+
expect(devbox!.id).toBeTruthy();
807+
});
808+
809+
test('devbox has network policy applied', async () => {
810+
expect(devbox).toBeDefined();
811+
const info = await devbox!.getInfo();
812+
expect(info.launch_parameters.network_policy_id).toBe(networkPolicy!.id);
813+
});
814+
815+
test('devbox has gateway config applied', async () => {
816+
expect(devbox).toBeDefined();
817+
const info = await devbox!.getInfo();
818+
expect(info.gateway_specs).toBeDefined();
819+
expect(info.gateway_specs?.['RUNLOOP']).toBeDefined();
820+
expect(info.gateway_specs?.['RUNLOOP']?.gateway_config_id).toBe(gatewayConfig!.id);
821+
});
822+
823+
test('gateway env vars are set correctly', async () => {
824+
expect(gatewayUrl).toBeTruthy();
825+
expect(gatewayUrl.startsWith('http')).toBe(true);
826+
expect(gatewayToken).toBeTruthy();
827+
expect(gatewayToken.startsWith('gws_')).toBe(true);
828+
});
829+
830+
test('network policy info is retrievable', async () => {
831+
expect(networkPolicy).toBeDefined();
832+
const info = await networkPolicy!.getInfo();
833+
expect(info.id).toBe(networkPolicy!.id);
834+
expect(info.egress.allow_all).toBe(true);
835+
});
836+
837+
test('gateway config info is retrievable', async () => {
838+
expect(gatewayConfig).toBeDefined();
839+
const info = await gatewayConfig!.getInfo();
840+
expect(info.id).toBe(gatewayConfig!.id);
841+
expect(info.auth_mechanism.type).toBe('bearer');
842+
});
843+
844+
// The following tests are currently skipped because gateway URLs are not
845+
// accessible from devboxes with network policies applied (see comment above)
846+
// Uncomment these when the backend infrastructure is updated to support this.
847+
/*
848+
test('GET request through gateway with network policy', async () => {
849+
const curlCmd = `curl -s -w "\\nHTTP_CODE:%{http_code}" --connect-timeout 30 -H "Authorization: Bearer ${gatewayToken}" "${gatewayUrl}/v1/devboxes?limit=1"`;
850+
const result = await devbox!.cmd.exec(curlCmd);
851+
const output = (await result.stdout()).trim();
852+
const lines = output.split('\n');
853+
const httpCodeLine = lines.pop() || '';
854+
const responseBody = lines.join('\n');
855+
const httpCode = parseInt(httpCodeLine.replace('HTTP_CODE:', ''), 10);
856+
857+
expect(httpCode).toBe(200);
858+
const response = JSON.parse(responseBody);
859+
expect(response).toBeDefined();
860+
expect(Array.isArray(response.devboxes)).toBe(true);
861+
});
862+
863+
test('POST request through gateway with network policy', async () => {
864+
const secretName = uniqueName('gw-np-created-secret');
865+
const curlCmd = `curl -s -w "\\nHTTP_CODE:%{http_code}" --connect-timeout 30 -X POST -H "Authorization: Bearer ${gatewayToken}" -H "Content-Type: application/json" -d '{"name": "${secretName}", "value": "test-value"}' "${gatewayUrl}/v1/secrets"`;
866+
const result = await devbox!.cmd.exec(curlCmd);
867+
const output = (await result.stdout()).trim();
868+
const lines = output.split('\n');
869+
const httpCodeLine = lines.pop() || '';
870+
const httpCode = parseInt(httpCodeLine.replace('HTTP_CODE:', ''), 10);
871+
872+
expect(httpCode).toBe(200);
873+
874+
// Clean up the created secret
875+
try {
876+
await sdk.api.secrets.delete(secretName);
877+
} catch {
878+
// Ignore
879+
}
880+
});
881+
*/
882+
},
883+
);
714884
});

0 commit comments

Comments
 (0)