Edited at

[AWS] Device FarmをCLIで実行してみた

More than 1 year has passed since last update.

AWS CLIでDeviceFarmを利用する場合の実行例をまとめました。

他のサービスと比べて実例がまだ少なく、検索しても CLIリファレンス ぐらいしか出てこなので、少し長くなりましたが実例をほぼそのまま載せています。

"arn"とリージョンの設定が少しややこしいので注意が必要です。実行結果はawsアカウントIDとSignatureのみ"999999999999"に変更していますが、それ以外は実際に実行した結果になっています。


1) プロジェクトの作成

create-projectコマンドで、プロジェクトを作成します。書式と実行結果は以下の通りです。

aws devicefarm create-project --region=<対象リージョン> --name <プロジェクト名>

$ aws devicefarm create-project --region=us-west-2 --name device-test-pj-va01

{
"project": {
"name": "device-test-pj-va01",
"arn": "arn:aws:devicefarm:us-west-2:999999999999:project:abbdcdca-9675-4c74-b0ad-c952ca66f2c5",
"created": 1498811354.048
}
}

作成済みプロジェクトの確認はlist-projectsコマンドで行います。

aws devicefarm list-projects --region=<対象リージョン>

$ aws devicefarm list-projects --region=us-west-2

{
"projects": [
{
"name": "device-test-pj-va01",
"arn": "arn:aws:devicefarm:us-west-2:999999999999:project:abbdcdca-9675-4c74-b0ad-c952ca66f2c5",
"created": 1498811354.048
}
]
}

コンソールでも作成されたことが確認できます。


注意事項


  • DeviceFarmのリージョンですが、今のところ全てus-west-2です。この例では毎回指定してありますが、config設定でデフォルトをus-west-2に設定してあれば指定は必要ありません。

  • コンソールを見ていると、URL(parameter)の一部で別のリージョン(以下の例ではap-northeast-1)が入っているのものがあるのですが、CLIで指定しても動きません。エラーメッセージが分かりづらいですがリージョン指定の問題です。

$ aws devicefarm list-projects --region ap-northeast-1

HTTPSConnectionPool(host='devicefarm.ap-northeast-1.amazonaws.com', port=443): Max retries exceeded with url: /
(Caused by NewConnectionError('<requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x7f455b534c50>
: Failed to establish a new connection: [Errno -2] Name or service not known'
,))


2) DevicePool作成

DevicePoolとはテストを実行するデバイスの一覧です。まず、利用可能なデバイスを取得します。

aws devicefarm list-devices --region=<対象リージョン>

$ aws devicefarm list-devices --region=us-west-2 | jq -r '.devices[] |  "\(.name),\(.arn)"'

Samsung Galaxy Tab 3 10.1" (WiFi),arn:aws:devicefarm:us-west-2::device:268066CE839F45A68487E46A25EEF89E
Apple iPhone 5c,arn:aws:devicefarm:us-west-2::device:9EB7F8906B1849D89E261352C630DA03
Samsung Galaxy S6 Edge SM-G925F,arn:aws:devicefarm:us-west-2::device:4D3ADF7212964893BFD8C13E93E26BD5
Apple iPhone 6 Plus,arn:aws:devicefarm:us-west-2::device:CFD07092060E49B08C494177A90B66EC
Motorola DROID Ultra (Verizon),arn:aws:devicefarm:us-west-2::device:B6B524CF9BF84CA891FFEF1C88E9A279
Samsung Galaxy S4 Active (AT&T),arn:aws:devicefarm:us-west-2::device:577DC08D6B964346B86610CFF090CD59
Apple iPhone 7,arn:aws:devicefarm:us-west-2::device:FD9876C6541D4D6186F338207B4881B2
(・・・以下省略)

一覧の中から利用するデバイスを選択して、そのarnのリストを含むパラメタjsonを作成します。

ここは抽出、変換をがんばる必要があり、Xperia全てを対象とした場合の例は以下の通りです。

$ aws devicefarm list-devices --region=us-west-2 | jq -r '.devices[] |  "\(.name),\(.arn)"' | grep Xperia

Sony Xperia Z1 Compact,arn:aws:devicefarm:us-west-2::device:29B5FCDF48794C89A514939415931DAA
Sony Xperia Z3 Compact,arn:aws:devicefarm:us-west-2::device:133050132D324AA8B264180506232FC1
Sony Xperia Z2,arn:aws:devicefarm:us-west-2::device:30D43F76A0B14F0FA162ED6AC7D4B8AE
Sony Xperia Z5,arn:aws:devicefarm:us-west-2::device:72B1388DC6F941A293C00A8CBD557EF6
Sony Xperia Z3,arn:aws:devicefarm:us-west-2::device:2DA046320998446B84407B50BFBD7757
Sony Xperia Z4 Tablet,arn:aws:devicefarm:us-west-2::device:5EE66F887B4D497F939935C2390EF4D3
$ cat testDevices.json
{
"projectArn": "arn:aws:devicefarm:us-west-2:999999999999:project:d4d3ace3-a2aa-4f5e-80b8-42bdd35e6aa3",
"name": "my-device-pool1",
"description": "my-device-pool1",
"rules":[
{
"attribute": "ARN",
"operator": "IN",
"value": "[\"arn:aws:devicefarm:us-west-2::device:29B5FCDF48794C89A514939415931DAA\",\"arn:aws:devicefarm:us-west-2::device:133050132D324AA8B264180506232FC1\",\"arn:aws:devicefarm:us-west-2::device:30D43F76A0B14F0FA162ED6AC7D4B8AE\",\"arn:aws:devicefarm:us-west-2::device:72B1388DC6F941A293C00A8CBD557EF6\",\"arn:aws:devicefarm:us-west-2::device:2DA046320998446B84407B50BFBD7757\",\"arn:aws:devicefarm:us-west-2::device:5EE66F887B4D497F939935C2390EF4D3\"]"
}
]
}

ここで、"projectArn"は 1) で作成したプロジェクトのarn、"value"は対象のデバイスのarnをコンマ区切りで指定したものです。

jsonが作成できたら、それを引数としてDevicePoolを作成します。

aws devicefarm create-device-pool --region=<対象リージョン> --cli-input-json file://<先ほど作成したファイル>

$ aws devicefarm create-device-pool --region=us-west-2 --cli-input-json file://testDevices.json

{
"devicePool": {
"rules": [
{
"operator": "IN",
"attribute": "ARN",
"value": "[\"arn:aws:devicefarm:us-west-2::device:29B5FCDF48794C89A514939415931DAA\",\"arn:aws:devicefarm:us-west-2::device:133050132D324AA8B264180506232FC1\",\"arn:aws:devicefarm:us-west-2::device:30D43F76A0B14F0FA162ED6AC7D4B8AE\",\"arn:aws:devicefarm:us-west-2::device:72B1388DC6F941A293C00A8CBD557EF6\",\"arn:aws:devicefarm:us-west-2::device:2DA046320998446B84407B50BFBD7757\",\"arn:aws:devicefarm:us-west-2::device:5EE66F887B4D497F939935C2390EF4D3\"]"
}
],
"type": "PRIVATE",
"name": "my-device-pool1",
"arn": "arn:aws:devicefarm:us-west-2:999999999999:devicepool:abbdcdca-9675-4c74-b0ad-c952ca66f2c5/08a8c626-1caa-40e7-887e-7ebb43660a9b",
"description": "my-device-pool1"
}
}

作成済みDevicePoolの確認にはlist-device-poolsコマンドを使用します。引数のarnは、プロジェクトarnです。

aws devicefarm list-device-pools --arn <プロジェクトarn> --region=<対象リージョン>

$ aws devicefarm list-device-pools --arn arn:aws:devicefarm:us-west-2:999999999999:project:abbdcdca-9675-4c74-b0ad-c952ca66f2c5 --region=us-west-2

{
"devicePools": [
{
"rules": [
{
"operator": "IN",
"attribute": "ARN",
"value": "[\"arn:aws:devicefarm:us-west-2::device:29B5FCDF48794C89A514939415931DAA\",\"arn:aws:devicefarm:us-west-2::device:133050132D324AA8B264180506232FC1\",\"arn:aws:devicefarm:us-west-2::device:30D43F76A0B14F0FA162ED6AC7D4B8AE\",\"arn:aws:devicefarm:us-west-2::device:72B1388DC6F941A293C00A8CBD557EF6\",\"arn:aws:devicefarm:us-west-2::device:2DA046320998446B84407B50BFBD7757\",\"arn:aws:devicefarm:us-west-2::device:5EE66F887B4D497F939935C2390EF4D3\"]"
}
],
"type": "PRIVATE",
"name": "my-device-pool1",
"arn": "arn:aws:devicefarm:us-west-2:999999999999:devicepool:abbdcdca-9675-4c74-b0ad-c952ca66f2c5/08a8c626-1caa-40e7-887e-7ebb43660a9b",
"description": "my-device-pool1"
}
]
}

コンソールでも作成されたことが確認できます。


3) ファイルのアップロード

テストで使用するファイルをアップロードします。

アップロード対象のファイルは、Androidアプリ(apk)、iOSアプリ(ipa)、Appiumなどのテストコード(zip)ですが、手順は全て同じです。以下はAndroidアプリの実行例です。


3-1) アップロードURLの取得

まず、create-uploadコマンドを実行してアップロードURLを取得します。

aws devicefarm create-upload --region=<対象リージョン> --project-arn <プロジェクトarn> -name <アップロードするファイル名> --type <アップロードするファイルの種類>

$ aws devicefarm create-upload --region=us-west-2 --project-arn arn:aws:devicefarm:us-west-2:999999999999:project:abbdcdca-9675-4c74-b0ad-c952ca66f2c5 --name app-debug_010-QA.apk --type ANDROID_APP

{
"upload": {
"status": "INITIALIZED",
"name": "app-debug_010-QA.apk",
"created": 1498814391.555,
"url": "https://prod-us-west-2-uploads.s3-us-west-2.amazonaws.com/arn%3Aaws%3Adevicefarm%3Aus-west-2%3A056530783435%3Aproject%3Aabbdcdca-9675-4c74-b0ad-c952ca66f2c5/uploads/arn%3Aaws%3Adevicefarm%3Aus-west-2%3A056530783435%3Aupload%3Aabbdcdca-9675-4c74-b0ad-c952ca66f2c5/c6837154-8222-428e-a691-d0673fac7d93/app-debug_010-QA.apk?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170630T091951Z&X-Amz-SignedHeaders=host&X-Amz-Expires=86400&X-Amz-Credential=AKIAI3XXXXXX7TQL2OZA%2F20170630%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=9999999999999999999999999999999999999999999999999999999999999999",
"type": "ANDROID_APP",
"arn": "arn:aws:devicefarm:us-west-2:999999999999:upload:abbdcdca-9675-4c74-b0ad-c952ca66f2c5/c6837154-8222-428e-a691-d0673fac7d93"
}
}

これでファイルがアップロードされたわけではなく、レスポンスの"url"としてアップロード用のURLが取得されただけです。この後実際にアップロードする必要があります。


3-2) ファイルのアップロード

curl等でファイルアップロードします。urlに、create-uploadコマンドで返されたS3のURL(長いです)を指定します。

$ curl -T app-debug_010-QA.apk "https://prod-us-west-2-uploads.s3-us-west-2.amazonaws.com/arn%3Aaws%3Adevicefarm%3Aus-west-2%3A056530783435%3Aproject%3Aabbdcdca-9675-4c74-b0ad-c952ca66f2c5/uploads/arn%3Aaws%3Adevicefarm%3Aus-west-2%3A056530783435%3Aupload%3Aabbdcdca-9675-4c74-b0ad-c952ca66f2c5/c6837154-8222-428e-a691-d0673fac7d93/app-debug_010-QA.apk?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170630T091951Z&X-Amz-SignedHeaders=host&X-Amz-Expires=86400&X-Amz-Credential=AKIAI3XXXXXX7TQL2OZA%2F20170630%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=9999999999999999999999999999999999999999999999999999999999999999"

アップロードが完了すると、コンソールでもファイルが確認できます。


注意事項


  • 今回の例では、URLをダブルコーテーションで囲まないとエラーになりました。

  • curlの他のオプションで実行した場合 "SignatureDoesNotMatch" や、"MissingContentLength/You must provide the Content-Length HTTP header."が出る場合があります ( 参考:https://forums.aws.amazon.com/thread.jspa?threadID=231815 )

curl "https://prod-us-west-2-uploads.s3-us-west-2.amazonaws.com/arn%3Aaws%3Adevicefarm%3Aus-west-2%3A056530783435%3Aproject%3Aabbdcdca-9675-4c74-b0ad-c952ca66f2c5/uploads/arn%3Aaws%3Adevicefarm%3Aus-west-2%3A056530783435%3Aupload%3Aabbdcdca-9675-4c74-b0ad-c952ca66f2c5/c6837154-8222-428e-a691-d0673fac7d93/app-debug_010-QA.apk?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170630T091951Z&X-Amz-SignedHeaders=host&X-Amz-Expires=86400&X-Amz-Credential=AKIAI3XXXXXX7TQL2OZA%2F20170630%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=9999999999999999999999999999999999999999999999999999999999999999" -X PUT --upload-file /home/azureuser/app-debug_010-QA.apk -H "Content-Type:application/octet-stream;Content-Length:1332683"

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>AAAAAAAAAAAAAAAAAAAA</AWSAccessKeyId><StringToSign>PUT


  • アップロードされたファイルは、現在DeviceFarmの仕様で、アップロード後30日で自動削除されます。期限を延長する方法は無いので、同じファイルで継続してテストしたい場合でも、30日ごとに再アップロードが必要です。


4) テスト実行

プロジェクト、DevicePool、ファイルの準備ができたらschedule-runコマンドでテストを実行します。まず、これまでの結果(から取得されるプロジェクト、DevicePool、アップロードのarn)を集めてパラメタjsonを作成します。

$ cat execTest.json

{
"projectArn": "arn:aws:devicefarm:us-west-2:999999999999:project:d4d3ace3-a2aa-4f5e-80b8-42bdd35e6aa3",
"appArn": "arn:aws:devicefarm:us-west-2:999999999999:upload:d4d3ace3-a2aa-4f5e-80b8-42bdd35e6aa3/78a23ee1-98d0-459a-8391-b3262c15254b",
"devicePoolArn": "arn:aws:devicefarm:us-west-2:999999999999:devicepool:d4d3ace3-a2aa-4f5e-80b8-42bdd35e6aa3/28c5918c-c0e1-4a70-85a7-b67cf7ba4058",
"name": "nakatsu-device-test-001",
"test": {
"type": "BUILTIN_FUZZ"
},
"configuration": {
"locale": "ja_JP"
}
}

schedule-runコマンドに --generate-cli-skeletonオプションを付けて実行すると、全てのオプションを含んだjsonスケルトンが自動生成されます。これ以外のオプションを指定する場合は、スケルトンとCLIリファレンスを参考に追加して下さい。

$ aws devicefarm schedule-run --region=us-west-2 --generate-cli-skeleton

jsonの準備ができたら実行します。

aws devicefarm schedule-run --region=<対象リージョン> --cli-input-json file://<先ほど作成したファイル>

$ aws devicefarm schedule-run --region=us-west-2 --cli-input-json file://execTest.json

{
"run": {
"status": "SCHEDULING",
"name": "nakatsu-device-test-001",
"created": 1498815355.117,
"totalJobs": 6,
"completedJobs": 0,
"platform": "ANDROID_APP",
"result": "PENDING",
"billingMethod": "METERED",
"type": "BUILTIN_FUZZ",
"arn": "arn:aws:devicefarm:us-west-2:999999999999:run:abbdcdca-9675-4c74-b0ad-c952ca66f2c5/3a4176dc-d110-41f4-9ac7-c6b162f144fe",
"counters": {
"skipped": 0,
"warned": 0,
"failed": 0,
"stopped": 0,
"passed": 0,
"errored": 0,
"total": 0
}
}
}

進捗はget-runコマンドのレスポンス"status"で確認します。get-runコマンドの結果がCOMPLETEDになれば完了です。

aws devicefarm get-run --region=<対象リージョン> --arn <schedule-runコマンドから返されたarn>

$ aws devicefarm get-run --region=us-west-2 --arn arn:aws:devicefarm:us-west-2:999999999999:run:abbdcdca-9675-4c74-b0ad-c952ca66f2c5/3a4176dc-d110-41f4-9ac7-c6b162f144fe | jq -r '.run .status'

RUNNING
$ aws devicefarm get-run --region=us-west-2 --arn arn:aws:devicefarm:us-west-2:999999999999:run:abbdcdca-9675-4c74-b0ad-c952ca66f2c5/3a4176dc-d110-41f4-9ac7-c6b162f144fe | jq -r '.run .status'
COMPLETED

コンソールでも結果が確認できます。


5) 結果の確認

最終結果はget-runコマンドのレスポンス"result"で確認します。

aws devicefarm get-run --region=<対象リージョン> --arn <schedule-runコマンドから返されたarn>

$ aws devicefarm get-run --region=us-west-2 --arn arn:aws:devicefarm:us-west-2:999999999999:run:abbdcdca-9675-4c74-b0ad-c952ca66f2c5/3a4176dc-d110-41f4-9ac7-c6b162f144fe

{
"run": {
"status": "COMPLETED",
"name": "nakatsu-device-test-001",
"created": 1498815355.117,
"totalJobs": 6,
"completedJobs": 6,
"deviceMinutes": {
"unmetered": 0.0,
"total": 22.61,
"metered": 14.65
},
"platform": "ANDROID_APP",
"result": "PASSED",
"billingMethod": "METERED",
"type": "BUILTIN_FUZZ",
"arn": "arn:aws:devicefarm:us-west-2:999999999999:run:abbdcdca-9675-4c74-b0ad-c952ca66f2c5/3a4176dc-d110-41f4-9ac7-c6b162f144fe",
"counters": {
"skipped": 0,
"warned": 0,
"failed": 0,
"stopped": 0,
"passed": 18,
"errored": 0,
"total": 18
}
}
}

結果ファイルの取得には、list-artifactsコマンドを使用します。

aws devicefarm list-artifacts --region=<対象リージョン> --arn <schedule-runコマンドから返されたarn> --type <取得するファイルの種類>

$ aws devicefarm list-artifacts --region=us-west-2 --arn arn:aws:devicefarm:us-west-2:999999999999:run:d4d3ace3-a2aa-4f5e-80b8-42bdd35e6aa3/5d4507b3-9d2d-4dfe-9861-5b03bb36d55e --type SCREENSHOT

{
"artifacts": [
{
"url": "https://prod-us-west-2-results.s3-us-west-2.amazonaws.com/999999999999/abbdcdca-9675-4c74-b0ad-c952ca66f2c5/3a4176dc-d110-41f4-9ac7-c6b162f144fe/00000/00001/00000/83e5554a-a6b0-4c07-8156-570278246abf.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170630T095043Z&X-Amz-SignedHeaders=host&X-Amz-Expires=259200&X-Amz-Credential=AKIAI3XXXXXX7TQL2OZA%2F20170630%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=9999999999999999999999999999999999999999999999999999999999999999",
"extension": "png",
"type": "SCREENSHOT",
"name": "background_screenshot_0",
"arn": "arn:aws:devicefarm:us-west-2:999999999999:artifact:abbdcdca-9675-4c74-b0ad-c952ca66f2c5/3a4176dc-d110-41f4-9ac7-c6b162f144fe/00000/00001/00000/00000"
},
{
"url": "https://prod-us-west-2-results.s3-us-west-2.amazonaws.com/999999999999/abbdcdca-9675-4c74-b0ad-c952ca66f2c5/3a4176dc-d110-41f4-9ac7-c6b162f144fe/00000/00001/00000/72f21e0b-6fb9-4ac4-ab69-62e6e8365621.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170630T095043Z&X-Amz-SignedHeaders=host&X-Amz-Expires=259200&X-Amz-Credential=AKIAI3XXXXXX7TQL2OZA%2F20170630%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=9999999999999999999999999999999999999999999999999999999999999999",
"extension": "png",
"type": "SCREENSHOT",
"name": "background_screenshot_1",
"arn": "arn:aws:devicefarm:us-west-2:999999999999:artifact:abbdcdca-9675-4c74-b0ad-c952ca66f2c5/3a4176dc-d110-41f4-9ac7-c6b162f144fe/00000/00001/00000/00001"
},
※以下省略※
]
}

--typeオプションに"FILE"または"LOG"を指定すると、実行ログやVideoファイルも取得することができます。また、デバイスやテストが多くなった場合は、list-jobsやlist-runsコマンドで一部(特定デバイスだけの結果など)を取得することもできます。

実際のファイルは、アップロードと同様に"url"から取得できます。以下はcurlの例です。

$ curl -o test.png "https://prod-us-west-2-results.s3-us-west-2.amazonaws.com/999999999999/d4d3ace3-a2aa-4f5e-80b8-42bdd35e6aa3/5d4507b3-9d2d-4dfe-9861-5b03bb36d55e/00001/00001/00000/67c67b08-65b4-43ce-a6d4-e315e3ad8337.png?AWSAccessKeyId=AKIAI3XXXXXX7TQL2OZA&Expires=1484294431&Signature=9999999999999999999999999999999999999999999999999999999999999999"

以上で、プロジェクトの作成から実行結果まで一通り確認できました。


おわりに

この実行結果は、昨年実際のプロジェクトでDevice Farmを使う機会があり、その実行結果をまとめたものです。その時にはAzure側にも Xamarin Test Cloud があることを知らず、ここだけawsを使っていました!

というわけで次回は Xamarin Test Cloud についても調べてみたいと思います。