mirror of
https://github.com/game-ci/unity-test-runner.git
synced 2026-02-05 03:39:06 +08:00
Added Windows Support (#184)
* Modifying js files to account for win support * Added new powershell scripts to support windows invocation * Fixed undefined error in stack trace logic * Added new func for resolving image tag default * Changed structure of docker.js to match new standard
This commit is contained in:
@@ -4,8 +4,8 @@ import path from 'path';
|
||||
|
||||
describe('Action', () => {
|
||||
describe('compatibility check', () => {
|
||||
it('throws for anything other than linux', () => {
|
||||
if (process.platform !== 'linux') {
|
||||
it('throws for anything other than linux or windows', () => {
|
||||
if (process.platform !== 'linux' && process.platform !== 'win32') {
|
||||
expect(() => Action.checkCompatibility()).toThrow();
|
||||
} else {
|
||||
expect(() => Action.checkCompatibility()).not.toThrow();
|
||||
|
||||
@@ -2,7 +2,7 @@ import path from 'path';
|
||||
|
||||
const Action = {
|
||||
get supportedPlatforms() {
|
||||
return ['linux'];
|
||||
return ['linux', 'win32'];
|
||||
},
|
||||
|
||||
get isRunningLocally() {
|
||||
|
||||
@@ -4,6 +4,21 @@ import path from 'path';
|
||||
|
||||
const Docker = {
|
||||
async run(image, parameters, silent = false) {
|
||||
let runCommand = '';
|
||||
switch (process.platform) {
|
||||
case 'linux':
|
||||
runCommand = this.getLinuxCommand(image, parameters);
|
||||
break;
|
||||
case 'win32':
|
||||
runCommand = this.getWindowsCommand(image, parameters);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Operation system, ${process.platform}, is not supported yet.`);
|
||||
}
|
||||
await exec(runCommand, undefined, { silent });
|
||||
},
|
||||
|
||||
getLinuxCommand(image, parameters): string {
|
||||
const {
|
||||
actionFolder,
|
||||
editorVersion,
|
||||
@@ -28,51 +43,125 @@ const Docker = {
|
||||
testMode === 'all' ? ['playmode', 'editmode', 'COMBINE_RESULTS'] : [testMode]
|
||||
).join(';');
|
||||
|
||||
const command = `docker run \
|
||||
--workdir /github/workspace \
|
||||
--rm \
|
||||
--env UNITY_LICENSE \
|
||||
--env UNITY_LICENSE_FILE \
|
||||
--env UNITY_EMAIL \
|
||||
--env UNITY_PASSWORD \
|
||||
--env UNITY_SERIAL \
|
||||
--env UNITY_VERSION="${editorVersion}" \
|
||||
--env PROJECT_PATH="${projectPath}" \
|
||||
--env CUSTOM_PARAMETERS="${customParameters}" \
|
||||
--env TEST_PLATFORMS="${testPlatforms}" \
|
||||
--env COVERAGE_OPTIONS="${coverageOptions}" \
|
||||
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
|
||||
--env ARTIFACTS_PATH="${artifactsPath}" \
|
||||
--env GITHUB_REF \
|
||||
--env GITHUB_SHA \
|
||||
--env GITHUB_REPOSITORY \
|
||||
--env GITHUB_ACTOR \
|
||||
--env GITHUB_WORKFLOW \
|
||||
--env GITHUB_HEAD_REF \
|
||||
--env GITHUB_BASE_REF \
|
||||
--env GITHUB_EVENT_NAME \
|
||||
--env GITHUB_WORKSPACE=/github/workspace \
|
||||
--env GITHUB_ACTION \
|
||||
--env GITHUB_EVENT_PATH \
|
||||
--env RUNNER_OS \
|
||||
--env RUNNER_TOOL_CACHE \
|
||||
--env RUNNER_TEMP \
|
||||
--env RUNNER_WORKSPACE \
|
||||
--env GIT_PRIVATE_TOKEN="${gitPrivateToken}" \
|
||||
${sshAgent ? '--env SSH_AUTH_SOCK=/ssh-agent' : ''} \
|
||||
--volume "${githubHome}":"/root:z" \
|
||||
--volume "${githubWorkflow}":"/github/workflow:z" \
|
||||
--volume "${workspace}":"/github/workspace:z" \
|
||||
--volume "${actionFolder}/steps":"/steps:z" \
|
||||
--volume "${actionFolder}/entrypoint.sh":"/entrypoint.sh:z" \
|
||||
${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \
|
||||
${sshAgent ? '--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro' : ''} \
|
||||
${useHostNetwork ? '--net=host' : ''} \
|
||||
${githubToken ? '--env USE_EXIT_CODE=false' : '--env USE_EXIT_CODE=true'} \
|
||||
${image} \
|
||||
/bin/bash /entrypoint.sh`;
|
||||
return `docker run \
|
||||
--workdir /github/workspace \
|
||||
--rm \
|
||||
--env UNITY_LICENSE \
|
||||
--env UNITY_LICENSE_FILE \
|
||||
--env UNITY_EMAIL \
|
||||
--env UNITY_PASSWORD \
|
||||
--env UNITY_SERIAL \
|
||||
--env UNITY_VERSION="${editorVersion}" \
|
||||
--env PROJECT_PATH="${projectPath}" \
|
||||
--env CUSTOM_PARAMETERS="${customParameters}" \
|
||||
--env TEST_PLATFORMS="${testPlatforms}" \
|
||||
--env COVERAGE_OPTIONS="${coverageOptions}" \
|
||||
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
|
||||
--env ARTIFACTS_PATH="${artifactsPath}" \
|
||||
--env GITHUB_REF \
|
||||
--env GITHUB_SHA \
|
||||
--env GITHUB_REPOSITORY \
|
||||
--env GITHUB_ACTOR \
|
||||
--env GITHUB_WORKFLOW \
|
||||
--env GITHUB_HEAD_REF \
|
||||
--env GITHUB_BASE_REF \
|
||||
--env GITHUB_EVENT_NAME \
|
||||
--env GITHUB_WORKSPACE="/github/workspace" \
|
||||
--env GITHUB_ACTION \
|
||||
--env GITHUB_EVENT_PATH \
|
||||
--env RUNNER_OS \
|
||||
--env RUNNER_TOOL_CACHE \
|
||||
--env RUNNER_TEMP \
|
||||
--env RUNNER_WORKSPACE \
|
||||
--env GIT_PRIVATE_TOKEN="${gitPrivateToken}" \
|
||||
${sshAgent ? '--env SSH_AUTH_SOCK=/ssh-agent' : ''} \
|
||||
--volume "${githubHome}:/root:z" \
|
||||
--volume "${githubWorkflow}:/github/workflow:z" \
|
||||
--volume "${workspace}:/github/workspace:z" \
|
||||
--volume "${actionFolder}/steps:/steps:z" \
|
||||
--volume "${actionFolder}/entrypoint.sh:/entrypoint.sh:z" \
|
||||
${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \
|
||||
${
|
||||
sshAgent ? `--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro` : ''
|
||||
} \
|
||||
${useHostNetwork ? '--net=host' : ''} \
|
||||
${githubToken ? '--env USE_EXIT_CODE=false' : '--env USE_EXIT_CODE=true'} \
|
||||
${image} \
|
||||
/bin/bash -c /entrypoint.sh`;
|
||||
},
|
||||
|
||||
await exec(command, undefined, { silent });
|
||||
getWindowsCommand(image, parameters): string {
|
||||
const {
|
||||
actionFolder,
|
||||
editorVersion,
|
||||
workspace,
|
||||
projectPath,
|
||||
customParameters,
|
||||
testMode,
|
||||
coverageOptions,
|
||||
artifactsPath,
|
||||
useHostNetwork,
|
||||
sshAgent,
|
||||
gitPrivateToken,
|
||||
githubToken,
|
||||
runnerTemporaryPath,
|
||||
} = parameters;
|
||||
|
||||
const githubHome = path.join(runnerTemporaryPath, '_github_home');
|
||||
if (!existsSync(githubHome)) mkdirSync(githubHome);
|
||||
const githubWorkflow = path.join(runnerTemporaryPath, '_github_workflow');
|
||||
if (!existsSync(githubWorkflow)) mkdirSync(githubWorkflow);
|
||||
const testPlatforms = (
|
||||
testMode === 'all' ? ['playmode', 'editmode', 'COMBINE_RESULTS'] : [testMode]
|
||||
).join(';');
|
||||
|
||||
return `docker run \
|
||||
--workdir /github/workspace \
|
||||
--rm \
|
||||
--env UNITY_LICENSE \
|
||||
--env UNITY_LICENSE_FILE \
|
||||
--env UNITY_EMAIL \
|
||||
--env UNITY_PASSWORD \
|
||||
--env UNITY_SERIAL \
|
||||
--env UNITY_VERSION="${editorVersion}" \
|
||||
--env PROJECT_PATH="${projectPath}" \
|
||||
--env CUSTOM_PARAMETERS="${customParameters}" \
|
||||
--env TEST_PLATFORMS="${testPlatforms}" \
|
||||
--env COVERAGE_OPTIONS="${coverageOptions}" \
|
||||
--env COVERAGE_RESULTS_PATH="CodeCoverage" \
|
||||
--env ARTIFACTS_PATH="${artifactsPath}" \
|
||||
--env GITHUB_REF \
|
||||
--env GITHUB_SHA \
|
||||
--env GITHUB_REPOSITORY \
|
||||
--env GITHUB_ACTOR \
|
||||
--env GITHUB_WORKFLOW \
|
||||
--env GITHUB_HEAD_REF \
|
||||
--env GITHUB_BASE_REF \
|
||||
--env GITHUB_EVENT_NAME \
|
||||
--env GITHUB_WORKSPACE="/github/workspace" \
|
||||
--env GITHUB_ACTION \
|
||||
--env GITHUB_EVENT_PATH \
|
||||
--env RUNNER_OS \
|
||||
--env RUNNER_TOOL_CACHE \
|
||||
--env RUNNER_TEMP \
|
||||
--env RUNNER_WORKSPACE \
|
||||
--env GIT_PRIVATE_TOKEN="${gitPrivateToken}" \
|
||||
${sshAgent ? '--env SSH_AUTH_SOCK=c:/ssh-agent' : ''} \
|
||||
--volume "${githubHome}":"c:/root" \
|
||||
--volume "${githubWorkflow}":"c:/github/workflow" \
|
||||
--volume "${workspace}":"c:/github/workspace" \
|
||||
--volume "${actionFolder}/steps":"c:/steps" \
|
||||
--volume "${actionFolder}":"c:/dist" \
|
||||
${sshAgent ? `--volume ${sshAgent}:c:/ssh-agent` : ''} \
|
||||
${
|
||||
sshAgent
|
||||
? `--volume c:/Users/Administrator/.ssh/known_hosts:c:/root/.ssh/known_hosts`
|
||||
: ''
|
||||
} \
|
||||
${useHostNetwork ? '--net=host' : ''} \
|
||||
${githubToken ? '--env USE_EXIT_CODE=false' : '--env USE_EXIT_CODE=true'} \
|
||||
${image} \
|
||||
powershell c:/dist/entrypoint.ps1`;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class ImageTag {
|
||||
constructor(imageProperties) {
|
||||
const {
|
||||
editorVersion = '2019.2.11f1',
|
||||
targetPlatform = Platform.types.StandaloneLinux64,
|
||||
targetPlatform = ImageTag.getImagePlatformType(process.platform),
|
||||
customImage,
|
||||
} = imageProperties;
|
||||
|
||||
@@ -43,7 +43,7 @@ class ImageTag {
|
||||
generic: '',
|
||||
webgl: 'webgl',
|
||||
mac: 'mac-mono',
|
||||
windows: 'windows-mono',
|
||||
windows: 'windows-il2cpp',
|
||||
linux: 'base',
|
||||
linuxIl2cpp: 'linux-il2cpp',
|
||||
android: 'android',
|
||||
@@ -56,8 +56,25 @@ class ImageTag {
|
||||
switch (platform) {
|
||||
case 'linux':
|
||||
return 'ubuntu';
|
||||
case 'win32':
|
||||
return 'windows';
|
||||
default:
|
||||
throw new Error('The Operating System of this runner is not yet supported.');
|
||||
throw new Error(
|
||||
`The Operating System of this runner, "${platform}", is not yet supported.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static getImagePlatformType(platform) {
|
||||
switch (platform) {
|
||||
case 'linux':
|
||||
return Platform.types.StandaloneLinux64;
|
||||
case 'win32':
|
||||
return Platform.types.StandaloneWindows;
|
||||
default:
|
||||
throw new Error(
|
||||
`The Operating System of this runner, "${platform}", is not yet supported.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,24 @@ describe('ResultsParser', () => {
|
||||
expect(result.annotation).toBeUndefined();
|
||||
});
|
||||
|
||||
test('no cdata in stack trace', () => {
|
||||
const result = ResultsParser.convertTestCase('Test Suite', {
|
||||
_attributes: {
|
||||
name: 'Test Name',
|
||||
duration: '3.14',
|
||||
},
|
||||
failure: {
|
||||
message: { _cdata: 'Message CDATA' },
|
||||
'stack-trace': {},
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.suite).toBe('Test Suite');
|
||||
expect(result.title).toBe('Test Name');
|
||||
expect(result.duration).toBe(3.14);
|
||||
expect(result.annotation).toBeUndefined();
|
||||
});
|
||||
|
||||
test('no annotation path', () => {
|
||||
const result = ResultsParser.convertTestCase('Test Suite', {
|
||||
_attributes: {
|
||||
|
||||
@@ -90,6 +90,10 @@ const ResultsParser = {
|
||||
}
|
||||
|
||||
const trace = failure['stack-trace']._cdata;
|
||||
if (trace === undefined) {
|
||||
core.warning(`No cdata in stack trace for test case: ${fullname}`);
|
||||
return testMeta;
|
||||
}
|
||||
const point = ResultsParser.findAnnotationPoint(trace);
|
||||
if (!point.path || !point.line) {
|
||||
core.warning(`Not able to find annotation point for failed test! Test trace: ${trace}`);
|
||||
|
||||
Reference in New Issue
Block a user