静的解析を快適に!静的解析管理ツールの活用法(REST API編)

皆さんは、静的解析の結果をどのように管理していますか?
静的解析ツールであるParasoftのJtestやdotTEST等を利用している人は、静的解析の利用が快適になるParasoft DTPというツールをおすすめします。

本記事では、Parasoft DTP(以降 DTP)のおすすめ機能(REST APIの機能を中心)をご紹介します。
コマンドラインからの実行により、CIツールとの連携にも活用できますので、ぜひ役立ててみてください。

 

 

DTPについて、簡単にご紹介します。
DTPはParasoft製品(Jtest、dotTESTなど)の静的解析や単体テストの結果を見える化し、プロジェクト全体で共有するためのレポーティングツールです。
Webブラウザーからアクセスすることで、静的解析の統計情報や問題の詳細をソースコードと一緒に確認できるため、開発のリーダーやマネージャーだけでなく、チーム全員でプロジェクトの状態をリアルタイムに把握でき、共有することが出来ます。

他にも以下のような機能が利用できます。

  • 複数のレポートを比較し、新しく検出された違反のみ表示
  • 違反修正の優先度や担当者の割り当て
  • 単体テスト、UIテストのカバレッジ情報の管理
  • ダッシュボードのカスタマイズ

等々、DTPにご興味があれば、以下のParasoftブログのページもご参照ください。

ブログタイトル 対象ページ
DTP で静的解析の結果を見やすくする  <ブログのリンク >
静的解析は大量に違反が出るから使えない、を解消する  <ブログのリンク >
開発プロセス全体のコードカバレッジを確認する  <ブログのリンク >
ParafostブログHome (Parasoft製品に関する色々な情報を公開中!!  <Homeのリンク >

 

 

DTPのREST APIを利用することで、以下のような運用ができるようになります。(REST APIの機能とCI環境を一緒に使用した時のイメージ。)

運用例1では、静的解析結果の管理を自動化(例えば、最新10件のビルド情報を保存し、それ以外のビルド情報を④で削除)することで、解析結果の情報量が必要最小限に抑えられ、必要な情報へ迅速にアクセスできるようになります。その結果、静的解析結果の管理の簡略化に期待が持てます。

 【運用例1で使用しているREST APIの機能】

 

運用例2では、バージョン管理システムのブランチ構成に合わせてDTP上の静的解析結果の管理を自動化し、その結果として管理作業が簡素化されます。また、同一プロジェクト内で複数の案件が並行して進行しても、案件毎の解析結果をブランチ毎のフィルターで管理することで、各案件に必要な解析結果情報へのアクセスが迅速化します。さらに、ブランチ全体に適用される抑制情報も1つのDTPプロジェクト内でフィルターとして管理されるため、保守性が向上し、効果的な運用に期待が持てます。

 【運用例2で使用しているREST APIの機能】

 

ここからが本題!! DTPのREST APIの機能(コマンドライン実行)をご紹介します。
DTPを使用する際は、ブラウザー上でUI操作を行うだけでなく、コマンドライン上での操作も可能です。

  ※1. DTPが理解できていることを前提にまとめています。 DTPの概念は、< DTP2023.1のページ >を参照。
  ※2. ここでご紹介するコマンドは、WindowsコマンドプロンプトとcURLを使用してAPIエンドポイントを実行しています。
     また、DTPのバージョンは、DTP2023.1.2を使用しています。一部の旧バージョンでは提供していない機能もあります。
  ※3. コマンド実行時に使用するDTPに関する情報は以下で統一しています。(利用の際は環境に合わせて書き換えてください)
      - DTPのユーザー名:user01
      - DTPのパスワード:pass01     ※ユーザー名とパスワードの記載例: curl -u user01:pass01
      - DTPのホスト名 :dtp.foo.com  ※ホスト名の記載例: http://dtp.foo.com/

 

1.DTPプロジェクトの作成

DTPのプロジェクトを作成します。(ソフトウェア開発のプロジェクト名などを定義します。)

※DTP2023.2のバージョン以降、解析結果をアップロード時に自動でプロジェクトが作成されます。

実行コマンド(主な変更箇所は太字)
curl -u user01:pass01 -X "POST" "http://dtp.foo.com/grs/api/v1.12/projects" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"active\": true, \"name\": \"ProjectA\"}"

実行後の戻り値(成功するとプロジェクトIDが返される、ここでは71)
{"id":71}

 ※コマンドのオプション詳細
   -d:作成プロジェクトの情報(Json形式で定義する。別ファイルにまとめて定義することも可能。)
     今回は以下の内容を設定
       - プロジェクト名:ProjectA
       - アクティブ:true

     別ファイルに定義する場合は、-dのオプションの部分を以下のように定義(ここではC:/test/test.jsonを指定)
       -d @C:/test/test.json

      DTPのプロジェクトの作成画面と同様の機能(DTPのRecporCenter設定画面 → プロジェクトの作成ボタン)

 

2.プロジェクトIDの取得

「1」で作成したプロジェクトのIDを取得します。
このプロジェクトIDは、他のREST APIの機能(3. DTPフィルターの作成など)で使用します。

実行コマンド(主な変更箇所は太字)
curl -u user01:pass01 -X GET "http://dtp.foo.com/grs/api/v1.12/projects?name=ProjectA&managedOnly=false"

実行後の戻り値(成功するとプロジェクトIDが返される、ここでは71)
[{"id":71,"name":"ProjectA","active":true}]

 ※コマンドのオプション詳細
   name:プロジェクト名
     今回は以下の内容を設定
       - プロジェクト名:ProjectA(「1」で作成したプロジェクト名)

      DTPプロジェクト作成画面と同様の機能(DTPのRecporCenter設定画面(プロジェクト)→プロジェクトの作成ボタン)

 

3.DTPフィルターの作成

静的解析の結果をグループ化するためのフィルターを作成します。

実行コマンド(主な変更箇所は太字)
curl -u user01:pass01 -X POST "http://dtp.foo.com/grs/api/v1.12/filters" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"name\": \"feature/branch-a\",\"project\": {\"id\": 71},\"autoAddNewRunConfigurations\": \"none\"}"

実行後の戻り値(成功するとフィルターIDが返される、ここでは94)
{"id":94}

 ※コマンドのオプション詳細
   -d:作成フィルターの情報(Json形式で定義する。別ファイルにまとめて定義することも可能。)
     今回は以下の内容を設定
       - フィルター名:feature/branch-a
       - 関連プロジェクトID:71(「1」で作成したプロジェクトのID)
       - 新規データの自動関連付け(autoAddNewRunConfigurations):none(※)
          ※自動関連付けの設定値:none(なし)、project(関連プロジェクト)、all(すべてのプロジェクト)
       

      DTPフィルターの作成画面と同様の機能(DTPのRecporCenter設定画面(フィルター)→フィルターの作成ボタン)
      新規データの自動関連付けは、フィルター作成後の編集画面で設定可能

 

4.フィルターIDの取得

静的解析の結果をグループ化しているフィルターのIDを取得します。
フィルターは、DTPのプロジェクトと関連付いており、プロジェクト作成時に自動的に作成されます。
このフィルターIDは、他のREST APIの機能(5. ランコンフィギュレーションIDの取得、6. ランコンフィギュレーションの割り当てなど)で使用します。

実行コマンド(主な変更箇所は太字)
curl -u user01:pass01 -X "GET" "http://dtp.foo.com/grs/api/v1.12/filters?name=ProjectA"

実行後の戻り値(成功するとフィルターIDが返される、ここでは93)
[{"id":93,"name":"ProjectA","project":{"id":71,"name":"ProjectA"," ~(省略)~

 ※コマンドのオプション詳細
   name:フィルター名
     今回は以下の内容を設定
       - フィルター名:ProjectA(「1」のプロジェクト作成時に自動的に作成されたフィルター)

      DTPのフィルターの一覧画面の赤枠と同じIDを取得(RecporCenter設定画面(フィルター))

 

5.ランコンフィギュレーションIDの取得

静的解析の結果のランコンフィギュレーションのIDを取得します。
このランコンフィギュレーションIDは、他のREST APIの機能(6. ランコンフィギュレーションの割り当てなど)で使用します。

実行コマンド(主な変更箇所は太字)
curl -u user01:pass01 -X GET "http://dtp.foo.com/grs/api/v1.12/runConfigurations?filterId=93"

実行後の戻り値(成功するとランコンフィギュレーションIDが返される、ここでは156、sessionTagの値も返される)
[{"id":156,"projectName":"ProjectA","engine":"DTP Engine for Java"," ~(省略)~ "sessionTag":"tag-2024-04-01_01", ~(省略)~ 

 ※コマンドのオプション詳細
   filterId:フィルターID
     今回は以下の内容を設定
       - フィルターID:93(「4」で取得したフィルターID)

      DTPのフィルター設定画面の赤枠と同じIDを取得(RecporCenter設定画面(フィルター)→対象フィルター選択)

 

6.ランコンフィギュレーションの割り当て

静的解析の結果のランコンフィギュレーションを任意のフィルターに割り当てします。
割り当てを行うことでフィルターに紐づいたプロジェクトから静的解析結果を参照できるようになります。

実行コマンド(主な変更箇所は太字)
curl -u user01:pass01 -X PUT http://dtp.foo.com/grs/api/v1.12/filters/94/runConfigurations -H "accept: application/json" -H "Content-Type: application/json;" -d "[{\"id\": 156},{\"id\": 157}]"

 ※コマンドのオプション詳細
   filterId:フィルターID(エンドポイントに直接設定)
     今回は以下の内容を設定
       - フィルターID:94(「4」で取得可能なフィルターID)
   -d:割り当てるの情報(Json形式で定義する。別ファイルにまとめて定義することも可能。)
     今回は以下の内容を設定
       - ランコンフィギュレーションID:156、157(「5」で取得可能なID2つを設定)

      DTPのフィルター設定画面の赤枠から設定内容を確認可能(RecporCenter設定画面(フィルター)→対象フィルター選択)

 

7.ビルドIDの取得

DTPにアップロードした静的解析のビルドIDを取得します。
(jtestcli.propertiesなどに定義する「build.id=xxxxxx」の情報を取得)
このビルドIDは、他のREST APIの機能(8. 静的解析結果の違反数の取得、9.ビルド情報の削除など)で使用します。

実行コマンド(主な変更箇所は太字)
curl -u user01:pass01 -X "GET" "http://dtp.foo.com/grs/api/v1.12/builds"

※filterIdのオプションを付けることで、取得対象の絞り込みが可能
curl -u user01:pass01 -X "GET" "http://dtp.foo.com/grs/api/v1.12/builds?filterId=93"

実行後の戻り値(成功するとビルドIDが返される、ここではtest-2024-04-02、複数存在する場合はその分の情報が返される)
[{"id":"test-2024-04-02","date":"2024-04-01T10:10:00Z"},{"id":"test-2024- ~(省略)~ 

 ※コマンドのオプション詳細
   filterId:フィルターID
     今回は以下の内容を設定
       - フィルターID:93(「4」で取得したフィルターID)

 

8.静的解析結果の違反数の取得

DTPにアップロードした静的解析結果の違反数を取得します。

実行コマンド(主な変更箇所は太字)
curl -u user01:pass01 -X "GET" "http://dtp.foo.com/grs/api/v1.12/staticAnalysisFiles?filterId=93&&buildId=test-2024-04-02"

実行後の戻り値(成功すると対象のビルドIDに紐づく違反数が返される、ここでは69)
{"total":69,"passed":{"count":40,"resources" ~(省略)~

 ※コマンドのオプション詳細
   filterId:フィルターID
     今回は以下の内容を設定
       - フィルターID:93(「4」で取得したフィルターID)

   buildId:ビルドID
     今回は以下の内容を設定
       - ビルドID:test-2024-04-02(「7」で取得したビルドID)

 

9.ビルド情報の削除

DTPにアップロードした静的解析結果を削除します。
(削除した情報は、同じ情報を再アップロードしない限り元に戻せません。)

実行コマンド(主な変更箇所は太字)
curl -u user01:pass01 -X "DELETE" "http://dtp.foo.com/grs/api/v1/builds/test-2024-04-02?force=true"

実行後の戻り値(成功すると作成されたビルドIDとメッセージが返される)
{"message":"ビルド test-2024-04-02 およびすべての関連データが削除されました。"}

 ※コマンドのオプション詳細
   ビルドID(エンドポイント”http://~(省略)~/builds/”の後に設定する。”?force=true”は固定で設定)
     今回は以下の内容を設定
       - ビルドID:test-2024-04-02(「7」で取得したビルドID)

 

10.ライセンス使用状況の取得

DTP LicenseServerで管理している、ライセンスの使用状況を取得します。

実行コマンド(主な変更箇所は太字)
curl -u user01:pass01 -X "GET" "http://dtp.foo.com/licenseserver/usage/api/v1.0/toolsUsage?startDate=2024-03-01"

実行後の戻り値(成功すると使用ライセンスの最大数や機能が返される)
[ { "maxConcurrentLicenseTime": "2024-03-01T10:00:00.000",
    "uniqueHostCount": 1,
    "usageHours": 0.24380305555555556,
    "tool": "jtest!",
    "maxConcurrentLicenseCount": 1,
    "featuresAtMaxConcurrentLicenseTime": [
      {
        "feature": "Coding Standards",
        "count": 1
      },
~(省略)~

 ※コマンドのオプション詳細
   startDate:使用状況取得の開始日
     今回は以下の内容を設定
       - 開始日:2024-03-01

 

他にも「フィルターに設定されている静的解析結果を別フィルターに変更する」等、色々なREST APIの機能や設定可能なオプションがありますので、気になった方は、DTPインストール後にアクセスできるドキュメント(以下URL)をブラウザーからご参照してみてください。

REST APIのドキュメントのURL太字は環境に合わせて変更)
http://dtp.foo.com/grs/api/

ライセンス関連のREST APIのドキュメントのURL太字は環境に合わせて変更)
http://dtp.foo.com/licenseserver/usage/api

 ※DTPサーバーの以下の画面からも参照可能

 

 

DTPは、主に画面のUI(ブラウザー)上からの利用が多いと思いますが、今回ご紹介したREST APIの機能を利用することで、CI環境などの自動化ツールでも利用することができ、活用の幅が広がると思います。
実際にどのように活用するかは、開発現場によって変わってくると思いますが、今回の運用例と機能を参考にDTPを活用していただき、静的解析の運用を快適にしてみてはいかがでしょうか。

Top