xcodebuild testのテスト対象のデバイスやテストケースをappiumぽく簡単に指定できるラッパースクリプトを書いてみた
この記事はiOS2 Advent Calendar 2017の3日目の記事です。
xcodebuild testのテスト対象のデバイスやテストケースをややappiumみたいに簡単に指定できるラッパースクリプトを書いてみました。
なお、CocoaPodsでライブラリ管理をしているプロジェクトを対象としています。CocoaPodsをご利用でない場合は、適宜 -workspace
を -project
オプションに読み替えていただけると幸いです。
スクリプト
スクリプト本体 xcode-wrapper.sh
#!/bin/bash # configuration for project, written here WORKSPACE="ExmapleApp.xcworkspace" APP_SCHEME="ExmapleApp" TEST_SCHEME="ExmapleAppTests" BUILD_CONFIG="Debug" # configuration for test target device written in caps.json TARGET_LABEL=$(jq .target < ./caps.json) DEVICE_NAME=$(jq .[$TARGET_LABEL]."deviceName" < ./caps.json | tr -d '"') PLATFORM_VERSION=$(jq .[$TARGET_LABEL]."platformVersion" < ./caps.json | tr -d '"') DEVICE_ID=$(jq .[$TARGET_LABEL]."udid" < ./caps.json | tr -d '"') DEVICE_TYPE=$(jq .[$TARGET_LABEL]."type" < ./caps.json | tr -d '"') build() { if [ "$DEVICE_TYPE" = "simulator" ] then # refs: https://qiita.com/roothybrid7/items/19f0aeeee98573dab2a6 xcodebuild \ -sdk iphonesimulator \ -destination "platform=iOS Simulator,name=${DEVICE_NAME},OS=${PLATFORM_VERSION}" \ -configuration "$BUILD_CONFIG" \ -workspace "$WORKSPACE" -scheme "$APP_SCHEME" \ build else xcodebuild \ -sdk iphoneos \ -destination "platform=iOS,id=${DEVICE_ID}" \ -configuration "$BUILD_CONFIG" \ -workspace "$WORKSPACE" -scheme "$APP_SCHEME" \ build fi } test() { if [ "$DEVICE_TYPE" = "simulator" ] then xcodebuild -workspace $WORKSPACE \ -scheme "$TEST_SCHEME" \ -sdk iphonesimulator \ "$TEST_CASE_OPTION" \ -destination "platform=iOS Simulator,name=${DEVICE_NAME},OS=${PLATFORM_VERSION}" test else xcodebuild -workspace $WORKSPACE \ -scheme "$TEST_SCHEME" \ -sdk iphoneos \ "$TEST_CASE_OPTION" \ -destination "platform=iOS,id=${DEVICE_ID}" test fi } if [ $1 == "build" ]; then build fi if [ $1 == "test" ]; then i=1 for OPT in "$@" do if [ $OPT = "-test" ]; then TEST_CASE_OPTION="-only-testing:${TEST_SCHEME}/${@:$(expr $i + 2):1}" test exit 0 fi i=$(expr $i + 1) done test fi
設定ファイル caps.json
"target" の部分を変更してテストを実行するデバイスを切り替えます。
{ "target": "iPhone5", // テストで使うデバイスの指定 "iPhone5": { "type": "simulator", // シミュレータ "deviceName": "iPhone 5", "platformVersion": "9.3", "udid": "" // シミュレータの指定では使わない }, "iPhone6": { "type": "simulator", // シミュレータ "deviceName": "iPhone 6", "platformVersion": "10.0", "udid": "" // シミュレータの指定では使わない }, "iPhone7": { "type": "simulator", // シミュレータ "deviceName": "iPhone 7", "platformVersion": "11.1", "udid": "" // シミュレータの指定では使わない }, "iPad": { "type": "iphoneos", // 実機 "deviceName": "woshidanのiPad", "" // 実機の指定では使わない "platformVersion": "10.3", "udid": "DUMMY_ID" } }
使用例
# 全てのテストを実行する $ ./xcode-wrapper.sh test # ExmapleTestクラスにおいたテストをすべて実行する $ ./xcode-wrapper.sh test -test ExmapleTest # ExmapleTestクラスにおいたテストメソッドtestAを実行する $ ./xcode-wrapper.sh test -test ExmapleTest/testA # アプリをビルドする $ ./xcode-wrapper.sh build
補足
実行されるテストを指定したい
CLIから見守るだけとはいえ、毎回全てのテストを実行するのは時間がかかります。 xcodebuild test
サブコマンドは only-testing
オプションを用いることで実行するテストを指定することができます。
上記のスクリプトでは、-test
オプションを指定することで only-testing
オプションで指定する文字列を与えることができます。スクリプト自体は -test
オプションなしでも利用可能で、その場合は全てのテストを実行します。
利用できるデバイスの名前やID, OSバージョンの組み合わせについて
caps.json
に書くシミュレータや実機デバイスの名前、OSバージョン、IDなどがわからない場合はXCodeの Add Simulators ...
の画面か $ instruments -s devices
コマンドより確認できます。
XCodeのデバイス管理画面から
ターミナルから
$ instruments -s devices ... iPhone SE (10.0) [7DB19BC4-5A56-4D40-93BD-90F551713043] (Simulator) iPhone SE (10.3.1) [10FE1E72-D129-4593-A18B-AE85F4D9DC78] (Simulator) iPhone SE (11.1) [C511B853-09C3-4599-A88F-737296F02DED] (Simulator) iPhone X (11.1) [95022FBF-DDDB-46A8-8978-0129C0A6142D] (Simulator) ...
もっと色々書こうかと思ったのですが力尽きたので現場からは以上です。
XCode Tools CLIのバージョンアップとビルドに必要なパラメータ、権限の変化について
お仕事の都合で古いOSに対してもXCode Tools CLIを使ってビルドする必要があって調べてみても要領を得なかったんだけど少しわかった気がするので、わかったところまで整理してみます*1。
アプリとして実機やシミュレータにインストールできるファイルの種類について
説明 | |
---|---|
.app | xcrun simctl を経由して iPhone simulatorへインストールできる。 xcodebuild build コマンドやXCodeでシミュレータへ向けてビルドすることで作成可能 |
.ipa | アプリストアへリリースしたり、実機へデプロイするときに作成する必要があるファイル形式。 .app や .xcarchive ファイルから開発者の証明書を何らかの形でアタッチするようなプロセスを経て作成 |
参考
- https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/xcodebuild.1.html
- https://qiita.com/HIkaruSato/items/a8d633d1b42c00b5722d
XCode7時代の .ipa 作成方法とXCode8時代の .ipa 作成方法
- XCodeが7の頃は
.ipa
作成に関して.app
ファイルを渡せばxcrun
のPackageApplication
がうまくやってくれていた - XCode8.3. で
PackageApplication
が廃止されてしまった- XCode8.3.2 を使う場合
xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH
というメッセージが出るようになっている
- XCode8.3.2 を使う場合
- このため、
xcrun PackageApplication
の代わりにxcodebuild archive
を使う必要があるxcodebuild
で.xcarchive
を作成した後、.ipa
を作成する際にexportProvisioningProfile
などを自分で設定する必要がある- これの具体的なパス (SampleXXX的なノリなのではなく 'MyMobileApp Distribution Profile' みたいなのりでファイル名などが想像しにくい例が多い) がよくわからなくてつらい
参考
XCode 8.2 -> XCode 8.3 で Automatically manage signing
が有効になっているプロジェクトにおいて .ipa
へのエクスポートが失敗するように
- [試せていない]
exportOptions.plist
のmethod
の値がdevelopment
でない場合、XCodeでビルドしているときに、ログインしているアカウントがAdmin
でない場合、、証明書(開発者登録. キーチェーンに登録している) とProvisioning Profile
(開発者とappIdに紐づいている) が揃っていても権限がたりなくて export に失敗する- [試せていない] CI用にadminにする?
- [試せていない]
xcodebuild -exportArchive -exportOptionsPlist /PATH/exportOptions.plist
で指定するexportOptions.plist
のmethod
の値をdevelopment
にすればうまくいくかも?
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>method</key> <string>development</string> <key>teamID</key> <string>GLPGBQ39X8</string> </dict> </plist>
参考
どうすればいいかわかったら今後追記しますが、詳しい人教えて欲しい感じです。
*1:上長許可あり
ERBとCSVを使って簡単な自分用ドリルを作る
最近シェルの勉強をしたいんですが、以前SQLを勉強した時のように基本的なシェルを反復して書くのが一番では? と思って、ドリルのようなものが欲しくなりました。
そこで、CSVにお題とお題の答えを書き連ねたらアコーディオンで答えを出したり隠したりしてくれるHTMLを出すコードと、そのHTMLを見るアプリ*1を書いたのでポスト。
使い方は、
$ ruby generator/generator.rb input.csv > drill.html
を実行して drill.html
をブラウザで開く、です。アプリで見る場合はさらに
$ cp drill.html cp drill.html CSDriller/app/assets/drill.html
とした後、一緒についているAndroidプロジェクトをビルドしてください。
実際動かしてみると下記のような感じです。
参考
- http://d.hatena.ne.jp/littlebuddha/20081022/1224645199
- https://qiita.com/shizuma/items/7719172eb5e8c29a7d6e
- http://magazine.rubyist.net/?0017-BundledLibraries
- https://qiita.com/kozo002/items/bcf693738a37aa9ee917
特に上記記事のアコーディオンがよすぎて作りたくなったので多謝。
Cocos2d-x 2.2.6をMac OS Sierraで動くようにするまでのメモ
仕事でやってて面白かったので許可を取って公開。
環境
- Cocos2d-x 2.2.6
- Eclipse Oxygen.1a Release (4.7.1a)
- Android NDK, Revision 10e
- Android SDK & tools v24.0.3 のもの一式
- Android Studioとは別に用意
- Eclipseの環境設定で下図のように設定
メモ
プロジェクトの作成
python create_project.py -project MyGame -package com.MyCompany.AwesomeGame -language cpp
Eclipse インストーラからJavaのIDEをインストールして環境変数を設定
Help > Install New SoftWare
Work with
の欄にhttps://dl-ssl.google.com/android/eclipse
を入力
cocos2dxのプロジェクトをインポートとプロジェクト間の依存関係の設定
Import > Andorid > Existing Android Code Into Workspace
でcocos2d-x-2.2.6/cocos2dx
のplatform/andorid/java
をインポートCopy projects into workspace
にチェックしておく
Import > Andorid > Existing Android Code Into Workspace
でcocos2d-x-2.2.6/cocos2dx/ProjectName
をインポートCopy projects into workspace
にチェックしないProjectName
のAndroidManifest.xml 中のminSDKVersion
が小さすぎるので14くらいにあげておく
PackageManager
上でProjectName
の上を右クリックしてProperties > Android
を開き、Libraryのところで、libcocos2dxを指すよう設定するisLibrary
のチェックはしない(アプリプロジェクトにisLibraryのチェックをするとapkが生成されない)
アプリ側のプロジェクトのLinked Resourcesの修正
- プロジェクトのところで右クリックして
Properteis > Resources > Linked Resources
のLinked Resources
のタブを確認。Classes
,cocos2dx
,extensions
,scropting
の壊れているパスを修正
古めのNDKを用意してNDK_ROOTの環境変数を設定
- 古めのNDK(Android NDK, Revision 10e)を https://developer.android.com/ndk/downloads/older_releases.html からDL
Eclipse
のPreferences > Android > NDK
の項目の NDK LocationにDLしてきたNDKを配置したパスを書く
Preferences > Android > NDK
に設定したパスが Eclipse に見えてないことがあるのでC/C++ > Build > Environment
にもNDK_ROOT
として追加Bulid Project
した結果、build_native.sh
は走ってくれたが。。
トラブルシューティング
Could not find BuildTest.apk!
...
- https://stackoverflow.com/questions/4778113/android-eclipse-could-not-find-apk
- アプリケーションプロジェクトのプロパティに
isLibrary
のチェックが入ってないか
Unknown error: Unable to build: the file dx.jar was not loaded from the SDK folder!
Failed to load /Users/woshidan/Library/Android/sdk/build-tools/26.0.2/lib/dx.jar
- https://stackoverflow.com/questions/5228453/android-adt-error-dx-jar-was-not-loaded-from-the-sdk-folder
Eclipse起動時に Failed to get the required ADT version number from the SDK
- Eclipseが想定しているADTのライブラリ構成のパスが古いせいで、ビルドツールの特定のライブラリが見つからないって言われてる(その2)
- Andorid SDKと一緒のディレクトリに入っているツールは
build-tools
以外は最新版しか保持できない。buildtools
以外のツールのバージョンが v26以上だと同様のメッセージが出るのでAndorid Studio用のSDKとは別のディレクトリにEclipse用の古いバージョンのSDKを入れ直してそちらを使う
エミュレータを起動しようとしたら[Start]が押せず詳細を確認したら Google Nexus 5X No longer exists as a device
Description Resource Path Location TypeThe container 'Android Dependencies' references non existing library'cocos2d-x-2.2.6/cocos2dx/platform/android/java/bin/libcocos2dx.jar' ...
- http://renkaze.seesaa.net/article/405756568.html
libcocos2xd
のプロジェクトでjar
を吐き出すパスが別のパスに設定されているlibcocos2dx
のプロジェクトで右クリックしてProperties > Java Build Path < Source
の下側のDefault output folder
をlibcocos2dx/bin/classes
に設定
java.lang.IllegalArgumentException: No configs match configSpec
というエラーでエミュレータで起動するとクラッシュする
- http://mapyo.hatenablog.com/entry/2013/08/27/Mac%E3%81%ABCocos2d-x%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%92%E4%BD%9C%E3%82%8B
- エミュレータ作成時の設定で
Emulation Options
のUse Host GPU
をチェック
Eclipse
でエミュレータを起動しようとしたら PANIC: Missing emulator engine program for 'arm' CPUS...
と出る
- Eclipse の ADT からエミュレータのシステムイメージが見えてないとかそういうことな気がする。
- Android Studioで使っている最新のAndroid SDK & Tools とは別にEclipse用の古いバージョンのSDKを入れ直したら解決した
Google Nexus 5X no longer exists as a device
とでて Nexus 5
のスキンのエミュレータがつけない
- Eclipse の ADT は対応しているバージョンより新しいAndroid SDKのスキンは存在しないものとして扱う、みたいな雰囲気
- Eclipse のデバイスマネージャから選択できるスキンのエミュレータを使う
まとめ
そろそろEclipseでAndroidを開発するのをやめたほうがいいのでは。
現場からは以上です。
ウェブオペレーション サイト運用管理の実践テクニックを読んだ
ウェブオペレーション ―サイト運用管理の実践テクニック (THEORY/IN/PRACTICE)
- 作者: John Allspaw,Jesse Robbins,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/05/14
- メディア: 大型本
- 購入: 10人 クリック: 923回
- この商品を含むブログ (50件) を見る
前職で研修に使われていた記憶があり、いい本なのかなーと思って読みました。 運用系の仕事をしているわけではないので、一ヶ月強かけてなんとか読みおおせた感じです。
各章はかなり生き生きとした文章で、場合によっては「これはもしかして飲み会の書き起こしではないだろうか」「これ開発者の前に出したらグーパンされても文句言えないのでは」と感じた章もいくつかあり、いんたーねっつの進歩を体感することができます。
なんとか読みおおせた印象としては
- ウェブサービスのサーバ構成について、それぞれのサーバの大まかなイメージが頭に描けるようになった
- 結構前の章でいいよって言われていることが次の章でそうでもないよって言われてたりして、道具を使ったり人の意見を採用する前に要件を確認するのは大事だな、と思えた
- もともとあまりシェルになじみのない人でなんでもLL言語+RDBMSで考えがちだったのですが、監視のシステムの実装例でawkなどが出てきたり、道具の得意分野に合わせていろんな道具を操ることについて考えさせられた
- Dynamoの論文の特徴が面白かった
- Consistent hash, read repair, hinted handoffが書いてあったよと紹介されていて、特に気になったのは read repair.
- 高可用性(リクエストがあったらいつでも応答できる)と応答速度/パフォーマンス(速くレスポンスが返ってくる)と一貫性(データに矛盾が生じない)が違う、相反しない、という例がくどくどと書かれていて身にしみた
- 分割耐性はまだ自信がない
- みんな結構データセンタや社内システムの外からファイアウォールでping弾かれてて面白かった
- サーバの監視システムについて、死活監視・リソース監視(Nagiosなど)・それらの結果の表示(Cacti, Muninなど)、みたいなソフトごとの得意領域があるんだなみたいなイメージが湧いた
- レスポンスの配信の節で、サーバとクライアントの間に一度に取得できるオブジェクト数の上限があるということを知らなかったため、デバッグコンソールを眺めてみたり
でした。
個人的に特に面白かったのは、6章、9章、12章、15章。
6章の学生時代のサイト運営経験から右往左往しながらシステムを運用していく様子に共感を覚え、9章の急増したトラフィックへの障害対応の文章を読んでリクエストがどのサーバに順に到達するかのイメージを描き、12章でこの人本当にMySQL好きなんだなという気持ちになり*1、15章で高分散型*2NoSQLの監視ソフトウェアの違いや比較的小さい規模で動かすものと大きい規模で動かすものの思想の違いに思いを馳せたり。。
運用経験のない人が一人で読むとどうなのかな、と思いつつ、ここで紹介されている技術は今の時代ではそれなりに枯れていたり廃れていたり流行っていたりするためインターネットにまとめられた記事を適宜参照しながら進めました。しかしまあ、早口でまくしたてるクセがある他部署の先輩の運用談義を聞かされている風味もあり、本開いてる間はなんだか忙しかったのでした...。
前述の文体が気になる点や2011年出版でやや古いところもあるので、この本のポジションに収まる新しい本とかあったらそちらも読んでみたいです。
現場からは以上です。
Athenaでクエリの実行結果を使い回すために最近投げたクエリとそのquery_execution_idを記録する
Amazon Athena
では
S3上にあるファイルをスキャンした量に応じた料金 + S3をスキャンするためにGETしたリクエスト数(+ファイル容量)
に応じて課金されます。
また、Athenaでは一回SQLを実行した時に query_execution_id
が発行され、同じ query_execution_id
を使って GetQueryResults
のAPIに複数回リクエストを送ると二回目以降は一回目の実行結果が再利用され、新しいクエリは実行されません*1。
このため、一度検索した結果が使い回せるのであれば、 query_execution_id
を控えておいて結果を再利用した方が良いです。
というわけで、雑に CSV
で直近で実行した クエリ
と query_execution_id
の対応を控えておいて、実行しようとしたクエリがすでに実行済みであれば教えてくれるスクリプトを書いたのでポスト。
gem にしようかと思ったけどそれほど大きくなかったのでひとまずこれで。
# athena_query_keeper.rb require "csv" class AthenaQueryKeeper def initialize(csv_path, keepe_count=20) @csv_path = csv_path @keepe_count = keepe_count @keeped_queries = [] begin CSV.foreach(@csv_path) do |row| @keeped_queries.push({ time: row[0], execution_id: row[1], query_string: row[2] }) end rescue Exception => ex puts ex puts "query keeped csv(path=#{csv_path}) was not found or format was broken." puts "new csv will be created." end end def keep(excution_id, query_string) if @keeped_queries.count >= @keepe_count @keeped_queries.slice!(0, @keeped_queries.count + 1 - @keepe_count) end @keeped_queries.push({ time: Time.now.to_i, execution_id: excution_id, query_string: query_string }) flush end def flush CSV.open(@csv_path, 'w') do |csv| @keeped_queries.each do |query| csv << [ query[:time], query[:execution_id], query[:query_string] ] end end end def keeped_execution_id_for(query_string) keeped_query = @keeped_queries.find { |query| query[:query_string] == query_string } if keeped_query.nil? puts "query: #{query_string.slice(0, 60)} ... has been not executed recently." "" else puts "query: \"#{query_string.slice(0, 60)} ... \" has been executed recently." puts "you should reuse that result unless the result update must be used." keeped_query[:execution_id] end end end
# test.rb require 'aws-sdk-athena' require "#{File.dirname(__FILE__)}/athena_query_keeper.rb" query_string = ARGV[0] client = Aws::Athena::Client.new begin query_execution_id = nil athena_query_keeper = AthenaQueryKeeper.new("./sample.csv", 20) keeped_query_id = athena_query_keeper.keeped_execution_id_for query_string if keeped_query_id.empty? start_query_response = client.start_query_execution({ query_string: query_string, query_execution_context: { database: "mydatabase", }, result_configuration: { output_location: "s3://example-woshidan-test/athena_query_result" }, }) sleep(3) query_execution_id = start_query_response.query_execution_id athena_query_keeper.keep(query_execution_id, query_string) else puts "reuse query result for id=#{keeped_query_id}." query_execution_id = keeped_query_id end puts "query_execution_id: #{query_execution_id}" get_query_response = client.get_query_results({ query_execution_id: query_execution_id }) get_query_response.inspect rescue Aws::Athena::Errors::InvalidRequestException => ex puts ex.inspect ensure puts "query request ended." end
$ ruby test.rb 'SELECT * FROM mydatabase."athena_logs_20171003_app" WHERE user_id = "tester" LIMIT 10;' query: SELECT * FROM mydatabase."athena_logs_20171003_app" WHERE us ... has been not executed recently. result_csv_file_key: 32e86285-e0c5-4329-973d-38bd039945e4 #<Aws::Athena::Errors::InvalidRequestException: Query did not finish successfully. Final query state: FAILED> query request ended. $ ruby test.rb 'SELECT * FROM mydatabase."athena_logs_20171003_app" WHERE user_id = "tester" LIMIT 10;' query: "SELECT * FROM mydatabase."athena_logs_20171003_app" WHERE us ... " has been executed recently. you should reuse that result unless the result update must be used. reuse query result for id=32e86285-e0c5-4329-973d-38bd039945e4 result_csv_file_key: 32e86285-e0c5-4329-973d-38bd039945e4 #<Aws::Athena::Errors::InvalidRequestException: Query did not finish successfully. Final query state: FAILED> query request ended.
参考
AWS CLIでAWS Athenaのクエリがデータベースが見つからないためになんども失敗する場合は結果出力先のS3のバケットのregionを確認する
俺の屍を越えていけ、的なメモ。
require 'aws-sdk-athena' client = Aws::Athena::Client.new begin start_response = client.start_query_execution({ query_string: "SELECT * FROM samples limit 10", query_execution_context: { database: "mydatabase", }, result_configuration: { output_location: "s3://sample-woshidan-test-tokyo/athena_query_result" }, }) sleep(5) result_response = client.get_query_results({ query_execution_id: start_response.query_execution_id }) rescue Aws::Athena::Errors::InvalidRequestException => ex puts ex.inspect ensure puts "Ensure" end
上記のコードで aws-sdk-athena
でAthena のクエリを飛ばそうとしたら
Query did not finish successfully. Final query state: FAILED (Aws::Athena::Errors::InvalidRequestException)
というエラーが出て失敗する。なんで失敗したのかさっぱりわからないので、CLIで実行し直すと、
$ aws athena start-query-execution \ > --query-string "SELECT * FROM mydatabase.samples limit 10;" \ > --result-configuration OutputLocation=s3://sample-woshidan-test/athena_query_result { "QueryExecutionId": "f8e45456-238a-44ba-955a-40f048e5c3b2" } $ aws athena get-query-execution --query-execution-id f8e45456-238a-44ba-955a-40f048e5c3b2 { "QueryExecution": { "Status": { "SubmissionDateTime": 1506675885.243, "State": "FAILED", "CompletionDateTime": 1506675885.387, "StateChangeReason": "com.facebook.presto.hive.DataCatalogException: Namespace mydatabase not found. Please check your query." }, "Query": "SELECT * FROM mydatabase.logs limit 10", "Statistics": { "DataScannedInBytes": 0, "EngineExecutionTimeInMillis": 53 }, "ResultConfiguration": { "OutputLocation": "s3://sample-woshidan-test/athena_query_result/f8e45456-238a-44ba-955a-40f048e5c3b2.csv" }, "QueryExecutionId": "f8e45456-238a-44ba-955a-40f048e5c3b2" } }
というメッセージが出て、どうも database
が見つからないらしい。
もしかして、 AWS のアカウントの region
を間違ったかな、とAWS CLIの設定で使う region を Athenaの管理画面で表示されている region に設定しなおしてみると
- region = ap-northeast-1 + region = us-east-2
The S3 location provided to save your query results is invalid. Please check your S3 location is correct and is in the same region and try again. If you continue to see the issue, contact customer support for further assistance.
戻すと
+ region = ap-northeast-1 - region = us-east-2
Query did not finish successfully. Final query state: FAILED (Aws::Athena::Errors::InvalidRequestException)
どっちに設定しても何かしらダメっぽい...
最終的に
自分がAthenaのクライアントとして選んだ aws-athena-client
はその実装でAWS CLIを利用しています。
そして、AWS CLIで設定値として使うregion は ~/.aws/config
で指定しているためか
- クエリを投げるAthenaのデータベースが
~/.aws/config
で指定したregionに存在すること - クエリ結果の出力先のS3のバケットが
~/.aws/config
で指定したregionに存在すること
の2点がAWS CLIでAthenaにクエリを投げるためには必要みたいです。そして最終的に結果出力先のS3のバケットのregionをAthenaのデータベースのregionに揃えてことなきを得ました。
AthenaのクエリでスキャンするS3のバケットのregionは、AWS CLIで使うIAMアカウントがアクセス権を持ってさえいればAthenaのデータベースのregionと違ってもクエリが実行できるのもあっていまいち原因がわからず焦りました。
もしかしたらAthena - S3 間だけでなく、複数のAWSのサービスが協調して動く場合、CLIが一個しかregionの値を持たない、みたいなことが原因で似たようなトラブルはあるかもなと思いつつ、現場からは以上です。