判断と処理を分けて読みやすくする

判断と処理を分けると、読みやすく、テストしやすく、デバッグしやすくなります。

例は javascriptで書いています。

1.初期バージョン

最初に書くバージョンはだいたいこんな感じです。
「もろもろの処理」は、複数行だったり、if文やfor文を含むことがあります。

function func2 (a, b) {
    if (a > 10) {
        if (a > 20) {
            if (a > 30){
                もろもろの処理_1
            } else {
                もろもろの処理_2
            }
        } else {
            もろもろの処理_3
        }
    } else {
        もろもろの処理_4
    }
}

2.もろもろの処理をそれぞれ別メソッドにします。

function func2 (a, b) {
    if (a > 10) {
        if (a > 20) {
            if (a > 30){
                func2_1();
            } else {
                func2_2();
            }
        } else {
            func2_3();
        }
    } else {
        func2_4();
    }
}

function func2_1() {
    もろもろの処理_1
}

function func2_2() {
    もろもろの処理_2
}

function func2_3() {
    もろもろの処理_3
}

function func2_4() {
    もろもろの処理_4
}

3.「判断」と「処理」を別メソッドにします。

function func2 (a, b) {
    var num = case_number(a, b);
    process(num);
}

function case_number(a, b) {
    var num = 0;
    if (a > 10) {
        if (a > 20) {
            if (a > 30){
                num = 1;
            } else {
                num = 2;
            }
        } else {
            num = 3;
        }
    } else {
        num = 4;
    }
    return num;
}

function process(num) {
    switch (num) {
        case 1:
            func2_1();
            break;
        case 2:
            func2_2();
            break;
        case 3:
            func2_3();
            break;
        case 4:
        default:
            func2_4();
            break;
    }
}

4.判断内のif文のネストをelse〜ifで小さくします。

function case_number(a, b) {
    var num = 0;

    if (a <= 10) {
        num = 4;
    } else if (a <= 20) {
        num = 3;
    } else if (a <= 30) {
        num = 2;
    } else {
        num = 1;
    }

    return num;
}

5.デシジョンテーブル風のコメントをつけておきます。

/*
| # | a     | action  |
| - | ----- | ------- |
| 4 | <= 10 | func2_1 |
| 3 | <= 20 | func2_2 |
| 2 | <= 30 | func2_3 |
| 1 | > 30  | func2_4 |
*/
function func2 (a, b) {
   ...
}

6. if文の条件式が長いときは、それぞれ別メソッドにします。

function case_number(a, b) {
    var num = 0;

    if (is_later_equal(a, 10)) {
        num = 4;
    } else if (is_later_equal(a, 20)) {
        num = 3;
    } else if (is_later_equal(a, 30)) {
        num = 2;
    } else {
        num = 1;
    }

    return num;
}

function is_later_equal(a, x) {
    var f = (a <= x);
    return f;
}

最後に、func2メソッドの処理をとりだして、別クラスにします。

cordovaで開発したiPhoneアプリをappiumでテスト(2/2)

cordovaで開発したiPhoneアプリをAppiumでテストしたので、まとめました。

cordovaで開発したiPhoneアプリをappiumでテスト(1/2)
1.目標
2.simulator用appをビルド
3.appium他のインストール
4.Appiumデスクトップのインストール
5.Appiumデクトップを起動、Inspectorウィンドウで操作の記録

cordovaで開発したiPhoneアプリをappiumでテスト(2/2)
6.nodeでテストケース作成(アプリ起動のみ)
7.テストケースの実行
8.テストケース作成(座標をタップ、スクリーンショット保存)

6.nodeでテストケース作成

githubにappium公式サンプルソースがあります。
https://github.com/appium/sample-code

sample-code/examples/node/helpers/*.js
sample-code/examples/node/ios-simple.js
sample-code/examples/node/package.json
をダウンロードして、ios-simple.jsを改造します。

/Users/taro/projects/hello/platforms/ios/appium-testcaseの下に
helpers/*.js
ios-simple.js
package.json
を保存しました。

必要なnodeモジュールをインストールします。

$ cd /Users/taro/projects/hello/platforms/ios/appium-testcase
$ npm install

beforeメソッドのdesired変数は、「4.Appiumデクトップを起動、Inspectorウィンドウで操作の記録」のdesired capbilitiesの各項目を参考に設定してください。

テストケースの内容は、アプリを起動して、1秒間表示して、終了するだけです。

ios-simple.jsを編集します。

"use strict";

require("./helpers/setup");

var wd = require("wd"),
    _ = require('underscore'),
    Q = require('q'),
    serverConfigs = require('./helpers/appium-servers');

describe("ios simple", function () {
  this.timeout(300000);
  var driver;
  var allPassed = true;

  before(function () {
    var serverConfig = process.env.npm_package_config_sauce ?
      serverConfigs.sauce : serverConfigs.local;
    driver = wd.promiseChainRemote(serverConfig);
    require("./helpers/logging").configure(driver);

    var desired = {
      "appium-version": "1.4",
      platformName: "iOS",
      deviceName: "iPhone 7",
      platformVersion: "11.0",
      automationName: "XCUITest",
      app: "/Users/taro/projects/hello/app/Applications/HelloWorld.app",
    }; 

    return driver.init(desired);
  });

  after(function () {
    return driver
      .quit()
      .finally(function () {
        if (process.env.npm_package_config_sauce) {
          return driver.sauceJobStatus(allPassed);
        }
      });
  });

  afterEach(function () {
    allPassed = allPassed && this.currentTest.state === 'passed';
  });

  it ("test_1", function () {
    return driver
      .sleep(1000)
  });

});

7.テストケースの実行

appiumサーバの起動

Appiumデスクトップで[Start Server]しておくか、または、ターミナルで

appiumサーバの起動
$ appium &

appiumサーバの停止
$ pkill -f appium

テストケースの実行

$ cd /Users/taro/projects/hello/platforms/ios/appium-testcase
$ npm run ios-simple

iPhone simulatorの終了

$ pkill -f CoreSimulator

8.テストケース作成(座標をタップ、スクリーンショット保存)

Inspectorウィンドウで、xy座標をメモしてはクリックを繰り返して、テストケースを作りました。
次のように、座標指定のタップ、スクリーンショット保存処理、AlertダイアログのOKを追加しました。

"use strict";

require("./helpers/setup");

var wd = require("wd"),
    _ = require('underscore'),
    Q = require('q'),
    serverConfigs = require('./helpers/appium-servers'),
    fs = require('fs');

describe("ios simple", function () {
  this.timeout(300000);
  var driver;
  var allPassed = true;

  before(function () {
    var serverConfig = process.env.npm_package_config_sauce ?
      serverConfigs.sauce : serverConfigs.local;
    driver = wd.promiseChainRemote(serverConfig);
    //require("./helpers/logging").configure(driver);

    var desired = {
      "appium-version": "1.4",
      platformName: "iOS",
      deviceName: "iPhone 7",
      platformVersion: "11.0",
      automationName: "XCUITest",
      app: "/Users/taro/projects/hello/app/Applications/HelloWorld.app",
    }; 

    driver.saveScreenshot = function (path) {
      return driver.takeScreenshot().then(function(data) {
        fs.writeFile(path, data, "base64", function(err) {
          if (err) {
           throw err;
          }
        });
      });
    };

    return driver.init(desired);
  });

  after(function () {
    return driver
      .quit()
      .finally(function () {
        if (process.env.npm_package_config_sauce) {
          return driver.sauceJobStatus(allPassed);
        }
      });
  });

  afterEach(function () {
    allPassed = allPassed && this.currentTest.state === 'passed';
  });

  var tap_at = function (x, y) {
    var action = new wd.TouchAction();
    return action
      .press({"x": x, "y": y})
      .wait(100)
      .release();
  }

  it ("test_1", function () {
    return driver
      .sleep(1000)
      .saveScreenshot("/Users/taro/projects/hello/platforms/ios/appium-testcase/screenshots/01.png")

      .performTouchAction(tap_at(161, 464))
      .sleep(1000)
      .saveScreenshot("/Users/taro/projects/hello/platforms/ios/appium-testcase/screenshots/02.png")

      .acceptAlert()
      .sleep(1000)
      .saveScreenshot("/Users/taro/projects/hello/platforms/ios/appium-testcase/screenshots/03.png")
  });

});

最終的に、desired変数のdeviceName、platformVersion、appやスクリーンショット保存パスは、環境変数で渡すようにしました。
また、シミュレータでの実行が思ったより遅かったので、sleepで調整しています。

cordovaで開発したiPhoneアプリをappiumでテスト(1/2)

cordovaで開発したiPhoneアプリをAppiumでテストしたので、まとめました。

cordovaで開発したiPhoneアプリをappiumでテスト(1/2)
1.目標
2.simulator用appをビルド
3.appium他のインストール
4.Appiumデスクトップのインストール
5.Appiumデクトップを起動、Inspectorウィンドウで操作の記録

cordovaで開発したiPhoneアプリをappiumでテスト(2/2)
6.nodeでテストケース作成(アプリ起動のみ)
7.テストケースの実行
8.テストケース作成(座標をタップ、スクリーンショット保存)

当初、XcodeのXCUITestでwebviewのDOMを取得できなかったので、appiumを使ってみました。結局、appiumでもwebviewのDOMを取得できず、xy座標を指定してタップ操作を記述することにしました。それなら、XCUITestでテストケースを書いたほうがよかったかもしれません。

1.目標

全画面を遷移し、スクリーンショットを保存する。

対象機種のシミュレータ:
iPhone X、iPhone 8、iPhone 7 (11.0)、iPhone 7 Plus (11.0)、iPhone 6 (10.3)

2.simulator用appをビルド

cordovaプロジェクトの位置=/Users/taro/projects/hello
xcodeワークスペースの位置=/Users/taro/projects/hello/platforms/ios/HelloWorld.xcworkspace
appのファイル位置=/Users/taro/projects/hello/app/Applications/HelloWorld.app

ターミナルで次のsim_build.shを実行します。
app/Applications/HelloWorld.appが作成されます。

$ cd /Users/taro/projects/hello
$ ./sim_build.sh

/Users/taro/projects/hello/sim_build.sh

#!/bin/bash -x

WORKSPACE=HelloWorld
SCHEME=HelloWorld
CONFIG=Debug
SDK=iphonesimulator

xcodebuild \
  -workspace $WORKSPACE \
  -scheme $SCHEME \
  -configuration $CONFIG \
  clean \
  DSTROOT=${PWD}/app

xcodebuild \
  -workspace $WORKSPACE \
  -scheme $SCHEME \
  -configuration $CONFIG \
  -sdk iphonesimulator \
  install \
  DSTROOT=${PWD}/app

3.appium他のインストール

必要なものをインストールしてください。
ターミナルの cd する場所はどこでもかまいません。

Homebrewのインストール
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

rbenvのインストール
$ brew install rbenv ruby-build readline

RubyのパスをBashに追記
$ echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile
$ source ~/.bash_profile

Rubyのインストール
$ rbenv install --list
$ rbenv install 2.4.2
$ rbenv global 2.4.2
$ ruby -v

$ npm install -g appium
$ npm install -g appium-doctor
$ brew install carthage

環境確認
$ appium-doctor --ios

4.Appiumデスクトップのインストール

デスクトップ版 appium
https://github.com/appium/appium-desktop/releases

最新バージョンの appium-desktop-x.x.x.dmg をダウンロード、インストールしてください。

4.Appiumデクトップを起動、Inspectorウィンドウで操作の記録

Finder>アプリケーション>Appiumを起動してください。
[Simple]のまま、[start server]をクリックしてください。

黒いログコンソールが表示されます。
右上の虫メガネ[Start Inspector Session]ボタンをクリックしてください。

Inspectorウィンドウが表示されます。
Desired Capabilitiesタブで、次の5項目を設定してください。

項目
platformName text iOS
automationName text XCUITest
deviceName text iPhone 7
platformVersion text 11.0
app text /Users/taro/projects/hello/app/Applications/HelloWorld.app

platformName
“iOS”固定です

automationName
“XCUITest”固定です

deviceName
“iPhone 7″、”iPhone 7 Plus”、”iPhone 6″、”iPhone 6 Plus”などを入力します。

platformVersion
“10.3”、”11.0″などを入力します。
Xcodeで”9.3″シミュレータもダウンロード済みでしたが、appiumから”9.3″は起動できず諦めました。

app
「1.simulator用appをビルド」で作成したappファイルの絶対パスを指定してください。

[Start Session]をクリックしてください。
しばらくすると、iPhoneシミュレータが表示されます。
iPhoneシミュレータでテスト対象アプリが起動します。
Inspectorウィンドウにスクリーンショットが表示されます。

スクリーンショット上でマウスを動かしてみてください。
識別可能な画面要素が黄色くなり、クリックすると、緑になります。
ウィンドウの中央のApp Source領域には、ツリーが表示されます。
右側のSelected Element領域には、クリックした画面要素のXCUIElementツリーのxpathが表示されます。

cordovaで開発したアプリなので、画面要素はWebView内です。残念ながらDOM IDで画面要素を指定できないようです。画面要素が存在していること、属性が期待した値になっていること、などをアサーションしたいのですが、今回はあきらめました。

いろいろ試して、次の操作でテストケースを書くことにしました。

sleep(ミリ秒)
x, y座標指定のタップ
alertダイアログのOK
スクリーンショットの保存

iPhone 7でxy座標を調べて、iPhone 7 Plusなら座標を1.1倍することにし、iPhone Xは別に座標定義を用意することにしました。

画面ごとにスクリーンショットを保存し、担当者が見て確認することにしました。

(つづく)

三項演算子はデバッグしにくい

三項演算子はデバッグしにくいので、デバッグしやすさという観点では使わないほうがいいと思います。

三項演算子の例

x = (a < b) ? a : b;

if文の例

if (a < b) {
    x = a;
} else {
    x = b;
}

理由1:
デバッガでステップ実行したとき、if文のほうが処理の流れを追いやすいから。

三項演算子の文をデバッガでステップ実行すると、単に次の行に移動します。行を追っているだけでは、aとbのどちらを採用したのかがわかりません。a, b, xの値を読んだり、式を評価する必要があります。

if文をステップ実行すると、if の次に、x = a; または x = b; の行に移動します。どの選択肢に移動したのか、ひと目でわかります。

理由2:
選択肢が3つ以上になったとき、if文で書き直すから。

今は選択肢が2つですが、近い将来3つに増えるかもしれません。三項演算子で書いてあれば、if〜else if文で書き直すでしょう。それなら、今、if文で書いたほうがいいと思います。

理由3:
三項演算子を入れ子にした難解なコードを見たことがあるから。

見た瞬間、ここ触りたくねーと思いました。

この記事を書いた後、自分のソースを検索したら、予想より多く見つかりました。まあそんなもんですね。

この記事のタグは「コーディングスタイル」より「デバッガブル」だなと思い、「デバッガブル」で検索したら、いい記事が見つかりました。
デバッグしやすい、解析しやすいコードを書こう

e-Taxソフトが新しいソフトウェアのインストールを構成中です。

e-TaxソフトをWindows 7 Home Premium 64bit(FMV AH700/5A)にインストールしたところ、プログレスバーは100%まで進んだが、「e-Taxソフトが新しいソフトウェアのインストールを構成中です。」と表示したまま5分待っても終わらない。

CPU利用率は60%から25%へ下がり、HDDアクセスランプも付いていないので、インストール処理は終わっているかもしれないと思い、[キャンセル]ボタンをクリックしたが、反応なし。タスクマネージャからeTaxソフトインストーラを終了した。

スタート>すべてのプログラムに「eTaxソフト」フォルダが作成されていたが、コントロールパネル>プログラムのアンインストールの一覧に「e-Taxソフト」が見当たらない。

スタート>すべてのプログラム>eTaxソフト>eTaxソフトのアンインストールをしようとするが、「初期インストールには使えません」と表示されてしまう。

ファイルコピーはしたが、レジストリにインストール情報の登録するところでつまずいているようだ。

再度インストーラを実行すると「別のインスタンスが存在します」と表示されてしまうので、Windows再起動。

いろいろ試してみた。

インストーラexeで右クリック>管理者として実行…
結果:NG

インストーラexeで右クリック>プロパティ>互換性タブ>Windows Vista SP2
(参考 http://naked30s.com/how-to-install-e-tax-software-successfully/)
結果:NG

ノートPCにつないでいる外部モニタを外した。
結果:NG

セキュリティソフトを無効にした。
結果:NG

再起動してF8、セーフモードとネットワークで起動、インストーラexeを実行
結果:OK
途中「レジストリに登録できませんでした ??data.dll」と表示されたが、いつのまにかインストール完了まで進んだ。

JenkinsのAndroid emulator plugin

AMD PhenomII 945+6GメモリにUbuntu 14.04 LTSをインストールし、Oracle JDK、kvm、jenkins、android studioをインストールしました。
ところが、Android emulator pluginのRun emulator with propertiesで自動作成した仮想マシンが動きません。
ターミナルから同じコマンドでエミュレータを起動しても、ps -ax | grep emu では表示されますが、adb devices -l で一覧に表示されません。

Android studio>Tools>AVD Managerで作成した仮想マシンは、ターミナルからエミュレータを起動しても、adb devices -lで表示されますし、adb shellでログインできました。

試行錯誤して、次のような設定でJenkinsでandroidビルドとテストをできるようになりました。

ディレクトリ構成の概要
/home/jenkins/.android/avd
/opt/android-sdk-linux
/var/lib/jenkins

Jenkinsインストール前にjenkinsユーザを作成しました。

kvmとlibvirtdグループにjenkinsユーザを追加しました。

Jenkinsをインストールしました。

Jenkinsで使うandroid sdkは、SDK Onlyをダウンロードして、/opt/android-sdk-linuxに設置しました。

デスクトップでAndroid studio>Tools>AVD Managerを起動し、仮想マシンを新規作成します。
例えば api_19_720x1280という名前で作成すると、/home/jenkins/.android/avd/api_19_720x1280.ini と /home/jenkins/.android/avd/api_19_720x1280.avd/* が作成されます。
(これは他のPCで作成したものをコピーしても動きます。その場合はconfig.iniとhardware-qemu.iniを編集して、コピー元PCのパスをコピー先PCにあわせて修正してください。)

Jenkins>Hoge_project>設定で、
Run an Android emulator during buildにチェックをつけ、
Run exsiting emulatorにチェックをつけ、
AVD nameに api_19_720x1280 を入力しました。

今まで4GメモリのMacBookAirで20分以上かかっていたビルドとテストが5分でできるようになりました。

jpostal ver2.8

jpostalの設置方法を紹介してくださる記事を見かけるようになりました。ありがとうございます。

さてRailsにjpostalを導入する方法の紹介記事がありました。

Railsでjpostal.jpを使って住所を自動入力する
http://ruby-rails.hatenadiary.com/entry/20150112/1421029284
しかし、「都道府県」がうまく入力されていません。
これは、プルダウンのoptionのvalue属性がPrefectureのidを表示しており、jpostal.jsで取得した都道府県は文字列(東京都、埼玉県など)のため、value属性がマッチせず、自動で選択されません。

Railsの住所フォームはOPTIONタグのvalueに数値(おそらく自治体コード?)を利用しているようです。この記事後半では、Railsビューを修正して、<option value=”北海道”>北海道</option>と表示する方法が説明されていました。

そこで、jspotal ver/2.8で、次のどの場合でも選択できるようにしました。

 <option value="北海道">北海道</option>
 <option value="1">北海道</option>
 <option value="01">北海道</option>

サンプルページ
http://jpostal-1006.appspot.com/sample_1_b.html

設置方法やjavascriptの記述方法はこれまでと同じです。

jquery.jpostal.jsの新サーバ:jpostal-1006.appspot.com

jpostalの設置サーバをjpostal-1006.appspot.comに変更しました。
これからご利用の場合は、README.txtを読んでください。

すでにjpostal.googlecode.com/svn/trunk/jquery.jpostal.jsをご利用の場合、
HTMLを次のように修正してください。
修正前
<script src="//jpostal.googlecode.com/svn/trunk/jquery.jpostal.js">
修正後
<script src="//jpostal-1006.appspot.com/jquery.jpostal.js">

jpostal.googlecode.com は郵便データ2015-06-30版のままとし、GoogleCodeサービス終了まで継続します。

GoogleCodeサービス終了予定

2016-01-26 GoogleCodeがサービス終了するそうです。
http://google-opensource.blogspot.jp/2015/03/farewell-to-google-code.html

jpostalでは、jpostal.googlecode.comとして利用しています。
次のサーバが決まり次第、お知らせします。

Linux RAID-0, RAID-1, RAID-5 sysbench

80GB, 80GB, 500GB, 500GBの4台でRAID-0、RAID-1、RAID-5を作成し、sysbenchを測定した。
速度の違うディスクが混在したRAID-0のseqrdはどうなるか、RAID-1のseqrdがSimpleDiskのseqrdより速くなるか、に注目した。

(1) PC
MB: GA-MA78GM-S2H ver1.1 (AMD 780G, AMD SB700)
CPU: AMD PhenomII X4 945
MEM: DDR2-800 2GB x 2
OS: Ubuntu 14.04 32bit

(2) disk
/dev/sdb1: ST380815AS (80GB)に、20GB ext4 partition
/dev/sdc1: ST380815AS (80GB)に、20GB ext4 partition
/dev/sdd1: HDS721050CLA362 (500GB)に、20GB ext4 partition
/dev/sde1: HDS721050CLA362 (500GB)に、20GB ext4 partition

(3) simple disk (partition 20GB ext4)

--------------------------------------------------
         hdparm- t | seqrd | seqwr | rndrd | rndwr
--------------------------------------------------
#1 sdb1:  78         70      71      3.6     1.1
#2 sdc1:  68         73      68      4.3     1.1
#3 sdd1: 129        126     116      4.6     2.2
#4 sde1: 138        135     125      4.5     2.2
--------------------------------------------------

(4) RAID-0 (volume 40GB, partition 20GB ext4)

----------------------------------------------------------------------
                        hdparm- t | seqrd | seqwr | rndrd | rndwr
----------------------------------------------------------------------
#11 sdb1 sdc1          : 150        146     142     4.5     1.1
#12 sdd1 sde1          : 258        252     219     4.9     2.5
#13 sdb1 sdd1          : 154        151     142     4.8     1.2
#14 sdd1 sdb1          : 153        152     143     4.7     1.2
#15 sdb1 sdc1 sdd1 sde1: 300        285     272     4.9     1.7
#16 sde1 sdd1 sdc1 sdb1: 297        284     282     4.8     1.7
----------------------------------------------------------------------

#11: seqrdとseqwrは、Simple Diskの合計に近い結果となった。
rndrdとrndwrは、Simple Disk 1台より少し速い程度。

#12: seqrdとseqwrは、Simple Diskの合計に近い結果となった。
rndrdとrndwrは、Simple Disk 1台より少し速い程度。

#13: 80GBディスク+500GBディスクでRAID-1を作成。
#14: 500GBディスク+80GBディスクでRAID-1を作成。
処理時間は、80GBディスク+500GBディスクではなく、80GBディスクx2となった。

#15:
#16:
処理時間は、80GBディスクx2+500GBディスクx2ではなく、80GBディスクx4となった。

(5) RAID-1 (volume 20HB, partition 20GB ext4)

----------------------------------------------------------------------
                      hdparm- t | seqrd | seqwr | rndrd | rndwr
----------------------------------------------------------------------
#21 sdb1 sdc1          :  78       70      68     4.1     0.77
#22 sdd1 sde1          : 129      115     112     4.5     1.9
#23 sdb1 sdd1          :  78       68      71     4.3     0.90
#24 sdd1 sdb1          : 113      125      71     4.6     0.90
#25 sdb1 sdc1 sdd1 sde1:  71       70      68     4.3     0.69
#26 sde1 sdd1 sdc1 sdb1: 128      122      68     4.5     0.69
----------------------------------------------------------------------

RAID-1のseqrdがSimpleDiskのseqrdより速くなるか注目していたが、同じであった。
rndwrは、Simple Diskより遅くなった。

(6) RAID-5 (volume 60GB, partition 20GB ext4)

----------------------------------------------------------------------
                         hdparm- t | seqrd | seqwr | rndrd | rndwr
----------------------------------------------------------------------
#31 sdb1 sdc1 sdd1 sde1: 179         141      93     4.7     0.48
#32 sde1 sdd1 sdc1 sdb1: 173         137     102     4.7     0.56
----------------------------------------------------------------------

あえて比較するなら、#22(500GBディスク2台のRAID-1)より多少速い程度。

(7) mdadm
mdadm –create /dev/md0 –level=stripe –raid-devices=2 /dev/sdb1 /dev/sdc1
mdadm –create /dev/md0 –level=mirror –raid-devices=2 /dev/sdb1 /dev/sdc1
mdadm –create /dev/md0 –level=5 –raid-devices=4 /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1

(8) sysbench
トータルファイルサイズ(既定では2048MB)を5000Mで測定した。
sysbench –test=fileio –file-total-size=5000M prepare
sync; sysctl -w vm.drop_caches=3
sysbench –test=fileio –file-total-size=5000M –file-test-mode=seqrd run
sync; sysctl -w vm.drop_caches=3
sysbench –test=fileio –file-total-size=5000M –file-test-mode=seqwr run
sync; sysctl -w vm.drop_caches=3
sysbench –test=fileio –file-total-size=5000M –file-test-mode=rndrd run
sync; sysctl -w vm.drop_caches=3
sysbench –test=fileio –file-total-size=5000M –file-test-mode=rndwr run
sysbench –test=fileio –file-total-size=5000M cleanup