コード品質テスト

パイプラインのコード品質テストの仕組みと、デプロイメントの品質を向上させる方法について説明します。

はじめに

コード品質テストは、一連の品質ルールに基づいてアプリケーションコードを評価します。これはコード品質のみのパイプラインの主な目的であり、実稼動および非実稼動のすべてのパイプラインで、ビルド手順の直後に実行されます。

様々なタイプのパイプラインの詳細については、CI/CD パイプラインのドキュメント設定を参照してください。

コード品質ルール

コード品質テストでは、ソースコードをスキャンし、一定の品質基準を満たしていることを確認します。これは SonarQube と、OakPAL を使用したコンテンツパッケージレベルの調査を組み合わせて実装されています。汎用の Java ルールと AEM 固有のルールを組み合わせたルールは 100 以上あります。AEM 固有のルールの一部は、AEM エンジニアリングのベストプラクティスに基づいて作成され、カスタムコード品質ルールと呼ばれます。

メモ

このリンクを使用して、ルールの完全なリストをダウンロードできます。

3 層評価

コード品質テストによって特定された問題は、3 つのカテゴリーのいずれかに分類されます。

  • 重大 - パイプラインの即時失敗を引き起こす問題です。

  • 重要 - パイプラインの一時停止状態を引き起こす問題です。デプロイメントマネージャー、プロジェクトマネージャーまたはビジネスオーナーは、問題をオーバーライドできます。この場合、パイプラインは続行されます。または、問題を承認できます。この場合、パイプラインはエラーで停止します。

  • 情報 - 情報提供だけを目的とした問題です。パイプラインの実行には影響しません。

メモ

コード品質専用パイプラインでは、コード品質テストステップがパイプラインの最終ステップであるため、コード品質テストゲートでの重要なエラーはオーバーライドできません。

評価

この手順の結果は、評価​として提供されます。

次の表に、重大、重要、情報の各カテゴリの評価と失敗のしきい値を示します。

名前 定義 カテゴリ 不合格のしきい値
セキュリティ評価 A = 脆弱性なし
B = 軽度の脆弱性が 1 つ以上
C = 重要な脆弱性が 1 つ以上
D = 重大な脆弱性が 1 つ以上
E = 致命的な脆弱性が 1 つ以上
重大 < B
信頼性評価 A = バグなし
B = 軽度のバグが 1 つ以上
C = 重要なバグが 1 つ以上
D = 重大なバグが 1 つ以上
E = 致命的なバグが 1 つ以上
重大 < D
保守性評価 コードスメルの未処理の修正コストによって、アプリケーションに既に投入された時間の割合として定義されます。
  • A = <=5%
  • B = 6~10%
  • C = 11~20%
  • D = 21~50%
  • E = >50%
重要 < A
カバレッジ 次の式を使用して、単体テストラインのカバレッジと条件のカバレッジを組み合わせて定義します。
Coverage = (CT + CF + LC)/(2*B + EL)
  • CT = 単体テストの実行中に少なくとも 1 回は true と評価された条件
  • CF = 単体テストの実行中に少なくとも 1 回は false と評価された条件
  • LC = 被覆線 = lines_to_cover - uncovered_lines
  • B = 条件の合計数
  • EL = 実行可能な行の総数 (lines_to_cover)
重要 < 50%
スキップした単体テスト スキップした単体テストの数 情報 > 1
未解決の問題 問題の全体的なタイプ - 脆弱性、バグ、コードスメル 情報 > 0
重複行 重複したブロックに含まれる行の数として定義されます。コードブロックは、次の条件下で重複していると見なされます。
Java 以外のプロジェクト:
  • 100 個以上の連続した重複トークンが必要です。
  • これらのトークンは、少なくとも次の場所に分散している必要があります。
  • 30 行の COBOL コード
  • 20 行の ABAP コード
  • 10 行の他言語コード
Java プロジェクト:
  • トークンと行の数にかかわらず、10 個以上の連続した重複ステートメントが必要です。
重複を検出する際は、インデントの違いと文字列リテラルの違いは無視されます。
情報 > 1%
Cloud Service の互換性 特定された Cloud Service の互換性に関する問題の数 情報 > 0
メモ

参照: SonarQube の指標の定義 を参照してください。

メモ

Cloud Manager で実行されるカスタムコード品質ルールについて詳しくは、カスタムコード品質ルールのドキュメントを参照してください。

偽陽性の処理

品質スキャンプロセスは完璧ではなく、実際には問題がないにもかかわらず問題として誤って特定することもあります。これは「偽陽性」と呼ばれます。

この場合、ルール ID を注釈属性として指定した標準の Java @SuppressWarnings 注釈を使用して、ソースコードに注釈を付けることができます。例えば、よくある問題の 1 つとして、ハードコードされたパスワードを検出する SonarQube ルールにおいて、ハードコードされたパスワードの識別方法が強引な場合があります。

次のコードは、AEM プロジェクトではかなり一般的です。AEM プロジェクトには、一部の外部サービスに接続するコードが含まれています。

@Property(label = "Service Password")
private static final String PROP_SERVICE_PASSWORD = "password";

この場合、SonarQube は致命的脆弱性を報告します。コードを見直した後、これが脆弱性でないことを確認し、適切なルール ID でこれに注釈を付けることができます。

@SuppressWarnings("squid:S2068")
@Property(label = "Service Password")
private static final String PROP_SERVICE_PASSWORD = "password";

ただし、コードが実際には次のような場合は、

@Property(label = "Service Password", value = "mysecretpassword")
private static final String PROP_SERVICE_PASSWORD = "password";

ハードコードされたパスワードを削除するのが正しい解決策です。

メモ

@SuppressWarnings 注釈をできるだけ具体的にすることをお勧めします。つまり、問題の原因となっている特定のステートメントまたはブロックにのみ注釈を付けます。ただし、クラスレベルで注釈を付けることもできます。

メモ

明示的なセキュリティテスト手順はありませんが、コード品質手順の間に評価されるセキュリティ関連のコード品質ルールはあります。Cloud Service でのセキュリティの詳細については、AEM as a Cloud Service のセキュリティの概要のドキュメントを参照してください。

コンテンツパッケージスキャンの最適化

Cloud Manager は、品質分析プロセスの一環として、Maven ビルドで生成されたコンテンツパッケージの分析を実行します。Cloud Manager は、このプロセスを高速化するための最適化を提供します。この最適化は、特定のパッケージ化の制約が観察された場合に有効です。最も重要なのは、単一のコンテンツパッケージ(一般的に「すべて」のパッケージと呼ばれます)を出力するプロジェクトで実行される最適化です。このパッケージには、ビルドで作成された他の多数のコンテンツパッケージが含まれ、スキップ済みとしてマークされます。Cloud Manager がこのシナリオを検出すると、「すべて」のパッケージを展開するのではなく、個々のコンテンツパッケージを直接スキャンし、依存関係に基づいて並べ替えます。例えば、次のビルド出力について考えてみましょう。

  • all/myco-all-1.0.0-SNAPSHOT.zip(コンテンツパッケージ)
  • ui.apps/myco-ui.apps-1.0.0-SNAPSHOT.zip(スキップされたコンテンツパッケージ)
  • ui.content/myco-ui.content-1.0.0-SNAPSHOT.zip(スキップされたコンテンツパッケージ)

myco-all-1.0.0-SNAPSHOT.zip 内の唯一のアイテムがスキップされた 2 つのコンテンツパッケージである場合、「すべて」のコンテンツパッケージの代わりに 2 つの埋め込みパッケージがスキャンされます。

数十の埋め込みパッケージを生成するプロジェクトの場合、この最適化により、パイプライン実行あたり 10 分以上の時間を節約できることが示されています。

「すべて」のコンテンツパッケージに、スキップされたコンテンツパッケージと OSGi バンドルの組み合わせが含まれている場合は、特殊なケースが発生する場合があります。例えば、myco-all-1.0.0-SNAPSHOT.zip に前述の 2 つの埋め込みパッケージと 1 つ以上の OSGi バンドルが含まれている場合、新しい最小限のコンテンツパッケージは OSGi バンドルのみで構築されます。このパッケージは常に cloudmanager-synthetic-jar-package という名前で、含まれているバンドルは /apps/cloudmanager-synthetic-installer/install に配置されます。

メモ
  • この最適化は、AEM にデプロイされるパッケージには影響しません。
  • 埋め込みコンテンツパッケージとスキップされたコンテンツパッケージの照合はファイル名に基づくので、複数のスキップされたコンテンツパッケージのファイル名が完全に同じである場合や、埋め込み中にファイル名が変更された場合は、この最適化を実行できません。

このページ