2014年12月26日金曜日

2014年はありがとうございました - 2015年もよろしくお願いします

2014年、最後の投稿です。
2014年はありがとうございました。今年もブログを更新し続けることができました。
2015年もよろしくお願いしますm(__)m

今年はこの記事も含めて 59 の記事を投稿しました。
2012年が 66 、2013年は 76 だったので、今年はちょっと少なめでしたが、週1回分は更新できたので来年も継続していきたいです。

投稿内容としては、今年も例年どおり テスティングフレームワークJenkins が多かった気がします。
それ以外だと、CI 系(Jenkins を除く)の記事を今年は多く書いたかなと思います。

あとは、Arduino 。読み返していて気づきましたが、イーサネットシールドは今年の始めに買っていたんですねー
回路図も簡単に書けるようになり、Visual Studio での開発環境も整って、あとは作るだけっ!
来年は Arduino のことをもっと書けるといいな~


それでは、良いお年を~

2014年12月16日火曜日

[Arduino] Visual Studio で Arduino 開発環境を構築する

Arduino いじりを再開しました。
改めて公式の IDE が微妙だなと感じたので、Visual Studio で Arduino 開発ができるようにしてみました。

拡張機能を使って構築
参考にしたのはこちら。

Arduino for Visual Studio and Atmel Studio 拡張機能
まさに!な拡張機能があります。

ダウンロード・インストール
今すぐ入手ボタンを押すとダウンロードページが開きます。
ページの右側、Information のところに Download リンクがあるので、そこをクリックするとインストーラーをダウンロードできます。

ダウンロードできたら、インストールします。

次に、Visual Studio を起動すると、Visual Micro のライセンスダイアログが出ます。
基本機能は無料で使えるのですが、一部機能は有償になってます。
30日間トライアル版が付いていたのでとりあえず使ってみました。
今すぐ使いたくない場合はキャンセルしておきましょう。

続いて、Config ダイアログが開くので、使っている Arduino IDE のバージョンとパスを設定します。

設定は以上です。

プロジェクトの作成
メニューの「ファイル(&F)」>「新規作成(&N)」に「Sketch Project」があるので、クリック。

ダイアログが出るので、プロジェクト名を入力して OK ボタンを押します。

スケルトンが作成されるので、あとはコードを書くだけです。


ビルド・転送
ビルドは F7 押すだけです。


転送する際は、ツールバーに Arduino のバーがあるので、
そこでデバイスの種類と COM ポートを選択しておいてください。

設定ができたら後は Ctrl + F5 をするだけです。

シリアルモニター
Arduino IDE と同様にシリアルモニターが使用できます。
ツールバーのシリアルモニターのボタンを押すとウィンドウがでてきます。あとは、ボーレートを適切に設定するだけです。


デバッグ
デバッグ機能については、公式のドキュメントを御覧ください。
ブレークポイントを置けたりします。
※ デバッグ機能は有償です。(試用期間あり)

まとめ
Arduino for Visual Studio and Atmel Studio 拡張機能は、すごく便利でした。やはり、Visual Studio でコーディングできるのがとてもイイです。
しかも、基本機能は無料で使うことができます。
デバッグ機能が有償ですが、なくても問題にはならないでしょう。
とはいえ、Student or Hobby License なら手の出る価格ですので、機能次第では買ってもよいかもしれません。
有償機能は時間があるときに調べてみようと思います。

Visual Studio Community 2013 がリリースされました。
Express では使えなかった拡張機能(Add-in)が無料で使えるようになってます。
うれしいニュースですね^^

拡張機能が無料になったので、すべて無料の範囲で環境を整えられるようになりました。
というわけで、
Visual Studio Community 2013 + Arduino for Visual Studio and Atmel Studio 拡張機能
はかなりオススメです。


最後に
この記事を書き始めたのが 10月 くらいなので、それから環境構築するだけで Arduino には全く触れず…
当初の予定では、コマンドラインツール + Makefile プロジェクトについても書くつもりだったのですが、転送の部分で躓いているので今回は省きました。
コマンドラインツールでもできるようになったら、またブログに書きたいと思います。

というわけで、まだしばらくは環境構築してると思います。
(でも、ホントにそろそろ再開したいですねぇ…)

2014年12月10日水曜日

iutest 開発で利用している無料ツールやサービス

今回は iutest の開発で利用しているツールやサービスを紹介したいと思います。
iutest の開発は「できるだけ無料の範囲でやる」というのもテーマの1つでもありますので、
紹介するものも基本的に無料で使えます。

コードホスティングサービス
SourceForge.JP
SourceForge.JP
iutest は主に SourceForge.JP で開発しています。
バージョン管理には Subversion を使用。
また、マイルストーンごとのリリースもこちらでしています。

追記: OSDN に名称が変わりました

Github

github にもコードをアップしています。
やはり、コミュニティの強みがあるのかなと思います。

基本的には、github の方は SourceForge.JP の svn での変更を半自動的に push しているだけです。
コミットメッセージがアレなのはすみません、手抜きです。

コンパイラー・IDE
gcc/clang

このへんは当然でしょう。

Visual Studio

Visual Studio ExpressVisual Studio Community を使用しています。

Wandbox

Wandbox はオンラインコンパイラーです。gcc や clang の様々なバージョンでコンパイルできます。
このへんは C++ Advent Calendar 2014 でも書いたのでそちらをご覧ください。
ブログズミ: Shippable + Wandbox で C++ の CI 環境構築


CI
Jenkins

Jenkins は CI ツールの定番ですね。
ローカルマシーンで稼働中です。
ただ、こちらは常時起動しているわけではなく、github に push するときとか、テストを実行するときに起動しています。

以前は、Cloudbees の Jenkins の無料プランを使っていたのですが、今は使っていません。
理由としては無料プラン内で収まらなくなったことと、メンテナンスがめんどくさくなったからです。
Jenkins は設定とかのメンテナンスが面倒だなー思うことが多々あります…そのへんはなんとかしたいですが…
(会社だとビルド処理はすべて外部ファイルに書いて git で管理してます)
最終的には、サービス体系が変わったのを機に使わなくなりました。

とはいえ、Jenkins は便利なので OpenShift 上で動かしています。(あまり使ってないけど)

Travis-CI

Travis-CI では、gcc/clang でのテスト、fused-src を使ってのテスト、カバレッジ計測、Coverity Scan のためのテストが走っています。
iutest のテストの主だった部分がこちらで行われています。

Travis-CI

Drone.io

Drone.io は C++ がサポートされた CI サービスの1つです。
特徴としては、他の CI サービスが yml ファイルに処理を記述するのに対し、Drone.io では Jenkins のように Web ページ上で管理します。
設定が公開されないのがメリットになると思います。

iutest では、コンパイル速度の計測を行っています。
(あまり意味があるのか微妙だが、)コンパイル速度を意識して修正する場合に、こちらの数値を基準にしています。



Shippalbe

Shippable も CI サービスの1つです。
こちらは C++ がサポート言語にありませんが、Wandbox を利用してコンパイルと実行テストをしています。
詳しいことは C++ Advent Calendar 2014 で書いたので、そちらを参考にしてください。
ブログズミ: Shippable + Wandbox で C++ の CI 環境構築

特徴としては、無料プランでプライベートリポジトリが使えるのと、github の他 bitbucket にも対応しています。
有料プランとの比較はこちらを参考にしてください。
https://www.shippable.com/pricing.html

Shippable

wercker

wercker も CI サービスの1つです。
こちらはβ期間中ですが、無料で github/bitbucket のプライベートリポジトリが扱えます。

ただ、こちらも C++ がサポート言語にありません。
iutest では Shippable と同じように Wandbox を使ったコンパイルと実行テストをしています。

Wercker status

Visual Studio Online

上記 CI サービスでは、Visual Studio が使えませんので、Visual Studio でのコンパイル・実行テストとしてVisual Studio Onlineを利用しています。

無料プランの場合、60分/月の制限があります。
iutest では制限を超えないように、1週間に1回、実行されるように設定しています。

静的解析・カバレッジ
Coveralls

Coveralls は計測したカバレッジの集計をし、推移や差分が見れるサービスです。
Travis などで gcov または lcov などで計測した結果を cpp-coveralls などのレポートツールを使って Coveralls と連携します。

Coverage Status

Cppcheck

無料の C++ 静的解析ツールといえば Cppcheck でしょう。
ローカルの Jenkins で実行しています。
導入当初はお世話になりましたが、現在はお世話になることがほぼなくなりました。

Coverity Scan

Cppcheck よりも高度な静的解析ツールとして Coverity Scan を利用しています。
Coverity 自体は有償ツールなのですが、Coverity Scan はオープンソースであれば無料で使えます。

iutest でもリリース前にチェックするようにしています。

その他
OpenShift

OpenShift は Red Hat が提供する PaaS です。
簡単操作で Jenkins や Redmine などが使えます。

Jenkins でのテスト環境は作ってありますが、今はそんなに使ってません。

CloudBees

Jenkins の項でも書きましたが、以前は CloudBees の Jenkins を使っていました。
久しぶりにログインしたら Enterprise Trial というプランがあったので、また試してみようかなーと思ってます。

2014年12月5日金曜日

Shippable + Wandbox で C++ の CI 環境構築

C++ Advent Calendar 2014
こちらは C++ Advent Calendar 2014 5日目の記事になります。

前置き
CI 環境構築のお話ですが、まずは簡単に用語の説明をしたいと思います。
  • CI
    Continuous Integration (継続的インテグレーション) の頭文字を取って CI 。
    ビルドやテストなどを継続的に(繰り返し)実行することで、問題の発見などをする手法です。
    この CI 環境のためのツールがたくさんあります。代表的なのは Jenkins でしょうか。
  • Shippable
    Shippable は CI ツールの一つです。
    github や bitbucket と連携して push をトリガーに、任意の処理を実行できるサービスです。
    類似サービスに Travis-CI があり、こちらの方が有名だとは思います(私も使ってます)
    が、今回は Shippable を使います。
  • Wandbox
    Wandbox は説明するまでもないでしょう。Online Compiler のひとつです。

ということで、
今回は Shippable と Wandbox を利用して、 C++ のソースコードを定期的にビルド、テストしてみようと思います。

なぜ Shippable と Wandbox か?
Wandbox は便利である
今回 Wandbox を使う理由は、
  • 豊富なコンパイラー
  • API がある
の2点です。

Wandbox でなくとも複数のコンパイラーで動作検証することは可能です。
しかし、環境構築の手間がかなりあると思います。
Wandbox ならば、そのような面倒なことをしなくとも API でコードを投げるだけで、コンパイル結果と実行結果が得られます。

なぜ Shippable か?
実は、Shippable のサポート言語には C++ がありません。
なので、 C++ の CI 環境としては Shippable は通常適さないのですが、今回はコンパイルや実行は Wandbox にお任せなので、CI 環境の要件としては Wandbox に API でコードを投げれるかどうかになります。まぁ簡単に言えば、Wandbox さえあればなんでも OK です!

でも、なんでわざわざサポートされていない環境を使うの?と思う方もいると思います。

それは、前述した通り C++ がサポートされているかどうかは、Wandbox を使うので関係ないからです。
つまり、サポート言語の縛りがなく、料金体系や private リポジトリを扱えるのかどうかなど、他の条件で CI サービスを選ぶことができます。

私の場合、Travis-CI を既に利用しており、そちらはそちらでテストが稼働中だったのと、
「言語サポートされていない環境でも CI できる」というのがネタになると思ったので、Shippable にしました。

Shippable + Wandbox で C++ の CI 環境構築
前置きはこのくらいにして、ここからどのように環境を整えたのか説明していきます。
実例
長々と説明を始めてもわかりにくいと思いますので、
はじめに Shippable + Wandbox で CI をしている実例を紹介したいと思います。

https://github.com/srz-zumix/iutest
こちらは私が作成している C++ テスティングフレームワークです。
ページを開くと README にバッジが付いているのがわかると思います。

そこに Shippable のバッジがあります。(build:shippable と書かれている黄緑のやつです)

バッジをクリックすると Shippable のページにジャンプします。
https://app.shippable.com/projects/541904d2ac22859af743f867/builds/latest


コンソールログの script あたりに Wandbox での実行結果が出力されていると思います。
こんな感じで、push があるたびに Shippable が自動的にビルドとテストをしてくれます。

だいたいどんな感じで動いているか、わかりましたでしょうか?
それでは、仕組みについて説明をしていきます。

Wandbox API を使う
まずは、Wandbox にコードを投げられるようにします。
API のドキュメントがあるのでそちらを参考に作成しました。
https://github.com/melpon/wandbox/blob/master/kennel2/API.rst

import requests
import json;

class Wandbox:
 """wandbox api class"""
 api_url = 'http://melpon.org/wandbox/api'
 parameter = { 'code':'' }
 def get_compiler_list(self):
  r = requests.get(self.api_url + '/list.json')
  r.raise_for_status()
  return r.json()
 def run(self):
  headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
  payload = json.dumps(self.parameter)
  r = requests.post(self.api_url + '/compile.json', data=payload, headers=headers)
  r.raise_for_status()
  return r.json()
 def get_permlink(self, link):
  r = requests.get(self.api_url + '/permlink/' + link )
  r.raise_for_status()
  return r.json()

 def code(self, str):
  self.parameter.update({'code':str})
 def compiler(self, str):
  self.parameter.update({'compiler':str})
 def options(self, str):
  self.parameter.update({'options':str})
 def stdin(self, str):
  self.parameter.update({'stdin':str})
 def compiler_options(self, str):
  self.parameter.update({'compiler-option-raw':str})
 def runtime_options(self, str):
  self.parameter.update({'runtime-option-raw':str})
 def permanent_link(self, b):
  self.parameter.update({'save':b})
 def dump(self):
  print self.parameter

if __name__ == '__main__':
 w = Wandbox()
 w.compiler('gcc-head')
 w.options('warning,gnu++1y')
 w.compiler_options('-Dx=hogefuga\n-O3')
 w.code('#include <iostream>\nint main() { int x = 0; std::cout << "hoge" << std::endl; }')
 print w.run()

こちらはベースとなるコードで、
iutest ではコマンドラインオプションに対応などをした iuwandbox.py という形で提供しています。
https://github.com/srz-zumix/iutest/blob/master/tools/wandbox/iuwandbox.py
使い方に関しては前回のブログで書いてますのでそちらを参照してください。
ブログズミ: iutest v1.11.0 をリリースしました

Wandbox でのコンパイルと実行ができるようになったら、ローカルでテストしておくとよいでしょう。

Shippable の登録とプロジェクト設定
Shippable の設定をします。
まずは、アカウント登録をします。

github か bitbucket が選べるのでお好きな方を使ってください。
今回は github で説明します。


github を選ぶとアクセス権を要求されます。問題なければ許可してください。




アカウント登録が済んだら、ダッシュボードの Organizations から github/bitbucket のアカウントを選択、
Repos から実行させたいリポジトリを選択するとプロジェクトが作成されます。



Shippable.yml の設定
次に、実行する処理の設定をします。
Shippable はリポジトリ直下の shippable.yml ファイルの記述にしたがって動作します。
shippable.yml の書き方は公式ドキュメントも確認してください。

language: python

python: 2.7

install:
  - pip install requests

before_script:
  - export PYTHONDONTWRITEBYTECODE=1
  - make -C tools/fuse

script:
  - cd tools/wandbox
  - python ./iuwandbox.py ../../test/iutest_syntax_tests.cpp -c ${WANDBOX_COMPILER} -f"-DIUTEST_USE_MAIN=1" --encoding utf-8-sig --expand_include

env:
  - WANDBOX_COMPILER=gcc-head
  - WANDBOX_COMPILER=gcc-4.9.1
#  - WANDBOX_COMPILER=gcc-4.9.0 # wercker
  - WANDBOX_COMPILER=gcc-4.8.2
#  - WANDBOX_COMPILER=gcc-4.8.1 # travis
  - WANDBOX_COMPILER=gcc-4.7.3
#  - WANDBOX_COMPILER=gcc-4.6.4 # drone
  - WANDBOX_COMPILER=gcc-4.5.4
#  - WANDBOX_COMPILER=gcc-4.4.7 # wercker
  - WANDBOX_COMPILER=gcc-4.3.6
  - WANDBOX_COMPILER=clang-head
#  - WANDBOX_COMPILER=clang-3.5
#  - WANDBOX_COMPILER=clang-3.4 # travis
  - WANDBOX_COMPILER=clang-3.3
#  - WANDBOX_COMPILER=clang-3.2 # wercker
#  - WANDBOX_COMPILER=clang-3.1 # wercker
  - WANDBOX_COMPILER=clang-3.0

notifications:
  email:
    on_success: change
    on_failure: always
こちらは iutest で実際に使用している設定です。
https://github.com/srz-zumix/iutest/blob/master/shippable.yml

Wandbox 連携部分(iuwandbox.py)を Python で書いているので言語は Python にしています。
install や script、before_script などはそれぞれビルドしたい内容にあわせて書くことになると思います。

また、env にコンパイラーを列挙してマトリックスを組んでいます。
Wandbox を使うのですから、様々なコンパイラーでテストするよう設定しました。

設定は以上
設定は以上です。あとはリポジトリに push すれば、自動的にビルドが走り出し、テストまでやってくれます!

バッジをつける
せっかくなので、バッジを付けたいと思います。
README なんかでよく見るアレです。

Shippable もバッジに対応していてます。
プロジェクトページの Badge を開くと、画像のリンクか Markdown のテキストが出てくるので適宜コピーして使ってください。




まとめ
  • Wandbox 最高!
    今回 CI 環境構築の肝となったのが Wandbox でした。
    多種多様なコンパイラーが扱えるので、テストに大変役に立っています。
    ホントにありがとうございます。いつもお世話になっておりますm(__)m

    とはいえ、今回紹介した iutest では push する度に 3万行近くのソースコードを投げているのですが、(しかも、マトリックス組んでるので x 10)こういう使い方は大丈夫なんでしょうか…今のところ問題は出ていませんが…ただ、それだけが気がかりではあります。

    最近だと、paiza.IO というのもリリースされたようですので、そちらも試してみようかと思ってます。

  • 使える CI ツールの幅が広がった!
    C++ で絞ると割と数が限られていた CI サービスですが、今回の方法なら言語サポートを気にすることなく使えますので、選択の幅が大きく広がったと思います。
  • C++ の話はほとんどなかった…
    C++ の話は皆無でしたね…すみません(汗)

C++ Advent Calendar 2014
明日は Fuyutsubaki さんです。よろしくお願いします。

それでは!


おまけ
この記事を執筆中、Shippable が不安定だったため、別の CI サービスとして wercker も試していました。
おまけとして簡単に紹介しておきます。

wercker も Shippable と同様に CI サービスの一種です。
対応言語は、PHP/Python/Ruby/Node.js/Go/java:android 。こちらも C++ がサポート外ですが問題ありません。

wercker も yml で動作を設定します。http://devcenter.wercker.com/articles/werckeryml/
wercker は Box と Step の組み合わせで動作する仕組みが特徴です。
http://devcenter.wercker.com/articles/introduction/pipeline.html

これら Box や Step は自作も可能ですが、今回はやってません。

また、Shippable のようなマトリックスができなさそうだったので、直列に各コンパイラーごとに Step を記述しました。
iutest の wercker.yml はこちら。
https://github.com/srz-zumix/iutest/blob/master/wercker.yml
実行結果はこんな感じになります。
https://app.wercker.com/project/bykey/d385156052aa4118a7f24affe4a8f851

2014年12月1日月曜日

iutest v1.11.0 をリリースしました

iutest v1.11.0 をリリースしました。
変更点は以下の通りです。

  • 追加
    • fused-src 対応
    • Wandbox 対応
    • Matcher に Eq,Ne,Le,Lt,Ge,Gt,IsNull,NotNull,TypeEq を追加
    • Matcher に StrEq,StrNe,StrCaseEq,StrCaseNe,HasSubstr を追加
    • Matcher に FloatEq,DoubleEq,NanSensitiveFloatEq,NanSensitiveDoubleEq を追加
    • Matcher に Not,ResultOf,Pointee を追加
    • コンテナMatcher に Each,ContainerEq,Pointwise,At,IsEmpty,ElementsAre,ElementsAreArray を追加
    • メンバーMatcher に Key,Pair,Field,Property を追加
    • ワイルドカードMatcher A,_ を追加
  • 変更
    • コンテナMatcher の Contains から HasSubstr 機能を削除
  • 修正
    • IUTEST_*_FLOAT_EQ,DOUBLE_EQ で NAN の比較が真を返す不具合を修正
    • コンテナMatcher の条件に Matcher を使えるように修正
    • Visual Studio 2015 Preview 対応
    • バグ修正

今回の大きな変更点は Matcher の種類追加、fused-src の追加、Wandbox 対応の3つです。

Matcher の種類追加
IUTEST_*_THAT で使える Matcher を大幅に追加し、
Google Mock 1.6.0 相当の Matcher が使えるようになりました。

また、Google Mock との互換性対応も少しだけしました。
対応はしましたが、ほんとに少しだけなので注意してください。
また、iutest v1.10.0 から挙動の変わった Matcher もあるので、ご了承ください。

fused-src の追加
fused-src は iutest の全ソースコードを1つにまとめたものです。
Google Test にも同様のものがあります。
1つのファイルにまとまったことで、ライブラリを作らなくてもプロジェクトに簡単に追加することができます。

とはいえ、iutest はヘッダーオンリーなテスティングフレームワークですので、メリットがないように思えますが、これは次の Wandbox 対応のための布石です。

Wandbox 対応
Wandbox で iutest が使えるように対応しました。
この話は Boost 勉強会でも話してきました。ブログズミ: Boost.勉強会#16 大阪に行ってきました

ここでは簡単に使い方を説明します。
iutest/tools/wandbox に iuwandbox.py があります。これが Wandbox 連携ツールです。

$ ./iuwandbox.py -h
usage: iuwandbox.py [-h] [-v] [--list_compiler] [--list_options LIST_OPTIONS]
                    [-c COMPILER] [-x OPTIONS] [--stdin STDIN]
                    [-f COMPILER_OPTION_RAW] [-r RUNTIME_OPTION_RAW] [-s]
                    [--permlink PERMLINK] [-o OUTPUT] [--encoding ENCODING]
                    [--expand_include]
                    [CODE]

positional arguments:
  CODE                  source code file

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  --list_compiler       listup compiler.
  --list_options LIST_OPTIONS
                        listup compiler options.
  -c COMPILER, --compiler COMPILER
                        compiler select. default=gcc-head
  -x OPTIONS, --options OPTIONS
                        used options for a compiler. default=warning,gnu++11
  --stdin STDIN         set stdin.
  -f COMPILER_OPTION_RAW, --compiler_option_raw COMPILER_OPTION_RAW
                        compile-time any additional options.
  -r RUNTIME_OPTION_RAW, --runtime_option_raw RUNTIME_OPTION_RAW
                        runtime-time any additional options.
  -s, --save            generate permanent link.
  --permlink PERMLINK   get permanent link.
  -o OUTPUT, --output OUTPUT
                        output source code.
  --encoding ENCODING   set encoding.
  --expand_include      expand include file.
上記がヘルプです。
基本的な機能としては以下の3つがありますが、今回はメイン機能であるコンパイルと実行方法について説明します。
  • コンパイルと実行
  • コンパイラーやオプションのリスト取得
  • permlink から結果を取得

コンパイルと実行
まず、コンパイルしたいソースコードですが、普通にテストコードを書くだけで OK です。
#include "../../include/iutest.hpp"

int main(int argc, char** argv)
{
    IUTEST_INIT(&argc, argv);
    return IUTEST_RUN_ALL_TESTS();
}

IUTEST(Foo, Bar)
{
    IUTEST_ASSERT_EQ(1, abs(-1));
}
あとは、ソースコードのパスを引数に iuwandbox.py に投げるだけです。
すると、以下のように結果が得られます。

--save オプションを付けると permanent link を発行。
また、--output オプションを付けると iuwandbox.py が生成したソースコードをファイルに書き出します。
コンパイラーの設定やオプションなどは、ヘルプを参照してください。

CI サービスとの連携
Wandbox でテストコードが書けるようになったことで、様々なコンパイラーでのチェックができるようになりました。
これを利用して、Travis CI や Jenkins などに組み込むことでコンパイラーチェックの自動化も簡単にできます。

C++ Advent Calender 2014 では、Wandbox + CI について書きたいと思ってます。

2014年11月20日木曜日

Travis CI で iutest を使う

前回Travis CIGoogle Test を使いました。
今回は Google Test ではなく iutest を使う方法を紹介したいと思います。

git clone するだけ
iutest はヘッダーオンリーなテスティングフレームワークです。
なので、やることは git clone するだけです。

language: cpp

compiler:
  - gcc

install:
  # iutest
  - git clone https://github.com/srz-zumix/iutest.git iutest

script:
  - cd ./test
  - make all

任意のパスに clone したら、インクルードパスを通してビルドしてください。
とっても簡単ですね--

サンプルはこちら。
https://github.com/srz-zumix/test/tree/iutest
Travis CI

2014年11月14日金曜日

Travis CI で Google Test を使う

自作テスティングフレームワークのテストを Travis CI でやっていますが、Google Test を使った場合のテストもするようにしました。

対応したときに参考にしたところ:

参考サイトに書かれていることそのまんまです。
なんの新規性もありません(汗)
.travis.yml はこんな感じ → https://github.com/srz-zumix/iutest/blob/master/.travis.yml
Makefile が汚いので誰か直してくれないかなぁー

兎にも角にも、これで gtest 互換のテストも自動化できました。
せっかくなので、「Travis CI で iutest を使う」というエントリーでも書こうかな。

2014年11月4日火曜日

[Visual Studio] GUID 挿入コマンド

仕事で GUID を挿入することが頻繁にあるのですが、いちいちツールメニューの GUID 作成ダイアログを開いてコピーするってのが面倒なので、ショートカットキーで挿入する拡張機能を探してみました。
GuidInserter2
拡張機能を「GUID」で検索して最初に出たのが GuidInserter2。
https://visualstudiogallery.msdn.microsoft.com/270f94f9-4631-4d95-8407-7954acd11bd7?SRC=VSIDE

インストールができたら、あとは「Ctrl+K, Ctrl+J」とコマンドを入力すれば、GUID が挿入されます。
ツールメニューに「GuidInserter2Settings」が追加されていますので、そちらからフォーマットを選択できます。

Insert Identifiers
少し下に出てきたのが Insert Identifiers。
https://visualstudiogallery.msdn.microsoft.com/22795583-5cc9-4681-af8e-6084f3441655?SRC=VSIDE

こちらは、「Alt+I, G」で GUID を挿入します。
フォーマットは、00000000-0000-0000-0000-000000000000 だけのようです。

最後に
個人的に、Insert Identifiers は「Alt+I, G」が押しにくいのと、フォーマットが選べないので却下。
GuidInserter2 を使うことにしました。

2014年10月21日火曜日

[gtest] 複数要素を持つパラメータでテストを書く

Google Test で値をパラメータとして扱う際に、パラメータに複数の要素を含めたい場合の書き方を説明します。

構造体をパラメータ化
ぱっと思いつく簡単な方法として構造体を使う方法があります。
struct Param
{
    int x;
    float y;
};

::std::vector<Param> make_param()
{
    ::std::vector<Param> v;
    for( int i=0; i < 5; ++i ) v.push_back(Param{ i, i*0.5f });
    return v;
}

class Test : public testing::TestWithParam<Param> {};
INSTANTIATE_TEST_CASE_P(A, Test, testing::ValuesIn(make_param()));

TEST_P(Test, A)
{
    Param p = GetParam();
    ::std::cout << p.x << ", " << p.y << ::std::endl;
}

ただ、これだと構造体の定義やパラメータの生成がやや面倒です。

tuple パラメータ
tuple をパラメータの型として扱う方法です。
class Test : public testing::TestWithParam< ::std::tuple<int, float> > {};
INSTANTIATE_TEST_CASE_P(A, Test, testing::Values(
    ::std::make_tuple(0, 0*0.5f)
    , ::std::make_tuple(1, 1 * 0.5f)
    , ::std::make_tuple(2, 2 * 0.5f)
    , ::std::make_tuple(3, 3 * 0.5f)
    , ::std::make_tuple(4, 4 * 0.5f)
    ));

TEST_P(Test, A)
{
    ::std::tuple<int, float> p = GetParam();
    ::std::cout << ::std::get<0>(p) << ", " << ::std::get<1>(p) << ::std::endl;
}

構造体の分だけ、すこ~しだけ簡単になった?気がします。
パラメータの構築は最初の例のように vector を返す関数で作ってもいいです。お好みでどうぞ。

iutest の場合
恒例の宣伝。
自作テスティングフレームワークである iutest では以下のようなに ::std::get を省略した書き方もできます。
class Test : public ::iutest::TestWithParam< ::std::tuple<int, float> > {};
IUTEST_INSTANTIATE_TEST_CASE_P(A, Test, ::iutest::Values(
    ::std::make_tuple(0, 0*0.5f)
    , ::std::make_tuple(1, 1 * 0.5f)
    , ::std::make_tuple(2, 2 * 0.5f)
    , ::std::make_tuple(3, 3 * 0.5f)
    , ::std::make_tuple(4, 4 * 0.5f)
    ));

IUTEST_P(Test, A)
{
    ::std::cout << GetParam<0>() << ", " << GetParam<1>() << ::std::endl;
}
[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

200投稿

週1回の更新を目標にやってきましたが、この投稿で200投稿となりました。
初投稿が 2011/11/06 なので約3年での達成ということで目標以上の結果となりました。
ここまで続けてこれたのもブログを見ていただいている皆様のおかげでございます。
今後ともよろしくお願いします。m(__)m

2014年10月14日火曜日

[gtest] OR 条件のアサーション

Google Group で OR 条件のアサーションはどう書くの?というトピックがあったので、紹介します。
Google C++ Testing Framework › Logical OR of EXPECT_*

AND は簡単だけど、OR は・・・
AND 条件は簡単に書けます。
TEST(Hoge, AndTest)
{
    ASSERT_NE(0, a);
    ASSERT_NE(4, a);
}

これは、a != 0 && a != 4 を意味します。

では、a == 0 || a == 4 のような条件を考えます。
TEST(Hoge, OrTest)
{
    EXPECT_EQ(0, a);
    EXPECT_EQ(4, a);
}
当然これはダメです。これでは AND になってしまします。
例えば、下記のように書けると良いのですが、残念ながらできません。
TEST(Hoge, OrTest)
{
    EXPECT_EQ(0, a) || EXPECT_EQ(4, a);
}

最も簡単な方法
Google Group でも紹介されていた最も簡単な方法です。

TEST(Hoge, OrTest)
{
    ASSERT_TRUE( a == 0 || a == 4 );
}
[----------] 1 test from Hoge
[ RUN      ] Hoge.OrTest
main.cpp(99): error: Value of: a == 0 || a == 4
  Actual: false
Expected: true
[  FAILED  ] Hoge.OrTest (4 ms)
[----------] 1 test from Hoge (6 ms total)

ただ、これでは失敗したときに a の値がなんだったのかわかりません。
なので、以下のようにして a の値を出力するようにします。

TEST(Hoge, OrTest)
{
    ASSERT_TRUE( a == 0 || a == 4 ) << "a = " << a;
}
出力はこのようになります。
[----------] 1 test from Hoge
[ RUN      ] Hoge.OrTest
main.cpp(99): error: Value of: a == 0 || a == 4
  Actual: false
Expected: true
a = 1
[  FAILED  ] Hoge.OrTest (4 ms)
[----------] 1 test from Hoge (6 ms total)

値の出力には SCOPED_TRACE を使う方法もあります。

TEST(Hoge, OrTest)
{
    SCOPED_TRACE( ::testing::Message() << a );
    ASSERT_TRUE( a == 0 || a == 4 );
}

SCOPED_TRACE は記述したスコープの間はメッセージが追記されます。なので、複数のアサーションを記述している場合は一箇所の修正で済むので楽です。
[----------] 1 test from Hoge
[ RUN      ] Hoge.OrTest
main.cpp(99): error: Value of: a == 0 || a == 4
  Actual: false
Expected: true
Google Test trace:
main.cpp(99): 1
[  FAILED  ] Hoge.OrTest (4 ms)
[----------] 1 test from Hoge (6 ms total)

Matcher を使う方法や他の方法もあると思いますが、Google Test のみの場合ではこの方法が一番だと思います。

2014年10月6日月曜日

[Jenkins] Build-timeout Plugin の「最後のログ出力からの経過時間」が便利

Build-timeout Plugin は文字通りビルドにタイムアウトの設定ができるプラグインです。
こちらの Version 1.13 からタイムアウトの判定方法に「最後のログ出力からの経過時間」が追加されました。
これがかなりいい感じです!

これまでの判定方法には
  • Absolute
  • Elastic
  • Likely stuck
がありました。

Absolute
Absolute は、絶対時間でビルド開始からの経過時間でタイムアウトする設定です。
これは、少なくともビルド成功時にかかる時間以上の時間に設定しないといけません。このため、成功時に10時間かからジョブの場合、ジョブ開始直後に問題が発生した場合でも最低10時間は待たなければいけません。これは大変無駄なことです。

Elastic
つぎに Elastic は、直近の成功ビルドの平均時間からタイムアウト時間を算出する設定です。平均時間の 150%~400% (50刻み)を設定できます。
これは一見良さそうなのですが、実行ノードが毎回異なり、さらにスレーブのマシンスペックに差があると、実行時間にばらつきが出てしまい一番遅い環境に合わせて多めにタイムアウト値を設定しなければいけなくなります。
Absolute の時と同様にジョブの実行時間が長い場合、それだけ無駄な時間が増えます。また、実行時間が短い場合、今度はマージンが少なくなりタイムアウトしなくても大丈夫な場合でもタイムアウトしてしまう、ということがありました。

Likely stuck
最後に Likely stuck の場合は、滞留している可能性が高いならば中止する設定です。この判断は Jenkins の API が判断しています。
http://javadoc.jenkins-ci.org/hudson/model/Executor.html#isLikelyStuck()
Returns true if the current build is likely stuck.
This is a heuristics based approach, but if the build is suspiciously taking for a long time, this method returns true.
この設定は使ったことがないのですが、コードを見た感じでは推定時間がある場合はその10倍(?)、なければ24時間でタイムアウトするようです。間違っていたらすみませんm(__)m
CodeNav for Github 便利だわー)
なんにせよ、この設定も無駄に長く待ってしまう感じがします。

最後のログ出力からの経過時間
新しい判定方法の「最後のログ出力からの経過時間」では、「ログ出力が停滞して○○秒後にタイムアウトする」という設定ができます。
ビルドでもテストでも大抵の場合ログ出力はあると思います。
また、ログが出ているところまでは正常なので、そこから停滞した時間の設定はそんなに多くなくて大丈夫なはずです。よって、この判定方法は他の方法よりも無駄を少なくすることができるでしょう。(当然ログが適宜出力されることを想定してます)

ビルドが長時間停滞して困っている方は一度プラグインの導入・判定方法の見直しをしてはいかかがでしょうか?

2014年9月29日月曜日

reveal.js + Markdown のちょっとしたメモ

reveal.js + Markdown でスライドを書くことが多いので、それ関係でちょっとしたことを備忘録として残しておく。

表題が大文字表記にならないようにする
表題が大文字に変換されてしまうのが嫌だったので対処してみました。

## Sample

これは sample です。


例えば上記の場合、デフォルト設定では以下のように表示されます。


これは、theme の css で表題のスタイルに text-transform: uppercase; があるためです。
これを無効にすれば良いので、theme css の指定の後に以下の記述を追記します。

<style type="text/css">
  .reveal h1,
  .reveal h2,
  .reveal h3,
  .reveal h4,
  .reveal h5,
  .reveal h6 {
    text-transform: none;
  }
</style>

これで大文字ではなく、書いたとおりに表示されます。

空行を入れる
## Sample

これは sample です。__
<!-- -->__
↑空行を入れたい。__

※わかりやすいようにスペースを "_" で表記してます。

改行をする場合、末尾にスペースを2つ入れるのですが、前方になんらかの文字が必要です。
なので、コメント + スペースとすることで空行を出力しています。


タグを直接記述する
こちらは以前にもブログに書きました。 Markdown でテキストカラーの変更
Markdown の記述中に html タグを含めてもなんら問題ありません。そのまま html に出力されます。
なので、Markdown で表現できないことも html で表現すれば OK です。

## テスト

タグを<span style="color:red">直接記述</span>することで<span style="color:blue">色</span>を変えます。



公開する
書いたスライドを公開するときは github pages が便利です。
github pages については割愛します。
GitHub Pagesホスティングサービス(ほぼ)完全活用ガイド | ゆっくりと…


手順としてはとっても簡単で、gh-pages ブランチを作って push するだけです。
例)
github: https://github.com/srz-zumix/slide
github pages: http://srz-zumix.github.io/slide/iuwandbox/#/

最後に
今回は以上です。
今後も reveal.js + Markdown でスライドを書くと思うので、また何かあったらブログに書こうと思います。