以下、図面に基づいて、本願の開示する解析プログラム、解析方法および解析装置の実施例を詳細に説明する。なお、本実施例により、開示技術が限定されるものではない。また、以下の実施例は、矛盾しない範囲で適宜組みあわせてもよい。
図1は、実施例の解析装置の構成の一例を示すブロック図である。図1に示す解析装置100は、ソースコードが入力されると、ソースコード内の要素について、要素をミュータントに変化させるメタミューテーション関数に置換する。解析装置100は、要素をメタミューテーション関数に置換する際に、メタミューテーション関数のID(IDentifier)と、ソースコード内の要素の位置情報とを記憶部120に記憶する。解析装置100は、要素がメタミューテーション関数に置換されたソースコードを中間コードにコンパイルし、中間コードに対してミューテーションを実行するとともにテストを実行する。解析装置100は、要素がメタミューテーション関数に置換されたソースコードに対するテスト結果と、記憶部120に記憶されたIDおよび位置情報とに基づいて、要素とテスト結果とを対応付けて出力する。これにより、解析装置100は、ソースコード上のどの要素のミューテーションのテスト結果であるかを把握できる。
ここで、ミューテーション解析について説明する。図2は、ミューテーション解析の一例を説明する図である。図2に示すように、ミューテーション解析では、テスト対象プログラムであるソースコード10の要素に対して、ミューテーションが行われる。ソースコード10aは、例えば、ソースコード10に対して「mutant1」で示すミューテーションが行われたソースコードである。「mutant1」は、例えば、2行目の「<=」を「>」に変化させる。すなわち、ソースコード10aでは、ソースコード10と比べて、ミューテーション箇所11で示す部分が変化している。
同様に、ソースコード10bは、例えば、ソースコード10に対して「mutant2」で示すミューテーションが行われたソースコードである。「mutant2」は、例えば、2行目の「0」を「1」に変化させる。すなわち、ソースコード10bでは、ソースコード10と比べて、ミューテーション箇所12で示す部分が変化している。同様に、ソースコード10cは、例えば、ソースコード10に対して「mutant3」で示すミューテーションが行われたソースコードである。「mutant3」は、例えば、3行目の「−」を「−−」に変化させる。すなわち、ソースコード10cでは、ソースコード10と比べて、ミューテーション箇所13で示す部分が変化している。
これらのミューテーションされたソースコード10a〜10cに対して、あるテストを実行した結果がテスト結果14である。例えば「Test1」では、「abs」に「2」が入力されて「2」が出力されると「pass」とし、「2」以外が出力されると「fail」とする。また、例えば「Test2」では、「abs」に「−2」が入力されて「2」が出力されると「pass」とし、「2」以外が出力されると「fail」とする。このとき、「mutant1」〜「mutant3」のそれぞれの結果は、テスト結果14に示す通りとなる。
「mutant1」は、「Test1」および「Test2」のいずれも「fail」となり、埋め込まれたバグを検出できるので「killed」となる。「mutant2」は、「Test1」および「Test2」のいずれも「pass」となり、埋め込まれたバグを検出できないので「unkilled」となる。「mutant3」は、「Test1」が「pass」、「Test2」が「fail」となり、埋め込まれたバグを検出できるので「killed」となる。この結果、「killed」となったミュータントの割合を示すミューテーションスコア(mutation score)は、2/3=0.667となる。
次に、ミューテーション解析の実行コストについて説明する。図3は、ミューテーション解析の実行コストの一例を説明する図である。図3に示すように、ミューテーション解析では、ソースコード21をミューテーションしたソースコード群22を、それぞれコンパイルして実行ファイル群23を生成する。ミューテーション解析では、さらに、生成した実行ファイル群23についてテストを実行し、テスト結果群24を得る。このときのミューテーション解析の実行時間は、合計時間=(ミュータント数)×(ミューテーション時間+コンパイル時間)+(ミュータント数)×(テスト項目数)×(1回の実行時間)となる。すなわち、図3に示すミューテーション解析の実行時間は、ミュータントを網羅的に生成するため、多くの時間がかかってしまうことになる。
これに対し、MSGを適用した場合について説明する。図4は、MSGの一例を説明する図である。図4に示すように、MSGでは、図3に示すミューテーションに代えて、要素を、パラメータを与えることで具体的なミュータントを表す関数であるメタミューテーション関数に置き換えることでコンパイルのコストを抑える。図4の例では、ソースコード31の要素をメタミューテーション関数に置き換えたソースコード32をコンパイルし、実行ファイル33を生成する。図4の例では、実行ファイル33に対してインスタンス化、つまりパラメータを付与して実行ファイル群34を生成し、生成した実行ファイル群34についてテストを実行してテスト結果群35を得る。MSGでは、実行ファイル33を実行するタイミング、すなわち、バイナリ状態でミュータントを切り替える。図4の例では、実行ファイル群34の各実行ファイルにかかるプロセスを、それぞれ起動するので、処理が重くなる。
これに対して、中間コードをVM上でミューテーションする場合について説明する。図5は、ビットコードミューテーションの一例を説明する図である。図5に示すように、ビットコードミューテーションでは、中間コードであるビットコードをVM上でミューテーションを行うことで、MSGよりもプロセス起動回数を減らすことができる。なお、中間コードは、ビットコードの他に、バイトコードトランスレーションを用いてもよい。図5の例では、ソースコード41をビットコード42にコンパイルし、ミューテーションしたビットコード42についてVM群43でテストを実行し、テスト結果群44を得る。ところが、ビットコードやバイトコード等の中間コードは、ソースコードと1対1対応ではないため、中間コードへのミューテーションがソースコード上のどの要素のミューテーションと対応するのかわからない場合がある。すなわち、中間コードのミューテーションのテスト結果が、ソースコード上のどの要素のミューテーションのテスト結果であるかを把握することが困難である。
図6は、ソースコードとビットコードとの対応の一例を説明する図である。図6に示すように、例えば、ビットコード45は、同一の動作を示すソースコード46とソースコード47のうち、どちらのソースコードから生成されたものであるかについて、ビットコード45からはわからない。つまり、ビットコード45と、ソースコード46、47とは、ビットコード45へのミューテーションがソースコード46、47上のどの要素のミューテーションと対応するのか不明となっている。
また、コンパイル時の最適化によってミュータントが消失する場合もある。図7は、最適化によるミュータントの消失の一例を説明する図である。図7に示すように、例えば、元のソースコード48aをビットコードにコンパイルすると、ビットコード49aとなる。このとき、元のソースコード48aに対して、シフト演算子をミュータントとしてミューテーションを行った、すなわちシフト演算子の置換を行ったソースコード48bをビットコードにコンパイルすると、ビットコード49bとなる。図7の例では、ソースコードからビットコードへのコンパイルの際に、定数の演算など冗長なプログラム要素が削除される等の最適化が行われる。このため、ビットコード49a、49bでは、シフト演算子が見えなくなってしまい、ビットコードレベルでのシフト演算子の置換が適用できなくなる。
上述の様な課題に対して、本実施例では、メタミューテーション関数のID(メタミューテーションID)と、ソースコード内の要素の位置情報とを対応付けて記憶することで、中間コードとソースコードとの間で要素の1対1対応をとることができる。図8は、実施例のビットコードミューテーションの一例を説明する図である。図8に示すように、本実施例のビットコードミューテーションでは、ソースコード51に対して要素をメタミューテーション関数に置換するメタミューテーションを行ってソースコード52を生成し、メタミューテーション情報53を記憶部120に記憶しておく。本実施例のビットコードミューテーションでは、ソースコード52をビットコード53にコンパイルし、ミューテーションしたビットコード53についてVM群54でテストを実行し、テスト結果群55を得る。本実施例のビットコードミューテーションでは、メタミューテーション情報53とテスト結果群55とに基づいて、結果レポート56を得る。
結果レポート56の生成について図9を用いて説明する。図9は、実施例の結果レポート生成の一例を説明する図である。図9に示すように、本実施例のビットコードミューテーションでは、メタミューテーション情報53とテスト結果群55とに基づいて出力処理を実行する。出力処理では、テスト結果群55に含まれるメタミューテーションIDを、メタミューテーション情報53から検索して対応するソースコード位置情報を取得する。出力処理では、例えば、ミューテーションスコア、「unkilled」となったミュータントに係るオリジナルの要素、ミュータントおよびソースコード位置情報等を含む結果レポート56を生成する。すなわち、本実施例のビットコードミューテーションでは、テスト結果が「unkilled」となったソースコード上の要素およびミュータントを把握できる。
次に、図1の説明に戻って、解析装置100の構成について説明する。図1に示すように、解析装置100は、通信部110と、入力部111と、表示部112と、操作部113と、記憶部120と、制御部130とを有する。なお、解析装置100は、図1に示す機能部以外にも既知のコンピュータが有する各種の機能部、例えば各種の入力デバイスや音声出力デバイス等の機能部を有することとしてもかまわない。
通信部110は、例えば、NIC(Network Interface Card)等によって実現される。通信部110は、図示しないネットワークを介して他の情報処理装置と有線または無線で接続され、他の情報処理装置との間で情報の通信を司る通信インタフェースである。通信部110は、例えば、他の情報処理装置から解析対象のソースコード、テスト項目およびミューテーションオペレータリストを受信する。通信部110は、受信した解析対象のソースコード、テスト項目およびミューテーションオペレータリストを制御部130に出力する。
入力部111は、例えば、光学ディスク、USB(Universal Serial Bus)メモリ、SDメモリカード等の外部記憶媒体に対する媒体アクセス装置等によって実現される。入力部111は、外部記憶媒体に記憶された解析対象のソースコード、テスト項目およびミューテーションオペレータリストを読み取って、読み取った解析対象のソースコード、テスト項目およびミューテーションオペレータリストを制御部130に出力する。なお、解析対象のソースコード、テスト項目およびミューテーションオペレータリストは、通信部110または入力部111のいずれかから制御部130に入力されればよく、以下の説明では、入力部111から制御部130に入力される場合について説明する。
表示部112は、各種情報を表示するための表示デバイスである。表示部112は、例えば、表示デバイスとして液晶ディスプレイ等によって実現される。表示部112は、制御部130から入力された結果画面等の各種画面を表示する。
操作部113は、解析装置100のユーザから各種操作を受け付ける入力デバイスである。操作部113は、例えば、入力デバイスとして、キーボードやマウス等によって実現される。操作部113は、ユーザによって入力された操作を操作情報として制御部130に出力する。なお、操作部113は、入力デバイスとして、タッチパネル等によって実現されるようにしてもよく、表示部112の表示デバイスと、操作部113の入力デバイスとは、一体化されるようにしてもよい。
記憶部120は、例えば、RAM(Random Access Memory)、フラッシュメモリ(Flash Memory)等の半導体メモリ素子、ハードディスクや光ディスク等の記憶装置によって実現される。記憶部120は、メタミューテーション情報記憶部121と、命令記憶部122と、ミュータント記憶部123と、テスト結果記憶部124とを有する。また、記憶部120は、制御部130での処理に用いる情報を記憶する。
メタミューテーション情報記憶部121は、メタミューテーション関数のIDと、ソースコード内の要素の位置情報とを対応付けて記憶する。図10は、メタミューテーション情報記憶部の一例を示す図である。図10に示すように、メタミューテーション情報記憶部121は、「メタミューテーションID」、「ソースコード位置情報」といった項目を有する。メタミューテーション情報記憶部121は、例えば、メタミューテーションIDごとに1レコードとして記憶する。なお、以下の説明では、メタミューテーションIDをMMIDとも表現する。
「メタミューテーションID」は、メタミューテーション関数ごとに一意に付される番号(ID)であり、メタミューテーション関数を識別する識別子である。「ソースコード位置情報」は、メタミューテーション関数に置換するソースコード内の要素の位置情報であり、例えば、ファイル名、行数、桁数を用いて特定する。図10の1行目の例では、メタミューテーションID「0」のメタミューテーション関数は、ファイル名が「a.c」のソースコード上の「2行6桁」から「2行20桁」までの位置にある要素に対応することを示す。
図1の説明に戻って、命令記憶部122は、ビットコードに対してミューテーションが実行され、VM上で実行される命令を記憶する。すなわち、命令記憶部122は、ビットコードのメタミューテーション関数が具体的なミュータントに置換された命令を記憶する。
ミュータント記憶部123は、メタミューテーション関数を具体的なミュータントに置換するパターンを記憶する。図11は、ミュータント記憶部の一例を示す図である。図11に示すように、ミュータント記憶部123は、「ミュータントID」、「メタミューテーションID」、「ミューテーションオペレータ」といった項目を有する。ミュータント記憶部123は、例えば、置換するパターンごとに1レコードとして記憶する。
「ミュータントID」は、メタミューテーションIDとミューテーションオペレータとのペアを識別する識別子である。すなわち、「ミュータントID」は、メタミューテーション関数を具体的なミュータントに置換するパターンを識別する識別子である。「メタミューテーションID」は、メタミューテーション関数を識別する識別子である。「ミューテーションオペレータ」は、メタミューテーションIDで示されるメタミューテーション関数をどの様に変更するかを示す情報である。「ミューテーションオペレータ」は、1つのメタミューテーションIDに対して、複数種類ある場合には、例えば、アンダースコア後にどの様な変更を行うかの記号を付している。図11の1行目の例では、ミュータントID「1」は、メタミューテーションID「0」のメタミューテーション関数について、ミューテーションオペレータ「ORRN_EQ」を実行することを示す。ここで、「ORRN_EQ」は、比較演算子を「==」にすることを示す。
図1の説明に戻って、テスト結果記憶部124は、ミューテーションされたソースコードに対して、テストを実行した結果であるテスト結果、すなわちテスト結果群を記憶する。図12は、テスト結果記憶部の一例を示す図である。図12に示すように、テスト結果記憶部124は、「テストID」、「ミュータントID」、「テスト合否」といった項目を有する。テスト結果記憶部124は、テスト項目ごとに1レコードとして記憶する。
「テストID」は、テスト項目を識別する識別子である。「ミュータントID」は、メタミューテーションIDとミューテーションオペレータとのペアを識別する識別子である。「テスト合否」は、テスト対象のソースコードのミューテーションに対するテストの合否を示す情報であり、「Pass」または「Fail」で表わされる。「Pass」は、ソースコード内の要素が、ミュータントIDに基づくミュータントに置換された場合に、当該テスト項目において埋め込まれたバグを検出できなかったことを示す。「Fail」は、ソースコード内の要素が、ミュータントIDに基づくミュータントに置換された場合に、当該テスト項目において埋め込まれたバグを検出できたことを示す。図12の1行目の例では、テストID「TEST(func_test,testcase1)」で示すテスト項目において、要素がミュータントID「1」に基づくミュータントに置換された場合に、テスト合否は「Fail」、つまり埋め込まれたバグを検出できたことを示す。
図1の説明に戻って、制御部130は、例えば、CPU(Central Processing Unit)やMPU(Micro Processing Unit)等によって、内部の記憶装置に記憶されているプログラムがRAMを作業領域として実行されることにより実現される。また、制御部130は、例えば、ASIC(Application Specific Integrated Circuit)やFPGA(Field Programmable Gate Array)等の集積回路により実現されるようにしてもよい。制御部130は、置換部131と、コンパイラ132と、ミューテーション部133と、命令実行部134と、出力部135とを有し、以下に説明する情報処理の機能や作用を実現または実行する。なお、制御部130の内部構成は、図1に示した構成に限られず、後述する情報処理を行う構成であれば他の構成であってもよい。
置換部131は、入力部111からソースコードが入力されると、ソースコード内の要素について、要素をミュータントに変化させるメタミューテーション関数に置換する。置換部131は、入力されたソースコードから次の要素を抽出する。なお、置換部131は、初回の場合には1つ目の要素を抽出する。置換部131は、次の要素が抽出出来たか否か、すなわち、ソースコードの要素が空か否かを判定する。置換部131は、要素が空である場合には、要素からメタミューテーション関数への置換を終了する。置換部131は、要素が空でない場合には、要素がミューテーション対象か否かを判定する。
置換部131は、要素がミューテーション対象である場合には、メタミューテーション関数のIDであるMMIDと、ソースコード内の要素の位置情報とをメタミューテーション情報記憶部121に記憶する。すなわち、置換部131は、メタミューテーション関数のIDと、ソースコード内の要素の位置情報とを、メタミューテーション情報記憶部121に記憶する記憶処理部である。なお、ソースコード内の要素の位置情報は、例えば、ソースコードのファイル名、行数および桁数を用いることができる。
また、置換部131は、当該要素を、MMIDを引数に持つメタミューテーション関数に置換する。置換部131は、要素がミューテーション対象でない場合には、次の要素を抽出する。置換部131は、ソースコード内の要素がメタミューテーション関数に置換された置換後のソースコードをコンパイラ132に出力する。
ここで、図13および図14を用いて、置換前後のソースコードの一例について説明する。図13は、ソースコードの一例を示す図である。図14は、置換後のソースコードの一例を示す図である。図13に示すソースコード61は、IF文61a、インクリメント文61bおよびデクリメント文61cを有する。また、図14に示す置換後のソースコード62は、IF文61aに対応するIF文62a、インクリメント文61bに対応するインクリメント文62b、および、デクリメント文61cに対応するデクリメント文62cを有する。
置換部131は、IF文61a内の要素「!=」を、メタミューテーション関数「bop_ne」に置換し、IF文61a内の要素「<<」を、メタミューテーション関数「bop_shl」に置換する。このとき、置換部131は、各要素に係る変数および定数をメタミューテーション関数の引数とする。また、置換部131は、メタミューテーション関数の引数に、MMIDを設定する。置換部131は、例えば「bop_ne」のMMIDを「0」と設定し、「bop_shl」のMMIDを「1」と設定する。
置換部131は、同様に、インクリメント文61b内の要素「++」を、メタミューテーション関数「uop_postinc」に置換し、デクリメント文61c内の要素「−−」を、メタミューテーション関数「uop_postdec」に置換する。また、置換部131は、例えば「uop_postinc」のMMIDを「2」と設定し、「uop_postdec」のMMIDを「3」と設定する。
図1の説明に戻って、コンパイラ132は、置換部131から置換後のソースコードが入力されると、置換後のソースコードをVM上で実行可能な中間コードであるビットコードにコンパイルする。コンパイラ132は、例えば、置換後のソースコードをLLVMビットコードにコンパイルする。なお、以下の説明では、LLVMビットコードを、単にビットコードと称して説明する。コンパイラ132は、コンパイルしたビットコードをミューテーション部133に出力する。
ここで、置換後のソースコードとビットコードとにおけるミューテーション箇所の対応について説明する。図15は、ソースコードとビットコードとのミューテーション箇所の対応の一例を示す図である。図15に示すように、ソースコード61の要素は、置換後のソースコード62のメタミューテーション関数に置き換えられる。このとき、各メタミューテーション関数にはMMIDが付与される。例えば、MMID62dで示す「bop_ne」のMMIDは「0」、MMID62eで示す「bop_shl」のMMIDは「1」とする。また、例えば、MMID62fで示す「uop_postinc」のMMIDは「2」、MMID62gで示す「uop_postdec」のMMIDは「3」とする。
置換後のソースコード62がビットコード65にコンパイルされると、ビットコード65には、MMID62dに対応するMMID65d、MMID62eに対応するMMID65eが1対1対応可能に含まれる。また、ビットコード65には、MMID62fに対応するMMID65f、MMID62gに対応するMMID65gが1対1対応可能に含まれる。すなわち、コンパイラ132におけるコンパイルでは、ミューテーション箇所がビットコードに全て残るので、最適化によるミュータントの消失が発生しない。
図1の説明に戻って、ミューテーション部133には、入力部111からテスト項目およびミューテーションオペレータリストが入力される。ミューテーション部133は、コンパイラ132からビットコードが入力されると、ミューテーション実行処理を開始する。ミューテーション部133は、コンパイラ132からビットコードが入力されるか、命令実行部134から次のテスト項目の入力指示が入力されると、入力されたテスト項目のうち、次のテスト項目をビットコードに入力する。なお、次のテスト項目は、コンパイラ132からビットコードが入力された場合、つまり初回のテスト項目の場合には、1つ目のテスト項目を用いる。
ミューテーション部133は、テスト項目がビットコードに入力されるか、命令実行部134からインクリメント指示が入力されると、MMIDをインクリメントする。ミューテーション部133は、例えば、MMIDを「0」から付番する場合には、初期値を「−1」としておき、MMIDをインクリメントすることで1回目に処理するMMIDを「0」とすることができる。
ミューテーション部133は、MMIDがインクリメントされるか、命令実行部134から次の命令の処理指示が入力されると、ビットコードから次の命令を抽出する。なお、次の命令は初回の命令の場合には1つ目の命令を抽出する。ミューテーション部133は、抽出した命令が当該MMIDのメタミューテーション関数の呼び出しであるか否かを判定する。ミューテーション部133は、抽出した命令が当該MMIDのメタミューテーション関数の呼び出しである場合には、メタミューテーション関数に対応するミューテーションオペレータとMMIDとをミュータント記憶部123に記憶する。また、ミューテーション部133は、ミューテーションオペレータによって変更された命令を命令記憶部122に記憶する。
ミューテーション部133は、抽出した命令が当該MMIDのメタミューテーション関数の呼び出しでない場合には、元の命令を命令記憶部122に記憶する。ミューテーション部133は、変更された命令または元の命令を命令記憶部122に記憶すると、命令実行部134に命令実行指示を出力する。
ここで、図16および図17を用いて、テスト項目およびミューテーションオペレータリストについて説明する。図16は、テスト項目の一例を示す図である。図17は、ミューテーションオペレータリストの一例を示す図である。図16に示すように、テスト項目63は、例えば、テスト項目ごとに関数の形で表現される。また、図17に示すように、ミューテーションオペレータリスト64は、例えば、OSSN(Shift operator mutation)、ORRN(Relational operator mutation)、OIDO(Increment/Decrement Replacement)といった形で表現される。
また、図18を用いて、ビットコードとミューテーション後の命令との関係について説明する。図18は、ビットコードとミューテーション後の命令との関係の一例を示す図である。図18に示すように、メタミューテーション関数を含むビットコード65は、ミューテーション部133に入力されると、ミューテーションが実行され、例えば命令群66が命令記憶部122に記憶される。このとき、ビットコード65のメタミューテーション関数67aを含む命令文65aは、命令文66aとなる。また、メタミューテーション関数67bを含む命令文65bは、命令文66bとなる。また、メタミューテーション関数67cを含む命令文65cは、命令文66cとなる。
図1の説明に戻って、命令実行部134は、ミューテーション部133から命令実行指示が入力されると、命令記憶部122に記憶された命令を読み出して実行する。命令実行部134は、同一のMMIDにおける各命令の実行結果を記憶部120に一時的に記憶する。命令実行部134は、ビットコードに次の命令があるか否かを判定する。命令実行部134は、ビットコードに次の命令がある場合には、ミューテーション部133に次の命令の処理指示を出力する。
命令実行部134は、ビットコードに次の命令がない場合には、記憶部120に一時的に記憶した各命令の実行結果を読み出して、テストID、ミュータントIDおよびテスト合否をテスト結果として、テスト結果記憶部124に記憶する。命令実行部134は、テスト結果をテスト結果記憶部124に記憶すると、MMIDが上限か否かを判定する。
命令実行部134は、MMIDが上限でない場合には、ミューテーション部133にインクリメント指示を出力する。命令実行部134は、MMIDが上限である場合には、次のテスト項目があるか否かを判定する。命令実行部134は、次のテスト項目がある場合には、ミューテーション部133に次のテスト項目の入力指示を出力する。命令実行部134は、次のテスト項目がない場合には、ミューテーション実行処理を終了し、出力部135に出力指示を出力する。なお、コンパイラ132、ミューテーション部133および命令実行部134は、コンパイルを行って、ミューテーションおよびテストを実行して命令の実行結果であるテスト結果を得る一連の動作を実行するミューテーション部として統合してもよい。
出力部135は、命令実行部134から出力指示が入力されると、テスト結果記憶部124を参照し、テスト結果から「unkilled」であるミュータントを抽出する。すなわち、出力部135は、ミュータントIDごとのテスト結果記憶部124のテスト合否の項目について、全て「Pass」であるミュータントIDを抽出する。また、出力部135は、テスト結果記憶部124のテスト合否の項目が1つ以上「Fail」であるミュータントIDの数、つまり「killed」となったミュータントIDの数を、ミュータントIDの総数で除算した値をミューテーションスコアとして算出する。
出力部135は、メタミューテーション情報記憶部121およびミュータント記憶部123をミュータントIDに基づいて検索し、ミュータントIDに対応するメタミューテーション情報を取得する。出力部135は、取得したメタミューテーション情報に基づいて、ミュータントの位置情報を復元する。
出力部135は、算出したミューテーションスコアと、「unkilled」であるミュータントとに基づいて、結果レポートを生成する。出力部135は、結果レポートを含む結果画面を生成し、生成した結果画面を表示部112に出力して表示させる。すなわち、出力部135は、要素がメタミューテーション関数に置換されたソースコードに対するテスト結果と、MMIDおよび位置情報とに基づいて、要素とテスト結果とを対応付けて出力する。言い換えると、出力部135は、テスト結果からMMIDを抽出し、抽出したMMIDに対応する位置情報と、抽出したMMIDに対応するメタミューテーション関数によって置換された要素とに基づいて、要素とテスト結果とを対応付けて出力する。
ここで、図19を用いて結果画面について説明する。図19は、結果画面の一例を示す図である。図19に示すように、結果画面70は、ミューテーションスコアを表示する領域71と、「unkilled」であるミュータントを表示する領域72と、ソースコードを表示する領域73とを有する。領域72には、テストで検出出来なかった、つまり「killed]とならなかったミュータントがリスト表示される。例えば、項目72aには、ソースコード位置情報が「a.c:3行5桁−3行8桁」であるオリジナルの要素「x++」に対するミュータント「++x」が表示される。また、結果画面70では、例えば、項目72aが選択されると、領域73にソースコードの該当箇所73aが表示される。これにより、解析装置100では、ソースコードにおけるミューテーション箇所の行および桁レベルの対応をとることができる。
すなわち、出力部135は、テストによって検出されなかったミュータントに対応するメタミューテーション関数によって置換された要素と、該要素の位置情報とを対応付けて出力する。言い換えると、出力部135は、テストによって検出されなかったミュータントと、該ミュータントに対応するメタミューテーション関数によって置換された要素と、該要素の位置情報と、ソースコード内の該要素の位置情報に対応する箇所とを表示する結果画面を出力する。
次に、実施例の解析装置100の動作について説明する。図20は、実施例の解析処理の一例を示すフローチャートである。
置換部131は、入力部111からソースコードが入力されると(ステップS1)、ソースコード内の要素をメタミューテーション関数に置換する置換処理を実行する(ステップS2)。ここで、図21を用いて置換処理について説明する。図21は、置換処理の一例を示すフローチャートである。
置換部131は、入力されたソースコードから次の要素を抽出する(ステップS21)。置換部131は、ソースコードの要素が空か否かを判定する(ステップS22)。置換部131は、要素が空でない場合には(ステップS22:否定)、要素がミューテーション対象か否かを判定する(ステップS23)。置換部131は、要素がミューテーション対象である場合には(ステップS23:肯定)、MMIDと要素の位置情報とをメタミューテーション情報記憶部121に記憶する(ステップS24)。また、置換部131は、当該要素を、MMIDを引数に持つメタミューテーション関数に置換して(ステップS25)、ステップS21に戻る。置換部131は、要素がミューテーション対象でない場合には(ステップS23:否定)、ステップS21に戻る。
置換部131は、要素が空である場合には(ステップS22:肯定)、ソースコード内の要素がメタミューテーション関数に置換された置換後のソースコードをコンパイラ132に出力し、置換処理を終了して元の処理に戻る。これにより、解析装置100は、ソースコード内の要素をメタミューテーション関数に置換できる。
図20の解析処理の説明に戻って、コンパイラ132は、置換後のソースコードが入力されると、置換後のソースコードをビットコードにコンパイルする(ステップS3)。コンパイラ132は、コンパイルしたビットコードをミューテーション部133に出力する。
ミューテーション部133は、入力部111からテスト項目およびミューテーションオペレータリストが入力され、コンパイラ132からビットコードが入力されると(ステップS4)、ミューテーション実行処理を開始する(ステップS5)。
ここで、図22を用いてミューテーション実行処理について説明する。図22は、ミューテーション実行処理の一例を示すフローチャートである。ミューテーション部133は、コンパイラ132からビットコードが入力されるか、命令実行部134から次のテスト項目の入力指示が入力されると、次のテスト項目をビットコードに入力する(ステップS51)。
ミューテーション部133は、テスト項目がビットコードに入力されるか、命令実行部134からインクリメント指示が入力されると、MMIDをインクリメントする(ステップS52)。ミューテーション部133は、MMIDがインクリメントされるか、命令実行部134から次の命令の処理指示が入力されると、ビットコードから次の命令を抽出する(ステップS53)。ミューテーション部133は、抽出した命令が当該MMIDのメタミューテーション関数の呼び出しであるか否かを判定する(ステップS54)。
ミューテーション部133は、抽出した命令が当該MMIDのメタミューテーション関数の呼び出しである場合には(ステップS54:肯定)、メタミューテーション関数に対応するミューテーションオペレータとMMIDとをミュータント記憶部123に記憶する(ステップS55)。また、ミューテーション部133は、ミューテーションオペレータによって変更された命令を命令記憶部122に記憶する(ステップS56)。
ミューテーション部133は、抽出した命令が当該MMIDのメタミューテーション関数の呼び出しでない場合には(ステップS54:否定)、元の命令を命令記憶部122に記憶する(ステップS57)。ミューテーション部133は、変更された命令または元の命令を命令記憶部122に記憶すると、命令実行部134に命令実行指示を出力する。
命令実行部134は、ミューテーション部133から命令実行指示が入力されると、命令記憶部122に記憶された命令を読み出して実行する(ステップS58)。命令実行部134は、同一のMMIDにおける各命令の実行結果を記憶部120に一時的に記憶する。命令実行部134は、ビットコードに次の命令があるか否かを判定する(ステップS59)。命令実行部134は、ビットコードに次の命令がある場合には(ステップS59:肯定)、ミューテーション部133に次の命令の処理指示を出力し、ステップS53に戻る。
命令実行部134は、ビットコードに次の命令がない場合には(ステップS59:否定)、記憶部120に一時的に記憶した各命令の実行結果を読み出して、テスト結果をテスト結果記憶部124に記憶する(ステップS60)。命令実行部134は、テスト結果をテスト結果記憶部124に記憶すると、MMIDが上限か否かを判定する(ステップS61)。
命令実行部134は、MMIDが上限でない場合には(ステップS61:否定)、ミューテーション部133にインクリメント指示を出力し、ステップS52に戻る。命令実行部134は、MMIDが上限である場合には(ステップS61:肯定)、次のテスト項目があるか否かを判定する(ステップS62)。命令実行部134は、次のテスト項目がある場合には(ステップS62:肯定)、ミューテーション部133に次のテスト項目の入力指示を出力し、ステップS51に戻る。命令実行部134は、次のテスト項目がない場合には(ステップS62:否定)、ミューテーション実行処理を終了し、出力部135に出力指示を出力して元の処理に戻る。これにより、解析装置100は、ミューテーションの結果であるテスト結果を得ることができる。
図20の解析処理の説明に戻って、出力部135は、命令実行部134から出力指示が入力されると、出力処理を実行する(ステップS6)。ここで、図23を用いて出力処理について説明する。図23は、出力処理の一例を示すフローチャートである。
出力部135は、命令実行部134から出力指示が入力されると、テスト結果記憶部124を参照し、テスト結果から「unkilled」であるミュータントを抽出する(ステップS71)。また、出力部135は、テスト結果記憶部124のテスト合否の項目に基づいて、ミューテーションスコアを算出する(ステップS72)。
出力部135は、メタミューテーション情報記憶部121およびミュータント記憶部123をミュータントIDに基づいて検索し、ミュータントIDに対応するメタミューテーション情報を取得する。出力部135は、取得したメタミューテーション情報に基づいて、ミュータントの位置情報を復元する(ステップS73)。
出力部135は、算出したミューテーションスコアと、「unkilled」であるミュータントとに基づいて、結果レポートを生成する(ステップS74)。出力部135は、結果レポートを含む結果画面を生成し、生成した結果画面を表示部112に出力して表示させ(ステップS75)、元の処理に戻る。これにより、解析装置100は、ビットコードミューテーションによるテストの高速な実行を維持しつつ、テストで検出されないミュータントに対応するソースコード上の要素を把握できる。すなわち、解析装置100は、ソースコード上のどの要素のミューテーションのテスト結果であるかを把握できる。
このように、解析装置100は、ソースコード内の要素について、要素をミュータントに変化させるメタミューテーション関数に置換する際に、メタミューテーション関数のMMIDと、ソースコード内の要素の位置情報とを記憶部120に記憶する。また、解析装置100は、要素がメタミューテーション関数に置換されたソースコードを中間コードにコンパイルして、中間コードに対してミューテーションを実行するとともにテストを実行する。また、解析装置100は、要素がメタミューテーション関数に置換されたソースコードに対するテスト結果と、記憶部120に記憶されたMMIDおよび位置情報とに基づいて、要素とテスト結果とを対応付けて出力する。その結果、ソースコード上のどの要素のミューテーションのテスト結果であるかを把握できる。また、解析装置100は、コンパイル時の最適化によるミュータントの消失を防止できる。
また、解析装置100では、MMIDは、メタミューテーション関数の引数に含まれる。その結果、ソースコード上のどの要素のミューテーションのテスト結果であるかを把握できる。
また、解析装置100は、テスト結果からMMIDを抽出し、抽出したMMIDに対応する位置情報と、抽出したMMIDに対応するメタミューテーション関数によって置換された要素とに基づいて、要素とテスト結果とを対応付けて出力する。その結果、ビットコードでのミュータントがソースコードのどの要素に対応するか正確に知ることができる。
また、解析装置100は、テストによって検出されなかったミュータントに対応するメタミューテーション関数によって置換された要素と、該要素の位置情報とを対応付けて出力する。その結果、テストで検出されなかったミュータントに対応するソースコード上の要素を把握できる。
また、解析装置100は、テストによって検出されなかったミュータントと、該ミュータントに対応するメタミューテーション関数によって置換された要素と、該要素の位置情報と、ソースコード内の該要素の位置情報に対応する箇所とを表示する結果画面を出力する。その結果、テストで検出されなかったミュータントに対応するソースコード上の要素を把握できる。
なお、上記実施例では、中間コードの一例としてLLVMビットコードを用いたが、これに限定されない。例えば、Java(登録商標)VMで実行可能なJavaバイトコード等を用いてもよい。
また、図示した各部の各構成要素は、必ずしも物理的に図示の如く構成されていることを要しない。すなわち、各部の分散・統合の具体的形態は図示のものに限られず、その全部または一部を、各種の負荷や使用状況等に応じて、任意の単位で機能的または物理的に分散・統合して構成することができる。例えば、コンパイラ132と、ミューテーション部133と、命令実行部134とは統合されてもよい。また、図示した各処理は、上記の順番に限定されるものではなく、処理内容を矛盾させない範囲において、同時に実施してもよく、順序を入れ替えて実施してもよい。
さらに、各装置で行われる各種処理機能は、CPU(またはMPU、MCU(Micro Controller Unit)等のマイクロ・コンピュータ)上で、その全部または任意の一部を実行するようにしてもよい。また、各種処理機能は、CPU(またはMPU、MCU等のマイクロ・コンピュータ)で解析実行されるプログラム上、またはワイヤードロジックによるハードウェア上で、その全部または任意の一部を実行するようにしてもよいことは言うまでもない。
ところで、上記の実施例で説明した各種の処理は、予め用意されたプログラムをコンピュータで実行することで実現できる。そこで、以下では、上記の実施例と同様の機能を有するプログラムを実行するコンピュータの一例を説明する。図24は、解析プログラムを実行するコンピュータの一例を示す図である。
図24に示すように、コンピュータ200は、各種演算処理を実行するCPU201と、データ入力を受け付ける入力装置202と、モニタ203とを有する。また、コンピュータ200は、記憶媒体からプログラム等を読み取る媒体読取装置204と、各種装置と接続するためのインタフェース装置205と、他の情報処理装置等と有線または無線により接続するための通信装置206とを有する。また、コンピュータ200は、各種情報を一時記憶するRAM207と、ハードディスク装置208とを有する。また、各装置201〜208は、バス209に接続される。
ハードディスク装置208には、図1に示した置換部131、コンパイラ132、ミューテーション部133、命令実行部134および出力部135の各処理部と同様の機能を有する解析プログラムが記憶される。また、ハードディスク装置208には、メタミューテーション情報記憶部121、命令記憶部122、ミュータント記憶部123、テスト結果記憶部、および、解析プログラムを実現するための各種データが記憶される。入力装置202は、例えば、コンピュータ200のユーザから操作情報、管理情報等の各種情報の入力を受け付ける。モニタ203は、例えば、コンピュータ200の管理者に対して結果画面、管理情報の画面および各種画面を表示する。媒体読取装置204は、記憶媒体からソースコード、テスト項目およびミューテーションオペレータリストを読み取る。インタフェース装置205は、例えば印刷装置等が接続される。通信装置206は、例えば、図1に示した通信部110と同様の機能を有し図示しないネットワークと接続され、他の情報処理装置と各種情報をやりとりする。
CPU201は、ハードディスク装置208に記憶された各プログラムを読み出して、RAM207に展開して実行することで、各種の処理を行う。また、これらのプログラムは、コンピュータ200を図1に示した置換部131、コンパイラ132、ミューテーション部133、命令実行部134および出力部135として機能させることができる。
なお、上記の解析プログラムは、必ずしもハードディスク装置208に記憶されている必要はない。例えば、コンピュータ200が読み取り可能な記憶媒体に記憶されたプログラムを、コンピュータ200が読み出して実行するようにしてもよい。コンピュータ200が読み取り可能な記憶媒体は、例えば、CD−ROMやDVDディスク、USBメモリ等の可搬型記録媒体、フラッシュメモリ等の半導体メモリ、ハードディスクドライブ等が対応する。また、公衆回線、インターネット、LAN等に接続された装置にこの解析プログラムを記憶させておき、コンピュータ200がこれらから解析プログラムを読み出して実行するようにしてもよい。
以上、本実施例を含む実施の形態に関し、さらに以下の付記を開示する。
(付記1)ソースコード内の要素について、前記要素をミュータントに変化させるメタミューテーション関数に置換する際に、前記メタミューテーション関数のIDと、前記ソースコード内の前記要素の位置情報とを記憶部に記憶し、
前記要素が前記メタミューテーション関数に置換されたソースコードを中間コードにコンパイルして、前記中間コードに対してミューテーションを実行するとともにテストを実行し、
前記要素が前記メタミューテーション関数に置換されたソースコードに対するテスト結果と、前記記憶部に記憶された前記IDおよび前記位置情報とに基づいて、前記要素と前記テスト結果とを対応付けて出力する、
処理をコンピュータに実行させることを特徴とする解析プログラム。
(付記2)前記IDは、前記メタミューテーション関数の引数に含まれる、
ことを特徴とする付記1に記載の解析プログラム。
(付記3)前記出力する処理は、前記テスト結果から前記IDを抽出し、抽出した前記IDに対応する前記位置情報と、抽出した前記IDに対応する前記メタミューテーション関数によって置換された前記要素とに基づいて、前記要素と前記テスト結果とを対応付けて出力する、
ことを特徴とする付記1または2に記載の解析プログラム。
(付記4)前記出力する処理は、前記テストによって検出されなかった前記ミュータントに対応する前記メタミューテーション関数によって置換された前記要素と、該要素の前記位置情報とを対応付けて出力する、
ことを特徴とする付記1〜3のいずれか1つに記載の解析プログラム。
(付記5)前記出力する処理は、前記テストによって検出されなかった前記ミュータントと、該ミュータントに対応する前記メタミューテーション関数によって置換された前記要素と、該要素の前記位置情報と、前記ソースコード内の該要素の前記位置情報に対応する箇所とを表示する結果画面を出力する、
ことを特徴とする付記4に記載の解析プログラム。
(付記6)ソースコード内の要素について、前記要素をミュータントに変化させるメタミューテーション関数に置換する際に、前記メタミューテーション関数のIDと、前記ソースコード内の前記要素の位置情報とを記憶部に記憶し、
前記要素が前記メタミューテーション関数に置換されたソースコードを中間コードにコンパイルして、前記中間コードに対してミューテーションを実行するとともにテストを実行し、
前記要素が前記メタミューテーション関数に置換されたソースコードに対するテスト結果と、前記記憶部に記憶された前記IDおよび前記位置情報とに基づいて、前記要素と前記テスト結果とを対応付けて出力する、
処理をコンピュータが実行することを特徴とする解析方法。
(付記7)前記IDは、前記メタミューテーション関数の引数に含まれる、
ことを特徴とする付記6に記載の解析方法。
(付記8)前記出力する処理は、前記テスト結果から前記IDを抽出し、抽出した前記IDに対応する前記位置情報と、抽出した前記IDに対応する前記メタミューテーション関数によって置換された前記要素とに基づいて、前記要素と前記テスト結果とを対応付けて出力する、
ことを特徴とする付記6または7に記載の解析方法。
(付記9)前記出力する処理は、前記テストによって検出されなかった前記ミュータントに対応する前記メタミューテーション関数によって置換された前記要素と、該要素の前記位置情報とを対応付けて出力する、
ことを特徴とする付記6〜8のいずれか1つに記載の解析方法。
(付記10)前記出力する処理は、前記テストによって検出されなかった前記ミュータントと、該ミュータントに対応する前記メタミューテーション関数によって置換された前記要素と、該要素の前記位置情報と、前記ソースコード内の該要素の前記位置情報に対応する箇所とを表示する結果画面を出力する、
ことを特徴とする付記9に記載の解析方法。
(付記11)ソースコード内の要素について、前記要素をミュータントに変化させるメタミューテーション関数に置換する際に、前記メタミューテーション関数のIDと、前記ソースコード内の前記要素の位置情報とを記憶部に記憶する記憶処理部と、
前記要素が前記メタミューテーション関数に置換されたソースコードを中間コードにコンパイルして、前記中間コードに対してミューテーションを実行するとともにテストを実行するミューテーション部と、
前記要素が前記メタミューテーション関数に置換されたソースコードに対するテスト結果と、前記記憶部に記憶された前記IDおよび前記位置情報とに基づいて、前記要素と前記テスト結果とを対応付けて出力する出力部と、
を有することを特徴とする解析装置。
(付記12)前記IDは、前記メタミューテーション関数の引数に含まれる、
ことを特徴とする付記11に記載の解析装置。
(付記13)前記出力部は、前記テスト結果から前記IDを抽出し、抽出した前記IDに対応する前記位置情報と、抽出した前記IDに対応する前記メタミューテーション関数によって置換された前記要素とに基づいて、前記要素と前記テスト結果とを対応付けて出力する、
ことを特徴とする付記11または12に記載の解析装置。
(付記14)前記出力部は、前記テストによって検出されなかった前記ミュータントに対応する前記メタミューテーション関数によって置換された前記要素と、該要素の前記位置情報とを対応付けて出力する、
ことを特徴とする付記11〜13のいずれか1つに記載の解析装置。
(付記15)前記出力部は、前記テストによって検出されなかった前記ミュータントと、該ミュータントに対応する前記メタミューテーション関数によって置換された前記要素と、該要素の前記位置情報と、前記ソースコード内の該要素の前記位置情報に対応する箇所とを表示する結果画面を出力する、
ことを特徴とする付記14に記載の解析装置。