sioaji2012のブログ

普段は組み込み開発でC言語のみです。主にプログラムや勉強日記です

組込C言語でUnitTest 3 リンク集

参考ページ

ここでは、参考リンクを貼り付けします。

TDDと言えば、和田卓人さん

gihyo.jp

組込みソフトウェア開発 ノウハウ集

GoogleTest の使用を推奨する理由も少し述べられている

組込みソフトウェア開発 ノウハウ集 — 組込みソフトウェア開発 ノウハウ集 0.5.0 ドキュメント

テスト駆動開発による組み込みプログラミングをgoogletestでやる

TDD本は CppUTestですが、それをGoogletestでも実施しています。

qiita.com

テスト駆動開発による組み込みプログラミングのつどい

legoboku.blogspot.com

Google Test ドキュメント日本語訳

Google Test — Google Test ドキュメント日本語訳

Google Mock ドキュメント日本語訳

Google Mock — Google Mock ドキュメント日本語訳

組込C言語でUnitTest 2

前回のつづきから

sioaji2012.hatenablog.com

普段は、下記の本を参考にTDD(テスト駆動開発)を勉強しています。

テスト駆動開発による組み込みプログラミングC言語オブジェクト指向で学ぶアジャイルな設計」:Amazon CAPTCHA

まだ半分くらいしか読んでいません。(^_^*)

Facebook組込みTDD勉強会にも参加させて頂いています。

ツールはOSSののCppUTestです。TDDをやる理由とやり方とソースが載っています。

勉強半ばで、なかなかOUTPUTは出来ない状況です。

googletestのセットアップ

Googletestのソースを取得します

GitHub - google/googletest: Google Test

MinGWをいれる

インストールは、まずは、WindowsMinGW (またはCygwinでもいいですが) を入れました。 (インストール後、MinGWのbinフォルダと Msysのbinフォルダのpathが通っている事を確認しておく)

osdn.net

MinGWにMsysというコマンドライン実行ツールみたいのがついてるので、msysを起動してそこから googletestのソースをビルドしました。

googletestのビルド方法はこちらにありますが、

googletest/README.md at master · google/googletest · GitHub

googlemockを使うと思うので、こちらはスキップしてgooglemockのビルド方法を実施した方が良いと思います。

(ググった先で、2つを別々にビルドしてうまく動かなかった人がいたみたいなので)

GoogleMockのビルド(Googletestも同時ビルド)

googletest/README.md at master · google/googletest · GitHub

上記ページの真ん中くらいのコマンドを実行します。

C直下にソースを置きました。(フォルダ例)

/c/googletest/googletest
/c/googletest/googlemock
・・・・

msysを起動して、googlemockのフォルダで実行

/c/googletest/googlemock
$ autoreconf -fvi

これをやれ。と書いてあるので、

g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
    -isystem ${GMOCK_DIR}/include -I${GMOCK_DIR} \
    -pthread -c ${GTEST_DIR}/src/gtest-all.cc
g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
    -isystem ${GMOCK_DIR}/include -I${GMOCK_DIR} \
    -pthread -c ${GMOCK_DIR}/src/gmock-all.cc
ar -rv libgmock.a gtest-all.o gmock-all.o

こんな感じに置き換えて順番に実施

g++ -isystem /c/googletest/googletest/include -I /c/googletest/googletest \
-pthread -c /c/googletest/googletest/src/gtest-all.cc
ar -rv libgtest.a gtest-all.o

g++ -isystem /c/googletest/googletest/include -I/c/googletest/googlemock \
-isystem /c/googletest/googlemock/include -I/c/googletest/googlemock \
-pthread -c /c/googletest/googletest/src/gtest-all.cc
g++ -isystem /c/googletest/googletest/include -I /c/googletest/googletest \
-isystem /c/googletest/googlemock/include -I/c/googletest/googlemock \
-pthread -c /c/googletest/googlemock/src/gmock-all.cc
ar -rv libgmock.a gtest-all.o gmock-all.o

最後のところ。オブジェクトファイルが出来た。

$ ar -rv libgmock.a gtest-all.o gmock-all.o
a - gtest-all.o
a - gmock-all.o

フォルダ内に、リンク用のオブジェクトファイル

  • libgtest.a
  • libgmock.a

ができてると思います。

実際のテストコードをビルドするコマンド

上記ページには、こうやってビルドして。と書いてありますが、

g++ -isystem ${GTEST_DIR}/include -isystem ${GMOCK_DIR}/include \
    -pthread path/to/your_test.cc libgmock.a -o your_test

eclipseから実行したかったので、こちらのページを参考にして実施しました。

googletestのみの説明ですが、googlemockも同じ様に設定します。

(-pthread の指定がされていないかもしれないのが気になる)

GoogleTest Installation and Use in Eclipse/C++ Instructions

やっていることは、だいたいこんな感じ。


  • MINGWコンパイラに使う
  • GCC C++ Compiler の Miscellaneous の、その他フラグに、 -std=gnu++11 を最後に追加。
  • GCC C++ Compiler の Includes に、googleのソースのincludeフォルダを指定する
  • MinGW C++ Linker の Libraries に、パスを指定(上記ビルドして作ったリンク用オブジェクトファイル)、名前を設定。(libと.aを除いた部分⇛gtest と gmock)

あとは、サンプルコードで試してみればテスト出来る環境になっている事が確認出来ます。

eclipseでやるときの注意

eclipseにも、mingwが入っています。

Windowsに別途入れたMinGWeclipseminGWとではバージョンが違うので、そのままだとうまくリンク出来ないので、 eclipsemingwを使わない様にする必要があるかもしれません。

方法は、eclipseのCC C++ Compiler のビルドタブあたりに、パスを設定するとことがあるので、 eclipse/mingw32/binみたいなパスの登録を削除します。

はじめから、googletestのビルドをeclipseでビルドできれば、MINGW自体を入れる必要もないのですが・・・(出来るか不明)


つづきは、また今度

組込C言語でUnitTest 1

組込開発C言語でテストコード書きたい

普段は、組み込みファーム開発で C言語 しかプログラムしていません。

今のところ、TDD(テスト駆動開発をやりたいわけではありません。
というか出来ないです。。
(やってみたいですが・・・)

私の会社では、シミュレータを自前で開発したり、実行ログの自動解析ツールを開発したりして、 動的なシステムテストが主流になっているので、 テストコードを書くという文化はありませんし、メリットを感じられていない様です。

実際に、『テストコード書ける様に環境を作っていきます!』 と宣言した時も、一部の方から猛反撃をくらいました。

  • ほんとに効果あるの?
  • テストコードを書くにあたっての費用対効果を説明してから
    テストコード書きましょう。って言ってくださいよ!
  • 何か効果あるらしいから、やってみようは拒否する!
  • 効果があるかどうかわからん物の環境構築って、、
    それ自体無駄だからやめた方がいいんじゃないの!

・・・怖っ・・・

一応は、『テストする事についての一般的な考え』を説明してましたが。。。

後工程での不具合だと

  • 原因にたどり着くまで時間がかかる
  • 大昔の実装なので当時の資料を掘り起こす時間ロス
  • システムとして既に作り込まれているので、修正による影響範囲とか確認項目が莫大
  • 市場に不具合が出回る

前工程での不具合になると

逆の事が言える

  • 修正したらすぐテスト失敗を報告してくれるので、原因を教えてくれてるに近い。
  • 実装したばかりなので、誰がいつ何の為に実装した?とか資料集めなどいらない事が多い。
  • 修正による影響範囲とか確認項目は、たぶんさっき修正したのとそんなに変わらない。
  • 市場に不具合が出回る前に見つかった!

継続的インテグレーション

  • 昔書いたテストが不具合を教えてくれる。自分の修正箇所が他の不具合を誘発する事に気がつく。

その他

  • テストしやすいモジュール化された良いコードが出来る。
  • リファクタリングしやすくなる (上記につながる )
  • システムでは発生させるのが難しいパターンを試せる。
  • 不具合の再現確認が出来る。修正の効果確認も同様、
  • なんか、安心だ!(モチベーション大事)

デメリット

  • テストコード書く時間が増える
  • そもそもテストコード書き方の勉強が必要。
  • ハード依存の部分や、システムテストが難しいので出来ない。
  • 仕様変更や不具合修正のたびにテストコードのメンテが必要。
  • テストコード自体の信頼性が気になる(やりたいテスト。目論見のテストをしてくれているのか)

それでもやるしかない

上からおりてきた仕事ですから、やらないという選択肢は簡単ではないですし。

ただ、只今の状況は、『非常にきびしー』です。

理由

  • レガシーコード*1だから。
    テストは当然ないですが、よくわからない関数が多いのでテストが書けない。
    コード流用することは美。リファクタリングするのは悪。で、レガシーコードが蔓延しています。
    (そもそもソース構造をまとめた資料もないし)
  • デメリットをくつがえす実例を示さないといけない。(費用対効果)
    テスト出来るところを見つけて。効果を積み重ねる必要がある。でもそこまでコツコツとやらせてくれるかどうか。・・・というと駄目だろうな。
  • テストの為にオリジナルのソースに手を加えたくない。
    モックが必要になった場合に、オリジナルのソースをいじらずに出来るか。
    C言語の壁が待っていそう。

一応、

選んだツールは、OSSの GoogleTest

本当は、CppUTest が組み込み用で広く使われているので、そちらが良かったかもしれませんが、

選んだ理由の概略は、モックのコード行数が少なく済むみたいなのと、Googleさんも自分たちでつかってるんだろうという事です。


最後は、商用ツール買えば楽にテストコード書けますよ。になるかもしれない。(会社ですし)

会社でやったことは、ここでは書けませんが、

redmineプラグイン開発のお勉強を保留して自分の時間を使ってしまいましたし、

(これはこれでグレーですが・・・。自己啓発ということで。。。)

少し覚え書きな感じになりますが、自宅で検討した内容を、あと少し書き留めていこうと思います。

つづきは、次回へ。


*1:一般的には『理解しづらい・変更しにくいコード』TDD本?では『テストの無いコード』だと思います

Redmineプラグインもくもく 山梨 #007回 プラグイン作成試し

前回、

Rubyの記述の意味がわかりませんでした

これ。

module RedmineIine
  class Hook < Redmine::Hook::ViewListener
    def view_layouts_base_content(context = {})
      controller = context[:controller]
      if controller.controller_name == 'issues' && controller.action_name == 'show'
        controller.render partial: 'redmine_iine/hooks/view_layouts_base_content'
      end
    end
  end
end

少しだけ、勉強しようと思いますが・・・。

(本来は体系的な勉強しなければいけないですが・・・すみません。。。)

モジュール - Ruby入門

Redmineプラグイン作成でHookを使ってみる - torutkの日記

上記ページからの抜粋になりますが、調べた結果を書きます。

Rubyではクラスという概念に似たものとしてモジュールという概念があります。

・モジュールはクラスと同じくメソッドを定義する事が出来ます。
・クラス変数に相当するものはモジュールにはありませんが、
 定数は定義する事が出来ます。
・クラスはクラスからオブジェクトを作成することが出来ますが、
 モジュールでは作成することは出来ません。

フックへ登録するコールバックの定義

 まず、フックのコールバックを実装するクラスを定義します。
 このクラスは、Redmine::Hook::ViewListenerクラスを継承します。
 クラス定義を記述するファイルは、プラグインのlib下に置きます

lib/redmine_iine/hook.rb

module RedmineIine ★モジュール名
  class Hook < Redmine::Hook::ViewListener ★クラスを継承
    def view_layouts_base_content(context = {}) ★クラスと同じメソッド
      controller = context[:controller]
      if controller.controller_name == 'issues' && controller.action_name == 'show'
        controller.render partial: 'redmine_iine/hooks/view_layouts_base_content' ★部分テンプレート
      end
    end
  end
end

・モジュールの利用方法としては、
 「モジュール名.メソッド名」の形式で関数のように実行するか、
 他のクラスの中にインクルードして利用することが出来ます。

Redmineプラグイン作成の情報を調べていると、
 moduleを定義している例と定義していない例を見かけますが
 (定義していないものが多い感触)、
 書籍「Redmine Plugin Extension and Development」では
 moduleを導入しているのでそれに倣っています。
 moduleにはプラグイン名をPascalケースにした文字列を指定しています。

・クラスの中身ですが、フック名と同じ名前のメソッドを定義して、
 その中で文字列(HTML)を作成しreturnするサンプルをよく見かけますが、
 書籍ではrender_onでフック名と部分テンプレートを指定している。

部分テンプレートは、ここで指定した名前の先頭にアンダースコアを付け、
 拡張子を.erbとしたファイルに記述します
 (拡張子は、.html.erbなどでも可)。
 ファイルの場所はプラグインのapp/views/redmine_iine/hooks/の下に置きました。

app/views/redmine_iine/hooks/_view_layouts_base_content.html.erb

<%= link_to 'いいね!', '#', class: 'redmine-iine', style: 'display: none;' %>

<script>
  $('.redmine-iine').on('click', function(e) {
    e.preventDefault();
    alert('いいね!');
  });

  $(function() {
    $('.redmine-iine').prependTo('#content .contextual').show();
  });
</script>

フックへ登録(init.rb)

init.rbに次を記述します。

require_dependency 'redmine_iine/hook'

libしたのlib/redmine_iine/hook.rbが呼び込まれます。

部分テンプレートを適用する条件

controller = context[:controller]
if controller.controller_name == 'issues' && controller.action_name == 'show'
  controller.render partial: 'redmine_iine/hooks/view_layouts_base_content' ★部分テンプレート
end

実装したい画面のコントローラ名:'issues'
アクション名: 'show'
これらを探すときは、
・実際にRedmine操作して、ログから追うのが早い。
・あとは、routesを読むか。
(ハンズオンより)


今回は、以上です。
わかった様な気になっているだけですが、次に進もうと思います。
只今、体調が絶不調中。。。会社も休みがちで、もくもくもあまり進められませんでした。


Redmineプラグインもくもく 山梨 #006回 プラグイン作成試し

前回、init.rb を書いただけという状態でした。 今回は、こちら。

チケット詳細ページにいいねを表示する。

既存のviewに何か要素を追加するときは、hook + jsで!

公式ページ hookリスト

www.redmine.org

既存画面に何か追加したい場合に、
上記のHooks List の中にあるView Hooksを使って実装していく。

パーシャル(Viewの断片ページ)を呼ぶ。

View Hooksでerbを挿入することになるが、
表示したいhtmlをそのまま挿入とせず、Javascriptで要素を差し込むような感じ。
Redmine本体のビューがとても変わりやすい為、JavaScriptで埋め込んだほうが後で柔軟に対応できる。

■app/views/redmine_iine/hooks/_view_layouts_base_content.html.erb
・'いいね!'のリンクにclass 'redmine-iine'を設定して、クラスで要素を指定。
・リンクが押されたらアラート表示。
・リンクは、'#content .contextual'要素の手前に追加表示する。

<%= link_to 'いいね!', '#', class: 'redmine-iine', style: 'display: none;' %>

<script>
  $('.redmine-iine').on('click', function(e) {
    e.preventDefault();
    alert('いいね!');
  });

  $(function() {
    $('.redmine-iine').prependTo('#content .contextual').show();
  });
</script>

汎用的なhookポイントを使う

RedmineのHooksでほしい位置に挿入できるようなHooksがないことがある。
(チケットの下に差し込むHookはあっても、上に差し込むのがなかったりなど)

Hookを上記ページからがんばって探すより、
汎用的に使える view_layouts_base_content で差し込んじゃう方を選ぶ感じ。

■lib/redmine_iine/hook.rb
・view_layouts_base_contentのHookを使う。
・html のbody のボトムに差し込まれる
・ここにおいて、(disply: none)、JSで置き換える。

module RedmineIine
  class Hook < Redmine::Hook::ViewListener
    def view_layouts_base_content(context = {})
      controller = context[:controller]
      if controller.controller_name == 'issues' && controller.action_name == 'show'
        controller.render partial: 'redmine_iine/hooks/view_layouts_base_content'
      end
    end
  end
end

■init.rb

require_dependency 'redmine_iine/hook'

Redmine::Plugin.register :redmine_iine do
  name 'Redmine いいね!Plugin'
  author 'sioaji'
  version '0.0.1'
end

実装したい画面のコントローラとアクション名を探すときは

実際にRedmine操作して、ログから追うのが早い。
あとは、routesを読むか。

ここまでの結果

表示した "いいね!" を押した場面。

f:id:sioaji2012:20180606211156p:plain


今日は、ここまで。
やっぱり、途中のフック指定するところが、ruby on rails な感じで
勉強しないとわからないので、お勉強しなければならない。…ですね。(^_^;)

 

Redmineプラグインもくもく会 山梨 #005回 プラグイン作成試し

これまでの開発環境を駆使するには、DockerやRailsなど詳しく勉強する必要があるかもしれませんが、一気にやっても多分忘れてしまうので(という理由で)後回しにしつつ、以前ハンズオンでちんぷんかんぷんだったものをトレースしながら、プラグイン作成にそって勉強を少しずつしていこうと思います。

agileware.connpass.com

それでは、こちらのハンズオンを思い出していきたいと思います。

プラグインを作成する

プラグインチュートリアルでは、ジェネレータでプラグインの雛形を作る方法が紹介されているのですが、ジェネレータの情報アップデートがいまいちらしく、失敗する事があるので信用していないという事でした。(ベタに作成することになります)

あと、ハンズオンはRedmine4に向けたハンズオンなので、今回の3.3.2環境ではうまくいかない可能性あり、途中でギブになる可能性あります。(^_^;)

題材は、『いいね!ボタン』です。

プラグインフォルダを作成

Dockerの開発環境用Redmineを起動します。

$ REDMINE_VERSION=3.3.2 docker-compose build --no-cache
$ docker-compose up -d 

作ったドッカー内に入ります。
■ docker exec -it 名前など /bin/bash
・-i : Interactive
・-t: terminal

$ docker exec -it redmine_sqlite3 /bin/bash

中に入れました。

root@ac584a652c94:/tmp/redmine# ls
CONTRIBUTING.md  Gemfile.lock  Rakefile  appveyor.yml  config     db   extra  lib  plugins  script  tmp
Gemfile      README.rdoc   app   bin           config.ru  doc  files  log  public   test

プラグイン用フォルダ『redmine_iine』を作成します。

cd plugins
mkdir redmine_iine

init.rbを作成

プラグインが最初に読み込むものを作成します。

ここからは、MAC側からソース修正してみます。 
Dockerfileと同じフォルダにpluginsフォルダを作ってあって、このフォルダがDockerコンテナ内のpluginsフォルダとの共有フォルダになっています。
(docker-compose.ymlで設定してる)

ctrl+p -> ctrl+q で抜けるとdockerコンテナは起動したまま、抜けられます。

ctrl+p
ctrl+q

MAC側のpluginsフォルダの中には、先程コンテナ内で作成した『redmine_iine』フォルダが作成されているのがわかると思います。

テキストエディタ等で、『init.rb』ファイルを作成します。

init.rb

Redmine::Plugin.register :redmine_iine do
  name 'Redmine いいね!Plugin'
  author 'sioaji'
  version '0.0.1'
end

ここで、通常ですと、プラグインを再読込のために、
railsサーバーをCtrl-C停止後、再起動するのですが、
現状のDocker構成でのやり方がわかりませんでした。

$ docker-compose restart
とか
$ docker stop redmine_sqlite3
$ docker start redmine_sqlite3
とかやっても
再起動されたコンテナがすぐに終了してしまう

困って、ググりました。

dev.classmethod.jp

unskilled.site

けど、良くわからず、、、一応ですが、

docker-compose.ymlを修正する事にしました。

★★★マークの行追加。

version: '3'
services:
  web:
    build:
      context: .
      args:
        REDMINE_VERSION: $REDMINE_VERSION
    image: redmine_sqlite3
    container_name: redmine_sqlite3
    command: >
      bash -c "bundle exec rake redmine:plugins:migrate &&
           bundle exec rails s -p 3000 -b '0.0.0.0'"
    environment:
      RAILS_ENV: development
    volumes:
      - ./plugins:/tmp/redmine/plugins
    ports:
      - "3000:3000"
    stdin_open: true ★★★
    tty: true ★★★

stdin_open: 標準入力
tty: 端末の付与

相当するdocker runオプション −it と同等になる様で、
こうすると、すぐにコンテナが終了しないっぽい。
(よく理解できていないです)

この構成でイメージ作り直して起動します。

$ REDMINE_VERSION=3.3.2 docker-compose build --no-cache
$ docker-compose up -d 

再起動する

docker-compose restart

で再起動した感じになる。
pluginのマイグレートとサーバーの起動するのかな。
二重起動とか心配。
(必ずうまくいくわけでは無さそう。すぐに終了しないでうまくいく場合がおおい感じ)

・・・ひとまずこのやり方で進めます。(^_^;)

ここまでの結果

f:id:sioaji2012:20180530234641p:plain


今回は、ここまで。ほとんど進まず(^_^;) 
次回は、いいね!ボタン表示とhookを少し。な感じでしょうか。

先は長いかも。。です。。。


Redmineプラグインもくもく会 山梨 #004回 開発環境

(まだ)開発環境の続きです。(遅い・・・(^_^;) )

DockerCompose

・Dockerツール群の一つであるDockerComposeを使うと、コンテナ立ち上げ設定をファイル化(yml形式)して管理することが可能になります。
・docker-compose で起動する場合は、Dockerfileを使ってイメージを作成します。

Docker Composeについてもほんの少し(汗)勉強しました。

Docker お勉強 04 Docker Compose - sioaji2012のブログ

対象の docker-compose.yml はこちら。

version: '3'
services:
  # start service for redmine with plugin
  # 1. $ docker-compose build --force-rm --no-cache
  # 2. $ docker-compose up -d
  #
  # If you want to change Redmine's version,
  #
  # 1. $ REDMINE_VERSION=master docker-compose build --force-rm --no-cache
  # 2. $ docker-compose up -d
  #
  #
  web:
    build:
      context: .
      args:
        REDMINE_VERSION: $REDMINE_VERSION
    image: redmine_sqlite3
    container_name: redmine_sqlite3
    command: >
      bash -c "bundle exec rake redmine:plugins:migrate &&
           bundle exec rails s -p 3000 -b '0.0.0.0'"
    environment:
      RAILS_ENV: development
    volumes:
      - ./plugins:/tmp/redmine/plugins
    ports:
      - "3000:3000"

勉強不足ですが、少しだけ説明書いてみます。

★今の最新は compose Ver3
version: '3'

★『WEB』というサービス名となる
services:
  web:

    ★構築時に適用するオプションを指定
    build:

      ★Dockerfile があるパス(や Git URL)を指定 → カレントDIR
      context: .

      ★構築時の引数指定
      args:
        REDMINE_VERSION: $REDMINE_VERSION

    ★ローカルのimageから検索して、なけれ DockerHubからの取得を試みる。
   (buildを指定した場合は構築する)
    image: redmine_sqlite3

    ★カスタム・コンテナ名
    container_name: redmine_sqlite3

    ★デフォルトのコマンドを上書きする
    ★DockerFileはrailsサーバー起動のみで、
     こちらはpluginマイグレードを追加したコマンドにしてる。
    ★docker run だとプラグインなしでRedmine起動。
     composeはプラグインつき起動になる。
    command: >
      bash -c "bundle exec rake redmine:plugins:migrate &&
           bundle exec rails s -p 3000 -b '0.0.0.0'"

    ★環境変数を追加する
    environment:
      RAILS_ENV: development

    ★コンテナ内にマウントするボリュームを指定する( ホスト:コンテナ )
    ★コンテナ内は、Redmineの標準pluginsフォルダ
    ★ホスト側は、カレントDirにpluginsというフォルダを作っている。
     MAC側でこの中にpluginソースを配置して開発する。
    volumes:
      - ./plugins:/tmp/redmine/plugins

    ★公開用のポートを指定する(ホスト側:コンテナ側)
    ports:
      - "3000:3000"

実行オプション docker-compose build

REDMINE_VERSION=3.3.2 docker-compose build --no-cache
docker-compose up -d

こちらも少しだけ説明してみます。

★引数を指定 REDMINE_VERSION=3.3.2
★構築する build
 オプション:
 --force-rm  常に中間コンテナを削除
 --no-cache  構築時にイメージのキャッシュを使わない ★こちら
 --pull      常に新しいバージョンのイメージ取得を試みる
REDMINE_VERSION=3.3.2 docker-compose build --no-cache

★サービス用のコンテナの構築、作成、起動、アタッチを行う:up
 オプション:
 -d  デタッチド・モード: バックグラウンドでコンテナを実行し、新しいコンテナ名を表示
docker-compose up -d

Dockerファイルを基本に適時Compose側の設定で構築・起動していく感じでしょうか。

以上が、DockerComposeの簡単な説明になります。
(もし余裕が出来たらDockerをもっと勉強しなくては。。。その前にRuby On Railsもですが。。。)

build結果

最後の方のログ (Dockerfileのdb:migrate終わったあたりから)
コマンドのステップありますが、実行されていない状態だと思います。

== 20160529063352 AddRolesSettings: migrated (0.0005s) ========================

Removing intermediate container 244ba24cd9b2
 ---> f7771e68733e
Step 13/15 : RUN bundle exec rake generate_secret_token
 ---> Running in 81f23bf15e13
Removing intermediate container 81f23bf15e13
 ---> 4e49572fc819
Step 14/15 : CMD bundle exec rails s -p 3000 -b '0.0.0.0'
 ---> Running in 0fc6f20e4369
Removing intermediate container 0fc6f20e4369
 ---> 41e55eadecaa
Step 15/15 : EXPOSE 3000
 ---> Running in 8b167069180b
Removing intermediate container 8b167069180b
 ---> 2315b3a0cca7
Successfully built 2315b3a0cca7
Successfully tagged redmine_sqlite3:latest

起動 (docker-compose up -d)

mbp:redmine_my_plugin sioaji$ docker-compose up -d
WARNING: The REDMINE_VERSION variable is not set. Defaulting to a blank string.
Recreating redmine_sqlite3 ... done

起動したコンテナの確認(docker ps)

mbp:redmine_my_plugin sioaji$ docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED
c288f733f5dc        redmine_sqlite3     "bash -c 'bundle exe…"   About a minute ago

STATUS              PORTS                    NAMES
Up About a minute   0.0.0.0:3000->3000/tcp   redmine_sqlite3

注意する事がありました。

同じことを何回もやると、古いイメージデータが名無しで残り続ける(HDD容量減る)ので注意。  
 
今のイメージ(ID = 2315b3a0cca7)

mbp:redmine_my_plugin sioaji$ docker images

REPOSITORY        TAG        IMAGE ID         CREATED          SIZE
redmine_sqlite3   latest     2315b3a0cca7     16 minutes ago   937MB

 
2回目のイメージ(ID = 420c17967e35)
ID = 2315b3a0cca7 は名無しで残り続ける。(タグがついていない)

mbp:redmine_my_plugin sioaji$ docker images

REPOSITORY        TAG        IMAGE ID         CREATED          SIZE
redmine_sqlite3   latest     420c17967e35     4 minutes ago    937MB
<none>            <none>     2315b3a0cca7     23 minutes ago   937MB

不要なイメージを消す

docker rmi イメージID

$ docker rmi 2315b3a0cca7

もくもくで使いそうなDockerコマンド

殴り書きですが、使いそうなコマンドを書いておきます。

http://localhost:3000
------------------------------------------------------------
/* 基本 */
------------------------------------------------------------
$ docker-compose build
$ docker-compose up -d

------------------------------------------------------------
/* バージョン指定 */
------------------------------------------------------------
Dockerfile FROM ruby:2.2.2

$ REDMINE_VERSION=3.3.2 docker-compose build --no-cache
$ docker-compose up -d

------------------------------------------------------------
/* 構築済みのイメージを起動する */
------------------------------------------------------------
■ docker start コンテナ
$ docker start redmine_sqlite3

■ docker stop コンテナ

------------------------------------------------------------
/* 作ったドッカー内に入る */
------------------------------------------------------------
■ docker exec -it 名前など /bin/bash
-i : Interactive
-t: terminal 

$ docker exec -it redmine_sqlite3 /bin/bash

------------------------------------------------------------
/* コンテナを外から止めるか中から止めるか */
------------------------------------------------------------
■ 中から止める
exitでコンテナから抜けた時のコンテナ起動→接続

$ sudo docker start <コンテナID>
$ sudo docker attach <コンテナID>

ctrl+p -> ctrl+q で抜けるとdockerコンテナは起動したまま、抜けられる
$ sudo docker attach <コンテナID>
で再入場


■ 外から止める
$ sudo docker stop <コンテナID>
$ sudo docker start <コンテナID>

$ sudo docker stop redmine_sqlite3

------------------------------------------------------------
/* 作業中のコンテナをイメージとして保存する */
------------------------------------------------------------
■ docker commit 名前など 保存イメージ名

$ docker commit redmine_sqlite3 create_ticket

⬇
イメージ一覧で確認
$ docker images

------------------------------------------------------------
/* コンテナ消す */
------------------------------------------------------------
$ docker rm コンテナIDとか名前していする

- docker start: コンテナを起動する
- docker stop : コンテナを止める(コンテナプロセスにSIGTERMを送信して一定時間経過後にSIGKILLを送信、デフォルトは10秒後)
- docker kill : コンテナを止める(直ちにSIGKILLを送信)
- docker rm : 停止状態のコンテナを削除 
- docker rm -f : 起動状態のコンテナも削除 
- docker ps -aq | xargs docker rm -f : 全部のコンテナをまとめてrm
  or
- docker rm -f 'docker -aq'

------------------------------------------------------------
/* イメージ消す */
------------------------------------------------------------
$ docker rmi <IMAGE ID> 

■未使用イメージ一括削除
$ docker image prune

■タグがついていないイメージをすべて削除する
docker rmi $(docker images -f 'dangling=true' -q)

------------------------------------------------------------
/* docker run */
------------------------------------------------------------
■名前つける
$ sudo docker run -it --name infra-workshop-sioaji centos
$ sudo docker rename 変更前の名前 変更後お名前

■docker run -v のお話
-v : volume

$ sudo docker run -it --name "mamy1326" -v /home/psuser:/home/test centos
[option] image [command] を守ればオプションの順番は問われないと思いますー
イメージ名は最後

参考:Docker の Data Volume まわりを整理する
https://qiita.com/lciel/items/e21a4ede3bac7fb3ec5a

■ 起動したコンテナのIPを知らべる
# for cname in $(docker ps |grep -v NAMES|awk '{print $1}'); do echo -n "${cname} ";docker inspect -format="{{ .NetworkSettings.IPAddress }}" ${cname}; done

00c5ccb98f17 ormat=172.17.0.8
39d0cd55f2f3 ormat=172.17.0.7
bf091cc5eafa ormat=172.17.0.6
4b2898c6f5a0 ormat=172.17.0.5
08d6607d8676 ormat=172.17.0.4
cb8719479fd3 ormat=172.17.0.3
dac5fd5ff2e9 ormat=172.17.0.2



今回は以上でした。
このままで、コンテナのrailsを再起動する方法がわかりませんでした。どうやってやるのかな。
developmentなので、再起動不要らしいのですが。。。

次回からは、以前ハンズオンでちんぷんかんぷんだったプラグインを写経してみようと思います。