Rustで「Java言語で学ぶデザインパターン入門」をなぞってみた。

ここ最近はRustの勉強をしています。

プログラミング言語Rustを読んではみたものの、 いろんな概念があることもあり、全体を理解することができませんでした。

手を動かさないことには理解できなさそうだったので、 増補改訂版Java言語で学ぶデザインパターン入門をRustで書き直してみるとどうなるか試してみました。

言語的にオブジェクト指向を推しているものではないので、題材としては不適切かなーと思いつつ、 オブジェクト指向っぽく書けるのかなどを調べるために題材にしてみました。

とりあえず動くようにはなったものの、コードが汚かったり、Rustのお作法的に間違っていたりすると思われるので、 勉強しながらリファクタリングしていきたいと思います。

github.com

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

MacでIkaLogの動作環境を整える。

最近はスプラトゥーンの世界に潜っていて、ほぼ毎日のようにプレイしています。
このあいだ、はてブIkaLogというツールがバズっていて、面白そうだったので動作環境を整えてみました。

IkaLogはスプラトゥーン用の支援ツールで、自分の対戦成績をファイルとして記録することができます。
さらにstat.inkというWebサービスと連携させることでブキやステージ毎の勝率を可視化できたりします。
詳細は作者の方のスライドを見てください。

www.slideshare.net

ハードウェア

全体構成

IkaLogはWiiUの出力する映像をPCのPythonプログラムで画像解析することで対戦成績を分析していため、WiiUHDMI出力をPCでキャプチャする必要があります。
ハードウェアの全体構成は下図のような感じで、WiiUHDMI出力をスプリッタで分配して、ディプレイとHDMIキャプチャボードに接続しています。
ディスプレイにも映像を出力したかったのでこのような構成にしました。

f:id:yukihir0:20151026194323p:plain:w600

HDMIスプリッタ

HDMIスプリッタはプリンストン社製のものを使っています。
マイクロUSBで給電できてコンパクトなのでオススメです。

HDMIキャプチャボード

HDMIキャプチャボードはIkaLogのキャプチャボードのページに載っているMacで動作報告のあるBlackmagic Design社のUltraStudio Mini Recorderを購入してみました。
HDMIの映像をThunderbolt接続でMacに取り込むことができます。
付属のSDカードからドライバとキャプチャソフトウェアをインストールした後に、WiiUの出力解像度を720pに設定したところ、無事にWiiUの出力をキャプチャすることができました。
結論として何の問題もなく動作したのですが、上記以外にUltraStudio Mini Recorder+IkaLogの情報が見つからなかったので若干不安でした。

Blackmagic Design 小型レコーダー UltraStudio Mini Recorder 001846

Blackmagic Design 小型レコーダー UltraStudio Mini Recorder 001846

ソフトウェア

ソフトウェアの方は先人の方がブログで解説している方法で上手くいきました。
最初はpyenvでインストールしたPythonで動作させようとしたのですが、pyenvとOpenCVの相性が悪いらしく、OpenCVのモジュールをインポートできなかったのでHomeBrewでシステムワイドにインストールしたPythonを使いました。

hiho-developer.hatenablog.com

Python

% brew install python3
% brew install numpy --with-python3
% brew link numpy
% brew install opencv3 --with-python3
% brew link opencv3 --force

% pip3 install slackweb
% pip3 install fluent-logger
% pip3 install requests-oauthlib
% pip3 install urllib3
% pip3 install u-msgpack-python
% pip3 install Pillow

IkaLog

IkaLog本体は適当なディレクトリにgit cloneしてきて、設定ファイルにログの出力先やAPIキーなどを設定します。
あとはIkaLogを実行した状態でスプラトゥーンをプレイすればログが出力されるはずです。

% git clone https://github.com/hasegaw/IkaLog
% cd IkaLog
% cp IkaConfig.py.sample IkaConfig.py
% vi IkaConfig.py

% python3 IkaLog.py

まとめ

MacでIkaLogの動作環境を整えて、自分の対戦成績を可視化できるようになりました。
自動的に自分の対戦成績が記録されていく様子を見ていると、エンジニア的にはニヤニヤが止まりません。
「推測するな、計測せよ。」の言葉のとおり、 データの助けを借りながら腕を磨いていきたいと思います。

GolangでHTTPサーバのモックを使ってテストを実行する。

GolangでHTTPリクエストを投げるクライアントを実装した場合に、任意のレスポンスを返すサーバのモックを利用してテストを実行したい。
Golangの標準パッケージのnet/http/httptestを使うと、任意のレスポンスを返すモックを定義できる。
net/http/httptestを使うのが王道なのだとは思うけれど、テスト実行時にHTTPクライアントがアクセスするエンドポイントのURLを差し替える必要があったりして少しめんどくさい。
もうちょっと手軽な方法はないものかと探したところ、jarcoal/httpmockを見つけた。
以下のような感じでテスト毎にモックを定義できる。
単純なテストでも構わない場合はこちらのほうがお手軽で良い気がする。

参考

ServerspecのDockerバックエンドでコンテナをテストする。

ServerspecでDockerコンテナをテストするのにDockerバックエンドを利用してみました。
Dockerコンテナ内にSSHDを立てたくなかったので、SSHバックエンドではなくDockerバックエンドでテストを実行したかったのですが、Web上にもあまり情報がなかったのでメモしておきます。
DockerバックエンドについてはServerspec本の中で紹介されています。
DockerバックエンドはDocker Remote APIを利用してテストを実行しているようです。

Serverspec

Serverspec

ディレクトリ構成

.
├── Dockerfile
├── Gemfile
├── Gemfile.lock
└── spec
    ├── nginx_spec.rb
    └── spec_helper.rb

docker-api gem

Dockerバックエンドがdocker-api gemに依存しているので、bundlerなどでインストールします。

% vi Gemfile

source "https://rubygems.org"

gem "rspec"
gem "serverspec"
gem "docker-api"

% bundle

spec_helper

spec_helperにDockerバックエンドの設定を追加します。
docker_urlにdocker remote apiのURLを指定します。 boot2dockerを利用しているのでENV["DOCKER_HOST"]を指定しています。
docker_imageにテスト対象のコンテナを指定します。 Docker Remote APISSLを利用するようになったみたいなのですが、SSLの設定を追加しても動かなかったので無効化しています。

% vi spec/spec_helper.rb

require "docker"
require "serverspec"

set :backend, :docker
set :docker_url, ENV["DOCKER_HOST"]
set :docker_image, "yukihir0/serverspec_docker"

# TODO https://github.com/swipely/docker-api/issues/202
Excon.defaults[:ssl_verify_peer] = false

テストコード作成

SSHバックエンドの場合と同様にテストを記述します。

% vi spec/nginx_spec.rb

require "spec_helper"

describe package('nginx') do
  it { should be_installed }
end

Dockerコンテナ作成

テスト対象のDockerコンテナを作成します。

% vi Dockerfile

FROM centos:7
MAINTAINER "yukihir0"

RUN yum update -y && \
    rpm --import http://nginx.org/keys/nginx_signing.key && \
    yum install -y http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm && \
    yum install -y nginx

EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]

% docker build -t yukihir0/serverspec_docker

テスト実行

Serverspecでテストを実行します。
テストを実行する度に、コンテナ実行>テスト実行>コンテナ破棄されている様子が見れて楽しいです。

% bundle exec rspec

まとめ

Dockerバックエンドを利用することで、Dockerコンテナ内にSSHDを立てなくてもServerspecでテストを実行することができます。
Dockerコンテナでもどんどんテストを書きましょう。

Golangでクロスコンパイルをする。

Golangでクロスコンパイルを試した時のメモ。
OSXでLinux64bitのバイナリをクロスコンパイルした。
ロスコンパイルできることは知っていたけれど、実際に動作すると感動する。
環境や方法は@Jxck_さんの記事がわかりやすかった。

環境構築

Homebrewを使っている場合は、インストール時にオプションを指定するだけでOK。
そうじゃない場合は、GOOSとGOARCHを指定して$GOROOT/src配下のmake.bashを実行する必要がある。
対応しているOSとアーキテクチャを実行しないといけないみたいなので、Homebrewが手軽で良いと思う。

% brew install go --cross-compile-all

ロスコンパイル

GOOSとGOARCHを指定してgo buildをクロスコンパイルする。
すごく簡単。

% GOOS=linux GOARCH=amd64 go build hoge.go