Upload Android benchmark results to S3 (#2964)
This commit is contained in:
17
.github/workflows/android-device-test.yml
vendored
17
.github/workflows/android-device-test.yml
vendored
@@ -162,9 +162,20 @@ jobs:
|
||||
if: (matrix.test.name == 'Android Benchmark' || failure()) && env.run_device_test == 'true'
|
||||
run: |
|
||||
npm install
|
||||
temp_dir="$(mktemp -d)"
|
||||
node scripts/aws-device-farm/store-test-artifacts.mjs ${{ steps.aws_device_farm_run.outputs.runArn }} "$temp_dir"
|
||||
zip -r test_artifacts.zip "$temp_dir"
|
||||
echo results_dir="$(mktemp -d)" >> "$GITHUB_ENV"
|
||||
node scripts/aws-device-farm/store-test-artifacts.mjs --runArn ${{ steps.aws_device_farm_run.outputs.runArn }} --outputDir ${{ env.results_dir }}
|
||||
zip -r test_artifacts.zip ${{ env.results_dir }}
|
||||
|
||||
- name: Store Benchmark Results
|
||||
if: matrix.test.name == 'Android Benchmark' && env.run_device_test == 'true'
|
||||
run: |
|
||||
for zipfile in ${{ env.results_dir }}/*.zip; do
|
||||
unzip "$zipfile" -d "${zipfile%.zip}"
|
||||
done
|
||||
|
||||
find "${{ env.results_dir }}" -name 'benchmark_results.json' | while read -r benchmark_json; do
|
||||
aws s3 cp "$benchmark_json" "s3://maplibre-native/android-benchmark-render/$(uuidgen).json"
|
||||
done
|
||||
|
||||
- name: Upload Test Artifacts
|
||||
if: (matrix.test.name == 'Android Benchmark' || failure()) && env.run_device_test == 'true'
|
||||
|
||||
@@ -3,29 +3,72 @@ import { Readable } from "node:stream";
|
||||
import { finished } from "node:stream/promises";
|
||||
import * as path from "node:path";
|
||||
import * as crypto from "node:crypto";
|
||||
import { parseArgs } from "node:util";
|
||||
|
||||
import { ListArtifactsCommand, ListJobsCommand, ListSuitesCommand } from "@aws-sdk/client-device-farm";
|
||||
import { ArtifactType, ListArtifactsCommand, ListJobsCommand, ListSuitesCommand } from "@aws-sdk/client-device-farm";
|
||||
import { getDeviceFarmClient } from "./device-farm-client.mjs";
|
||||
|
||||
function getArgs() {
|
||||
const {
|
||||
values
|
||||
} = parseArgs({
|
||||
options: {
|
||||
outputDir: {
|
||||
type: "string",
|
||||
},
|
||||
runArn: {
|
||||
type: "string"
|
||||
},
|
||||
testsSuite: {
|
||||
type: "boolean"
|
||||
},
|
||||
customerArtifacts: {
|
||||
type: "boolean"
|
||||
}
|
||||
},
|
||||
});
|
||||
const { outputDir, runArn } = values;
|
||||
if (typeof outputDir !== 'string') usage();
|
||||
|
||||
if (typeof runArn !== 'string') usage();
|
||||
|
||||
function suitesFilter() {
|
||||
const names = new Set();
|
||||
if (values.testsSuite) names.add("Tests Suite");
|
||||
|
||||
if (names.size === 0) return () => true;
|
||||
|
||||
return (/** @type {string} **/ name) => names.has(name);
|
||||
}
|
||||
|
||||
/** @type {() => ArtifactType[]} **/
|
||||
function getArtifactsToDownload() {
|
||||
if (values.customerArtifacts) return ["CUSTOMER_ARTIFACT"];
|
||||
return ['TESTSPEC_OUTPUT', 'CUSTOMER_ARTIFACT', 'CUSTOMER_ARTIFACT_LOG', 'DEVICE_LOG'];
|
||||
}
|
||||
|
||||
return {
|
||||
outputDir,
|
||||
runArn,
|
||||
suitesFilter,
|
||||
artifactsToDownload: getArtifactsToDownload()
|
||||
}
|
||||
}
|
||||
|
||||
const { outputDir, runArn, suitesFilter, artifactsToDownload } = getArgs();
|
||||
|
||||
/**
|
||||
* @returns {never}
|
||||
*/
|
||||
function usage() {
|
||||
console.error("Stores artifacts from AWS Device Farm run");
|
||||
console.error(`Usage: node ${process.argv.at(1)} RUN_ARN OUTPUT_DIR`);
|
||||
console.error("Usage: node store-test-artifacts.mjs --outputDir OUTPUT_DIR --runArn RUN_ARN");
|
||||
console.error("Arguments:")
|
||||
console.error("--customerArtifacts: only download customer artifacts");
|
||||
console.error("--testsSuite: only download stuff from Tests Suite");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (process.argv.length !== 4) usage();
|
||||
|
||||
const arn = process.argv.at(2);
|
||||
const outputDirArg = process.argv.at(3);
|
||||
|
||||
if (typeof arn !== 'string') usage();
|
||||
if (typeof outputDirArg !== 'string') usage();
|
||||
|
||||
const outputDir = outputDirArg;
|
||||
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
console.error("Output dir does not exist");
|
||||
process.exit(1);
|
||||
@@ -46,14 +89,14 @@ async function getTestSpecOutput(arn) {
|
||||
|
||||
await Promise.all((jobs.jobs || []).map(async (job) => {
|
||||
const suites = await deviceFarmClient.send(new ListSuitesCommand({arn: job.arn}));
|
||||
await Promise.all((suites.suites || []).map(async (suite) => {
|
||||
await Promise.all((suites.suites || []).filter(suitesFilter).map(async (suite) => {
|
||||
const artifacts = await deviceFarmClient.send(new ListArtifactsCommand({
|
||||
arn: suite.arn,
|
||||
type: 'FILE'
|
||||
}));
|
||||
await Promise.all((artifacts.artifacts || []).map(async (artifact) => {
|
||||
if (!artifact.name || !artifact.url || !artifact.type) return;
|
||||
if (['TESTSPEC_OUTPUT', 'CUSTOMER_ARTIFACT', 'CUSTOMER_ARTIFACT_LOG', 'DEVICE_LOG'].includes(artifact.type)) {
|
||||
if (artifactsToDownload.includes(artifact.type)) {
|
||||
const filename = `${artifact.name.replaceAll(' ', '_')}-${crypto.randomBytes(10).toString('hex')}.${artifact.extension}`;
|
||||
const res = await fetch(artifact.url);
|
||||
if (!res.ok || !res.body) return;
|
||||
@@ -66,4 +109,4 @@ async function getTestSpecOutput(arn) {
|
||||
}));
|
||||
}
|
||||
|
||||
await getTestSpecOutput(arn);
|
||||
await getTestSpecOutput(runArn);
|
||||
|
||||
Reference in New Issue
Block a user