コード品質テスト

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

はじめに

パイプライン実行中は、多数の指標が取得され、ビジネスオーナーによって定義された主要業績評価指標(KPI)または Adobe Managed Services で設定された標準と比較されます。

これらは、3 層評価システムを使用して報告されます。

3 層評価

パイプラインには次の 3 つのゲートがあります。

  • コード品質
  • パフォーマンステスト
  • セキュリティテスト

これらの各ゲートには、ゲートで特定される問題に対して 3 層構造があります。

  • 重大 - パイプラインの即時失敗を引き起こす問題です。
  • 重要 - パイプラインの一時停止状態を引き起こす問題です。デプロイメントマネージャー、プロジェクトマネージャーまたはビジネスオーナーは、問題をオーバーライドできます。この場合、パイプラインは続行されます。または、問題を承認できます。この場合、パイプラインはエラーで停止します。重要なエラーのオーバーライドは、タイムアウトの影響を受けます。
  • 情報 - 情報提供だけを目的とした問題です。パイプラインの実行には影響しません。
メモ

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

コード品質テスト

この手順では、コード品質のみのパイプラインの主な目的であるアプリケーションコードの品質を評価し、実稼動以外および実稼動のすべてのパイプラインのビルド手順の直後に実行します。詳しくは、実稼動以外のパイプラインの設定のドキュメントを参照してください。

コード品質テストでは、ソースコードをスキャンし、一定の品質基準を満たしていることを確認します。現在、これは、SonarQube、OakPAL を使用したコンテンツパッケージレベルの調査、および Dispatcher 最適化ツールを使用したディスパッチャー検証の組み合わせによって実装されます。

汎用の Java ルールと AEM 固有のルールを組み合わせたルールは 100 以上あります。AEM 固有のルールの一部は、AEM エンジニアリングのベストプラクティスに基づいて作成され、カスタムコード品質ルールと呼ばれます。

ヒント

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

コード品質テストの結果は、次の表にまとめた評価として提供されます。

名前 定義 カテゴリ 不合格のしきい値
セキュリティ評価 A = 脆弱性なし
B = 軽度の脆弱性が 1 つ以上
C = 重要な脆弱性が 1 つ以上
D = 重大な脆弱性が 1 つ以上
E = 致命的な脆弱性が 1 つ以上
重大 < B
信頼性評価 A = バグなし
B = 軽度のバグが 1 つ以上
C = 重要なバグが 1 つ以上
D = 重大なバグが 1 つ以上
E = 致命的なバグが 1 つ以上
重要 < C
保守性評価 コードスメルの未処理の修正コストによって、アプリケーションに既に投入された時間の割合として定義されます。
  • 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 Manager では、デプロイメント後にステージング環境で既存の AEM セキュリティヘルスチェックを実行し、UI を通じてそのステータスを報告します。結果は、環境内のすべての AEM インスタンスから集計されます。

同じヘルスチェックは、web コンソールまたはオペレーションダッシュボードを使用して、いつでも実行できます。

いずれかのインスタンスが特定のヘルスチェックに対して不合格を報告した場合、環境全体がそのヘルスチェックに不合格となります。コード品質テストやパフォーマンステストと同様に、これらのヘルスチェックもいくつかのカテゴリにまとめられ、3 層ゲートシステムを使用して報告されます。セキュリティテストでは、しきい値がない点のみが異なります。すべてのヘルスチェックでは、合格または不合格になります。

ヘルスチェックの一覧を次の表に示します。

名前 ヘルスチェックの実装 カテゴリ
Deserialization firewall Attach API の準備状態が、受け入れ可能な状態である。 デシリアライゼーションファイアウォール添付 API レディネス 重大
デシリアライゼーションファイアウォールが機能している。 デシリアライゼーションファイアウォール機能 重大
デシリアライゼーションファイアウォールが読み込まれている。 デシリアライゼーションファイアウォール読み込み 重大
AuthorizableNodeName 実装において、認証可能な ID がノード名/パスで公開されていない。 認証可能なノード名生成 重大
デフォルトのパスワードが変更されている。 デフォルトのログインアカウント 重大
Sling のデフォルトの GET サーブレットが DOS 攻撃から保護されている Sling Get Servlet 重大
Sling Java Script Handler が適切に設定されている。 Sling Java Script Handler 重大
Sling JSP Script Handler が適切に設定されている。 Sling JSP Script Handler 重大
SSL が正しく設定されている。 SSL 設定 重大
明らかに安全ではないユーザープロファイルポリシーが見つからない。 ユーザープロファイルへのデフォルトアクセス 重大
Sling Referrer Filter が CSRF 攻撃を防止するように設定されている。 Sling Referrer Filter 重要
Adobe Granite HTML Library Manager が適切に設定されている。 CQ HTML Library Manager 設定 重要
CRXDE サポートバンドルが無効である。 CRXDE サポート 重要
Sling DavEx のバンドルおよびサーブレットが無効である。 DavEx ヘルスチェック 重要
サンプルコンテンツがインストールされていない。 サンプルコンテンツパッケージ 重要
WCM Request Filter と WCM Debug Filter が両方とも無効になっている。 WCM フィルター設定 重要
Sling WebDAV のバンドルおよびサーブレットが適切に設定されている。 WebDAV ヘルスチェック 重要
web サーバーが、クリックジャッキングを防止するように設定されている。 Web サーバー設定 重要
レプリケーションが admin ユーザーを使用していない。 レプリケーションとトランスポートユーザー 情報

パフォーマンステスト

AEM Sites

Cloud Manager は、AEM Sites プログラムのパフォーマンステストを実行します。パフォーマンステストは、実際のユーザーをシミュレートする仮想ユーザー(コンテナ)を実行して、トラフィックをシミュレートするためにステージング環境でページにアクセスすることで、約 30 分間実行されます。これらのページは、クローラーを使用して検出されます。

仮想ユーザー

Cloud Manager で実行される仮想ユーザーまたはコンテナの数は、プログラムの作成または編集中に、ビジネスオーナー​の役割でユーザーが定義した KPI(応答時間とページビュー数/分)によって決まります。 定義済みの KPI に基づき、実際のユーザーをシミュレートする最大 10 個のコンテナが実行されます。テスト用に選択したページは分割され、各仮想ユーザーに割り当てられます。

クローラ

30 分のテスト期間が開始される前に、Cloud Manager は、カスタマーサクセスエンジニアが設定した 1 つ以上のシード URL セットを使用してステージング環境をクロールします。これらの URL から、各ページの HTML を調べ、幅優先方式でリンクが走査されます。

  • このクロール処理は、デフォルトで最大 5000 ページに制限されています。
  • テストされるページの最大数は、環境変数 MAX_PAGES を設定して上書きできます。
    • 使用できる値は 20007000 です。
  • クローラーからのリクエストのタイムアウトは 10 秒に固定されています。

テスト用ページセット

ページは 3 つのページセットで選択されます。Cloud Manager は、実稼動環境とステージング環境全体で AEM インスタンスのアクセスログを使用して、次のバケットを決定します。

  • 最頻訪問ライブページ - このオプションは、実際の顧客が最も頻繁にアクセスした訪問ページをテストするときに選択します。Cloud Manager はアクセスログを読み取り、ライブユーザーによるアクセスが最も多かったページの上位 25 個を特定し、上位 Popular Live Pages のリストを生成します。その後、ステージング環境にも存在するこれらの積集合が、ステージング環境でクロールされます。

  • その他のライブページ - このオプションを選択すると、最頻訪問ライブページの上位 25 ページに含まれないページのうち、頻度は低くてもテストに重要なページが確実にテストされるようになります。最頻訪問ライブページと同様、ライブページはアクセスログから抽出され、ステージング環境にも存在する必要があります。

  • 新規ページ - このオプションを選択すると、ステージング環境にのみデプロイ済みで、まだ実稼動環境にはデプロイされておらずテストが必要な新しいページがテストされるようになります。

選択したページセットをまたいだトラフィックの配分

パイプライン設定の「テスト」タブで、1 セットから全 3 セットまでのいずれかを選択できます。 トラフィックの配分は、選択したセットの数によって決まります。つまり、3 つのセットがすべて選択されている場合、合計ページビューの 33%が各セットに送られます。選択したセットが 選択したセットが 2 つの場合は各セットに 50%ずつ送られ、選択したセットが 1 つの場合はトラフィックの 100%がそのセットに送られます。

この例を考えてみましょう。

  • 頻度の高いライブページと新しいページセットは 50/50 で分割されます。
  • その他のライブページは使用されません。
  • 新しいページセットには 3,000 ページが含まれています。
  • 「1 分あたりのページビュー数」KPI は 200 に設定されます。

30 分間のテストの結果は次のようになります。

  • 「頻度の高いライブページ」セットの 25 ページは、それぞれ 120 回ヒットします。((200 * 0.5) / 25) * 30 = 120
  • 「新規ページ」セットの 3,000 ページは、それぞれ 1 回ヒットします。((200 * 0.5) / 3000) * 30 = 1

テストとレポート

Cloud Manager は、ステージングパブリッシュサーバーで 30 分のテスト期間、デフォルトで認証されていないユーザーとしてページをリクエストすることで、AEM Sites プログラムのパフォーマンステストを実行します。各ページの仮想的なユーザー生成指標(応答時間、エラー率、1 分あたりのビュー数など)と、すべてのインスタンスに対して様々なシステムレベルの指標(CPU、メモリ、ネットワークデータ)を測定します。

3 層ゲートシステムを使用したパフォーマンステストマトリックスの概要を次の表に示します。

指標 カテゴリ 不合格のしきい値
ページリクエストエラー率 重大 >= 2%
CPU 使用率 重大 >= 80%
ディスク I/O 待機時間 重大 >= 50%
第 95 百分位応答時間 重要 >= プログラムレベルの KPI
ピーク応答時間 重要 >= 18 秒
1 分あたりのページビュー数 重要 < プログラムレベルの KPI
ディスク帯域幅使用量 重要 >= 90%
ネットワーク帯域幅使用量 重要 >= 90%
1 分あたりのリクエスト数 情報 >= 6000

Sites と Assets のパフォーマンステストで基本的な認証を使用する方法について詳しくは、認証済みパフォーマンステストの節を参照してください。

メモ

テスト期間中は、オーサーインスタンスとパブリッシュインスタンスの両方が監視されます。もし 1 つのインスタンスでも指標が取得されない場合、その指標は不明として報告され、対応する手順は失敗します。

認証済みパフォーマンステスト

認証済みサイトを持つ AMS の顧客は、必要に応じて、Cloud Manager がサイトのパフォーマンステスト中に web サイトにアクセスするために使用するユーザー名とパスワードを指定できます。

ユーザー名とパスワードは、CM_PERF_TEST_BASIC_USERNAMECM_PERF_TEST_BASIC_PASSWORD という名前で、パイプライン変数として指定します。

ユーザー名は string 変数、パスワードは secretString 変数に保存する必要があります。これらの両方を指定した場合、パフォーマンステストクローラーとテスト仮想ユーザーからのリクエストすべてに、HTTP 基本認証としての資格情報が含まれます。

Cloud Manager CLI を使用してこれらの変数を設定するには、次のコマンドを実行します。

$ aio cloudmanager:set-pipeline-variables <pipeline id> --variable CM_PERF_TEST_BASIC_USERNAME <username> --secret CM_PERF_TEST_BASIC_PASSWORD <password>

API の使用方法については、Patch User Pipeline Variables(ユーザーパイプライン変数へのパッチ適用)の API ドキュメントを参照してください。

AEM Assets

Cloud Manager では、30 分間のテスト期間にわたってアセットを繰り返しアップロードすることで、AEM Assets プログラムのパフォーマンステストを実行します。

オンボーディング要件

Assets のパフォーマンステストの場合、お客様のカスタマーサクセスエンジニアが、オーサーのステージング環境へのオンボーディング中に、cloudmanager ユーザーとパスワードを作成します。パフォーマンステストの手順では、cloudmanager というユーザーと、関連付けられたパスワード(CSE によって作成)が必要です。これをオーサーインスタンスから削除したり、権限を変更したりしないでください。Assets のパフォーマンステストが失敗する可能性があります。

テスト用の画像とアセット

顧客は、独自のアセットをアップロードしてテストできます。この操作は、パイプライン設定​または​編集​画面で行うことができます。JPEG、PNG、GIF、BMP などの一般的な画像形式のほか、Photoshop ファイル、Illustrator ファイル、Postscript ファイルがサポートされています。

ただし、画像がアップロードされない場合、Cloud Manager では、デフォルトの画像と PDF ドキュメントがテストに使用されます。

テスト用アセットの配分

1 分ごとにアップロードされる各タイプのアセット数の配分は、パイプライン設定​または​編集​画面で設定します。

例えば、70/30 分割を使用し、1 分に 10 個のアセットがアップロードされる場合、1 分に 7 個の画像と 3 個のドキュメントがアップロードされます。

テストとレポート

Cloud Manager は、CSE にセットアップされたユーザー名とパスワードを使用して、オーサーインスタンス上にフォルダーを作成します。その後、オープンソースライブラリを使用してアセットがフォルダーにアップロードされます。アセットのテスト手順で実行されるテストは、このオープンソースライブラリを使用して記述されます。 30 分のテスト期間にわたって、各アセットの処理時間と、様々なシステムレベルの指標の両方が測定されます。この機能では、画像と PDF ドキュメントの両方をアップロードできます。

ヒント

詳しくは、実稼動パイプラインの設定のドキュメントを参照してください。プログラムのセットアップ方法と KPI の定義方法については、プログラムのセットアップのドキュメントを参照してください。

パフォーマンステスト結果のグラフ

様々な指標を​パフォーマンステストダイアログ​で使用できます

指標のリスト

指標パネルを展開して、グラフを表示したり、ダウンロードへのリンクを提供したりできます。

グラフとして展開された指標

この機能は、次の指標で使用できます。

  • CPU 使用率 - テスト期間中の CPU 使用率のグラフ

  • ディスク I/O 待機時間 - テスト期間中のディスク I/O 待機時間のグラフ

  • ページエラー率 - テスト期間中の 1 分あたりのページエラー数のグラフ

    • テスト中にエラーが発生したページの一覧を示す CSV ファイル
  • ディスク帯域幅使用量 - テスト期間中のディスク帯域幅使用率のグラフ

  • ネットワーク帯域幅使用率 - テスト期間中のネットワーク帯域幅使用率のグラフ

  • ピーク応答時間 - テスト期間中の 1 分あたりのピーク応答時間のグラフ

  • 第 95 百分位応答時間 - テスト期間中の 1 分あたりの第 95 百分位応答時間のグラフ

    • 第 95 百分位応答時間が定義済みの KPI を超えたページの一覧を示す CSV ファイル。

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

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

このページ