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
4 changes: 4 additions & 0 deletions scripts/build-xcuitest-apple.sh
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ xcodebuild build-for-testing \
AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID="$RUNNER_TEST_BUNDLE_ID" \
COMPILER_INDEX_STORE_ENABLE=NO \
ENABLE_CODE_COVERAGE=NO \
-IDEPackageSupportDisableManifestSandbox=1 \
-IDEPackageSupportDisablePluginExecutionSandbox=1 \
ENABLE_USER_SCRIPT_SANDBOXING=NO \
OTHER_SWIFT_FLAGS='$(inherited) -disable-sandbox' \
$SIGNING_BUILD_SETTINGS

node --experimental-strip-types scripts/patch-xcuitest-runner-icon.ts "$DERIVED_PATH"
Expand Down
10 changes: 10 additions & 0 deletions scripts/write-xcuitest-cache-metadata.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,15 @@ function resolveSigningBuildSettings() {
];
}

function resolveSandboxBuildArgs() {
return [
'-IDEPackageSupportDisableManifestSandbox=1',
'-IDEPackageSupportDisablePluginExecutionSandbox=1',
'ENABLE_USER_SCRIPT_SANDBOXING=NO',
'OTHER_SWIFT_FLAGS=$(inherited) -disable-sandbox',
];
}

const appBundleId = resolveRunnerAppBundleId();
const testBundleId = resolveRunnerTestBundleId();
const metadata = {
Expand All @@ -214,6 +223,7 @@ const metadata = {
],
runnerSigningBuildSettings: resolveSigningBuildSettings(),
runnerPerformanceBuildSettings: ['COMPILER_INDEX_STORE_ENABLE=NO', 'ENABLE_CODE_COVERAGE=NO'],
runnerSandboxBuildArgs: resolveSandboxBuildArgs(),
};

const artifacts = resolveRunnerCacheArtifacts();
Expand Down
41 changes: 41 additions & 0 deletions src/platforms/ios/__tests__/runner-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
resolveRunnerDerivedPath,
resolveRunnerCacheMetadataPath,
resolveRunnerPerformanceBuildSettings,
resolveRunnerSandboxBuildArgs,
shouldDeleteRunnerDerivedRootEntry,
writeRunnerCacheMetadata,
xctestrunReferencesProjectRoot,
Expand Down Expand Up @@ -475,6 +476,15 @@ test('resolveRunnerPerformanceBuildSettings disables indexing and code coverage'
]);
});

test('resolveRunnerSandboxBuildArgs disables nested Xcode and Swift sandboxing', () => {
assert.deepEqual(resolveRunnerSandboxBuildArgs(), [
'-IDEPackageSupportDisableManifestSandbox=1',
'-IDEPackageSupportDisablePluginExecutionSandbox=1',
'ENABLE_USER_SCRIPT_SANDBOXING=NO',
'OTHER_SWIFT_FLAGS=$(inherited) -disable-sandbox',
]);
});

test('resolveRunnerBundleBuildSettings returns default bundle identifiers', () => {
assert.deepEqual(resolveRunnerBundleBuildSettings({}), [
'AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=com.callstack.agentdevice.runner',
Expand Down Expand Up @@ -1195,6 +1205,37 @@ test('ensureXctestrun rebuilds cached runner when metadata package version misma
assert.equal(rebuiltMetadata.artifacts?.xctestrunPath, rebuiltXctestrunPath);
});

test('ensureXctestrunArtifact passes sandbox-disabling settings to xcodebuild', async () => {
const projectRoot = repoRoot;
const tmpDir = await makeProjectTmpDir();
const derivedPath = path.join(tmpDir, 'custom-derived');
const rebuiltXctestrunPath = path.join(derivedPath, 'Build', 'Products', 'rebuilt.xctestrun');

withRunnerDerivedPathEnv(derivedPath);

mockRunCmdStreaming.mockImplementationOnce(async () => {
await fs.promises.mkdir(path.join(derivedPath, 'Build', 'Products', 'Runner.app'), {
recursive: true,
});
writeXctestrunFixture(rebuiltXctestrunPath, {
projectRoot,
productRelativePaths: ['Runner.app'],
});
});

const result = await ensureXctestrunArtifact(iosSimulator, {
forceRunnerXctestrunRebuild: true,
});

assert.equal(result.xctestrunPath, rebuiltXctestrunPath);
assert.equal(mockRunCmdStreaming.mock.calls.length, 1);
const args = mockRunCmdStreaming.mock.calls[0]?.[1] ?? [];
assert.equal(args.includes('-IDEPackageSupportDisableManifestSandbox=1'), true);
assert.equal(args.includes('-IDEPackageSupportDisablePluginExecutionSandbox=1'), true);
assert.equal(args.includes('ENABLE_USER_SCRIPT_SANDBOXING=NO'), true);
assert.equal(args.includes('OTHER_SWIFT_FLAGS=$(inherited) -disable-sandbox'), true);
});

test('ensureXctestrunArtifact stress-recovers after a bad restored artifact', async () => {
const projectRoot = repoRoot;
const tmpDir = await makeProjectTmpDir();
Expand Down
14 changes: 14 additions & 0 deletions src/platforms/ios/runner-xctestrun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ const RUNNER_XCTESTRUN_CAPTURE_OPTIONS = {
SystemAttachmentLifetime: 'keepNever',
UserAttachmentLifetime: 'keepNever',
} as const;
const RUNNER_SANDBOX_BUILD_ARGS = [
'-IDEPackageSupportDisableManifestSandbox=1',
'-IDEPackageSupportDisablePluginExecutionSandbox=1',
'ENABLE_USER_SCRIPT_SANDBOXING=NO',
'OTHER_SWIFT_FLAGS=$(inherited) -disable-sandbox',
] as const;

const runnerXctestrunBuildLocks = new Map<string, Promise<unknown>>();
const badRunnerArtifactsForRun = new Set<string>();
Expand Down Expand Up @@ -107,6 +113,7 @@ export type RunnerXctestrunCacheMetadata = {
runnerBundleBuildSettings: string[];
runnerSigningBuildSettings: string[];
runnerPerformanceBuildSettings: string[];
runnerSandboxBuildArgs: string[];
artifacts?: RunnerXctestrunCacheArtifacts;
};

Expand Down Expand Up @@ -758,6 +765,7 @@ export function resolveExpectedRunnerCacheMetadata(
device.platform,
),
runnerPerformanceBuildSettings: resolveRunnerPerformanceBuildSettings(),
runnerSandboxBuildArgs: resolveRunnerSandboxBuildArgs(),
};
}

Expand Down Expand Up @@ -1363,6 +1371,7 @@ async function buildRunnerXctestrun(
);
const provisioningArgs = device.kind === 'device' ? ['-allowProvisioningUpdates'] : [];
const performanceBuildSettings = resolveRunnerPerformanceBuildSettings();
const sandboxBuildArgs = resolveRunnerSandboxBuildArgs();
const simulatorSetRedirect = await acquireXcodebuildSimulatorSetRedirect(device);
try {
await runCmdStreaming(
Expand All @@ -1382,6 +1391,7 @@ async function buildRunnerXctestrun(
'-derivedDataPath',
derived,
...performanceBuildSettings,
...sandboxBuildArgs,
...runnerBundleBuildSettings,
...provisioningArgs,
...signingBuildSettings,
Expand Down Expand Up @@ -1486,6 +1496,10 @@ export function resolveRunnerPerformanceBuildSettings(): string[] {
return ['COMPILER_INDEX_STORE_ENABLE=NO', 'ENABLE_CODE_COVERAGE=NO'];
}

export function resolveRunnerSandboxBuildArgs(): string[] {
return [...RUNNER_SANDBOX_BUILD_ARGS];
}

function shouldCleanDerived(): boolean {
return isEnvTruthy(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED);
}
Expand Down
Loading