knqyf263's blog

自分のためのメモとして残しておくためのブログ。

Goの1.14以前かつChrome 80以上を使っているとgo tool traceが動かない問題

問題

Goにはtrace機能がありgoroutineの実行状況などを可視化出来ます。具体的にはCPUやメモリを計測するときと同じようにpprofを差し込めば使えます。

defer profile.Start(profile.TraceProfile, profile.ProfilePath(".")).Stop()

あとは実行したらtrace.outが出力されるので $ go tool trace trace.out で利用可能です。ですが、自分の環境ではうまく表示されずエラーが出て困っていました。

f:id:knqyf263:20200326010443p:plain

解決策

自分の環境の問題だろうと思っていたのですが、 @orisano 先生に聞いたら同様のエラーが表示されるとのことでした。どうやらChromeがWebComponents V0を廃止したのが原因のようだと@orisano先生が発見しました。

github.com

ということでGo 1.14.1以降を使えば動くようですが、Go 1.14以前かつChrome 80以上だと動かないようです。

Goのpprofがruntime関連の情報しか表示してくれない時の解決方法

問題

Goでpprofを使っていたら以下のようにruntimeの情報しか表示してくれなくなりました。これだとどこがボトルネックなのか分かりません。runtimeのpthread_cond_signalが大きいけどどこから呼ばれているのか分からないし何も分からんという感じです。

f:id:knqyf263:20200326005037p:plain

解決策

GOMAXPROCS=1 を指定すれば良いと @orisano 先生から教わりました。CPUのコア数が多い時に発生しそうな雰囲気ですが詳細は深追いしてないので不明です。これで必ず解決するとは限りませんが自分の環境では改善されました。

イスラエルの良いところ・大変なところ

対象読者

イスラエルに引っ越す可能性があるような人やイスラエル生活に興味がある人向けに少しでも情報提供できればという思いで詳しく書いた記事になります。あくまで住む人対象で観光地とかはあまり触れてないです。それ以外の人はやたら長いだけで読んでも特に得るものないです。

背景

イスラエルに来て半年が経ちました。1年ぐらい経ったら引っ越してみての感想を書こうと思っていたのですが、既に慣れてきて自分の中で新鮮さが失われつつあり、日本もこんな感じじゃなかったっけ?みたいな気持ちになってきたので今のうちに書くことにしました。それでも面倒で放置していたのですが、CEOやCTOからも日本に向けて書いてよって言われたのでついに重い腰を上げました。

最初に断っておくと日本と比べてどっちが良いというわけではなく、一長一短だなと感じています。単にインターネット上に情報が多いほうが良いということで良い点・大変な点を書いてます。実際、自分がこっちに来る前に調べてみたもののアメリカやヨーロッパのようにたくさん日本人が住んでいる国とは違いあまり情報は得られず、良く分からないけど行ってみるか、とノリで来た部分はあります。もし来る前にもう少し情報があれば不安は少し和らいだかもと思うので、未来の誰かの役に立てばということで覚えている限りで全部書きます。何か思い出したらちょくちょく追記していこうかなと思っています。

あと、多分ここに出てくる多くの話はテルアビブの話になります。テルアビブはイスラエルで一番の都市で、自分もそこに住んでいるので必然的にテルアビブで体験したことが多くなります。とはいえイスラエル初心者がいきなりテルアビブというキーワードで検索するかと言うとそうじゃない気がするので(自分がそうじゃなかった)、あえてタイトルは大きめにしています。1つの都市にしか住んだことない人が日本を語ることもありますし、あまり大きく捉えずにそういうこともあるんだなーと思ってもらえれば幸いです。

あくまで主観の話なので、ヨーロッパではそれは常識だ!とか日本でもこの地域ではこうだ!というよりはボケーっと見てもらえればと思います。

気づいたことは大体Twitterに書いてるのでツイートをペタペタ貼ってます。

良いところ

良いところはとても多くて挙げきれないのですが、一応可能な限り説明してみます。

天気が良い

まず、基本ずっと晴れてます。9月に来て12月末まで一回もまともに雨見たことなかったです。今は雨季みたいなやつに入ったので雨が降ってますが、こっちの人に聞くと乾季の9ヶ月ぐらい雨の日が0という年も普通にあるみたいです。

もしかしたら天気がなんぼのもんじゃいと思う人もいるかも知れません。実際こちらに来る前に現地の人に天気良いと言われた時に自分も思ってました。ですが、こちらに来て気づきました。天気は本当に重要です。精神に与える影響が絶大です。こっちに陽気な人が多いのも間違いなく天気のおかげです(適当)。一番好きなところを挙げろと言われたら天気かもしれません。

自分はスクーターで会社に来てますが、雨が降って帰れないかも...とか心配する必要がありません。天気予報をチェックするのが苦手だった自分としては人生のストレスが1割ぐらい減りました。もう天気予報を見るのは諦めて濡れるという紳士的解決策を取っていた自分としてはとても助かっています。犬の散歩も行き放題です。

あと冬も短いので大体暖かいです。とはいえ冬は10度ちょっとぐらいまでは下がるみたいなので、あまり油断しないほうが良いです。

ヨーロッパの町並み

雰囲気はヨーロッパに似ていると思います。オフィスの近くは以下みたいな感じです。

週末には蚤の市のようなものも開かれ歩いてるだけで楽しいです。

そしてTel Avivは普通に都会ですし綺麗です。日本のニュースの印象や中東のイメージとはかけ離れてます。自分も来てからただの都会じゃん...と驚きました。もちろん事前に調べてはいましたが想像以上でした。

ちなみに1人当たり名目国内総生産GDP)では日本は2014年にイスラエルに抜かれています。あまりイメージがないかもしれませんが完全に先進国です。その後もめざましく発展を続けています。

www.nikkei.com

宗教の聖地がある

特に詳しくない自分が語るべきことではないので割愛しますが、エルサレムがあり3つの宗教の聖地になっています。無宗教の自分ですら嘆きの壁は感じるものがあったので歴史に造詣が深い方は感動するのではないかと思います。

ちなみに無宗教と言うよりは"仏教"と答えるほうが良いみたいですが、今のところ無宗教と答えて何か問題になったことはありません。

1kara.tulip-k.jp

Tel Avivは移民も多く割とその辺りゆるい都市なので、会社の人も親は敬虔な信者だけど自分たちの世代はそこまで教えを厳格に守っている人は少ないと言っていました。エルサレムに住んでる人たちはかなりその辺り厳格で、ユダヤ教の制服のようなものも着ています。黒いスーツに黒いハットで全身黒い感じです。ただ一部のユダヤ教の人はあんなの暑くて無理でしょ、と言ってましたし個人差がありそうです。

イスラエルは今選挙のやり直し続きで非常に揉めていますが、より宗教色を強くしてユダヤ教以外の人間を締め出したいという派閥ともっと海外の人を呼び込んでオープンな国にしたいという派閥で争っているみたいです。Tel Avivの人はグローバルな人が多いので後者の考えの人が多いみたいですが、エルサレム周辺の人は前者の考えみたいなので票が真っ二つとのことです。

人が優しい

イスラエルは英語話せる人がかなり多くて、その点では困ることは少ないのですが駅の仕組みとか諸々日常で困ることがあります。そんな時、どうやるんだろう...みたいな顔をしていると大体誰か近づいてきて助けてくれます。駅のチケット売り場で困っていたらやり方を教えてくれましたし(普段は難しくないのですがその日は選挙でちょっと特殊だった)、スーパーで肉の注文とか分からなくて困っていた時も助けてもらいました(日本みたいにパックで売られていなくて、店内にでかい肉が置いてあって量を伝えて切ってもらう)。

また、妻が体調悪くなってベンチで休んでいたら色々な人が声かけてくれたり水買ってきてくれたりしました。全部イスラエルに着いてから2週間ぐらい以内に起きたことで驚きました。

日本で海外から来た人が困っていても自分が積極的に声かけられるかと言うと難しいと思うので、この辺りガンガン行けるのは良いなーと思いました。1回や2回なら良い人もいるんだなーという感じですが、しょっちゅう起きるのでもうこれは国民性と言っても良いんじゃないかと思っています。

上の例は見知らぬ人の例でしたが、社内でも助けられまくっています。銀行口座作ったりとか家の契約したりとか、自分のような外人には簡単ではなくて毎日困難の連続でしたが、その度に会社の人が付き添ってくれたり代理でやってくれたりして何とかなってきました。あまりにも何もできないですし、自分が一人で単独乗り込んでいたら今頃死んでたと思います。アメリカからイスラエルに移住した人とかは割と多いのでもう少しスムーズに行くのですが、日本人はとにかく少ないので銀行でも「日本人は初めてだからなー」とか言われますし難易度高めです。

Wikipediaによると2015年時点でイスラエルにいる日本人は1011名らしいです。自分の大学の学部入学者は毎年1100人ぐらいいたと思うので、それよりも少ないです。

2015年10月時点で在留邦人数は1011名

日本とイスラエルの関係 - Wikipedia

レストランは大体英語メニューが付いていますが、大衆向けのところは回転が早いのでレジの前に行ってからゆっくり見る余裕はありません。なので遠くからメニューを見て予め頼むものを決めておく必要がありますが、大きく書いてあるのは大体ヘブライ語です。そんな時も同僚は常に英訳してくれます。とても助かっているのですが、英語も別に得意じゃないのでちょくちょく理解できてなくて本当にすまぬと思っています。

妻の誕生日が近いと言ったらみんなオススメとかを次々と教えてくれたり代わりに電話でスパ予約してくれたり、マジで優しいです。インターネット開通手続きも代わりにやってもらいましたし、注文した洗濯機が大きすぎて部屋に入らなかった時の交換の交渉とかも全部やってもらいました。これだけ良い人が多いのも天気が影響してるのではないかと疑っています。他にも挙げるとキリがないのでこの辺りにしておきます。

人が陽気

やたらと話しかけてきます。店員とかも気さくな人が多いです。この写真は家の近くのカフェの店員です。

今何時?とか火貸してとかすぐ言われます。近所付き合いも活発なので外出ると最近どう?みたいに話しかけられます。東京で住んでたマンションでは隣に誰が住んでたのかすら知らなかったので大きな変化でした。その辺りは日本の田舎も同じかもしれませんが。

陽気なところ良いなと自分では思っていたのですが、近所の人はスーパーで多めに買ってたら知らないおばさんから「あんた何をそんなにたくさん買うの!」とか言われたりするので陽気すぎてちょっとうざいと言ってました。

シェアスクーターが便利

電動スクーターが至るところに置いてあって、好きなところで乗って好きなところに乗り捨てられます。

電動スクーターがこれだけ普及しているのはサイクルレーンのおかげだと思います。もし車道で車と一緒に走らないとダメだとしたらかなり怖いと思います。

www.bcnretail.com

日本ではサイクルレーンも少ないですし、こういう新しい取り組みに対して障壁が多いので使えるようになるとしても当分先かなと思います。

jp.techcrunch.com

リゾート

テルアビブはビーチがすぐそこにあり、地中海リゾートと呼ばれています。この辺りは既に解説しているブログが多いので割愛します。ビーチ綺麗だし人の密度もハワイとかに比べれば全然少ないので快適です。

sekaishinbun.net

オフィス街とビーチが近い

リゾートなのは良いとして、もしそのリゾートが遠ければ気軽に行けないし実質意味ありません。ですが、テルアビブの凄いところはビーチとオフィスが融合されているところだと思います。ちょうどよい写真を持っていないのですが、若干雰囲気伝わる写真を貼っておきます。

これを見るとビーチと高いビルが近いことがわかります。オフィス街からスクーターで飛ばせば12, 13分でビーチまで着きます。自分の家からであればビーチまで8分です。オフィスまでも8分なので移動が楽です。今日疲れたからビーチ行こうとかも気軽にできます。実際、休日は気分転換ビーチに行ったりすることもちょくちょくあります。そもそもテルアビブは51.79平方kmで小さい都市なのでスクーターでどこでも行けます。

治安が良い

イスラエル行くというと治安大丈夫なの?とか聞かれたりすることがありますが、正直かなり安全です。大枠は以下のブログに書いてある通りです。

https://getnews.jp/archives/2212356getnews.jp

上のブログに書いてないようなことを補足しておきます。まずガザ地区からの攻撃ですが、基本的にTel Avivに届くようなことはほとんどありません。万が一危険性があるような場合はアラームが街中に鳴り響くのでアパートに付いているシェルターに入れば普通に間に合います。

そしてこれは同僚から聞いた話なのですが、そもそもガザはイスラエルに大きなダメージを与えることを望んでいないとのことです。もしそうなれば戦争になり、軍事力で劣るガザは深刻なダメージを受けることになります。なので、適度に緊張感を保つようにしているとのことです。また、ロケット弾を打つとイスラエル市民はシェルターに入ることになり学校等も休校になり会社も休みになります。そうすることで経済的にダメージを与えることが可能です。このように直接的に死者を出すようなダメージを与えるというよりは経済的な狙いのほうが大きいということみたいです。ロケット弾に関してもガザは経済的な余裕がないため威力の大きい高精度なロケット弾は打つことが出来ないようです。さらにイスラエルにはアイアンドームという迎撃ミサイルがあるためほとんどが撃墜されます。ですが、ガザの打つ安いロケット弾よりもアイアンドームのミサイルのほうが高額です。そのためロケット弾を打てば打つほど経済的にはイスラエルにダメージを与えられます。こちらも先程同様の狙いがあるということです。

ということでガザの脅威はあまりありません。もちろん最初にアラームを聞いてシェルター入ったときは驚きましたが、日本の地震の方がやばいだろうという指摘を受けてその通りだと思いました。ロケット弾に慣れているイスラエル人にとっては地震のほうが遥かに怖いと。東日本大震災では死者1万5897人、不明2533人ですが、ここ10年でのガザのロケット弾による死者はそれより遥かに少ないと思われます。

イスラエルパレスチナ紛争として第四次中東戦争以来最大の死傷者と言われているガザ侵攻でも民間人犠牲者は7人です。東日本大震災での死者はほとんど民間人と考えるとロケット弾より断然恐ろしい国に住んでいたのではないかという気がしました。東京に首都直下地震とか来たらどうなるのか考えると恐ろしいです。それに比べたらロケット弾はアイアンドームで頑張れば防げる、とこっちの人に言われてなるほど...と考えさせられました。

ガザ侵攻 (2014年) - Wikipedia

ということで長くなりましたが街中の治安の話に戻します。上のブログにもあるように、こっちの人はレストランとかで平気で財布等の貴重品を置きっぱなしにして離れます。財布も普通にズボンの後ろポケットに入れて剥き出しになっています。フランスとかイタリアでそんなことをしたら一瞬で盗まれると思いますが、こっちはそういう危険な雰囲気も全く無いです。

あとは夜間に女性が1人で出歩いていたりします。子供も夜遅くに外で遊んでいたりします。治安の悪い国ではまず不可能なので安全な国だなと感じています。

そしてつい先日のことですが、自分はショッピングモールで鞄をなくしました。3/11で日本では防災意識を高めようという雰囲気だったと思いますが、危機意識のかけらもない自分は普通に鞄を置きっぱなしにして手ぶらで帰宅しました。何か体が軽いな?とは思いましたが全く気づきませんでした。

鞄にはiPadAirPods Proなどなどそこそこの金額のものが何点か入っていました。これは絶対見つからないなと思って諦めていたのですが、翌日探しに行ったら発見されました。中身も全部無事でした。親切な人が届けていてくれたみたいです。

高価なものが一切盗まれず落とし物が見つかるというのは治安の良さとして伝わりやすいのではないかと思います。

ヨーロッパに観光行ったときは結構怖い地域も多かったのですがイスラエルは怖いと感じることがほとんどないです。こっちに8年住んでいる日本人の方と話したら東京よりもテルアビブの方が治安良いと感じていると言っていました。そう言うのも納得なぐらいです。ただもちろんテルアビブ以外では少し怖いと感じる地域もあります。どこに行っても安全というわけではないので、その点は気をつけてください。

食事が美味しい

個人差あると思いますが、料理は普通に美味しいです。以下はフムスやファラフェル、シャクシューカの写真です。そのあたりのワードでググれば美味しそうな写真出てきます。

朝食は小皿みたいなのがいくつか出てくるのが主流で美味しいです。

ユダヤ教徒が多いのでもっと質素な食事を想像していたのですが、昼にハンバーガー夜にピザとか平気で食べます。正直日本のほうが質素な食事してました。

唯一注意したいのはKosherです。これはユダヤ教徒が守る食事に関する教えなのですが、これがかなり厳しいです。豚はNGですし、エビや貝のように鱗がない魚もNGです。

コーシャジャパン株式会社 | 日本初のKJマーク(コーシャ認定)取得機関

肉と魚を同時に食べることも許されていませんし、肉と乳製品を同時に食べることも出来ません。つまりチーズバーガーは食べられません。そして肉も血抜きが必要なのでジューシーさがあまりありません。そこまで詳しくないので細かいルールは間違っているかもしれません。

基本的にユダヤ教徒ではない人には関係ないのですが、Kosherレストランが街には結構多いです。うっかり知らずに入ってしまうと口に合わない可能性が高いです。Kosherマクドナルドも存在しているのですが、我々の知っているマクドナルドの味だと思って食べると衝撃を受けると思います。観光の記念として挑戦して見る分には良いと思います。

安息日がある

毎週安息日というユダヤ教の休日があります。こちらは金土休みなのですが、金曜の日没から土曜の日没まで労働が許されていません。つまりショッピングモールやレストランは閉まります。さらにバスや電車等の交通機関も全て止まります。そのためどこにも出かけられませんし、出かけても何もすることがないです。

business.nikkei.com

厳格なユダヤ教徒は電化製品も使えないのでテレビやパソコンも利用不可です。料理もできないので前日までに作っておく必要があります。さらに労働の解釈は広く、エレベーターのボタンを押したりするのすら労働に当たります。そのためホテルではどうしているかというと各階に停止するエレベーターが動きます。ボタンを押さずに乗ることが出来ます。Apple Storeだと思えばオシャレさを感じることが可能です。

基本的には何も出来ないしデメリットだなと思っていたのですが、逆に言うと何も出来ないのでひたすらリラックスする時間になります。自分はこっちで犬を飼い始めたので週末は犬と散歩に行ってます。

日本だと何かしなくては、という強迫観念にかられていましたが毎週強制的に休ませられるというのは実はとても良いことかもしれないと思うようになりました。

公園で犬とダラダラ過ごすのも悪くないです。

多様性に寛容

LGBTフレンドリーな国です。

locotabi.jp

また、ビーガンメニューなど多くのレストランにありますし、デカフェコーヒーも多くのカフェにあります。日本に観光行ったビーガンの人は日本では食べられるものを探すのが大変だったと言っていて、自分がビーガンじゃないので意識していませんでしたが確かにビーガン対応レストランとか少ないなと気づきました。

電車が綺麗

電車が新幹線みたいなスタイルで綺麗ですし広いです。さらに自分が乗った限りでは100%座れてます。もちろん路線にも依るとは思います。東京の電車とかに慣れていると、電車ってこんなに快適な乗り物だったのか、と気付かされます。

子供に優しい

合計特殊出生率は3.1で、日本の1.4と比べて倍以上あります。街中にとにかく子供が多いです。そしてみんな子供に優しいです。子供が泣いて嫌な顔をする人とか基本いませんし、ベビーカー押してるお母さんとかがいると知らない人が当たり前のように手伝っています。バスの中で旦那さんがベビーカー持ってるのかな、と思ったらお母さんがベビーカーと降りる時に手を振ってお別れしてて、全く知らない人がただ手伝っていただけみたいなことも多いです。

dot.asahi.com

あと公園の数が多いです。さらに一つ一つの公園に遊具がとても多いです。ブランコも長い。

週末は子供がとても多くて家族で溢れています。

犬に優しい

Tel Avivは信じられないぐらい数の犬がいます。犬の散歩に行くとどの時間帯でもまず間違いなく数匹の犬と会います。ドッグランが家の近くだけで徒歩10分以内に3つもあるので週末はそこに連れて行って他の犬達と遊ばせてやれます。レストランも基本的に大体犬OKです。それどころかレストランに犬用の水や餌入れとかも用意してあることが多いです。

さらに驚いたのは犬専用ビーチがあります。はっきりと犬向けと書いてあるのでみんな犬を連れてきてビーチで遊ばせています。

あとオフィスに犬を連れてくる人も普通にいます。大きい企業だとドッグシッターを雇っていて仕事中は預けておけば散歩なども行ってくれるみたいです。バスや電車など乗せるのも何も問題ありません。犬に関しては間違いなく日本に住むよりこっちに住むほうが幸せだろうなと思います。

ベンチが多い

街中の至るところにベンチがあります。みんな日中ベンチに座ってコーヒー飲んだりしながらゆったり過ごしていて良いなーと思います(この写真では誰も座っていませんが)。

ゴミ箱が多い

ゴミ箱が5m置きぐらいに設置されていたりします。すぐに物を捨てられるの便利。

美男・美女が多い

こっちの人はヨーロッパ系の顔立ちで、女性は金髪の人が多く美人が多いです。あと男女ともに太っている人が少なくてシュッとしてます。理由を聞いてみたら兵役でトレーニングさせられるので土台として身体が鍛えられているし運動する習慣が付くので兵役後も運動している人が多いのとかはあるかも、と言っていました。

街中には軍服来た兵役中の女性も多いので本当にこんな感じです。

matome.naver.jp

ナタリー・ポートマンイスラエル出身です。

www.mine-3m.com

携帯料金が安い

後述しているように基本的には物価がめちゃめちゃ高いので焼け石に水的なところはありますが、携帯料金はなぜか安いです。月20GBで電話かけ放題のプランで1500~2000円です。同僚に言ったら「それでも高い。1000円以内で契約できる。」と言ってました。

タクシーが安い

タクシーはGettというUberのようなアプリがあってとても便利です。そしてなぜかやたら安いです。結構乗ったし3000, 4000円はするだろうなーと思ってメーター見ても2000円行ってないこととかも普通にあります。

10bisが便利

10bisというサービスがあるのですがこれが便利です。

www.10bis.co.il

会社からカードが配られて、そのカードで支払うと会社支払になります。会社は月にある程度の金額をそのカードにチャージしてくれるので、そのカードで支払えば無料で食べられます。このカードはほとんどの店が対応しているため、休日とかでもそのカードで払えばタダです。月の上限を超えれば自分のクレジットカードから引落されます。社食とか作るよりもみんな好きなものを店で食べられるからこっちのほうが良い、と言っていてなるほどなと思いました。

あとデリバリーも可能です。賢いなと思ったのはオフィスにいる場合、別フロアの人が同じ店で頼んでいれば注文がまとめられて送料が無料になります。うちのビルは40F以上あって会社が多く入っているので送料がほぼ間違いなく無料になります。これ日本でもやったら流行るんじゃないかと思ってます。

そして送料払えば家からでも注文可能です。中にはデリバリーが無料の店もあります。他にもWoltというUber Eatsみたいなやつもありますしフードデリバリーは日本よりも盛んです。

医療制度が整っている

以下の記事に書いているのですが、大きな病院のグループが4つぐらいあってそのグループ内ではカルテ等が全て共有されているので違う病院に行っても続きから受けられます。さらにその先生でわからないことがあっても別の病院の先生にすぐ連携できるので専門家の話が聞きやすいというメリットもあります。日本では何で毎回問診票書くんだ...と常々思っていたので便利で驚きました。過去の病気とかうっかり書き忘れたら命に関わることもありそうだし改善されて欲しいなと思います。

www.itmedia.co.jp

Tel Avivは狭いのでmeetupとか行くの楽

日本では基本的に移動が面倒であまり勉強会とか行かない人間だったのですが、こっちでは大体徒歩で行ける距離で開催されるのでそれなら仕事終わりに少し顔出してみるかという気分になります。それでも2ヶ月に1回ぐらいしか行ってませんが。

ソフトウェアエンジニアの待遇が良い

これはまた別途書こうと思いますがイスラエル企業はアメリカのソフトウェアエンジニアとかを雇うための給料設定がされているので給料はかなり高いです。これは若者にとってソフトウェアエンジニアが憧れの職業であることが大きいみたいです。逆に医者や弁護士は人気がなくて給料が低いらしいです。こちらで働いている日本人弁護士の方は日本の時よりも給料が下がったとのことです。

どちらでもない点

アジア人が少ない

チャイナタウンは世界中にどこでもあるからな〜とか言ってイスラエルに来たのですがありませんでした。聞いたら中国人や韓国人はビザを取るのがとても難しいみたいです。日本人も簡単なわけではないので先述したとおり1000人程度しかいません。実際に街中を歩いていてアジア人を見かけることはほとんど0です。観光客っぽい人をたまに見かけるぐらいです。日本人は半年で1, 2回しか見たことないです。こっちでアジア人と交流したいと思っても厳しいです。

自分は別に交流しなくても平気だなと思ってたのですが、中華料理や韓国料理が食べられないのはかなりストレスであることに気づきました。中華料理店自体はたまーにあるのですが、恐らく知っている料理とは大きく異なります。韓国料理がないので焼肉屋も一切ありません。というかアジアの区別がそもそもあまり付いてません。

ですが日本料理はこちらで大人気で寿司はどこでも食べられます。人口あたりの寿司屋の数は世界3位と言われているみたいです。ただ周りを揚げてあったりスパイシーマヨネーズを付けて食べたり、我々の求めている寿司とはかなり異なります。お金を出せば日本っぽい寿司が食べられたりもしますが高すぎて頻繁には食べられないのと、それでも回転寿司のクオリティにも満たないのでおとなしくフムス食べておいたほうが良いな、となって久しく食べてないです。

アジア人が本当にいないので日本語とかを使う機会が0です。こないだ2ヶ月ぶりに妻以外の日本人の人と会いました。さすがに少しテンション上がりました。基本生活の全てが英語かヘブライ語で話さないといけないので勉強になるという点では良い点かなと思います。

ただ一方でとても目立ちます。すぐ「Chinese?」とか話しかけられます。別に普段は気にしていなかったのですがコロナウイルスの影響でアジア人に対しての風当たりが強い状況だと少しマイナスかなと感じています。

www3.nhk.or.jp

とはいえこういうのは一部の話で自分は全く被害を受けていません。会社の人も近所の人もひたすら優しいです。一部におかしなやつもいるから気をつけてね、と忠告はしてもらいました。

大変な点

どちらかと言うと日本が異常、みたいな話が多い気もしますが一応比較として。

物価が高い

これは今となっては日本の物価が安すぎるという話だとは思いますが、日本と比べると物価が圧倒的に高いです。すべての物が2倍はします。マクドナルドに行ってセット頼むと1500円はします。ランチで2000円ぐらい出しても大したものが食べられないということも多いです。

同僚がビッグマックの値段で比較すると良いと教えてくれたのですがイスラエルは6位です。アメリカが3位なのでアメリカの物価に迫るぐらいの高さだということが分かります。日本は27位です。

https://www.statista.com/statistics/274326/big-mac-index-global-prices-for-a-big-mac/www.statista.com

たまにまだ東京が高い物価の都市だと思ってくれる人もいるのですが、毎回半分ぐらいの物価だと伝えて切ない気持ちになっています。既にそれを知っている人は日本は物価が安いので旅行や買い物に便利という認識になっていますし、後進国になっていってる感があって悲しいです。

家賃高い

家賃もTel Avivだと平気で30~40万円とかかかります。こちらに住んでる日本人弁護士の方も家賃は40万円以上だと言っていました。自分たちはたまたま日本好きのオーナーの人と出会えたおかげで22~23万円ぐらいのところに住むことが出来ましたが、他の物件は高かったですし運が良かったケースかなと思っています。

ウォシュレットがない

イスラエルに限らずアメリカとかアジアとか日本人が多数住んでいる国全てそうだと思いますがウォシュレットがないです。これは本当に致命的で、ずっとウォシュレットのない国には住めないと言い続けていたのですが主張は正しかったです。もう限界が来ています。

二郎がない

自分はジロリアンですが二郎食べられないのが本当にストレスです。これだけで日本に住む価値があります。ただボストンにもあるという噂を聞いたのでアメリカは住めるかもしれません。というかこっちは二郎どころかラーメンすら殆ど無いです。2000円払って出てきたラーメンは不味すぎて食べきれずに残しました。こっちでマルちゃん正麺を2000円で売ればエグいほど儲けが出るんじゃないかと思ってます。

時間にルーズ

基本待ち合わせも遅刻しますし、バスや電車の時間は守られません。日本では電車が1分遅れるだけで謝罪することもあると言うと大体狂ってると言われますし、日本が異常なだけという気もしてます。

運送業が終わっている

時間指定とかいうのはまず機能しません。時間外に来るならまだマシですが、その日にすら来ないことがしょっちゅうです。そして来なくても連絡の一つもありません。仕方ないのでこちらから電話するのですが、道に迷って帰ったとか言われたりします。しかもこっちの住所はとてもシンプルで、〜丁目までしかありません。つまり"品川1丁目"とかがもう家の位置を指します。このシンプルさで道分からないならドライバーもうやっていけないでしょ...と思ってます。さらに言うと休日は安息日の関係で働かないので平日の日中に待機し続ける必要があるのも大変です。

つまり、

  1. 時間指定する
  2. 平日に家で待機する
  3. 時間内に来ない
  4. その日にすら来ない
  5. こちらから電話する
  6. 1に戻る

というのを3回ぐらい繰り返す必要があります。死ぬほどストレスが溜まるのですが、3回ぐらいやるとさすがに受け取れます。そして受け取ると大体以下のような状況になっています。

ツイートにも書きましたが、3回目ですら時間内に来ずiMacの入ったボロボロの段ボールを家の前に放置して帰っていました。一番信頼性が高いと言われているEMSで送ったのですが、現地の人からするとイスラエルに物を送るときには絶対にEMSは使ってはいけないというのは常識みたいです。自分の場合は関税で何ヶ月もストップされた挙げ句、新品のPCに見えるとかイチャモンを付けられて何万円も取られて3ヶ月越しにようやく受け取れる...!!と胸を膨らませて上の状況だったので、さすがにドライバーを10発ぐらい本気で殴ろうかと思いました。税関では新品に見えるとイチャモンつけられていたので壊したのはほぼ間違いなく運送業者だと思われます。

中もボロボロです。

補償を求めてダメージレポートを出したのですが、実はドアの前に放置されていたのは逆に良かったみたいです。もし受け取ってしまっていたらこの状態の荷物を了承したとみなされて厳しかったみたいです。ダメージレポートも自分では出せなかったのでこっちの人に代理でやってもらいました。本当にありがたいです。

ちなみにPCが壊れた話を会社の人にしたらみんな似たようなことを言っていて国民性を感じました。

EMSは一番速いと歌っているため一番値段が高いのですが、実際には数ヶ月かかる上に関税に間違いなく目をつけられるので一つもいいことがありません。その上粉々に壊されます。ですが実験を重ねた結果、小型包装物が神であることが分かりました。

www.post.japanpost.jp

2kgまでしか送れませんが1週間で届きますし5000円以下と書いておけば関税にも捕まりません。2kg超えるものは帰国時に気合で持ってくるか諦めましょう。

買い物が不便

大型量販店みたいなのがないので、それぞれ買いに行く必要があります。日本みたいにイオンで何でも揃うぜ!みたいなことがないです。肉欲しければ肉屋に行って野菜が欲しければ八百屋に行きます。家電が欲しくてもビッグカメラみたいなのがないので、在庫調べて小さい店に行ったりしないといけないです。ただこれはヨーロッパとかも割と同じだと思います。

接客が雑

これも日本が異常シリーズだと思いますし他の国に行ったときにもよく感じていたことなのですが、接客が雑です。普通に話しかけてもスマホゲームしてて無視とかされます。レストランで声かけて明らかに目があったのに無視されることもあります。

特に酷いのはバスです。バス停で待っていても平気で無視します。上に書いたように遅延も酷いので30分待たされた挙げ句に無視されたこともあります。手を挙げて全力で乗りたいアピールしないと止まってくれません。外人に対する嫌がらせか?!と思いましたがイスラエル人も辛いらしいのでバス運転手が単に酷いみたいです。以前バス乗ってたらおじいちゃんが走ってきてドア叩いて開けてくれ!と叫んでいたのにガン無視する運転手も見ました。

色々と雑

接客だけに限らず基本大体全てが雑です。銀行でカード発行されたから支店に取りに来いと言われたから行ったらないと言われて、「でもあるって言われて来たんだけど?」「いやないもんはない」ってやり取りをして帰らされたことがあります。コールセンターにかけたらやっぱり支店にあるって言われて、仕方なくもう一度行ったら「だからないって言ってるでしょ」と言われて「は?!?!」ってなりました。最終的に支店の人がカード紛失していただけらしくめっちゃ探したら見つかったと後日連絡が来ました。銀行でカードなくすことある?!と衝撃を受けました。

他にも携帯の契約を自動更新することが出来ず(理由はIDのところで後述)3ヶ月単位で契約していたんですが、突然2ヶ月で使えなくなりました。連絡したら「2と3間違えてたわーガハハ」ってなって、いやネットから申し込んだのに手動で打ち込んでんの...?と衝撃を受けたりもしました。

他にも当初言われていた日程からビザの手続きが遅れに遅れまくって、家解約したのにビザが間に合わずホームレスになったりもしました。

仕方なく1ヶ月遅らせたのですがそれでもギリギリで、出国まで24時間を切ってもビザが手に入らずひたすら祈り続けたりもしました。

この手の衝撃エピソードは挙げるとキリがないです。

順番守らない

順番待っていても普通に割り込まれます。そのぐらいはまだいいのですが、番号を発行して待っていても割り込まれることがあります。郵便局では待っている人に対して番号が発行されます。モニターに番号が表示されたらカウンターに行く仕組みですが、自分の番だと思って行ったらサッと自分の前に他の人が入りました。さすがにいやいや自分の番だからって言ったのですがガン無視されました。驚いて譲ってしまったのですが、こういう時に強く言えるようにならないと生きていけないなと思います。

物言いがストレート

回りくどいのが嫌いみたいなのでかなりビシッと言います。お前のアイディアはダメだ、とか平気で言います。喧嘩してるのか...?みたいなミーティングもありますがネチネチ言うよりはストレートに言う方がスムーズで良いなと言う気もするので最近は特に気になってないです。

サウナがない

サウナがないです。もしかしたら現地の人に探してもらえば見つかるのかもしれませんが、自分で見つけられたサウナはゲイのやつでした。

年末年始休みがない

ユダヤ教の新年は9月末から10月頭(年によって違うとのこと)なので、12月末は平日です。時期が異なるだけで年末年始がないわけではないのですが、日本の年末年始の感じは好きだったので少し残念に感じます。そして同じチームで別の国の同僚達が12月中旬あたりから長期休暇を取る中働いていると切ない気持ちになります。

祝日が固まっている

こっちに来てから気づいたのですが日本は祝日天国でした。ほぼ毎月祝日があるという。イスラエルでは10月に大量の休みがあり、有給も繋げれば1ヶ月ほとんど休みみたいな感じになります。ただし、10月が終わるとそれ以降4月まで祝日が0です。トータルでの祝日も日本に比べたら少ないです。日本とやり取りしていると今週も3連休!みたいなことを凄く頻繁に言われているように感じて辛くなります。 www.arukikata.co.jp

何するにもIDが必要

これはイスラエルが悪いわけではないのですが、イスラエルに住む外人には関係ある話なので書いておきます。当たり前ですがイスラエル市民じゃないと国民番号がもらえません。そしてオンラインショッピングなどをしようとすると98%ぐらいの確率でIDを求められます。そのためネット上で買い物ができません。他にも税金や光熱費などの支払いでもIDが求められるせいでネット手続きができません。なので仕方なく近くの郵便局に2ヶ月に1回行って支払っています。これは結構ストレスなので気をつけたほうが良いです。

ラクション鳴らしがち

始めて中国や韓国に行った時にも驚いたことなので特に気にしてないのですが、自分がスクーター載ってる時に後ろの車からクラクション鳴らされると結構ビビるので辞めてほしいと思うことがあります。

まとめ

日本にもイスラエルにもどちらにも良いところ・大変なところがあります。

KubeCon + CloudNativeConにプロポーザル出すときに気をつけたこと

サイボウズさんの記事を読んで、自分も今回プロポーザル出したときに会社の人から貰ったアドバイスをまとめておこうと思いました。というのも、自分の席の隣の人が実際に今回のKubeCon Europe 2020でレビュワーだった人ですし、チームのボスはKubeConのChair経験者だったりするので、割と貴重な情報なのではないかと思っています。とはいえ何か特別なテクニックがあるわけではないです。

KubeConって何?とかは以下の記事を読んでもらえればと思います。 blog.cybozu.io

恐らくKubeConに限った話ではないですし指摘内容も普通の内容が多いと思いますが、一応次以降に自分で見返すこともありそうなので全部書いておきます。

プロポーザルに関するアドバイス

全部教えてもらったやつです。ただ自分なりに解釈した内容を書いてるので伝言ゲームで若干齟齬あるかもです。

タイトルは短く

あまりに説明的すぎるタイトルは避けたほうが良いようです。長すぎると敬遠されがちなので、Wordに書いて1行以内には納めたほうが良さそうです。恐らく50~80文字ぐらい。しかし一方で短すぎても何のセッションか分からないので、参加者が興味を持つぐらいの内容を1行でまとめる必要があり難しいです。

箇条書き

発表内容について長々と文章で書くよりは、箇条書きで要点をレビュワーの方に伝えるほうが良いようです。その箇条書きも5~10個とかだと見にくいので色々書きたい気持ちは抑えて2, 3個にしましょう。

デモ

デモがある発表の方が人気みたいです。もちろんデモがなくても良いのですが、もし出来そうなら積極的にやるべきでプロポーザル内にもその旨を書くべき、とのこと。実際うちのボスはほぼすべての発表でデモしていて、それが評判良いみたいです。

対象者

これも重要で、誰に向けての発表なのかはしっかり盛り込むほうが良いです。もし事前知識が必要だったりする場合は正直に書きましょう。

エコシステムへの影響

確か応募フォームの中にBenefits to the Ecosystemという欄があります。CloudNativeConなので、クラウドネイティブのエコシステムにどう影響があるのかを書く必要があります。これも重要で関連性が強かったり分かりやすい方が通りやすいそうです。

実用的な解決策

既存のCNCFプロジェクトにどういう問題がありこの発表でそれをどう解決するのか、という内容や、デフォルトだとこういう問題があるのでこのCNCFプロジェクトの利用をおすすめします、とかいう内容も書くと良さそうです。聞いてふーんで終わりの内容ではなく、実際にすぐ聴講者が行動出来るような内容を持ち帰ってもらえる発表ですよ、というのがポイントみたいです。

プロポーザル例

上のをまとめると以下のような構成です。

# タイトル
短くて興味を引くタイトル(80文字以内ぐらい)

# 発表内容
概要1(1~2行ぐらい)

- 要点1
- 要点2

概要2(1~2行ぐらい)
デモの内容

この発表の対象者、必要な事前知識

# Benefits to the Ecosystem
この発表がCNCFにおいて重要な理由(1~2行ぐらい)
CNCFプロジェクトとの関連性(1~2行ぐらい)
聴講者に持ち帰ってもらえる内容(1~2行ぐらい)

これがベストかどうかは分かりませんが、今回自分はボスの過去のプロポーザルを丸パクリして上の構成で出しました。

その他

発表実績

実はこの部分が今回の記事で一番書きたかったところで、こいつは英語でうまく発表できるのか?というのを見られるみたいです。もちろん応募内容が圧倒的に良ければそんなの関係なく通るのですが、当落線上にいる場合は実績が重要になってきます。自分の場合は何も実績の動画とか送らなかったので判断つかなくて困っていたらしいのですが、レビュワーの同僚が英語発表問題ないと言ってくれたらしく(実際には問題ありまくるけど)、それなら良いかということで通ったみたいです。そういう意味では自分はラッキーだったと言えます。もし何か実績が少しでもあるなら送っておいたほうが良いです。

実際KubeSecというKubeConと一緒に開催されるイベントに知人が応募していたのですが、レビュワーから彼の英語発表大丈夫?と聞かれました。大丈夫です!!!と答えた結果、採択されることになりました。もちろん大前提として応募内容が良かったからなのですが、やはり発表スキルは気にされるみたいです。

つまり大きいカンファレンスに一発目から行くよりは少し小さめのところで発表して実績を作り(可能ならYouTubeとかで録画が配信されるぐらいの規模)、そのURLを一緒に送ると採択率が上がるということです。知人だから通りやすいとかいうわけではなくて、判断がつかないとカンファレンスを成功させたいレビュワーとしても困るということです。

メンタル

そもそもカンファレンスで話したいと思ってる時点で圧倒的に他の人より前にいますし、上のような点に気をつければ問題なく通ると思います。さらに言えば通ると良いなというよりは通って当然ぐらいの気持ちで応募すると良いかもしれません。

正直自分は登壇自体も苦手で敬遠してるので経験が少ないですし、英語力もヤムチャぐらいしかないので話したいとは全く思ってませんでした。自分程度の実力で大きなカンファレンス行くのは無謀だと思ってます。ヤムチャが街に人造人間探しに行くようなもんです。仲間呼ぶ前に殺されます。ただうちのチームはフルタイムが6人いて、前回と今回だけでスピーカーが4人もいます。実質CTO直轄チームなのでCTOも入れてしまえば7人中5人です(1人諸事情で辞退しましたが)。つまり話してない方のほうが少ないぐらいです。なので、あまり乗り気ではなかったのですが何で出さないの?みたいな空気感もあり結局出しました。ダメ元で、というよりは通さないとダメだよな...みたいな気持ちだったのが今となっては良かったのかもなと思っています。

そんな感じで自分の中で当たり前のレベルが上がると自然と自信を持って書けるようになって良い結果に繋がるのかなと感じました。

まとめ

お願いだから誰も聞きに来ないで欲しい。

コミット前後でベンチマークが悪化していたらテストを落とすGoのCI用ツール

本当にただこれがやりたかっただけです。今でも既存のものがあるだろうと思っているのですが、誰も教えてくれなかったのでシュッと作りました。落ち込まないので今からでも教えてくれて良いです!

概要

上のツイートにある通りなのですが、Goだとベンチマークを計測するツールがデフォルトでgo testに同梱されているので、GitHubとかにコミットされたらそのコミットと一つ前のコミットでベンチマークのスコアを比較して、悪くなっていたら教えて欲しかっただけです。シェルスクリプトで数行で出来るようなレベルですし、ちょっとオプションつけたり表示をリッチにしても200行ぐらいで済みそうだったのでGoでツールを作りました。ブログ執筆時点だと260行でした。

f:id:knqyf263:20200114005936p:plain:w300

github.com

実際、あまりにも簡易的なツール過ぎてGoのコードよりインストールスクリプトのほうが行数が長く、GitHub上でShellScriptのリポジトリとして認識されてしまいました。テストを足してかさ増ししたりもしたのですが、最終的には.gitattributesを足してちょろまかしました。

使い方

基本的にはCI上で使うことを想定しています。内部でgit reset相当のことをしているので、ローカルで実行する場合は注意して下さい。 もしコードが消えても責任は取れないです。というか自分が開発中に間違って自分のリポジトリ上で実行してコードが消え去りました。内部でgo-gitを使っているのですが、こいつのresetはuntrackedなやつも消されるみたいです。まだgit addすらしてないから大丈夫だろうと油断していて完全にやられました。シンプルにコードを失いました。そもそもgo-gitのこの挙動がアレだと思うので直したい気持ちもあります。

とりあえず実行するならベンチマークのあるプロジェクトのディレクトリに行って以下のように打つだけです。これで勝手にHEADとHEAD{@1}のベンチマークを比較します。

$ cob ./...

メモリとかも計測したい場合は-benchmemつければよいです。使い方はgo testと同じです。go testのうちベンチマークに関係ありそうで自分が欲しかったオプションだけ取り込んでいます。-bench-benchmem-benchtimeはそのままgo testに渡されます。

$ cob -benchmem ./...

結果は以下のようになります。上のテーブルは単純にHEADとHEAD{@1}の値が並んでいます。下のテーブルはそれがどのぐらい変化したかを表示しています。赤は悪化で青は改善を示します。

f:id:knqyf263:20200113043030p:plain

デフォルトではベンチマークが20%以上悪化するとプログラムがエラーを返します。つまりCI上で実行するとテストが落ちます。ただ元々の値が小さい場合は変化が大きく出てしまうので、同じベンチマークを実行しても20%を超える場合があります。そういう場合は-threshold を変えたり -benchtime 10s など大きくして値が安定するようにすると良いです。

$ cob -benchtime 10s -threshold 0.5 ./...

ベンチマークの関数ごとに閾値を決められると良いかもなとは思っているのですが、-benchの正規表現指定とパッケージ指定とか工夫でなんとか出来る気がしたのでやめました。上に書いたように簡易的なツールなので機能は殆ど無いです。

$ cob -bench BenchAppend -threshold ./foo

上のような感じですね。BenchAppendという文字列を含むfooパッケージ内のベンチマークだけ実行されます。-benchgo testに渡してるだけなので、正規表現も使えます。

あと、パッケージが違えば同じベンチマークの関数名が定義できますが、それも対応してないです。同じ名前がある場合はうまく結果が表示されないのでパッケージ名を指定して2回実行して下さい。

$ cob ./foo
$ cob ./bar

オプションもあまりないです。

NAME:
   cob - Continuous Benchmark for Go Project

USAGE:
   cob [global options] command [command options] [arguments...]

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --only-degression  Show only benchmarks with worse score (default: false)
   --threshold value  The program fails if the benchmark gets worse than the threshold (default: 0.1)
   --bench value      Run only those benchmarks matching a regular expression. (default: ".")
   --benchmem         Print memory allocation statistics for benchmarks. (default: false)
   --benchtime value  Run enough iterations of each benchmark to take t, specified as a time.Duration (for example, -benchtime 1h30s). (default: "1s")
   --help, -h         show help (default: false)

結果をコミットIDと保存しておいて比較すれば2回実行しなくても済むかなと思ったのですが、CI環境だと起動される度に微妙に環境が違ったりしてそっちの要因でベンチマークのスコアが変わったら嫌だなと思って今のところやっていません。その辺り、何か良い知見をお持ちの方がいらっしゃれば助けてほしいです。

CI

CIで使う場合のサンプルを置いておきます。ここではGitHub Actionsだけ置いておきますが、他の例や実際の出力を見たい場合はcob-exampleを見て下さい。

name: Bench
on: [push, pull_request]
jobs:
  test:
    name: Bench
    runs-on: ubuntu-latest
    steps:

    - name: Set up Go 1.13
      uses: actions/setup-go@v1
      with:
        go-version: 1.13
      id: go

    - name: Check out code into the Go module directory
      uses: actions/checkout@v1

    - name: Install GolangCI-Lint
      run: curl -sfL https://raw.githubusercontent.com/knqyf263/cob/master/install.sh | sudo sh -s -- -b /usr/local/bin

    - name: Run Benchmark
      run: cob -benchmem ./...

まとめ

みんな黙ってるだけでやっぱりこういうツールあるんじゃないかと疑っています。でも自分の要件はこれぐらいなので、必要最小限という意味では自作して良かったかもしれません。自分の環境以外でちゃんと動くかも分かりません。もしこういうの欲しくて困っていた人はフィードバック頂ければもう少し真面目にメンテナンスします。

stretchr/testify/mockでTable Driven Testしやすいようにmockeryを拡張した

アドベントカレンダー用に書こうと思っていたのですが乗り遅れました。あとあんまり大衆向けの話でもないのでひっそりと公開しておきます。

良いやり方を調べても見つからない時は自分の思いつく最良の方法を公開すると誰か凄い人がやってきてより良いやり方を教えてくれたりするので、今回もそれを期待しています。

課題

stretchr/testifyにはテストするために使える便利なパッケージが複数含まれていますが、その中にmockがあります。
https://github.com/stretchr/testify

これを使うと指定した引数に対する戻り値を簡単に定義できます。例えば会社名入れたら会社情報を返してくれるstructのmockに対する引数と戻り値は以下のように書けます。

mockCompany.On("Info", "FooCompany").Return("101-0001", "東京都千代田区", "03-3000-0000", "2000")

上の場合だとinterfaceは以下のような感じです

type Company interface {
    Info(string) (string, string, string, int)
}

思いつきで作ったので、このInterfaceなんなんみたいなのは置いておいて下さい。

ちなみにmockはこれ以外にもCallで関数呼び出したりとか、色々な機能があるので普段テストでそれらを使う機会の方が多い人はここで記事を閉じてもらったほうが良さそうです。自分もCallTimesたまに使うのですが、多くのケースでは上のシンプルな使い方で十分な場合が多いです。なので、今回は上のmock.On().Return()の形に絞った話になります。

テスト用のstructを用意する

これをTable Driven Testで使おうとすると、テストケース内で上の引数・戻り値を定義したくなります。そしてその時に専用のstructがあると便利です。MockCompanyは先に作っておく必要がありますが、それはググればたくさん使い方出るので省略します。MockCompanyは作成済みということで進めます。

// mockが受け取る引数
type InfoArgs struct {
    CompanyName string
}

// mockが返す戻り値
type InfoReturns struct {
    Zip      string
    Address  string
    Phone    string
    Employee int
}

// 上の2つをまとめたstruct
type InfoExpectation struct {
    Args    InfoArgs
    Returns InfoReturns
}

こんな感じでstructを定義しておけば、テストケースを定義する時に綺麗に書けます。補完も効くしサクサク書けて気持ち良いです。意味的にも分かりやすいです(個人的には)。

testCases = []struct {
    name string
    info InfoExpectation
}{
    {
        name: "happy path",
        info: InfoExpectation{
            Args: InfoArgs{
                CompanyName: "FooCompany",
            },
            Returns: InfoReturns{
                Zip:      "101-0001",
                Address:  "東京都千代田区",
                Phone:    "03-3000-0000",
                Employee: 2000,
            },
        },
    },
}

あとはこれをfor文の中でOnとReturnに渡せばよいです。

for _, tc := range testCases {
    t.Run(tc.name, func(t *testing.T) {
        mockCompany := new(MockCompany)
        mockCompany.On("Info", tc.info.Args.CompanyName).Return(tc.info.Returns.Zip,
            tc.info.Returns.Address, tc.info.Returns.Phone, tc.info.Returns.Employee)
        ...

これで複数のテストケースでも対応できて便利なのですが、問題は上のstruct達をいちいち作るのがだるすぎるということです。導入が若干長くなりましたがこれが自分の課題でした。

Sliceを使ってみる

Onはinterfaceを渡せるので、以下のような方法も考えたりしました。

type InfoExpectation struct {
    Args    []interface{}
    Returns []interface{}
}

func TestCompany_Info() {
    testCases = []struct {
        name string
        info InfoExpectation
    }{
        {
            name: "happy path",
            info: InfoExpectation{
                Args:    []interface{}{"FooCompany"},
                Returns: []interface{}{"101-0001", "東京都千代田区", "03-3000-0000", 2000},
            },
        },
    }
    for _, tc := range testCases {
        t.Run(tc.name, func(t *testing.T) {
            mockCompany := new(MockCompany)
            mockCompany.On("Info", tc.info.Args...).Return(tc.info.Returns...)
        })
    }
}

[]interface{}で全部受け取れるようにしてOnとReturnに渡す方法です。試した時のコード消しちゃったので上ので動くかわかりませんがイメージが伝わればよいです。これを試してみて思ったのは、何番目が何の値とか覚えてられないです。例えば住所と電話番号逆にしてもすぐには気づけないですし、型も分からないので郵便番号ってstringだったっけ...?みたいになって辛いです。あとintやstringなどのプリミティブ型だけでなく別のstructを渡したい時も不便です。

mapを使ってみる

せめて名前ぐらいは知りたいということでmapにしてみたりもしました。

func TestCompany_Info() {
    testCases = []struct {
        name string
        info InfoExpectation
    }{
        {
            name: "happy path",
            info: InfoExpectation{
                Args: map[string]interface{}{
                    "CompanyName": "FooCompany",
                },
                Returns: map[string]interface{}{
                    "Zip":      "101-0001",
                    "Address":  "東京都千代田区",
                    "Phone":    "03-3000-0000",
                    "Employee": 2000,
                },
            },
        },
    }
    ...
}

ですが、これも結局keyがただの文字列なのでtypoとかすると終了します。補完も効かないので自分で名前を調べて打つ必要があって人類がやるべきことではないなと感じました。

などと考えると一番最初のように専用のstructがある方が補完も出来るし名前付いてるから分かりやすいし一番良いなーとなりました。もし他に良い方法をご存じの方は可及的速やかに教えていただきたいです。

stretchr/testify は有名なツールだし他のOSSで既に同じことやってるだろうと思って調べたのですが、意外とみんなTable Driven Testしてませんでした。特にmockとか使うようなテストは割と手続き的に書いてました。自分が見つけられなかっただけで良い方法で解決してるOSSがあればどなたか教えて下さい。

Goの流儀に則るならやはりコード生成だろう、ということでstructを自動生成することにしました。

ツール

上のようなstructを作ってくれるツールを探したのですが見つけられませんでした。なので作りました。既存のvektra/mockeryというinterfaceを見つけてMockを作ってくれるツールがあったので、それをforkして作りました。
https://github.com/knqyf263/mockery

upstreamにパッチ送らないのかという話がありますが、残念ながらメンテナンスが止まっているようです。
https://github.com/vektra/mockery/issues/237

ソースコードを読んだのですが難しいことはしていなかったですし、自分で使う範囲なら十分メンテナンスしていけそうだったのでforkすることにしました。特に他の人に使ってもらおうと思って作っておらず、自分の使う範囲で動くように拡張しています。なのでオプション次第では動かないかもしれません。ただupstrean自体が既にバグあったりしてfork内で直したりもしました。

2時間ぐらいで作ったので全く動作保証はできないです。追加したかった機能とは別のupstreamのバグの調査に時間かかったのでもう満足してしまいました。

では実際に使ってみます。オプションの意味はヘルプを見てもらえればと思いますが、以下のように打つとサブディレクトリも含めinterfaceを探してきて同じパッケージ内にMockを作ります。

$ mockery -all -inpkg -case=snake

本家mockeryは以下のようなMockを生成します。

// MockCompany is an autogenerated mock type for the Company type
type MockCompany struct {
    mock.Mock
}

// Info provides a mock function with given fields: _a0
func (_m *MockCompany) Info(_a0 string) (string, string, string, int) {
    ret := _m.Called(_a0)
    ...
}

自分が拡張した方のmockeryを使うと、上のMockに加えてテストで使うときのためのstruct達が生成されます。また、interfaceの引数や戻り値に名前つけておかないと_a0とかになっちゃうので、付けておくのがおすすめです。じゃないと実質名前付きじゃなくなっちゃってこの拡張があんまり意味なくなると思います。

interfaceの引数と戻り値に名前つけると以下のようになります。

type Company interface {
    Info(name string) (zip, address, phone, string, employee int)
}

以下のようなstructになります。

type InfoArgs struct {
    Name         string
    NameAnything bool
}

type InfoReturns struct {
    Zip      string
    Address  string
    Phone    string
    Employee int
}

type InfoExpectation struct {
    Args    InfoArgs
    Returns InfoReturns
}

Name だけじゃなくて NameAnything があるのは、Mockしたいけど引数は何でも良い場合とかがあるので、その場合に NameAnything をtrueにしておくとMockには mock.Anything を渡してくれます。 mock.Anything がただのstringなので、 Employee: mock.Anything みたいに渡すことができず苦肉の策でこうしています。これに関しては何か他に良いやり方ありそう。

そして同時にApplyする側のメソッドも生成します。

func (_m *MockCompany) ApplyInfoExpectation(e InfoExpectation) {
    var args []interface{}
    if e.Args.NameAnything {
        args = append(args, mock.Anything)
    } else {
        args = append(args, e.Args.Name)
    }
    _m.On("Info", args...).Return(e.Returns.Zip, e.Returns.Address, e.Returns.Phone, e.Returns.Employee)
}

テストから呼び出す時は、これを単に呼び出せばよいです。OnとかReturnとかテストに書かなくても良いのですっきりします。

for _, tc := range testCases {
    t.Run(tc.name, func(t *testing.T) {
        mockCompany := new(MockCompany)
        mockCompany.ApplyInfoExpectation(tc.info)
        ...

簡単に引数・戻り値を定義できるしApplyも簡単だし最高ですね(個人の感想)。ちなみに自分は全然違う命名をしてたのですが、英語の得意な同僚が上のような命名をしているのを見てそっと変えました。

定義の部分で文字数が少し増えてしまうのが気にはなっているものの、補完されるし書く分にはあまり困らないです。どちらかと言うと読む時に文字が詰まって見えることがあるのでそれは何とかしたい気持ちがあります。ただきちんと説明されているという意味では初めて見る時には今のほうが良いかもしれないし悩みどころです。

余談

vektra/mockeryはメンテナンスが止まっているため、stretchr/testifyからgomockに移行するという人も結構いるみたいです。ただ個人的にはtestify/mockの方が使いやすくて好きなので現時点ではこっちで良いかなと思っています。数カ月後にどうなるかはわかりませんそもそも大体必要な機能は揃っているのでこれからどんどん破壊的変更が入るかと言うとそうではないような気がしますし、Kubernetesなども使っているのでとりあえずは大丈夫かなと楽観視しています。 https://github.com/kubernetes/kubernetes/blob/7f23a743e8c23ac6489340bbb34fa6f1d392db9d/pkg/kubelet/eviction/mock_threshold_notifier_test.go#L20

自分はあまりMock自体が好きじゃないので本当に必要になるまでは使わないのですが、最近は大人の事情で必要になってしまったので使っています。

まとめ

Mockに与える引数と戻り値を簡単に定義できるstructと適用するためのメソッドを自動生成できるように既存ツールを拡張しました。このツールを使ってほしいと言うよりは、みんなどうしてるんだろう、という議論の種になれば良いなという気持ちです。実は同じ問題を抱えてた人が多かったりしたら真面目にmockeryの拡張部分のテスト書いたりして整備しようと思います。

あと今回の件もそうなのですが、入門記事みたいなのは結構出てくるけどプロダクトで実際にどうやって使うのみたいなので困ることが結構多い気がします。GitHubを漁って実際の使われ方を探すものの意外と出てこなかったりするので、そういうのに使ってる時間が結構長くて辛いです。

GitHub Actionsで支払いのエラーが出る場合

個人のリポジトリGitHub Actionsを使おうとしたら「Workflows can't be executed on this repository. Please check your payment method or billing status.」と出て使えませんでした。GitHub ActionsはFreeで使えるはずなのに何だろうとは思いつつ、未だにFreeユーザだし仕方ないかと諦めていました。ただやっぱり少しテストしたいときとかに不便過ぎる気持ちになったので直し方を調べました。細かい話ですが他にも困っている人がいそうなので一応書いておきます。

以下のページに行ってBillingの詳細を見ます。 https://github.com/settings/billing

すると以下のようにエラーが出ていることに気づきます。 f:id:knqyf263:20200112045420p:plain

元々学生プランにしていたからなのか理由はよくわかっていませんが、一度も有料ユーザになったことがないので登録していたクレジットカードの有効期限が切れたとかが原因ではなさそうです。このエラーが出たままだと動かないようなので、"update your payment method"を押してクレジットカードの情報を入力します。

f:id:knqyf263:20200112050157p:plain

入力後もやはりFreeのままなのですがエラーは消え、GitHub Actionsも動くようになりました。Freeユーザなのでクレジットカードの入力をせずにエラーを消す方法を探したのですが見つけられませんでした。

GitHub Proについて

そもそも有料ユーザになれば良いじゃないかという話なのですが、数年前までOSSとかにあまり縁がなかったので特に有料ユーザになりたいタイミングがありませんでした。しかし最近はOpen Source Engineerという肩書になったし良い機会かなと思ったのですが、基本全部publicリポジトリなのでやはりメリットが感じられず。応援の意味でも良いのですが今はMicrosoftがいるし...などと思ってしまっています。どうでも良いですが自分は日本の漫画業界を応援しているのであまり読まない雑誌も含め片っ端から定期購読しています。スピリッツはお願いなので早く定期購読を始めて下さい。Kindleでいちいち買うのは大変なのです。 GitHub Proはこんなメリットがあるからなったほうが良いぞ!というのがあれば教えて貰えると助かります。