コード品質テスト code-quality-testing
パイプラインのコード品質テストの仕組みと、デプロイメントの品質を向上させる方法について説明します。
はじめに introduction
パイプライン実行中、ソフトウェアは多数の指標を取得します。次に、これらの指標は、ビジネスオーナーが定義した主要業績評価指標(KPI)、または Adobe Managed Services によって設定された標準と比較されます。
これらの結果は、3 層評価システムを使用して報告されます。
3 層評価 three-tiered-ratings
パイプラインには次の 3 つのゲートがあります。
- コード品質
- パフォーマンステスト
- セキュリティテスト
これらの各ゲートには、ゲートで特定される問題に対して 3 層構造があります。
- 重大 - パイプラインの即時失敗を引き起こす問題です。
- 重要 - パイプラインの一時停止状態を引き起こす問題です。デプロイメントマネージャー、プロジェクトマネージャーまたはビジネスオーナーは、問題をオーバーライドできます。この場合、パイプラインは意図したとおりに続行されます。または、問題を受け入れて、パイプラインがエラーで停止する可能性もあります。重要なエラーのオーバーライドは、タイムアウトの影響を受けます。
- 情報 - 情報提供だけを目的とした問題です。パイプラインの実行には影響しません。
コード品質テスト code-quality-testing-step
このテスト手順では、コード品質のみのパイプラインの主な目的であるアプリケーションコードの品質を評価します。これは、実稼動以外および実稼動のすべてのパイプラインのビルド手順の直後に実行されます。詳しくは、実稼動以外のパイプラインの設定を参照してください。
コード品質テストでは、ソースコードをスキャンし、一定の品質基準を満たしていることを確認します。
これは、SonarQube、OakPAL を使用したコンテンツパッケージレベルの調査、および Dispatcher 最適化ツールを使用したディスパッチャー検証の組み合わせによって実装されます。
汎用の Java ルールと AEM 固有のルールを組み合わせた 100 以上のルールがあります。AEM 固有のルールの一部は、AEM エンジニアリングのベストプラクティスに基づいて作成され、カスタムコード品質ルールと呼ばれます。
コード品質テストの結果は、次の表にまとめた評価として提供されます。
B = 軽度の脆弱性が 1 つ以上
C = 重要な脆弱性が 1 つ以上
D = 重大な脆弱性が 1 つ以上
E = 致命的な脆弱性が 1 つ以上
B = 軽度のバグが 1 つ以上
C = 重要なバグが 1 つ以上
D = 重大なバグが 1 つ以上
E = 致命的なバグが 1 つ以上
コードスメルの未処理の修正コストによって、アプリケーションに既に投入された時間の割合として定義されます。
- A = <=5%
- B = 6~10%
- C = 11~20%
- D = 21~50%
- E = >50%
次の式を使用して、単体テストラインのカバレッジと条件のカバレッジを組み合わせて定義します。Coverage = (CT + CF + LC) / (2 * B + EL)
CT
= 単体テストの実行中に少なくとも 1 回はtrue
と評価された条件CF
= 単体テストの実行中に少なくとも 1 回はfalse
と評価された条件LC
= 被覆線 = lines_to_cover - uncovered_linesB
= 条件の合計数EL
= 実行可能な行の総数 (lines_to_cover)
重複したブロックに含まれる行の数として定義されます。コードブロックは、次の条件下で重複していると見なされます。
Java 以外のプロジェクト:
- 100 個以上の連続した重複トークンが必要です。
- これらのトークンは、少なくとも次の場所に分散している必要があります。
- 30 行の COBOL コード
- 20 行の ABAP コード
- 10 行の他言語コード
Java プロジェクト:
- トークンと行の数にかかわらず、10 個以上の連続した重複ステートメントが必要です。
重複を検出する際は、インデントの違いと文字列リテラルの違いは無視されます。
誤検出の処理 dealing-with-false-positives
品質スキャンプロセスは完璧ではありません。実際には問題がないにもかかわらず、誤って問題として特定することもあります。このシナリオは誤検出と呼ばれます。
この場合、ルール 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
注釈をできるだけ具体的にすることがベストプラクティスです。つまり、問題の原因となっている特定のステートメントまたはブロックにのみ注釈を付けます。ただし、クラスレベルで注釈を付けることは可能です。これにより、より広範囲で警告を抑制できます。セキュリティテスト security-testing
Cloud Manager では、デプロイメント後にステージング環境で既存の AEM セキュリティヘルスチェックを実行し、UI を通じてそのステータスを報告します。結果は、環境内のすべての AEM インスタンスから集計されます。
同じヘルスチェックは、web コンソールまたはオペレーションダッシュボードを使用して、いつでも実行できます。
いずれかのインスタンスが特定のヘルスチェックに対して不合格を報告した場合、環境全体がそのヘルスチェックに不合格となります。コード品質テストやパフォーマンステストと同様に、これらのヘルスチェックもいくつかのカテゴリにまとめられ、3 層ゲートシステムを使用して報告されます。唯一の違いは、セキュリティテストが行われる際にはしきい値がないということです。すべてのヘルスチェックでは、合格または不合格になります。
ヘルスチェックの一覧を次の表に示します。
admin
ユーザーを使用していない。パフォーマンスのテスト performance-testing
AEM Sites aem-sites
Cloud Manager は、AEM Sites プログラムのパフォーマンステストを実行します。パフォーマンステストは、実際のユーザーをシミュレートする仮想ユーザー(コンテナ)を実行して、トラフィックをシミュレートするためにステージング環境でページにアクセスすることで、約 30 分間実行されます。これらのページは、クローラーを使用して検出されます。
仮想ユーザー virtual-users
Cloud Manager では、ビジネスオーナー の役割で設定した KPI(応答時間とページビュー数/分)に基づいて仮想ユーザーまたはコンテナが実行されます。これらの KPI は、プログラムの作成または編集中に設定されます。
定義済みの KPI に基づき、実際のユーザーをシミュレートする最大 10 個のコンテナが実行されます。テスト用に選択したページは分割され、各仮想ユーザーに割り当てられます。
クローラ crawler
30 分のテスト期間が開始される前に、Cloud Manager は、カスタマーサクセスエンジニアが設定した 1 つ以上のシード URL セットを使用してステージング環境をクロールします。これらの URL から、各ページの HTML を調べ、幅優先方式でリンクが走査されます。
- このクロール処理は、デフォルトで最大 5000 ページに制限されています。
- テストされるページの最大数は、パイプライン変数
CM_PERF_TEST_CRAWLER_MAX_PAGES
を設定して上書きできます。- 使用できる値は
2000
~7000
です。
- 使用できる値は
- クローラーからのリクエストのタイムアウトは 10 秒に固定されています。
テスト用ページセット page-sets
ページは 3 つのページセットで選択されます。Cloud Manager は、実稼動環境とステージング環境全体で AEM インスタンスのアクセスログを使用して、次のバケットを決定します。
-
最頻訪問ライブページ - 実際の顧客が最も頻繁にアクセスした訪問ページをテストします。Cloud Manager はアクセスログを読み取り、ライブユーザーによるアクセスが最も多かったページの上位 25 個を特定し、上位
Popular Live Pages
のリストを生成します。その後、ステージング環境にも存在するこれらのページの積集合が、ステージング環境でクロールされます。 -
その他のライブページ - 最頻訪問ライブページの上位 25 ページに含まれないページのうち、頻度は低くてもテストに重要なページが確実にテストされるようになります。最頻訪問ライブページと同様、ライブページはアクセスログから抽出され、ステージング環境にも存在する必要があります。
-
新規ページ - ステージング環境にのみデプロイ済みで、まだ実稼動環境にはデプロイされておらずテストが必要な新しいページがテストされるようになります。
選択したページセットをまたいだトラフィックの配分 distribution-of-traffic
パイプライン設定の「テスト」タブで、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
テストとレポート testing-reporting
Cloud Manager は、ステージングパブリッシュサーバーで 30 分のテスト期間、デフォルトで認証されていないユーザーとしてページをリクエストすることで、AEM Sites プログラムのパフォーマンステストを実行します。各ページの仮想的なユーザー生成指標(応答時間、エラー率、1 分あたりのビュー数など)と、すべてのインスタンスに対して様々なシステムレベルの指標(CPU、メモリ、ネットワークデータ)を測定します。
3 層ゲートシステムを使用したパフォーマンステストマトリックスの概要を次の表に示します。
Sites と Assets のパフォーマンステストで基本的な認証を使用する方法について詳しくは、認証済みパフォーマンステストを参照してください。
認証済みパフォーマンステスト authenticated-performance-testing
認証済みサイトを持つ AMS の顧客は、必要に応じて、Cloud Manager がサイトのパフォーマンステスト中に web サイトにアクセスするために使用するユーザー名とパスワードを指定できます。
ユーザー名とパスワードは、CM_PERF_TEST_BASIC_USERNAME
と CM_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 aem-assets
Cloud Manager では、30 分間にわたってアセットを繰り返しアップロードすることで、AEM Assets プログラムのパフォーマンステストを実行します。
オンボーディング要件 onboarding-requirement
Assets のパフォーマンステストの場合、お客様のカスタマーサクセスエンジニアが、オーサーのステージング環境へのオンボーディング中に、cloudmanager
ユーザーとパスワードを作成します。パフォーマンステストの手順では、cloudmanager
というユーザーと、関連付けられたパスワード(CSE によって作成)が必要です。
このメソッドは、権限を変更せずにオーサーインスタンスに残す必要があります。変更または削除すると、Assets のパフォーマンステストが失敗する可能性があります。
テスト用の画像とアセット assets-for-testing
顧客は、独自のアセットをアップロードしてテストできます。このプロセスは、パイプライン設定 または 編集 画面で行うことができます。JPEG、PNG、GIF、BMP などの一般的な画像形式のほか、Photoshop ファイル、Illustrator ファイル、Postscript ファイルがサポートされています。
ただし、画像がアップロードされない場合、Cloud Manager では、デフォルトの画像と PDF ドキュメントがテストに使用されます。
テスト用アセットの配分 distribution-of-assets
1 分ごとにアップロードされる各タイプのアセット数の配分は、パイプライン設定 または 編集 画面で設定します。
例えば、70/30 分割を使用し、1 分に 10 個のアセットがアップロードされる場合、1 分に 7 個の画像と 3 個のドキュメントがアップロードされます。
テストとレポート testing-and-reporting
Cloud Manager は、CSE にセットアップされたユーザー名とパスワードを使用して、オーサーインスタンス上にフォルダーを作成します。その後、オープンソースライブラリを使用してアセットがフォルダーにアップロードされます。アセットのテスト手順で実行されるテストは、このオープンソースライブラリを使用して記述されます。30 分のテスト期間にわたって、各アセットの処理時間と、様々なシステムレベルの指標の両方が測定されます。この機能では、画像と PDF ドキュメントの両方をアップロードできます。
パフォーマンステスト結果のグラフ performance-testing-results-graphs
様々な指標を パフォーマンステストダイアログボックス で使用できます。
指標パネルを展開して、グラフを表示したり、ダウンロードへのリンクを提供したりできます。
この機能は、次の指標で使用できます。
-
CPU 使用率 - テスト期間中の CPU 使用率のグラフ
-
ディスク I/O 待機時間 - テスト期間中のディスク I/O 待機時間のグラフ
-
ページエラー率 - テスト期間中の 1 分あたりのページエラー数のグラフ
- テスト中にエラーが発生したページの一覧を示す CSV ファイル
-
ディスク帯域幅使用率 - テスト期間中のディスク帯域幅使用率のグラフ
-
ネットワーク帯域幅使用率 - テスト期間中のネットワーク帯域幅使用率のグラフ
-
ピーク応答時間 - テスト期間中の 1 分あたりのピーク応答時間のグラフ
-
第 95 百分位応答時間 - テスト期間中の 1 分あたりの第 95 百分位応答時間のグラフ
- 第 95 百分位応答時間が定義済みの KPI を超えたページの一覧を示す CSV ファイル。
コンテンツパッケージスキャンの最適化 content-package-scanning-optimization
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 にデプロイされるパッケージには影響しません。
- 埋め込みコンテンツパッケージとスキップされたコンテンツパッケージの照合はファイル名に基づきます。複数のスキップされたコンテンツパッケージが同じファイル名を共有する場合や、埋め込み中にファイル名が変更された場合、この最適化は失敗します。