56
+ モデル検査入門 〜自動設計検証技術の世界〜 WACATE実行委員 朱峰錦司@kjstylepp

モデル検査入門 #wacate

Embed Size (px)

DESCRIPTION

WACATE2014冬の講演資料です

Citation preview

Page 1: モデル検査入門 #wacate

+

モデル検査入門〜自動設計検証技術の世界〜

WACATE実行委員 朱峰錦司@kjstylepp

Page 2: モデル検査入門 #wacate

+ 自己紹介

所属某豊洲のSIer勤務

〜2014.3

テストプロセスおよびツールの研究開発

2014.4〜

アジャイルプロセスおよびツールの研究開発

WACATE実行委員会テスト自動化研究会 Nippon Enterprise Agile Transformation

専門テスト分析・設計方法論スクラム

2014/12/06WACATE 2014 Winter

2

Page 3: モデル検査入門 #wacate

+ 【宣伝1】テスト自動化研究会

隔月でオフライン研究会を実施中 https://sites.google.com/site/testautomationresearch/

活動内容

本読み/翻訳

ツール紹介

カンファレンス運営

スキル標準整備…etc

2014/12/06WACATE 2014 Winter

3

Page 4: モデル検査入門 #wacate

+ 【宣伝2】チョットデキルTシャツ

ワタシハ ソフトウェアテスト チョットデキル

https://suzuri.jp/miwa719/96277/t-shirt/s/white

2014/12/06WACATE 2014 Winter

4

ダイエットに失敗しても問題なし!

Page 5: モデル検査入門 #wacate

+ 【宣伝3】チョットデキルTシャツ2

ほんの1時間前に新作が https://suzuri.jp/miwa719/130755/t-shirt/m/lightpink

2014/12/06WACATE 2014 Winter

5

女性にもオススメ💓

Page 6: モデル検査入門 #wacate

+ 本講義の目的

モデル検査技術について以下を理解する

動的テストの違い

できること&できないこと

使い所

検査の粒度とツールの種類

オプション目標

ツールデモの再現

2014/12/06WACATE 2014 Winter

6

Page 7: モデル検査入門 #wacate

+ 目次

1. 設計に対する「テスト」

2. モデル

3. モデル検査

4. モデル検査の実施例

5. 活用ポイント

6. 様々なモデル検査ツール

7. まとめ

2014/12/06WACATE 2014 Winter

7

Page 8: モデル検査入門 #wacate

+

1. 設計に対する「テスト」

2014/12/06WACATE 2014 Winter

8

Page 9: モデル検査入門 #wacate

+ 1.1. 開発プロセスにおけるテスト

テスト(testing)の定義 by JSTQB

全てのライフサイクルを通じて実施する静的、動的なプロセスにおいて、成果物が特定の要件を満足するかを判定し、目的に合致することを実証し、欠陥を見つけるため、ソフトウェアプロダクトや関連成果物に対し、計画、準備、評価をすること。

2014/12/06WACATE 2014 Winter

9

Page 10: モデル検査入門 #wacate

+

狭義のテスト

実装後の「テスト」工程を指すことが多い

広義のテスト

実装以前工程の「レビュー」や「静的解析」も含む

2014/12/06WACATE 2014 Winter

10

要件定義

設計 実装 テスト要件定義書

設計書ソースコード

ソースコード(修正)

テスト結果

レビュー レビュー レビュー

静的解析

モデル検査もここ

1.2. 狭義/広義のテスト

Page 11: モデル検査入門 #wacate

+ 1.3. レビューの種類

様々な種類が存在

インスペクション

テクニカルレビュー

ウォークスルー

レビューにおける指摘

表現不備

設計不備…etc

2014/12/06WACATE 2014 Winter

11

詳しくは明日のレビューセッションで!!

Page 12: モデル検査入門 #wacate

+ 1.4. レビューの自動化

表現不備の発見

文法

ゆらぎ

設計(実装)不備発見

漏れ

誤り

2014/12/06WACATE 2014 Winter

12

Microsoft Wordによるチェック

Eclipseによるチェック

Page 13: モデル検査入門 #wacate

+ 1.5. モデル検査

レビューの自動化技術の一種

レビュー対象は「モデル」

モデルが「仕様」を満たすかどうかを「検査」

2014/12/06WACATE 2014 Winter

13

2章で解説

3章で解説

Page 14: モデル検査入門 #wacate

+

2. モデル

2014/12/06WACATE 2014 Winter

14

Page 15: モデル検査入門 #wacate

+ 2.1. モデルとは

開発対象のシステム(=テスト対象)の振る舞いや性質を特定の観点で抽象化して表現したもの

2014/12/06WACATE 2014 Winter

15

状態遷移モデル

アクティビティモデル

Page 16: モデル検査入門 #wacate

+ 2.2. モデルの種類

様々な観点によるモデリング手法が存在

状態遷移モデル

論理モデル

組合せモデル

フローモデル

代数モデル

統計モデル…etc

2014/12/06WACATE 2014 Winter

16

Page 17: モデル検査入門 #wacate

+ 2.3. モデルを扱う際の注意点

ひとつのモデルで全て仕様を表現するのは不可能

無理に様々な情報を込めようとすると肥大化

可読性の低下

変更容易性の低下

観点を絞ったシンプルな抽象化が重要

データモデルの状態変化に着目

性能の変化に着目…etc

2014/12/06WACATE 2014 Winter

17

Page 18: モデル検査入門 #wacate

+ 2.4. 状態遷移モデル(1/3)

システムの状態変化に着目してシステムの振る舞いをモデリング

モデル検査は状態遷移を検査対象とすることが多い

構成要素

様々な書き方が存在

基本的な構成要素は以下の通り

2014/12/06WACATE 2014 Winter

18

事前状態変数:x,y

事後状態変数:x,y

イベント[遷移条件]/アクション

Page 19: モデル検査入門 #wacate

+ 2.4. 状態遷移モデル(2/3)

構成要素

2014/12/06WACATE 2014 Winter

19

構成要素 説明

状態 ある時点でのシステムの状態を表現。

初期状態 特殊な状態。モデルで表現したい状態遷移の開始時点を表現。

終了状態 特殊な状態。モデルで表現したい状態遷移の終了時点を表現。なくてもよい。

状態変数 状態の細かなバリエーションを表現するための変数。アクションによって変化する。

イベント 状態遷移が発生するきっかけ。

遷移条件 状態遷移の分岐条件。

アクション 状態遷移の結果、システムに発生する状態遷移以外の変化。なくてもよい。

Page 20: モデル検査入門 #wacate

+ 2.4. 状態遷移モデル(3/3)

会員システムの例

2014/12/06WACATE 2014 Winter

20

Page 21: モデル検査入門 #wacate

+

3. モデル検査

2014/12/06WACATE 2014 Winter

21

Page 22: モデル検査入門 #wacate

+ 3.1. モデル検査とは

モデルが「仕様」を満たしているかどうかを検査

満たさない場合、具体的な満たさない振る舞いのパターン=反例を示す

2014/12/06WACATE 2014 Winter

22

Page 23: モデル検査入門 #wacate

+ 3.2. モデル検査のイメージ

会員システムの例(再掲)

2014/12/06WACATE 2014 Winter

23

Page 24: モデル検査入門 #wacate

+ 3.2.1. 検査したい仕様

「会員はアカウントロックのままにはならない」

アカウントロック状態になったらそのうち別状態になる

この仕様は満たされない

アカウントロック状態から抜け出すには明示的にロック解除イベントが必要

ロック解除イベントが実施されない場合、アカウントロック状態のまま

2014/12/06WACATE 2014 Winter

24

Page 25: モデル検査入門 #wacate

+ 3.2.2. 検査の仕方

イベント(会員の行動)を発生する状態遷移モデルを作成

2014/12/06WACATE 2014 Winter

25

「ロック解除をする」か「何もしない」をランダムに実行

Page 26: モデル検査入門 #wacate

+ 3.2.3. 2つの状態遷移モデルが連動

2014/12/06WACATE 2014 Winter

26

互いにイベントを通知しあって状態遷移

Page 27: モデル検査入門 #wacate

+ 3.2.4. ロックが解除されるフロー

2014/12/06WACATE 2014 Winter

27

Page 28: モデル検査入門 #wacate

+ 3.2.5. ロックが解除されないフロー(反例)

2014/12/06WACATE 2014 Winter

28

11で10と同じアクションを実行した結果状態変化なし

→ロック解除しないループが存在

Page 29: モデル検査入門 #wacate

+ 3.2.6. モデル検査ツールがやること

3.2.4.や3.2.5.のような遷移パターンを自動で網羅的に探索

網羅した結果、3.2.5のような反例があれば提示

反例がない場合は仕様を満たす

2014/12/06WACATE 2014 Winter

29

Page 30: モデル検査入門 #wacate

+ 3.3. ところで「仕様」とは?

なんでも検査できるわけではない

時相論理で表現可能なものを扱うことが多い

時間の概念を取り入れた論理表現

基本的には以下の3種類

常にxxxだ

常にラーメンが食べたい

いつかxxxになる

いつかラーメンが食べたくなる

xxxになるまでyyyだ

ラーメンを食べるまではラーメンが食べたい

2014/12/06WACATE 2014 Winter

30

Page 31: モデル検査入門 #wacate

+ 小演習:プチモデル検査をしてみよう

一度ラーメンを食べたくなったら永久にラーメンを食べたい

2014/12/06WACATE 2014 Winter

31

塩ラーメンが食べたい

醤油ラーメンが食べたい

何も食べたくない

Page 32: モデル検査入門 #wacate

+ 小演習:プチモデル検査をしてみよう

いつかラーメンを食べたくなる

2014/12/06WACATE 2014 Winter

32

何も食べたくない

醤油ラーメンが食べたい

チャーハンが食べたい

Page 33: モデル検査入門 #wacate

+ 小演習:プチモデル検査をしてみよう

塩ラーメンを食べたくなったら必ずいつか醤油ラーメンを食べたくなる

2014/12/06WACATE 2014 Winter

33

何も食べたくない

醤油ラーメンが食べたい

塩ラーメン食べたい

Page 34: モデル検査入門 #wacate

+ 小演習:プチモデル検査をしてみよう

塩ラーメンを食べたくなったら必ずいつか醤油ラーメンを食べたくなる

2014/12/06WACATE 2014 Winter

34

何も食べたくない

醤油ラーメンが食べたい

塩ラーメン食べたい

Page 35: モデル検査入門 #wacate

+

互いにメリット/デメリットがある

モデル検査の優位な点が要求される局面が使い所となる

モデル検査 動的テスト

網羅性 網羅的 部分的

厳密性 厳密 不確実

容易性 難 易

検査対象の規模 小規模 大規模

利用実績 少 多

2014/12/06WACATE 2014 Winter

35

3.4. 動的テストとの比較

Page 36: モデル検査入門 #wacate

+ 3.5. モデル検査の種類

設計モデル検査

主に先述の例のような相互作用する状態遷移モデルに対して検査を実施

実装モデル検査

主にマルチスレッドなソースコードの実行パターンに対して検査を実施

2014/12/06WACATE 2014 Winter

36

Page 37: モデル検査入門 #wacate

+

4. モデル検査の実践例

2014/12/06WACATE 2014 Winter

37

Page 38: モデル検査入門 #wacate

+ 4.1. 設計モデル検査の例

Spin

もっとも古典的で有名なモデル検査ツールのひとつ

日本語で得られるモデル検査ツールの情報の大半はSpin

状態遷移モデルをPromelaというC Likeな独自言語で記述

文法が少し似ているだけ

パラダイムは全く別

2014/12/06WACATE 2014 Winter

38

Page 39: モデル検査入門 #wacate

+ 4.1.1. 例題

競合を起こす簡単な並行システム

2014/12/06WACATE 2014 Winter

39

mtype = {LOCKED, UNLOCKED};

mtype mutex = UNLOCKED;

int cnt = 0;

inline lock() {

mutex == UNLOCKED -> mutex = LOCKED

}

inline unlock() {

mutex = UNLOCKED

}

active[3] proctype LockUnlock() {

again:

lock();

cnt ++;

assert(cnt == 1);

cnt --;

unlock();

goto again

}

ロックを管理する共有変数

ロックされてなければロックするロックしている場合はブロック

インクリメントを確認

ロック判定と状態遷移の間のタイミングで競合が起こる

Page 40: モデル検査入門 #wacate

+ 4.1.2. モデル検査の実施

プロセス間競合を起こすパターンを検出

2014/12/06WACATE 2014 Winter

40

0: proc - (:root:) creates proc 0 (LockUnlock)

0: proc - (:root:) creates proc 1 (LockUnlock)

0: proc - (:root:) creates proc 2 (LockUnlock)

1: proc 2 (LockUnlock:1) sample.pml:6 (state 1)[((mutex==UNLOCKED))]

2: proc 0 (LockUnlock:1) sample.pml:6 (state 1)[((mutex==UNLOCKED))]

3: proc 2 (LockUnlock:1) sample.pml:6 (state 2)[mutex = LOCKED]

4: proc 0 (LockUnlock:1) sample.pml:6 (state 2)[mutex = LOCKED]

5: proc 2 (LockUnlock:1) sample.pml:17 (state 4) [cnt = (cnt+1)]

6: proc 0 (LockUnlock:1) sample.pml:17 (state 4) [cnt = (cnt+1)]

spin: sample.pml:18, Error: assertion violated

spin: text of failed assertion: assert((cnt==1))

#processes: 3

7: proc 2 (LockUnlock:1) sample.pml:18 (state 5)

7: proc 1 (LockUnlock:1) sample.pml:5 (state 3)

7: proc 0 (LockUnlock:1) sample.pml:18 (state 5)

3 processes created

mutexの状態変化の前に連続してUNLOCKED判定が行われるとダ

メ!

Page 41: モデル検査入門 #wacate

+ 4.2. 実装モデル検査の例

Java Path Finder

NASAが宇宙探索機ソフトウェアの検証のために開発したJavaプログラムの検査ツール

statement実行ごとに状態を記録/仕様の充足を確認

OKなら次に起こり得る状態の一覧を作成したうえで、深さ優先探索で次の実行パターンを検査

NGならそこに至る実行過程を反例として示す

2014/12/06WACATE 2014 Winter

41

Page 42: モデル検査入門 #wacate

+ 4.2.1. 例題

スレッド競合を起こす簡単なプログラム

2014/12/06WACATE 2014 Winter

42

public class Sample implements Runnable {

static int sharedData = 0;

public void run() {

int tmp = sharedData;

sharedData += 1;

assert(tmp + 1 == sharedData);

}

public static void main(String args[]) {

int size = Integer.parseInt(args[0]);

Sample instance = new Sample();

for(int i = 0; i < size; i++) {

Thread thread = new Thread(instance);

thread.start();

}

}}

共有変数

共有変数をインクリメント

インクリメントを確認

このタイミングで他のスレッドでインクリメントされると例外発生!

Page 43: モデル検査入門 #wacate

+ 4.2.2. モデル検査の実施

スレッド競合を起こすパターンを検出

2014/12/06WACATE 2014 Winter

43

====================================================== error 1

gov.nasa.jpf.vm.NoUncaughtExceptionsProperty

java.lang.AssertionError

at Sample.run(Sample.java:7)

====================================================== snapshot #1

thread java.lang.Thread:{id:2,name:Thread-2,status:RUNNING,priority:5,isDaemon:false,lockCount:0,suspendCount:0}

call stack:

at Sample.run(Sample.java:7)

thread java.lang.Thread:{id:3,name:Thread-3,status:RUNNING,priority:5,isDaemon:false,lockCount:0,suspendCount:0}

call stack:

at Sample.run(Sample.java:7)

====================================================== results

error #1: gov.nasa.jpf.vm.NoUncaughtExceptionsProperty "java.lang.AssertionError at Sample.run(Sample.jav...“

2つのスレッドが同時に7行目(assert)を実行するとダメ!

Page 44: モデル検査入門 #wacate

+

5. 活用のポイント

2014/12/06WACATE 2014 Winter

44

Page 45: モデル検査入門 #wacate

+ 5.1. 使い所

モデル検査の優位性

網羅性

厳密性

網羅性が求められる局面

複雑な非同期/並行システムにおいて、レアケースを特定するような検査

厳密性が求められる局面

障害によって人命や巨額な資産を損なうようなシステムの検査

2014/12/06WACATE 2014 Winter

45

Page 46: モデル検査入門 #wacate

+ 5.2. 注意点

計算量の爆発

遷移パターンが発散するようなモデルを書くとすぐに状態爆発をして検査が終わらなくなる

関心ごとを絞ったシンプルなモデリングを行う

モデルおよび仕様の実装誤り

設計を忠実に再現した(検査可能な)モデルや仕様を書くのがそもそも困難

Try & Errorを繰り返しながら洗練させていくしかない

2014/12/06WACATE 2014 Winter

46

Page 47: モデル検査入門 #wacate

+ (参考)JavaPathFinderの計算量

3スレッド

15スレッド

100スレッド

まぁムリムリ\(^o^)/2014/12/06WACATE 2014 Winter

47

====================================================== statistics

elapsed time: 00:00:00

states: new=31,visited=10,backtracked=21,end=6

search: maxDepth=20,constraints=0

choice generators: thread=30 (signal=0,lock=3,sharedRef=12,threadApi=3,reschedule=12), data=0

heap: new=394,released=139,maxLive=367,gcCycles=28

instructions: 4022

max memory: 123MB

====================================================== statistics

elapsed time: 00:00:18

states: new=32875,visited=213010,backtracked=245781,end=18

search: maxDepth=104,constraints=0

choice generators: thread=32874 (signal=0,lock=15,sharedRef=60,threadApi=15,reschedule=32784), data=0

heap: new=478,released=983323,maxLive=415,gcCycles=245824

instructions: 4183958max memory: 353MB

31状態作って10個探索して終了

32,875状態作って213,010個探索してやっと終了

Page 48: モデル検査入門 #wacate

+

6. 様々なモデル検査ツール

2014/12/06WACATE 2014 Winter

48

Page 49: モデル検査入門 #wacate

+ 6.1. Alloy

この頃流行りのモデル検査ツール

集合と制約によってモデルを記述

文法が(比較的)直感的

反例の表示もグラフィカルでわかりやすい

2014/12/06WACATE 2014 Winter

49

Page 50: モデル検査入門 #wacate

+ 6.2. CBMC

C/C++のモデル検査

gccおよびVisualStudioで動作

コードに対して以下を検査可能

配列溢れ

ポインタの安全性

例外の発生やユーザ定義のアサーション

2014/12/06WACATE 2014 Winter

50

Page 51: モデル検査入門 #wacate

+ 6.3. ESC/Java

Javaのモデル検査

JMLによってアノテーションとして定義された仕様を検査可能

JML:Java Modeling Language

Java向けの契約プログラミングツール

各メソッドの事前/事後条件や普遍条件を記述

実行時に条件違反を検知

ESC/JavaはJML違反をプログラムの実行時ではなく静的解析によって検査

2014/12/06WACATE 2014 Winter

51

Page 52: モデル検査入門 #wacate

+ (参考)JMLの例

2014/12/06WACATE 2014 Winter

52

public class BankingExample {

public static final int MAX_BALANCE = 1000;

private /*@ spec_public @*/ int balance;

//@ public invariant balance >= 0 && balance <= MAX_BALANCE;

//@ assignable balance;

//@ ensures balance == 0;

public BankingExample() {

this.balance = 0;

}

//@ requires 0 < amount && amount + balance < MAX_BALANCE;

//@ assignable balance;

//@ ensures balance == ¥old(balance) + amount;

public void credit(final int amount) {

this.balance += amount;

}}

普遍条件

事後条件

事前条件

Page 53: モデル検査入門 #wacate

+

7. まとめ

2014/12/06WACATE 2014 Winter

53

Page 54: モデル検査入門 #wacate

+ 7.1. モデル検査

レビューの自動化技術の一種

振る舞いの妥当性を検査

検査対象は主に状態遷移モデル

相互作用する状態遷移モデル

マルチスレッドプログラムの実行状態パターン

検査仕様は主に時相論理

常にxxxだ

いつかxxxになる

xxxになるまでyyyだ

2014/12/06WACATE 2014 Winter

54

Page 55: モデル検査入門 #wacate

+ 7.2. モデル検査の活用

動的テストとの違い

網羅性や厳密性が求められる局面で活用

活用の際は状態爆発に気をつけながら段階的にモデルを洗練させていく

2014/12/06WACATE 2014 Winter

55

モデル検査 動的テスト

網羅性 網羅的 部分的

厳密性 厳密 不確実

容易性 難 易

検査対象の規模 小規模 大規模

利用実績 少 多

Page 56: モデル検査入門 #wacate

+Let’s Modeling!

2014/12/06 WACATE 2014 Winter