AWS devicefarm documentation change
Summary
Added comprehensive examples for uploading apps/tests to Device Farm using AWS CLI and SDKs (Python, Java, JavaScript, C#, Ruby) with presigned S3 URLs
Security assessment
The change documents secure upload patterns using temporary S3 presigned URLs (expiring after 24 hours) which is a security best practice. However, there is no evidence this addresses a specific vulnerability - it's standard documentation of existing security-relevant functionality.
Diff
diff --git a/devicefarm/latest/developerguide/api-ref.md b/devicefarm/latest/developerguide/api-ref.md index aba211760..cfe4748d9 100644 --- a//devicefarm/latest/developerguide/api-ref.md +++ b//devicefarm/latest/developerguide/api-ref.md @@ -5 +5 @@ -Example: Using the AWS SDK to start a Device Farm run and collect artifacts +Example: Using the AWS CLI or SDK to upload an app or test to Device FarmExample: Using the AWS SDK to start a Device Farm run and collect artifacts @@ -19,0 +20,542 @@ The AWS SDK provides access to every AWS service, including Device Farm, Amazon +## Example: Using the AWS CLI or SDK to upload an app or test to Device Farm + +The following examples show how to create an upload on Device Farm using the AWS CLI or using the AWS SDK in various languages. Uploads are the core building blocks for scheduling test runs on Device Farm, and include the following: + + * Your app + + * Your test + + * Your [test spec file](./custom-test-environment-test-spec.html) + + + + +Uploads are created using the [`CreateUpload`](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_CreateUpload.html) API. This API returns an S3 presigned URL that you can push your upload to using an HTTP PUT request. The URL expires after 24 hours. + +AWS CLI + + +_Note: this example uses the[ command-line tool `curl`](https://curl.se/) to push the app to Device Farm._ + +First, create a project if you haven't already done so. + + + $ aws devicefarm create-project --name MyProjectName + +This will show output such as the following: + + + { + "project": { + "name": "MyProjectName", + "arn": "arn:aws:devicefarm:us-west-2:123456789101:project:5e01a8c7-c861-4c0a-b1d5-12345EXAMPLE", + "created": 1535675814.414 + } + } + +Then, do the following to create your upload and push it to Device Farm. In this example, we'll be creating an Android app upload using a local APK file. For more upload type information, including details about iOS app upload types, please see our API documentation for creating an [`Upload`](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_Upload.html). + + + $ export APP_PATH="/local/path/to/my_sample_app.apk" + $ export APP_TYPE="ANDROID_APP" + +First, we create the upload in Device Farm: + + + $ aws devicefarm create-upload \ + --project-arn "arn:aws:devicefarm:us-west-2:123456789101:project:5e01a8c7-c861-4c0a-b1d5-12345EXAMPLE" \ + --name "$(basename "$APP_PATH")" \ + --type "$APP_TYPE" + +This will show output such as the following: + + + { + "upload": { + "arn": "arn:aws:devicefarm:us-west-2:385076942068:upload:490a6350-0ba3-43e5-83f5-d2896b069a34/a120e848-c57b-4e8d-a720-d750a0c4d936", + "name": "my_sample_app.apk", + "created": 1760747318.266, + "type": "ANDROID_APP", + "status": "INITIALIZED", + "url": "https://prod-us-west-2-uploads.s3.dualstack.us-west-2.amazonaws.com/arn%3Aaws%3Adevicefarm%3Aus-west-2...", + "category": "PRIVATE" + } + } + +Then, do a PUT call using curl to push the app to Device Farm's S3 bucket: + + + $ curl -T "$APP_PATH" "https://prod-us-west-2-uploads.s3.dualstack.us-west-2.amazonaws.com/arn%3Aaws%3Adevicefarm%3Aus-west-2..." + +Finally, wait for the app to be in "succeeded" status: + + + $ aws devicefarm get-upload --arn "arn:aws:devicefarm:us-west-2:385076942068:upload:490a6350-0ba3-43e5-83f5-d2896b069a34/a120e848-c57b-4e8d-a720-d750a0c4d936" + +This will show output such as the following: + + + { + "upload": { + "arn": "arn:aws:devicefarm:us-west-2:385076942068:upload:490a6350-0ba3-43e5-83f5-d2896b069a34/a120e848-c57b-4e8d-a720-d750a0c4d936", + "name": "my_sample_app.apk", + "created": 1760747318.266, + "type": "ANDROID_APP", + "status": "SUCCEEDED", + "url": "https://prod-us-west-2-uploads.s3.dualstack.us-west-2.amazonaws.com/arn%3Aaws%3Adevicefarm%3Aus-west-2...", + "metadata": "{\"activity_name\":\"com.amazonaws.devicefarm.android.referenceapp.Activities.MainActivity\",\"package_name\":\"com.amazonaws.devicefarm.android.referenceapp\",...}", + "category": "PRIVATE" + } + } + +Python + + +_Note: this example uses the third-party`requests` package to push the app to Device Farm, as well as the AWS SDK for Python `boto3`._ + +First, create a project if you haven't already done so. + + + import boto3 + + client = boto3.client("devicefarm", region_name="us-west-2") + resp = client.create_project(name="MyProjectName") + + print(resp) + # Response will be something like: + # { + # "project": { + # "name": "MyProjectName", + # "arn": "arn:aws:devicefarm:us-west-2:123456789101:project:5e01a8c7-c861-4c0a-b1d5-12345EXAMPLE", + # "created": 1535675814.414 + # } + # } + + +Then, do the following to create your upload and push it to Device Farm. In this example, we'll be creating an Android app upload using a local APK file. For more upload type information, including details about iOS app upload types, please see our API documentation for creating an [`Upload`](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_Upload.html). + + + import os + import time + import datetime + import requests + from pathlib import Path + import boto3 + + + def upload_device_farm_file(): + project_arn = "arn:aws:devicefarm:us-west-2:123456789101:project:5e01a8c7-c861-4c0a-b1d5-12345EXAMPLE" + app_path = Path("/local/path/to/my_sample_app.apk") + file_type = "ANDROID_APP" + + if not app_path.is_file(): + raise RuntimeError(f"{app_path} is not a valid app file path") + + client = boto3.client("devicefarm", region_name="us-west-2") + + # 1) Create the upload in Device Farm + create = client.create_upload( + projectArn=project_arn, + name=app_path.name, + type=file_type, + contentType="application/octet-stream", + ) + upload = create["upload"] + upload_arn = upload["arn"] + upload_url = upload["url"] + # This will show output such as the following: + # { "upload": { "arn": "...", "name": "my_sample_app.apk", "type": "ANDROID_APP", "status": "INITIALIZED", "url": "https://..." } } + + # 2) Do an HTTP PUT command to push the file to the pre-signed S3 URL + with app_path.open("rb") as fh: + print(f"Uploading {app_path.name} to Device Farm...") + put_resp = requests.put(upload_url, data=fh, headers={"Content-Type": "application/octet-stream"}) + put_resp.raise_for_status() + + # 3) Wait for the app to be in "SUCCEEDED" status (or fail/timeout) + timeout_seconds = 30 + start = time.time() + while True: + get_resp = client.get_upload(arn=upload_arn) + status = get_resp["upload"]["status"] + msg = get_resp["upload"].get("message") or get_resp["upload"].get("metadata") or "" + elapsed = datetime.timedelta(seconds=int(time.time() - start)) + print(f"[{elapsed}] status={status}{' - ' + msg if msg else ''}") + + if status == "SUCCEEDED": + print(f"Upload complete: {upload_arn}") + return upload_arn + if status == "FAILED": + raise RuntimeError(f"Device Farm failed to process upload: {msg}") + + if (time.time() - start) > timeout_seconds: + raise RuntimeError(f"Timed out after {timeout_seconds}s waiting for upload to process (last status={status}).") + + time.sleep(1) + + upload_device_farm_file() + + +Java + + +_Note: this example uses the AWS SDK for Java v2 and`HttpClient` to push the app to Device Farm, and is compatible with JDK versions 11 and higher._ + +First, create a project if you haven't already done so. + + + import software.amazon.awssdk.regions.Region; + import software.amazon.awssdk.services.devicefarm.DeviceFarmClient; + import software.amazon.awssdk.services.devicefarm.model.CreateProjectRequest; + import software.amazon.awssdk.services.devicefarm.model.CreateProjectResponse; +